Home | History | Annotate | Download | only in google_now
      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.
      4 
      5 /**
      6  * Test fixture for cards.js.
      7  * @constructor
      8  * @extends {testing.Test}
      9  */
     10 function GoogleNowCardsUnitTest () {
     11   testing.Test.call(this);
     12 }
     13 
     14 GoogleNowCardsUnitTest.prototype = {
     15   __proto__: testing.Test.prototype,
     16 
     17   /** @override */
     18   extraLibraries: [
     19     'common_test_util.js',
     20     'cards.js'
     21   ]
     22 };
     23 
     24 // Test implementation of a function provided by utility.js.
     25 function verify(condition, message) {
     26   assertTrue(condition, message);
     27 }
     28 
     29 var testChromeNotificationId = 'TEST CHROME NOTIFICATION ID';
     30 var testServerNotificationIdA = 'TEST SERVER NOTIFICATION ID-A';
     31 var testServerNotificationIdB = 'TEST SERVER NOTIFICATION ID-B';
     32 var testNotificationA = {
     33   testNotificationField: 'TEST NOTIFICATION VALUE A',
     34   priority: 1
     35 };
     36 var testNotificationB = {
     37   testNotificationField: 'TEST NOTIFICATION VALUE B',
     38   priority: 2
     39 };
     40 var groupNameA = 'A';
     41 var groupNameB = 'B';
     42 var expectedAlarmId = 'card-TEST CHROME NOTIFICATION ID';
     43 var testActionUrlsA = {testField: 'TEST VALUE A'};
     44 var testActionUrlsB = {testField: 'TEST VALUE B'};
     45 var testDismissalA = {testDismissalField: 'TEST DISMISSAL VALUE A'};
     46 var testDismissalB = {testDismissalField: 'TEST DISMISSAL VALUE B'};
     47 var EXPLANATORY_CARDS_LINK_THRESHOLD = 4;
     48 var localStorage = {explanatoryCardsShown: 0};
     49 var notificationUpdateSuccessful = true;
     50 var notificationUpdateFailed = false;
     51 
     52 function setUpCardManagerTest(fixture) {
     53   fixture.makeAndRegisterMockApis([
     54       'chrome.alarms.clear',
     55       'chrome.alarms.create',
     56       'chrome.storage.local.set',
     57       'countExplanatoryCard',
     58       'fillFromChromeLocalStorage',
     59       'instrumented.alarms.onAlarm.addListener',
     60       'instrumented.notifications.clear',
     61       'instrumented.notifications.create',
     62       'instrumented.notifications.update',
     63       'tasks.add'
     64   ]);
     65 
     66   chrome.runtime = {}; // No error.
     67 
     68   var onAlarmSavedArgs = new SaveMockArguments();
     69   fixture.mockApis.expects(once()).
     70       instrumented_alarms_onAlarm_addListener(
     71           onAlarmSavedArgs.match(ANYTHING));
     72 
     73   var cardSet = buildCardSet();
     74 
     75   Mock4JS.verifyAllMocks();
     76 
     77   Date.now = function() { return 300000; };
     78 
     79   var test = {
     80     cardSet: cardSet,
     81     alarmCallback: onAlarmSavedArgs.arguments [0]
     82   };
     83 
     84   return test;
     85 }
     86 
     87 TEST_F('GoogleNowCardsUnitTest', 'BuildCardManager', function() {
     88   // Tests that buildCardSet() call completes with no problems.
     89   var test = setUpCardManagerTest(this);
     90 
     91   assertEquals('object', typeof test.cardSet);
     92   assertEquals('function', typeof test.alarmCallback);
     93 });
     94 
     95 TEST_F('GoogleNowCardsUnitTest', 'UpdateSimpleHideFuture', function() {
     96   // Update a simple card with the hide event in future.
     97 
     98   var testUncombinedNotification = {
     99     receivedNotification: {
    100       notificationId: testServerNotificationIdA,
    101       chromeNotificationId: testChromeNotificationId,
    102       chromeNotificationOptions: testNotificationA,
    103       actionUrls: testActionUrlsA,
    104       dismissal: testDismissalA,
    105       groupName: groupNameA
    106     },
    107     hideTime: 300001
    108   };
    109 
    110   // Setup and expectations.
    111   var test = setUpCardManagerTest(this);
    112   this.mockApis.expects(once()).
    113       chrome_alarms_clear(expectedAlarmId);
    114   var chromeNotificationsUpdateSavedArgs = new SaveMockArguments();
    115   this.mockApis.expects(once()).
    116       instrumented_notifications_update(
    117           chromeNotificationsUpdateSavedArgs.match(
    118               eq(testChromeNotificationId)),
    119           chromeNotificationsUpdateSavedArgs.match(eqJSON(testNotificationA)),
    120           chromeNotificationsUpdateSavedArgs.match(ANYTHING)).
    121       will(invokeCallback(
    122           chromeNotificationsUpdateSavedArgs, 2, notificationUpdateSuccessful));
    123   this.mockApis.expects(once()).
    124       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300001}));
    125 
    126   // Call tested method.
    127   var notificationData = test.cardSet.update(
    128       testChromeNotificationId, [testUncombinedNotification], {});
    129 
    130   // Check the return value.
    131   assertEquals(
    132       JSON.stringify({
    133         actionUrls: testActionUrlsA,
    134         timestamp: 300000,
    135         combinedCard: [testUncombinedNotification]
    136       }),
    137       JSON.stringify(notificationData));
    138 });
    139 
    140 TEST_F('GoogleNowCardsUnitTest', 'CreateSimpleHideFuture', function() {
    141   // Create a simple card with the hide event in future.
    142 
    143   var testUncombinedNotification = {
    144     receivedNotification: {
    145       notificationId: testServerNotificationIdA,
    146       chromeNotificationId: testChromeNotificationId,
    147       chromeNotificationOptions: testNotificationA,
    148       actionUrls: testActionUrlsA,
    149       dismissal: testDismissalA,
    150       groupName: groupNameA
    151     },
    152     hideTime: 300001
    153   };
    154 
    155   // Setup and expectations.
    156   var test = setUpCardManagerTest(this);
    157   this.makeMockLocalFunctions(['onCardShown']);
    158 
    159   this.mockApis.expects(once()).
    160       chrome_alarms_clear(expectedAlarmId);
    161 
    162   // notifications.update will return false, which will trigger
    163   // notifications.create.
    164   var chromeNotificationsUpdateSavedArgs = new SaveMockArguments();
    165   this.mockApis.expects(once()).
    166       instrumented_notifications_update(
    167           chromeNotificationsUpdateSavedArgs.match(
    168               eq(testChromeNotificationId)),
    169           chromeNotificationsUpdateSavedArgs.match(eqJSON(testNotificationA)),
    170           chromeNotificationsUpdateSavedArgs.match(ANYTHING)).
    171       will(invokeCallback(
    172           chromeNotificationsUpdateSavedArgs, 2, notificationUpdateFailed));
    173   var chromeNotificationsCreateSavedArgs = new SaveMockArguments();
    174   this.mockApis.expects(once()).
    175       instrumented_notifications_create(
    176           chromeNotificationsCreateSavedArgs.match(
    177               eq(testChromeNotificationId)),
    178           chromeNotificationsCreateSavedArgs.match(eqJSON(testNotificationA)),
    179           chromeNotificationsCreateSavedArgs.match(ANYTHING)).
    180       will(invokeCallback(
    181           chromeNotificationsCreateSavedArgs, 2, testChromeNotificationId));
    182 
    183   this.mockLocalFunctions.expects(once()).
    184       onCardShown(eqJSON(testUncombinedNotification.receivedNotification));
    185 
    186   this.mockApis.expects(once()).
    187       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300001}));
    188 
    189   // Call tested method.
    190   var notificationData = test.cardSet.update(
    191       testChromeNotificationId,
    192       [testUncombinedNotification],
    193       {},
    194       this.mockLocalFunctions.functions().onCardShown);
    195 
    196   // Check the return value.
    197   assertEquals(
    198       JSON.stringify({
    199         actionUrls: testActionUrlsA,
    200         timestamp: 300000,
    201         combinedCard: [testUncombinedNotification]
    202       }),
    203       JSON.stringify(notificationData));
    204 });
    205 
    206 TEST_F('GoogleNowCardsUnitTest', 'CreateSimpleShowFuture', function() {
    207   // Create a simple card with the show event in future. Should create an alarm
    208   // to fire at the show time.
    209 
    210   var testUncombinedNotification = {
    211     receivedNotification: {
    212       notificationId: testServerNotificationIdA,
    213       chromeNotificationId: testChromeNotificationId,
    214       chromeNotificationOptions: testNotificationA,
    215       actionUrls: testActionUrlsA,
    216       dismissal: testDismissalA,
    217       groupName: groupNameA
    218     },
    219     showTime: 300001,
    220     hideTime: 300002
    221   };
    222 
    223   // Setup and expectations.
    224   var test = setUpCardManagerTest(this);
    225 
    226   this.mockApis.expects(once()).
    227       chrome_alarms_clear(expectedAlarmId);
    228   this.mockApis.expects(once()).
    229       instrumented_notifications_clear(testChromeNotificationId, ANYTHING);
    230   this.mockApis.expects(once()).
    231       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300001}));
    232 
    233   // Call tested method.
    234   var notificationData = test.cardSet.update(
    235       testChromeNotificationId, [testUncombinedNotification], {});
    236 
    237   // Check the return value.
    238   assertEquals(
    239       JSON.stringify({
    240         timestamp: 300000,
    241         combinedCard: [testUncombinedNotification]
    242       }),
    243       JSON.stringify(notificationData));
    244 });
    245 
    246 TEST_F('GoogleNowCardsUnitTest', 'UpdateSimpleHidePast', function() {
    247   // Update a simple card with the hide event in the past (actually, present).
    248   // Should clear the notification.
    249 
    250   var testUncombinedNotification = {
    251     receivedNotification: {
    252       notificationId: testServerNotificationIdA,
    253       chromeNotificationId: testChromeNotificationId,
    254       chromeNotificationOptions: testNotificationA,
    255       actionUrls: testActionUrlsA,
    256       dismissal: testDismissalA,
    257       groupName: groupNameA
    258     },
    259     hideTime: 300000
    260   };
    261 
    262   // Setup and expectations.
    263   var test = setUpCardManagerTest(this);
    264   this.mockApis.expects(once()).
    265       chrome_alarms_clear(expectedAlarmId);
    266   this.mockApis.expects(once()).
    267       instrumented_notifications_clear(testChromeNotificationId, ANYTHING);
    268 
    269   var groups = {
    270     A: {
    271       cards: [
    272         {chromeNotificationId: 'ID1'},
    273         {chromeNotificationId: testChromeNotificationId}
    274       ]
    275     },
    276     B: {
    277       cards: [
    278         {chromeNotificationId: testChromeNotificationId},
    279         {chromeNotificationId: 'ID2'}
    280       ]
    281     }
    282   };
    283 
    284   // Call tested method.
    285   var notificationData = test.cardSet.update(
    286       testChromeNotificationId, [testUncombinedNotification], groups);
    287 
    288   // Check the return value.
    289   assertEquals(undefined, notificationData);
    290 
    291   // Check that groups were cleaned up.
    292   var expectedCleanedGroups = {
    293     A: {
    294       cards: [{chromeNotificationId: 'ID1'}]
    295     },
    296     B: {
    297       cards: [{chromeNotificationId: 'ID2'}]
    298     }
    299   };
    300 
    301   assertEquals(JSON.stringify(expectedCleanedGroups), JSON.stringify(groups));
    302 });
    303 
    304 TEST_F('GoogleNowCardsUnitTest', 'UpdateComplex', function() {
    305   // Update a combined card that contains 2 uncombined cards. The card from
    306   // group B has higher priority and wins.
    307 
    308   var testUncombinedNotificationA = {
    309     receivedNotification: {
    310       notificationId: testServerNotificationIdA,
    311       chromeNotificationId: testChromeNotificationId,
    312       chromeNotificationOptions: testNotificationA,
    313       actionUrls: testActionUrlsA,
    314       dismissal: testDismissalA,
    315       groupName: groupNameA
    316     },
    317     hideTime: 300001
    318   };
    319 
    320   var testUncombinedNotificationB = {
    321     receivedNotification: {
    322       notificationId: testServerNotificationIdB,
    323       chromeNotificationId: testChromeNotificationId,
    324       chromeNotificationOptions: testNotificationB,
    325       actionUrls: testActionUrlsB,
    326       dismissal: testDismissalB,
    327       groupName: groupNameB
    328     },
    329     hideTime: 300002
    330   };
    331 
    332   // Setup and expectations.
    333   var test = setUpCardManagerTest(this);
    334   this.mockApis.expects(once()).
    335       chrome_alarms_clear(expectedAlarmId);
    336   var chromeNotificationsUpdateSavedArgs = new SaveMockArguments();
    337   this.mockApis.expects(once()).
    338       instrumented_notifications_update(
    339           chromeNotificationsUpdateSavedArgs.match(
    340               eq(testChromeNotificationId)),
    341           chromeNotificationsUpdateSavedArgs.match(eqJSON(testNotificationB)),
    342           chromeNotificationsUpdateSavedArgs.match(ANYTHING)).
    343       will(invokeCallback(
    344           chromeNotificationsUpdateSavedArgs, 2, notificationUpdateSuccessful));
    345   this.mockApis.expects(once()).
    346       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300001}));
    347 
    348   // Call tested method.
    349   var notificationData = test.cardSet.update(
    350       testChromeNotificationId,
    351       [testUncombinedNotificationA, testUncombinedNotificationB],
    352       {});
    353 
    354   // Check the return value.
    355   assertEquals(
    356       JSON.stringify({
    357         actionUrls: testActionUrlsB,
    358         timestamp: 300000,
    359         combinedCard: [testUncombinedNotificationA, testUncombinedNotificationB]
    360       }),
    361       JSON.stringify(notificationData));
    362 });
    363 
    364 TEST_F('GoogleNowCardsUnitTest', 'DismissSimple', function() {
    365   // Dismiss a combined card that contains 1 uncombined currently visible card.
    366   // The notification should be deleted, and the card data should be cleared.
    367 
    368   var testUncombinedNotificationA = {
    369     receivedNotification: {
    370       notificationId: testServerNotificationIdA,
    371       chromeNotificationId: testChromeNotificationId,
    372       chromeNotificationOptions: testNotificationA,
    373       actionUrls: testActionUrlsA,
    374       dismissal: testDismissalA,
    375       groupName: groupNameA
    376     },
    377     showTime: 299995,
    378     hideTime: 300005
    379   };
    380 
    381   // Setup and expectations.
    382   var test = setUpCardManagerTest(this);
    383   this.mockApis.expects(once()).
    384       chrome_alarms_clear(expectedAlarmId);
    385   this.mockApis.expects(once()).
    386       instrumented_notifications_clear(testChromeNotificationId, ANYTHING);
    387 
    388   var groups = {
    389     A: {
    390       cards: [
    391         {chromeNotificationId: 'ID1'},
    392         {chromeNotificationId: testChromeNotificationId}
    393       ]
    394     },
    395     B: {
    396       cards: [
    397         {chromeNotificationId: testChromeNotificationId},
    398         {chromeNotificationId: 'ID2'}
    399       ]
    400     }
    401   };
    402 
    403   // Call tested method.
    404   var dismissalResult = test.cardSet.onDismissal(
    405       testChromeNotificationId,
    406       {
    407         actionUrls: testActionUrlsA,
    408         timestamp: 299999,
    409         combinedCard: [testUncombinedNotificationA]
    410       },
    411       groups);
    412 
    413   // Check the return value.
    414   assertEquals(
    415       JSON.stringify({
    416         dismissals: [{
    417           notificationId: testServerNotificationIdA,
    418           parameters: testDismissalA
    419         }],
    420         notificationData: undefined
    421       }),
    422       JSON.stringify(dismissalResult));
    423 
    424   // Check that groups were cleaned up.
    425   var expectedCleanedGroups = {
    426     A: {
    427       cards: [{chromeNotificationId: 'ID1'}]
    428     },
    429     B: {
    430       cards: [{chromeNotificationId: 'ID2'}]
    431     }
    432   };
    433 
    434   assertEquals(JSON.stringify(expectedCleanedGroups), JSON.stringify(groups));
    435 });
    436 
    437 TEST_F('GoogleNowCardsUnitTest', 'DismissComplex', function() {
    438   // Dismiss a combined card that contains 2 uncombined cards. One of them (B),
    439   // is currently shown, and it should be dismissed. The other one (A) has
    440   // showTime in future, and it should not be dismissed.
    441 
    442   var testUncombinedNotificationA = {
    443     receivedNotification: {
    444       notificationId: testServerNotificationIdA,
    445       chromeNotificationId: testChromeNotificationId,
    446       chromeNotificationOptions: testNotificationA,
    447       actionUrls: testActionUrlsA,
    448       dismissal: testDismissalA,
    449       groupName: groupNameA
    450     },
    451     showTime: 300010,
    452     hideTime: 300011
    453   };
    454 
    455   var testUncombinedNotificationB = {
    456     receivedNotification: {
    457       notificationId: testServerNotificationIdB,
    458       chromeNotificationId: testChromeNotificationId,
    459       chromeNotificationOptions: testNotificationB,
    460       actionUrls: testActionUrlsB,
    461       dismissal: testDismissalB,
    462       groupName: groupNameB
    463     },
    464     showTime: 299995,
    465     hideTime: 300005
    466   };
    467 
    468   // Setup and expectations.
    469   var test = setUpCardManagerTest(this);
    470   this.mockApis.expects(once()).
    471       chrome_alarms_clear(expectedAlarmId);
    472   this.mockApis.expects(once()).
    473       instrumented_notifications_clear(testChromeNotificationId, ANYTHING);
    474   this.mockApis.expects(once()).
    475       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300010}));
    476 
    477   // Call tested method.
    478   var dismissalResult = test.cardSet.onDismissal(
    479       testChromeNotificationId,
    480       {
    481         actionUrls: testActionUrlsB,
    482         timestamp: 299999,
    483         combinedCard: [testUncombinedNotificationA, testUncombinedNotificationB]
    484       },
    485       {});
    486 
    487   // Check the return value.
    488   assertEquals(
    489       JSON.stringify({
    490         dismissals: [{
    491           notificationId: testServerNotificationIdB,
    492           parameters: testDismissalB
    493         }],
    494         notificationData: {
    495           timestamp: 300000,
    496           combinedCard: [testUncombinedNotificationA]
    497         }}),
    498       JSON.stringify(dismissalResult));
    499 });
    500 
    501 TEST_F('GoogleNowCardsUnitTest', 'onAlarmUnrecognized', function() {
    502   // Tests onAlarm does nothing on an unrelated alarm.
    503   var test = setUpCardManagerTest(this);
    504 
    505   // Call tested method.
    506   test.alarmCallback({name: 'unrelated'});
    507 });
    508 
    509 TEST_F('GoogleNowCardsUnitTest', 'onAlarmClear', function() {
    510   // Tests onAlarm fired at a moment past all card's events. The card should be
    511   // cleaned.
    512   var testUncombinedNotification = {
    513     receivedNotification: {
    514       notificationId: testServerNotificationIdA,
    515       chromeNotificationId: testChromeNotificationId,
    516       chromeNotificationOptions: testNotificationA,
    517       actionUrls: testActionUrlsA,
    518       dismissal: testDismissalA,
    519       groupName: groupNameA
    520     },
    521     hideTime: 299999
    522   };
    523 
    524   // Setup and expectations.
    525   var test = setUpCardManagerTest(this);
    526   var tasksAddSavedArgs = new SaveMockArguments();
    527   this.mockApis.expects(once()).
    528       tasks_add(
    529           tasksAddSavedArgs.match(eq(UPDATE_CARD_TASK_NAME)),
    530           tasksAddSavedArgs.match(ANYTHING)).
    531       will(invokeCallback(tasksAddSavedArgs,1));
    532   expectChromeLocalStorageGet(
    533       this,
    534       {
    535         notificationsData: {},
    536         notificationGroups: {}
    537       },
    538       {
    539         notificationsData: {
    540           'TEST CHROME NOTIFICATION ID': {
    541             actionUrls: testActionUrlsA,
    542             timestamp: 299998,
    543             combinedCard: [testUncombinedNotification]
    544           },
    545           'TEST CARD ID 1': {testField: 'TEST VALUE 1'}
    546         },
    547         notificationGroups: {
    548           A: {
    549             cards: [
    550               {chromeNotificationId: 'ID1'},
    551               {chromeNotificationId: testChromeNotificationId}
    552             ]
    553           },
    554           B: {
    555             cards: [
    556               {chromeNotificationId: testChromeNotificationId},
    557               {chromeNotificationId: 'ID2'}
    558             ]
    559         }}});
    560   this.mockApis.expects(once()).
    561       instrumented_notifications_clear(testChromeNotificationId, ANYTHING);
    562   this.mockApis.expects(once()).
    563       chrome_alarms_clear(expectedAlarmId);
    564   this.mockApis.expects(once()).
    565       chrome_storage_local_set(eqJSON({
    566         notificationsData: {
    567           'TEST CARD ID 1': {testField: 'TEST VALUE 1'}
    568         },
    569         notificationGroups: {
    570           A: {
    571             cards: [{chromeNotificationId: 'ID1'}]
    572           },
    573           B: {
    574             cards: [{chromeNotificationId: 'ID2'}]
    575         }}}));
    576 
    577   // Call tested method.
    578   test.alarmCallback({name: expectedAlarmId});
    579 });
    580 
    581 TEST_F('GoogleNowCardsUnitTest', 'onAlarmUpdate', function() {
    582   // Tests onAlarm fired at a moment when there are future card's events. The
    583   // card needs to be updated.
    584   var testUncombinedNotification = {
    585     receivedNotification: {
    586       notificationId: testServerNotificationIdA,
    587       chromeNotificationId: testChromeNotificationId,
    588       chromeNotificationOptions: testNotificationA,
    589       actionUrls: testActionUrlsA,
    590       dismissal: testDismissalA,
    591       groupName: groupNameA
    592     },
    593     hideTime: 300001
    594   };
    595 
    596   // Setup and expectations.
    597   var test = setUpCardManagerTest(this);
    598   var tasksAddSavedArgs = new SaveMockArguments();
    599   this.mockApis.expects(once()).
    600       tasks_add(
    601           tasksAddSavedArgs.match(eq(UPDATE_CARD_TASK_NAME)),
    602           tasksAddSavedArgs.match(ANYTHING)).
    603       will(invokeCallback(tasksAddSavedArgs,1));
    604   expectChromeLocalStorageGet(
    605       this,
    606       {
    607         notificationsData: {},
    608         notificationGroups: {}
    609       },
    610       {
    611         notificationsData: {
    612           'TEST CHROME NOTIFICATION ID': {
    613             actionUrls: testActionUrlsA,
    614             timestamp: 299998,
    615             combinedCard: [testUncombinedNotification]
    616           }},
    617         notificationGroups: {}
    618       });
    619   this.mockApis.expects(once()).
    620       chrome_alarms_clear(expectedAlarmId);
    621   var chromeNotificationsUpdateSavedArgs = new SaveMockArguments();
    622   this.mockApis.expects(once()).
    623       instrumented_notifications_update(
    624           chromeNotificationsUpdateSavedArgs.match(
    625               eq(testChromeNotificationId)),
    626           chromeNotificationsUpdateSavedArgs.match(eqJSON(testNotificationA)),
    627           chromeNotificationsUpdateSavedArgs.match(ANYTHING)).
    628       will(invokeCallback(
    629           chromeNotificationsUpdateSavedArgs, 2, notificationUpdateSuccessful));
    630   this.mockApis.expects(once()).
    631       chrome_alarms_create(expectedAlarmId, eqJSON({when: 300001}));
    632   this.mockApis.expects(once()).
    633       chrome_storage_local_set(eqJSON({
    634             notificationsData: {
    635               'TEST CHROME NOTIFICATION ID': {
    636                 actionUrls: testActionUrlsA,
    637                 timestamp: 300000,
    638                 combinedCard: [testUncombinedNotification]
    639               }
    640             },
    641             notificationGroups: {
    642             }}));
    643 
    644   // Call tested method.
    645   test.alarmCallback({name: expectedAlarmId});
    646 });
    647