From 331b238976fa4e37af4a348cfe14cfbeeb34a428 Mon Sep 17 00:00:00 2001 From: caele Date: Wed, 16 Mar 2022 12:59:31 +0100 Subject: [PATCH] chore: fix test for long running query --- .../src/mocks/get-object-mock.js | 9 +- apis/enigma-mocker/src/prop.js | 8 +- .../src/components/LongRunningQuery.jsx | 4 +- test/mashup/visualize/life.int.js | 15 +++ test/mashup/visualize/scenarios.js | 114 ++++++++++++++++++ 5 files changed, 142 insertions(+), 8 deletions(-) diff --git a/apis/enigma-mocker/src/mocks/get-object-mock.js b/apis/enigma-mocker/src/mocks/get-object-mock.js index a93e4e1b6..1ad7b81b4 100644 --- a/apis/enigma-mocker/src/mocks/get-object-mock.js +++ b/apis/enigma-mocker/src/mocks/get-object-mock.js @@ -1,5 +1,4 @@ import { getPropValue, getPropFn } from '../prop'; -import { findAsync } from '../util'; /** * Properties on `getObject()` operating synchronously. @@ -13,6 +12,7 @@ const PROPS_SYNC = [ 'removeAllListeners', 'removeListener', 'setMaxListerners', + 'qId', ]; /** @@ -30,7 +30,7 @@ function isPropAsync(name) { * @returns The mocked object */ function createMock(genericObject) { - const { id, session, ...props } = genericObject; + const { id, session, delay = 0, ...props } = genericObject; return { id: getPropValue(id, { defaultValue: `object - ${+Date.now()}` }), session: getPropValue(session, { defaultValue: true }), @@ -39,7 +39,7 @@ function createMock(genericObject) { ...Object.entries(props).reduce( (fns, [name, value]) => ({ ...fns, - [name]: getPropFn(value, { async: isPropAsync(name) }), + [name]: getPropFn(value, { async: isPropAsync(name), delay }), }), {} ), @@ -63,6 +63,7 @@ function validate(genericObject) { if (!(layout.qInfo && layout.qInfo.qId)) { throw new Error('Generic object is missing "qId" for path "getLayout().qInfo.qId"'); } + genericObject.qId = layout.qInfo.qId; // eslint-disable-line no-param-reassign } /** @@ -75,7 +76,7 @@ function GetObjectMock(genericObjects = []) { const genericObjectMocks = genericObjects.map(createMock); return async (id) => { - const mock = findAsync(genericObjectMocks, async (m) => (await m.getLayout()).qInfo.qId === id); + const mock = genericObjectMocks.find((m) => m.qId() === id); return Promise.resolve(mock); }; } diff --git a/apis/enigma-mocker/src/prop.js b/apis/enigma-mocker/src/prop.js index b4b95ff7a..0458c4bc9 100644 --- a/apis/enigma-mocker/src/prop.js +++ b/apis/enigma-mocker/src/prop.js @@ -55,8 +55,12 @@ export const getPropValue = (prop, { args = [], defaultValue } = {}) => { * @returns A fixture property function */ export const getPropFn = - (prop, { defaultValue, async = true } = {}) => + (prop, { defaultValue, async = true, delay = 0 } = {}) => (...args) => { const value = getPropValue(prop, { defaultValue, args }); - return async ? Promise.resolve(value) : value; + return async + ? new Promise((resolve) => { + setTimeout(() => resolve(value), delay); + }) + : value; }; diff --git a/apis/nucleus/src/components/LongRunningQuery.jsx b/apis/nucleus/src/components/LongRunningQuery.jsx index 2ae5404d3..b509e4a91 100644 --- a/apis/nucleus/src/components/LongRunningQuery.jsx +++ b/apis/nucleus/src/components/LongRunningQuery.jsx @@ -31,7 +31,7 @@ export function Cancel({ cancel, translator, ...props }) { - + {translator.get('Object.Update.Active')} @@ -52,7 +52,7 @@ export function Retry({ retry, translator, ...props }) { - + {translator.get('Object.Update.Cancelled')} diff --git a/test/mashup/visualize/life.int.js b/test/mashup/visualize/life.int.js index 2d30864fd..56912b980 100644 --- a/test/mashup/visualize/life.int.js +++ b/test/mashup/visualize/life.int.js @@ -32,6 +32,21 @@ describe('object lifecycle', () => { await waitForTextStatus('[data-tid="error-title"]', 'Incomplete visualization'); }); + it('should render long running query', async () => { + const url = getScenarioUrl('long-running'); + await page.goto(url); + await waitForTextStatus('[data-tid="update-active"]', 'Updating data'); + + // the cancel button should appear after 2000ms + await page.click('.njs-cell button'); + await waitForTextStatus('[data-tid="update-cancelled"]', 'Data update was cancelled'); + // Retry + await waitForTextStatus('.njs-cell button', 'Retry'); + await page.click('.njs-cell button'); + + await waitForTextStatus('.rendered', 'Success!', { timeout: 7000 }); + }); + // need to fix calc condition view first it('should show calculation unfulfilled', async () => { const url = getScenarioUrl('calc-unfulfilled'); diff --git a/test/mashup/visualize/scenarios.js b/test/mashup/visualize/scenarios.js index aaa85623d..16ac43ca9 100644 --- a/test/mashup/visualize/scenarios.js +++ b/test/mashup/visualize/scenarios.js @@ -36,6 +36,120 @@ scenarios['valid-type'] = { }, }; +scenarios['long-running'] = { + name: 'Long running query', + genericObject: { + delay: 5000, + session: { + getObjectApi() { + return { + cancelRequest() { + return {}; + }, + }; + }, + }, + getLayout() { + return { + qInfo: { + qId: 'bb8', + qType: 'doesnt matter', + }, + qMeta: { + privileges: ['read', 'update', 'delete', 'exportdata'], + }, + qSelectionInfo: {}, + visualization: 'my-chart', + qHyperCube: { + qSize: { + qcx: 2, + qcy: 1, + }, + qDimensionInfo: [ + { + qFallbackTitle: '=a', + qApprMaxGlyphCount: 1, + qCardinal: 0, + qSortIndicator: 'N', + qGroupFallbackTitles: ['=a'], + qGroupPos: 0, + qStateCounts: { + qLocked: 0, + qSelected: 0, + qOption: 0, + qDeselected: 0, + qAlternative: 0, + qExcluded: 0, + qSelectedExcluded: 0, + qLockedExcluded: 0, + }, + qTags: [], + qDimensionType: 'D', + qGrouping: 'N', + qNumFormat: { + qType: 'U', + qnDec: 0, + qUseThou: 0, + }, + qIsAutoFormat: true, + qGroupFieldDefs: ['=a'], + qMin: 'NaN', + qMax: 'NaN', + qAttrExprInfo: [], + qAttrDimInfo: [], + qIsCalculated: true, + qCardinalities: { + qCardinal: 0, + qHypercubeCardinal: 1, + qAllValuesCardinal: -1, + }, + }, + ], + qMeasureInfo: [ + { + qFallbackTitle: '=1', + qApprMaxGlyphCount: 1, + qCardinal: 0, + qSortIndicator: 'N', + qNumFormat: { + qType: 'U', + qnDec: 0, + qUseThou: 0, + }, + qMin: 1, + qMax: 1, + qIsAutoFormat: true, + qAttrExprInfo: [], + qAttrDimInfo: [], + qTrendLines: [], + }, + ], + qEffectiveInterColumnSortOrder: [0, 1], + qGrandTotalRow: [ + { + qText: '1', + qNum: 1, + qElemNumber: -1, + qState: 'X', + qIsTotalCell: true, + }, + ], + qDataPages: [], + qPivotDataPages: [], + qStackedDataPages: [], + qMode: 'S', + qNoOfLeftDims: -1, + qTreeNodesOnDim: [], + qColumnOrder: [], + }, + }; + }, + getProperties() { + return {}; + }, + }, +}; + scenarios['calc-unfulfilled'] = { name: 'Calculations unfulfilled', genericObject: {