From 0ccc802a6acbdca4491c0ea7a0b790070e2ec85e Mon Sep 17 00:00:00 2001 From: Davis Date: Fri, 20 Sep 2024 19:48:56 +0300 Subject: [PATCH 1/5] feat: add feature toggle support --- .../control-property-editor/src/index.tsx | 6 +++-- .../control-property-editor/src/middleware.ts | 7 ++++-- packages/control-property-editor/src/slice.ts | 8 ++++++ packages/feature-toggle/src/featureToggle.ts | 11 ++++++++ .../src/adp/quick-actions/load.ts | 8 +++--- .../src/cpe/feature-service.ts | 25 +++++++++++++++++++ packages/preview-middleware/package.json | 1 + .../preview-middleware/src/base/config.ts | 1 + packages/preview-middleware/src/base/flp.ts | 7 +++++- .../templates/flp/editor.html | 1 + .../templates/flp/sandbox.html | 1 + packages/preview-middleware/tsconfig.json | 3 +++ pnpm-lock.yaml | 3 +++ 13 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 packages/preview-middleware-client/src/cpe/feature-service.ts diff --git a/packages/control-property-editor/src/index.tsx b/packages/control-property-editor/src/index.tsx index 75a3868540..796c3d00c4 100644 --- a/packages/control-property-editor/src/index.tsx +++ b/packages/control-property-editor/src/index.tsx @@ -11,7 +11,7 @@ import './index.css'; import App from './App'; import { store } from './store'; import { registerAppIcons } from './icons'; -import { initializeLivereload, setProjectScenario } from './slice'; +import { initializeLivereload, setProjectScenario, setFeatureToggles } from './slice'; export interface StartOptions { previewUrl: string; @@ -23,6 +23,7 @@ export interface StartOptions { livereloadUrl?: string; telemetry?: boolean; scenario: Scenario; + features?: { feature: string; isEnabled: boolean }[]; } /** @@ -31,7 +32,7 @@ export interface StartOptions { * @param options StartOptions */ export function start(options: StartOptions): void { - const { previewUrl, rootElementId, telemetry = false, scenario } = options; + const { previewUrl, rootElementId, telemetry = false, scenario, features = [] } = options; if (telemetry) { enableTelemetry(); } @@ -39,6 +40,7 @@ export function start(options: StartOptions): void { registerAppIcons(); initIcons(); + store.dispatch(setFeatureToggles(features)); store.dispatch(setProjectScenario(scenario)); store.dispatch(initializeLivereload({ port: options.livereloadPort, url: options.livereloadUrl })); diff --git a/packages/control-property-editor/src/middleware.ts b/packages/control-property-editor/src/middleware.ts index 3da47de19e..3d5a9cc390 100644 --- a/packages/control-property-editor/src/middleware.ts +++ b/packages/control-property-editor/src/middleware.ts @@ -1,5 +1,5 @@ import type { Dispatch } from 'redux'; -import type { Middleware, MiddlewareAPI } from '@reduxjs/toolkit'; +import type { AnyAction, Middleware, MiddlewareAPI } from '@reduxjs/toolkit'; import type { ExternalAction } from '@sap-ux-private/control-property-editor-common'; import { @@ -16,6 +16,7 @@ import { executeQuickAction } from '@sap-ux-private/control-property-editor-common'; +import type reducer from './slice'; import { changeProperty } from './slice'; type Action = ReturnType; @@ -26,7 +27,9 @@ type Action = ReturnType; * @param store - redux store * @returns Function */ -export const communicationMiddleware: Middleware> = (store: MiddlewareAPI) => { +export const communicationMiddleware: Middleware, ReturnType> = ( + store: MiddlewareAPI, ReturnType> +) => { const { sendAction } = startPostMessageCommunication( function getTarget(): Window | undefined { let result; diff --git a/packages/control-property-editor/src/slice.ts b/packages/control-property-editor/src/slice.ts index d02f68eaf1..0d932226c1 100644 --- a/packages/control-property-editor/src/slice.ts +++ b/packages/control-property-editor/src/slice.ts @@ -53,6 +53,7 @@ export interface SliceState { scenario: Scenario; isAdpProject: boolean; icons: IconDetails[]; + features: Record; changes: ChangesSlice; dialogMessage: ShowMessage | undefined; fileChanges?: string[]; @@ -119,6 +120,7 @@ export const changePreviewScaleMode = createAction<'fit' | 'fixed'>('app/change- export const changeDeviceType = createAction('app/change-device-type'); export const filterNodes = createAction('app/filter-nodes'); export const fileChanged = createAction('app/file-changed'); +export const setFeatureToggles = createAction<{ feature: string; isEnabled: boolean }[]>('app/set-feature-toggles'); interface LivereloadOptions { port: number; @@ -137,6 +139,7 @@ export const initialState: SliceState = { scenario: SCENARIO.UiAdaptation, isAdpProject: false, icons: [], + features: {}, changes: { controls: {}, pending: [], @@ -331,6 +334,11 @@ const slice = createSlice, string>({ .addMatcher(setSaveEnablement.match, (state, action: ReturnType): void => { state.canSave = action.payload; }) + .addMatcher(setFeatureToggles.match, (state, action: ReturnType): void => { + for (const { feature, isEnabled } of action.payload) { + state.features[feature] = isEnabled; + } + }) .addMatcher(appLoaded.match, (state): void => { state.isAppLoading = false; }) diff --git a/packages/feature-toggle/src/featureToggle.ts b/packages/feature-toggle/src/featureToggle.ts index 8524d7d466..97dd0ec019 100644 --- a/packages/feature-toggle/src/featureToggle.ts +++ b/packages/feature-toggle/src/featureToggle.ts @@ -80,6 +80,17 @@ export class FeatureToggleAccess { }); }); } + // if TOOLSUITE_FEATURES env is set check if the feature is enabled there. + else if (process.env.TOOLSUITE_FEATURES) { + const envFeatures = process.env.TOOLSUITE_FEATURES.split(','); + for (const feature of envFeatures) { + const toggle: FeatureToggle = { + feature, + isEnabled: true + }; + definedToggles.push(toggle); + } + } return definedToggles; } } diff --git a/packages/preview-middleware-client/src/adp/quick-actions/load.ts b/packages/preview-middleware-client/src/adp/quick-actions/load.ts index 3369078ff2..e1de66b7b3 100644 --- a/packages/preview-middleware-client/src/adp/quick-actions/load.ts +++ b/packages/preview-middleware-client/src/adp/quick-actions/load.ts @@ -1,15 +1,15 @@ +import { FeatureService } from '../../cpe/feature-service'; import type { QuickActionDefinitionRegistry } from '../../cpe/quick-actions/registry'; import type { ApplicationType } from '../../utils/application'; /** * Loads the appropriate Quick Action registries for the given application type. - * - * @param appType - Application type. + * + * @param appType - Application type. * @returns Quick Action registries. */ export async function loadDefinitions(appType: ApplicationType): Promise[]> { - // eslint-disable-next-line fiori-custom/sap-no-localstorage - if (localStorage.getItem('com.sap.ux.control-property-editor.features.quick-actions') !== 'true') { + if (FeatureService.isFeatureEnabled('cpe.beta.quick-actions') === false) { return []; } if (appType === 'fe-v2') { diff --git a/packages/preview-middleware-client/src/cpe/feature-service.ts b/packages/preview-middleware-client/src/cpe/feature-service.ts new file mode 100644 index 0000000000..8bf875a1a6 --- /dev/null +++ b/packages/preview-middleware-client/src/cpe/feature-service.ts @@ -0,0 +1,25 @@ +export class FeatureService { + private static features: Record = {}; + + static { + // eslint-disable-next-line fiori-custom/sap-no-dom-access, fiori-custom/sap-browser-api-warning + const bootstrapConfig = document.getElementById('sap-ui-bootstrap'); + const features = bootstrapConfig?.getAttribute('data-open-ux-preview-features'); + if (features) { + const featureToggles = JSON.parse(features) as { feature: string; isEnabled: boolean }[]; + for (const { feature, isEnabled } of featureToggles) { + this.features[feature] = isEnabled; + } + } + } + + /** + * Checks if given feature is enabled. + * + * @param featureId - Id of the feature. + * @returns true if feature is enabled. + */ + public static isFeatureEnabled(featureId: string): boolean { + return this.features[featureId] ?? false; + } +} diff --git a/packages/preview-middleware/package.json b/packages/preview-middleware/package.json index 3307e1b484..eff2da9f79 100644 --- a/packages/preview-middleware/package.json +++ b/packages/preview-middleware/package.json @@ -41,6 +41,7 @@ ], "dependencies": { "@sap-ux/logger": "workspace:*", + "@sap-ux/feature-toggle": "workspace:*", "@sap-ux/btp-utils": "workspace:*", "@sap-ux/adp-tooling": "workspace:*", "@sap-ux/control-property-editor-sources": "workspace:@sap-ux/control-property-editor@*", diff --git a/packages/preview-middleware/src/base/config.ts b/packages/preview-middleware/src/base/config.ts index 8cf030611f..47a28c83e3 100644 --- a/packages/preview-middleware/src/base/config.ts +++ b/packages/preview-middleware/src/base/config.ts @@ -50,6 +50,7 @@ export interface TemplateConfig { developerMode: boolean; pluginScript?: string; }; + features?: { feature: string; isEnabled: boolean }[]; locateReuseLibsScript?: boolean; } diff --git a/packages/preview-middleware/src/base/flp.ts b/packages/preview-middleware/src/base/flp.ts index e5bd81cee4..46526af6c4 100644 --- a/packages/preview-middleware/src/base/flp.ts +++ b/packages/preview-middleware/src/base/flp.ts @@ -18,6 +18,7 @@ import { type OperationType } from '@sap-ux/adp-tooling'; import { isAppStudio, exposePort } from '@sap-ux/btp-utils'; +import { FeatureToggleAccess } from '@sap-ux/feature-toggle'; import { deleteChange, readChanges, writeChange } from './flex'; import { generateImportList, mergeTestConfigDefaults } from './test'; @@ -167,6 +168,8 @@ export class FlpSandbox { developerMode: editor.developerMode === true, pluginScript: editor.pluginScript }; + config.features = FeatureToggleAccess.getAllFeatureToggles(); + if (editor.developerMode === true) { config.ui5.bootstrapOptions = serializeUi5Configuration(DEVELOPER_MODE_CONFIG); } @@ -193,6 +196,7 @@ export class FlpSandbox { templatePreviewUrl = templatePreviewUrl.replace('?', `?sap-ui-layer=${rta.layer}&`); } const template = readFileSync(join(__dirname, '../../templates/flp/editor.html'), 'utf-8'); + const features = FeatureToggleAccess.getAllFeatureToggles(); const envPort = process.env.FIORI_TOOLS_LIVERELOAD_PORT; let livereloadPort: number = envPort ? parseInt(envPort, 10) : DEFAULT_LIVERELOAD_PORT; livereloadPort = isNaN(livereloadPort) ? DEFAULT_LIVERELOAD_PORT : livereloadPort; @@ -203,7 +207,8 @@ export class FlpSandbox { appName: rta.options?.appName, scenario, livereloadPort, - livereloadUrl: envLivereloadUrl + livereloadUrl: envLivereloadUrl, + features: JSON.stringify(features) }); this.sendResponse(res, 'text/html', 200, html); }); diff --git a/packages/preview-middleware/templates/flp/editor.html b/packages/preview-middleware/templates/flp/editor.html index 64d56f6234..d891a622b6 100644 --- a/packages/preview-middleware/templates/flp/editor.html +++ b/packages/preview-middleware/templates/flp/editor.html @@ -20,6 +20,7 @@ scenario: '<%- scenario %>', livereloadPort: <%- livereloadPort %>, livereloadUrl: '<%- livereloadUrl %>', + features: <%- features %> }); diff --git a/packages/preview-middleware/templates/flp/sandbox.html b/packages/preview-middleware/templates/flp/sandbox.html index c25be8dd45..3d52b0af03 100644 --- a/packages/preview-middleware/templates/flp/sandbox.html +++ b/packages/preview-middleware/templates/flp/sandbox.html @@ -62,6 +62,7 @@ data-sap-ui-xx-componentPreload="off"<%- ui5.bootstrapOptions %> data-sap-ui-oninit="module:open/ux/preview/client/flp/init"<% if (locals.init) { %> data-open-ux-preview-customInit='<%- init %>'<% } if (locals.flex) { %> + data-open-ux-preview-features='<%- JSON.stringify(features) %>' data-open-ux-preview-flex-settings='<%- JSON.stringify(flex) %>'<% } if (locals.locateReuseLibsScript) { %> data-open-ux-preview-libs-manifests='<%- JSON.stringify(Object.values(apps).map(app => app.url)) %>'<% } %>> diff --git a/packages/preview-middleware/tsconfig.json b/packages/preview-middleware/tsconfig.json index 7e3fc4a28f..a1fa1caaab 100644 --- a/packages/preview-middleware/tsconfig.json +++ b/packages/preview-middleware/tsconfig.json @@ -20,6 +20,9 @@ { "path": "../btp-utils" }, + { + "path": "../feature-toggle" + }, { "path": "../i18n" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 183faf3e5b..21f22bbee7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2043,6 +2043,9 @@ importers: '@sap-ux/control-property-editor-sources': specifier: workspace:@sap-ux/control-property-editor@* version: link:../control-property-editor + '@sap-ux/feature-toggle': + specifier: workspace:* + version: link:../feature-toggle '@sap-ux/logger': specifier: workspace:* version: link:../logger From 6680044e6c7b7b4136fc9a911e165109b511bd13 Mon Sep 17 00:00:00 2001 From: Davis Date: Wed, 16 Oct 2024 11:13:22 +0300 Subject: [PATCH 2/5] test: add feature toggle tests --- .changeset/clean-jars-remember.md | 5 +++ .changeset/fluffy-oranges-divide.md | 7 ++++ .../test/index_no_vscode.test.ts | 32 ++++++++++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .changeset/clean-jars-remember.md create mode 100644 .changeset/fluffy-oranges-divide.md diff --git a/.changeset/clean-jars-remember.md b/.changeset/clean-jars-remember.md new file mode 100644 index 0000000000..1c9ef4f6d0 --- /dev/null +++ b/.changeset/clean-jars-remember.md @@ -0,0 +1,5 @@ +--- +'@sap-ux/feature-toggle': patch +--- + +Include feature toggles form environment variable in `getAllFeatureToggles` diff --git a/.changeset/fluffy-oranges-divide.md b/.changeset/fluffy-oranges-divide.md new file mode 100644 index 0000000000..40a100cb05 --- /dev/null +++ b/.changeset/fluffy-oranges-divide.md @@ -0,0 +1,7 @@ +--- +'@sap-ux-private/preview-middleware-client': patch +'@sap-ux/control-property-editor': patch +'@sap-ux/preview-middleware': patch +--- + +Use feature toggles in the control property editor diff --git a/packages/feature-toggle/test/index_no_vscode.test.ts b/packages/feature-toggle/test/index_no_vscode.test.ts index fa8f574fd2..a064c1676e 100644 --- a/packages/feature-toggle/test/index_no_vscode.test.ts +++ b/packages/feature-toggle/test/index_no_vscode.test.ts @@ -1,10 +1,26 @@ -import { isFeatureEnabled, isInternalFeaturesSettingEnabled } from '../src'; +import { isFeatureEnabled, isInternalFeaturesSettingEnabled, FeatureToggleAccess } from '../src'; describe('Feature Toggle Tests - ENV', () => { + const originalEnv = { ...process.env }; + const originalVSCode = FeatureToggleAccess.vscode; + + beforeAll(() => { + Object.defineProperty(FeatureToggleAccess, 'vscode', { value: undefined }); + }); + beforeEach(() => { jest.resetModules(); jest.doMock('vscode', () => undefined); }); + + afterEach(() => { + process.env = originalEnv; + }); + + afterAll(() => { + Object.defineProperty(FeatureToggleAccess, 'vscode', { value: originalVSCode }); + }); + test('Feature Toggle Tests - getFeatureToggle - enabled', () => { process.env.TOOLSUITE_FEATURES = 'dummy.testToggle,otherToggle'; const featureToggle = isFeatureEnabled(`otherToggle`); @@ -21,6 +37,20 @@ describe('Feature Toggle Tests - ENV', () => { const isInternal = isInternalFeaturesSettingEnabled(); expect(isInternal).toBeTruthy(); }); + test('Feature Toggle Tests - getAllFeatureToggles', () => { + process.env.TOOLSUITE_FEATURES = 'dummy.testToggle,otherToggle'; + const featureToggles = FeatureToggleAccess.getAllFeatureToggles(); + expect(featureToggles).toStrictEqual([ + { + feature: 'dummy.testToggle', + isEnabled: true + }, + { + feature: 'otherToggle', + isEnabled: true + } + ]); + }); }); describe('Feature Toggle Tests - ENV - Negative', () => { From 4ce7ac16ac69547e9320f5a11337f9a2d80465ce Mon Sep 17 00:00:00 2001 From: Davis Date: Wed, 16 Oct 2024 11:37:52 +0300 Subject: [PATCH 3/5] test: add cpe tests --- .../test/unit/slice.test.ts | 24 ++++++++++++++++- .../test/index_no_vscode.test.ts | 14 +++------- .../test/unit/cpe/feature-service.test.ts | 27 +++++++++++++++++++ 3 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 packages/preview-middleware-client/test/unit/cpe/feature-service.test.ts diff --git a/packages/control-property-editor/test/unit/slice.test.ts b/packages/control-property-editor/test/unit/slice.test.ts index bd9155a597..8803a78d84 100644 --- a/packages/control-property-editor/test/unit/slice.test.ts +++ b/packages/control-property-editor/test/unit/slice.test.ts @@ -20,9 +20,11 @@ import reducer, { changeDeviceType, setProjectScenario, fileChanged, - initialState + initialState, + setFeatureToggles } from '../../src/slice'; import { DeviceType } from '../../src/devices'; +import { features } from 'process'; describe('main redux slice', () => { describe('property changed', () => { @@ -624,4 +626,24 @@ describe('main redux slice', () => { ] }); }); + + describe('setFeatureToggles', () => { + test('add feature toggles', () => { + expect( + reducer( + { features: {} } as any, + setFeatureToggles([ + { + feature: 'test.feature', + isEnabled: true + } + ]) + ) + ).toStrictEqual({ + features: { + 'test.feature': true + } + }); + }); + }); }); diff --git a/packages/feature-toggle/test/index_no_vscode.test.ts b/packages/feature-toggle/test/index_no_vscode.test.ts index a064c1676e..d6850456e3 100644 --- a/packages/feature-toggle/test/index_no_vscode.test.ts +++ b/packages/feature-toggle/test/index_no_vscode.test.ts @@ -1,12 +1,7 @@ -import { isFeatureEnabled, isInternalFeaturesSettingEnabled, FeatureToggleAccess } from '../src'; +import { isFeatureEnabled, isInternalFeaturesSettingEnabled } from '../src'; describe('Feature Toggle Tests - ENV', () => { const originalEnv = { ...process.env }; - const originalVSCode = FeatureToggleAccess.vscode; - - beforeAll(() => { - Object.defineProperty(FeatureToggleAccess, 'vscode', { value: undefined }); - }); beforeEach(() => { jest.resetModules(); @@ -17,10 +12,6 @@ describe('Feature Toggle Tests - ENV', () => { process.env = originalEnv; }); - afterAll(() => { - Object.defineProperty(FeatureToggleAccess, 'vscode', { value: originalVSCode }); - }); - test('Feature Toggle Tests - getFeatureToggle - enabled', () => { process.env.TOOLSUITE_FEATURES = 'dummy.testToggle,otherToggle'; const featureToggle = isFeatureEnabled(`otherToggle`); @@ -37,8 +28,9 @@ describe('Feature Toggle Tests - ENV', () => { const isInternal = isInternalFeaturesSettingEnabled(); expect(isInternal).toBeTruthy(); }); - test('Feature Toggle Tests - getAllFeatureToggles', () => { + test('Feature Toggle Tests - getAllFeatureToggles', async () => { process.env.TOOLSUITE_FEATURES = 'dummy.testToggle,otherToggle'; + const { FeatureToggleAccess } = await import('../src'); const featureToggles = FeatureToggleAccess.getAllFeatureToggles(); expect(featureToggles).toStrictEqual([ { diff --git a/packages/preview-middleware-client/test/unit/cpe/feature-service.test.ts b/packages/preview-middleware-client/test/unit/cpe/feature-service.test.ts new file mode 100644 index 0000000000..a84b06f65f --- /dev/null +++ b/packages/preview-middleware-client/test/unit/cpe/feature-service.test.ts @@ -0,0 +1,27 @@ +describe('FeatureService', () => { + afterEach(() => { + jest.resetModules(); + }); + + function setFeatureToggles(featureNames: string[]) { + const features = featureNames.map((feature) => ({ + feature, + isEnabled: true + })); + const bootstrap = document.createElement('div'); + bootstrap.setAttribute('id', 'sap-ui-bootstrap'); + bootstrap.setAttribute('data-open-ux-preview-features', JSON.stringify(features)); + document.body.appendChild(bootstrap); + } + + test('not enabled feature', async () => { + const { FeatureService } = await import('../../../src/cpe/feature-service'); + expect(FeatureService.isFeatureEnabled('test.feature')).toStrictEqual(false); + }); + + test('enabled feature', async () => { + setFeatureToggles(['test.feature']); + const { FeatureService } = await import('../../../src/cpe/feature-service'); + expect(FeatureService.isFeatureEnabled('test.feature')).toStrictEqual(true); + }); +}); From 468f0a5f21dee087242503246669a4489a858d12 Mon Sep 17 00:00:00 2001 From: Davis Date: Wed, 16 Oct 2024 11:57:21 +0300 Subject: [PATCH 4/5] test: update outdated tests --- .../test/unit/adp/quick-actions/load.test.ts | 11 ++++++----- .../test/unit/base/__snapshots__/flp.test.ts.snap | 5 +++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/preview-middleware-client/test/unit/adp/quick-actions/load.test.ts b/packages/preview-middleware-client/test/unit/adp/quick-actions/load.test.ts index a17e0f9199..6ac8149054 100644 --- a/packages/preview-middleware-client/test/unit/adp/quick-actions/load.test.ts +++ b/packages/preview-middleware-client/test/unit/adp/quick-actions/load.test.ts @@ -1,14 +1,15 @@ +import { FeatureService } from '../../../../src/cpe/feature-service'; import { loadDefinitions } from '../../../../src/adp/quick-actions/load'; import FEV4QuickActionRegistry from 'open/ux/preview/client/adp/quick-actions/fe-v4/registry'; import FEV2QuickActionRegistry from 'open/ux/preview/client/adp/quick-actions/fe-v2/registry'; -describe('quick action dyncmic loading', () => { +describe('quick action dynamic loading', () => { beforeEach(() => { - jest.spyOn(window.localStorage.__proto__, 'getItem').mockImplementation((key) => { - if (key === 'com.sap.ux.control-property-editor.features.quick-actions') { - return 'true'; + jest.spyOn(FeatureService, 'isFeatureEnabled').mockImplementation((key: string) => { + if (key === 'cpe.beta.quick-actions') { + return true; } - return null; + return false; }); }); test('fe-v2', async () => { diff --git a/packages/preview-middleware/test/unit/base/__snapshots__/flp.test.ts.snap b/packages/preview-middleware/test/unit/base/__snapshots__/flp.test.ts.snap index 1ed59ed379..b3f5bf5917 100644 --- a/packages/preview-middleware/test/unit/base/__snapshots__/flp.test.ts.snap +++ b/packages/preview-middleware/test/unit/base/__snapshots__/flp.test.ts.snap @@ -608,6 +608,7 @@ exports[`FlpSandbox router rta 1`] = ` data-sap-ui-frameOptions=\\"allow\\" data-sap-ui-xx-componentPreload=\\"off\\" data-sap-ui-oninit=\\"module:open/ux/preview/client/flp/init\\" + data-open-ux-preview-features='[]' data-open-ux-preview-flex-settings='{\\"layer\\":\\"CUSTOMER_BASE\\",\\"baseId\\":\\"test.fe.v2.app\\",\\"appName\\":\\"test.fe.v2.app\\",\\"generator\\":\\"@sap-ux/preview-middleware\\",\\"developerMode\\":false}'> @@ -645,6 +646,7 @@ exports[`FlpSandbox router rta with developerMode=true 1`] = ` scenario: '', livereloadPort: 35729, livereloadUrl: '', + features: [] }); @@ -720,6 +722,7 @@ exports[`FlpSandbox router rta with developerMode=true 2`] = ` data-sap-ui-xx-suppressDeactivationOfControllerCode=\\"true\\" data-sap-ui-xx-viewCache=\\"false\\" data-sap-ui-oninit=\\"module:open/ux/preview/client/flp/init\\" + data-open-ux-preview-features='[]' data-open-ux-preview-flex-settings='{\\"layer\\":\\"CUSTOMER_BASE\\",\\"baseId\\":\\"test.fe.v2.app\\",\\"appName\\":\\"test.fe.v2.app\\",\\"generator\\":\\"@sap-ux/control-property-editor\\",\\"developerMode\\":true,\\"pluginScript\\":\\"open/ux/preview/client/cpe/init\\"}'> @@ -814,6 +817,7 @@ exports[`FlpSandbox router rta with developerMode=true and plugin 1`] = ` data-sap-ui-xx-suppressDeactivationOfControllerCode=\\"true\\" data-sap-ui-xx-viewCache=\\"false\\" data-sap-ui-oninit=\\"module:open/ux/preview/client/flp/init\\" + data-open-ux-preview-features='[]' data-open-ux-preview-flex-settings='{\\"layer\\":\\"CUSTOMER_BASE\\",\\"baseId\\":\\"test.fe.v2.app\\",\\"appName\\":\\"test.fe.v2.app\\",\\"generator\\":\\"@sap-ux/control-property-editor\\",\\"developerMode\\":true,\\"pluginScript\\":\\"open/ux/tools/plugin\\"}'> @@ -905,6 +909,7 @@ exports[`FlpSandbox router rta with editors path without leading "/" 1`] = ` data-sap-ui-frameOptions=\\"allow\\" data-sap-ui-xx-componentPreload=\\"off\\" data-sap-ui-oninit=\\"module:open/ux/preview/client/flp/init\\" + data-open-ux-preview-features='[]' data-open-ux-preview-flex-settings='{\\"layer\\":\\"CUSTOMER_BASE\\",\\"baseId\\":\\"test.fe.v2.app\\",\\"appName\\":\\"test.fe.v2.app\\",\\"generator\\":\\"@sap-ux/preview-middleware\\",\\"developerMode\\":false}'> From f67817874b84a99a14291939755c30aa705c9d24 Mon Sep 17 00:00:00 2001 From: Davis Date: Wed, 16 Oct 2024 12:07:21 +0300 Subject: [PATCH 5/5] test: update outdated test --- .../test/unit/appIndex.test.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/control-property-editor/test/unit/appIndex.test.ts b/packages/control-property-editor/test/unit/appIndex.test.ts index bbc44c0626..f9e054c1d7 100644 --- a/packages/control-property-editor/test/unit/appIndex.test.ts +++ b/packages/control-property-editor/test/unit/appIndex.test.ts @@ -4,7 +4,7 @@ import * as icons from '../../src/icons'; import * as initIcon from '@sap-ux/ui-components/dist/components/Icons'; // bug in TS 4.6 https://github.com/microsoft/TypeScript/issues/43081 import ReactDOM from 'react-dom'; import { store } from '../../src/store'; -import { initializeLivereload, setProjectScenario } from '../../src/slice'; +import { initializeLivereload, setFeatureToggles, setProjectScenario } from '../../src/slice'; describe('index', () => { const i18nSpy = jest.spyOn(i18n, 'initI18n'); @@ -17,13 +17,20 @@ describe('index', () => { test('start', () => { const previewUrl = 'URL'; const rootElementId = 'root'; - start({ previewUrl, rootElementId, livereloadPort: 8080, scenario: 'APP_VARIANT' }); + const features = [ + { + feature: 'test.feature', + isEnabled: true + } + ]; + start({ previewUrl, rootElementId, livereloadPort: 8080, scenario: 'APP_VARIANT', features }); expect(i18nSpy).toHaveBeenCalledTimes(1); expect(iconsSpy).toHaveBeenCalledTimes(1); expect(initIconSpy).toHaveBeenCalledTimes(1); expect(reactSpy).toHaveBeenCalledTimes(1); - expect(dispatchSpy).toHaveBeenCalledTimes(2); - expect(dispatchSpy).nthCalledWith(1, setProjectScenario('APP_VARIANT')); - expect(dispatchSpy).nthCalledWith(2, initializeLivereload({ port: 8080, url: undefined })); + expect(dispatchSpy).toHaveBeenCalledTimes(3); + expect(dispatchSpy).nthCalledWith(1, setFeatureToggles(features)); + expect(dispatchSpy).nthCalledWith(2, setProjectScenario('APP_VARIANT')); + expect(dispatchSpy).nthCalledWith(3, initializeLivereload({ port: 8080, url: undefined })); }); });