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

Side by Side 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: already reviewed 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 /** @fileoverview Suite of tests for cr-settings-prefs. */
6 cr.define('cr_settings_prefs', function() {
7 /**
8 * Mock of chrome.settingsPrivate API.
9 * @constructor
10 * @extends {chrome.settingsPrivate}
11 */
12 function MockSettingsApi() {
13 this.prefs = {};
14 this.listener_ = null;
15
16 // Hack alert: bind this instance's onPrefsChanged members to this.
17 this.onPrefsChanged = {
18 addListener: this.onPrefsChanged.addListener.bind(this),
19 removeListener: this.onPrefsChanged.removeListener.bind(this),
20 };
21
22 this.addBooleanPref_('top_level_pref', true);
23 this.addBooleanPref_('browser.enable_flash', false);
24 this.addBooleanPref_('browser.enable_html5', true);
25 this.addNumberPref_('device.overclock', .6);
26 this.addStringPref_('homepage', 'example.com');
27 }
28
29 MockSettingsApi.prototype = {
30 // chrome.settingsPrivate overrides.
31 onPrefsChanged: {
32 addListener: function(listener) {
33 this.listener_ = listener;
34 },
35
36 removeListener: function(listener) {
37 expectNotEquals(null, this.listener_);
38 this.listener_ = null;
39 },
40 },
41
42 getAllPrefs: function(callback) {
43 // Send a copy of prefs to keep our internal state private.
44 var prefs = [];
45 for (var key in this.prefs)
46 prefs.push(Object.assign({}, this.prefs[key]));
47
48 setTimeout(callback.bind(null, prefs));
49 },
50
51 setPref: function(key, value, pageId, callback) {
52 var pref = this.prefs[key];
53 assertNotEquals(undefined, pref);
54 assertEquals(typeof value, typeof pref.value);
55 assertEquals(Array.isArray(value), Array.isArray(pref.value));
56
57 if (this.failNextSetPref_) {
58 setTimeout(callback.bind(null, false));
59 this.failNextSetPref_ = false;
60 return;
61 }
62
63 // TODO(michaelpg): support list and dict prefs.
64 var changed = this.prefs[key].value != value;
65 this.prefs[key].value = value;
66 setTimeout(function() {
67 callback(true);
68 // Like chrome.settingsPrivate, send a notification when prefs change.
69 if (changed)
70 this.sendPrefChanges([key], [value]);
71 }.bind(this));
72 },
73
74 getPref: function(key, callback) {
75 var pref = this.prefs[key];
76 assertNotEquals(undefined, pref);
77
78 var prefCopy = Object.assign({}, pref);
79 setTimeout(callback.bind(null, prefCopy));
80 },
81
82 // Functions used by tests.
83
84 /** Instructs the API to fail when setPref is next called. */
85 failNextSetPref: function() {
86 this.failNextSetPref_ = true;
87 },
88
89 /**
90 * Notifies the listener of pref changes.
91 * @param {!Array<string>} keys
92 * @param {!Array<*>} values
93 */
94 sendPrefChanges: function(keys, values) {
95 var prefs = [];
96 for (var i = 0; i < keys.length; i++) {
97 var key = keys[i];
98 var pref = this.prefs[key];
99 pref.value = values[i];
100 prefs.push(Object.assign({}, pref));
101 }
102
103 setTimeout(this.listener_.bind(null, prefs));
104 },
105
106 // Private methods for use by the mock API.
107
108 /**
109 * @param {!chrome.settingsPrivate.PrefType} type
110 * @param {string} key
111 * @param {*} value
112 */
113 addPref_: function(type, key, value) {
114 this.prefs[key] = {
115 type: type,
116 key: key,
117 value: value,
118 };
119 },
120
121 /**
122 * @param {string} key
123 * @param {boolean} value
124 */
125 addBooleanPref_: function(key, value) {
126 this.addPref_(chrome.settingsPrivate.PrefType.BOOLEAN, key, value);
127 },
128
129 /**
130 * @param {string} key
131 * @param {number} value
132 */
133 addNumberPref_: function(key, value) {
134 this.addPref_(chrome.settingsPrivate.PrefType.NUMBER, key, value);
135 },
136
137 /**
138 * @param {string} key
139 * @param {string} value
140 */
141 addStringPref_: function(key, value) {
142 this.addPref_(chrome.settingsPrivate.PrefType.STRING, key, value);
143 },
144 };
145
146 /**
147 * Helper function to deal with asynchronicity by repeatedly queueing
148 * tasks to check if the callback returns true.
149 * @param {function(): boolean} callback
150 * @return {Promise}
151 */
152 function waitUntilTrue(callback) {
153 return new Promise(function(resolve, reject) {
154 var interval = setInterval(function() {
155 if (callback.call()) {
156 clearInterval(interval);
157 resolve();
158 }
159 });
160 });
161 }
162
163 /**
164 * @param {!Object} prefStore Pref store from <cr-settings-prefs>.
165 * @param {string} key Pref key of the pref to return.
166 * @return {(chrome.settingsPrivate.PrefObject|undefined}
Dan Beam 2015/09/14 23:31:48 nit: https://xkcd.com/859/
michaelpg 2015/09/15 01:17:57 Done.
167 */
168 function getPrefFromKey(prefStore, key) {
169 var path = key.split('.');
170 var pref = prefStore;
171 for (var part of path) {
172 pref = pref[part];
173 if (!pref)
174 return;
stevenjb 2015/09/14 23:18:19 nit: return undefined? (That would be more clear t
Dan Beam 2015/09/14 23:31:48 not all that common
michaelpg 2015/09/15 01:17:58 Done.
175 }
176 return pref;
177 }
178
179 function registerTests() {
180 suite('CrSettingsPrefs', function() {
181 /**
182 * Prefs instance created before each test.
183 * @type {CrSettingsPrefs}
184 */
185 var prefs;
186
187 /** @type {MockSettingsApi} */
188 var mockApi = null;
189
190 // Initialize a <cr-settings-prefs> element before each test.
191 setup(function(done) {
192 mockApi = new MockSettingsApi();
193 // TODO(michaelpg): don't use global variables to inject the API.
194 window.mockApi = mockApi;
195
196 // Create and attach the <cr-settings-prefs> element.
197 PolymerTest.clearBody();
198 prefs = document.createElement('cr-settings-prefs');
199 document.body.appendChild(prefs);
200
201 window.mockApi = undefined;
202
203 // Wait for CrSettingsPrefs.INITIALIZED.
204 if (!CrSettingsPrefs.isInitialized) {
205 var listener = function() {
206 document.removeEventListener(CrSettingsPrefs.INITIALIZED, listener);
207 done();
208 };
209 document.addEventListener(CrSettingsPrefs.INITIALIZED, listener);
210 return;
211 }
212
213 done();
214 });
215
216 test('receives and caches prefs', function() {
217 // Test that each pref has been successfully copied to the Polymer
218 // |prefs| property.
219 for (var key in mockApi.prefs) {
220 var expectedPref = mockApi.prefs[key];
221 var actualPref = getPrefFromKey(prefs.prefs, key);
222 if (!expectNotEquals(undefined, actualPref)) {
223 // We've already registered an error, so skip the pref.
224 continue;
225 }
226
227 expectEquals(expectedPref.key, actualPref.key);
228 expectEquals(expectedPref.type, actualPref.type);
229 if (expectedPref.type != chrome.settingsPrivate.LIST) {
230 expectEquals(expectedPref.value, actualPref.value);
231 } else {
232 expectEquals(JSON.stringify(expectedPref.value),
233 JSON.stringify(actualPref.value));
234 }
235 }
236 });
237
238 test('forwards pref changes to API', function() {
239 // Test that cr-settings-prefs uses the setPref API.
240 prefs.set('prefs.browser.enable_flash.value', true);
241 expectTrue(mockApi.prefs['browser.enable_flash'].value);
242
243 prefs.set('prefs.device.overclock.value', 1.2);
244 expectEquals(1.2, mockApi.prefs['device.overclock'].value);
245
246 prefs.set('prefs.homepage.value', 'chromium.org');
247 expectEquals('chromium.org', mockApi.prefs['homepage'].value);
248
249 // Test that when setPref fails, the pref is reverted locally.
250 mockApi.failNextSetPref();
251 prefs.set('prefs.browser.enable_flash.value', false);
252
253 mockApi.failNextSetPref();
254 prefs.set('prefs.device.overclock.value', 2.0);
255
256 mockApi.failNextSetPref();
257 prefs.set('prefs.homepage.value', 'invalid-url');
258
259 // Multiple asynchronous round trips need to happen.
260 return Promise.all([
261 waitUntilTrue(function() {
262 return prefs.prefs.browser.enable_flash.value;
263 }),
264 waitUntilTrue(function() {
265 return prefs.prefs.device.overclock.value == 1.2;
266 }),
267 waitUntilTrue(function() {
268 return prefs.prefs.homepage.value == 'chromium.org';
269 }),
270 ]);
271 });
272
273 test('responds to API changes', function(done) {
274 mockApi.sendPrefChanges(['top_level_pref'], [false]);
275 PolymerTest.async(function() {
276 expectEquals(false, prefs.prefs.top_level_pref.value);
277
278 mockApi.sendPrefChanges(['top_level_pref'], [true]);
279 });
280 PolymerTest.async(function() {
281 expectEquals(true, prefs.prefs.top_level_pref.value);
282 done();
283 });
284 });
285 });
286 }
287
288 return {
289 registerTests: registerTests,
290 };
291 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698