OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 suite('<bookmarks-store>', function() { | 5 suite('<bookmarks-store>', function() { |
6 var store; | 6 var store; |
7 var TEST_TREE; | 7 var TEST_TREE; |
8 | 8 |
9 setup(function() { | 9 setup(function() { |
10 TEST_TREE = createFolder('0', [ | 10 TEST_TREE = createFolder('0', [ |
11 createFolder( | 11 createFolder( |
12 '1', | 12 '1', |
13 [ | 13 [ |
14 createItem('2', {url: 'link2'}), | 14 createItem('2', {url: 'link2'}), |
15 createFolder('3', []), | 15 createFolder('3', []), |
| 16 createItem('6', {url: 'link4'}), |
| 17 createItem('7', {url: 'link5'}), |
16 ]), | 18 ]), |
17 createItem('4', {url: 'link4'}), | 19 createItem('4', {url: 'link4'}), |
18 createItem('5', {url: 'link5'}), | 20 createItem('5', {url: 'link5'}), |
19 ]); | 21 ]); |
20 | 22 |
21 store = document.createElement('bookmarks-store'); | 23 store = document.createElement('bookmarks-store'); |
22 replaceBody(store); | 24 replaceBody(store); |
23 store.setupStore_(TEST_TREE); | 25 store.setupStore_(TEST_TREE); |
24 }); | 26 }); |
25 | 27 |
(...skipping 24 matching lines...) Expand all Loading... |
50 }); | 52 }); |
51 | 53 |
52 test('correct paths generated for nodes', function() { | 54 test('correct paths generated for nodes', function() { |
53 var TEST_PATHS = { | 55 var TEST_PATHS = { |
54 '0': 'rootNode', | 56 '0': 'rootNode', |
55 '1': 'rootNode.children.#0', | 57 '1': 'rootNode.children.#0', |
56 '2': 'rootNode.children.#0.children.#0', | 58 '2': 'rootNode.children.#0.children.#0', |
57 '3': 'rootNode.children.#0.children.#1', | 59 '3': 'rootNode.children.#0.children.#1', |
58 '4': 'rootNode.children.#1', | 60 '4': 'rootNode.children.#1', |
59 '5': 'rootNode.children.#2', | 61 '5': 'rootNode.children.#2', |
| 62 '6': 'rootNode.children.#0.children.#2', |
| 63 '7': 'rootNode.children.#0.children.#3', |
60 }; | 64 }; |
61 | 65 |
62 for (var id in store.idToNodeMap_) | 66 for (var id in store.idToNodeMap_) |
63 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | 67 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); |
64 }); | 68 }); |
65 | 69 |
66 test('store updates on selected event', function() { | 70 test('store updates on selected event', function() { |
67 // First child of root is selected by default. | 71 // First child of root is selected by default. |
68 assertEquals('1', store.selectedId); | 72 assertEquals('1', store.selectedId); |
69 assertTrue(store.idToNodeMap_['1'].isSelected); | 73 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); |
70 | 74 |
71 // Selecting a selected folder doesn't deselect it. | 75 // Selecting a selected folder doesn't deselect it. |
72 store.fire('selected-folder-changed', '1'); | 76 store.fire('selected-folder-changed', '1'); |
73 assertEquals('1', store.selectedId); | 77 assertEquals('1', store.selectedId); |
74 assertTrue(store.idToNodeMap_['1'].isSelected); | 78 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); |
75 | 79 |
76 // Select a deeply nested descendant. | 80 // Select a deeply nested descendant. |
77 store.fire('selected-folder-changed', '3'); | 81 store.fire('selected-folder-changed', '3'); |
78 assertEquals('3', store.selectedId); | 82 assertEquals('3', store.selectedId); |
79 assertTrue(store.idToNodeMap_['3'].isSelected); | 83 assertTrue(store.idToNodeMap_['3'].isSelectedFolder); |
80 assertFalse(store.idToNodeMap_['1'].isSelected); | 84 assertFalse(store.idToNodeMap_['1'].isSelectedFolder); |
81 | 85 |
82 // Select a folder in separate subtree. | 86 // Select a folder in separate subtree. |
83 store.fire('selected-folder-changed', '5'); | 87 store.fire('selected-folder-changed', '5'); |
84 assertEquals('5', store.selectedId); | 88 assertEquals('5', store.selectedId); |
85 assertTrue(store.idToNodeMap_['5'].isSelected); | 89 assertTrue(store.idToNodeMap_['5'].isSelectedFolder); |
86 assertFalse(store.idToNodeMap_['3'].isSelected); | 90 assertFalse(store.idToNodeMap_['3'].isSelectedFolder); |
87 }); | 91 }); |
88 | 92 |
89 test('store updates on open and close', function() { | 93 test('store updates on open and close', function() { |
90 // All folders are open by default. | 94 // All folders are open by default. |
91 for (var id in store.idToNodeMap_) { | 95 for (var id in store.idToNodeMap_) { |
92 if (store.idToNodeMap_[id].url) | 96 if (store.idToNodeMap_[id].url) |
93 continue; | 97 continue; |
94 | 98 |
95 assertTrue(store.idToNodeMap_[id].isOpen); | 99 assertTrue(store.idToNodeMap_[id].isOpen); |
96 } | 100 } |
97 | 101 |
98 // Closing a folder doesn't close any descendants. | 102 // Closing a folder doesn't close any descendants. |
99 store.fire('folder-open-changed', {id: '1', open: false}); | 103 store.fire('folder-open-changed', {id: '1', open: false}); |
100 assertFalse(store.idToNodeMap_['1'].isOpen); | 104 assertFalse(store.idToNodeMap_['1'].isOpen); |
101 assertTrue(store.idToNodeMap_['3'].isOpen); | 105 assertTrue(store.idToNodeMap_['3'].isOpen); |
102 store.fire('folder-open-changed', {id: '1', open: true}); | 106 store.fire('folder-open-changed', {id: '1', open: true}); |
103 | 107 |
104 // Closing an ancestor folder of a selected folder selects the ancestor. | 108 // Closing an ancestor folder of a selected folder selects the ancestor. |
105 store.fire('selected-folder-changed', '3'); | 109 store.fire('selected-folder-changed', '3'); |
106 store.fire('folder-open-changed', {id: '1', open: false}); | 110 store.fire('folder-open-changed', {id: '1', open: false}); |
107 assertFalse(store.idToNodeMap_['1'].isOpen); | 111 assertFalse(store.idToNodeMap_['1'].isOpen); |
108 assertEquals('1', store.selectedId); | 112 assertEquals('1', store.selectedId); |
109 assertTrue(store.idToNodeMap_['1'].isSelected); | 113 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); |
110 assertFalse(store.idToNodeMap_['3'].isSelected); | 114 assertFalse(store.idToNodeMap_['3'].isSelectedFolder); |
111 }); | 115 }); |
112 | 116 |
113 test('deleting a node updates the tree', function() { | 117 test('deleting a node updates the tree', function() { |
114 // Remove an empty folder/bookmark. | 118 // Remove an empty folder/bookmark. |
115 store.onBookmarkRemoved_('4', {parentId: '0', index: '1'}); | 119 store.onBookmarkRemoved_('4', {parentId: '0', index: '1'}); |
116 | 120 |
117 // Check the tree is correct. | 121 // Check the tree is correct. |
118 assertEquals('5', store.rootNode.children[1].id); | 122 assertEquals('5', store.rootNode.children[1].id); |
119 | 123 |
120 // idToNodeMap_ has been updated. | 124 // idToNodeMap_ has been updated. |
121 assertEquals(undefined, store.idToNodeMap_['4']); | 125 assertEquals(undefined, store.idToNodeMap_['4']); |
122 assertEquals(store.rootNode.children[1], store.idToNodeMap_['5']); | 126 assertEquals(store.rootNode.children[1], store.idToNodeMap_['5']); |
123 | 127 |
124 // Paths have been updated. | 128 // Paths have been updated. |
125 var TEST_PATHS = { | 129 var TEST_PATHS = { |
126 '0': 'rootNode', | 130 '0': 'rootNode', |
127 '1': 'rootNode.children.#0', | 131 '1': 'rootNode.children.#0', |
128 '2': 'rootNode.children.#0.children.#0', | 132 '2': 'rootNode.children.#0.children.#0', |
129 '3': 'rootNode.children.#0.children.#1', | 133 '3': 'rootNode.children.#0.children.#1', |
130 '5': 'rootNode.children.#1', | 134 '5': 'rootNode.children.#1', |
| 135 '6': 'rootNode.children.#0.children.#2', |
| 136 '7': 'rootNode.children.#0.children.#3', |
131 }; | 137 }; |
132 | 138 |
133 for (var id in store.idToNodeMap_) | 139 for (var id in store.idToNodeMap_) |
134 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | 140 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); |
135 | 141 |
136 // Remove a folder with children. | 142 // Remove a folder with children. |
137 store.onBookmarkRemoved_('1', {parentId: '0', index: '0'}); | 143 store.onBookmarkRemoved_('1', {parentId: '0', index: '0'}); |
138 | 144 |
139 // Check the tree is correct. | 145 // Check the tree is correct. |
140 assertEquals('5', store.rootNode.children[0].id); | 146 assertEquals('5', store.rootNode.children[0].id); |
(...skipping 12 matching lines...) Expand all Loading... |
153 }; | 159 }; |
154 | 160 |
155 for (var id in store.idToNodeMap_) | 161 for (var id in store.idToNodeMap_) |
156 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); | 162 assertEquals(TEST_PATHS[id], store.idToNodeMap_[id].path); |
157 }); | 163 }); |
158 | 164 |
159 test('selectedId updates after removing a selected folder', function() { | 165 test('selectedId updates after removing a selected folder', function() { |
160 // Selected folder gets removed. | 166 // Selected folder gets removed. |
161 store.selectedId = '2'; | 167 store.selectedId = '2'; |
162 store.onBookmarkRemoved_('2', {parentId:'1', index:'0'}); | 168 store.onBookmarkRemoved_('2', {parentId:'1', index:'0'}); |
163 assertTrue(store.idToNodeMap_['1'].isSelected); | 169 assertTrue(store.idToNodeMap_['1'].isSelectedFolder); |
164 assertEquals('1', store.selectedId); | 170 assertEquals('1', store.selectedId); |
165 | 171 |
166 // A folder with selected folder in it gets removed. | 172 // A folder with selected folder in it gets removed. |
167 store.selectedId = '3'; | 173 store.selectedId = '3'; |
168 store.onBookmarkRemoved_('1', {parentId:'0', index:'0'}); | 174 store.onBookmarkRemoved_('1', {parentId:'0', index:'0'}); |
169 assertTrue(store.idToNodeMap_['0'].isSelected); | 175 assertTrue(store.idToNodeMap_['0'].isSelectedFolder); |
170 assertEquals('0', store.selectedId); | 176 assertEquals('0', store.selectedId); |
171 }); | 177 }); |
172 | 178 |
173 test('displayedList updates after searchTerm changes', function() { | 179 test('displayedList updates after searchTerm changes', function() { |
174 var SEARCH_RESULTS = [ | 180 var SEARCH_RESULTS = TEST_TREE.children[0].children; |
175 'cat', | |
176 'apple', | |
177 'Paris', | |
178 ]; | |
179 | |
180 chrome.bookmarks.search = function(searchTerm, callback) { | 181 chrome.bookmarks.search = function(searchTerm, callback) { |
181 callback(SEARCH_RESULTS); | 182 callback(SEARCH_RESULTS); |
182 }; | 183 }; |
183 | 184 |
184 // Search for a non-empty string. | 185 // Search for a non-empty string. |
185 store.searchTerm = 'a'; | 186 store.searchTerm = 'a'; |
186 assertFalse(store.rootNode.children[0].isSelected); | 187 assertFalse(store.rootNode.children[0].isSelectedFolder); |
187 assertEquals(null, store.selectedId); | 188 assertEquals(null, store.selectedId); |
188 assertEquals(SEARCH_RESULTS, store.displayedList); | 189 for (var i = 0; i < SEARCH_RESULTS.length; i++) |
| 190 assertEquals(SEARCH_RESULTS[i], store.displayedList[i]); |
189 | 191 |
190 // Clear the searchTerm. | 192 // Clear the searchTerm. |
191 store.searchTerm = ''; | 193 store.searchTerm = ''; |
192 var defaultFolder = store.rootNode.children[0]; | 194 var defaultFolder = store.rootNode.children[0]; |
193 assertTrue(defaultFolder.isSelected); | 195 assertTrue(defaultFolder.isSelectedFolder); |
194 assertEquals(defaultFolder.id, store.selectedId); | 196 assertEquals(defaultFolder.id, store.selectedId); |
195 assertEquals(defaultFolder.children, store.displayedList); | 197 assertEquals(defaultFolder.children, store.displayedList); |
196 | 198 |
197 // Search with no bookmarks returned. | 199 // Search with no bookmarks returned. |
198 var EMPTY_RESULT = []; | |
199 chrome.bookmarks.search = function(searchTerm, callback) { | 200 chrome.bookmarks.search = function(searchTerm, callback) { |
200 callback(EMPTY_RESULT); | 201 callback([]); |
201 }; | 202 }; |
202 store.searchTerm = 'asdf'; | 203 store.searchTerm = 'asdf'; |
203 assertEquals(EMPTY_RESULT, store.displayedList); | 204 assertEquals(0, store.displayedList.length); |
| 205 }); |
| 206 |
| 207 test('path gets linked correctly after searchTerm changes', function() { |
| 208 var SEARCH_RESULTS = [ |
| 209 createItem('2', {url: 'link2'}), |
| 210 createItem('4', {url: 'link4'}), |
| 211 createItem('5', {url: 'link5'}), |
| 212 ]; |
| 213 chrome.bookmarks.search = function(searchTerm, callback) { |
| 214 callback(SEARCH_RESULTS); |
| 215 }; |
| 216 |
| 217 var TEST_PATHS = [ |
| 218 'rootNode.children.#0.children.#0', |
| 219 'rootNode.children.#1', |
| 220 'rootNode.children.#2', |
| 221 ]; |
| 222 store.searchTerm = 'a'; |
| 223 for(var i = 0; i < TEST_PATHS.length; i++) |
| 224 assertEquals(TEST_PATHS[i], store.displayedList[i].path); |
204 }); | 225 }); |
205 | 226 |
206 test('bookmark gets updated after editing', function() { | 227 test('bookmark gets updated after editing', function() { |
207 // Edit title updates idToNodeMap_ properly. | 228 // Edit title updates idToNodeMap_ properly. |
208 store.onBookmarkChanged_('4', {'title': 'test'}); | 229 store.onBookmarkChanged_('4', {'title': 'test'}); |
209 assertEquals('test', store.idToNodeMap_['4'].title); | 230 assertEquals('test', store.idToNodeMap_['4'].title); |
210 assertEquals('link4', store.idToNodeMap_['4'].url); | 231 assertEquals('link4', store.idToNodeMap_['4'].url); |
211 | 232 |
212 // Edit url updates idToNodeMap_ properly. | 233 // Edit url updates idToNodeMap_ properly. |
213 store.onBookmarkChanged_('5', {'url': 'http://www.google.com'}); | 234 store.onBookmarkChanged_('5', {'url': 'http://www.google.com'}); |
214 assertEquals('', store.idToNodeMap_['5'].title); | 235 assertEquals('', store.idToNodeMap_['5'].title); |
215 assertEquals('http://www.google.com', store.idToNodeMap_['5'].url); | 236 assertEquals('http://www.google.com', store.idToNodeMap_['5'].url); |
216 | 237 |
217 // Edit url and title updates idToNodeMap_ properly. | 238 // Edit url and title updates idToNodeMap_ properly. |
218 store.onBookmarkChanged_('2', { | 239 store.onBookmarkChanged_('2', { |
219 'title': 'test', | 240 'title': 'test', |
220 'url': 'http://www.google.com', | 241 'url': 'http://www.google.com', |
221 }); | 242 }); |
222 assertEquals('test', store.idToNodeMap_['2'].title); | 243 assertEquals('test', store.idToNodeMap_['2'].title); |
223 assertEquals('http://www.google.com', store.idToNodeMap_['2'].url); | 244 assertEquals('http://www.google.com', store.idToNodeMap_['2'].url); |
224 }); | 245 }); |
| 246 |
| 247 test('single select selects the correct bookmark', function() { |
| 248 for (var id in store.idToNodeMap_) { |
| 249 assertFalse(store.idToNodeMap_[id].isSelected); |
| 250 } |
| 251 |
| 252 store.fire('select-single-item', {item: TEST_TREE.children[0].children[0]}); |
| 253 assertTrue(store.idToNodeMap_['2'].isSelected); |
| 254 assertEquals(0, store.prevSelectedItemIndex_); |
| 255 |
| 256 // Select other item will remove the previous selection. |
| 257 store.fire('select-single-item', {item: TEST_TREE.children[0].children[1]}); |
| 258 assertFalse(store.idToNodeMap_['2'].isSelected); |
| 259 assertTrue(store.idToNodeMap_['3'].isSelected); |
| 260 assertEquals(1, store.prevSelectedItemIndex_); |
| 261 |
| 262 // Changing the selected folder will remove the select status of the |
| 263 // bookmark. |
| 264 store.selectedId = '3'; |
| 265 assertFalse(store.idToNodeMap_['2'].isSelected); |
| 266 assertEquals(undefined, store.prevSelectedItemIndex_); |
| 267 }); |
| 268 |
| 269 test('shift select selects the correct bookmarks', function() { |
| 270 // When nothing has been selected, it selects a single item. |
| 271 assertEquals(undefined, store.prevSelectedItemIndex_); |
| 272 store.fire( |
| 273 'shift-select-multiple-items', |
| 274 {item: TEST_TREE.children[0].children[2]}); |
| 275 assertTrue(store.idToNodeMap_['6'].isSelected); |
| 276 assertEquals(2, store.prevSelectedItemIndex_); |
| 277 |
| 278 // Select an item below the previous selected item. |
| 279 store.fire( |
| 280 'shift-select-multiple-items', |
| 281 {item: TEST_TREE.children[0].children[3]}); |
| 282 assertEquals(2, store.prevSelectedItemIndex_); |
| 283 assertTrue(store.idToNodeMap_['6'].isSelected); |
| 284 assertTrue(store.idToNodeMap_['7'].isSelected); |
| 285 |
| 286 // Select an item above the previous selected item. |
| 287 store.fire( |
| 288 'shift-select-multiple-items', |
| 289 {item: TEST_TREE.children[0].children[0]}); |
| 290 assertEquals(2, store.prevSelectedItemIndex_); |
| 291 assertTrue(store.idToNodeMap_['2'].isSelected); |
| 292 assertTrue(store.idToNodeMap_['3'].isSelected); |
| 293 assertTrue(store.idToNodeMap_['6'].isSelected); |
| 294 assertFalse(store.idToNodeMap_['7'].isSelected); |
| 295 }); |
| 296 |
| 297 test('ctrl select selects the correct bookmarks', function() { |
| 298 // When nothing has been selected, it selects a single item. |
| 299 assertEquals(undefined, store.prevSelectedItemIndex_); |
| 300 store.fire( |
| 301 'ctrl-select-multiple-items', |
| 302 {item: TEST_TREE.children[0].children[2]}); |
| 303 assertTrue(store.idToNodeMap_['6'].isSelected); |
| 304 assertEquals(2, store.prevSelectedItemIndex_); |
| 305 |
| 306 // Select a new item will not deselect the previous item, but will update |
| 307 // prevSelectedItemIndex_. |
| 308 store.fire( |
| 309 'ctrl-select-multiple-items', |
| 310 {item: TEST_TREE.children[0].children[0]}); |
| 311 assertTrue(store.idToNodeMap_['2'].isSelected); |
| 312 assertFalse(store.idToNodeMap_['3'].isSelected); |
| 313 assertTrue(store.idToNodeMap_['6'].isSelected); |
| 314 assertEquals(0, store.prevSelectedItemIndex_); |
| 315 }); |
| 316 |
| 317 test('selection in search mode', function() { |
| 318 // Item gets unselected in search. |
| 319 var SEARCH_RESULTS = [ |
| 320 createItem('4', {url: 'link4'}), |
| 321 createItem('2', {url: 'link2'}), |
| 322 createItem('5', {url: 'link5'}), |
| 323 ]; |
| 324 chrome.bookmarks.search = function(searchTerm, callback) { |
| 325 callback(SEARCH_RESULTS); |
| 326 }; |
| 327 |
| 328 store.selectedId = '1'; |
| 329 store.fire('select-single-item', {item: TEST_TREE.children[0].children[1]}); |
| 330 store.searchTerm = 'a'; |
| 331 assertFalse(store.idToNodeMap_['3'].isSelected); |
| 332 assertEquals(undefined, store.prevSelectedItemIndex_); |
| 333 |
| 334 // prevSelectedItemIndex_ gets updated properly in single select. |
| 335 store.fire('select-single-item', {item: TEST_TREE.children[0].children[0]}); |
| 336 assertTrue(store.idToNodeMap_['2'].isSelected); |
| 337 assertEquals(1, store.prevSelectedItemIndex_); |
| 338 |
| 339 // prevSelectedItemIndex_ gets updated properly in ctrl select. |
| 340 store.fire('ctrl-select-multiple-items', {item: TEST_TREE.children[1]}); |
| 341 assertTrue(store.idToNodeMap_['2'].isSelected); |
| 342 assertTrue(store.idToNodeMap_['4'].isSelected); |
| 343 assertEquals(0, store.prevSelectedItemIndex_); |
| 344 }); |
225 }); | 345 }); |
OLD | NEW |