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

Side by Side Diff: chrome/test/data/webui/md_bookmarks/store_test.js

Issue 2704983002: MD Bookmarks: Proof-of-concept reimplementation of data storage/binding layer (Closed)
Patch Set: Add doc comments Created 3 years, 9 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 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('changing selectedId changes the displayedList', function() {
97 store.selectedId = '0';
98 assertEquals(TEST_TREE.children, store.displayedList);
99 store.selectedId = '1';
100 assertEquals(TEST_TREE.children[0].children, store.displayedList);
101 store.selectedId = '3';
102 assertEquals(
103 TEST_TREE.children[0].children[1].children, store.displayedList);
104
105 // Selecting an item selects the default folder.
106 store.selectedId = '5';
107 assertEquals(TEST_TREE.children[0].children, store.displayedList);
108 });
109
110 test('store updates on selected event', function() {
111 // First child of root is selected by default.
112 assertEquals('1', store.selectedId);
113 assertTrue(store.idToNodeMap_['1'].isSelectedFolder);
114
115 // Selecting a selected folder doesn't deselect it.
116 store.fire('selected-folder-changed', '1');
117 assertEquals('1', store.selectedId);
118 assertTrue(store.idToNodeMap_['1'].isSelectedFolder);
119
120 // Select a deeply nested descendant.
121 store.fire('selected-folder-changed', '3');
122 assertEquals('3', store.selectedId);
123 assertTrue(store.idToNodeMap_['3'].isSelectedFolder);
124 assertFalse(store.idToNodeMap_['1'].isSelectedFolder);
125
126 // Select a folder in separate subtree.
127 store.fire('selected-folder-changed', '8');
128 assertEquals('8', store.selectedId);
129 assertTrue(store.idToNodeMap_['8'].isSelectedFolder);
130 assertFalse(store.idToNodeMap_['3'].isSelectedFolder);
131 });
132
133 test('store updates on open and close', function() {
134 // All folders are open by default.
135 for (var id in store.idToNodeMap_) {
136 if (store.idToNodeMap_[id].url)
137 continue;
138
139 assertTrue(store.idToNodeMap_[id].isOpen);
140 }
141
142 // Closing a folder doesn't close any descendants.
143 store.fire('folder-open-changed', {id: '1', open: false});
144 assertFalse(store.idToNodeMap_['1'].isOpen);
145 assertTrue(store.idToNodeMap_['3'].isOpen);
146 store.fire('folder-open-changed', {id: '1', open: true});
147
148 // Closing an ancestor folder of a selected folder selects the ancestor.
149 store.fire('selected-folder-changed', '3');
150 store.fire('folder-open-changed', {id: '1', open: false});
151 assertFalse(store.idToNodeMap_['1'].isOpen);
152 assertEquals('1', store.selectedId);
153 assertTrue(store.idToNodeMap_['1'].isSelectedFolder);
154 assertFalse(store.idToNodeMap_['3'].isSelectedFolder);
155 });
156
157 test('parent folder opens when descendant folder is selected', function() {
158 store.idToNodeMap_['0'].isOpen = false;
159 store.idToNodeMap_['1'].isOpen = false;
160 store.idToNodeMap_['3'].isOpen = false;
161 store.fire('selected-folder-changed', '3');
162 assertTrue(store.idToNodeMap_['0'].isOpen);
163 assertTrue(store.idToNodeMap_['1'].isOpen);
164 assertFalse(store.idToNodeMap_['3'].isOpen);
165 });
166
167 test('deleting a node updates the tree', function() {
168 removeChild(TEST_TREE, 1);
169 overrideBookmarksGetSubTree([TEST_TREE]);
170 // Remove an empty folder/bookmark.
171 store.onBookmarkRemoved_('4', {parentId: '0', index: 1});
172
173 // Check the tree is correct.
174 assertEquals('5', store.rootNode.children[1].id);
175
176 // idToNodeMap_ has been updated.
177 assertEquals(undefined, store.idToNodeMap_['4']);
178 assertEquals(store.rootNode.children[1], store.idToNodeMap_['5']);
179
180 // Paths have been updated.
181 var TEST_PATHS = {
182 '0': 'rootNode',
183 '1': 'rootNode.children.#0',
184 '2': 'rootNode.children.#0.children.#0',
185 '3': 'rootNode.children.#0.children.#1',
186 '5': 'rootNode.children.#1',
187 '6': 'rootNode.children.#0.children.#2',
188 '7': 'rootNode.children.#0.children.#3',
189 '8': 'rootNode.children.#2',
190 };
191
192 for (var id in store.idToNodeMap_)
193 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path);
194
195 // Remove a folder with children.
196 removeChild(TEST_TREE, 0);
197 overrideBookmarksGetSubTree([TEST_TREE]);
198
199 store.onBookmarkRemoved_('1', {parentId: '0', index: '0'});
200
201 // Check the tree is correct.
202 assertEquals('5', store.rootNode.children[0].id);
203 assertEquals('8', store.rootNode.children[1].id);
204
205 // idToNodeMap_ has been updated.
206 assertEquals(undefined, store.idToNodeMap_['1']);
207 assertEquals(undefined, store.idToNodeMap_['2']);
208 assertEquals(undefined, store.idToNodeMap_['3']);
209 assertEquals(undefined, store.idToNodeMap_['4']);
210 assertEquals(store.rootNode.children[0], store.idToNodeMap_['5']);
211 assertEquals(store.rootNode.children[1], store.idToNodeMap_['8']);
212
213 // Paths have been updated.
214 TEST_PATHS = {
215 '0': 'rootNode',
216 '5': 'rootNode.children.#0',
217 '8': 'rootNode.children.#1'
218 };
219
220 for (var id in store.idToNodeMap_)
221 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path);
222 });
223
224 test('selectedId updates after removing a selected folder', function() {
225 // Selected folder gets removed.
226 store.selectedId = '8';
227 removeChild(TEST_TREE, 3);
228 overrideBookmarksGetSubTree([TEST_TREE]);
229
230 store.onBookmarkRemoved_('8', {parentId:'0', index:'3'});
231 assertTrue(store.idToNodeMap_['0'].isSelectedFolder);
232 assertEquals('0', store.selectedId);
233
234 // A folder with selected folder in it gets removed.
235 store.selectedId = '3';
236 removeChild(TEST_TREE, 0);
237 overrideBookmarksGetSubTree([TEST_TREE]);
238
239 store.onBookmarkRemoved_('1', {parentId:'0', index:'0'});
240 assertTrue(store.idToNodeMap_['0'].isSelectedFolder);
241 assertEquals('0', store.selectedId);
242 });
243
244 test('bookmark gets updated after editing', function() {
245 // Edit title updates idToNodeMap_ properly.
246 store.onBookmarkChanged_('4', {'title': 'test'});
247 assertEquals('test', store.idToNodeMap_['4'].title);
248 assertEquals('link4', store.idToNodeMap_['4'].url);
249
250 // Edit url updates idToNodeMap_ properly.
251 store.onBookmarkChanged_('5', {'url': 'http://www.google.com'});
252 assertEquals('', store.idToNodeMap_['5'].title);
253 assertEquals('http://www.google.com', store.idToNodeMap_['5'].url);
254
255 // Edit url and title updates idToNodeMap_ properly.
256 store.onBookmarkChanged_('2', {
257 'title': 'test',
258 'url': 'http://www.google.com',
259 });
260 assertEquals('test', store.idToNodeMap_['2'].title);
261 assertEquals('http://www.google.com', store.idToNodeMap_['2'].url);
262 });
263
264 test('folder gets updated after renaming', function() {
265 store.onBookmarkChanged_('3', {'title': 'Main Folder'});
266 assertEquals('Main Folder', store.idToNodeMap_['3'].title);
267 assertEquals(undefined, store.idToNodeMap_['3'].url);
268 });
269
270 //////////////////////////////////////////////////////////////////////////////
271 // search tests:
272
273 test('displayedList updates after searchTerm changes', function() {
274 var SEARCH_RESULTS = [
275 createItem('1', {title: 'cat'}),
276 createItem('2', {title: 'apple'}),
277 createItem('3', {title: 'paris'}),
278 ];
279 overrideBookmarksSearch(SEARCH_RESULTS);
280
281 // Search for a non-empty string.
282 store.searchTerm = 'a';
283 assertFalse(store.rootNode.children[0].isSelectedFolder);
284 assertEquals(null, store.selectedId);
285 assertEquals(SEARCH_RESULTS, store.displayedList);
286
287 // Clear the searchTerm.
288 store.searchTerm = '';
289 var defaultFolder = store.rootNode.children[0];
290 assertTrue(defaultFolder.isSelectedFolder);
291 assertEquals(defaultFolder.id, store.selectedId);
292 assertEquals(defaultFolder.children, store.displayedList);
293
294 // Search with no bookmarks returned.
295 overrideBookmarksSearch([]);
296 store.searchTerm = 'asdf';
297 assertEquals(0, store.displayedList.length);
298 });
299
300 //////////////////////////////////////////////////////////////////////////////
301 // router tests:
302
303 test('search updates from route', function() {
304 overrideBookmarksSearch([]);
305 searchTerm = 'Pond';
306 navigateTo('/?q=' + searchTerm);
307 assertEquals(searchTerm, store.searchTerm);
308 });
309
310 test('search updates from route on setup', function() {
311 overrideBookmarksSearch([]);
312 var searchTerm = 'Boat24';
313 navigateTo('/?q=' + searchTerm);
314 replaceStore();
315 assertEquals(searchTerm, store.searchTerm);
316 });
317
318 test('route updates from search', function() {
319 overrideBookmarksSearch([]);
320 var searchTerm = 'Boat24';
321 store.searchTerm = searchTerm;
322 assertEquals('chrome://bookmarks/?q=' + searchTerm, window.location.href);
323 });
324
325 test('selectedId updates from route', function() {
326 // Folder id routes to the corresponding folder.
327 var selectedId = '3';
328 navigateTo('/?id=' + selectedId);
329 assertEquals(selectedId, store.selectedId);
330
331 // Bookmark id routes to the default Bookmarks Bar.
332 var selectedId = '2';
333 navigateTo('/?id=' + selectedId);
334 assertEquals(store.rootNode.children[0].id, store.selectedId);
335
336 // Invalid id routes to the default Bookmarks Bar.
337 selectedId = 'foo';
338 navigateTo('/?id=' + selectedId);
339 assertEquals(store.rootNode.children[0].id, store.selectedId);
340 });
341
342 test('selectedId updates from route on setup', function() {
343 selectedId = '3';
344 navigateTo('/?id=' + selectedId);
345 replaceStore();
346 assertEquals(selectedId, store.selectedId);
347 });
348
349 test('route updates from selectedId', function() {
350 var selectedId = '2';
351 store.selectedId = selectedId;
352 assertEquals('chrome://bookmarks/?id=' + selectedId, window.location.href);
353 });
354
355 //////////////////////////////////////////////////////////////////////////////
356 // selection tests:
357
358 test('single select selects the correct bookmark', function() {
359 for (var id in store.idToNodeMap_)
360 assertFalse(store.idToNodeMap_[id].isSelectedItem);
361
362 store.fire('select-item', {item: store.idToNodeMap_['2']});
363 assertDeepEquals(
364 [true, false, false, false],
365 store.displayedList.map(i => i.isSelectedItem));
366 assertEquals(0, store.anchorIndex_);
367
368 // Select other item will remove the previous selection.
369 store.fire('select-item', {item: store.idToNodeMap_['3']});
370 assertDeepEquals(
371 [false, true, false, false],
372 store.displayedList.map(i => i.isSelectedItem));
373 assertEquals(1, store.anchorIndex_);
374
375 // Deleting the selected item will unselect everything.
376 store.selectedId = '1';
377 store.fire('select-item', {item: store.idToNodeMap_['2']});
378 removeChild(TEST_TREE.children[0], 0);
379 overrideBookmarksGetSubTree([TEST_TREE.children[0]]);
380 store.onBookmarkRemoved_('2', {parentId: '1', index: 0});
381 assertDeepEquals(
382 [false, false, false],
383 store.displayedList.map(i => i.isSelectedItem));
384 assertEquals(null, store.anchorIndex_);
385
386 // Changing the selected folder will remove the select status of the
387 // bookmark.
388 store.selectedId = '3';
389 assertDeepEquals(
390 [false, false, false],
391 store.idToNodeMap_['1'].children.map(i => i.isSelectedItem));
392 assertEquals(null, store.anchorIndex_);
393 });
394
395 test('shift select selects the correct bookmarks', function() {
396 // When nothing has been selected, it selects a single item.
397 assertEquals(null, store.anchorIndex_);
398 store.fire('select-item', {item: store.idToNodeMap_['6'], range: true});
399 assertDeepEquals(
400 [false, false, true, false],
401 store.displayedList.map(i => i.isSelectedItem));
402 assertEquals(2, store.anchorIndex_);
403
404 // Select an item below the previous selected item.
405 store.fire('select-item', {item: store.idToNodeMap_['7'], range: true});
406 assertEquals(2, store.anchorIndex_);
407 assertDeepEquals(
408 [false, false, true, true],
409 store.displayedList.map(i => i.isSelectedItem));
410
411 // Select an item above the previous selected item.
412 store.fire('select-item', {item: store.idToNodeMap_['2'], range: true});
413 assertEquals(2, store.anchorIndex_);
414 assertDeepEquals(
415 [true, true, true, false],
416 store.displayedList.map(i => i.isSelectedItem));
417 });
418
419 test('ctrl select selects the correct bookmarks', function() {
420 // When nothing has been selected, it selects a single item.
421 assertEquals(null, store.anchorIndex_);
422 store.fire('select-item', {item: store.idToNodeMap_['6'], add: true});
423 assertDeepEquals(
424 [false, false, true, false],
425 store.displayedList.map(i => i.isSelectedItem));
426 assertEquals(2, store.anchorIndex_);
427
428 // Select a new item will not deselect the previous item, but will update
429 // anchorIndex_.
430 store.fire('select-item', {item: store.idToNodeMap_['2'], add: true});
431 assertDeepEquals(
432 [true, false, true, false],
433 store.displayedList.map(i => i.isSelectedItem));
434 assertEquals(0, store.anchorIndex_);
435 });
436
437 test('shift + ctrl select selects the correct bookmarks', function() {
438 store.fire('select-item', {item: store.displayedList[0]});
439 store.fire(
440 'select-item', {item: store.displayedList[2], add: true, range: false});
441 store.fire(
442 'select-item', {item: store.displayedList[3], add: true, range: true});
443 assertDeepEquals(
444 [true, false, true, true],
445 store.displayedList.map(i => i.isSelectedItem));
446 assertEquals(2, store.anchorIndex_);
447 });
448
449 test('selection in search mode', function() {
450 // Item gets unselected in search.
451 overrideBookmarksSearch([
452 createItem('4', {url: 'link4'}),
453 createItem('2', {url: 'link2'}),
454 createItem('5', {url: 'link5'}),
455 ]);
456
457 store.selectedId = '1';
458 store.fire('select-item', {item: store.idToNodeMap_['3']});
459 store.searchTerm = 'a';
460 assertFalse(store.idToNodeMap_['3'].isSelectedItem);
461 assertEquals(null, store.anchorIndex_);
462
463 // anchorIndex_ gets updated properly in single select.
464 store.fire('select-item', {item: store.displayedList[1]});
465 assertDeepEquals(
466 [false, true, false],
467 store.displayedList.map(i => i.isSelectedItem));
468 assertEquals(1, store.anchorIndex_);
469
470 // anchorIndex_ gets updated properly in ctrl select.
471 store.fire('select-item', {item: store.displayedList[0], add: true});
472 assertDeepEquals(
473 [true, true, false],
474 store.displayedList.map(i => i.isSelectedItem));
475 assertEquals(0, store.anchorIndex_);
476
477 // Deleting the selected item will unselect everything.
478 store.fire('select-item', {item: store.displayedList[1]});
479 overrideBookmarksSearch([
480 createItem('4', {url: 'link4'}),
481 createItem('5', {url: 'link5'}),
482 ]);
483 removeChild(TEST_TREE.children[0], 0);
484 overrideBookmarksGetSubTree([TEST_TREE.children[0]]);
485
486 store.onBookmarkRemoved_('2', {parentId: '1', index: 0});
487 assertDeepEquals(
488 [false, false],
489 store.displayedList.map(i => i.isSelectedItem));
490 assertEquals(null, store.anchorIndex_);
491
492 // Shift+Ctrl select selects the right items.
493 overrideBookmarksSearch([
494 createItem('4', {url: 'link4'}),
495 createFolder('3', []),
496 createItem('5', {url: 'link5'}),
497 createItem('6', {url: 'link4'}),
498 createItem('7', {url: 'link5'}),
499 ]);
500 store.searchTerm = 'b';
501 store.fire('select-item', {item: store.displayedList[0]});
502 store.fire(
503 'select-item', {item: store.displayedList[2], add: true, range: false});
504 store.fire(
505 'select-item', {item: store.displayedList[4], add: true, range: true});
506 assertDeepEquals(
507 [true, false, true, true, true],
508 store.displayedList.map(i => i.isSelectedItem));
509 assertEquals(2, store.anchorIndex_);
510 });
511 });
OLDNEW
« no previous file with comments | « chrome/test/data/webui/md_bookmarks/store_client_test.js ('k') | chrome/test/data/webui/md_bookmarks/test_store.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698