|
3 | 3 |
|
4 | 4 | 'use strict'; |
5 | 5 |
|
6 | | -import { expect } from 'chai'; |
| 6 | +import { assert, expect } from 'chai'; |
| 7 | +import * as sinon from 'sinon'; |
7 | 8 | import { anything, instance, mock, verify, when } from 'ts-mockito'; |
8 | 9 | import * as TypeMoq from 'typemoq'; |
9 | 10 | import { ExtensionSurveyPrompt, extensionSurveyStateKeys } from '../../client/activation/extensionSurvey'; |
10 | 11 | import { IApplicationShell } from '../../client/common/application/types'; |
11 | 12 | import { PersistentStateFactory } from '../../client/common/persistentState'; |
12 | 13 | import { IBrowserService, IPersistentState, IPersistentStateFactory, IRandom } from '../../client/common/types'; |
| 14 | +import { createDeferred } from '../../client/common/utils/async'; |
| 15 | +import { Common, ExtensionSurveyBanner, LanguageService } from '../../client/common/utils/localize'; |
| 16 | +import { sleep } from '../core'; |
13 | 17 |
|
14 | 18 | // tslint:disable:no-any |
15 | 19 |
|
16 | 20 | // tslint:disable-next-line:max-func-body-length |
17 | | -suite('xExtension survey prompt - shouldShowBanner()', () => { |
| 21 | +suite('Extension survey prompt - shouldShowBanner()', () => { |
18 | 22 | let appShell: TypeMoq.IMock<IApplicationShell>; |
19 | 23 | let browserService: TypeMoq.IMock<IBrowserService>; |
20 | 24 | let random: TypeMoq.IMock<IRandom>; |
@@ -137,3 +141,192 @@ suite('xExtension survey prompt - shouldShowBanner()', () => { |
137 | 141 | random.verifyAll(); |
138 | 142 | }); |
139 | 143 | }); |
| 144 | + |
| 145 | +// tslint:disable-next-line: max-func-body-length |
| 146 | +suite('Extension survey prompt - showSurvey()', () => { |
| 147 | + let appShell: TypeMoq.IMock<IApplicationShell>; |
| 148 | + let browserService: TypeMoq.IMock<IBrowserService>; |
| 149 | + let random: TypeMoq.IMock<IRandom>; |
| 150 | + let persistentStateFactory: IPersistentStateFactory; |
| 151 | + let disableSurveyForTime: TypeMoq.IMock<IPersistentState<any>>; |
| 152 | + let doNotShowAgain: TypeMoq.IMock<IPersistentState<any>>; |
| 153 | + let extensionSurveyPrompt: ExtensionSurveyPrompt; |
| 154 | + setup(() => { |
| 155 | + appShell = TypeMoq.Mock.ofType<IApplicationShell>(); |
| 156 | + browserService = TypeMoq.Mock.ofType<IBrowserService>(); |
| 157 | + random = TypeMoq.Mock.ofType<IRandom>(); |
| 158 | + persistentStateFactory = mock(PersistentStateFactory); |
| 159 | + disableSurveyForTime = TypeMoq.Mock.ofType<IPersistentState<any>>(); |
| 160 | + doNotShowAgain = TypeMoq.Mock.ofType<IPersistentState<any>>(); |
| 161 | + when(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.disableSurveyForTime, false, anything())).thenReturn(disableSurveyForTime.object); |
| 162 | + when(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false)).thenReturn(doNotShowAgain.object); |
| 163 | + extensionSurveyPrompt = new ExtensionSurveyPrompt(appShell.object, browserService.object, instance(persistentStateFactory), random.object, 10); |
| 164 | + }); |
| 165 | + |
| 166 | + test('Launch survey if \'Yes\' option is clicked', async () => { |
| 167 | + const prompts = [LanguageService.bannerLabelYes(), ExtensionSurveyBanner.maybeLater(), Common.doNotShowAgain()]; |
| 168 | + appShell |
| 169 | + .setup(a => a.showInformationMessage(ExtensionSurveyBanner.bannerMessage(), ...prompts)) |
| 170 | + .returns(() => Promise.resolve(LanguageService.bannerLabelYes())) |
| 171 | + .verifiable(TypeMoq.Times.once()); |
| 172 | + browserService |
| 173 | + .setup(s => s.launch(TypeMoq.It.isAny())) |
| 174 | + .returns(() => Promise.resolve()) |
| 175 | + .verifiable(TypeMoq.Times.once()); |
| 176 | + disableSurveyForTime |
| 177 | + .setup(d => d.updateValue(true)) |
| 178 | + .returns(() => Promise.resolve()) |
| 179 | + .verifiable(TypeMoq.Times.once()); |
| 180 | + doNotShowAgain |
| 181 | + .setup(d => d.updateValue(true)) |
| 182 | + .returns(() => Promise.resolve()) |
| 183 | + .verifiable(TypeMoq.Times.never()); |
| 184 | + await extensionSurveyPrompt.showSurvey(); |
| 185 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.disableSurveyForTime, false, anything())).once(); |
| 186 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false)).never(); |
| 187 | + appShell.verifyAll(); |
| 188 | + browserService.verifyAll(); |
| 189 | + disableSurveyForTime.verifyAll(); |
| 190 | + doNotShowAgain.verifyAll(); |
| 191 | + }); |
| 192 | + |
| 193 | + test('Do nothing if \'Maybe later\' option is clicked', async () => { |
| 194 | + const prompts = [LanguageService.bannerLabelYes(), ExtensionSurveyBanner.maybeLater(), Common.doNotShowAgain()]; |
| 195 | + appShell |
| 196 | + .setup(a => a.showInformationMessage(ExtensionSurveyBanner.bannerMessage(), ...prompts)) |
| 197 | + .returns(() => Promise.resolve(ExtensionSurveyBanner.maybeLater())) |
| 198 | + .verifiable(TypeMoq.Times.once()); |
| 199 | + browserService |
| 200 | + .setup(s => s.launch(TypeMoq.It.isAny())) |
| 201 | + .returns(() => Promise.resolve()) |
| 202 | + .verifiable(TypeMoq.Times.never()); |
| 203 | + disableSurveyForTime |
| 204 | + .setup(d => d.updateValue(true)) |
| 205 | + .returns(() => Promise.resolve()) |
| 206 | + .verifiable(TypeMoq.Times.never()); |
| 207 | + doNotShowAgain |
| 208 | + .setup(d => d.updateValue(true)) |
| 209 | + .returns(() => Promise.resolve()) |
| 210 | + .verifiable(TypeMoq.Times.never()); |
| 211 | + await extensionSurveyPrompt.showSurvey(); |
| 212 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.disableSurveyForTime, false, anything())).never(); |
| 213 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false)).never(); |
| 214 | + appShell.verifyAll(); |
| 215 | + browserService.verifyAll(); |
| 216 | + disableSurveyForTime.verifyAll(); |
| 217 | + doNotShowAgain.verifyAll(); |
| 218 | + }); |
| 219 | + |
| 220 | + test('Do nothing if no option is clicked', async () => { |
| 221 | + const prompts = [LanguageService.bannerLabelYes(), ExtensionSurveyBanner.maybeLater(), Common.doNotShowAgain()]; |
| 222 | + appShell |
| 223 | + .setup(a => a.showInformationMessage(ExtensionSurveyBanner.bannerMessage(), ...prompts)) |
| 224 | + .returns(() => Promise.resolve(undefined)) |
| 225 | + .verifiable(TypeMoq.Times.once()); |
| 226 | + browserService |
| 227 | + .setup(s => s.launch(TypeMoq.It.isAny())) |
| 228 | + .returns(() => Promise.resolve()) |
| 229 | + .verifiable(TypeMoq.Times.never()); |
| 230 | + disableSurveyForTime |
| 231 | + .setup(d => d.updateValue(true)) |
| 232 | + .returns(() => Promise.resolve()) |
| 233 | + .verifiable(TypeMoq.Times.never()); |
| 234 | + doNotShowAgain |
| 235 | + .setup(d => d.updateValue(true)) |
| 236 | + .returns(() => Promise.resolve()) |
| 237 | + .verifiable(TypeMoq.Times.never()); |
| 238 | + await extensionSurveyPrompt.showSurvey(); |
| 239 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.disableSurveyForTime, false, anything())).never(); |
| 240 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false)).never(); |
| 241 | + appShell.verifyAll(); |
| 242 | + browserService.verifyAll(); |
| 243 | + disableSurveyForTime.verifyAll(); |
| 244 | + doNotShowAgain.verifyAll(); |
| 245 | + }); |
| 246 | + |
| 247 | + test('Disable prompt if \'Do not show again\' option is clicked', async () => { |
| 248 | + const prompts = [LanguageService.bannerLabelYes(), ExtensionSurveyBanner.maybeLater(), Common.doNotShowAgain()]; |
| 249 | + appShell |
| 250 | + .setup(a => a.showInformationMessage(ExtensionSurveyBanner.bannerMessage(), ...prompts)) |
| 251 | + .returns(() => Promise.resolve(Common.doNotShowAgain())) |
| 252 | + .verifiable(TypeMoq.Times.once()); |
| 253 | + browserService |
| 254 | + .setup(s => s.launch(TypeMoq.It.isAny())) |
| 255 | + .returns(() => Promise.resolve()) |
| 256 | + .verifiable(TypeMoq.Times.never()); |
| 257 | + disableSurveyForTime |
| 258 | + .setup(d => d.updateValue(true)) |
| 259 | + .returns(() => Promise.resolve()) |
| 260 | + .verifiable(TypeMoq.Times.never()); |
| 261 | + doNotShowAgain |
| 262 | + .setup(d => d.updateValue(true)) |
| 263 | + .returns(() => Promise.resolve()) |
| 264 | + .verifiable(TypeMoq.Times.once()); |
| 265 | + await extensionSurveyPrompt.showSurvey(); |
| 266 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.disableSurveyForTime, false, anything())).never(); |
| 267 | + verify(persistentStateFactory.createGlobalPersistentState(extensionSurveyStateKeys.doNotShowAgain, false)).once(); |
| 268 | + appShell.verifyAll(); |
| 269 | + browserService.verifyAll(); |
| 270 | + disableSurveyForTime.verifyAll(); |
| 271 | + doNotShowAgain.verifyAll(); |
| 272 | + }); |
| 273 | +}); |
| 274 | + |
| 275 | +// tslint:disable-next-line: max-func-body-length |
| 276 | +suite('Extension survey prompt - activate()', () => { |
| 277 | + let appShell: TypeMoq.IMock<IApplicationShell>; |
| 278 | + let browserService: TypeMoq.IMock<IBrowserService>; |
| 279 | + let random: TypeMoq.IMock<IRandom>; |
| 280 | + let persistentStateFactory: IPersistentStateFactory; |
| 281 | + let shouldShowBanner: sinon.SinonStub<any>; |
| 282 | + let showSurvey: sinon.SinonStub<any>; |
| 283 | + let extensionSurveyPrompt: ExtensionSurveyPrompt; |
| 284 | + setup(() => { |
| 285 | + appShell = TypeMoq.Mock.ofType<IApplicationShell>(); |
| 286 | + browserService = TypeMoq.Mock.ofType<IBrowserService>(); |
| 287 | + random = TypeMoq.Mock.ofType<IRandom>(); |
| 288 | + persistentStateFactory = mock(PersistentStateFactory); |
| 289 | + }); |
| 290 | + |
| 291 | + teardown(() => { |
| 292 | + sinon.restore(); |
| 293 | + }); |
| 294 | + |
| 295 | + test('No survey is shown if shouldShowBanner() returns false', async () => { |
| 296 | + const deferred = createDeferred<true>(); |
| 297 | + shouldShowBanner = sinon.stub(ExtensionSurveyPrompt.prototype, 'shouldShowBanner'); |
| 298 | + shouldShowBanner.callsFake(() => false); |
| 299 | + showSurvey = sinon.stub(ExtensionSurveyPrompt.prototype, 'showSurvey'); |
| 300 | + showSurvey.callsFake(() => { |
| 301 | + deferred.resolve(true); |
| 302 | + return Promise.resolve(); |
| 303 | + }); |
| 304 | + // waitTimeToShowSurvey = 50 ms |
| 305 | + extensionSurveyPrompt = new ExtensionSurveyPrompt(appShell.object, browserService.object, instance(persistentStateFactory), random.object, 10, 50); |
| 306 | + await extensionSurveyPrompt.activate(); |
| 307 | + assert.ok(shouldShowBanner.calledOnce); |
| 308 | + |
| 309 | + const doesSurveyShowUp = await Promise.race([deferred.promise, sleep(100).then(() => false)]); |
| 310 | + assert.ok(showSurvey.notCalled); |
| 311 | + expect(doesSurveyShowUp).to.equal(false, 'Survey should not appear'); |
| 312 | + }); |
| 313 | + |
| 314 | + test('Survey is shown after waitTimeToShowSurvey if shouldShowBanner() returns true', async () => { |
| 315 | + const deferred = createDeferred<true>(); |
| 316 | + shouldShowBanner = sinon.stub(ExtensionSurveyPrompt.prototype, 'shouldShowBanner'); |
| 317 | + shouldShowBanner.callsFake(() => true); |
| 318 | + showSurvey = sinon.stub(ExtensionSurveyPrompt.prototype, 'showSurvey'); |
| 319 | + showSurvey.callsFake(() => { |
| 320 | + deferred.resolve(true); |
| 321 | + return Promise.resolve(); |
| 322 | + }); |
| 323 | + // waitTimeToShowSurvey = 50 ms |
| 324 | + extensionSurveyPrompt = new ExtensionSurveyPrompt(appShell.object, browserService.object, instance(persistentStateFactory), random.object, 10, 50); |
| 325 | + await extensionSurveyPrompt.activate(); |
| 326 | + assert.ok(shouldShowBanner.calledOnce); |
| 327 | + |
| 328 | + const doesSurveyShowUp = await Promise.race([deferred.promise, sleep(200).then(() => false)]); |
| 329 | + expect(doesSurveyShowUp).to.equal(true, 'Survey should appear'); |
| 330 | + assert.ok(showSurvey.calledOnce); |
| 331 | + }); |
| 332 | +}); |
0 commit comments