| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // TODO(robliao,vadimt): Determine the granularity of testing to perform. |
| |
| /** |
| * Test fixture for background.js. |
| * @constructor |
| * @extends {testing.Test} |
| */ |
| function GoogleNowBackgroundUnitTest () { |
| testing.Test.call(this); |
| } |
| |
| GoogleNowBackgroundUnitTest.prototype = { |
| __proto__: testing.Test.prototype, |
| |
| /** @override */ |
| extraLibraries: [ |
| 'common_test_util.js', |
| 'background_test_util.js', |
| 'background.js' |
| ] |
| }; |
| |
| var TEST_NAME = 'GoogleNowBackgroundUnitTest'; |
| |
| /** |
| * Tasks Conflict Test |
| */ |
| TEST_F(TEST_NAME, 'AreTasksConflicting', function() { |
| function testTaskPair(newTaskName, scheduledTaskName, expected) { |
| assertTrue(areTasksConflicting(newTaskName, scheduledTaskName) == expected, |
| '(' + newTaskName + ', ' + scheduledTaskName + ')'); |
| } |
| |
| testTaskPair(UPDATE_CARDS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true); |
| testTaskPair(UPDATE_CARDS_TASK_NAME, DISMISS_CARD_TASK_NAME, false); |
| testTaskPair(UPDATE_CARDS_TASK_NAME, RETRY_DISMISS_TASK_NAME, false); |
| testTaskPair(UPDATE_CARDS_TASK_NAME, STATE_CHANGED_TASK_NAME, false); |
| |
| testTaskPair(DISMISS_CARD_TASK_NAME, UPDATE_CARDS_TASK_NAME, false); |
| testTaskPair(DISMISS_CARD_TASK_NAME, DISMISS_CARD_TASK_NAME, false); |
| testTaskPair(DISMISS_CARD_TASK_NAME, RETRY_DISMISS_TASK_NAME, false); |
| testTaskPair(DISMISS_CARD_TASK_NAME, STATE_CHANGED_TASK_NAME, false); |
| |
| testTaskPair(RETRY_DISMISS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true); |
| testTaskPair(RETRY_DISMISS_TASK_NAME, DISMISS_CARD_TASK_NAME, true); |
| testTaskPair(RETRY_DISMISS_TASK_NAME, RETRY_DISMISS_TASK_NAME, true); |
| testTaskPair(RETRY_DISMISS_TASK_NAME, STATE_CHANGED_TASK_NAME, false); |
| |
| testTaskPair(STATE_CHANGED_TASK_NAME, UPDATE_CARDS_TASK_NAME, false); |
| testTaskPair(STATE_CHANGED_TASK_NAME, DISMISS_CARD_TASK_NAME, false); |
| testTaskPair(STATE_CHANGED_TASK_NAME, RETRY_DISMISS_TASK_NAME, false); |
| testTaskPair(STATE_CHANGED_TASK_NAME, STATE_CHANGED_TASK_NAME, false); |
| }); |
| |
| /** |
| * Server Request Tests |
| */ |
| TEST_F(TEST_NAME, 'AuthServerRequestSuccess', function() { |
| expectServerRequests(this, 200, '{}'); |
| var callbackCalled = false; |
| requestFromServer('GET', 'test/target').then(function(request) { |
| callbackCalled = true; |
| assertTrue(request.status === 200); |
| assertTrue(request.responseText === '{}'); |
| }); |
| assertTrue(callbackCalled); |
| }); |
| |
| TEST_F(TEST_NAME, 'AuthServerRequestForbidden', function() { |
| this.makeAndRegisterMockApis(['authenticationManager.removeToken']); |
| this.mockApis.expects(once()).authenticationManager_removeToken(ANYTHING); |
| |
| expectServerRequests(this, 403, ''); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestFromServer('GET', 'test/target').then(function(request) { |
| thenCalled = true; |
| }).catch(function(request) { |
| // The promise is rejected on HTTP failures. |
| catchCalled = true; |
| assertTrue(request.status === 403); |
| }); |
| assertFalse(thenCalled); |
| assertTrue(catchCalled); |
| }); |
| |
| TEST_F(TEST_NAME, 'AuthServerRequestNoAuth', function() { |
| this.makeAndRegisterMockApis(['authenticationManager.removeToken']); |
| this.mockApis.expects(once()).authenticationManager_removeToken(ANYTHING); |
| |
| expectServerRequests(this, 401, ''); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestFromServer('GET', 'test/target').then(function(request) { |
| thenCalled = true; |
| }).catch(function(request) { |
| // The promise is rejected on HTTP failures. |
| catchCalled = true; |
| assertTrue(request.status === 401); |
| }); |
| assertFalse(thenCalled); |
| assertTrue(catchCalled); |
| }); |
| |
| function expectServerRequests(fixture, httpStatus, responseText) { |
| fixture.makeAndRegisterMockApis([ |
| 'authenticationManager.getAuthToken', |
| 'buildServerRequest' |
| ]); |
| |
| function XMLHttpRequest() {} |
| |
| XMLHttpRequest.prototype = { |
| addEventListener: function(type, listener, wantsUntrusted) {}, |
| setRequestHeader: function(header, value) {}, |
| send: function() {} |
| } |
| |
| fixture.mockApis.expects(once()).authenticationManager_getAuthToken() |
| .will(returnValue(Promise.resolve('token'))); |
| |
| var mockXMLHttpRequest = mock(XMLHttpRequest); |
| var mockXMLHttpRequestProxy = mockXMLHttpRequest.proxy(); |
| fixture.mockApis.expects(once()) |
| .buildServerRequest(ANYTHING, ANYTHING, ANYTHING) |
| .will(returnValue(mockXMLHttpRequestProxy)); |
| |
| mockXMLHttpRequest.expects(once()) |
| .setRequestHeader('Authorization', 'Bearer token'); |
| |
| var loadEndSavedArgs = new SaveMockArguments(); |
| mockXMLHttpRequest.expects(once()) |
| .addEventListener( |
| loadEndSavedArgs.match(eq('loadend')), |
| loadEndSavedArgs.match(ANYTHING), |
| loadEndSavedArgs.match(eq(false))); |
| |
| mockXMLHttpRequestProxy.status = httpStatus; |
| mockXMLHttpRequestProxy.response = responseText; |
| mockXMLHttpRequestProxy.responseText = responseText; |
| |
| mockXMLHttpRequest.expects(once()).send() |
| .will(invokeCallback(loadEndSavedArgs, 1, mockXMLHttpRequestProxy)); |
| } |
| |
| TEST_F(TEST_NAME, 'AuthServerRequestNoToken', function() { |
| this.makeAndRegisterMockApis([ |
| 'authenticationManager.getAuthToken', |
| 'buildServerRequest' |
| ]); |
| |
| this.mockApis.expects(once()).authenticationManager_getAuthToken() |
| .will(returnValue(Promise.reject())); |
| this.mockApis.expects(never()).buildServerRequest() |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestFromServer('GET', 'test/target').then(function(request) { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertFalse(thenCalled); |
| assertTrue(catchCalled); |
| }) |
| |
| /** |
| * requestNotificationGroupsFromServer Tests |
| */ |
| TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerEmpty', function() { |
| this.makeAndRegisterMockGlobals([ |
| 'shouldShowExplanatoryCard', |
| 'recordEvent', |
| 'requestFromServer' |
| ]); |
| |
| this.mockGlobals.expects(once()).shouldShowExplanatoryCard() |
| .will(returnValue(false)); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); |
| |
| var requestFromServerArgs = new SaveMockArguments(); |
| this.mockGlobals.expects(once()).requestFromServer( |
| requestFromServerArgs.match(eq('GET')), |
| requestFromServerArgs.match(ANYTHING)) |
| .will(returnValue( |
| Promise.resolve({status: 200, responseText: "{}"}))); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestNotificationGroupsFromServer([]).then(function() { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertTrue(thenCalled); |
| assertFalse(catchCalled); |
| |
| var pathAndQuery = requestFromServerArgs.arguments[1]; |
| var query = pathAndQuery.split('?')[1]; |
| assertTrue(query.search('timeZoneOffsetMs') >= 0); |
| assertTrue(query.search('uiLocale') >= 0); |
| assertFalse(query.search('cardExplanation') >= 0); |
| }); |
| |
| TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerWithGroups', function() { |
| this.makeAndRegisterMockGlobals([ |
| 'shouldShowExplanatoryCard', |
| 'recordEvent', |
| 'requestFromServer' |
| ]); |
| |
| this.mockGlobals.expects(once()).shouldShowExplanatoryCard() |
| .will(returnValue(false)); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); |
| |
| var requestFromServerArgs = new SaveMockArguments(); |
| this.mockGlobals.expects(once()).requestFromServer( |
| requestFromServerArgs.match(eq('GET')), |
| requestFromServerArgs.match(ANYTHING)) |
| .will(returnValue( |
| Promise.resolve({status: 200, responseText: "{}"}))); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestNotificationGroupsFromServer(['A', 'B', 'C']).then(function() { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertTrue(thenCalled); |
| assertFalse(catchCalled); |
| |
| var pathAndQuery = requestFromServerArgs.arguments[1]; |
| var query = pathAndQuery.split('?')[1]; |
| assertTrue(query.search('timeZoneOffsetMs') >= 0); |
| assertTrue(query.search('uiLocale') >= 0); |
| assertFalse(query.search('cardExplanation') >= 0); |
| assertTrue(query.search('requestTypes=A') >= 0); |
| assertTrue(query.search('requestTypes=B') >= 0); |
| assertTrue(query.search('requestTypes=C') >= 0); |
| }); |
| |
| TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerExplanatory', function() { |
| this.makeAndRegisterMockGlobals([ |
| 'shouldShowExplanatoryCard', |
| 'recordEvent', |
| 'requestFromServer' |
| ]); |
| |
| this.mockGlobals.expects(once()).shouldShowExplanatoryCard() |
| .will(returnValue(true)); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); |
| |
| var requestFromServerArgs = new SaveMockArguments(); |
| this.mockGlobals.expects(once()).requestFromServer( |
| requestFromServerArgs.match(eq('GET')), |
| requestFromServerArgs.match(ANYTHING)) |
| .will(returnValue( |
| Promise.resolve({status: 200, responseText: "{}"}))); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestNotificationGroupsFromServer([]).then(function() { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertTrue(thenCalled); |
| assertFalse(catchCalled); |
| |
| var pathAndQuery = requestFromServerArgs.arguments[1]; |
| var query = pathAndQuery.split('?')[1]; |
| assertTrue(query.search('timeZoneOffsetMs') >= 0); |
| assertTrue(query.search('uiLocale') >= 0); |
| assertTrue(query.search('cardExplanation=true') >= 0); |
| }); |
| |
| TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerFailure', function() { |
| this.makeAndRegisterMockGlobals([ |
| 'shouldShowExplanatoryCard', |
| 'recordEvent', |
| 'requestFromServer' |
| ]); |
| |
| this.mockGlobals.expects(once()).shouldShowExplanatoryCard() |
| .will(returnValue(false)); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL); |
| |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS); |
| |
| var requestFromServerArgs = new SaveMockArguments(); |
| this.mockGlobals.expects(once()).requestFromServer( |
| requestFromServerArgs.match(eq('GET')), |
| requestFromServerArgs.match(ANYTHING)) |
| .will(returnValue( |
| Promise.reject({status: 401}))); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestNotificationGroupsFromServer([]).then(function() { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertFalse(thenCalled); |
| assertTrue(catchCalled); |
| }); |
| |
| /** |
| * requestAndUpdateOptIn Tests |
| */ |
| TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedIn', function() { |
| this.makeAndRegisterMockApis([ |
| 'chrome.storage.local.set', |
| 'requestFromServer' |
| ]); |
| |
| this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin') |
| .will(returnValue(Promise.resolve({ |
| status: 200, |
| responseText: '{"value": true}'}))); |
| |
| this.mockApis.expects(once()) |
| .chrome_storage_local_set(eqJSON({googleNowEnabled: true})); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestAndUpdateOptedIn().then(function(optedIn) { |
| thenCalled = true; |
| assertTrue(optedIn); |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertTrue(thenCalled); |
| assertFalse(catchCalled); |
| }); |
| |
| TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedOut', function() { |
| this.makeAndRegisterMockApis([ |
| 'chrome.storage.local.set', |
| 'requestFromServer' |
| ]); |
| |
| this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin') |
| .will(returnValue(Promise.resolve({ |
| status: 200, |
| responseText: '{"value": false}'}))); |
| |
| this.mockApis.expects(once()) |
| .chrome_storage_local_set(eqJSON({googleNowEnabled: false})); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestAndUpdateOptedIn().then(function(optedIn) { |
| thenCalled = true; |
| assertFalse(optedIn); |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertTrue(thenCalled); |
| assertFalse(catchCalled); |
| }); |
| |
| TEST_F(TEST_NAME, 'RequestAndUpdateOptInFailure', function() { |
| this.makeAndRegisterMockApis([ |
| 'chrome.storage.local.set', |
| 'requestFromServer' |
| ]); |
| |
| this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin') |
| .will(returnValue(Promise.reject({status: 404}))); |
| |
| this.mockApis.expects(never()).chrome_storage_local_set(); |
| |
| var thenCalled = false; |
| var catchCalled = false; |
| requestAndUpdateOptedIn().then(function() { |
| thenCalled = true; |
| }).catch(function() { |
| catchCalled = true; |
| }); |
| assertFalse(thenCalled); |
| assertTrue(catchCalled); |
| }); |
| |
| /** |
| * pollOptedInNoImmediateRecheck Tests |
| */ |
| TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedIn', function() { |
| this.makeAndRegisterMockApis([ |
| 'requestAndUpdateOptedIn', |
| 'instrumented.metricsPrivate.getVariationParams', |
| 'optInPollAttempts.start' |
| ]); |
| |
| this.mockApis.expects(once()).requestAndUpdateOptedIn() |
| .will(returnValue(Promise.resolve(true))); |
| |
| this.mockApis.expects(never()) |
| .instrumented_metricsPrivate_getVariationParams(); |
| |
| this.mockApis.expects(never()).optInPollAttempts_start(); |
| |
| pollOptedInNoImmediateRecheck(); |
| }); |
| |
| TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedOut', function() { |
| this.makeAndRegisterMockApis([ |
| 'requestAndUpdateOptedIn', |
| 'instrumented.metricsPrivate.getVariationParams', |
| 'optInPollAttempts.start' |
| ]); |
| |
| this.mockApis.expects(once()).requestAndUpdateOptedIn() |
| .will(returnValue(Promise.resolve(false))); |
| |
| var getVariationParamsSavedArgs = new SaveMockArguments(); |
| this.mockApis.expects(once()) |
| .instrumented_metricsPrivate_getVariationParams( |
| getVariationParamsSavedArgs.match(eq('GoogleNow')), |
| getVariationParamsSavedArgs.match(ANYTHING)) |
| .will(invokeCallback(getVariationParamsSavedArgs, 1, {})); |
| |
| this.mockApis.expects(once()) |
| .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS); |
| |
| pollOptedInNoImmediateRecheck(); |
| }); |
| |
| TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckFailure', function() { |
| this.makeAndRegisterMockApis([ |
| 'requestAndUpdateOptedIn', |
| 'instrumented.metricsPrivate.getVariationParams', |
| 'optInPollAttempts.start' |
| ]); |
| |
| this.mockApis.expects(once()).requestAndUpdateOptedIn() |
| .will(returnValue(Promise.reject())); |
| |
| var getVariationParamsSavedArgs = new SaveMockArguments(); |
| this.mockApis.expects(once()) |
| .instrumented_metricsPrivate_getVariationParams( |
| getVariationParamsSavedArgs.match(eq('GoogleNow')), |
| getVariationParamsSavedArgs.match(ANYTHING)) |
| .will(invokeCallback(getVariationParamsSavedArgs, 1, {})); |
| |
| this.mockApis.expects(once()) |
| .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS); |
| |
| pollOptedInNoImmediateRecheck(); |
| }); |
| |
| /** |
| * getGroupsToRequest Tests |
| */ |
| TEST_F(TEST_NAME, 'GetGroupsToRequestNone', function() { |
| this.makeAndRegisterMockApis([ |
| 'fillFromChromeLocalStorage', |
| 'Date.now' |
| ]); |
| |
| this.mockApis.expects(once()) |
| .fillFromChromeLocalStorage(eqJSON({notificationGroups: {}})) |
| .will(returnValue(Promise.resolve({notificationGroups: {}}))); |
| |
| this.mockApis.expects(once()).Date_now().will(returnValue(20)); |
| |
| getGroupsToRequest().then(function(groupsToRequest) { |
| assertTrue(JSON.stringify(groupsToRequest) === '[]'); |
| }); |
| }); |
| |
| TEST_F(TEST_NAME, 'GetGroupsToRequestWithGroups', function() { |
| this.makeAndRegisterMockApis([ |
| 'fillFromChromeLocalStorage', |
| 'Date.now' |
| ]); |
| |
| this.mockApis.expects(once()) |
| .fillFromChromeLocalStorage(eqJSON({notificationGroups: {}})) |
| .will(returnValue(Promise.resolve({notificationGroups: { |
| TIME18: {nextPollTime: 18}, |
| TIME19: {nextPollTime: 19}, |
| TIME20: {nextPollTime: 20}, |
| TIME21: {nextPollTime: 21}, |
| TIME22: {nextPollTime: 22}, |
| TIMEUNDEF: {} |
| }}))); |
| |
| this.mockApis.expects(once()).Date_now().will(returnValue(20)); |
| |
| getGroupsToRequest().then(function(groupsToRequest) { |
| assertTrue(groupsToRequest.length == 3); |
| assertTrue(groupsToRequest.indexOf('TIME18') >= 0); |
| assertTrue(groupsToRequest.indexOf('TIME19') >= 0); |
| assertTrue(groupsToRequest.indexOf('TIME20') >= 0); |
| }); |
| }); |
| |
| /** |
| * combineGroup Tests |
| */ |
| TEST_F(TEST_NAME, 'CombineGroup', function() { |
| // Tests combineGroup function. Verifies that both notifications with and |
| // without show time are handled correctly and that cards are correctly |
| // added to existing cards with same ID or start a new combined card. |
| |
| // Setup and expectations. |
| var combinedCards = { |
| 'EXISTING CARD': [1] |
| }; |
| |
| var receivedNotificationNoShowTime = { |
| chromeNotificationId: 'EXISTING CARD', |
| trigger: {hideTimeSec: 1} |
| }; |
| var receivedNotificationWithShowTime = { |
| chromeNotificationId: 'NEW CARD', |
| trigger: {showTimeSec: 2, hideTimeSec: 3} |
| } |
| |
| var storedGroup = { |
| cardsTimestamp: 10000, |
| cards: [ |
| receivedNotificationNoShowTime, |
| receivedNotificationWithShowTime |
| ] |
| }; |
| |
| // Invoking the tested function. |
| combineGroup(combinedCards, storedGroup); |
| |
| // Check the output value. |
| var expectedCombinedCards = { |
| 'EXISTING CARD': [ |
| 1, |
| { |
| receivedNotification: receivedNotificationNoShowTime, |
| hideTime: 11000 |
| } |
| ], |
| 'NEW CARD': [ |
| { |
| receivedNotification: receivedNotificationWithShowTime, |
| showTime: 12000, |
| hideTime: 13000 |
| } |
| ] |
| }; |
| |
| assertEquals( |
| JSON.stringify(expectedCombinedCards), |
| JSON.stringify(combinedCards)); |
| }); |
| |
| /** |
| * Mocks global functions and APIs that initialize() depends upon. |
| * @param {Test} fixture Test fixture. |
| */ |
| function mockInitializeDependencies(fixture) { |
| fixture.makeAndRegisterMockGlobals([ |
| 'pollOptedInNoImmediateRecheck', |
| 'recordEvent', |
| 'removeAllCards', |
| 'setBackgroundEnable', |
| 'startPollingCards', |
| 'stopPollingCards' |
| ]); |
| fixture.makeAndRegisterMockApis([ |
| 'authenticationManager.isSignedIn', |
| 'chrome.storage.local.remove', |
| 'fillFromChromeLocalStorage', |
| 'instrumented.metricsPrivate.getVariationParams', |
| 'instrumented.notifications.getAll', |
| 'instrumented.notifications.getPermissionLevel', |
| 'instrumented.webstorePrivate.getBrowserLogin', |
| 'optInPollAttempts.isRunning', |
| 'optInPollAttempts.stop', |
| 'tasks.add', |
| 'updateCardsAttempts.isRunning', |
| 'updateCardsAttempts.stop' |
| ]); |
| } |
| |
| /** |
| * Sets up the test to expect the state machine calls and send |
| * the specified state machine state. Currently used to test initialize(). |
| * Note that this CAN NOT be used if any of the methods below are called |
| * outside of this context with the same argument matchers. |
| * expects() calls cannot be chained with the same argument matchers. |
| * @param {object} fixture Test fixture. |
| * @param {string} testIdentityToken getAuthToken callback token. |
| * @param {object} testExperimentVariationParams Response of |
| * metricsPrivate.getVariationParams. |
| * @param {string} testExperimentVariationParams Response of |
| * notifications.getPermissionLevel. |
| * @param {boolean} testGoogleNowEnabled True if the user is opted in to Google |
| * Now. |
| */ |
| function expectStateMachineCalls( |
| fixture, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled) { |
| fixture.mockApis.expects(once()). |
| authenticationManager_isSignedIn(). |
| will(returnValue(new Promise(function(resolve) { |
| resolve(!!testIdentityToken); |
| }))); |
| |
| var getVariationParamsSavedArgs = new SaveMockArguments(); |
| fixture.mockApis.expects(once()). |
| instrumented_metricsPrivate_getVariationParams( |
| getVariationParamsSavedArgs.match(ANYTHING), |
| getVariationParamsSavedArgs.match(ANYTHING)). |
| will(invokeCallback( |
| getVariationParamsSavedArgs, 1, testExperimentVariationParams)); |
| |
| var notificationGetPermissionLevelSavedArgs = new SaveMockArguments(); |
| fixture.mockApis.expects(once()). |
| instrumented_notifications_getPermissionLevel( |
| notificationGetPermissionLevelSavedArgs.match(ANYTHING)). |
| will(invokeCallback( |
| notificationGetPermissionLevelSavedArgs, |
| 0, |
| testNotificationPermissionLevel)) |
| |
| expectChromeLocalStorageGet( |
| fixture, |
| {googleNowEnabled: false}, |
| {googleNowEnabled: testGoogleNowEnabled}); |
| |
| var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments(); |
| fixture.mockApis.expects(once()). |
| updateCardsAttempts_isRunning( |
| updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)). |
| will( |
| invokeCallback( |
| updateCardsAttemptsIsRunningSavedArgs, 0, undefined)); |
| |
| var optInPollAttemptsIsRunningSavedArgs = new SaveMockArguments(); |
| fixture.mockApis.expects(once()). |
| optInPollAttempts_isRunning( |
| optInPollAttemptsIsRunningSavedArgs.match(ANYTHING)). |
| will( |
| invokeCallback( |
| optInPollAttemptsIsRunningSavedArgs, 0, undefined)); |
| } |
| |
| /** |
| * Sets up the test to expect the initialization calls that |
| * initialize() invokes. |
| * Note that this CAN NOT be used if any of the methods below are called |
| * outside of this context with the same argument matchers. |
| * expects() calls cannot be chained with the same argument matchers. |
| */ |
| function expectInitialization(fixture) { |
| var tasksAddSavedArgs = new SaveMockArguments(); |
| fixture.mockApis.expects(once()). |
| tasks_add( |
| tasksAddSavedArgs.match(ANYTHING), |
| tasksAddSavedArgs.match(ANYTHING)). |
| will(invokeCallback(tasksAddSavedArgs, 1, function() {})); |
| |
| // The ordering here between stubs and expects is important. |
| // We only care about the EXTENSION_START event. The other events are covered |
| // by the NoCards tests below. Reversing the calls will cause all recordEvent |
| // calls to be unexpected. |
| fixture.mockGlobals.stubs().recordEvent(ANYTHING); |
| fixture.mockGlobals. |
| expects(once()).recordEvent(GoogleNowEvent.EXTENSION_START); |
| } |
| |
| TEST_F(TEST_NAME,'Initialize_SignedOut', function() { |
| // Tests the case when getAuthToken fails most likely because the user is |
| // not signed in. In this case, the function should quietly exit after |
| // finding out that getAuthToken fails. |
| |
| // Setup and expectations. |
| var testIdentityToken = undefined; |
| var testExperimentVariationParams = {}; |
| var testNotificationPermissionLevel = 'denied'; |
| var testGoogleNowEnabled = undefined; |
| |
| mockInitializeDependencies(this); |
| |
| expectInitialization(this); |
| |
| expectStateMachineCalls( |
| this, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled); |
| |
| this.mockGlobals.expects(once()).setBackgroundEnable(false); |
| this.mockGlobals.expects(never()).startPollingCards(); |
| this.mockGlobals.expects(once()).stopPollingCards(); |
| this.mockGlobals.expects(once()).removeAllCards(); |
| this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck(); |
| this.mockApis.expects(once()).optInPollAttempts_stop(); |
| |
| // Invoking the tested function. |
| initialize(); |
| }); |
| |
| TEST_F(TEST_NAME,'Initialize_NotificationDisabled', function() { |
| // Tests the case when Google Now is disabled in the notifications center. |
| |
| // Setup and expectations. |
| var testIdentityToken = 'some identity token'; |
| var testExperimentVariationParams = {}; |
| var testNotificationPermissionLevel = 'denied'; |
| var testGoogleNowEnabled = undefined; |
| |
| mockInitializeDependencies(this); |
| |
| expectInitialization(this); |
| |
| expectStateMachineCalls( |
| this, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled); |
| |
| this.mockGlobals.expects(once()).setBackgroundEnable(false); |
| this.mockGlobals.expects(never()).startPollingCards(); |
| this.mockGlobals.expects(once()).stopPollingCards(); |
| this.mockGlobals.expects(once()).removeAllCards(); |
| this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck(); |
| this.mockApis.expects(once()).optInPollAttempts_stop(); |
| |
| // Invoking the tested function. |
| initialize(); |
| }); |
| |
| TEST_F(TEST_NAME, 'Initialize_NoBackground', function() { |
| // Tests when the no background variation is received. |
| |
| // Setup and expectations. |
| var testIdentityToken = 'some identity token'; |
| var testExperimentVariationParams = {canEnableBackground: 'false'}; |
| var testNotificationPermissionLevel = 'granted'; |
| var testGoogleNowEnabled = true; |
| |
| mockInitializeDependencies(this); |
| |
| expectInitialization(this); |
| |
| expectStateMachineCalls( |
| this, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled); |
| |
| this.mockGlobals.expects(once()).setBackgroundEnable(false); |
| this.mockGlobals.expects(once()).startPollingCards(); |
| this.mockGlobals.expects(never()).stopPollingCards(); |
| this.mockGlobals.expects(never()).removeAllCards(); |
| this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck(); |
| this.mockApis.expects(once()).optInPollAttempts_stop(); |
| |
| // Invoking the tested function. |
| initialize(); |
| }); |
| |
| TEST_F(TEST_NAME, 'Initialize_GoogleNowDisabled', function() { |
| // Tests when the user has Google Now disabled. |
| |
| // Setup and expectations. |
| var testIdentityToken = 'some identity token'; |
| var testExperimentVariationParams = {}; |
| var testNotificationPermissionLevel = 'granted'; |
| var testGoogleNowEnabled = false; |
| |
| mockInitializeDependencies(this); |
| |
| expectInitialization(this); |
| |
| expectStateMachineCalls( |
| this, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled); |
| |
| this.mockGlobals.expects(once()).setBackgroundEnable(false); |
| this.mockGlobals.expects(never()).startPollingCards(); |
| this.mockGlobals.expects(once()).stopPollingCards(); |
| this.mockGlobals.expects(once()).removeAllCards(); |
| this.mockGlobals.expects(once()).pollOptedInNoImmediateRecheck(); |
| this.mockApis.expects(never()).optInPollAttempts_stop(); |
| |
| // Invoking the tested function. |
| initialize(); |
| }); |
| |
| TEST_F(TEST_NAME, 'Initialize_RunGoogleNow', function() { |
| // Tests if Google Now will invoke startPollingCards when all |
| // of the required state is fulfilled. |
| |
| // Setup and expectations. |
| var testIdentityToken = 'some identity token'; |
| var testExperimentVariationParams = {}; |
| var testNotificationPermissionLevel = 'granted'; |
| var testGoogleNowEnabled = true; |
| |
| mockInitializeDependencies(this); |
| |
| expectInitialization(this); |
| |
| expectStateMachineCalls( |
| this, |
| testIdentityToken, |
| testExperimentVariationParams, |
| testNotificationPermissionLevel, |
| testGoogleNowEnabled); |
| |
| this.mockGlobals.expects(once()).setBackgroundEnable(true); |
| this.mockGlobals.expects(once()).startPollingCards(); |
| this.mockGlobals.expects(never()).stopPollingCards(); |
| this.mockGlobals.expects(never()).removeAllCards(); |
| this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck(); |
| this.mockApis.expects(once()).optInPollAttempts_stop(); |
| |
| // Invoking the tested function. |
| initialize(); |
| }); |
| |
| /** |
| * No Cards Event Recording Tests |
| */ |
| TEST_F(TEST_NAME, 'NoCardsSignedOut', function() { |
| var signedIn = false; |
| var notificationEnabled = false; |
| var googleNowEnabled = false; |
| this.makeAndRegisterMockGlobals([ |
| 'recordEvent', |
| 'removeAllCards', |
| 'setBackgroundEnable', |
| 'setShouldPollCards', |
| 'setShouldPollOptInStatus']); |
| |
| this.mockGlobals.stubs().removeAllCards(); |
| this.mockGlobals.stubs().setBackgroundEnable(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollCards(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.STOPPED); |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.SIGNED_OUT); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.NOTIFICATION_DISABLED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.GOOGLE_NOW_DISABLED); |
| updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled); |
| }); |
| |
| TEST_F(TEST_NAME, 'NoCardsNotificationsDisabled', function() { |
| var signedIn = true; |
| var notificationEnabled = false; |
| var googleNowEnabled = false; |
| this.makeAndRegisterMockGlobals([ |
| 'recordEvent', |
| 'removeAllCards', |
| 'setBackgroundEnable', |
| 'setShouldPollCards', |
| 'setShouldPollOptInStatus']); |
| |
| this.mockGlobals.stubs().removeAllCards(); |
| this.mockGlobals.stubs().setBackgroundEnable(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollCards(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING); |
| |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.STOPPED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.SIGNED_OUT); |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.NOTIFICATION_DISABLED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.GOOGLE_NOW_DISABLED); |
| updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled); |
| }); |
| |
| TEST_F(TEST_NAME, 'NoCardsGoogleNowDisabled', function() { |
| var signedIn = true; |
| var notificationEnabled = true; |
| var googleNowEnabled = false; |
| this.makeAndRegisterMockGlobals([ |
| 'recordEvent', |
| 'removeAllCards', |
| 'setBackgroundEnable', |
| 'setShouldPollCards', |
| 'setShouldPollOptInStatus']); |
| |
| this.mockGlobals.stubs().removeAllCards(); |
| this.mockGlobals.stubs().setBackgroundEnable(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollCards(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING); |
| |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.STOPPED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.SIGNED_OUT); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.NOTIFICATION_DISABLED); |
| this.mockGlobals.expects(once()).recordEvent( |
| GoogleNowEvent.GOOGLE_NOW_DISABLED); |
| updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled); |
| }); |
| |
| TEST_F(TEST_NAME, 'NoCardsEverythingEnabled', function() { |
| var signedIn = true; |
| var notificationEnabled = true; |
| var googleNowEnabled = true; |
| this.makeAndRegisterMockGlobals([ |
| 'recordEvent', |
| 'removeAllCards', |
| 'setBackgroundEnable', |
| 'setShouldPollCards', |
| 'setShouldPollOptInStatus']); |
| |
| this.mockGlobals.stubs().removeAllCards(); |
| this.mockGlobals.stubs().setBackgroundEnable(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollCards(ANYTHING); |
| this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING); |
| |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.STOPPED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.SIGNED_OUT); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.NOTIFICATION_DISABLED); |
| this.mockGlobals.expects(never()).recordEvent( |
| GoogleNowEvent.GOOGLE_NOW_DISABLED); |
| updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled); |
| }); |
| |
| /** |
| * Mocks global functions and APIs that onNotificationClicked() depends upon. |
| * @param {Test} fixture Test fixture. |
| */ |
| function mockOnNotificationClickedDependencies(fixture) { |
| fixture.makeAndRegisterMockApis([ |
| 'chrome.windows.create', |
| 'chrome.windows.update', |
| 'fillFromChromeLocalStorage', |
| 'instrumented.tabs.create']); |
| } |
| |
| TEST_F(TEST_NAME, 'OnNotificationClicked_NoData', function() { |
| // Tests the case when there is no data associated with notification id. |
| // In this case, the function should do nothing. |
| |
| // Setup and expectations. |
| var testNotificationId = 'TEST_ID'; |
| var testNotificationDataRequest = {notificationsData: {}}; |
| var testNotificationData = {notificationsData: {}}; |
| |
| mockOnNotificationClickedDependencies(this); |
| this.makeMockLocalFunctions(['selector']); |
| |
| expectChromeLocalStorageGet( |
| this, testNotificationDataRequest, testNotificationData); |
| |
| // Invoking the tested function. |
| onNotificationClicked( |
| testNotificationId, this.mockLocalFunctions.functions().selector); |
| }); |
| |
| TEST_F(TEST_NAME, 'OnNotificationClicked_ActionUrlsUndefined', function() { |
| // Tests the case when the data associated with notification id is |
| // 'undefined'. |
| // In this case, the function should do nothing. |
| |
| // Setup and expectations. |
| var testActionUrls = undefined; |
| var testNotificationId = 'TEST_ID'; |
| var testNotificationDataRequest = {notificationsData: {}}; |
| var testNotificationData = { |
| notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} |
| }; |
| |
| mockOnNotificationClickedDependencies(this); |
| this.makeMockLocalFunctions(['selector']); |
| |
| expectChromeLocalStorageGet( |
| this, testNotificationDataRequest, testNotificationData); |
| |
| this.mockLocalFunctions.expects(once()) |
| .selector(eqJSON( |
| testNotificationData.notificationsData[testNotificationId])) |
| .will(returnValue(undefined)); |
| |
| // Invoking the tested function. |
| onNotificationClicked( |
| testNotificationId, this.mockLocalFunctions.functions().selector); |
| }); |
| |
| TEST_F(TEST_NAME, 'OnNotificationClicked_TabCreateSuccess', function() { |
| // Tests the selected URL is OK and crome.tabs.create suceeds. |
| |
| // Setup and expectations. |
| var testActionUrls = {testField: 'TEST VALUE'}; |
| var testNotificationId = 'TEST_ID'; |
| var testNotificationDataRequest = {notificationsData: {}}; |
| var testNotificationData = { |
| notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} |
| }; |
| var testActionUrl = 'http://testurl.com'; |
| var testCreatedTab = {windowId: 239}; |
| |
| mockOnNotificationClickedDependencies(this); |
| this.makeMockLocalFunctions(['selector']); |
| |
| expectChromeLocalStorageGet( |
| this, testNotificationDataRequest, testNotificationData); |
| this.mockLocalFunctions.expects(once()) |
| .selector(eqJSON( |
| testNotificationData.notificationsData[testNotificationId])) |
| .will(returnValue(testActionUrl)); |
| var chromeTabsCreateSavedArgs = new SaveMockArguments(); |
| this.mockApis.expects(once()). |
| instrumented_tabs_create( |
| chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})), |
| chromeTabsCreateSavedArgs.match(ANYTHING)). |
| will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab)); |
| this.mockApis.expects(once()).chrome_windows_update( |
| testCreatedTab.windowId, |
| eqJSON({focused: true})); |
| |
| // Invoking the tested function. |
| onNotificationClicked( |
| testNotificationId, this.mockLocalFunctions.functions().selector); |
| }); |
| |
| TEST_F(TEST_NAME, 'OnNotificationClicked_TabCreateFail', function() { |
| // Tests the selected URL is OK and crome.tabs.create fails. |
| // In this case, the function should invoke chrome.windows.create as a |
| // second attempt. |
| |
| // Setup and expectations. |
| var testActionUrls = {testField: 'TEST VALUE'}; |
| var testNotificationId = 'TEST_ID'; |
| var testNotificationDataRequest = {notificationsData: {}}; |
| var testNotificationData = { |
| notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} |
| }; |
| var testActionUrl = 'http://testurl.com'; |
| var testCreatedTab = undefined; // chrome.tabs.create fails |
| |
| mockOnNotificationClickedDependencies(this); |
| this.makeMockLocalFunctions(['selector']); |
| |
| expectChromeLocalStorageGet( |
| this, testNotificationDataRequest, testNotificationData); |
| this.mockLocalFunctions.expects(once()) |
| .selector(eqJSON( |
| testNotificationData.notificationsData[testNotificationId])) |
| .will(returnValue(testActionUrl)); |
| var chromeTabsCreateSavedArgs = new SaveMockArguments(); |
| this.mockApis.expects(once()). |
| instrumented_tabs_create( |
| chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})), |
| chromeTabsCreateSavedArgs.match(ANYTHING)). |
| will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab)); |
| this.mockApis.expects(once()).chrome_windows_create( |
| eqJSON({url: testActionUrl, focused: true})); |
| |
| // Invoking the tested function. |
| onNotificationClicked( |
| testNotificationId, this.mockLocalFunctions.functions().selector); |
| }); |
| |
| TEST_F(TEST_NAME, 'ShowNotificationGroups', function() { |
| // Tests showNotificationGroups function. Checks that the function properly |
| // deletes the card that didn't get an update, updates existing card and |
| // creates a new card that previously didn't exist. |
| |
| // Setup and expectations. |
| var existingNotifications = { |
| 'SHOULD BE DELETED': 'SOMETHING', |
| 'SHOULD BE KEPT': 'SOMETHING' |
| }; |
| |
| var keptCard = { |
| chromeNotificationId: 'SHOULD BE KEPT', |
| trigger: {showTimeSec: 0, hideTimeSec: 0} |
| }; |
| |
| var keptNotification = { |
| receivedNotification: keptCard, |
| showTime: 0, |
| hideTime: 0 |
| }; |
| |
| var newCard = { |
| chromeNotificationId: 'NEW CARD', |
| trigger: {showTimeSec: 0, hideTimeSec: 0} |
| }; |
| |
| var newNotification = { |
| receivedNotification: newCard, |
| showTime: 0, |
| hideTime: 0 |
| }; |
| |
| var notificationGroups = { |
| 'TEST GROUP 1': {cards: [keptCard], cardsTimestamp: 0}, |
| 'TEST GROUP 2': {cards: [newCard], cardsTimestamp: 0} |
| }; |
| |
| var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION'; |
| |
| var expectedUpdatedNotifications = { |
| 'SHOULD BE KEPT': 'KEPT CARD NOTIFICATION DATA', |
| 'NEW CARD': 'NEW CARD NOTIFICATION DATA' |
| }; |
| |
| this.makeAndRegisterMockApis([ |
| 'cardSet.update', |
| 'chrome.storage.local.set', |
| 'instrumented.notifications.getAll' |
| ]); |
| this.makeMockLocalFunctions([ |
| 'onSuccess' |
| ]); |
| |
| var notificationsGetAllSavedArgs = new SaveMockArguments(); |
| this.mockApis.expects(once()). |
| instrumented_notifications_getAll( |
| notificationsGetAllSavedArgs.match(ANYTHING)). |
| will(invokeCallback( |
| notificationsGetAllSavedArgs, 0, existingNotifications)); |
| |
| this.mockApis.expects(once()). |
| cardSet_update( |
| 'SHOULD BE KEPT', |
| eqJSON([keptNotification]), |
| eqJSON(notificationGroups), |
| fakeOnCardShownFunction). |
| will(returnValue('KEPT CARD NOTIFICATION DATA')); |
| this.mockApis.expects(once()). |
| cardSet_update( |
| 'NEW CARD', |
| eqJSON([newNotification]), |
| eqJSON(notificationGroups), |
| fakeOnCardShownFunction). |
| will(returnValue('NEW CARD NOTIFICATION DATA')); |
| this.mockApis.expects(once()). |
| cardSet_update( |
| 'SHOULD BE DELETED', |
| [], |
| eqJSON(notificationGroups), |
| fakeOnCardShownFunction). |
| will(returnValue(undefined)); |
| |
| this.mockApis.expects(once()). |
| chrome_storage_local_set( |
| eqJSON({notificationsData: expectedUpdatedNotifications})); |
| |
| this.mockLocalFunctions.expects(once()). |
| onSuccess(undefined); |
| |
| // Invoking the tested function. |
| showNotificationGroups(notificationGroups, fakeOnCardShownFunction) |
| .then(this.mockLocalFunctions.functions().onSuccess); |
| }); |
| |
| TEST_F(TEST_NAME, 'ProcessServerResponse', function() { |
| // Tests processServerResponse function. |
| |
| // Setup and expectations. |
| Date.now = function() { return 3000000; }; |
| |
| // GROUP1 was requested and contains cards c4 and c5. For c5, there is a |
| // non-expired dismissal, so it will be ignored. |
| // GROUP2 was not requested, but is contained in server response to |
| // indicate that the group still exists. Stored group GROUP2 won't change. |
| // GROUP3 is stored, but is not present in server's response, which means |
| // it doesn't exist anymore. This group will be deleted. |
| // GROUP4 doesn't contain cards, but it was requested. This is treated as |
| // if it had an empty array of cards. Cards in the stored group will be |
| // replaced with an empty array. |
| // GROUP5 doesn't have next poll time, and it will be stored without next |
| // poll time. |
| var serverResponse = { |
| groups: { |
| GROUP1: {requested: true, nextPollSeconds: 46}, |
| GROUP2: {requested: false}, |
| GROUP4: {requested: true, nextPollSeconds: 45}, |
| GROUP5: {requested: true} |
| }, |
| notifications: [ |
| {notificationId: 'c4', groupName: 'GROUP1'}, |
| {notificationId: 'c5', groupName: 'GROUP1'} |
| ] |
| }; |
| |
| var recentDismissals = { |
| c4: 1800000, // expired dismissal |
| c5: 1800001 // non-expired dismissal |
| }; |
| |
| var storedGroups = { |
| GROUP2: { |
| cards: [{notificationId: 'c2'}], |
| cardsTimestamp: 239, |
| nextPollTime: 10000 |
| }, |
| GROUP3: { |
| cards: [{notificationId: 'c3'}], |
| cardsTimestamp: 240, |
| nextPollTime: 10001 |
| }, |
| GROUP4: { |
| cards: [{notificationId: 'c6'}], |
| cardsTimestamp: 241, |
| nextPollTime: 10002 |
| } |
| }; |
| |
| var expectedUpdatedGroups = { |
| GROUP1: { |
| cards: [{notificationId: 'c4', groupName: 'GROUP1'}], |
| cardsTimestamp: 3000000, |
| nextPollTime: 3046000 |
| }, |
| GROUP2: { |
| cards: [{notificationId: 'c2'}], |
| cardsTimestamp: 239, |
| nextPollTime: 10000 |
| }, |
| GROUP4: { |
| cards: [], |
| cardsTimestamp: 3000000, |
| nextPollTime: 3045000 |
| }, |
| GROUP5: { |
| cards: [], |
| cardsTimestamp: 3000000 |
| } |
| }; |
| |
| var expectedUpdatedRecentDismissals = { |
| c5: 1800001 |
| }; |
| |
| this.makeAndRegisterMockGlobals([ |
| 'scheduleNextCardsPoll' |
| ]); |
| |
| this.makeAndRegisterMockApis([ |
| 'fillFromChromeLocalStorage', |
| ]); |
| |
| expectChromeLocalStorageGet( |
| this, |
| { |
| notificationGroups: {}, |
| recentDismissals: {} |
| }, |
| { |
| notificationGroups: storedGroups, |
| recentDismissals: recentDismissals |
| }); |
| |
| this.mockGlobals.expects(once()) |
| .scheduleNextCardsPoll(eqJSON(expectedUpdatedGroups)); |
| |
| // Invoking the tested function. |
| processServerResponse(serverResponse); |
| }); |
| |
| TEST_F(TEST_NAME, 'ProcessServerResponseGoogleNowDisabled', function() { |
| // Tests processServerResponse function for the case when the response |
| // indicates that Google Now is disabled. |
| |
| // Setup and expectations. |
| var serverResponse = { |
| googleNowDisabled: true, |
| groups: {} |
| }; |
| |
| this.makeAndRegisterMockGlobals([ |
| 'scheduleNextCardsPoll' |
| ]); |
| |
| this.makeAndRegisterMockApis([ |
| 'chrome.storage.local.set', |
| 'fillFromChromeLocalStorage' |
| ]); |
| |
| this.mockApis.expects(once()). |
| chrome_storage_local_set(eqJSON({googleNowEnabled: false})); |
| |
| this.mockGlobals.expects(never()).scheduleNextCardsPoll(); |
| |
| // Invoking the tested function. |
| processServerResponse(serverResponse); |
| }); |
| |