Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / resources / google_now / background_unittest.gtestjs
bloba9578a890bd8b9131f57c5d8582b945a21e006a2
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // TODO(robliao,vadimt): Determine the granularity of testing to perform.
7 /**
8  * Test fixture for background.js.
9  * @constructor
10  * @extends {testing.Test}
11  */
12 function GoogleNowBackgroundUnitTest () {
13   testing.Test.call(this);
16 GoogleNowBackgroundUnitTest.prototype = {
17   __proto__: testing.Test.prototype,
19   /** @override */
20   extraLibraries: [
21     'common_test_util.js',
22     'background_test_util.js',
23     'background.js'
24   ]
27 var TEST_NAME = 'GoogleNowBackgroundUnitTest';
29 /**
30  * Tasks Conflict Test
31  */
32 TEST_F(TEST_NAME, 'AreTasksConflicting', function() {
33   function testTaskPair(newTaskName, scheduledTaskName, expected) {
34     assertTrue(areTasksConflicting(newTaskName, scheduledTaskName) == expected,
35                '(' + newTaskName + ', ' + scheduledTaskName + ')');
36   }
38   testTaskPair(UPDATE_CARDS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
39   testTaskPair(UPDATE_CARDS_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
40   testTaskPair(UPDATE_CARDS_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
41   testTaskPair(UPDATE_CARDS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
43   testTaskPair(DISMISS_CARD_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
44   testTaskPair(DISMISS_CARD_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
45   testTaskPair(DISMISS_CARD_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
46   testTaskPair(DISMISS_CARD_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
48   testTaskPair(RETRY_DISMISS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
49   testTaskPair(RETRY_DISMISS_TASK_NAME, DISMISS_CARD_TASK_NAME, true);
50   testTaskPair(RETRY_DISMISS_TASK_NAME, RETRY_DISMISS_TASK_NAME, true);
51   testTaskPair(RETRY_DISMISS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
53   testTaskPair(STATE_CHANGED_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
54   testTaskPair(STATE_CHANGED_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
55   testTaskPair(STATE_CHANGED_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
56   testTaskPair(STATE_CHANGED_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
57 });
59 /**
60  * Server Request Tests
61  */
62 TEST_F(TEST_NAME, 'AuthServerRequestSuccess', function() {
63   expectServerRequests(this, 200, '{}');
64   var callbackCalled = false;
65   requestFromServer('GET', 'test/target').then(function(request) {
66     callbackCalled = true;
67     assertTrue(request.status === 200);
68     assertTrue(request.responseText === '{}');
69   });
70   assertTrue(callbackCalled);
71 });
73 TEST_F(TEST_NAME, 'AuthServerRequestForbidden', function() {
74   this.makeAndRegisterMockApis(['authenticationManager.removeToken']);
75   this.mockApis.expects(once()).authenticationManager_removeToken(ANYTHING);
77   expectServerRequests(this, 403, '');
79   var thenCalled = false;
80   var catchCalled = false;
81   requestFromServer('GET', 'test/target').then(function(request) {
82     thenCalled = true;
83   }).catch(function(request) {
84     // The promise is rejected on HTTP failures.
85     catchCalled = true;
86     assertTrue(request.status === 403);
87   });
88   assertFalse(thenCalled);
89   assertTrue(catchCalled);
90 });
92 TEST_F(TEST_NAME, 'AuthServerRequestNoAuth', function() {
93   this.makeAndRegisterMockApis(['authenticationManager.removeToken']);
94   this.mockApis.expects(once()).authenticationManager_removeToken(ANYTHING);
96   expectServerRequests(this, 401, '');
98   var thenCalled = false;
99   var catchCalled = false;
100   requestFromServer('GET', 'test/target').then(function(request) {
101     thenCalled = true;
102   }).catch(function(request) {
103     // The promise is rejected on HTTP failures.
104     catchCalled = true;
105     assertTrue(request.status === 401);
106   });
107   assertFalse(thenCalled);
108   assertTrue(catchCalled);
111 function expectServerRequests(fixture, httpStatus, responseText) {
112   fixture.makeAndRegisterMockApis([
113     'authenticationManager.getAuthToken',
114     'buildServerRequest'
115   ]);
117   function XMLHttpRequest() {}
119   XMLHttpRequest.prototype = {
120     addEventListener: function(type, listener, wantsUntrusted) {},
121     setRequestHeader: function(header, value) {},
122     send: function() {}
123   }
125   fixture.mockApis.expects(once()).authenticationManager_getAuthToken()
126       .will(returnValue(Promise.resolve('token')));
128   var mockXMLHttpRequest = mock(XMLHttpRequest);
129   var mockXMLHttpRequestProxy = mockXMLHttpRequest.proxy();
130   fixture.mockApis.expects(once())
131       .buildServerRequest(ANYTHING, ANYTHING, ANYTHING)
132       .will(returnValue(mockXMLHttpRequestProxy));
134   mockXMLHttpRequest.expects(once())
135       .setRequestHeader('Authorization', 'Bearer token');
137   var loadEndSavedArgs = new SaveMockArguments();
138   mockXMLHttpRequest.expects(once())
139       .addEventListener(
140           loadEndSavedArgs.match(eq('loadend')),
141           loadEndSavedArgs.match(ANYTHING),
142           loadEndSavedArgs.match(eq(false)));
144   mockXMLHttpRequestProxy.status = httpStatus;
145   mockXMLHttpRequestProxy.response = responseText;
146   mockXMLHttpRequestProxy.responseText = responseText;
148   mockXMLHttpRequest.expects(once()).send()
149       .will(invokeCallback(loadEndSavedArgs, 1, mockXMLHttpRequestProxy));
152 TEST_F(TEST_NAME, 'AuthServerRequestNoToken', function() {
153   this.makeAndRegisterMockApis([
154     'authenticationManager.getAuthToken',
155     'buildServerRequest'
156   ]);
158   this.mockApis.expects(once()).authenticationManager_getAuthToken()
159       .will(returnValue(Promise.reject()));
160   this.mockApis.expects(never()).buildServerRequest()
162   var thenCalled = false;
163   var catchCalled = false;
164   requestFromServer('GET', 'test/target').then(function(request) {
165     thenCalled = true;
166   }).catch(function() {
167     catchCalled = true;
168   });
169   assertFalse(thenCalled);
170   assertTrue(catchCalled);
174  * requestNotificationGroupsFromServer Tests
175  */
176 TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerEmpty', function() {
177   this.makeAndRegisterMockGlobals([
178     'shouldShowExplanatoryCard',
179     'recordEvent',
180     'requestFromServer'
181   ]);
183   this.mockGlobals.expects(once()).shouldShowExplanatoryCard()
184       .will(returnValue(false));
186   this.mockGlobals.expects(once()).recordEvent(
187       GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL);
189   this.mockGlobals.expects(once()).recordEvent(
190       GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS);
192   var requestFromServerArgs = new SaveMockArguments();
193   this.mockGlobals.expects(once()).requestFromServer(
194       requestFromServerArgs.match(eq('GET')),
195       requestFromServerArgs.match(ANYTHING))
196       .will(returnValue(
197           Promise.resolve({status: 200, responseText: "{}"})));
199   var thenCalled = false;
200   var catchCalled = false;
201   requestNotificationGroupsFromServer([]).then(function() {
202     thenCalled = true;
203   }).catch(function() {
204     catchCalled = true;
205   });
206   assertTrue(thenCalled);
207   assertFalse(catchCalled);
209   var pathAndQuery = requestFromServerArgs.arguments[1];
210   var query = pathAndQuery.split('?')[1];
211   assertTrue(query.search('timeZoneOffsetMs') >= 0);
212   assertTrue(query.search('uiLocale') >= 0);
213   assertFalse(query.search('cardExplanation') >= 0);
216 TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerWithGroups', function() {
217   this.makeAndRegisterMockGlobals([
218     'shouldShowExplanatoryCard',
219     'recordEvent',
220     'requestFromServer'
221   ]);
223   this.mockGlobals.expects(once()).shouldShowExplanatoryCard()
224       .will(returnValue(false));
226   this.mockGlobals.expects(once()).recordEvent(
227       GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL);
229   this.mockGlobals.expects(once()).recordEvent(
230       GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS);
232   var requestFromServerArgs = new SaveMockArguments();
233   this.mockGlobals.expects(once()).requestFromServer(
234       requestFromServerArgs.match(eq('GET')),
235       requestFromServerArgs.match(ANYTHING))
236       .will(returnValue(
237           Promise.resolve({status: 200, responseText: "{}"})));
239   var thenCalled = false;
240   var catchCalled = false;
241   requestNotificationGroupsFromServer(['A', 'B', 'C']).then(function() {
242     thenCalled = true;
243   }).catch(function() {
244     catchCalled = true;
245   });
246   assertTrue(thenCalled);
247   assertFalse(catchCalled);
249   var pathAndQuery = requestFromServerArgs.arguments[1];
250   var query = pathAndQuery.split('?')[1];
251   assertTrue(query.search('timeZoneOffsetMs') >= 0);
252   assertTrue(query.search('uiLocale') >= 0);
253   assertFalse(query.search('cardExplanation') >= 0);
254   assertTrue(query.search('requestTypes=A') >= 0);
255   assertTrue(query.search('requestTypes=B') >= 0);
256   assertTrue(query.search('requestTypes=C') >= 0);
259 TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerExplanatory', function() {
260   this.makeAndRegisterMockGlobals([
261     'shouldShowExplanatoryCard',
262     'recordEvent',
263     'requestFromServer'
264   ]);
266   this.mockGlobals.expects(once()).shouldShowExplanatoryCard()
267       .will(returnValue(true));
269   this.mockGlobals.expects(once()).recordEvent(
270       GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL);
272   this.mockGlobals.expects(once()).recordEvent(
273       GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS);
275   var requestFromServerArgs = new SaveMockArguments();
276   this.mockGlobals.expects(once()).requestFromServer(
277       requestFromServerArgs.match(eq('GET')),
278       requestFromServerArgs.match(ANYTHING))
279       .will(returnValue(
280           Promise.resolve({status: 200, responseText: "{}"})));
282   var thenCalled = false;
283   var catchCalled = false;
284   requestNotificationGroupsFromServer([]).then(function() {
285     thenCalled = true;
286   }).catch(function() {
287     catchCalled = true;
288   });
289   assertTrue(thenCalled);
290   assertFalse(catchCalled);
292   var pathAndQuery = requestFromServerArgs.arguments[1];
293   var query = pathAndQuery.split('?')[1];
294   assertTrue(query.search('timeZoneOffsetMs') >= 0);
295   assertTrue(query.search('uiLocale') >= 0);
296   assertTrue(query.search('cardExplanation=true') >= 0);
299 TEST_F(TEST_NAME, 'RequestNotificationGroupsFromServerFailure', function() {
300   this.makeAndRegisterMockGlobals([
301     'shouldShowExplanatoryCard',
302     'recordEvent',
303     'requestFromServer'
304   ]);
306   this.mockGlobals.expects(once()).shouldShowExplanatoryCard()
307       .will(returnValue(false));
309   this.mockGlobals.expects(once()).recordEvent(
310       GoogleNowEvent.REQUEST_FOR_CARDS_TOTAL);
312   this.mockGlobals.expects(never()).recordEvent(
313       GoogleNowEvent.REQUEST_FOR_CARDS_SUCCESS);
315   var requestFromServerArgs = new SaveMockArguments();
316   this.mockGlobals.expects(once()).requestFromServer(
317       requestFromServerArgs.match(eq('GET')),
318       requestFromServerArgs.match(ANYTHING))
319       .will(returnValue(
320           Promise.reject({status: 401})));
322   var thenCalled = false;
323   var catchCalled = false;
324   requestNotificationGroupsFromServer([]).then(function() {
325     thenCalled = true;
326   }).catch(function() {
327     catchCalled = true;
328   });
329   assertFalse(thenCalled);
330   assertTrue(catchCalled);
334  * shouldScheduleRetryFromGroupList Tests
335  */
336 TEST_F(TEST_NAME, 'ShouldScheduleRetryEmptyGroupList', function() {
337   assertTrue(shouldScheduleRetryFromGroupList([]));
340 TEST_F(TEST_NAME, 'ShouldScheduleRetryNorOnlyGroupList', function() {
341   assertFalse(shouldScheduleRetryFromGroupList(['NOR']));
344 TEST_F(TEST_NAME, 'ShouldScheduleRetryNotOnlyGroupList', function() {
345   assertTrue(shouldScheduleRetryFromGroupList(['NOT']));
348 TEST_F(TEST_NAME, 'ShouldScheduleRetryMultipleGroupsList', function() {
349   assertTrue(shouldScheduleRetryFromGroupList(['NOR', 'NOT']));
353  * requestAndUpdateOptIn Tests
354  */
355 TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedIn', function() {
356   this.makeAndRegisterMockApis([
357     'chrome.storage.local.set',
358     'requestFromServer'
359   ]);
361   this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
362       .will(returnValue(Promise.resolve({
363         status: 200,
364         responseText: '{"value": true}'})));
366   this.mockApis.expects(once())
367       .chrome_storage_local_set(eqJSON({googleNowEnabled: true}));
369   var thenCalled = false;
370   var catchCalled = false;
371   requestAndUpdateOptedIn().then(function(optedIn) {
372     thenCalled = true;
373     assertTrue(optedIn);
374   }).catch(function() {
375     catchCalled = true;
376   });
377   assertTrue(thenCalled);
378   assertFalse(catchCalled);
381 TEST_F(TEST_NAME, 'RequestAndUpdateOptInOptedOut', function() {
382   this.makeAndRegisterMockApis([
383     'chrome.storage.local.set',
384     'requestFromServer'
385   ]);
387   this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
388       .will(returnValue(Promise.resolve({
389         status: 200,
390         responseText: '{"value": false}'})));
392   this.mockApis.expects(once())
393       .chrome_storage_local_set(eqJSON({googleNowEnabled: false}));
395   var thenCalled = false;
396   var catchCalled = false;
397   requestAndUpdateOptedIn().then(function(optedIn) {
398     thenCalled = true;
399     assertFalse(optedIn);
400   }).catch(function() {
401     catchCalled = true;
402   });
403   assertTrue(thenCalled);
404   assertFalse(catchCalled);
407 TEST_F(TEST_NAME, 'RequestAndUpdateOptInFailure', function() {
408   this.makeAndRegisterMockApis([
409     'chrome.storage.local.set',
410     'requestFromServer'
411   ]);
413   this.mockApis.expects(once()).requestFromServer('GET', 'settings/optin')
414       .will(returnValue(Promise.reject({status: 404})));
416   this.mockApis.expects(never()).chrome_storage_local_set();
418   var thenCalled = false;
419   var catchCalled = false;
420   requestAndUpdateOptedIn().then(function() {
421     thenCalled = true;
422   }).catch(function() {
423     catchCalled = true;
424   });
425   assertFalse(thenCalled);
426   assertTrue(catchCalled);
430  * pollOptedInNoImmediateRecheck Tests
431  */
432 TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedIn', function() {
433   this.makeAndRegisterMockApis([
434     'requestAndUpdateOptedIn',
435     'instrumented.metricsPrivate.getVariationParams',
436     'optInPollAttempts.start'
437   ]);
439   this.mockApis.expects(once()).requestAndUpdateOptedIn()
440       .will(returnValue(Promise.resolve(true)));
442   this.mockApis.expects(never())
443       .instrumented_metricsPrivate_getVariationParams();
445   this.mockApis.expects(never()).optInPollAttempts_start();
447   pollOptedInNoImmediateRecheck();
450 TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckOptedOut', function() {
451   this.makeAndRegisterMockApis([
452     'requestAndUpdateOptedIn',
453     'instrumented.metricsPrivate.getVariationParams',
454     'optInPollAttempts.start'
455   ]);
457   this.mockApis.expects(once()).requestAndUpdateOptedIn()
458       .will(returnValue(Promise.resolve(false)));
460   var getVariationParamsSavedArgs = new SaveMockArguments();
461   this.mockApis.expects(once())
462       .instrumented_metricsPrivate_getVariationParams(
463           getVariationParamsSavedArgs.match(eq('GoogleNow')),
464           getVariationParamsSavedArgs.match(ANYTHING))
465       .will(invokeCallback(getVariationParamsSavedArgs, 1, {}));
467   this.mockApis.expects(once())
468       .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS);
470   pollOptedInNoImmediateRecheck();
473 TEST_F(TEST_NAME, 'pollOptedInNoImmediateRecheckFailure', function() {
474   this.makeAndRegisterMockApis([
475     'requestAndUpdateOptedIn',
476     'instrumented.metricsPrivate.getVariationParams',
477     'optInPollAttempts.start'
478   ]);
480   this.mockApis.expects(once()).requestAndUpdateOptedIn()
481       .will(returnValue(Promise.reject()));
483   var getVariationParamsSavedArgs = new SaveMockArguments();
484   this.mockApis.expects(once())
485       .instrumented_metricsPrivate_getVariationParams(
486           getVariationParamsSavedArgs.match(eq('GoogleNow')),
487           getVariationParamsSavedArgs.match(ANYTHING))
488       .will(invokeCallback(getVariationParamsSavedArgs, 1, {}));
490   this.mockApis.expects(once())
491       .optInPollAttempts_start(DEFAULT_OPTIN_CHECK_PERIOD_SECONDS);
493   pollOptedInNoImmediateRecheck();
497  * getGroupsToRequest Tests
498  */
499 TEST_F(TEST_NAME, 'GetGroupsToRequestNone', function() {
500   this.makeAndRegisterMockApis([
501     'fillFromChromeLocalStorage',
502     'Date.now'
503   ]);
505   this.mockApis.expects(once())
506       .fillFromChromeLocalStorage(eqJSON({notificationGroups: {}}))
507       .will(returnValue(Promise.resolve({notificationGroups: {}})));
509   this.mockApis.expects(once()).Date_now().will(returnValue(20));
511   getGroupsToRequest().then(function(groupsToRequest) {
512     assertTrue(JSON.stringify(groupsToRequest) === '[]');
513   });
516 TEST_F(TEST_NAME, 'GetGroupsToRequestWithGroups', function() {
517   this.makeAndRegisterMockApis([
518     'fillFromChromeLocalStorage',
519     'Date.now'
520   ]);
522   this.mockApis.expects(once())
523       .fillFromChromeLocalStorage(eqJSON({notificationGroups: {}}))
524       .will(returnValue(Promise.resolve({notificationGroups: {
525         TIME18: {nextPollTime: 18},
526         TIME19: {nextPollTime: 19},
527         TIME20: {nextPollTime: 20},
528         TIME21: {nextPollTime: 21},
529         TIME22: {nextPollTime: 22},
530         TIMEUNDEF: {}
531       }})));
533   this.mockApis.expects(once()).Date_now().will(returnValue(20));
535   getGroupsToRequest().then(function(groupsToRequest) {
536     assertTrue(groupsToRequest.length == 3);
537     assertTrue(groupsToRequest.indexOf('TIME18') >= 0);
538     assertTrue(groupsToRequest.indexOf('TIME19') >= 0);
539     assertTrue(groupsToRequest.indexOf('TIME20') >= 0);
540   });
544  * combineGroup Tests
545  */
546 TEST_F(TEST_NAME, 'CombineGroup', function() {
547   // Tests combineGroup function. Verifies that both notifications with and
548   // without show time are handled correctly and that cards are correctly
549   // added to existing cards with same ID or start a new combined card.
551   // Setup and expectations.
552   var combinedCards = {
553     'EXISTING CARD': [1]
554   };
556   var receivedNotificationNoShowTime = {
557     chromeNotificationId: 'EXISTING CARD',
558     trigger: {hideTimeSec: 1}
559   };
560   var receivedNotificationWithShowTime = {
561     chromeNotificationId: 'NEW CARD',
562     trigger: {showTimeSec: 2, hideTimeSec: 3}
563   }
565   var storedGroup = {
566     cardsTimestamp: 10000,
567     cards: [
568       receivedNotificationNoShowTime,
569       receivedNotificationWithShowTime
570     ]
571   };
573   // Invoking the tested function.
574   combineGroup(combinedCards, storedGroup);
576   // Check the output value.
577   var expectedCombinedCards = {
578     'EXISTING CARD': [
579       1,
580       {
581         receivedNotification: receivedNotificationNoShowTime,
582         hideTime: 11000
583       }
584     ],
585     'NEW CARD': [
586       {
587         receivedNotification: receivedNotificationWithShowTime,
588         showTime: 12000,
589         hideTime: 13000
590       }
591     ]
592   };
594   assertEquals(
595       JSON.stringify(expectedCombinedCards),
596       JSON.stringify(combinedCards));
600  * Mocks global functions and APIs that initialize() depends upon.
601  * @param {Test} fixture Test fixture.
602  */
603 function mockInitializeDependencies(fixture) {
604   fixture.makeAndRegisterMockGlobals([
605     'pollOptedInNoImmediateRecheck',
606     'recordEvent',
607     'removeAllCards',
608     'setBackgroundEnable',
609     'startPollingCards',
610     'stopPollingCards'
611   ]);
612   fixture.makeAndRegisterMockApis([
613     'authenticationManager.isSignedIn',
614     'chrome.storage.local.remove',
615     'fillFromChromeLocalStorage',
616     'instrumented.metricsPrivate.getVariationParams',
617     'instrumented.notifications.getAll',
618     'instrumented.notifications.getPermissionLevel',
619     'instrumented.webstorePrivate.getBrowserLogin',
620     'optInPollAttempts.isRunning',
621     'optInPollAttempts.stop',
622     'tasks.add',
623     'updateCardsAttempts.isRunning',
624     'updateCardsAttempts.stop'
625   ]);
629  * Sets up the test to expect the state machine calls and send
630  * the specified state machine state. Currently used to test initialize().
631  * Note that this CAN NOT be used if any of the methods below are called
632  * outside of this context with the same argument matchers.
633  * expects() calls cannot be chained with the same argument matchers.
634  * @param {object} fixture Test fixture.
635  * @param {string} testIdentityToken getAuthToken callback token.
636  * @param {object} testExperimentVariationParams Response of
637  *     metricsPrivate.getVariationParams.
638  * @param {string} testExperimentVariationParams Response of
639  *     notifications.getPermissionLevel.
640  * @param {boolean} testGoogleNowEnabled True if the user is opted in to Google
641  *     Now.
642  */
643 function expectStateMachineCalls(
644     fixture,
645     testIdentityToken,
646     testExperimentVariationParams,
647     testNotificationPermissionLevel,
648     testGoogleNowEnabled) {
649   fixture.mockApis.expects(once()).
650       authenticationManager_isSignedIn().
651       will(returnValue(new Promise(function(resolve) {
652         resolve(!!testIdentityToken);
653       })));
655   var getVariationParamsSavedArgs = new SaveMockArguments();
656   fixture.mockApis.expects(once()).
657       instrumented_metricsPrivate_getVariationParams(
658           getVariationParamsSavedArgs.match(ANYTHING),
659           getVariationParamsSavedArgs.match(ANYTHING)).
660       will(invokeCallback(
661           getVariationParamsSavedArgs, 1, testExperimentVariationParams));
663   var notificationGetPermissionLevelSavedArgs = new SaveMockArguments();
664   fixture.mockApis.expects(once()).
665       instrumented_notifications_getPermissionLevel(
666           notificationGetPermissionLevelSavedArgs.match(ANYTHING)).
667       will(invokeCallback(
668           notificationGetPermissionLevelSavedArgs,
669           0,
670           testNotificationPermissionLevel))
672   expectChromeLocalStorageGet(
673       fixture,
674       {googleNowEnabled: false},
675       {googleNowEnabled: testGoogleNowEnabled});
677   var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments();
678   fixture.mockApis.expects(once()).
679       updateCardsAttempts_isRunning(
680           updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)).
681       will(
682           invokeCallback(
683               updateCardsAttemptsIsRunningSavedArgs, 0, undefined));
685   var optInPollAttemptsIsRunningSavedArgs = new SaveMockArguments();
686   fixture.mockApis.expects(once()).
687       optInPollAttempts_isRunning(
688           optInPollAttemptsIsRunningSavedArgs.match(ANYTHING)).
689       will(
690           invokeCallback(
691               optInPollAttemptsIsRunningSavedArgs, 0, undefined));
695  * Sets up the test to expect the initialization calls that
696  * initialize() invokes.
697  * Note that this CAN NOT be used if any of the methods below are called
698  * outside of this context with the same argument matchers.
699  * expects() calls cannot be chained with the same argument matchers.
700  */
701 function expectInitialization(fixture) {
702   var tasksAddSavedArgs = new SaveMockArguments();
703   fixture.mockApis.expects(once()).
704       tasks_add(
705           tasksAddSavedArgs.match(ANYTHING),
706           tasksAddSavedArgs.match(ANYTHING)).
707       will(invokeCallback(tasksAddSavedArgs, 1, function() {}));
709   // The ordering here between stubs and expects is important.
710   // We only care about the EXTENSION_START event. The other events are covered
711   // by the NoCards tests below. Reversing the calls will cause all recordEvent
712   // calls to be unexpected.
713   fixture.mockGlobals.stubs().recordEvent(ANYTHING);
714   fixture.mockGlobals.
715       expects(once()).recordEvent(GoogleNowEvent.EXTENSION_START);
716   fixture.mockApis.expects(once())
717       .fillFromChromeLocalStorage(eqJSON({gcmNotificationKey: undefined}))
718       .will(returnValue(Promise.resolve({gcmNotificationKey: 'gcmkey'})));
722 TEST_F(TEST_NAME,'Initialize_SignedOut', function() {
723   // Tests the case when getAuthToken fails most likely because the user is
724   // not signed in. In this case, the function should quietly exit after
725   // finding out that getAuthToken fails.
727   // Setup and expectations.
728   var testIdentityToken = undefined;
729   var testExperimentVariationParams = {};
730   var testNotificationPermissionLevel = 'denied';
731   var testGoogleNowEnabled = undefined;
733   mockInitializeDependencies(this);
735   expectInitialization(this);
737   expectStateMachineCalls(
738       this,
739       testIdentityToken,
740       testExperimentVariationParams,
741       testNotificationPermissionLevel,
742       testGoogleNowEnabled);
744   this.mockGlobals.expects(once()).setBackgroundEnable(false);
745   this.mockGlobals.expects(never()).startPollingCards();
746   this.mockGlobals.expects(once()).stopPollingCards();
747   this.mockGlobals.expects(once()).removeAllCards();
748   this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
749   this.mockApis.expects(once()).optInPollAttempts_stop();
751   // Invoking the tested function.
752   initialize();
755 TEST_F(TEST_NAME,'Initialize_NotificationDisabled', function() {
756   // Tests the case when Google Now is disabled in the notifications center.
758   // Setup and expectations.
759   var testIdentityToken = 'some identity token';
760   var testExperimentVariationParams = {};
761   var testNotificationPermissionLevel = 'denied';
762   var testGoogleNowEnabled = undefined;
764   mockInitializeDependencies(this);
766   expectInitialization(this);
768   expectStateMachineCalls(
769       this,
770       testIdentityToken,
771       testExperimentVariationParams,
772       testNotificationPermissionLevel,
773       testGoogleNowEnabled);
775   this.mockGlobals.expects(once()).setBackgroundEnable(false);
776   this.mockGlobals.expects(never()).startPollingCards();
777   this.mockGlobals.expects(once()).stopPollingCards();
778   this.mockGlobals.expects(once()).removeAllCards();
779   this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
780   this.mockApis.expects(once()).optInPollAttempts_stop();
782   // Invoking the tested function.
783   initialize();
786 TEST_F(TEST_NAME, 'Initialize_NoBackground', function() {
787   // Tests when the no background variation is received.
789   // Setup and expectations.
790   var testIdentityToken = 'some identity token';
791   var testExperimentVariationParams = {canEnableBackground: 'false'};
792   var testNotificationPermissionLevel = 'granted';
793   var testGoogleNowEnabled = true;
795   mockInitializeDependencies(this);
797   expectInitialization(this);
799   expectStateMachineCalls(
800       this,
801       testIdentityToken,
802       testExperimentVariationParams,
803       testNotificationPermissionLevel,
804       testGoogleNowEnabled);
806   this.mockGlobals.expects(once()).setBackgroundEnable(false);
807   this.mockGlobals.expects(once()).startPollingCards();
808   this.mockGlobals.expects(never()).stopPollingCards();
809   this.mockGlobals.expects(never()).removeAllCards();
810   this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
811   this.mockApis.expects(once()).optInPollAttempts_stop();
813   // Invoking the tested function.
814   initialize();
817 TEST_F(TEST_NAME, 'Initialize_GoogleNowDisabled', function() {
818   // Tests when the user has Google Now disabled.
820   // Setup and expectations.
821   var testIdentityToken = 'some identity token';
822   var testExperimentVariationParams = {};
823   var testNotificationPermissionLevel = 'granted';
824   var testGoogleNowEnabled = false;
826   mockInitializeDependencies(this);
828   expectInitialization(this);
830   expectStateMachineCalls(
831       this,
832       testIdentityToken,
833       testExperimentVariationParams,
834       testNotificationPermissionLevel,
835       testGoogleNowEnabled);
837   this.mockGlobals.expects(once()).setBackgroundEnable(false);
838   this.mockGlobals.expects(never()).startPollingCards();
839   this.mockGlobals.expects(once()).stopPollingCards();
840   this.mockGlobals.expects(once()).removeAllCards();
841   this.mockGlobals.expects(once()).pollOptedInNoImmediateRecheck();
842   this.mockApis.expects(never()).optInPollAttempts_stop();
844   // Invoking the tested function.
845   initialize();
848 TEST_F(TEST_NAME, 'Initialize_RunGoogleNow', function() {
849   // Tests if Google Now will invoke startPollingCards when all
850   // of the required state is fulfilled.
852   // Setup and expectations.
853   var testIdentityToken = 'some identity token';
854   var testExperimentVariationParams = {};
855   var testNotificationPermissionLevel = 'granted';
856   var testGoogleNowEnabled = true;
858   mockInitializeDependencies(this);
860   expectInitialization(this);
862   expectStateMachineCalls(
863       this,
864       testIdentityToken,
865       testExperimentVariationParams,
866       testNotificationPermissionLevel,
867       testGoogleNowEnabled);
869   this.mockGlobals.expects(once()).setBackgroundEnable(true);
870   this.mockGlobals.expects(once()).startPollingCards();
871   this.mockGlobals.expects(never()).stopPollingCards();
872   this.mockGlobals.expects(never()).removeAllCards();
873   this.mockGlobals.expects(never()).pollOptedInNoImmediateRecheck();
874   this.mockApis.expects(once()).optInPollAttempts_stop();
876   // Invoking the tested function.
877   initialize();
881  * No Cards Event Recording Tests
882  */
883 TEST_F(TEST_NAME, 'NoCardsSignedOut', function() {
884   var signedIn = false;
885   var notificationEnabled = false;
886   var googleNowEnabled = false;
887   this.makeAndRegisterMockGlobals([
888       'recordEvent',
889       'removeAllCards',
890       'setBackgroundEnable',
891       'setShouldPollCards',
892       'setShouldPollOptInStatus']);
894   this.mockGlobals.stubs().removeAllCards();
895   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
896   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
897   this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
899   this.mockGlobals.expects(once()).recordEvent(
900       GoogleNowEvent.STOPPED);
901   this.mockGlobals.expects(once()).recordEvent(
902       GoogleNowEvent.SIGNED_OUT);
903   this.mockGlobals.expects(never()).recordEvent(
904       GoogleNowEvent.NOTIFICATION_DISABLED);
905   this.mockGlobals.expects(never()).recordEvent(
906       GoogleNowEvent.GOOGLE_NOW_DISABLED);
907   updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled);
910 TEST_F(TEST_NAME, 'NoCardsNotificationsDisabled', function() {
911   var signedIn = true;
912   var notificationEnabled = false;
913   var googleNowEnabled = false;
914   this.makeAndRegisterMockGlobals([
915       'recordEvent',
916       'removeAllCards',
917       'setBackgroundEnable',
918       'setShouldPollCards',
919       'setShouldPollOptInStatus']);
921   this.mockGlobals.stubs().removeAllCards();
922   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
923   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
924   this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
926   this.mockGlobals.expects(once()).recordEvent(
927       GoogleNowEvent.STOPPED);
928   this.mockGlobals.expects(never()).recordEvent(
929       GoogleNowEvent.SIGNED_OUT);
930   this.mockGlobals.expects(once()).recordEvent(
931       GoogleNowEvent.NOTIFICATION_DISABLED);
932   this.mockGlobals.expects(never()).recordEvent(
933       GoogleNowEvent.GOOGLE_NOW_DISABLED);
934   updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled);
937 TEST_F(TEST_NAME, 'NoCardsGoogleNowDisabled', function() {
938   var signedIn = true;
939   var notificationEnabled = true;
940   var googleNowEnabled = false;
941   this.makeAndRegisterMockGlobals([
942       'recordEvent',
943       'removeAllCards',
944       'setBackgroundEnable',
945       'setShouldPollCards',
946       'setShouldPollOptInStatus']);
948   this.mockGlobals.stubs().removeAllCards();
949   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
950   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
951   this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
953   this.mockGlobals.expects(never()).recordEvent(
954       GoogleNowEvent.STOPPED);
955   this.mockGlobals.expects(never()).recordEvent(
956       GoogleNowEvent.SIGNED_OUT);
957   this.mockGlobals.expects(never()).recordEvent(
958       GoogleNowEvent.NOTIFICATION_DISABLED);
959   this.mockGlobals.expects(once()).recordEvent(
960       GoogleNowEvent.GOOGLE_NOW_DISABLED);
961   updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled);
964 TEST_F(TEST_NAME, 'NoCardsEverythingEnabled', function() {
965   var signedIn = true;
966   var notificationEnabled = true;
967   var googleNowEnabled = true;
968   this.makeAndRegisterMockGlobals([
969       'recordEvent',
970       'removeAllCards',
971       'setBackgroundEnable',
972       'setShouldPollCards',
973       'setShouldPollOptInStatus']);
975   this.mockGlobals.stubs().removeAllCards();
976   this.mockGlobals.stubs().setBackgroundEnable(ANYTHING);
977   this.mockGlobals.stubs().setShouldPollCards(ANYTHING);
978   this.mockGlobals.stubs().setShouldPollOptInStatus(ANYTHING);
980   this.mockGlobals.expects(never()).recordEvent(
981       GoogleNowEvent.STOPPED);
982   this.mockGlobals.expects(never()).recordEvent(
983       GoogleNowEvent.SIGNED_OUT);
984   this.mockGlobals.expects(never()).recordEvent(
985       GoogleNowEvent.NOTIFICATION_DISABLED);
986   this.mockGlobals.expects(never()).recordEvent(
987       GoogleNowEvent.GOOGLE_NOW_DISABLED);
988   updateRunningState(signedIn, true, notificationEnabled, googleNowEnabled);
992  * Mocks global functions and APIs that onNotificationClicked() depends upon.
993  * @param {Test} fixture Test fixture.
994  */
995 function mockOnNotificationClickedDependencies(fixture) {
996   fixture.makeAndRegisterMockApis([
997     'chrome.windows.create',
998     'chrome.windows.update',
999     'fillFromChromeLocalStorage',
1000     'instrumented.tabs.create']);
1003 TEST_F(TEST_NAME, 'OnNotificationClicked_NoData', function() {
1004   // Tests the case when there is no data associated with notification id.
1005   // In this case, the function should do nothing.
1007   // Setup and expectations.
1008   var testNotificationId = 'TEST_ID';
1009   var testNotificationDataRequest = {notificationsData: {}};
1010   var testNotificationData = {notificationsData: {}};
1012   mockOnNotificationClickedDependencies(this);
1013   this.makeMockLocalFunctions(['selector']);
1015   expectChromeLocalStorageGet(
1016       this, testNotificationDataRequest, testNotificationData);
1018   // Invoking the tested function.
1019   onNotificationClicked(
1020       testNotificationId, this.mockLocalFunctions.functions().selector);
1023 TEST_F(TEST_NAME, 'OnNotificationClicked_ActionUrlsUndefined', function() {
1024   // Tests the case when the data associated with notification id is
1025   // 'undefined'.
1026   // In this case, the function should do nothing.
1028   // Setup and expectations.
1029   var testActionUrls = undefined;
1030   var testNotificationId = 'TEST_ID';
1031   var testNotificationDataRequest = {notificationsData: {}};
1032   var testNotificationData = {
1033       notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
1034   };
1036   mockOnNotificationClickedDependencies(this);
1037   this.makeMockLocalFunctions(['selector']);
1039   expectChromeLocalStorageGet(
1040       this, testNotificationDataRequest, testNotificationData);
1042   this.mockLocalFunctions.expects(once())
1043       .selector(eqJSON(
1044           testNotificationData.notificationsData[testNotificationId]))
1045       .will(returnValue(undefined));
1047   // Invoking the tested function.
1048   onNotificationClicked(
1049       testNotificationId, this.mockLocalFunctions.functions().selector);
1052 TEST_F(TEST_NAME, 'OnNotificationClicked_TabCreateSuccess', function() {
1053   // Tests the selected URL is OK and crome.tabs.create suceeds.
1055   // Setup and expectations.
1056   var testActionUrls = {testField: 'TEST VALUE'};
1057   var testNotificationId = 'TEST_ID';
1058   var testNotificationDataRequest = {notificationsData: {}};
1059   var testNotificationData = {
1060       notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
1061   };
1062   var testActionUrl = 'http://testurl.com';
1063   var testCreatedTab = {windowId: 239};
1065   mockOnNotificationClickedDependencies(this);
1066   this.makeMockLocalFunctions(['selector']);
1068   expectChromeLocalStorageGet(
1069       this, testNotificationDataRequest, testNotificationData);
1070   this.mockLocalFunctions.expects(once())
1071       .selector(eqJSON(
1072           testNotificationData.notificationsData[testNotificationId]))
1073       .will(returnValue(testActionUrl));
1074   var chromeTabsCreateSavedArgs = new SaveMockArguments();
1075   this.mockApis.expects(once()).
1076       instrumented_tabs_create(
1077           chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
1078           chromeTabsCreateSavedArgs.match(ANYTHING)).
1079       will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
1080   this.mockApis.expects(once()).chrome_windows_update(
1081       testCreatedTab.windowId,
1082       eqJSON({focused: true}));
1084   // Invoking the tested function.
1085   onNotificationClicked(
1086       testNotificationId, this.mockLocalFunctions.functions().selector);
1089 TEST_F(TEST_NAME, 'OnNotificationClicked_TabCreateFail', function() {
1090   // Tests the selected URL is OK and crome.tabs.create fails.
1091   // In this case, the function should invoke chrome.windows.create as a
1092   // second attempt.
1094   // Setup and expectations.
1095   var testActionUrls = {testField: 'TEST VALUE'};
1096   var testNotificationId = 'TEST_ID';
1097   var testNotificationDataRequest = {notificationsData: {}};
1098   var testNotificationData = {
1099     notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
1100   };
1101   var testActionUrl = 'http://testurl.com';
1102   var testCreatedTab = undefined; // chrome.tabs.create fails
1104   mockOnNotificationClickedDependencies(this);
1105   this.makeMockLocalFunctions(['selector']);
1107   expectChromeLocalStorageGet(
1108       this, testNotificationDataRequest, testNotificationData);
1109   this.mockLocalFunctions.expects(once())
1110       .selector(eqJSON(
1111           testNotificationData.notificationsData[testNotificationId]))
1112       .will(returnValue(testActionUrl));
1113   var chromeTabsCreateSavedArgs = new SaveMockArguments();
1114   this.mockApis.expects(once()).
1115       instrumented_tabs_create(
1116           chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
1117           chromeTabsCreateSavedArgs.match(ANYTHING)).
1118       will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
1119   this.mockApis.expects(once()).chrome_windows_create(
1120       eqJSON({url: testActionUrl, focused: true}));
1122   // Invoking the tested function.
1123   onNotificationClicked(
1124       testNotificationId, this.mockLocalFunctions.functions().selector);
1127 TEST_F(TEST_NAME, 'ShowNotificationGroups', function() {
1128   // Tests showNotificationGroups function. Checks that the function properly
1129   // deletes the card that didn't get an update, updates existing card and
1130   // creates a new card that previously didn't exist.
1132   // Setup and expectations.
1133   var existingNotifications = {
1134     'SHOULD BE DELETED': 'SOMETHING',
1135     'SHOULD BE KEPT': 'SOMETHING'
1136   };
1138   var keptCard = {
1139     chromeNotificationId: 'SHOULD BE KEPT',
1140     trigger: {showTimeSec: 0, hideTimeSec: 0}
1141   };
1143   var keptNotification = {
1144     receivedNotification: keptCard,
1145     showTime: 0,
1146     hideTime: 0
1147   };
1149   var newCard = {
1150     chromeNotificationId: 'NEW CARD',
1151     trigger: {showTimeSec: 0, hideTimeSec: 0}
1152   };
1154   var newNotification = {
1155     receivedNotification: newCard,
1156     showTime: 0,
1157     hideTime: 0
1158   };
1160   var notificationGroups = {
1161     'TEST GROUP 1': {cards: [keptCard], cardsTimestamp: 0},
1162     'TEST GROUP 2': {cards: [newCard], cardsTimestamp: 0}
1163   };
1165   var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
1167   var expectedUpdatedNotifications = {
1168     'SHOULD BE KEPT': 'KEPT CARD NOTIFICATION DATA',
1169     'NEW CARD': 'NEW CARD NOTIFICATION DATA'
1170   };
1172   this.makeAndRegisterMockApis([
1173     'cardSet.update',
1174     'chrome.storage.local.set',
1175     'instrumented.notifications.getAll'
1176   ]);
1177   this.makeMockLocalFunctions([
1178     'onSuccess'
1179   ]);
1181   var notificationsGetAllSavedArgs = new SaveMockArguments();
1182   this.mockApis.expects(once()).
1183       instrumented_notifications_getAll(
1184           notificationsGetAllSavedArgs.match(ANYTHING)).
1185       will(invokeCallback(
1186           notificationsGetAllSavedArgs, 0, existingNotifications));
1188   this.mockApis.expects(once()).
1189       cardSet_update(
1190           'SHOULD BE KEPT',
1191           eqJSON([keptNotification]),
1192           eqJSON(notificationGroups),
1193           fakeOnCardShownFunction).
1194       will(returnValue('KEPT CARD NOTIFICATION DATA'));
1195   this.mockApis.expects(once()).
1196       cardSet_update(
1197           'NEW CARD',
1198           eqJSON([newNotification]),
1199           eqJSON(notificationGroups),
1200           fakeOnCardShownFunction).
1201       will(returnValue('NEW CARD NOTIFICATION DATA'));
1202   this.mockApis.expects(once()).
1203       cardSet_update(
1204           'SHOULD BE DELETED',
1205           [],
1206           eqJSON(notificationGroups),
1207           fakeOnCardShownFunction).
1208       will(returnValue(undefined));
1210   this.mockApis.expects(once()).
1211       chrome_storage_local_set(
1212           eqJSON({notificationsData: expectedUpdatedNotifications}));
1214   this.mockLocalFunctions.expects(once()).
1215       onSuccess(undefined);
1217   // Invoking the tested function.
1218   showNotificationGroups(notificationGroups, fakeOnCardShownFunction)
1219       .then(this.mockLocalFunctions.functions().onSuccess);
1222 TEST_F(TEST_NAME, 'ProcessServerResponse', function() {
1223   // Tests processServerResponse function.
1225   // Setup and expectations.
1226   Date.now = function() { return 3000000; };
1228   // GROUP1 was requested and contains cards c4 and c5. For c5, there is a
1229   // non-expired dismissal, so it will be ignored.
1230   // GROUP2 was not requested, but is contained in server response to
1231   // indicate that the group still exists. Stored group GROUP2 won't change.
1232   // GROUP3 is stored, but is not present in server's response, which means
1233   // it doesn't exist anymore. This group will be deleted.
1234   // GROUP4 doesn't contain cards, but it was requested. This is treated as
1235   // if it had an empty array of cards. Cards in the stored group will be
1236   // replaced with an empty array.
1237   // GROUP5 doesn't have next poll time, and it will be stored without next
1238   // poll time.
1239   var serverResponse = {
1240     groups: {
1241       GROUP1: {requested: true, nextPollSeconds: 46},
1242       GROUP2: {requested: false},
1243       GROUP4: {requested: true, nextPollSeconds: 45},
1244       GROUP5: {requested: true}
1245     },
1246     notifications: [
1247       {notificationId: 'c4', groupName: 'GROUP1'},
1248       {notificationId: 'c5', groupName: 'GROUP1'}
1249     ]
1250   };
1252   var recentDismissals = {
1253     c4: 1800000, // expired dismissal
1254     c5: 1800001  // non-expired dismissal
1255   };
1257   var storedGroups = {
1258     GROUP2: {
1259       cards: [{notificationId: 'c2'}],
1260       cardsTimestamp: 239,
1261       nextPollTime: 10000
1262     },
1263     GROUP3: {
1264       cards: [{notificationId: 'c3'}],
1265       cardsTimestamp: 240,
1266       nextPollTime: 10001
1267     },
1268     GROUP4: {
1269       cards: [{notificationId: 'c6'}],
1270       cardsTimestamp: 241,
1271       nextPollTime: 10002
1272     }
1273   };
1275   var expectedUpdatedGroups = {
1276     GROUP1: {
1277       cards: [{notificationId: 'c4', groupName: 'GROUP1'}],
1278       cardsTimestamp: 3000000,
1279       nextPollTime: 3046000
1280     },
1281     GROUP2: {
1282       cards: [{notificationId: 'c2'}],
1283       cardsTimestamp: 239,
1284       nextPollTime: 10000
1285     },
1286     GROUP4: {
1287       cards: [],
1288       cardsTimestamp: 3000000,
1289       nextPollTime: 3045000
1290     },
1291     GROUP5: {
1292       cards: [],
1293       cardsTimestamp: 3000000
1294     }
1295   };
1297   var expectedUpdatedRecentDismissals = {
1298     c5: 1800001
1299   };
1301   this.makeAndRegisterMockGlobals([
1302     'scheduleNextCardsPoll'
1303   ]);
1305   this.makeAndRegisterMockApis([
1306     'fillFromChromeLocalStorage',
1307   ]);
1309   expectChromeLocalStorageGet(
1310       this,
1311       {
1312         notificationGroups: {},
1313         recentDismissals: {}
1314       },
1315       {
1316         notificationGroups: storedGroups,
1317         recentDismissals: recentDismissals
1318       });
1320   this.mockGlobals.expects(once())
1321       .scheduleNextCardsPoll(eqJSON(expectedUpdatedGroups));
1323   // Invoking the tested function.
1324   processServerResponse(serverResponse);
1327 TEST_F(TEST_NAME, 'ProcessServerResponseGoogleNowDisabled', function() {
1328   // Tests processServerResponse function for the case when the response
1329   // indicates that Google Now is disabled.
1331   // Setup and expectations.
1332   var serverResponse = {
1333     googleNowDisabled: true,
1334     groups: {}
1335   };
1337   this.makeAndRegisterMockGlobals([
1338     'scheduleNextCardsPoll'
1339   ]);
1341   this.makeAndRegisterMockApis([
1342     'chrome.storage.local.set',
1343     'fillFromChromeLocalStorage'
1344   ]);
1346   this.mockApis.expects(once()).
1347       chrome_storage_local_set(eqJSON({googleNowEnabled: false}));
1349   this.mockGlobals.expects(never()).scheduleNextCardsPoll();
1351   // Invoking the tested function.
1352   processServerResponse(serverResponse);