OLD | NEW |
---|---|
(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 callback(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 callback(false); | |
56 this.failNextSetPref_ = false; | |
57 return; | |
58 } | |
59 assertNotEquals(true, this.disallowSetPref_); | |
60 | |
61 // TODO(michaelpg): support list and dict prefs. | |
62 var changed = pref.value != value; | |
63 pref.value = value; | |
64 callback(true); | |
65 | |
66 // Like chrome.settingsPrivate, send a notification when prefs change. | |
67 if (changed) | |
68 this.sendPrefChanges([{key: key, value: value}]); | |
69 }, | |
70 | |
71 getPref: function(key, callback) { | |
72 var pref = this.prefs[key]; | |
73 assertNotEquals(undefined, pref); | |
74 callback(Object.assign({}, pref)); | |
75 }, | |
76 | |
77 // Functions used by tests. | |
78 | |
79 /** Instructs the API to return a failure when setPref is next called. */ | |
80 failNextSetPref: function() { | |
81 this.failNextSetPref_ = true; | |
82 }, | |
83 | |
84 /** Instructs the API to assert (fail the test) if setPref is called. */ | |
85 disallowSetPref: function() { | |
86 this.disallowSetPref_ = true; | |
87 }, | |
88 | |
89 allowSetPref: function() { | |
90 this.disallowSetPref_ = false; | |
91 }, | |
92 | |
93 /** | |
94 * Notifies the listener of pref changes. | |
95 * @param {!Object<{key: string, value: *}>} changes | |
96 */ | |
97 sendPrefChanges: function(changes) { | |
98 var prefs = []; | |
99 for (var change of changes) { | |
100 var pref = this.prefs[change.key]; | |
101 assertNotEquals(undefined, pref); | |
102 pref.value = change.value; | |
103 prefs.push(Object.assign({}, pref)); | |
104 } | |
105 this.listener_(prefs); | |
106 }, | |
107 | |
108 // Private methods for use by the mock API. | |
109 | |
110 /** | |
111 * @param {!chrome.settingsPrivate.PrefType} type | |
112 * @param {string} key | |
113 * @param {*} value | |
114 */ | |
115 addPref_: function(type, key, value) { | |
116 this.prefs[key] = { | |
117 type: type, | |
118 key: key, | |
119 value: value, | |
120 }; | |
121 }, | |
122 }; | |
123 | |
124 function registerTests() { | |
125 suite('CrSettingsPrefs', function() { | |
126 /** | |
127 * Prefs instance created before each test. | |
128 * @type {CrSettingsPrefs} | |
129 */ | |
130 var prefs; | |
131 | |
132 /** @type {MockSettingsApi} */ | |
133 var mockApi = null; | |
134 | |
135 /** | |
136 * @param {!Object} prefStore Pref store from <cr-settings-prefs>. | |
137 * @param {string} key Pref key of the pref to return. | |
138 * @return {(chrome.settingsPrivate.PrefObject|undefined)} | |
139 */ | |
140 function getPrefFromKey(prefStore, key) { | |
141 var path = key.split('.'); | |
142 var pref = prefStore; | |
143 for (var part of path) { | |
144 pref = pref[part]; | |
145 if (!pref) | |
146 return undefined; | |
147 } | |
148 return pref; | |
149 } | |
150 | |
151 /** | |
152 * Checks that the mock API pref store contains the expected values. | |
153 * @param {number} testCaseValueIndex The index of possible values from | |
154 * the test case to check. | |
155 */ | |
156 function expectMockApiPrefsSet(testCaseValueIndex) { | |
157 for (var testCase of prefsTestCases) { | |
158 var expectedValue = JSON.stringify( | |
159 testCase.values[testCaseValueIndex]); | |
160 var actualValue = JSON.stringify(mockApi.prefs[testCase.key].value); | |
161 expectEquals(expectedValue, actualValue); | |
162 } | |
163 } | |
164 | |
165 /** | |
166 * Checks that the <cr-settings-prefs> contains the expected values. | |
167 * @param {number} testCaseValueIndex The index of possible values from | |
168 * the test case to check. | |
169 */ | |
170 function expectPrefsSet(testCaseValueIndex) { | |
171 for (var testCase of prefsTestCases) { | |
172 var expectedValue = JSON.stringify( | |
173 testCase.values[testCaseValueIndex]); | |
174 var actualValue = JSON.stringify( | |
175 prefs.get('prefs.' + testCase.key + '.value')); | |
176 expectEquals(expectedValue, actualValue); | |
177 } | |
178 } | |
179 | |
180 // Initialize a <cr-settings-prefs> element before each test. | |
181 setup(function(done) { | |
182 mockApi = new MockSettingsApi(); | |
183 // TODO(michaelpg): don't use global variables to inject the API. | |
184 window.mockApi = mockApi; | |
185 | |
186 // Create and attach the <cr-settings-prefs> element. | |
187 PolymerTest.clearBody(); | |
188 prefs = document.createElement('cr-settings-prefs'); | |
189 document.body.appendChild(prefs); | |
190 | |
191 window.mockApi = undefined; | |
192 | |
193 // Wait for CrSettingsPrefs.INITIALIZED. | |
194 if (!CrSettingsPrefs.isInitialized) { | |
195 var listener = function() { | |
196 document.removeEventListener(CrSettingsPrefs.INITIALIZED, listener); | |
197 done(); | |
198 }; | |
199 document.addEventListener(CrSettingsPrefs.INITIALIZED, listener); | |
200 return; | |
201 } | |
202 | |
203 done(); | |
204 }); | |
205 | |
206 test('receives and caches prefs', function() { | |
207 // Test that each pref has been successfully copied to the Polymer | |
208 // |prefs| property. | |
209 for (var key in mockApi.prefs) { | |
210 var expectedPref = mockApi.prefs[key]; | |
211 var actualPref = getPrefFromKey(prefs.prefs, key); | |
212 if (!expectNotEquals(undefined, actualPref)) { | |
213 // We've already registered an error, so skip the pref. | |
214 continue; | |
215 } | |
216 | |
217 expectEquals(JSON.stringify(expectedPref), | |
218 JSON.stringify(actualPref)); | |
219 } | |
220 }); | |
221 | |
222 test('forwards pref changes to API', function() { | |
223 // Test that cr-settings-prefs uses the setPref API. | |
224 for (var testCase of prefsTestCases) | |
225 prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]); | |
226 | |
227 // Check that setPref has been called for the right values. | |
228 expectMockApiPrefsSet(1); | |
229 | |
230 // Test that when setPref fails, the pref is reverted locally. | |
231 for (var testCase of prefsTestCases) { | |
232 mockApi.failNextSetPref(); | |
233 prefs.set('prefs.' + testCase.key + '.value', testCase.values[2]); | |
234 } | |
235 | |
236 expectPrefsSet(1); | |
237 | |
238 // Test that setPref is not called when the pref doesn't change. | |
239 mockApi.disallowSetPref(); | |
240 for (var testCase of prefsTestCases) | |
241 prefs.set('prefs.' + testCase.key + '.value', testCase.values[1]); | |
242 | |
243 expectMockApiPrefsSet(1); | |
244 mockApi.allowSetPref(); | |
245 }); | |
246 | |
247 test('responds to API changes', function() { | |
248 mockApi.disallowSetPref(); | |
249 var prefChanges = []; | |
250 for (var testCase of prefsTestCases) | |
251 prefChanges.push({key: testCase.key, value: testCase.values[1]}); | |
252 mockApi.sendPrefChanges(prefChanges); | |
253 | |
254 expectPrefsSet(1); | |
255 | |
256 prefChanges = []; | |
257 for (var testCase of prefsTestCases) | |
258 prefChanges.push({key: testCase.key, value: testCase.values[2]}); | |
259 mockApi.sendPrefChanges(prefChanges); | |
260 | |
261 expectPrefsSet(2); | |
262 | |
263 // Only expect setPref calls when the changes are actually different. | |
Dan Beam
2015/09/16 05:53:56
doesn't this mean you need to expectPrefsSet(2) ag
michaelpg
2015/09/16 18:27:17
It wouldn't hurt, but that isn't what I was testin
| |
264 mockApi.disallowSetPref(); | |
265 mockApi.sendPrefChanges(prefChanges); | |
266 }); | |
267 }); | |
268 } | |
269 | |
270 return { | |
271 registerTests: registerTests, | |
272 }; | |
273 }); | |
OLD | NEW |