blob: 0099576f4a1e4c67b983095e34186f27dff82e50 [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.
// 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);
});
/**
* 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);
});