// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO(robliao,vadimt): Determine the granularity of testing to perform.

/**
 * Test fixture for background.js.
 * @constructor
 * @extends {testing.Test}
 */
function GoogleNowBackgroundUnitTest () {
  testing.Test.call(this);
}

GoogleNowBackgroundUnitTest.prototype = {
  __proto__: testing.Test.prototype,

  /** @override */
  extraLibraries: [
    'common_test_util.js',
    'background_test_util.js',
    'background.js'
  ]
};

TEST_F('GoogleNowBackgroundUnitTest', 'AreTasksConflicting', function() {
  function testTaskPair(newTaskName, scheduledTaskName, expected) {
    assertTrue(areTasksConflicting(newTaskName, scheduledTaskName) == expected,
               '(' + newTaskName + ', ' + scheduledTaskName + ')');
  }

  testTaskPair(UPDATE_CARDS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
  testTaskPair(UPDATE_CARDS_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
  testTaskPair(UPDATE_CARDS_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
  testTaskPair(UPDATE_CARDS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);

  testTaskPair(DISMISS_CARD_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
  testTaskPair(DISMISS_CARD_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
  testTaskPair(DISMISS_CARD_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
  testTaskPair(DISMISS_CARD_TASK_NAME, STATE_CHANGED_TASK_NAME, false);

  testTaskPair(RETRY_DISMISS_TASK_NAME, UPDATE_CARDS_TASK_NAME, true);
  testTaskPair(RETRY_DISMISS_TASK_NAME, DISMISS_CARD_TASK_NAME, true);
  testTaskPair(RETRY_DISMISS_TASK_NAME, RETRY_DISMISS_TASK_NAME, true);
  testTaskPair(RETRY_DISMISS_TASK_NAME, STATE_CHANGED_TASK_NAME, false);

  testTaskPair(STATE_CHANGED_TASK_NAME, UPDATE_CARDS_TASK_NAME, false);
  testTaskPair(STATE_CHANGED_TASK_NAME, DISMISS_CARD_TASK_NAME, false);
  testTaskPair(STATE_CHANGED_TASK_NAME, RETRY_DISMISS_TASK_NAME, false);
  testTaskPair(STATE_CHANGED_TASK_NAME, STATE_CHANGED_TASK_NAME, false);
});

var testNotificationId = 'TEST GROUP-SOME TEST ID';
var testChromeNotificationId = 'TEST CARD ID';
var testNotification1 =
    {testNotificationField: 'TEST NOTIFICATION VALUE1', priority: -1};
var testNotification2 =
    {testNotificationField: 'TEST NOTIFICATION VALUE2', priority: 0};
var testActionUrls1 = {testField: 'TEST VALUE1'};
var testActionUrls2 = {testField: 'TEST VALUE2'};
var testDismissal1 = {testDismissalField: 'TEST DISMISSAL VALUE 1'};
var testDismissal2 = {testDismissalField: 'TEST DISMISSAL VALUE 2'};
var testVersion = 7;
var testTimestamp1 = 300000;
var testTimestamp2 = 600000;
var testGroupRank1 = 19;
var testGroupRank2 = 23;
var testTriggerUnmerged = {showTimeSec: 100, hideTimeSec: 200};
var testTriggerMerged = {showTime: 300007, hideTime: 300011};
var testVersion1 = 29;
var testVersion2 = 31;

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeCardsEmptyNoTrigger',
    function() {
      // Tests merging a card with an empty trigger into an 'undefined' merged
      // card. This should start a new card.

      // Invoking the tested function.
      var resultingMergedCard = mergeCards(undefined, {
        notificationId: testNotificationId,
        chromeNotificationId: testChromeNotificationId,
        version: testVersion1,
        chromeNotificationOptions: testNotification1,
        actionUrls: testActionUrls1,
        dismissal: testDismissal1
      }, testTimestamp1, testGroupRank1);

      // Check the return value.
      assertEquals(
          JSON.stringify({
            dismissals: [
              {
                notificationId: testNotificationId,
                parameters: testDismissal1
              }
            ],
            groupRank: testGroupRank1,
            trigger: {},
            timestamp: testTimestamp1,
            notification: testNotification1,
            actionUrls: testActionUrls1,
            version: testVersion1
          }),
        JSON.stringify(resultingMergedCard));
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeCards1',
    function() {
      // Tests merging a unmerged card into a merged card.
      // Unmerged card priority is greater than merged card one. Unmerged card
      // rank is less than merged card one, and it's older.

      // Setup.
      var mergedCard = {
        trigger: testTriggerMerged,
        version: testVersion1,
        timestamp: testTimestamp2,
        notification: testNotification1,
        actionUrls: testActionUrls1,
        groupRank: testGroupRank2,
        dismissals:
            [{notificationId: testNotificationId, parameters: testDismissal1}]
      };

      var unmergedNotification = {
        notificationId: testNotificationId,
        chromeNotificationId: testChromeNotificationId,
        version: testVersion2,
        chromeNotificationOptions: testNotification2,
        actionUrls: testActionUrls2,
        dismissal: testDismissal2,
        trigger: testTriggerUnmerged
      };

      // Invoking the tested function.
      var resultingMergedCard = mergeCards(
          mergedCard, unmergedNotification, testTimestamp1, testGroupRank1);

      // Check the return value.
      assertEquals(
          JSON.stringify({
            trigger: testTriggerMerged,
            version: testVersion1,
            timestamp: testTimestamp2,
            notification: {
                testNotificationField: 'TEST NOTIFICATION VALUE1',
                priority: 0
             },
            actionUrls: testActionUrls1,
            groupRank: testGroupRank2,
            dismissals: [
              {notificationId: testNotificationId, parameters: testDismissal1},
              {notificationId: testNotificationId, parameters: testDismissal2}
            ]
          }),
        JSON.stringify(resultingMergedCard));
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeCards2',
    function() {
      // Tests merging a unmerged card into a merged card.
      // Unmerged card priority is less than merged card one. Unmerged card rank
      // is greater than merged card one, and it's older.

      // Setup.
      var mergedCard = {
        trigger: testTriggerMerged,
        version: testVersion1,
        timestamp: testTimestamp2,
        notification: testNotification2,
        actionUrls: testActionUrls1,
        groupRank: testGroupRank1,
        dismissals:
            [{notificationId: testNotificationId, parameters: testDismissal1}]
      };

      var unmergedNotification = {
        notificationId: testNotificationId,
        chromeNotificationId: testChromeNotificationId,
        version: testVersion2,
        chromeNotificationOptions: testNotification1,
        actionUrls: testActionUrls2,
        dismissal: testDismissal2,
        trigger: testTriggerUnmerged
      };

      // Invoking the tested function.
      var resultingMergedCard = mergeCards(
          mergedCard, unmergedNotification, testTimestamp1, testGroupRank2);

      // Check the return value.
      assertEquals(
          JSON.stringify({
            trigger: {showTime: 400000, hideTime: 500000},
            version: testVersion1,
            timestamp: testTimestamp2,
            notification: {
                testNotificationField: 'TEST NOTIFICATION VALUE2',
                priority: 0
             },
            actionUrls: testActionUrls1,
            groupRank: testGroupRank2,
            dismissals: [
              {notificationId: testNotificationId, parameters: testDismissal1},
              {notificationId: testNotificationId, parameters: testDismissal2}
            ]
          }),
        JSON.stringify(resultingMergedCard));
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeCards3',
    function() {
      // Tests merging a unmerged card into a merged card.
      // Unmerged card priority is less than merged card one. Unmerged card rank
      // is less than merged card one, and it's newer.

      // Setup.
      var mergedCard = {
        trigger: testTriggerMerged,
        version: testVersion1,
        timestamp: testTimestamp1,
        notification: testNotification2,
        actionUrls: testActionUrls1,
        groupRank: testGroupRank2,
        dismissals:
            [{notificationId: testNotificationId, parameters: testDismissal1}]
      };

      var unmergedNotification = {
        notificationId: testNotificationId,
        chromeNotificationId: testChromeNotificationId,
        version: testVersion2,
        chromeNotificationOptions: testNotification1,
        actionUrls: testActionUrls2,
        dismissal: testDismissal2,
        trigger: testTriggerUnmerged
      };

      // Invoking the tested function.
      var resultingMergedCard = mergeCards(
          mergedCard, unmergedNotification, testTimestamp2, testGroupRank1);

      // Check the return value.
      assertEquals(
          JSON.stringify({
            trigger: testTriggerMerged,
            version: testVersion2,
            timestamp: testTimestamp2,
            notification: {
                testNotificationField: 'TEST NOTIFICATION VALUE1',
                priority: 0
             },
            actionUrls: testActionUrls2,
            groupRank: testGroupRank2,
            dismissals: [
              {notificationId: testNotificationId, parameters: testDismissal1},
              {notificationId: testNotificationId, parameters: testDismissal2}
            ]
          }),
        JSON.stringify(resultingMergedCard));
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeGroup',
    function() {
      // Tests mergeGroup method.

      // Setup.
      this.makeAndRegisterMockGlobals(['mergeCards']);

      this.mockGlobals.expects(once()).
          mergeCards(
              undefined,
              eqJSON({chromeNotificationId: 'ID 1', testField: 'TEST_FIELD1'}),
              300000,
              17).
          will(returnValue({testField: 'RESULT 1'}));
      this.mockGlobals.expects(once()).
          mergeCards(
              eqJSON({testField: 'TEST_FIELD22'}),
              eqJSON({chromeNotificationId: 'ID 2', testField: 'TEST_FIELD2'}),
              300000,
              17).
          will(returnValue({testField: 'RESULT 2'}));

      var group = {
        cards: [
          {chromeNotificationId: 'ID 1', testField: 'TEST_FIELD1'},
          {chromeNotificationId: 'ID 2', testField: 'TEST_FIELD2'}
        ],
        cardsTimestamp: 300000,
        nextPollTime: 600000,
        rank: 17
      };

      var mergedCards = {
        'ID 2': { testField: 'TEST_FIELD22' },
        'ID 3': { testField: 'TEST_FIELD3' }
      };

      // Invoking the tested function.
      mergeGroup(mergedCards, group);

      // Check the output parameter.
      assertEquals(
          JSON.stringify({
            'ID 2': { testField: 'RESULT 2' },
            'ID 3': { testField: 'TEST_FIELD3'},
            'ID 1': { testField: 'RESULT 1' }}),
          JSON.stringify(mergedCards));
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'MergeAndShowNotificationCards',
    function() {
      // Tests mergeAndShowNotificationCards function.
      // The test passes 2 groups to mergeAndShowNotificationCards, checks that
      // it calls mergeGroup() for each of these groups and calls
      // showNotificationCards() with the results of these mergeGroup() calls.

      // Setup and expectations.
      var testGroups = {
        'TEST GROUP 1': {testField: 'TEST VALUE 1'},
        'TEST GROUP 2': {testField: 'TEST VALUE 2'}
      };

      this.makeAndRegisterMockGlobals(['mergeGroup', 'showNotificationCards']);

      var mergeGroupSavedArgs = new SaveMockArguments();
      this.mockGlobals.expects(once()).
          mergeGroup(
              mergeGroupSavedArgs.match(eqJSON({})),
              mergeGroupSavedArgs.match(eqJSON({testField: 'TEST VALUE 1'}))).
          will(callFunction(function() {
            mergeGroupSavedArgs.arguments[0].card1 = {
              testValue: 'TEST CARD VALUE 1'
            };
          }));
      this.mockGlobals.expects(once()).
          mergeGroup(
              mergeGroupSavedArgs.match(
                  eqJSON({card1: {testValue: 'TEST CARD VALUE 1'}})),
              mergeGroupSavedArgs.match(
                  eqJSON({testField: 'TEST VALUE 2'}))).
          will(callFunction(function() {
              mergeGroupSavedArgs.arguments[0].card2 = {
                testValue: 'TEST CARD VALUE 2'
              };
          }));
      this.mockGlobals.expects(once()).
          showNotificationCards(
              eqJSON({
                card1: {testValue: 'TEST CARD VALUE 1'},
                card2: {testValue: 'TEST CARD VALUE 2'}
              }),
              ANYTHING);

      // Invoking the tested function.
      mergeAndShowNotificationCards(testGroups, function() {});
    });

// TODO(vadimt): Add more tests for parseAndShowNotificationCards().
TEST_F(
    'GoogleNowBackgroundUnitTest',
    'ParseAndShowNotificationCardsAdd1Remove1',
    function() {
      // Tests parseAndShowNotificationCards function for the case when the
      // extension has 2 groups, and the server sends update with 2 groups, one
      // of which is new, and another one matches a stored group. The client
      // has to delete the group that didn't receive an update, keep the
      // existing group that received an update, and add a new stored group for
      // the new group from the server.

      // Setup and expectations.
      var serverResponse = {
        groups: {
          GROUP1: {},
          GROUP2: {}
        }
      };

      var storedGroups = {
        GROUP2: {
          cards: ['c2'],
          cardsTimestamp: 239,
          nextPollTime: 10000,
          rank: 1
        },
        GROUP3: {
          cards: ['c3'],
          cardsTimestamp: 240,
          nextPollTime: 10001,
          rank: 2
        }
      };

      var expectedUpdatedGroups = {
        GROUP1: {
          cards: []
        },
        GROUP2: {
          cards: ['c2'],
          cardsTimestamp: 239,
          nextPollTime: 10000,
          rank: 1
        }
      };

      this.makeAndRegisterMockGlobals(
          ['scheduleNextPoll', 'mergeAndShowNotificationCards', 'recordEvent']);

      this.makeAndRegisterMockApis([
        'chrome.storage.local.set',
        'instrumented.storage.local.get'
      ]);

      var storageGetSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_storage_local_get(
              storageGetSavedArgs.match(eq('notificationGroups')),
              storageGetSavedArgs.match(ANYTHING)).
          will(invokeCallback(
              storageGetSavedArgs, 1, {notificationGroups: storedGroups}));

      this.mockGlobals.expects(once()).
          scheduleNextPoll(eqJSON(expectedUpdatedGroups), true);

      this.mockApis.expects(once()).
          chrome_storage_local_set(
              eqJSON({notificationGroups: expectedUpdatedGroups}));

      this.mockGlobals.expects(once()).
          mergeAndShowNotificationCards(
              eqJSON(expectedUpdatedGroups), ANYTHING);

      this.mockGlobals.expects(once()).
          recordEvent(GoogleNowEvent.CARDS_PARSE_SUCCESS);

      // Invoking the tested function.
      parseAndShowNotificationCards(JSON.stringify(serverResponse));
    });

/**
 * Mocks global functions and APIs that initialize() depends upon.
 * @param {Test} fixture Test fixture.
 */
function mockInitializeDependencies(fixture) {
  fixture.makeAndRegisterMockGlobals([
    'recordEvent',
    'setBackgroundEnable',
    'startPollingCards'
  ]);
  fixture.makeAndRegisterMockApis([
    'authenticationManager.isSignedIn',
    'chrome.location.clearWatch',
    'chrome.storage.local.remove',
    'instrumented.metricsPrivate.getVariationParams',
    'instrumented.notifications.getAll',
    'instrumented.notifications.getPermissionLevel',
    'instrumented.preferencesPrivate.googleGeolocationAccessEnabled.get',
    'instrumented.storage.local.get',
    'tasks.add',
    'updateCardsAttempts.isRunning',
    'updateCardsAttempts.stop'
  ]);
}

/**
 * Sets up the test to expect the state machine calls and send
 * the specified state machine state. Currently used to test initialize().
 * Note that this CAN NOT be used if any of the methods below are called
 * outside of this context with the same argument matchers.
 * expects() calls cannot be chained with the same argument matchers.
 * @param {object} fixture Test fixture.
 * @param {string} testIdentityToken getAuthToken callback token.
 * @param {boolean} testGeolocationPref Geolocation Preference callback value.
 * @param {object} testExperimentVariationParams Response of
 *     metricsPrivate.getVariationParams.
 * @param {string} testExperimentVariationParams Response of
 *     notifications.getPermissionLevel.
 * @param {boolean} testGoogleNowEnabled True if the user is opted in to Google
 *     Now.
 */
function expectStateMachineCalls(
    fixture,
    testIdentityToken,
    testGeolocationPref,
    testExperimentVariationParams,
    testNotificationPermissionLevel,
    testGoogleNowEnabled) {
  var authenticationManagerIsSignedInSavedArgs = new SaveMockArguments();
  fixture.mockApis.expects(once()).
      authenticationManager_isSignedIn(
          authenticationManagerIsSignedInSavedArgs.match(ANYTHING)).
      will(invokeCallback(
          authenticationManagerIsSignedInSavedArgs,
          0,
          testIdentityToken));

  var getVariationParamsSavedArgs = new SaveMockArguments();
  fixture.mockApis.expects(once()).
      instrumented_metricsPrivate_getVariationParams(
          getVariationParamsSavedArgs.match(ANYTHING),
          getVariationParamsSavedArgs.match(ANYTHING)).
      will(invokeCallback(
          getVariationParamsSavedArgs, 1, testExperimentVariationParams));

  var googleGeolocationPrefGetSavedArgs = new SaveMockArguments();
  fixture.mockApis.expects(once()).
      instrumented_preferencesPrivate_googleGeolocationAccessEnabled_get(
          googleGeolocationPrefGetSavedArgs.match(eqJSON({})),
          googleGeolocationPrefGetSavedArgs.match(ANYTHING)).
      will(invokeCallback(
          googleGeolocationPrefGetSavedArgs, 1, {value: testGeolocationPref}));

  var notificationGetPermissionLevelSavedArgs = new SaveMockArguments();
  fixture.mockApis.expects(once()).
      instrumented_notifications_getPermissionLevel(
          notificationGetPermissionLevelSavedArgs.match(ANYTHING)).
      will(invokeCallback(
          notificationGetPermissionLevelSavedArgs,
          0,
          testNotificationPermissionLevel))

   var storageGetSavedArgs = new SaveMockArguments();	 
   fixture.mockApis.expects(once()).	 
       instrumented_storage_local_get(	 
           storageGetSavedArgs.match(eq('googleNowEnabled')),	 
           storageGetSavedArgs.match(ANYTHING)).	 
       will(invokeCallback(
          storageGetSavedArgs, 1, {googleNowEnabled: testGoogleNowEnabled}));	 

  fixture.mockGlobals.expects(once()).
      setBackgroundEnable(ANYTHING);
}

/**
 * Sets up the test to expect the initialization calls that
 * initialize() invokes.
 * Note that this CAN NOT be used if any of the methods below are called
 * outside of this context with the same argument matchers.
 * expects() calls cannot be chained with the same argument matchers.
 */
function expectInitialization(mockApisObj) {
  var tasksAddSavedArgs = new SaveMockArguments();
  mockApisObj.expects(once()).
      tasks_add(
          tasksAddSavedArgs.match(ANYTHING),
          tasksAddSavedArgs.match(ANYTHING)).
      will(invokeCallback(tasksAddSavedArgs, 1, function() {}));
  var updateCardsAttemptsIsRunningSavedArgs = new SaveMockArguments();
  mockApisObj.expects(once()).
      updateCardsAttempts_isRunning(
          updateCardsAttemptsIsRunningSavedArgs.match(ANYTHING)).
      will(
          invokeCallback(
             updateCardsAttemptsIsRunningSavedArgs, 0, false));
}

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'Initialize_ToastStateEmpty',
    function() {
      // Tests the case when getAuthToken fails most likely because the user is
      // not signed in. In this case, the function should quietly exit after
      // finding out that getAuthToken fails.

      // Setup and expectations.
      var testIdentityToken = undefined;
      var testGeolocationPref = false;
      var testExperimentVariationParams = {};
      var testNotificationPermissionLevel = 'denied';
      var testGoogleNowEnabled = undefined;

      mockInitializeDependencies(this);

      this.mockGlobals.expects(once()).recordEvent(
          GoogleNowEvent.EXTENSION_START);

      this.mockGlobals.expects(once()).recordEvent(
          GoogleNowEvent.STOPPED);

      expectInitialization(this.mockApis);

      expectStateMachineCalls(
          this,
          testIdentityToken,
          testGeolocationPref,
          testExperimentVariationParams,
          testNotificationPermissionLevel,
          testGoogleNowEnabled);

      // Invoking the tested function.
      initialize();
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'DISABLED_Initialize_ToastStateEmpty2',
    function() {
      // Tests the case when getAuthToken succeeds, and the user has never
      // responded to the toast.
      // In this case, the function should invoke showWelcomeToast().

      // Setup and expectations.
      var testIdentityToken = 'some identity token';
      var testGeolocationPref = false;
      var testExperimentVariationParams = {};
      var testNotificationPermissionLevel = 'denied';
      var testGoogleNowEnabled = undefined;

      mockInitializeDependencies(this);

      this.mockGlobals.expects(once()).recordEvent(
          GoogleNowEvent.EXTENSION_START);

      expectInitialization(this.mockApis);

      expectStateMachineCalls(
          this,
          testIdentityToken,
          testGeolocationPref,
          testExperimentVariationParams,
          testNotificationPermissionLevel,
          testGoogleNowEnabled);

      var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
      this.mockApis.expects(exactly(1)).
          instrumented_notifications_getAll(
              chromeNotificationGetAllSavedArgs.match(ANYTHING)).
          will(
              invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
              invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));

      // Invoking the tested function.
      initialize();
    });

TEST_F('GoogleNowBackgroundUnitTest', 'Initialize_RunGoogleNow', function() {
  // Tests if Google Now will invoke startPollingCards when all
  // of the required state is fulfilled.

  // Setup and expectations.
  var testIdentityToken = 'some identity token';
  var testGeolocationPref = true;
  var testExperimentVariationParams = {};
  var testNotificationPermissionLevel = 'granted';
  var testGoogleNowEnabled = true;

  mockInitializeDependencies(this);

  this.mockGlobals.expects(once()).recordEvent(
        GoogleNowEvent.EXTENSION_START);

  expectInitialization(this.mockApis);

  expectStateMachineCalls(
      this,
      testIdentityToken,
      testGeolocationPref,
      testExperimentVariationParams,
      testNotificationPermissionLevel,
      testGoogleNowEnabled);

  this.mockGlobals.expects(once()).startPollingCards();

  // Invoking the tested function.
  initialize();
});

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'DISABLED_Initialize_NoGeolocation',
    function() {
  // Tests the case where everything is in place except for the
  // Geolocation Preference after the user responded to the toast.

  // Setup and expectations.
  var testIdentityToken = 'some identity token';
  var testGeolocationPref = false;
  var testExperimentVariationParams = {};
  var testNotificationPermissionLevel = 'denied';
  var testGoogleNowEnabled = undefined;


  mockInitializeDependencies(this);

  this.mockGlobals.expects(once()).recordEvent(
        GoogleNowEvent.EXTENSION_START);

  this.mockGlobals.expects(once()).recordEvent(
      GoogleNowEvent.USER_SUPPRESSED);

  expectInitialization(this.mockApis);

  expectStateMachineCalls(
      this,
      testIdentityToken,
      testGeolocationPref,
      testExperimentVariationParams,
      testNotificationPermissionLevel,
      testNotificationPermissionLevel,
      testGoogleNowEnabled);

  var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
  this.mockApis.expects(exactly(2)).
      instrumented_notifications_getAll(
          chromeNotificationGetAllSavedArgs.match(ANYTHING)).
      will(
          invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
          invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));

  // Invoking the tested function.
  initialize();
});

/**
 * Mocks global functions and APIs that onNotificationClicked() depends upon.
 * @param {Test} fixture Test fixture.
 */
function mockOnNotificationClickedDependencies(fixture) {
  fixture.makeAndRegisterMockApis([
      'chrome.windows.create',
      'chrome.windows.update',
      'instrumented.storage.local.get',
      'instrumented.tabs.create']);
}

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'OnNotificationClicked_NoData',
    function() {
      // Tests the case when there is no data associated with notification id.
      // In this case, the function should do nothing.

      // Setup and expectations.
      var testNotificationId = 'TEST_ID';
      var testNotificationData = {};

      mockOnNotificationClickedDependencies(this);
      this.makeMockLocalFunctions(['selector']);

      var storageGetSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_storage_local_get(
              storageGetSavedArgs.match(eq('notificationsData')),
              storageGetSavedArgs.match(ANYTHING)).
          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));

      // Invoking the tested function.
      onNotificationClicked(
          testNotificationId, this.mockLocalFunctions.functions().selector);
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'OnNotificationClicked_ActionUrlsUndefined',
    function() {
      // Tests the case when the data associated with notification id is
      // 'undefined'.
      // In this case, the function should do nothing.

      // Setup and expectations.
      var testActionUrls = undefined;
      var testNotificationId = 'TEST_ID';
      var testNotificationData = {
          notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
      };

      mockOnNotificationClickedDependencies(this);
      this.makeMockLocalFunctions(['selector']);

      var storageGetSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_storage_local_get(
              storageGetSavedArgs.match(eq('notificationsData')),
              storageGetSavedArgs.match(ANYTHING)).
          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
      this.mockLocalFunctions.expects(once()).selector(undefined).will(
          returnValue(undefined));

      // Invoking the tested function.
      onNotificationClicked(
          testNotificationId, this.mockLocalFunctions.functions().selector);
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'OnNotificationClicked_TabCreateSuccess',
    function() {
      // Tests the selected URL is OK and crome.tabs.create suceeds.

      // Setup and expectations.
      var testActionUrls = {testField: 'TEST VALUE'};
      var testNotificationId = 'TEST_ID';
      var testNotificationData = {
          notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
      };
      var testActionUrl = 'http://testurl.com';
      var testCreatedTab = {windowId: 239};

      mockOnNotificationClickedDependencies(this);
      this.makeMockLocalFunctions(['selector']);

      var storageGetSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_storage_local_get(
              storageGetSavedArgs.match(eq('notificationsData')),
              storageGetSavedArgs.match(ANYTHING)).
          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
      this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
          returnValue(testActionUrl));
      var chromeTabsCreateSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_tabs_create(
              chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
              chromeTabsCreateSavedArgs.match(ANYTHING)).
          will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
      this.mockApis.expects(once()).chrome_windows_update(
          testCreatedTab.windowId,
          eqJSON({focused: true}));

      // Invoking the tested function.
      onNotificationClicked(
          testNotificationId, this.mockLocalFunctions.functions().selector);
    });

TEST_F(
    'GoogleNowBackgroundUnitTest',
    'OnNotificationClicked_TabCreateFail',
    function() {
      // Tests the selected URL is OK and crome.tabs.create fails.
      // In this case, the function should invoke chrome.windows.create as a
      // second attempt.

      // Setup and expectations.
      var testActionUrls = {testField: 'TEST VALUE'};
      var testNotificationId = 'TEST_ID';
      var testNotificationData = {
        notificationsData: {'TEST_ID': {actionUrls: testActionUrls}}
      };
      var testActionUrl = 'http://testurl.com';
      var testCreatedTab = undefined; // chrome.tabs.create fails

      mockOnNotificationClickedDependencies(this);
      this.makeMockLocalFunctions(['selector']);

      var storageGetSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_storage_local_get(
              storageGetSavedArgs.match(eq('notificationsData')),
              storageGetSavedArgs.match(ANYTHING)).
          will(invokeCallback(storageGetSavedArgs, 1, testNotificationData));
      this.mockLocalFunctions.expects(once()).selector(testActionUrls).will(
          returnValue(testActionUrl));
      var chromeTabsCreateSavedArgs = new SaveMockArguments();
      this.mockApis.expects(once()).
          instrumented_tabs_create(
              chromeTabsCreateSavedArgs.match(eqJSON({url: testActionUrl})),
              chromeTabsCreateSavedArgs.match(ANYTHING)).
          will(invokeCallback(chromeTabsCreateSavedArgs, 1, testCreatedTab));
      this.mockApis.expects(once()).chrome_windows_create(
          eqJSON({url: testActionUrl, focused: true}));

      // Invoking the tested function.
      onNotificationClicked(
          testNotificationId, this.mockLocalFunctions.functions().selector);
    });
