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.
8 * Test fixture for background.js.
10 * @extends {testing.Test}
12 function GoogleNowBackgroundUnitTest () {
13 testing.Test.call(this);
16 GoogleNowBackgroundUnitTest.prototype = {
17 __proto__: testing.Test.prototype,
21 'common_test_util.js',
22 'background_test_util.js',
27 TEST_F('GoogleNowBackgroundUnitTest', 'AreTasksConflicting', function() {
28 function testTaskPair(newTaskName, scheduledTaskName, expected) {
29 assertTrue(areTasksConflicting(newTaskName, scheduledTaskName) == expected,
30 '(' + newTaskName + ', ' + scheduledTaskName + ')');
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);
55 * Mocks global functions and APIs that initialize() depends upon.
56 * @param {Test} fixture Test fixture.
58 function mockInitializeDependencies(fixture) {
59 fixture.makeAndRegisterMockGlobals([
61 'setBackgroundEnable',
64 fixture.makeAndRegisterMockApis([
65 'authenticationManager.isSignedIn',
66 'chrome.storage.local.remove',
67 'instrumented.metricsPrivate.getVariationParams',
68 'instrumented.notifications.getAll',
69 'instrumented.notifications.getPermissionLevel',
70 'instrumented.storage.local.get',
71 'instrumented.webstorePrivate.getBrowserLogin',
73 'updateCardsAttempts.isRunning',
74 'updateCardsAttempts.stop'
79 * Sets up the test to expect the state machine calls and send
80 * the specified state machine state. Currently used to test initialize().
81 * Note that this CAN NOT be used if any of the methods below are called
82 * outside of this context with the same argument matchers.
83 * expects() calls cannot be chained with the same argument matchers.
84 * @param {object} fixture Test fixture.
85 * @param {string} testIdentityToken getAuthToken callback token.
86 * @param {object} testExperimentVariationParams Response of
87 * metricsPrivate.getVariationParams.
88 * @param {string} testExperimentVariationParams Response of
89 * notifications.getPermissionLevel.
90 * @param {boolean} testGoogleNowEnabled True if the user is opted in to Google
93 function expectStateMachineCalls(
96 testExperimentVariationParams,
97 testNotificationPermissionLevel,
98 testGoogleNowEnabled) {
99 fixture.mockApis.expects(once()).
100 authenticationManager_isSignedIn().
101 will(returnValue(new Promise(function(resolve) {
102 resolve(!!testIdentityToken);
105 var getVariationParamsSavedArgs = new SaveMockArguments();
106 fixture.mockApis.expects(once()).
107 instrumented_metricsPrivate_getVariationParams(
108 getVariationParamsSavedArgs.match(ANYTHING),
109 getVariationParamsSavedArgs.match(ANYTHING)).
111 getVariationParamsSavedArgs, 1, testExperimentVariationParams));
113 var notificationGetPermissionLevelSavedArgs = new SaveMockArguments();
114 fixture.mockApis.expects(once()).
115 instrumented_notifications_getPermissionLevel(
116 notificationGetPermissionLevelSavedArgs.match(ANYTHING)).
118 notificationGetPermissionLevelSavedArgs,
120 testNotificationPermissionLevel))
122 var storageGetSavedArgs = new SaveMockArguments();
123 fixture.mockApis.expects(once()).
124 instrumented_storage_local_get(
125 storageGetSavedArgs.match(eq('googleNowEnabled')),
126 storageGetSavedArgs.match(ANYTHING)).
128 storageGetSavedArgs, 1, {googleNowEnabled: testGoogleNowEnabled}));
130 fixture.mockGlobals.expects(once()).
131 setBackgroundEnable(ANYTHING);
135 * Sets up the test to expect the initialization calls that
136 * initialize() invokes.
137 * Note that this CAN NOT be used if any of the methods below are called
138 * outside of this context with the same argument matchers.
139 * expects() calls cannot be chained with the same argument matchers.
141 function expectInitialization(mockApisObj) {
142 var tasksAddSavedArgs = new SaveMockArguments();
143 mockApisObj.expects(once()).
145 tasksAddSavedArgs.match(ANYTHING),
146 tasksAddSavedArgs.match(ANYTHING)).
147 will(invokeCallback(tasksAddSavedArgs, 1, function() {}));
148 var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments();
149 mockApisObj.expects(once()).
150 updateCardsAttempts_isRunning(
151 updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)).
154 updateCardsAttemptsIsRunningSavedArgs, 0, false));
158 'GoogleNowBackgroundUnitTest',
159 'Initialize_ToastStateEmpty',
161 // Tests the case when getAuthToken fails most likely because the user is
162 // not signed in. In this case, the function should quietly exit after
163 // finding out that getAuthToken fails.
165 // Setup and expectations.
166 var testIdentityToken = undefined;
167 var testExperimentVariationParams = {};
168 var testNotificationPermissionLevel = 'denied';
169 var testGoogleNowEnabled = undefined;
171 mockInitializeDependencies(this);
173 this.mockGlobals.expects(once()).recordEvent(
174 GoogleNowEvent.EXTENSION_START);
176 this.mockGlobals.expects(once()).recordEvent(
177 GoogleNowEvent.STOPPED);
179 expectInitialization(this.mockApis);
181 expectStateMachineCalls(
184 testExperimentVariationParams,
185 testNotificationPermissionLevel,
186 testGoogleNowEnabled);
188 // Invoking the tested function.
192 TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_RunGoogleNow', function() {
193 // Tests if Google Now will invoke startPollingCards when all
194 // of the required state is fulfilled.
196 // Setup and expectations.
197 var testIdentityToken = 'some identity token';
198 var testExperimentVariationParams = {};
199 var testNotificationPermissionLevel = 'granted';
200 var testGoogleNowEnabled = true;
202 mockInitializeDependencies(this);
204 this.mockGlobals.expects(once()).recordEvent(
205 GoogleNowEvent.EXTENSION_START);
207 expectInitialization(this.mockApis);
209 expectStateMachineCalls(
212 testExperimentVariationParams,
213 testNotificationPermissionLevel,
214 testGoogleNowEnabled);
216 this.mockGlobals.expects(once()).startPollingCards();
218 // Invoking the tested function.
223 * Mocks global functions and APIs that onNotificationClicked() depends upon.
224 * @param {Test} fixture Test fixture.
226 function mockOnNotificationClickedDependencies(fixture) {
227 fixture.makeAndRegisterMockApis([
228 'chrome.windows.create',
229 'chrome.windows.update',
230 'instrumented.storage.local.get',
231 'instrumented.tabs.create']);
235 'GoogleNowBackgroundUnitTest',
236 'OnNotificationClicked_NoData',
238 // Tests the case when there is no data associated with notification id.
239 // In this case, the function should do nothing.
241 // Setup and expectations.
242 var testNotificationId = 'TEST_ID';
243 var testNotificationData = {};
245 mockOnNotificationClickedDependencies(this);
246 this.makeMockLocalFunctions(['selector']);
248 var storageGetSavedArgs = new SaveMockArguments();
249 this.mockApis.expects(once()).
250 instrumented_storage_local_get(
251 storageGetSavedArgs.match(eq('notificationsData')),
252 storageGetSavedArgs.match(ANYTHING)).
253 will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
255 // Invoking the tested function.
256 onNotificationClicked(
257 testNotificationId, this.mockLocalFunctions.functions().selector);
261 'GoogleNowBackgroundUnitTest',
262 'OnNotificationClicked_ActionUrlsUndefined',
264 // Tests the case when the data associated with notification id is
266 // In this case, the function should do nothing.
268 // Setup and expectations.
269 var testActionUrls = undefined;
270 var testNotificationId = 'TEST_ID';
271 var testNotificationData = {
272 notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
275 mockOnNotificationClickedDependencies(this);
276 this.makeMockLocalFunctions(['selector']);
278 var storageGetSavedArgs = new SaveMockArguments();
279 this.mockApis.expects(once()).
280 instrumented_storage_local_get(
281 storageGetSavedArgs.match(eq('notificationsData')),
282 storageGetSavedArgs.match(ANYTHING)).
283 will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
284 this.mockLocalFunctions.expects(once()).selector(undefined).will(
285 returnValue(undefined));
287 // Invoking the tested function.
288 onNotificationClicked(
289 testNotificationId, this.mockLocalFunctions.functions().selector);
293 'GoogleNowBackgroundUnitTest',
294 'OnNotificationClicked_TabCreateSuccess',
296 // Tests the selected URL is OK and crome.tabs.create suceeds.
298 // Setup and expectations.
299 var testActionUrls = {testField: 'TEST VALUE'};
300 var testNotificationId = 'TEST_ID';
301 var testNotificationData = {
302 notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
304 var testActionUrl = 'http://testurl.com';
305 var testCreatedTab = {windowId: 239};
307 mockOnNotificationClickedDependencies(this);
308 this.makeMockLocalFunctions(['selector']);
310 var storageGetSavedArgs = new SaveMockArguments();
311 this.mockApis.expects(once()).
312 instrumented_storage_local_get(
313 storageGetSavedArgs.match(eq('notificationsData')),
314 storageGetSavedArgs.match(ANYTHING)).
315 will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
316 this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
317 returnValue(testActionUrl));
318 var chromeTabsCreateSavedArgs = new SaveMockArguments();
319 this.mockApis.expects(once()).
320 instrumented_tabs_create(
321 chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
322 chromeTabsCreateSavedArgs.match(ANYTHING)).
323 will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
324 this.mockApis.expects(once()).chrome_windows_update(
325 testCreatedTab.windowId,
326 eqJSON({focused: true}));
328 // Invoking the tested function.
329 onNotificationClicked(
330 testNotificationId, this.mockLocalFunctions.functions().selector);
334 'GoogleNowBackgroundUnitTest',
335 'OnNotificationClicked_TabCreateFail',
337 // Tests the selected URL is OK and crome.tabs.create fails.
338 // In this case, the function should invoke chrome.windows.create as a
341 // Setup and expectations.
342 var testActionUrls = {testField: 'TEST VALUE'};
343 var testNotificationId = 'TEST_ID';
344 var testNotificationData = {
345 notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
347 var testActionUrl = 'http://testurl.com';
348 var testCreatedTab = undefined; // chrome.tabs.create fails
350 mockOnNotificationClickedDependencies(this);
351 this.makeMockLocalFunctions(['selector']);
353 var storageGetSavedArgs = new SaveMockArguments();
354 this.mockApis.expects(once()).
355 instrumented_storage_local_get(
356 storageGetSavedArgs.match(eq('notificationsData')),
357 storageGetSavedArgs.match(ANYTHING)).
358 will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
359 this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
360 returnValue(testActionUrl));
361 var chromeTabsCreateSavedArgs = new SaveMockArguments();
362 this.mockApis.expects(once()).
363 instrumented_tabs_create(
364 chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
365 chromeTabsCreateSavedArgs.match(ANYTHING)).
366 will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
367 this.mockApis.expects(once()).chrome_windows_create(
368 eqJSON({url: testActionUrl, focused: true}));
370 // Invoking the tested function.
371 onNotificationClicked(
372 testNotificationId, this.mockLocalFunctions.functions().selector);
376 'GoogleNowBackgroundUnitTest',
377 'ShowNotificationCards',
379 // Tests showNotificationCards function. Checks that the function properly
380 // deletes the card that didn't get an update, updates existing card and
381 // creates a new card that previously didn't exist.
383 // Setup and expectations.
384 var existingNotifications = {
385 'SHOULD BE DELETED': 'SOMETHING',
386 'SHOULD BE KEPT': 'SOMETHING'
389 var notificationGroups = {
390 TEST_FIELD: 'TEST VALUE'
394 'SHOULD BE KEPT': [1],
398 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
400 var expectedUpdatedNotifications = {
401 'SHOULD BE KEPT': 'KEPT CARD NOTIFICATION DATA',
402 'NEW CARD': 'NEW CARD NOTIFICATION DATA'
405 this.makeAndRegisterMockApis([
407 'chrome.storage.local.set',
408 'instrumented.notifications.getAll'
410 this.makeMockLocalFunctions([
414 var notificationsGetAllSavedArgs = new SaveMockArguments();
415 this.mockApis.expects(once()).
416 instrumented_notifications_getAll(
417 notificationsGetAllSavedArgs.match(ANYTHING)).
419 notificationsGetAllSavedArgs, 0, existingNotifications));
421 this.mockApis.expects(once()).
425 eqJSON(notificationGroups),
426 fakeOnCardShownFunction).
427 will(returnValue('KEPT CARD NOTIFICATION DATA'));
428 this.mockApis.expects(once()).
432 eqJSON(notificationGroups),
433 fakeOnCardShownFunction).
434 will(returnValue('NEW CARD NOTIFICATION DATA'));
435 this.mockApis.expects(once()).
439 eqJSON(notificationGroups),
440 fakeOnCardShownFunction).
441 will(returnValue(undefined));
443 this.mockApis.expects(once()).
444 chrome_storage_local_set(
445 eqJSON({notificationsData: expectedUpdatedNotifications}));
447 this.mockLocalFunctions.expects(once()).
450 // Invoking the tested function.
451 showNotificationCards(
454 this.mockLocalFunctions.functions().onSuccess,
455 fakeOnCardShownFunction);
459 'GoogleNowBackgroundUnitTest',
462 // Tests combineGroup function. Verifies that both notifications with and
463 // without show time are handled correctly and that cards are correctly
464 // added to existing cards with same ID or start a new combined card.
466 // Setup and expectations.
467 var combinedCards = {
471 var receivedNotificationNoShowTime = {
472 chromeNotificationId: 'EXISTING CARD',
473 trigger: {hideTimeSec: 1}
475 var receivedNotificationWithShowTime = {
476 chromeNotificationId: 'NEW CARD',
477 trigger: {showTimeSec: 2, hideTimeSec: 3}
481 cardsTimestamp: 10000,
483 receivedNotificationNoShowTime,
484 receivedNotificationWithShowTime
488 // Invoking the tested function.
489 combineGroup(combinedCards, storedGroup);
491 // Check the output value.
492 var expectedCombinedCards = {
496 receivedNotification: receivedNotificationNoShowTime,
502 receivedNotification: receivedNotificationWithShowTime,
510 JSON.stringify(expectedCombinedCards),
511 JSON.stringify(combinedCards));
515 'GoogleNowBackgroundUnitTest',
516 'CombineAndShowNotificationCards',
518 // Tests combineAndShowNotificationCards function.
519 // The test passes 2 groups to combineAndShowNotificationCards, checks
520 // that it calls combineGroup() for each of these groups and calls
521 // showNotificationCards() with the results of these combineGroup() calls.
523 // Setup and expectations.
525 'TEST GROUP 1': {testField: 'TEST VALUE 1'},
526 'TEST GROUP 2': {testField: 'TEST VALUE 2'}
529 var fakeOnSuccessFunction = 'FAKE ON SUCCESS FUNCTION';
530 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
532 this.makeAndRegisterMockGlobals(
533 ['combineGroup', 'showNotificationCards']);
535 var combineGroupSavedArgs = new SaveMockArguments();
536 this.mockGlobals.expects(once()).
538 combineGroupSavedArgs.match(eqJSON({})),
539 combineGroupSavedArgs.match(eqJSON({testField: 'TEST VALUE 1'}))).
540 will(callFunction(function() {
541 combineGroupSavedArgs.arguments[0].card1 = {
542 testValue: 'TEST CARD VALUE 1'
545 this.mockGlobals.expects(once()).
547 combineGroupSavedArgs.match(
548 eqJSON({card1: {testValue: 'TEST CARD VALUE 1'}})),
549 combineGroupSavedArgs.match(
550 eqJSON({testField: 'TEST VALUE 2'}))).
551 will(callFunction(function() {
552 combineGroupSavedArgs.arguments[0].card2 = {
553 testValue: 'TEST CARD VALUE 2'
556 this.mockGlobals.expects(once()).
557 showNotificationCards(
560 card1: {testValue: 'TEST CARD VALUE 1'},
561 card2: {testValue: 'TEST CARD VALUE 2'}
563 fakeOnSuccessFunction,
564 fakeOnCardShownFunction);
566 // Invoking the tested function.
567 combineAndShowNotificationCards(
568 testGroups, fakeOnSuccessFunction, fakeOnCardShownFunction);
572 'GoogleNowBackgroundUnitTest',
573 'ProcessServerResponse',
575 // Tests processServerResponse function.
577 // Setup and expectations.
578 Date.now = function() { return 3000000; };
580 // GROUP1 was requested and contains cards c4 and c5. For c5, there is a
581 // non-expired dismissal, so it will be ignored.
582 // GROUP2 was not requested, but is contained in server response to
583 // indicate that the group still exists. Stored group GROUP2 won't change.
584 // GROUP3 is stored, but is not present in server's response, which means
585 // it doesn't exist anymore. This group will be deleted.
586 // GROUP4 doesn't contain cards, but it was requested. This is treated as
587 // if it had an empty array of cards. Cards in the stored group will be
588 // replaced with an empty array.
589 // GROUP5 doesn't have next poll time, and it will be stored without next
591 var serverResponse = {
593 GROUP1: {requested: true, nextPollSeconds: 46},
594 GROUP2: {requested: false},
595 GROUP4: {requested: true, nextPollSeconds: 45},
596 GROUP5: {requested: true}
599 {notificationId: 'c4', groupName: 'GROUP1'},
600 {notificationId: 'c5', groupName: 'GROUP1'}
604 var recentDismissals = {
605 c4: 1800000, // expired dismissal
606 c5: 1800001 // non-expired dismissal
611 cards: [{notificationId: 'c2'}],
616 cards: [{notificationId: 'c3'}],
621 cards: [{notificationId: 'c6'}],
627 var expectedUpdatedGroups = {
629 cards: [{notificationId: 'c4', groupName: 'GROUP1'}],
630 cardsTimestamp: 3000000,
631 nextPollTime: 3046000
634 cards: [{notificationId: 'c2'}],
640 cardsTimestamp: 3000000,
641 nextPollTime: 3045000
645 cardsTimestamp: 3000000
649 var expectedUpdatedRecentDismissals = {
653 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
655 this.makeAndRegisterMockGlobals([
657 'combineAndShowNotificationCards',
661 this.makeAndRegisterMockApis([
662 'chrome.storage.local.set',
663 'instrumented.storage.local.get'
666 var storageGetSavedArgs = new SaveMockArguments();
667 this.mockApis.expects(once()).
668 instrumented_storage_local_get(
669 storageGetSavedArgs.match(
670 eq(['notificationGroups', 'recentDismissals'])),
671 storageGetSavedArgs.match(ANYTHING)).
676 notificationGroups: storedGroups,
677 recentDismissals: recentDismissals
680 this.mockGlobals.expects(once()).
681 scheduleNextPoll(eqJSON(expectedUpdatedGroups), true);
683 var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments();
684 this.mockGlobals.expects(once()).
685 combineAndShowNotificationCards(
686 combineAndShowNotificationCardsSavedArgs.match(
687 eqJSON(expectedUpdatedGroups)),
688 combineAndShowNotificationCardsSavedArgs.match(
690 combineAndShowNotificationCardsSavedArgs.match(
691 eq(fakeOnCardShownFunction))).
692 will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1));
694 this.mockApis.expects(once()).
695 chrome_storage_local_set(
697 notificationGroups: expectedUpdatedGroups,
698 recentDismissals: expectedUpdatedRecentDismissals}));
700 this.mockGlobals.expects(once()).
701 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
703 // Invoking the tested function.
704 processServerResponse(serverResponse, fakeOnCardShownFunction);
708 'GoogleNowBackgroundUnitTest',
709 'ProcessServerResponseGoogleNowDisabled',
711 // Tests processServerResponse function for the case when the response
712 // indicates that Google Now is disabled.
714 // Setup and expectations.
715 var serverResponse = {
716 googleNowDisabled: true,
718 GROUP1: {nextPollTimeSeconds: 200}
724 cards: [{notificationId: 'c2'}],
729 cards: [{notificationId: 'c3'}],
735 var expectedUpdatedGroups = {
738 var fakeOnCardShownFunction = 'FAKE ON CARD SHOWN FUNCTION';
740 this.makeAndRegisterMockGlobals([
742 'combineAndShowNotificationCards',
747 this.makeAndRegisterMockApis([
748 'chrome.storage.local.set',
749 'instrumented.storage.local.get'
752 this.mockApis.expects(once()).
753 chrome_storage_local_set(
754 eqJSON({googleNowEnabled: false}));
756 this.mockGlobals.expects(once()).onStateChange();
758 var storageGetSavedArgs = new SaveMockArguments();
759 this.mockApis.expects(once()).
760 instrumented_storage_local_get(
761 storageGetSavedArgs.match(
762 eq(['notificationGroups', 'recentDismissals'])),
763 storageGetSavedArgs.match(ANYTHING)).
765 storageGetSavedArgs, 1, {notificationGroups: storedGroups}));
767 this.mockGlobals.expects(once()).
768 scheduleNextPoll(eqJSON(expectedUpdatedGroups), false);
770 var combineAndShowNotificationCardsSavedArgs = new SaveMockArguments();
771 this.mockGlobals.expects(once()).
772 combineAndShowNotificationCards(
773 combineAndShowNotificationCardsSavedArgs.match(
774 eqJSON(expectedUpdatedGroups)),
775 combineAndShowNotificationCardsSavedArgs.match(
777 combineAndShowNotificationCardsSavedArgs.match(
778 eq(fakeOnCardShownFunction))).
779 will(invokeCallback(combineAndShowNotificationCardsSavedArgs, 1));
781 this.mockApis.expects(once()).
782 chrome_storage_local_set(
784 notificationGroups: expectedUpdatedGroups,
785 recentDismissals: {}}));
787 this.mockGlobals.expects(once()).
788 recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);
790 // Invoking the tested function.
791 processServerResponse(serverResponse, fakeOnCardShownFunction);