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

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: 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 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 for (var testCase of prefsTestCases)
23 this.addPref_(testCase.type, testCase.key, testCase.values[0]);
24 }
25
26 MockSettingsApi.prototype = {
27 // chrome.settingsPrivate overrides.
28 onPrefsChanged: {
29 addListener: function(listener) {
30 this.listener_ = listener;
31 },
32
33 removeListener: function(listener) {
34 expectNotEquals(null, this.listener_);
35 this.listener_ = null;
36 },
37 },
38
39 getAllPrefs: function(callback) {
40 // Send a copy of prefs to keep our internal state private.
41 var prefs = [];
42 for (var key in this.prefs)
43 prefs.push(Object.assign({}, this.prefs[key]))
44
45 setTimeout(callback.bind(null, prefs));
46 },
47
48 setPref: function(key, value, pageId, callback) {
49 var pref = this.prefs[key];
50 assertNotEquals(undefined, pref);
51 assertEquals(typeof value, typeof pref.value);
52 assertEquals(Array.isArray(value), Array.isArray(pref.value));
53
54 if (this.failNextSetPref_) {
55 setTimeout(callback.bind(null, false));
56 this.failNextSetPref_ = false;
57 return;
58 }
59 assertNotEquals(true, this.disallowSetPref_);
60
61 var changed = JSON.stringify(pref.value) != JSON.stringify(value);
62 pref.value = JSON.parse(JSON.stringify(value));
63 setTimeout(function() {
64 callback(true);
65
66 // Like chrome.settingsPrivate, send a notification when prefs change.
67 if (changed)
68 this.sendPrefChangesAsync([{key: key, value: value}]);
69 }.bind(this));
70 },
71
72 getPref: function(key, callback) {
73 var pref = this.prefs[key];
74 assertNotEquals(undefined, pref);
75
76 var prefCopy = Object.assign({}, pref);
77 setTimeout(callback.bind(null, prefCopy));
78 },
79
80 // Functions used by tests.
81
82 /** Instructs the API to return a failure when setPref is next called. */
83 failNextSetPref: function() {
84 this.failNextSetPref_ = true;
85 },
86
87 /** Instructs the API to assert (fail the test) if setPref is called. */
88 disallowSetPref: function() {
89 this.disallowSetPref_ = true;
90 },
91
92 allowSetPref: function() {
93 this.disallowSetPref_ = false;
94 },
95
96 /**
97 * Notifies the listener of pref changes.
98 * @param {!Object<{key: string, value: *}>} changes
99 */
100 sendPrefChangesAsync: function(changes) {
101 var prefs = [];
102 for (var change of changes) {
103 var pref = this.prefs[change.key];
104 assertNotEquals(undefined, pref);
105 pref.value = change.value;
106 prefs.push(Object.assign({}, pref));
107 }
108
109 setTimeout(this.listener_.bind(null, prefs));
110 },
111
112 // Private methods for use by the mock API.
113
114 /**
115 * @param {!chrome.settingsPrivate.PrefType} type
116 * @param {string} key
117 * @param {*} value
118 */
119 addPref_: function(type, key, value) {
120 this.prefs[key] = {
121 type: type,
122 key: key,
123 value: value,
124 };
125 },
126 };
127
128 function registerTests() {
129 suite('CrSettingsPrefs', function() {
130 /**
131 * Prefs instance created before each test.
132 * @type {CrSettingsPrefs}
133 */
134 var prefs;
135
136 /** @type {MockSettingsApi} */
137 var mockApi = null;
138
139 /**
140 * @param {!Object} prefStore Pref store from <cr-settings-prefs>.
141 * @param {string} key Pref key of the pref to return.
142 * @return {(chrome.settingsPrivate.PrefObject|undefined)}
143 */
144 function getPrefFromKey(prefStore, key) {
145 var path = key.split('.');
146 var pref = prefStore;
147 for (var part of path) {
148 pref = pref[part];
149 if (!pref)
150 return undefined;
151 }
152 return pref;
153 }
154
155 /**
156 * Checks that the mock API pref store contains the expected values.
157 * @param {number} testCaseValueIndex The index of possible values from
158 * the test case to check.
159 */
160 function expectMockApiPrefsSet(testCaseValueIndex) {
161 for (var testCase of prefsTestCases) {
162 var expectedValue = JSON.stringify(
163 testCase.values[testCaseValueIndex]);
164 var actualValue = JSON.stringify(mockApi.prefs[testCase.key].value);
165 expectEquals(expectedValue, actualValue);
166 }
167 }
168
169 /**
170 * Checks that the <cr-settings-prefs> contains the expected values.
171 * @param {number} testCaseValueIndex The index of possible values from
172 * the test case to check.
173 */
174 function expectPrefsSet(testCaseValueIndex) {
175 for (var testCase of prefsTestCases) {
176 var expectedValue = JSON.stringify(
177 testCase.values[testCaseValueIndex]);
178 var actualValue = JSON.stringify(
179 prefs.get('prefs.' + testCase.key + '.value'));
180 expectEquals(expectedValue, actualValue);
181 }
182 }
183
184 // Initialize a <cr-settings-prefs> element before each test.
185 setup(function(done) {
186 mockApi = new MockSettingsApi();
187 // TODO(michaelpg): don't use global variables to inject the API.
188 window.mockApi = mockApi;
189
190 // Create and attach the <cr-settings-prefs> element.
191 PolymerTest.clearBody();
192 prefs = document.createElement('cr-settings-prefs');
193 document.body.appendChild(prefs);
194
195 window.mockApi = undefined;
196
197 // Wait for CrSettingsPrefs.INITIALIZED.
198 if (!CrSettingsPrefs.isInitialized) {
199 var listener = function() {
200 document.removeEventListener(CrSettingsPrefs.INITIALIZED, listener);
201 done();
202 };
203 document.addEventListener(CrSettingsPrefs.INITIALIZED, listener);
204 return;
205 }
206
207 done();
208 });
209
210 test('receives and caches prefs', function() {
211 // Test that each pref has been successfully copied to the Polymer
212 // |prefs| property.
213 for (var key in mockApi.prefs) {
214 var expectedPref = mockApi.prefs[key];
215 var actualPref = getPrefFromKey(prefs.prefs, key);
216 if (!expectNotEquals(undefined, actualPref)) {
217 // We've already registered an error, so skip the pref.
218 continue;
219 }
220
221 expectEquals(JSON.stringify(expectedPref),
222 JSON.stringify(actualPref));
223 }
224 });
225
226 test('forwards pref changes to API', function(done) {
227 // Test that cr-settings-prefs uses the setPref API.
228 for (var testCase of prefsTestCases)
229 prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]);
230
231 // Check that setPref has been called for the right values.
232 expectMockApiPrefsSet(1);
233
234 // Test that when setPref fails, the pref is reverted locally.
235 for (var testCase of prefsTestCases) {
236 mockApi.failNextSetPref();
237 prefs.set('prefs.' + testCase.key + '.value', testCase.values[2]);
238 }
239
240 // Queue two async tasks to delay checking the prefs until the
241 // asynchronous round-trip has completed.
242 PolymerTest.async();
243 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
244 expectPrefsSet(1);
245 });
246
247 PolymerTest.async(function() {
248 // Test that setPref is not called when the pref doesn't change.
249 mockApi.disallowSetPref();
250 for (var testCase of prefsTestCases)
251 prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]);
252
253 expectMockApiPrefsSet(1);
254 mockApi.allowSetPref();
255 done();
256 });
257 });
258
259 test('responds to API changes', function(done) {
260 mockApi.disallowSetPref();
261 var prefChanges = [];
262 for (var testCase of prefsTestCases)
263 prefChanges.push({key: testCase.key, value: testCase.values[1]});
264 mockApi.sendPrefChangesAsync(prefChanges);
265
266 PolymerTest.async(function() {
267 expectPrefsSet(1);
268
269 prefChanges = [];
270 for (var testCase of prefsTestCases)
271 prefChanges.push({key: testCase.key, value: testCase.values[2]});
272 mockApi.sendPrefChangesAsync(prefChanges);
273 });
274
275 PolymerTest.async(function() {
276 expectPrefsSet(2);
277 });
278
279 PolymerTest.async(function() {
280 // 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.
281 mockApi.disallowSetPref();
282 mockApi.sendPrefChangesAsync(prefChanges);
283 });
284
285 PolymerTest.async(done);
286 });
287 });
288 }
289
290 return {
291 registerTests: registerTests,
292 };
293 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698