Skip to content

Commit

Permalink
refactor: changed the way feature flags are provided to app
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshusinghs committed Nov 24, 2023
1 parent d93f5cf commit 65130dd
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 140 deletions.
23 changes: 19 additions & 4 deletions src/featureFlags.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
export type FeatureFlag = 'useNewConnectionForm';
export type FeatureFlags = Record<FeatureFlag, boolean>;
export const getFeatureFlags = (): FeatureFlags => ({
const FEATURE_FLAGS = {
useNewConnectionForm: `${process.env.MDB_USE_NEW_CONNECTION_FORM}` === 'true',
});
};

export type FeatureFlag = keyof typeof FEATURE_FLAGS;

export const getFeatureFlag = (flag: FeatureFlag) => {
if (typeof window === 'object') {
return (window as any).MDB_FEATURE_FLAGS?.[flag];
}
return FEATURE_FLAGS[flag];
};

export const getFeatureFlagsScript = (nonce: string) => {
return `
<script nonce="${nonce}">window['MDB_FEATURE_FLAGS']=${JSON.stringify(
FEATURE_FLAGS
)}</script>
`;
};
42 changes: 5 additions & 37 deletions src/test/suite/views/webview-app/app.test.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,21 @@
import assert from 'assert';
import * as React from 'react';
import sinon from 'sinon';
import { render, screen, act } from '@testing-library/react';
import * as featureFlags from '../../../../featureFlags';
import { render, screen } from '@testing-library/react';
import App from '../../../../views/webview-app/app';
import { MESSAGE_TYPES } from '../../../../views/webview-app/extension-app-message-constants';

describe('App Component Test Suite', () => {
let fakeVscodeWindowPostMessage;
let fakeOnEventFunction;
let fakeAddEventListener;

beforeEach(() => {
fakeVscodeWindowPostMessage = sinon.fake.returns(null);
fakeAddEventListener = (eventName, eventFn): void => {
if (eventName === 'message') {
fakeOnEventFunction = eventFn;
}
};

sinon.replace(
(global as any).vscodeFake,
'postMessage',
fakeVscodeWindowPostMessage
);

sinon.replace(window, 'addEventListener', fakeAddEventListener);
});

afterEach(() => {
sinon.restore();
});

afterEach(() => sinon.restore());
test('it renders the old overview page when useNewConnectionForm is falsy', () => {
sinon.stub(featureFlags, 'getFeatureFlag').returns(false);
render(<App />);
assert.doesNotThrow(() => screen.getAllByTestId('legacy-app'));
});

test('it renders the new overview page when useNewConnectionForm is truthy', () => {
sinon.stub(featureFlags, 'getFeatureFlag').returns(true);
render(<App />);
act(() => {
fakeOnEventFunction({
data: {
command: MESSAGE_TYPES.FEATURE_FLAGS_RESULTS,
featureFlags: {
useNewConnectionForm: true,
},
},
});
});
assert.throws(() => screen.getAllByTestId('legacy-app'));
});
});
51 changes: 0 additions & 51 deletions src/test/suite/views/webviewController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -849,55 +849,4 @@ suite('Webview Test Suite', () => {
);
});
});

test('webview returns the feature flags on a feature flags request', (done) => {
const extensionContextStub = new ExtensionContextStub();
const testStorageController = new StorageController(extensionContextStub);
const testTelemetryService = new TelemetryService(
testStorageController,
extensionContextStub
);
const testConnectionController = new ConnectionController({
statusView: new StatusView(extensionContextStub),
storageController: testStorageController,
telemetryService: testTelemetryService,
});
let messageReceived;

const fakeWebview = {
html: '',
postMessage: (message): void => {
assert.strictEqual(message.command, 'FEATURE_FLAGS_RESULTS');
assert.strictEqual(typeof message.featureFlags, 'object');
done();
},
onDidReceiveMessage: (callback): void => {
messageReceived = callback;
},
asWebviewUri: sandbox.fake.returns(''),
};

sandbox.replace(
vscode.window,
'createWebviewPanel',
sandbox.fake.returns({
webview: fakeWebview,
})
);

const testWebviewController = new WebviewController({
connectionController: testConnectionController,
storageController: testStorageController,
telemetryService: testTelemetryService,
});

void testWebviewController.openWebview(
mdbTestExtension.extensionContextStub
);

// Mock a connection status request call.
messageReceived({
command: MESSAGE_TYPES.GET_FEATURE_FLAGS,
});
});
});
28 changes: 3 additions & 25 deletions src/views/webview-app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
import React, { useEffect, useState } from 'react';
import type { FeatureFlags } from '../../featureFlags';
import { vscode } from './vscode-api';
import {
type MESSAGE_FROM_EXTENSION_TO_WEBVIEW,
MESSAGE_TYPES,
} from './extension-app-message-constants';
import React from 'react';
import { getFeatureFlag } from '../../featureFlags';
import LegacyApp from './legacy/app-with-store';

