diff options
Diffstat (limited to 'chromium/chrome/browser/resources/google_now/background_unittest.gtestjs')
-rw-r--r-- | chromium/chrome/browser/resources/google_now/background_unittest.gtestjs | 1444 |
1 files changed, 1148 insertions, 296 deletions
diff --git a/chromium/chrome/browser/resources/google_now/background_unittest.gtestjs b/chromium/chrome/browser/resources/google_now/background_unittest.gtestjs index 0099576f4a1..22ac6152ee4 100644 --- a/chromium/chrome/browser/resources/google_now/background_unittest.gtestjs +++ b/chromium/chrome/browser/resources/google_now/background_unittest.gtestjs @@ -24,7 +24,12 @@ GoogleNowBackgroundUnitTest.prototype = { ] }; -TEST_F('GoogleNowBackgroundUnitTest', 'AreTasksConflicting', function() { +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 + ')'); @@ -52,24 +57,549 @@ TEST_F('GoogleNowBackgroundUnitTest', 'AreTasksConflicting', function() { }); /** + * 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' + 'startPollingCards', + 'stopPollingCards' ]); fixture.makeAndRegisterMockApis([ 'authenticationManager.isSignedIn', - 'chrome.location.clearWatch', 'chrome.storage.local.remove', + 'fillFromChromeLocalStorage', 'instrumented.metricsPrivate.getVariationParams', 'instrumented.notifications.getAll', 'instrumented.notifications.getPermissionLevel', - 'instrumented.preferencesPrivate.googleGeolocationAccessEnabled.get', - 'instrumented.storage.local.get', + 'instrumented.webstorePrivate.getBrowserLogin', + 'optInPollAttempts.isRunning', + 'optInPollAttempts.stop', 'tasks.add', 'updateCardsAttempts.isRunning', 'updateCardsAttempts.stop' @@ -84,7 +614,6 @@ function mockInitializeDependencies(fixture) { * expects() calls cannot be chained with the same argument matchers. * @param {object} fixture Test fixture. * @param {string} testIdentityToken getAuthToken callback token. - * @param {boolean} testGeolocationPref Geolocation Preference callback value. * @param {object} testExperimentVariationParams Response of * metricsPrivate.getVariationParams. * @param {string} testExperimentVariationParams Response of @@ -95,18 +624,14 @@ function mockInitializeDependencies(fixture) { function expectStateMachineCalls( fixture, testIdentityToken, - testGeolocationPref, testExperimentVariationParams, testNotificationPermissionLevel, testGoogleNowEnabled) { - var authenticationManagerIsSignedInSavedArgs = new SaveMockArguments(); fixture.mockApis.expects(once()). - authenticationManager_isSignedIn( - authenticationManagerIsSignedInSavedArgs.match(ANYTHING)). - will(invokeCallback( - authenticationManagerIsSignedInSavedArgs, - 0, - testIdentityToken)); + authenticationManager_isSignedIn(). + will(returnValue(new Promise(function(resolve) { + resolve(!!testIdentityToken); + }))); var getVariationParamsSavedArgs = new SaveMockArguments(); fixture.mockApis.expects(once()). @@ -116,14 +641,6 @@ function expectStateMachineCalls( will(invokeCallback( getVariationParamsSavedArgs, 1, testExperimentVariationParams)); - var googleGeolocationPrefGetSavedArgs = new SaveMockArguments(); - fixture.mockApis.expects(once()). - instrumented_preferencesPrivate_googleGeolocationAccessEnabled_get( - googleGeolocationPrefGetSavedArgs.match(eqJSON({})), - googleGeolocationPrefGetSavedArgs.match(ANYTHING)). - will(invokeCallback( - googleGeolocationPrefGetSavedArgs, 1, {value: testGeolocationPref})); - var notificationGetPermissionLevelSavedArgs = new SaveMockArguments(); fixture.mockApis.expects(once()). instrumented_notifications_getPermissionLevel( @@ -133,16 +650,26 @@ function expectStateMachineCalls( 0, testNotificationPermissionLevel)) - var storageGetSavedArgs = new SaveMockArguments(); - fixture.mockApis.expects(once()). - instrumented_storage_local_get( - storageGetSavedArgs.match(eq('googleNowEnabled')), - storageGetSavedArgs.match(ANYTHING)). - will(invokeCallback( - storageGetSavedArgs, 1, {googleNowEnabled: testGoogleNowEnabled})); + expectChromeLocalStorageGet( + fixture, + {googleNowEnabled: false}, + {googleNowEnabled: testGoogleNowEnabled}); + + var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments(); + fixture.mockApis.expects(once()). + updateCardsAttempts_isRunning( + updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)). + will( + invokeCallback( + updateCardsAttemptsIsRunningSavedArgs, 0, undefined)); - fixture.mockGlobals.expects(once()). - setBackgroundEnable(ANYTHING); + var optInPollAttemptsIsRunningSavedArgs = new SaveMockArguments(); + fixture.mockApis.expects(once()). + optInPollAttempts_isRunning( + optInPollAttemptsIsRunningSavedArgs.match(ANYTHING)). + will( + invokeCallback( + optInPollAttemptsIsRunningSavedArgs, 0, undefined)); } /** @@ -152,328 +679,653 @@ function expectStateMachineCalls( * outside of this context with the same argument matchers. * expects() calls cannot be chained with the same argument matchers. */ -function expectInitialization(mockApisObj) { +function expectInitialization(fixture) { var tasksAddSavedArgs = new SaveMockArguments(); - mockApisObj.expects(once()). + fixture.mockApis.expects(once()). tasks_add( tasksAddSavedArgs.match(ANYTHING), tasksAddSavedArgs.match(ANYTHING)). will(invokeCallback(tasksAddSavedArgs, 1, function() {})); - var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments(); - mockApisObj.expects(once()). - updateCardsAttempts_isRunning( - updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)). - will( - invokeCallback( - updateCardsAttemptsIsRunningSavedArgs, 0, false)); + + // 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( - 'GoogleNowBackgroundUnitTest', - 'Initialize_ToastStateEmpty', - 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 testGeolocationPref = false; - var testExperimentVariationParams = {}; - var testNotificationPermissionLevel = 'denied'; - var testGoogleNowEnabled = undefined; - - mockInitializeDependencies(this); - - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.EXTENSION_START); - - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.STOPPED); - - expectInitialization(this.mockApis); - - expectStateMachineCalls( - this, - testIdentityToken, - testGeolocationPref, - testExperimentVariationParams, - testNotificationPermissionLevel, - testGoogleNowEnabled); - - // Invoking the tested function. - initialize(); - }); - -TEST_F( - 'GoogleNowBackgroundUnitTest', - 'DISABLED_Initialize_ToastStateEmpty2', - function() { - // Tests the case when getAuthToken succeeds, and the user has never - // responded to the toast. - // In this case, the function should invoke showWelcomeToast(). - - // Setup and expectations. - var testIdentityToken = 'some identity token'; - var testGeolocationPref = false; - var testExperimentVariationParams = {}; - var testNotificationPermissionLevel = 'denied'; - var testGoogleNowEnabled = undefined; - - mockInitializeDependencies(this); - - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.EXTENSION_START); - - expectInitialization(this.mockApis); - - expectStateMachineCalls( - this, - testIdentityToken, - testGeolocationPref, - testExperimentVariationParams, - testNotificationPermissionLevel, - testGoogleNowEnabled); - - var chromeNotificationGetAllSavedArgs = new SaveMockArguments(); - this.mockApis.expects(exactly(1)). - instrumented_notifications_getAll( - chromeNotificationGetAllSavedArgs.match(ANYTHING)). - will( - invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}), - invokeCallback(chromeNotificationGetAllSavedArgs, 0, {})); - - // Invoking the tested function. - initialize(); - }); - -TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_RunGoogleNow', function() { - // Tests if Google Now will invoke startPollingCards when all - // of the required state is fulfilled. +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 = 'some identity token'; - var testGeolocationPref = true; + var testIdentityToken = undefined; var testExperimentVariationParams = {}; - var testNotificationPermissionLevel = 'granted'; - var testGoogleNowEnabled = true; + var testNotificationPermissionLevel = 'denied'; + var testGoogleNowEnabled = undefined; mockInitializeDependencies(this); - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.EXTENSION_START); - - expectInitialization(this.mockApis); + expectInitialization(this); expectStateMachineCalls( this, testIdentityToken, - testGeolocationPref, testExperimentVariationParams, testNotificationPermissionLevel, testGoogleNowEnabled); - this.mockGlobals.expects(once()).startPollingCards(); + 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( - 'GoogleNowBackgroundUnitTest', - 'DISABLED_Initialize_NoGeolocation', - function() { - // Tests the case where everything is in place except for the - // Geolocation Preference after the user responded to the toast. +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 testGeolocationPref = false; 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); - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.EXTENSION_START); + expectInitialization(this); - this.mockGlobals.expects(once()).recordEvent( - GoogleNowEvent.USER_SUPPRESSED); + expectStateMachineCalls( + this, + testIdentityToken, + testExperimentVariationParams, + testNotificationPermissionLevel, + testGoogleNowEnabled); - expectInitialization(this.mockApis); + 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, - testGeolocationPref, 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); - var chromeNotificationGetAllSavedArgs = new SaveMockArguments(); - this.mockApis.expects(exactly(2)). - instrumented_notifications_getAll( - chromeNotificationGetAllSavedArgs.match(ANYTHING)). - will( - invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}), - invokeCallback(chromeNotificationGetAllSavedArgs, 0, {})); + 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', - 'instrumented.storage.local.get', - 'instrumented.tabs.create']); + 'chrome.windows.create', + 'chrome.windows.update', + 'fillFromChromeLocalStorage', + 'instrumented.tabs.create']); } -TEST_F( - 'GoogleNowBackgroundUnitTest', - '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 testNotificationData = {}; - - mockOnNotificationClickedDependencies(this); - this.makeMockLocalFunctions(['selector']); - - var storageGetSavedArgs = new SaveMockArguments(); - this.mockApis.expects(once()). - instrumented_storage_local_get( - storageGetSavedArgs.match(eq('notificationsData')), - storageGetSavedArgs.match(ANYTHING)). - will(invokeCallback(storageGetSavedArgs, 1, testNotificationData)); - - // Invoking the tested function. - onNotificationClicked( - testNotificationId, this.mockLocalFunctions.functions().selector); - }); - -TEST_F( - 'GoogleNowBackgroundUnitTest', - '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 testNotificationData = { - notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} - }; - - mockOnNotificationClickedDependencies(this); - this.makeMockLocalFunctions(['selector']); - - var storageGetSavedArgs = new SaveMockArguments(); - this.mockApis.expects(once()). - instrumented_storage_local_get( - storageGetSavedArgs.match(eq('notificationsData')), - storageGetSavedArgs.match(ANYTHING)). - will(invokeCallback(storageGetSavedArgs, 1, testNotificationData)); - this.mockLocalFunctions.expects(once()).selector(undefined).will( - returnValue(undefined)); - - // Invoking the tested function. - onNotificationClicked( - testNotificationId, this.mockLocalFunctions.functions().selector); - }); - -TEST_F( - 'GoogleNowBackgroundUnitTest', - '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 testNotificationData = { - notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} - }; - var testActionUrl = 'http://testurl.com'; - var testCreatedTab = {windowId: 239}; - - mockOnNotificationClickedDependencies(this); - this.makeMockLocalFunctions(['selector']); - - var storageGetSavedArgs = new SaveMockArguments(); - this.mockApis.expects(once()). - instrumented_storage_local_get( - storageGetSavedArgs.match(eq('notificationsData')), - storageGetSavedArgs.match(ANYTHING)). - will(invokeCallback(storageGetSavedArgs, 1, testNotificationData)); - this.mockLocalFunctions.expects(once()).selector(testActionUrls).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( - 'GoogleNowBackgroundUnitTest', - '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 testNotificationData = { - notificationsData: {'TEST_ID': {actionUrls: testActionUrls}} - }; - var testActionUrl = 'http://testurl.com'; - var testCreatedTab = undefined; // chrome.tabs.create fails - - mockOnNotificationClickedDependencies(this); - this.makeMockLocalFunctions(['selector']); - - var storageGetSavedArgs = new SaveMockArguments(); - this.mockApis.expects(once()). - instrumented_storage_local_get( - storageGetSavedArgs.match(eq('notificationsData')), - storageGetSavedArgs.match(ANYTHING)). - will(invokeCallback(storageGetSavedArgs, 1, testNotificationData)); - this.mockLocalFunctions.expects(once()).selector(testActionUrls).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, '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); +}); + |