Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Unified Diff: chrome/test/data/webui/settings/prefs_tests.js

Issue 1310843010: Add Polymer tests for cr-settings-prefs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: new changes Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/test/data/webui/settings/prefs_tests.js
diff --git a/chrome/test/data/webui/settings/prefs_tests.js b/chrome/test/data/webui/settings/prefs_tests.js
new file mode 100644
index 0000000000000000000000000000000000000000..b2168e77b19b130445353b58c7a145d62ff13aaa
--- /dev/null
+++ b/chrome/test/data/webui/settings/prefs_tests.js
@@ -0,0 +1,293 @@
+// Copyright 2015 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.
+
+/** @fileoverview Suite of tests for cr-settings-prefs. */
+cr.define('cr_settings_prefs', function() {
+ /**
+ * Mock of chrome.settingsPrivate API.
+ * @constructor
+ * @extends {chrome.settingsPrivate}
+ */
+ function MockSettingsApi() {
+ this.prefs = {};
+ this.listener_ = null;
+
+ // Hack alert: bind this instance's onPrefsChanged members to this.
+ this.onPrefsChanged = {
+ addListener: this.onPrefsChanged.addListener.bind(this),
+ removeListener: this.onPrefsChanged.removeListener.bind(this),
+ };
+
+ for (var testCase of prefsTestCases)
+ this.addPref_(testCase.type, testCase.key, testCase.values[0]);
+ }
+
+ MockSettingsApi.prototype = {
+ // chrome.settingsPrivate overrides.
+ onPrefsChanged: {
+ addListener: function(listener) {
+ this.listener_ = listener;
+ },
+
+ removeListener: function(listener) {
+ expectNotEquals(null, this.listener_);
+ this.listener_ = null;
+ },
+ },
+
+ getAllPrefs: function(callback) {
+ // Send a copy of prefs to keep our internal state private.
+ var prefs = [];
+ for (var key in this.prefs)
+ prefs.push(Object.assign({}, this.prefs[key]))
+
+ setTimeout(callback.bind(null, prefs));
+ },
+
+ setPref: function(key, value, pageId, callback) {
+ var pref = this.prefs[key];
+ assertNotEquals(undefined, pref);
+ assertEquals(typeof value, typeof pref.value);
+ assertEquals(Array.isArray(value), Array.isArray(pref.value));
+
+ if (this.failNextSetPref_) {
+ setTimeout(callback.bind(null, false));
+ this.failNextSetPref_ = false;
+ return;
+ }
+ assertNotEquals(true, this.disallowSetPref_);
+
+ var changed = JSON.stringify(pref.value) != JSON.stringify(value);
+ pref.value = JSON.parse(JSON.stringify(value));
+ setTimeout(function() {
+ callback(true);
+
+ // Like chrome.settingsPrivate, send a notification when prefs change.
+ if (changed)
+ this.sendPrefChangesAsync([{key: key, value: value}]);
+ }.bind(this));
+ },
+
+ getPref: function(key, callback) {
+ var pref = this.prefs[key];
+ assertNotEquals(undefined, pref);
+
+ var prefCopy = Object.assign({}, pref);
+ setTimeout(callback.bind(null, prefCopy));
+ },
+
+ // Functions used by tests.
+
+ /** Instructs the API to return a failure when setPref is next called. */
+ failNextSetPref: function() {
+ this.failNextSetPref_ = true;
+ },
+
+ /** Instructs the API to assert (fail the test) if setPref is called. */
+ disallowSetPref: function() {
+ this.disallowSetPref_ = true;
+ },
+
+ allowSetPref: function() {
+ this.disallowSetPref_ = false;
+ },
+
+ /**
+ * Notifies the listener of pref changes.
+ * @param {!Object<{key: string, value: *}>} changes
+ */
+ sendPrefChangesAsync: function(changes) {
+ var prefs = [];
+ for (var change of changes) {
+ var pref = this.prefs[change.key];
+ assertNotEquals(undefined, pref);
+ pref.value = change.value;
+ prefs.push(Object.assign({}, pref));
+ }
+
+ setTimeout(this.listener_.bind(null, prefs));
+ },
+
+ // Private methods for use by the mock API.
+
+ /**
+ * @param {!chrome.settingsPrivate.PrefType} type
+ * @param {string} key
+ * @param {*} value
+ */
+ addPref_: function(type, key, value) {
+ this.prefs[key] = {
+ type: type,
+ key: key,
+ value: value,
+ };
+ },
+ };
+
+ function registerTests() {
+ suite('CrSettingsPrefs', function() {
+ /**
+ * Prefs instance created before each test.
+ * @type {CrSettingsPrefs}
+ */
+ var prefs;
+
+ /** @type {MockSettingsApi} */
+ var mockApi = null;
+
+ /**
+ * @param {!Object} prefStore Pref store from <cr-settings-prefs>.
+ * @param {string} key Pref key of the pref to return.
+ * @return {(chrome.settingsPrivate.PrefObject|undefined)}
+ */
+ function getPrefFromKey(prefStore, key) {
+ var path = key.split('.');
+ var pref = prefStore;
+ for (var part of path) {
+ pref = pref[part];
+ if (!pref)
+ return undefined;
+ }
+ return pref;
+ }
+
+ /**
+ * Checks that the mock API pref store contains the expected values.
+ * @param {number} testCaseValueIndex The index of possible values from
+ * the test case to check.
+ */
+ function expectMockApiPrefsSet(testCaseValueIndex) {
+ for (var testCase of prefsTestCases) {
+ var expectedValue = JSON.stringify(
+ testCase.values[testCaseValueIndex]);
+ var actualValue = JSON.stringify(mockApi.prefs[testCase.key].value);
+ expectEquals(expectedValue, actualValue);
+ }
+ }
+
+ /**
+ * Checks that the <cr-settings-prefs> contains the expected values.
+ * @param {number} testCaseValueIndex The index of possible values from
+ * the test case to check.
+ */
+ function expectPrefsSet(testCaseValueIndex) {
+ for (var testCase of prefsTestCases) {
+ var expectedValue = JSON.stringify(
+ testCase.values[testCaseValueIndex]);
+ var actualValue = JSON.stringify(
+ prefs.get('prefs.' + testCase.key + '.value'));
+ expectEquals(expectedValue, actualValue);
+ }
+ }
+
+ // Initialize a <cr-settings-prefs> element before each test.
+ setup(function(done) {
+ mockApi = new MockSettingsApi();
+ // TODO(michaelpg): don't use global variables to inject the API.
+ window.mockApi = mockApi;
+
+ // Create and attach the <cr-settings-prefs> element.
+ PolymerTest.clearBody();
+ prefs = document.createElement('cr-settings-prefs');
+ document.body.appendChild(prefs);
+
+ window.mockApi = undefined;
+
+ // Wait for CrSettingsPrefs.INITIALIZED.
+ if (!CrSettingsPrefs.isInitialized) {
+ var listener = function() {
+ document.removeEventListener(CrSettingsPrefs.INITIALIZED, listener);
+ done();
+ };
+ document.addEventListener(CrSettingsPrefs.INITIALIZED, listener);
+ return;
+ }
+
+ done();
+ });
+
+ test('receives and caches prefs', function() {
+ // Test that each pref has been successfully copied to the Polymer
+ // |prefs| property.
+ for (var key in mockApi.prefs) {
+ var expectedPref = mockApi.prefs[key];
+ var actualPref = getPrefFromKey(prefs.prefs, key);
+ if (!expectNotEquals(undefined, actualPref)) {
+ // We've already registered an error, so skip the pref.
+ continue;
+ }
+
+ expectEquals(JSON.stringify(expectedPref),
+ JSON.stringify(actualPref));
+ }
+ });
+
+ test('forwards pref changes to API', function(done) {
+ // Test that cr-settings-prefs uses the setPref API.
+ for (var testCase of prefsTestCases)
+ prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]);
+
+ // Check that setPref has been called for the right values.
+ expectMockApiPrefsSet(1);
+
+ // Test that when setPref fails, the pref is reverted locally.
+ for (var testCase of prefsTestCases) {
+ mockApi.failNextSetPref();
+ prefs.set('prefs.' + testCase.key + '.value', testCase.values[2]);
+ }
+
+ // Queue two async tasks to delay checking the prefs until the
+ // asynchronous round-trip has completed.
+ PolymerTest.async();
+ PolymerTest.async(function() {
Dan Beam 2015/09/15 01:37:18 can this be PolymerTest.async().then(...)?
michaelpg 2015/09/15 02:20:53 no: * = prefs_tests.js \> = prefs.js depth = stac
Dan Beam 2015/09/16 00:54:19 this doesn't seem good
michaelpg 2015/09/16 01:14:09 it comes down to: do we want to A) write a complex
Dan Beam 2015/09/16 01:37:00 you're really just testing a complex mock
+ expectPrefsSet(1);
+ });
+
+ PolymerTest.async(function() {
+ // Test that setPref is not called when the pref doesn't change.
+ mockApi.disallowSetPref();
+ for (var testCase of prefsTestCases)
+ prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]);
+
+ expectMockApiPrefsSet(1);
+ mockApi.allowSetPref();
+ done();
+ });
+ });
+
+ test('responds to API changes', function(done) {
+ mockApi.disallowSetPref();
+ var prefChanges = [];
+ for (var testCase of prefsTestCases)
+ prefChanges.push({key: testCase.key, value: testCase.values[1]});
+ mockApi.sendPrefChangesAsync(prefChanges);
+
+ PolymerTest.async(function() {
+ expectPrefsSet(1);
+
+ prefChanges = [];
+ for (var testCase of prefsTestCases)
+ prefChanges.push({key: testCase.key, value: testCase.values[2]});
+ mockApi.sendPrefChangesAsync(prefChanges);
+ });
+
+ PolymerTest.async(function() {
+ expectPrefsSet(2);
+ });
+
+ PolymerTest.async(function() {
+ // Shouldn't respond to non-changes.
Dan Beam 2015/09/15 01:37:18 nit: don't not remove double negatives?
michaelpg 2015/09/15 02:20:53 Not undone.
+ mockApi.disallowSetPref();
+ mockApi.sendPrefChangesAsync(prefChanges);
+ });
+
+ PolymerTest.async(done);
+ });
+ });
+ }
+
+ return {
+ registerTests: registerTests,
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698