blob: f298348819ad6f984b0ed276d807ba48cd9bcea1 [file] [log] [blame]
// 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.
/**
* Test fixture for background.js.
* @constructor
* @extends {testing.Test}
*/
function GoogleNowBackgroundUnitTest () {
testing.Test.call(this);
}
GoogleNowBackgroundUnitTest.prototype = {
__proto__: testing.Test.prototype,
/** @override */
extraLibraries: [
'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);
});
/**
* Mocks global functions and APIs that initialize() depends upon.
* @param {Test} fixture Test fixture.
*/
function mockInitializeDependencies(fixture) {
fixture.makeAndRegisterMockGlobals([
'recordEvent',
'setBackgroundEnable',
'showWelcomeToast',
'startPollingCards'
]);
fixture.makeAndRegisterMockApis([
'authenticationManager.isSignedIn',
'chrome.location.clearWatch',
'chrome.storage.local.set',
'instrumented.metricsPrivate.getVariationParams',
'instrumented.notifications.getAll',
'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 {boolean} testUserRespondedToToast User Response to toast
* callback value.
* @param {object} testExperimentVariationParams Response of
* metricsPrivate.getVariationParams
*/
function expectStateMachineCalls(
fixture,
testIdentityToken,
testGeolocationPref,
testUserRespondedToToast,
testExperimentVariationParams) {
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 storageGetSavedArgs = new SaveMockArguments();
fixture.mockApis.expects(once()).
instrumented_storage_local_get(
storageGetSavedArgs.match(eq('userRespondedToToast')),
storageGetSavedArgs.match(ANYTHING)).
will(invokeCallback(storageGetSavedArgs, 1, testUserRespondedToToast));
var setBackgroundEnableSavedArgs = new SaveMockArguments();
fixture.mockGlobals.expects(once()).
setBackgroundEnable(
setBackgroundEnableSavedArgs.match(ANYTHING),
setBackgroundEnableSavedArgs.match(ANYTHING)).
will(invokeCallback(
setBackgroundEnableSavedArgs, 1, {}));
}
/**
* 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) {
mockApisObj.expects(once()).
chrome_location_clearWatch(ANYTHING);
mockApisObj.expects(once()).
updateCardsAttempts_stop();
mockApisObj.expects(once()).
chrome_storage_local_set(eqJSON({notificationsData: {}}));
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_ToastStateEmpty1',
function() {
// Tests the case when the user isn't signed in and NOTIFICATION_CARDS_URL
// is not set. Since NOTIFICATION_CARDS_URL is empty,
// nothing should start.
// Setup and expectations.
NOTIFICATION_CARDS_URL = undefined;
var testIdentityToken = undefined;
var testGeolocationPref = false;
var testUserRespondedToToast = {};
var testExperimentVariationParams = {};
mockInitializeDependencies(this);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.EXTENSION_START);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.STOPPED);
expectInitialization(this.mockApis);
expectStateMachineCalls(
this,
testIdentityToken,
testGeolocationPref,
testUserRespondedToToast,
testExperimentVariationParams);
var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
this.mockApis.expects(exactly(2)).
instrumented_notifications_getAll(
chromeNotificationGetAllSavedArgs.match(ANYTHING)).
will(
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));
// TODO(robliao,vadimt): Determine the granularity of testing to perform.
// Invoking the tested function.
initialize();
});
TEST_F(
'GoogleNowBackgroundUnitTest',
'Initialize_ToastStateEmpty2',
function() {
// Tests the case when NOTIFICATION_CARDS_URL is but 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.
NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
var testIdentityToken = undefined;
var testGeolocationPref = false;
var testUserRespondedToToast = {};
var testExperimentVariationParams = {};
mockInitializeDependencies(this);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.EXTENSION_START);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.STOPPED);
expectInitialization(this.mockApis);
expectStateMachineCalls(
this,
testIdentityToken,
testGeolocationPref,
testUserRespondedToToast,
testExperimentVariationParams);
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();
});
TEST_F(
'GoogleNowBackgroundUnitTest',
'Initialize_ToastStateEmpty3',
function() {
// Tests the case when NOTIFICATION_CARDS_URL is set, getAuthToken
// succeeds, and the user has never responded to the toast.
// In this case, the function should invoke showWelcomeToast().
// Setup and expectations.
NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
var testIdentityToken = 'some identity token';
var testGeolocationPref = false;
var testUserRespondedToToast = {};
var testExperimentVariationParams = {};
mockInitializeDependencies(this);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.EXTENSION_START);
expectInitialization(this.mockApis);
expectStateMachineCalls(
this,
testIdentityToken,
testGeolocationPref,
testUserRespondedToToast,
testExperimentVariationParams);
var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
this.mockApis.expects(exactly(2)).
instrumented_notifications_getAll(
chromeNotificationGetAllSavedArgs.match(ANYTHING)).
will(
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));
this.mockGlobals.expects(once()).showWelcomeToast();
// 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.
NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
var testIdentityToken = 'some identity token';
var testGeolocationPref = true;
var testUserRespondedToToast = {userRespondedToToast: true};
var testExperimentVariationParams = {};
mockInitializeDependencies(this);
this.mockGlobals.expects(once()).recordEvent(
GoogleNowEvent.EXTENSION_START);
expectInitialization(this.mockApis);
expectStateMachineCalls(
this,
testIdentityToken,
testGeolocationPref,
testUserRespondedToToast,
testExperimentVariationParams);
var chromeNotificationGetAllSavedArgs = new SaveMockArguments();
this.mockApis.expects(exactly(2)).
instrumented_notifications_getAll(
chromeNotificationGetAllSavedArgs.match(ANYTHING)).
will(
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}),
invokeCallback(chromeNotificationGetAllSavedArgs, 0, {}));
this.mockGlobals.expects(once()).startPollingCards();
// Invoking the tested function.
initialize();
});
TEST_F('GoogleNowBackgroundUnitTest', '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.
NOTIFICATION_CARDS_URL = 'https://some.server.url.com';
var testIdentityToken = 'some identity token';
var testGeolocationPref = false;
var testUserRespondedToToast = {userRespondedToToast: true};
var testExperimentVariationParams = {};
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,
testUserRespondedToToast,
testExperimentVariationParams);
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_ActionUrlsNotObject',
function() {
// Tests the case when the data associated with notification id is not an
// object, probably because of a malformed server response.
// In this case, the function should do nothing.
// Setup and expectations.
var testActionUrls = 'string, not object';
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));
// 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);
});