1 // Copyright (c) 2012 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.
5 // Bookmark Manager API test for Chrome.
6 // browser_tests.exe --gtest_filter=ExtensionApiTest.BookmarkManager
8 const pass = chrome.test.callbackPass;
9 const fail = chrome.test.callbackFail;
10 const assertEq = chrome.test.assertEq;
11 const assertTrue = chrome.test.assertTrue;
12 const assertFalse = chrome.test.assertFalse;
13 const bookmarks = chrome.bookmarks;
14 const bookmarkManager = chrome.bookmarkManagerPrivate;
15 var fooNode, fooNode2, barNode, gooNode, count, emptyFolder, emptyFolder2;
16 var folder, nodeA, nodeB;
17 var childFolder, grandChildFolder, childNodeA, childNodeB;
19 var clipboardArguments;
21 clipboardArguments = arguments;
22 document.execCommand('copy');
25 clipboardArguments = arguments;
26 document.execCommand('cut');
29 clipboardArguments = arguments;
30 document.execCommand('paste');
32 document.addEventListener('copy', function (event) {
33 bookmarkManager.copy.apply(null, clipboardArguments);
34 event.preventDefault();
36 document.addEventListener('cut', function (event) {
37 bookmarkManager.cut.apply(null, clipboardArguments);
38 event.preventDefault();
40 document.addEventListener('paste', function (event) {
41 bookmarkManager.paste.apply(null, clipboardArguments);
42 event.preventDefault();
46 function getStrings() {
47 bookmarkManager.getStrings(pass(function(strings) {
48 assertEq('string', typeof strings['title']);
49 assertEq('string', typeof strings['search_button']);
53 function sortChildren() {
60 url: 'http://www.example.com/a'
64 url: 'http://www.example.com/b'
66 bookmarks.create(folder, pass(function(result) {
67 folder.id = result.id;
68 nodeA.parentId = folder.id;
69 nodeB.parentId = folder.id;
71 bookmarks.create(nodeB, pass(function(result) {
74 bookmarks.create(nodeA, pass(function(result) {
80 function sortChildren2() {
81 bookmarkManager.sortChildren(folder.id);
83 bookmarks.getChildren(folder.id, pass(function(children) {
84 assertEq(nodeA.id, children[0].id);
85 assertEq(nodeB.id, children[1].id);
89 function setupSubtree() {
96 url: 'http://www.example.com/childNodeA'
100 url: 'http://www.example.com/childNodeB'
103 title: 'grandChildFolder'
105 bookmarks.create(childFolder, pass(function(result) {
106 childFolder.id = result.id;
107 childNodeA.parentId = childFolder.id;
108 childNodeB.parentId = childFolder.id;
109 grandChildFolder.parentId = childFolder.id;
111 bookmarks.create(childNodeA, pass(function(result) {
112 childNodeA.id = result.id;
114 bookmarks.create(childNodeB, pass(function(result) {
115 childNodeB.id = result.id;
117 bookmarks.create(grandChildFolder, pass(function(result) {
118 grandChildFolder.id = result.id;
123 function getSubtree() {
124 bookmarkManager.getSubtree(childFolder.id, false, pass(function(result) {
125 var children = result[0].children;
126 assertEq(3, children.length);
127 assertEq(childNodeA.id, children[0].id);
128 assertEq(childNodeB.id, children[1].id);
129 assertEq(grandChildFolder.id, children[2].id);
133 function getSubtreeFoldersOnly() {
134 bookmarkManager.getSubtree(childFolder.id, true, pass(function(result) {
135 var children = result[0].children;
136 assertEq(1, children.length);
137 assertEq(grandChildFolder.id, children[0].id);
141 // The clipboard test is split into different parts to allow asynchronous
142 // operations to finish.
143 function clipboard() {
144 // Create a new bookmark.
148 url: 'http://www.example.com/foo'
153 title: 'Empty Folder'
156 bookmarks.create(fooNode, pass(function(result) {
157 fooNode.id = result.id;
158 fooNode.index = result.index;
159 count = result.index + 1;
162 bookmarks.create(emptyFolder, pass(function(result) {
163 emptyFolder.id = result.id;
164 emptyFolder.index = result.index;
165 count = result.index + 1;
168 // Create a couple more bookmarks to test proper insertion of pasted items.
172 url: 'http://www.example.com/bar'
175 bookmarks.create(barNode, pass(function(result) {
176 barNode.id = result.id;
177 barNode.index = result.index;
178 count = result.index + 1;
184 url: 'http://www.example.com/goo'
187 bookmarks.create(gooNode, pass(function(result) {
188 gooNode.id = result.id;
189 gooNode.index = result.index;
190 count = result.index + 1;
194 function clipboard2() {
196 doCopy([fooNode.id]);
198 // Ensure canPaste is now true.
199 bookmarkManager.canPaste('1', pass(function(result) {
200 assertTrue(result, 'Should be able to paste now');
206 // Ensure it got added at the end.
207 bookmarks.getChildren('1', pass(function(result) {
209 assertEq(count, result.length);
211 fooNode2 = result[result.length - 1];
213 assertEq(fooNode.title + " (1)", fooNode2.title);
214 assertEq(fooNode.url, fooNode2.url);
215 assertEq(fooNode.parentId, fooNode2.parentId);
219 function clipboard3() {
220 // Cut fooNode bookmarks.
221 doCut([fooNode.id, fooNode2.id]);
223 // Ensure count decreased by 2.
224 bookmarks.getChildren('1', pass(function(result) {
226 assertEq(count, result.length);
229 // Ensure canPaste is still true.
230 bookmarkManager.canPaste('1', pass(function(result) {
231 assertTrue(result, 'Should be able to paste now');
235 function clipboard4() {
236 // Paste the cut bookmarks at a specific position between bar and goo.
237 doPaste('1', [barNode.id]);
239 // Check that the two bookmarks were pasted after bar.
240 bookmarks.getChildren('1', pass(function(result) {
242 assertEq(count, result.length);
244 // Look for barNode's index.
245 for (var barIndex = 0; barIndex < result.length; barIndex++) {
246 if (result[barIndex].id == barNode.id)
249 assertTrue(barIndex + 2 < result.length);
251 var last = result[barIndex + 1];
252 var last2 = result[barIndex + 2];
253 assertEq(fooNode.title, last.title);
254 assertEq(fooNode.url, last.url);
255 assertEq(fooNode.parentId, last.parentId);
256 assertEq(last.title + " (1)", last2.title);
257 assertEq(last.url, last2.url);
258 assertEq(last.parentId, last2.parentId);
260 // Remember last2 id, so we can use it in next test.
261 fooNode2.id = last2.id;
265 // Ensure we can copy empty folders
266 function clipboard5() {
268 doCopy([emptyFolder.id]);
270 // Ensure canPaste is now true.
271 bookmarkManager.canPaste('1', pass(function(result) {
272 assertTrue(result, 'Should be able to paste now');
275 // Paste it at the end of a multiple selection.
276 doPaste('1', [barNode.id, fooNode2.id]);
278 // Ensure it got added at the right place.
279 bookmarks.getChildren('1', pass(function(result) {
281 assertEq(count, result.length);
283 // Look for fooNode2's index.
284 for (var foo2Index = 0; foo2Index < result.length; foo2Index++) {
285 if (result[foo2Index].id == fooNode2.id)
288 assertTrue(foo2Index + 1 < result.length);
290 emptyFolder2 = result[foo2Index + 1];
292 assertEq(emptyFolder2.title, emptyFolder.title);
293 assertEq(emptyFolder2.url, emptyFolder.url);
294 assertEq(emptyFolder2.parentId, emptyFolder.parentId);
298 function clipboard6() {
299 // Verify that we can't cut managed folders.
300 bookmarks.getChildren('4', pass(function(result) {
301 assertEq(2, result.length);
302 const error = "Can't modify managed bookmarks.";
303 bookmarkManager.cut([ result[0].id ], fail(error));
306 bookmarkManager.copy([ result[0].id ], pass());
308 // Pasting to a managed folder is not allowed.
309 assertTrue(result[1].url === undefined);
310 bookmarkManager.canPaste(result[1].id, pass(function(result) {
311 assertFalse(result, 'Should not be able to paste to managed folders.');
314 bookmarkManager.paste(result[1].id, fail(error));
319 bookmarkManager.canEdit(pass(function(result) {
320 assertTrue(result, 'Should be able to edit bookmarks');
324 function getSetMetaInfo() {
325 bookmarkManager.getMetaInfo(nodeA.id, 'meta', pass(function(result) {
328 chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass(
329 function(id, changes) {
330 assertEq(nodeA.id, id);
331 assertEq({meta: 'bla'}, changes);
333 bookmarkManager.setMetaInfo(nodeA.id, 'meta', 'bla');
334 bookmarkManager.setMetaInfo(nodeA.id, 'meta2', 'foo');
335 bookmarkManager.getMetaInfo(nodeA.id, 'meta', pass(function(result) {
336 assertEq('bla', result);
339 bookmarkManager.getMetaInfo(nodeA.id, pass(function(result) {
340 assertEq({meta: 'bla', meta2: 'foo'}, result);
344 function setMetaInfoPermanent() {
345 bookmarks.getTree(pass(function(nodes) {
346 var unmodifiableFolder = nodes[0].children[0];
347 bookmarkManager.setMetaInfo(unmodifiableFolder.id, 'meta', 'foo', fail(
348 "Can't modify the root bookmark folders."));
349 bookmarkManager.updateMetaInfo(unmodifiableFolder.id, {a: 'a', b: 'b'},
350 fail("Can't modify the root bookmark folders."));
354 function setMetaInfoManaged() {
355 bookmarks.getChildren('4', pass(function(result) {
356 assertTrue(result.length > 0);
357 bookmarkManager.setMetaInfo(result[0].id, 'meta', 'foo', fail(
358 "Can't modify managed bookmarks."));
359 bookmarkManager.updateMetaInfo(result[0].id, {a: 'a', b: 'b'},
360 fail("Can't modify managed bookmarks."));
364 function updateMetaInfo() {
365 bookmarkManager.getMetaInfo(nodeB.id, pass(function(result){
366 assertEq({}, result);
369 chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass(
370 function(id, changes) {
371 assertEq(nodeB.id, id);
372 assertEq({a: 'a', b: 'b', c: 'c'}, changes);
374 bookmarkManager.updateMetaInfo(nodeB.id, {a: 'a', b: 'b', c: 'c'}, pass(
376 chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass(
377 function(id, changes) {
378 assertEq(nodeB.id, id);
379 assertEq({a: 'aa', d: 'd'}, changes);
381 bookmarkManager.updateMetaInfo(nodeB.id, {a: 'aa', b: 'b', d: 'd'});
382 bookmarkManager.getMetaInfo(nodeB.id, pass(function(result) {
383 assertEq({a: 'aa', b: 'b', c: 'c', d: 'd'}, result);
388 function createWithMetaInfo() {
389 var node = {title: 'title', url: 'http://www.google.com/'};
390 var metaInfo = {a: 'a', b: 'b'};
391 chrome.test.listenOnce(bookmarks.onCreated, pass(function(id, created) {
392 assertEq(node.title, created.title);
393 assertEq(node.url, created.url);
394 bookmarkManager.getMetaInfo(id, pass(function(result) {
395 assertEq(metaInfo, result);
398 bookmarkManager.createWithMetaInfo(node, metaInfo, pass(
399 function(createdNode) {
400 assertEq(node.title, createdNode.title);
401 assertEq(node.url, createdNode.url);
406 chrome.test.runTests(tests);