Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / google_now / background_unittest.gtestjs
blob81dbadcd1cbe32e82a5a7879278f5263f01d082c
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 TEST_F('GoogleNowBackgroundUnitTest', 'AreTasksConflicting', function() {
28   function testTaskPair(newTaskName, scheduledTaskName, expected) {
29     assertTrue(areTasksConflicting(newTaskName, scheduledTaskName) == expected,
30                '(' + newTaskName + ', ' + scheduledTaskName + ')');
31   }
33   testTaskPair(UPDATE_CARDS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
34   testTaskPair(UPDATE_CARDS_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
35   testTaskPair(UPDATE_CARDS_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
36   testTaskPair(UPDATE_CARDS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
38   testTaskPair(DISMISS_CARD_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
39   testTaskPair(DISMISS_CARD_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
40   testTaskPair(DISMISS_CARD_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
41   testTaskPair(DISMISS_CARD_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
43   testTaskPair(RETRY_DISMISS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
44   testTaskPair(RETRY_DISMISS_TASK_NAME, DISMISS_CARD_TASK_NAME, true);
45   testTaskPair(RETRY_DISMISS_TASK_NAME, RETRY_DISMISS_TASK_NAME, true);
46   testTaskPair(RETRY_DISMISS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
48   testTaskPair(STATE_CHANGED_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
49   testTaskPair(STATE_CHANGED_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
50   testTaskPair(STATE_CHANGED_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
51   testTaskPair(STATE_CHANGED_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
52 });
54 /**
55  * Mocks global functions and APIs that initialize() depends upon.
56  * @param {Test} fixture Test fixture.
57  */
58 function mockInitializeDependencies(fixture) {
59   fixture.makeAndRegisterMockGlobals([
60     'recordEvent',
61     'setBackgroundEnable',
62     'startPollingCards'
63   ]);
64   fixture.makeAndRegisterMockApis([
65     'authenticationManager.isSignedIn',
66     'chrome.location.clearWatch',
67     'chrome.storage.local.remove',
68     'instrumented.metricsPrivate.getVariationParams',
69     'instrumented.notifications.getAll',
70     'instrumented.notifications.getPermissionLevel',
71     'instrumented.preferencesPrivate.googleGeolocationAccessEnabled.get',
72     'instrumented.storage.local.get',
73     'tasks.add',
74     'updateCardsAttempts.isRunning',
75     'updateCardsAttempts.stop'
76   ]);
79 /**
80  * Sets up the test to expect the state machine calls and send
81  * the specified state machine state. Currently used to test initialize().
82  * Note that this CAN NOT be used if any of the methods below are called
83  * outside of this context with the same argument matchers.
84  * expects() calls cannot be chained with the same argument matchers.
85  * @param {object} fixture Test fixture.
86  * @param {string} testIdentityToken getAuthToken callback token.
87  * @param {boolean} testGeolocationPref Geolocation Preference callback value.
88  * @param {object} testExperimentVariationParams Response of
89  *     metricsPrivate.getVariationParams.
90  * @param {string} testExperimentVariationParams Response of
91  *     notifications.getPermissionLevel.
92  * @param {boolean} testGoogleNowEnabled True if the user is opted in to Google
93  *     Now.
94  */
95 function expectStateMachineCalls(
96     fixture,
97     testIdentityToken,
98     testGeolocationPref,
99     testExperimentVariationParams,
100     testNotificationPermissionLevel,
101     testGoogleNowEnabled) {
102   var authenticationManagerIsSignedInSavedArgs = new SaveMockArguments();
103   fixture.mockApis.expects(once()).
104       authenticationManager_isSignedIn(
105           authenticationManagerIsSignedInSavedArgs.match(ANYTHING)).
106       will(invokeCallback(
107           authenticationManagerIsSignedInSavedArgs,
108           0,
109           testIdentityToken));
111   var getVariationParamsSavedArgs = new SaveMockArguments();
112   fixture.mockApis.expects(once()).
113       instrumented_metricsPrivate_getVariationParams(
114           getVariationParamsSavedArgs.match(ANYTHING),
115           getVariationParamsSavedArgs.match(ANYTHING)).
116       will(invokeCallback(
117           getVariationParamsSavedArgs, 1, testExperimentVariationParams));
119   var googleGeolocationPrefGetSavedArgs = new SaveMockArguments();
120   fixture.mockApis.expects(once()).
121       instrumented_preferencesPrivate_googleGeolocationAccessEnabled_get(
122           googleGeolocationPrefGetSavedArgs.match(eqJSON({})),
123           googleGeolocationPrefGetSavedArgs.match(ANYTHING)).
124       will(invokeCallback(
125           googleGeolocationPrefGetSavedArgs, 1, {value: testGeolocationPref}));
127   var notificationGetPermissionLevelSavedArgs = new SaveMockArguments();
128   fixture.mockApis.expects(once()).
129       instrumented_notifications_getPermissionLevel(
130           notificationGetPermissionLevelSavedArgs.match(ANYTHING)).
131       will(invokeCallback(
132           notificationGetPermissionLevelSavedArgs,
133           0,
134           testNotificationPermissionLevel))
136    var storageGetSavedArgs = new SaveMockArguments();    
137    fixture.mockApis.expects(once()).     
138        instrumented_storage_local_get(   
139            storageGetSavedArgs.match(eq('googleNowEnabled')),    
140            storageGetSavedArgs.match(ANYTHING)).         
141        will(invokeCallback(
142           storageGetSavedArgs, 1, {googleNowEnabled: testGoogleNowEnabled}));    
144   fixture.mockGlobals.expects(once()).
145       setBackgroundEnable(ANYTHING);
149  * Sets up the test to expect the initialization calls that
150  * initialize() invokes.
151  * Note that this CAN NOT be used if any of the methods below are called
152  * outside of this context with the same argument matchers.
153  * expects() calls cannot be chained with the same argument matchers.
154  */
155 function expectInitialization(mockApisObj) {
156   var tasksAddSavedArgs = new SaveMockArguments();
157   mockApisObj.expects(once()).
158       tasks_add(
159           tasksAddSavedArgs.match(ANYTHING),
160           tasksAddSavedArgs.match(ANYTHING)).
161       will(invokeCallback(tasksAddSavedArgs, 1, function() {}));
162   var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments();
163   mockApisObj.expects(once()).
164       updateCardsAttempts_isRunning(
165           updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)).
166       will(
167           invokeCallback(
168              updateCardsAttemptsIsRunningSavedArgs, 0, false));
171 TEST_F(
172     'GoogleNowBackgroundUnitTest',
173     'Initialize_ToastStateEmpty',
174     function() {
175       // Tests the case when getAuthToken fails most likely because the user is
176       // not signed in. In this case, the function should quietly exit after
177       // finding out that getAuthToken fails.
179       // Setup and expectations.
180       var testIdentityToken = undefined;
181       var testGeolocationPref = false;
182       var testExperimentVariationParams = {};
183       var testNotificationPermissionLevel = 'denied';
184       var testGoogleNowEnabled = undefined;
186       mockInitializeDependencies(this);
188       this.mockGlobals.expects(once()).recordEvent(
189           GoogleNowEvent.EXTENSION_START);
191       this.mockGlobals.expects(once()).recordEvent(
192           GoogleNowEvent.STOPPED);
194       expectInitialization(this.mockApis);
196       expectStateMachineCalls(
197           this,
198           testIdentityToken,
199           testGeolocationPref,
200           testExperimentVariationParams,
201           testNotificationPermissionLevel,
202           testGoogleNowEnabled);
204       // Invoking the tested function.
205       initialize();
206     });
208 TEST_F(
209     'GoogleNowBackgroundUnitTest',
210     'DISABLED_Initialize_ToastStateEmpty2',
211     function() {
212       // Tests the case when getAuthToken succeeds, and the user has never
213       // responded to the toast.
214       // In this case, the function should invoke showWelcomeToast().
216       // Setup and expectations.
217       var testIdentityToken = 'some identity token';
218       var testGeolocationPref = false;
219       var testExperimentVariationParams = {};
220       var testNotificationPermissionLevel = 'denied';
221       var testGoogleNowEnabled = undefined;
223       mockInitializeDependencies(this);
225       this.mockGlobals.expects(once()).recordEvent(
226           GoogleNowEvent.EXTENSION_START);
228       expectInitialization(this.mockApis);
230       expectStateMachineCalls(
231           this,
232           testIdentityToken,
233           testGeolocationPref,
234           testExperimentVariationParams,
235           testNotificationPermissionLevel,
236           testGoogleNowEnabled);
238       var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
239       this.mockApis.expects(exactly(1)).
240           instrumented_notifications_getAll(
241               chromeNotificationGetAllSavedArgs.match(ANYTHING)).
242           will(
243               invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
244               invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));
246       // Invoking the tested function.
247       initialize();
248     });
250 TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_RunGoogleNow', function() {
251   // Tests if Google Now will invoke startPollingCards when all
252   // of the required state is fulfilled.
254   // Setup and expectations.
255   var testIdentityToken = 'some identity token';
256   var testGeolocationPref = true;
257   var testExperimentVariationParams = {};
258   var testNotificationPermissionLevel = 'granted';
259   var testGoogleNowEnabled = true;
261   mockInitializeDependencies(this);
263   this.mockGlobals.expects(once()).recordEvent(
264         GoogleNowEvent.EXTENSION_START);
266   expectInitialization(this.mockApis);
268   expectStateMachineCalls(
269       this,
270       testIdentityToken,
271       testGeolocationPref,
272       testExperimentVariationParams,
273       testNotificationPermissionLevel,
274       testGoogleNowEnabled);
276   this.mockGlobals.expects(once()).startPollingCards();
278   // Invoking the tested function.
279   initialize();
282 TEST_F(
283     'GoogleNowBackgroundUnitTest',
284     'DISABLED_Initialize_NoGeolocation',
285     function() {
286   // Tests the case where everything is in place except for the
287   // Geolocation Preference after the user responded to the toast.
289   // Setup and expectations.
290   var testIdentityToken = 'some identity token';
291   var testGeolocationPref = false;
292   var testExperimentVariationParams = {};
293   var testNotificationPermissionLevel = 'denied';
294   var testGoogleNowEnabled = undefined;
297   mockInitializeDependencies(this);
299   this.mockGlobals.expects(once()).recordEvent(
300         GoogleNowEvent.EXTENSION_START);
302   this.mockGlobals.expects(once()).recordEvent(
303       GoogleNowEvent.USER_SUPPRESSED);
305   expectInitialization(this.mockApis);
307   expectStateMachineCalls(
308       this,
309       testIdentityToken,
310       testGeolocationPref,
311       testExperimentVariationParams,
312       testNotificationPermissionLevel,
313       testNotificationPermissionLevel,
314       testGoogleNowEnabled);
316   var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
317   this.mockApis.expects(exactly(2)).
318       instrumented_notifications_getAll(
319           chromeNotificationGetAllSavedArgs.match(ANYTHING)).
320       will(
321           invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
322           invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));
324   // Invoking the tested function.
325   initialize();
329  * Mocks global functions and APIs that onNotificationClicked() depends upon.
330  * @param {Test} fixture Test fixture.
331  */
332 function mockOnNotificationClickedDependencies(fixture) {
333   fixture.makeAndRegisterMockApis([
334       'chrome.windows.create',
335       'chrome.windows.update',
336       'instrumented.storage.local.get',
337       'instrumented.tabs.create']);
340 TEST_F(
341     'GoogleNowBackgroundUnitTest',
342     'OnNotificationClicked_NoData',
343     function() {
344       // Tests the case when there is no data associated with notification id.
345       // In this case, the function should do nothing.
347       // Setup and expectations.
348       var testNotificationId = 'TEST_ID';
349       var testNotificationData = {};
351       mockOnNotificationClickedDependencies(this);
352       this.makeMockLocalFunctions(['selector']);
354       var storageGetSavedArgs = new SaveMockArguments();
355       this.mockApis.expects(once()).
356           instrumented_storage_local_get(
357               storageGetSavedArgs.match(eq('notificationsData')),
358               storageGetSavedArgs.match(ANYTHING)).
359           will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
361       // Invoking the tested function.
362       onNotificationClicked(
363           testNotificationId, this.mockLocalFunctions.functions().selector);
364     });
366 TEST_F(
367     'GoogleNowBackgroundUnitTest',
368     'OnNotificationClicked_ActionUrlsUndefined',
369     function() {
370       // Tests the case when the data associated with notification id is
371       // 'undefined'.
372       // In this case, the function should do nothing.
374       // Setup and expectations.
375       var testActionUrls = undefined;
376       var testNotificationId = 'TEST_ID';
377       var testNotificationData = {
378           notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
379       };
381       mockOnNotificationClickedDependencies(this);
382       this.makeMockLocalFunctions(['selector']);
384       var storageGetSavedArgs = new SaveMockArguments();
385       this.mockApis.expects(once()).
386           instrumented_storage_local_get(
387               storageGetSavedArgs.match(eq('notificationsData')),
388               storageGetSavedArgs.match(ANYTHING)).
389           will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
390       this.mockLocalFunctions.expects(once()).selector(undefined).will(
391           returnValue(undefined));
393       // Invoking the tested function.
394       onNotificationClicked(
395           testNotificationId, this.mockLocalFunctions.functions().selector);
396     });
398 TEST_F(
399     'GoogleNowBackgroundUnitTest',
400     'OnNotificationClicked_TabCreateSuccess',
401     function() {
402       // Tests the selected URL is OK and crome.tabs.create suceeds.
404       // Setup and expectations.
405       var testActionUrls = {testField: 'TEST VALUE'};
406       var testNotificationId = 'TEST_ID';
407       var testNotificationData = {
408           notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
409       };
410       var testActionUrl = 'http://testurl.com';
411       var testCreatedTab = {windowId: 239};
413       mockOnNotificationClickedDependencies(this);
414       this.makeMockLocalFunctions(['selector']);
416       var storageGetSavedArgs = new SaveMockArguments();
417       this.mockApis.expects(once()).
418           instrumented_storage_local_get(
419               storageGetSavedArgs.match(eq('notificationsData')),
420               storageGetSavedArgs.match(ANYTHING)).
421           will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
422       this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
423           returnValue(testActionUrl));
424       var chromeTabsCreateSavedArgs = new SaveMockArguments();
425       this.mockApis.expects(once()).
426           instrumented_tabs_create(
427               chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
428               chromeTabsCreateSavedArgs.match(ANYTHING)).
429           will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
430       this.mockApis.expects(once()).chrome_windows_update(
431           testCreatedTab.windowId,
432           eqJSON({focused: true}));
434       // Invoking the tested function.
435       onNotificationClicked(
436           testNotificationId, this.mockLocalFunctions.functions().selector);
437     });
439 TEST_F(
440     'GoogleNowBackgroundUnitTest',
441     'OnNotificationClicked_TabCreateFail',
442     function() {
443       // Tests the selected URL is OK and crome.tabs.create fails.
444       // In this case, the function should invoke chrome.windows.create as a
445       // second attempt.
447       // Setup and expectations.
448       var testActionUrls = {testField: 'TEST VALUE'};
449       var testNotificationId = 'TEST_ID';
450       var testNotificationData = {
451         notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
452       };
453       var testActionUrl = 'http://testurl.com';
454       var testCreatedTab = undefined; // chrome.tabs.create fails
456       mockOnNotificationClickedDependencies(this);
457       this.makeMockLocalFunctions(['selector']);
459       var storageGetSavedArgs = new SaveMockArguments();
460       this.mockApis.expects(once()).
461           instrumented_storage_local_get(
462               storageGetSavedArgs.match(eq('notificationsData')),
463               storageGetSavedArgs.match(ANYTHING)).
464           will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
465       this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
466           returnValue(testActionUrl));
467       var chromeTabsCreateSavedArgs = new SaveMockArguments();
468       this.mockApis.expects(once()).
469           instrumented_tabs_create(
470               chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
471               chromeTabsCreateSavedArgs.match(ANYTHING)).
472           will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
473       this.mockApis.expects(once()).chrome_windows_create(
474           eqJSON({url: testActionUrl, focused: true}));
476       // Invoking the tested function.
477       onNotificationClicked(
478           testNotificationId, this.mockLocalFunctions.functions().selector);
479     });
481 TEST_F(
482     'GoogleNowBackgroundUnitTest',
483     'ShowNotificationCards',
484     function() {
485       // Tests showNotificationCards function. Checks that the function properly
486       // deletes the card that didn't get an update, updates existing card and
487       // creates a new card that previously didn't exist.
489       // Setup and expectations.
490       var existingNotifications = {
491         'SHOULD BE DELETED': 'SOMETHING',
492         'SHOULD BE KEPT': 'SOMETHING'
493       };
495       var notificationGroups = {
496         TEST_FIELD: 'TEST VALUE'
497       };
499       var cards = {
500         'SHOULD BE KEPT': [1],
501         'NEW CARD': [2]
502       };
504       var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
506       var expectedUpdatedNotifications = {
507         'SHOULD BE KEPT': 'KEPT CARD NOTIFICATION DATA',
508         'NEW CARD': 'NEW CARD NOTIFICATION DATA'
509       };
511       this.makeAndRegisterMockApis([
512         'cardSet.update',
513         'chrome.storage.local.set',
514         'instrumented.notifications.getAll'
515       ]);
516       this.makeMockLocalFunctions([
517         'onSuccess'
518       ]);
520       var notificationsGetAllSavedArgs = new SaveMockArguments();
521       this.mockApis.expects(once()).
522           instrumented_notifications_getAll(
523               notificationsGetAllSavedArgs.match(ANYTHING)).
524           will(invokeCallback(
525               notificationsGetAllSavedArgs, 0, existingNotifications));
527       this.mockApis.expects(once()).
528           cardSet_update(
529               'SHOULD BE KEPT',
530               [1],
531               eqJSON(notificationGroups),
532               fakeOnCardShownFunction).
533           will(returnValue('KEPT CARD NOTIFICATION DATA'));
534       this.mockApis.expects(once()).
535           cardSet_update(
536               'NEW CARD',
537               [2],
538               eqJSON(notificationGroups),
539               fakeOnCardShownFunction).
540           will(returnValue('NEW CARD NOTIFICATION DATA'));
541       this.mockApis.expects(once()).
542           cardSet_update(
543               'SHOULD BE DELETED',
544               [],
545               eqJSON(notificationGroups),
546               fakeOnCardShownFunction).
547           will(returnValue(undefined));
549       this.mockApis.expects(once()).
550           chrome_storage_local_set(
551               eqJSON({notificationsData: expectedUpdatedNotifications}));
553       this.mockLocalFunctions.expects(once()).
554           onSuccess();
556       // Invoking the tested function.
557       showNotificationCards(
558           notificationGroups,
559           cards,
560           this.mockLocalFunctions.functions().onSuccess,
561           fakeOnCardShownFunction);
562     });
564 TEST_F(
565     'GoogleNowBackgroundUnitTest',
566     'CombineGroup',
567     function() {
568       // Tests combineGroup function. Verifies that both notifications with and
569       // without show time are handled correctly and that cards are correctly
570       // added to existing cards with same ID or start a new combined card.
572       // Setup and expectations.
573       var combinedCards = {
574         'EXISTING CARD': [1]
575       };
577       var receivedNotificationNoShowTime = {
578         chromeNotificationId: 'EXISTING CARD',
579         trigger: {hideTimeSec: 1}
580       };
581       var receivedNotificationWithShowTime = {
582         chromeNotificationId: 'NEW CARD',
583         trigger: {showTimeSec: 2, hideTimeSec: 3}
584       }
586       var storedGroup = {
587         cardsTimestamp: 10000,
588         cards: [
589           receivedNotificationNoShowTime,
590           receivedNotificationWithShowTime
591         ]
592       };
594       // Invoking the tested function.
595       combineGroup(combinedCards, storedGroup);
597       // Check the output value.
598       var expectedCombinedCards = {
599         'EXISTING CARD': [
600           1, 
601           {
602             receivedNotification: receivedNotificationNoShowTime,
603             hideTime: 11000
604           }
605         ],
606         'NEW CARD': [
607           {
608             receivedNotification: receivedNotificationWithShowTime,
609             showTime: 12000,
610             hideTime: 13000
611           }
612         ]
613       };
615       assertEquals(
616           JSON.stringify(expectedCombinedCards),
617           JSON.stringify(combinedCards));
618     });
620 TEST_F(
621     'GoogleNowBackgroundUnitTest',
622     'CombineAndShowNotificationCards',
623     function() {
624       // Tests combineAndShowNotificationCards function.
625       // The test passes 2 groups to combineAndShowNotificationCards, checks
626       // that it calls combineGroup() for each of these groups and calls
627       // showNotificationCards() with the results of these combineGroup() calls.
629       // Setup and expectations.
630       var testGroups = {
631         'TEST GROUP 1': {testField: 'TEST VALUE 1'},
632         'TEST GROUP 2': {testField: 'TEST VALUE 2'}
633       };
635       var fakeOnSuccessFunction = 'FAKE ON SUCCESS FUNCTION';
636       var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
638       this.makeAndRegisterMockGlobals(
639           ['combineGroup', 'showNotificationCards']);
641       var combineGroupSavedArgs = new SaveMockArguments();
642       this.mockGlobals.expects(once()).
643           combineGroup(
644               combineGroupSavedArgs.match(eqJSON({})),
645               combineGroupSavedArgs.match(eqJSON({testField: 'TEST VALUE 1'}))).
646           will(callFunction(function() {
647             combineGroupSavedArgs.arguments[0].card1 = {
648               testValue: 'TEST CARD VALUE 1'
649             };
650           }));
651       this.mockGlobals.expects(once()).
652           combineGroup(
653               combineGroupSavedArgs.match(
654                   eqJSON({card1: {testValue: 'TEST CARD VALUE 1'}})),
655               combineGroupSavedArgs.match(
656                   eqJSON({testField: 'TEST VALUE 2'}))).
657           will(callFunction(function() {
658               combineGroupSavedArgs.arguments[0].card2 = {
659                 testValue: 'TEST CARD VALUE 2'
660               };
661           }));
662       this.mockGlobals.expects(once()).
663           showNotificationCards(
664               eqJSON(testGroups),
665               eqJSON({
666                 card1: {testValue: 'TEST CARD VALUE 1'},
667                 card2: {testValue: 'TEST CARD VALUE 2'}
668               }),
669               fakeOnSuccessFunction,
670               fakeOnCardShownFunction);
672       // Invoking the tested function.
673       combineAndShowNotificationCards(
674           testGroups, fakeOnSuccessFunction, fakeOnCardShownFunction);
675     });
677 TEST_F(
678     'GoogleNowBackgroundUnitTest',
679     'ProcessServerResponse',
680     function() {
681       // Tests processServerResponse function.
683       // Setup and expectations.
684       Date.now = function() { return 3000000; };
686       // GROUP1 was requested and contains cards c4 and c5. For c5, there is a
687       // non-expired dismissal, so it will be ignored.
688       // GROUP2 was not requested, but is contained in server response to
689       // indicate that the group still exists. Stored group GROUP2 won't change.
690       // GROUP3 is stored, but is not present in server's response, which means
691       // it doesn't exist anymore. This group will be deleted.
692       // GROUP4 doesn't contain cards, but it was requested. This is treated as
693       // if it had an empty array of cards. Cards in the stored group will be
694       // replaced with an empty array.
695       // GROUP5 doesn't have next poll time, and it will be stored without next
696       // poll time.
697       var serverResponse = {
698         groups: {
699           GROUP1: {requested: true, nextPollSeconds: 46},
700           GROUP2: {requested: false},
701           GROUP4: {requested: true, nextPollSeconds: 45},
702           GROUP5: {requested: true}
703         },
704         notifications: [
705           {notificationId: 'c4', groupName: 'GROUP1'},
706           {notificationId: 'c5', groupName: 'GROUP1'}
707         ]
708       };
710       var recentDismissals = {
711         c4: 1800000, // expired dismissal
712         c5: 1800001  // non-expired dismissal
713       };
715       var storedGroups = {
716         GROUP2: {
717           cards: [{notificationId: 'c2'}],
718           cardsTimestamp: 239,
719           nextPollTime: 10000
720         },
721         GROUP3: {
722           cards: [{notificationId: 'c3'}],
723           cardsTimestamp: 240,
724           nextPollTime: 10001
725         },
726         GROUP4: {
727           cards: [{notificationId: 'c6'}],
728           cardsTimestamp: 241,
729           nextPollTime: 10002
730         }
731       };
733       var expectedUpdatedGroups = {
734         GROUP1: {
735           cards: [{notificationId: 'c4', groupName: 'GROUP1'}],
736           cardsTimestamp: 3000000,
737           nextPollTime: 3046000
738         },
739         GROUP2: {
740           cards: [{notificationId: 'c2'}],
741           cardsTimestamp: 239,
742           nextPollTime: 10000
743         },
744         GROUP4: {
745           cards: [],
746           cardsTimestamp: 3000000,
747           nextPollTime: 3045000
748         },
749         GROUP5: {
750           cards: [],
751           cardsTimestamp: 3000000
752         }
753       };
755       var expectedUpdatedRecentDismissals = {
756         c5: 1800001
757       };
759       var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
761       this.makeAndRegisterMockGlobals([
762         'scheduleNextPoll',
763         'combineAndShowNotificationCards',
764         'recordEvent'
765       ]);
767       this.makeAndRegisterMockApis([
768         'chrome.storage.local.set',
769         'instrumented.storage.local.get'
770       ]);
772       var storageGetSavedArgs = new SaveMockArguments();
773       this.mockApis.expects(once()).
774           instrumented_storage_local_get(
775               storageGetSavedArgs.match(
776                   eq(['notificationGroups', 'recentDismissals'])),
777               storageGetSavedArgs.match(ANYTHING)).
778           will(invokeCallback(
779               storageGetSavedArgs,
780               1,
781               {
782                 notificationGroups: storedGroups,
783                 recentDismissals: recentDismissals
784               }));
786       this.mockGlobals.expects(once()).
787           scheduleNextPoll(eqJSON(expectedUpdatedGroups), true);
789       var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments();
790       this.mockGlobals.expects(once()).
791           combineAndShowNotificationCards(
792               combineAndShowNotificationCardsSavedArgs.match(
793                   eqJSON(expectedUpdatedGroups)),
794               combineAndShowNotificationCardsSavedArgs.match(
795                   ANYTHING),
796               combineAndShowNotificationCardsSavedArgs.match(
797                   eq(fakeOnCardShownFunction))).
798           will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1));
800       this.mockApis.expects(once()).
801           chrome_storage_local_set(
802               eqJSON({
803                 notificationGroups: expectedUpdatedGroups,
804                 recentDismissals: expectedUpdatedRecentDismissals}));
806       this.mockGlobals.expects(once()).
807           recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
809       // Invoking the tested function.
810       processServerResponse(serverResponse, fakeOnCardShownFunction);
811     });
813 TEST_F(
814     'GoogleNowBackgroundUnitTest',
815     'ProcessServerResponseGoogleNowDisabled',
816     function() {
817       // Tests processServerResponse function for the case when the response
818       // indicates that Google Now is disabled.
820       // Setup and expectations.
821       var serverResponse = {
822         googleNowDisabled: true,
823         groups: {
824           GROUP1: {nextPollTimeSeconds: 200}
825         }
826       };
828       var storedGroups = {
829         GROUP2: {
830           cards: [{notificationId: 'c2'}],
831           cardsTimestamp: 239,
832           nextPollTime: 10000
833         },
834         GROUP3: {
835           cards: [{notificationId: 'c3'}],
836           cardsTimestamp: 240,
837           nextPollTime: 10001
838         }
839       };
841       var expectedUpdatedGroups = {
842       };
844       var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
846       this.makeAndRegisterMockGlobals([
847         'scheduleNextPoll',
848         'combineAndShowNotificationCards',
849         'recordEvent',
850         'onStateChange'
851       ]);
853       this.makeAndRegisterMockApis([
854         'chrome.storage.local.set',
855         'instrumented.storage.local.get'
856       ]);
858       this.mockApis.expects(once()).
859           chrome_storage_local_set(
860               eqJSON({googleNowEnabled: false}));
862       this.mockGlobals.expects(once()).onStateChange();
864       var storageGetSavedArgs = new SaveMockArguments();
865       this.mockApis.expects(once()).
866           instrumented_storage_local_get(
867               storageGetSavedArgs.match(
868                   eq(['notificationGroups', 'recentDismissals'])),
869               storageGetSavedArgs.match(ANYTHING)).
870           will(invokeCallback(
871               storageGetSavedArgs, 1, {notificationGroups: storedGroups}));
873       this.mockGlobals.expects(once()).
874           scheduleNextPoll(eqJSON(expectedUpdatedGroups), false);
876       var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments();
877       this.mockGlobals.expects(once()).
878           combineAndShowNotificationCards(
879               combineAndShowNotificationCardsSavedArgs.match(
880                   eqJSON(expectedUpdatedGroups)),
881               combineAndShowNotificationCardsSavedArgs.match(
882                   ANYTHING),
883               combineAndShowNotificationCardsSavedArgs.match(
884                   eq(fakeOnCardShownFunction))).
885           will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1));
887       this.mockApis.expects(once()).
888           chrome_storage_local_set(
889               eqJSON({
890                 notificationGroups: expectedUpdatedGroups,
891                 recentDismissals: {}}));
893       this.mockGlobals.expects(once()).
894           recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
896       // Invoking the tested function.
897       processServerResponse(serverResponse, fakeOnCardShownFunction);
898     });