OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 suite('<bookmarks-store>', function() { | |
6 var store; | |
7 var TEST_TREE; | |
8 | |
9 function replaceStore() { | |
10 store = document.createElement('bookmarks-store'); | |
11 replaceBody(store); | |
12 store.setupStore_(TEST_TREE); | |
13 } | |
14 | |
15 function navigateTo(route) { | |
16 window.history.replaceState({}, '', route); | |
17 window.dispatchEvent(new CustomEvent('location-changed')); | |
18 } | |
19 | |
20 /** | |
21 * Overrides the chrome.bookmarks.search to pass results into the callback. | |
22 * @param {Array} results | |
23 */ | |
24 function overrideBookmarksSearch(results) { | |
25 chrome.bookmarks.search = function(searchTerm, callback) { | |
26 callback(results); | |
27 }; | |
28 } | |
29 | |
30 /** | |
31 * Overrides the chrome.bookmarks.getSubTree to pass results into the | |
32 * callback. | |
33 * @param {Array} results | |
34 */ | |
35 function overrideBookmarksGetSubTree(results) { | |
36 chrome.bookmarks.getSubTree = function(parentId, callback) { | |
37 callback(results); | |
38 }; | |
39 } | |
40 | |
41 setup(function() { | |
42 TEST_TREE = createFolder('0', [ | |
43 createFolder( | |
44 '1', | |
45 [ | |
46 createItem('2', {url: 'link2'}), | |
47 createFolder('3', []), | |
48 createItem('6', {url: 'link4'}), | |
49 createItem('7', {url: 'link5'}), | |
50 ]), | |
51 createItem('4', {url: 'link4'}), | |
52 createItem('5', {url: 'link5'}), | |
53 createFolder('8', []), | |
54 ]); | |
55 | |
56 replaceStore(); | |
57 }); | |
58 | |
59 teardown(function() { | |
60 // Clean up anything left in URL. | |
61 navigateTo('/'); | |
62 }); | |
63 | |
64 ////////////////////////////////////////////////////////////////////////////// | |
65 // store initialization tests: | |
66 | |
67 test('initNodes inserts nodes into idToNodeMap', function() { | |
68 assertEquals(TEST_TREE, store.idToNodeMap_['0']); | |
69 assertEquals(TEST_TREE.children[0], store.idToNodeMap_['1']); | |
70 assertEquals(TEST_TREE.children[0].children[0], store.idToNodeMap_['2']); | |
71 assertEquals(TEST_TREE.children[0].children[1], store.idToNodeMap_['3']); | |
72 assertEquals(TEST_TREE.children[1], store.idToNodeMap_['4']); | |
73 assertEquals(TEST_TREE.children[2], store.idToNodeMap_['5']); | |
74 }); | |
75 | |
76 test('correct paths generated for nodes', function() { | |
77 var TEST_PATHS = { | |
78 '0': 'rootNode', | |
79 '1': 'rootNode.children.#0', | |
80 '2': 'rootNode.children.#0.children.#0', | |
81 '3': 'rootNode.children.#0.children.#1', | |
82 '4': 'rootNode.children.#1', | |
83 '5': 'rootNode.children.#2', | |
84 '6': 'rootNode.children.#0.children.#2', | |
85 '7': 'rootNode.children.#0.children.#3', | |
86 '8': 'rootNode.children.#3', | |
87 }; | |
88 | |
89 for (var id in store.idToNodeMap_) | |
90 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | |
91 }); | |
92 | |
93 ////////////////////////////////////////////////////////////////////////////// | |
94 // editing bookmarks tree tests: | |
95 | |
96 test('store updates on selected event', function() { | |
97 // First child of root is selected by default. | |
98 assertEquals('1', store.selectedId); | |
99 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); | |
100 | |
101 // Selecting a selected folder doesn't deselect it. | |
102 store.fire('selected-folder-changed', '1'); | |
103 assertEquals('1', store.selectedId); | |
104 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); | |
105 | |
106 // Select a deeply nested descendant. | |
107 store.fire('selected-folder-changed', '3'); | |
108 assertEquals('3', store.selectedId); | |
109 assertTrue(store.idToNodeMap_['3'].isSelectedFolder); | |
110 assertFalse(store.idToNodeMap_['1'].isSelectedFolder); | |
111 | |
112 // Select a folder in separate subtree. | |
113 store.fire('selected-folder-changed', '8'); | |
114 assertEquals('8', store.selectedId); | |
115 assertTrue(store.idToNodeMap_['8'].isSelectedFolder); | |
116 assertFalse(store.idToNodeMap_['3'].isSelectedFolder); | |
117 }); | |
118 | |
119 test('store updates on open and close', function() { | |
120 // All folders are open by default. | |
121 for (var id in store.idToNodeMap_) { | |
122 if (store.idToNodeMap_[id].url) | |
123 continue; | |
124 | |
125 assertTrue(store.idToNodeMap_[id].isOpen); | |
126 } | |
127 | |
128 // Closing a folder doesn't close any descendants. | |
129 store.fire('folder-open-changed', {id: '1', open: false}); | |
130 assertFalse(store.idToNodeMap_['1'].isOpen); | |
131 assertTrue(store.idToNodeMap_['3'].isOpen); | |
132 store.fire('folder-open-changed', {id: '1', open: true}); | |
133 | |
134 // Closing an ancestor folder of a selected folder selects the ancestor. | |
135 store.fire('selected-folder-changed', '3'); | |
136 store.fire('folder-open-changed', {id: '1', open: false}); | |
137 assertFalse(store.idToNodeMap_['1'].isOpen); | |
138 assertEquals('1', store.selectedId); | |
139 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); | |
140 assertFalse(store.idToNodeMap_['3'].isSelectedFolder); | |
141 }); | |
142 | |
143 test('parent folder opens when descendant folder is selected', function() { | |
144 store.idToNodeMap_['0'].isOpen = false; | |
145 store.idToNodeMap_['1'].isOpen = false; | |
146 store.idToNodeMap_['3'].isOpen = false; | |
147 store.fire('selected-folder-changed', '3'); | |
148 assertTrue(store.idToNodeMap_['0'].isOpen); | |
149 assertTrue(store.idToNodeMap_['1'].isOpen); | |
150 assertFalse(store.idToNodeMap_['3'].isOpen); | |
151 }); | |
152 | |
153 test('deleting a node updates the tree', function() { | |
154 removeChild(TEST_TREE, 1); | |
155 overrideBookmarksGetSubTree([TEST_TREE]); | |
156 // Remove an empty folder/bookmark. | |
157 store.onBookmarkRemoved_('4', {parentId: '0', index: 1}); | |
158 | |
159 // Check the tree is correct. | |
160 assertEquals('5', store.rootNode.children[1].id); | |
161 | |
162 // idToNodeMap_ has been updated. | |
163 assertEquals(undefined, store.idToNodeMap_['4']); | |
164 assertEquals(store.rootNode.children[1], store.idToNodeMap_['5']); | |
165 | |
166 // Paths have been updated. | |
167 var TEST_PATHS = { | |
168 '0': 'rootNode', | |
169 '1': 'rootNode.children.#0', | |
170 '2': 'rootNode.children.#0.children.#0', | |
171 '3': 'rootNode.children.#0.children.#1', | |
172 '5': 'rootNode.children.#1', | |
173 '6': 'rootNode.children.#0.children.#2', | |
174 '7': 'rootNode.children.#0.children.#3', | |
175 '8': 'rootNode.children.#2', | |
176 }; | |
177 | |
178 for (var id in store.idToNodeMap_) | |
179 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | |
180 | |
181 // Remove a folder with children. | |
182 removeChild(TEST_TREE, 0); | |
183 overrideBookmarksGetSubTree([TEST_TREE]); | |
184 | |
185 store.onBookmarkRemoved_('1', {parentId: '0', index: '0'}); | |
186 | |
187 // Check the tree is correct. | |
188 assertEquals('5', store.rootNode.children[0].id); | |
189 assertEquals('8', store.rootNode.children[1].id); | |
190 | |
191 // idToNodeMap_ has been updated. | |
192 assertEquals(undefined, store.idToNodeMap_['1']); | |
193 assertEquals(undefined, store.idToNodeMap_['2']); | |
194 assertEquals(undefined, store.idToNodeMap_['3']); | |
195 assertEquals(undefined, store.idToNodeMap_['4']); | |
196 assertEquals(store.rootNode.children[0], store.idToNodeMap_['5']); | |
197 assertEquals(store.rootNode.children[1], store.idToNodeMap_['8']); | |
198 | |
199 // Paths have been updated. | |
200 TEST_PATHS = { | |
201 '0': 'rootNode', | |
202 '5': 'rootNode.children.#0', | |
203 '8': 'rootNode.children.#1' | |
204 }; | |
205 | |
206 for (var id in store.idToNodeMap_) | |
207 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | |
208 }); | |
209 | |
210 test('selectedId updates after removing a selected folder', function() { | |
211 // Selected folder gets removed. | |
212 store.selectedId = '8'; | |
213 removeChild(TEST_TREE, 3); | |
214 overrideBookmarksGetSubTree([TEST_TREE]); | |
215 | |
216 store.onBookmarkRemoved_('8', {parentId:'0', index:'3'}); | |
217 assertTrue(store.idToNodeMap_['0'].isSelectedFolder); | |
218 assertEquals('0', store.selectedId); | |
219 | |
220 // A folder with selected folder in it gets removed. | |
221 store.selectedId = '3'; | |
222 removeChild(TEST_TREE, 0); | |
223 overrideBookmarksGetSubTree([TEST_TREE]); | |
224 | |
225 store.onBookmarkRemoved_('1', {parentId:'0', index:'0'}); | |
226 assertTrue(store.idToNodeMap_['0'].isSelectedFolder); | |
227 assertEquals('0', store.selectedId); | |
228 }); | |
229 | |
230 test('bookmark gets updated after editing', function() { | |
231 // Edit title updates idToNodeMap_ properly. | |
232 store.onBookmarkChanged_('4', {'title': 'test'}); | |
233 assertEquals('test', store.idToNodeMap_['4'].title); | |
234 assertEquals('link4', store.idToNodeMap_['4'].url); | |
235 | |
236 // Edit url updates idToNodeMap_ properly. | |
237 store.onBookmarkChanged_('5', {'url': 'http://www.google.com'}); | |
238 assertEquals('', store.idToNodeMap_['5'].title); | |
239 assertEquals('http://www.google.com', store.idToNodeMap_['5'].url); | |
240 | |
241 // Edit url and title updates idToNodeMap_ properly. | |
242 store.onBookmarkChanged_('2', { | |
243 'title': 'test', | |
244 'url': 'http://www.google.com', | |
245 }); | |
246 assertEquals('test', store.idToNodeMap_['2'].title); | |
247 assertEquals('http://www.google.com', store.idToNodeMap_['2'].url); | |
248 }); | |
249 | |
250 test('folder gets updated after renaming', function() { | |
251 store.onBookmarkChanged_('3', {'title': 'Main Folder'}); | |
252 assertEquals('Main Folder', store.idToNodeMap_['3'].title); | |
253 assertEquals(undefined, store.idToNodeMap_['3'].url); | |
254 }); | |
255 | |
256 ////////////////////////////////////////////////////////////////////////////// | |
257 // search tests: | |
258 | |
259 test('displayedList updates after searchTerm changes', function() { | |
260 var SEARCH_RESULTS = [ | |
261 createItem('1', {title: 'cat'}), | |
262 createItem('2', {title: 'apple'}), | |
263 createItem('3', {title: 'paris'}), | |
264 ]; | |
265 overrideBookmarksSearch(SEARCH_RESULTS); | |
266 | |
267 // Search for a non-empty string. | |
268 store.searchTerm = 'a'; | |
269 assertFalse(store.rootNode.children[0].isSelectedFolder); | |
270 assertEquals(null, store.selectedId); | |
271 assertEquals(SEARCH_RESULTS, store.displayedList); | |
272 | |
273 // Clear the searchTerm. | |
274 store.searchTerm = ''; | |
275 var defaultFolder = store.rootNode.children[0]; | |
276 assertTrue(defaultFolder.isSelectedFolder); | |
277 assertEquals(defaultFolder.id, store.selectedId); | |
278 assertEquals(defaultFolder.children, store.displayedList); | |
279 | |
280 // Search with no bookmarks returned. | |
281 overrideBookmarksSearch([]); | |
282 store.searchTerm = 'asdf'; | |
283 assertEquals(0, store.displayedList.length); | |
284 }); | |
285 | |
286 ////////////////////////////////////////////////////////////////////////////// | |
287 // selection tests: | |
288 | |
289 test('single select selects the correct bookmark', function() { | |
290 for (var id in store.idToNodeMap_) | |
291 assertFalse(store.idToNodeMap_[id].isSelectedItem); | |
292 | |
293 store.fire('select-item', {item: store.idToNodeMap_['2']}); | |
294 assertDeepEquals( | |
295 [true, false, false, false], | |
296 store.displayedList.map(i => i.isSelectedItem)); | |
297 assertEquals(0, store.anchorIndex_); | |
298 | |
299 // Select other item will remove the previous selection. | |
300 store.fire('select-item', {item: store.idToNodeMap_['3']}); | |
301 assertDeepEquals( | |
302 [false, true, false, false], | |
303 store.displayedList.map(i => i.isSelectedItem)); | |
304 assertEquals(1, store.anchorIndex_); | |
305 | |
306 // Deleting the selected item will unselect everything. | |
307 store.selectedId = '1'; | |
308 store.fire('select-item', {item: store.idToNodeMap_['2']}); | |
309 removeChild(TEST_TREE.children[0], 0); | |
310 overrideBookmarksGetSubTree([TEST_TREE.children[0]]); | |
311 store.onBookmarkRemoved_('2', {parentId: '1', index: 0}); | |
312 assertDeepEquals( | |
313 [false, false, false], | |
314 store.displayedList.map(i => i.isSelectedItem)); | |
315 assertEquals(null, store.anchorIndex_); | |
316 | |
317 // Changing the selected folder will remove the select status of the | |
318 // bookmark. | |
319 store.selectedId = '3'; | |
320 assertDeepEquals( | |
321 [false, false, false], | |
322 store.idToNodeMap_['1'].children.map(i => i.isSelectedItem)); | |
323 assertEquals(null, store.anchorIndex_); | |
324 }); | |
325 | |
326 test('shift select selects the correct bookmarks', function() { | |
327 // When nothing has been selected, it selects a single item. | |
328 assertEquals(null, store.anchorIndex_); | |
329 store.fire('select-item', {item: store.idToNodeMap_['6'], range: true}); | |
330 assertDeepEquals( | |
331 [false, false, true, false], | |
332 store.displayedList.map(i => i.isSelectedItem)); | |
333 assertEquals(2, store.anchorIndex_); | |
334 | |
335 // Select an item below the previous selected item. | |
336 store.fire('select-item', {item: store.idToNodeMap_['7'], range: true}); | |
337 assertEquals(2, store.anchorIndex_); | |
338 assertDeepEquals( | |
339 [false, false, true, true], | |
340 store.displayedList.map(i => i.isSelectedItem)); | |
341 | |
342 // Select an item above the previous selected item. | |
343 store.fire('select-item', {item: store.idToNodeMap_['2'], range: true}); | |
344 assertEquals(2, store.anchorIndex_); | |
345 assertDeepEquals( | |
346 [true, true, true, false], | |
347 store.displayedList.map(i => i.isSelectedItem)); | |
348 }); | |
349 | |
350 test('ctrl select selects the correct bookmarks', function() { | |
351 // When nothing has been selected, it selects a single item. | |
352 assertEquals(null, store.anchorIndex_); | |
353 store.fire('select-item', {item: store.idToNodeMap_['6'], add: true}); | |
354 assertDeepEquals( | |
355 [false, false, true, false], | |
356 store.displayedList.map(i => i.isSelectedItem)); | |
357 assertEquals(2, store.anchorIndex_); | |
358 | |
359 // Select a new item will not deselect the previous item, but will update | |
360 // anchorIndex_. | |
361 store.fire('select-item', {item: store.idToNodeMap_['2'], add: true}); | |
362 assertDeepEquals( | |
363 [true, false, true, false], | |
364 store.displayedList.map(i => i.isSelectedItem)); | |
365 assertEquals(0, store.anchorIndex_); | |
366 }); | |
367 | |
368 test('shift + ctrl select selects the correct bookmarks', function() { | |
369 store.fire('select-item', {item: store.displayedList[0]}); | |
370 store.fire( | |
371 'select-item', {item: store.displayedList[2], add: true, range: false}); | |
372 store.fire( | |
373 'select-item', {item: store.displayedList[3], add: true, range: true}); | |
374 assertDeepEquals( | |
375 [true, false, true, true], | |
376 store.displayedList.map(i => i.isSelectedItem)); | |
377 assertEquals(2, store.anchorIndex_); | |
378 }); | |
379 | |
380 test('selection in search mode', function() { | |
381 // Item gets unselected in search. | |
382 overrideBookmarksSearch([ | |
383 createItem('4', {url: 'link4'}), | |
384 createItem('2', {url: 'link2'}), | |
385 createItem('5', {url: 'link5'}), | |
386 ]); | |
387 | |
388 store.selectedId = '1'; | |
389 store.fire('select-item', {item: store.idToNodeMap_['3']}); | |
390 store.searchTerm = 'a'; | |
391 assertFalse(store.idToNodeMap_['3'].isSelectedItem); | |
392 assertEquals(null, store.anchorIndex_); | |
393 | |
394 // anchorIndex_ gets updated properly in single select. | |
395 store.fire('select-item', {item: store.displayedList[1]}); | |
396 assertDeepEquals( | |
397 [false, true, false], | |
398 store.displayedList.map(i => i.isSelectedItem)); | |
399 assertEquals(1, store.anchorIndex_); | |
400 | |
401 // anchorIndex_ gets updated properly in ctrl select. | |
402 store.fire('select-item', {item: store.displayedList[0], add: true}); | |
403 assertDeepEquals( | |
404 [true, true, false], | |
405 store.displayedList.map(i => i.isSelectedItem)); | |
406 assertEquals(0, store.anchorIndex_); | |
407 | |
408 // Deleting the selected item will unselect everything. | |
409 store.fire('select-item', {item: store.displayedList[1]}); | |
410 overrideBookmarksSearch([ | |
411 createItem('4', {url: 'link4'}), | |
412 createItem('5', {url: 'link5'}), | |
413 ]); | |
414 removeChild(TEST_TREE.children[0], 0); | |
415 overrideBookmarksGetSubTree([TEST_TREE.children[0]]); | |
416 | |
417 store.onBookmarkRemoved_('2', {parentId: '1', index: 0}); | |
418 assertDeepEquals( | |
419 [false, false], | |
420 store.displayedList.map(i => i.isSelectedItem)); | |
421 assertEquals(null, store.anchorIndex_); | |
422 | |
423 // Shift+Ctrl select selects the right items. | |
424 overrideBookmarksSearch([ | |
425 createItem('4', {url: 'link4'}), | |
426 createFolder('3', []), | |
427 createItem('5', {url: 'link5'}), | |
428 createItem('6', {url: 'link4'}), | |
429 createItem('7', {url: 'link5'}), | |
430 ]); | |
431 store.searchTerm = 'b'; | |
432 store.fire('select-item', {item: store.displayedList[0]}); | |
433 store.fire( | |
434 'select-item', {item: store.displayedList[2], add: true, range: false}); | |
435 store.fire( | |
436 'select-item', {item: store.displayedList[4], add: true, range: true}); | |
437 assertDeepEquals( | |
438 [true, false, true, true, true], | |
439 store.displayedList.map(i => i.isSelectedItem)); | |
440 assertEquals(2, store.anchorIndex_); | |
441 }); | |
442 }); | |
OLD | NEW |