const App: React.FC = () => {
const [featureFlags, setFeatureFlags] = useState<FeatureFlags>({
useNewConnectionForm: false,
});
useEffect(() => {
const handleFeatureFlagResponse = (event: any) => {
const message: MESSAGE_FROM_EXTENSION_TO_WEBVIEW = event.data;
if (message.command === MESSAGE_TYPES.FEATURE_FLAGS_RESULTS) {
setFeatureFlags(message.featureFlags);
}
};

window.addEventListener('message', handleFeatureFlagResponse);
vscode.postMessage({ command: MESSAGE_TYPES.GET_FEATURE_FLAGS });
return () =>
window.removeEventListener('message', handleFeatureFlagResponse);
}, []);

return featureFlags.useNewConnectionForm ? (
return getFeatureFlag('useNewConnectionForm') ? (
<>Silence is golden</>
) : (
<LegacyApp />
Expand Down
18 changes: 2 additions & 16 deletions src/views/webview-app/extension-app-message-constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { FeatureFlags } from '../../featureFlags';
import type LegacyConnectionModel from './legacy/connection-model/legacy-connection-model';
import type { FilePickerActionTypes } from './legacy/store/actions';

Expand All @@ -25,8 +24,6 @@ export enum MESSAGE_TYPES {
OPEN_FILE_PICKER = 'OPEN_FILE_PICKER',
OPEN_TRUSTED_LINK = 'OPEN_TRUSTED_LINK',
RENAME_ACTIVE_CONNECTION = 'RENAME_ACTIVE_CONNECTION',
GET_FEATURE_FLAGS = 'GET_FEATURE_FLAGS',
FEATURE_FLAGS_RESULTS = 'FEATURE_FLAGS_RESULTS',
}

interface BasicWebviewMessage {
Expand Down Expand Up @@ -92,15 +89,6 @@ export interface RenameConnectionMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.RENAME_ACTIVE_CONNECTION;
}

export interface GetFeatureFlagsMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.GET_FEATURE_FLAGS;
}

export interface FeatureFlagsResultsMessage extends BasicWebviewMessage {
command: MESSAGE_TYPES.FEATURE_FLAGS_RESULTS;
featureFlags: FeatureFlags;
}

export type MESSAGE_FROM_WEBVIEW_TO_EXTENSION =
| ConnectMessage
| CreateNewPlaygroundMessage
Expand All @@ -109,11 +97,9 @@ export type MESSAGE_FROM_WEBVIEW_TO_EXTENSION =
| OpenConnectionStringInputMessage
| OpenFilePickerMessage
| OpenTrustedLinkMessage
| RenameConnectionMessage
| GetFeatureFlagsMessage;
| RenameConnectionMessage;

export type MESSAGE_FROM_EXTENSION_TO_WEBVIEW =
| ConnectResultsMessage
| FilePickerResultsMessage
| ConnectionStatusMessage
| FeatureFlagsResultsMessage;
| ConnectionStatusMessage;
9 changes: 2 additions & 7 deletions src/views/webviewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
import { openLink } from '../utils/linkHelper';
import type { StorageController } from '../storage';
import type TelemetryService from '../telemetry/telemetryService';
import { getFeatureFlags } from '../featureFlags';
import { getFeatureFlagsScript } from '../featureFlags';

const log = createLogger('webview controller');

Expand Down Expand Up @@ -74,6 +74,7 @@ export const getWebviewContent = ({
</head>
<body>
<div id="root"></div>
${getFeatureFlagsScript(nonce)}
<script nonce="${nonce}">window['${VSCODE_EXTENSION_SEGMENT_ANONYMOUS_ID}'] = '${telemetryUserId}';</script>
<script nonce="${nonce}" src="${jsAppFileUrl}"></script>
</body>
Expand Down Expand Up @@ -213,12 +214,6 @@ export default class WebviewController {
);
}
return;
case MESSAGE_TYPES.GET_FEATURE_FLAGS:
void panel.webview.postMessage({
command: MESSAGE_TYPES.FEATURE_FLAGS_RESULTS,
featureFlags: getFeatureFlags(),
});
return;
default:
// no-op.
return;
Expand Down

0 comments on commit 65130dd

Please sign in to comment.