diff --git a/src/mdbExtensionController.ts b/src/mdbExtensionController.ts index 791d85287..78b9cb741 100644 --- a/src/mdbExtensionController.ts +++ b/src/mdbExtensionController.ts @@ -150,6 +150,7 @@ export default class MDBExtensionController implements vscode.Disposable { this.registerCommands(); this.showOverviewPageIfRecentlyInstalled(); + void this.showSurveyForEstablishedUsers(); } registerCommands = (): void => { @@ -815,6 +816,44 @@ export default class MDBExtensionController implements vscode.Disposable { } } + async showSurveyForEstablishedUsers(): Promise { + const surveyId = '9viN9wcbsC3zvHyg7'; + + const hasBeenShownSurveyAlready = + this._storageController.get(StorageVariables.GLOBAL_SURVEY_SHOWN) === + surveyId; + + // Show the overview page when it hasn't been show to the + // user yet, and they have saved connections + // -> they haven't just started using this extension + if ( + hasBeenShownSurveyAlready || + !this._connectionStorage.hasSavedConnections() + ) { + return; + } + + const action = 'Share your thoughts'; + const text = 'How can we make the MongoDB extension better for you?'; + const link = 'https://forms.gle/9viN9wcbsC3zvHyg7'; + const result = await vscode.window.showInformationMessage( + text, + {}, + { + title: action, + } + ); + if (result?.title === action) { + void vscode.env.openExternal(vscode.Uri.parse(link)); + } + + // whether action was taken or the prompt dismissed, we won't show this again + void this._storageController.update( + StorageVariables.GLOBAL_SURVEY_SHOWN, + surveyId + ); + } + async dispose(): Promise { await this.deactivate(); } diff --git a/src/storage/storageController.ts b/src/storage/storageController.ts index 3ae1a71ec..0148208b9 100644 --- a/src/storage/storageController.ts +++ b/src/storage/storageController.ts @@ -6,6 +6,7 @@ import type { StoreConnectionInfo } from './connectionStorage'; export enum StorageVariables { // Only exists on globalState. GLOBAL_HAS_BEEN_SHOWN_INITIAL_VIEW = 'GLOBAL_HAS_BEEN_SHOWN_INITIAL_VIEW', + GLOBAL_SURVEY_SHOWN = 'GLOBAL_SURVEY_SHOWN', GLOBAL_SAVED_CONNECTIONS = 'GLOBAL_SAVED_CONNECTIONS', // Analytics user identify. GLOBAL_USER_ID = 'GLOBAL_USER_ID', @@ -50,6 +51,7 @@ interface StorageVariableContents { [StorageVariables.GLOBAL_USER_ID]: string; [StorageVariables.GLOBAL_ANONYMOUS_ID]: string; [StorageVariables.GLOBAL_HAS_BEEN_SHOWN_INITIAL_VIEW]: boolean; + [StorageVariables.GLOBAL_SURVEY_SHOWN]: string; [StorageVariables.GLOBAL_SAVED_CONNECTIONS]: ConnectionsFromStorage; [StorageVariables.WORKSPACE_SAVED_CONNECTIONS]: ConnectionsFromStorage; } diff --git a/src/test/suite/mdbExtensionController.test.ts b/src/test/suite/mdbExtensionController.test.ts index 9fc872a19..e887485b9 100644 --- a/src/test/suite/mdbExtensionController.test.ts +++ b/src/test/suite/mdbExtensionController.test.ts @@ -175,6 +175,7 @@ suite('MDBExtensionController Test Suite', function () { let fakeActiveConnectionId: SinonSpy; let showErrorMessageStub: SinonStub; let fakeCreatePlaygroundFileWithContent: SinonSpy; + let openExternalStub: SinonStub; const sandbox = sinon.createSandbox(); @@ -183,6 +184,7 @@ suite('MDBExtensionController Test Suite', function () { vscode.window, 'showInformationMessage' ); + openExternalStub = sandbox.stub(vscode.env, 'openExternal'); openTextDocumentStub = sandbox.stub(vscode.workspace, 'openTextDocument'); fakeActiveConnectionId = sandbox.fake.returns('tasty_sandwhich'); sandbox.replace( @@ -1717,5 +1719,138 @@ suite('MDBExtensionController Test Suite', function () { }); }); }); + + suite('survey prompt', function () { + suite( + "when a user hasn't been shown the survey prompt yet, and they have connections saved", + () => { + [ + { + description: 'clicked the button', + value: { title: 'Share your thoughts' }, + }, + { description: 'dismissed', value: undefined }, + ].forEach((reaction) => { + suite(`user ${reaction.description}`, () => { + let connectionsUpdateStub: SinonStub; + let uriParseStub: SinonStub; + beforeEach(async () => { + showInformationMessageStub.resolves(reaction.value); + openExternalStub.resolves(undefined); + sandbox.replace( + mdbTestExtension.testExtensionController._storageController, + 'get', + sandbox.fake.returns(undefined) + ); + sandbox.replace( + mdbTestExtension.testExtensionController._connectionStorage, + 'hasSavedConnections', + sandbox.fake.returns(true) + ); + connectionsUpdateStub = sandbox.stub( + mdbTestExtension.testExtensionController._storageController, + 'update' + ); + uriParseStub = sandbox.stub(vscode.Uri, 'parse'); + connectionsUpdateStub.resolves(undefined); + await mdbTestExtension.testExtensionController.showSurveyForEstablishedUsers(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + test('they are shown the survey prompt', () => { + assert(showInformationMessageStub.called); + assert.strictEqual( + showInformationMessageStub.firstCall.args[0], + 'How can we make the MongoDB extension better for you?' + ); + }); + + test('the link was open if and only if they click the button', () => { + if (reaction.value === undefined) { + assert(openExternalStub.notCalled); + } + if (reaction.value) { + assert(openExternalStub.called); + assert(uriParseStub.called); + assert.strictEqual( + uriParseStub.firstCall.args[0], + 'https://forms.gle/9viN9wcbsC3zvHyg7' + ); + } + }); + + test("it sets that they've been shown the survey", () => { + assert(connectionsUpdateStub.called); + assert.strictEqual( + connectionsUpdateStub.firstCall.args[0], + StorageVariables.GLOBAL_SURVEY_SHOWN + ); + assert.strictEqual( + connectionsUpdateStub.firstCall.args[1], + '9viN9wcbsC3zvHyg7' + ); + }); + }); + }); + } + ); + + suite('when a user has been shown the survey prompt already', () => { + let connectionsUpdateStub: SinonStub; + beforeEach(() => { + sandbox.replace( + mdbTestExtension.testExtensionController._storageController, + 'get', + sandbox.fake.returns('9viN9wcbsC3zvHyg7') // survey has been shown + ); + sandbox.replace( + mdbTestExtension.testExtensionController._connectionStorage, + 'hasSavedConnections', + sandbox.fake.returns(true) + ); + connectionsUpdateStub = sandbox.stub( + mdbTestExtension.testExtensionController._storageController, + 'update' + ); + connectionsUpdateStub.resolves(undefined); + + void mdbTestExtension.testExtensionController.showSurveyForEstablishedUsers(); + }); + + test('they are not shown the survey prompt', () => { + assert(showInformationMessageStub.notCalled); + }); + }); + + suite('when a has no connections saved', () => { + let connectionsUpdateStub: SinonStub; + beforeEach(() => { + sandbox.replace( + mdbTestExtension.testExtensionController._storageController, + 'get', + sandbox.fake.returns(undefined) + ); + sandbox.replace( + mdbTestExtension.testExtensionController._connectionStorage, + 'hasSavedConnections', + sandbox.fake.returns(false) // no connections yet - this might be the first install + ); + connectionsUpdateStub = sandbox.stub( + mdbTestExtension.testExtensionController._storageController, + 'update' + ); + connectionsUpdateStub.resolves(undefined); + + void mdbTestExtension.testExtensionController.showSurveyForEstablishedUsers(); + }); + + test('they are not shown the survey prompt', () => { + assert(showInformationMessageStub.notCalled); + }); + }); + }); }); });