1 // Copyright 2014 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 #include "components/bookmarks/browser/bookmark_utils.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
12 #include "components/bookmarks/browser/bookmark_model.h"
13 #include "components/bookmarks/browser/bookmark_node_data.h"
14 #include "components/bookmarks/test/test_bookmark_client.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/base/clipboard/clipboard.h"
17 #include "ui/base/clipboard/scoped_clipboard_writer.h"
19 using base::ASCIIToUTF16
;
25 class BookmarkUtilsTest
: public testing::Test
,
26 public BaseBookmarkModelObserver
{
29 : grouped_changes_beginning_count_(0),
30 grouped_changes_ended_count_(0) {}
31 ~BookmarkUtilsTest() override
{}
33 // Copy and paste is not yet supported on iOS. http://crbug.com/228147
35 void TearDown() override
{
36 ui::Clipboard::DestroyClipboardForCurrentThread();
38 #endif // !defined(OS_IOS)
40 // Certain user actions require multiple changes to the bookmark model,
41 // however these modifications need to be atomic for the undo framework. The
42 // BaseBookmarkModelObserver is used to inform the boundaries of the user
43 // action. For example, when multiple bookmarks are cut to the clipboard we
44 // expect one call each to GroupedBookmarkChangesBeginning/Ended.
45 void ExpectGroupedChangeCount(int expected_beginning_count
,
46 int expected_ended_count
) {
47 // The undo framework is not used under Android. Thus the group change
48 // events will not be fired and so should not be tested for Android.
49 #if !defined(OS_ANDROID)
50 EXPECT_EQ(grouped_changes_beginning_count_
, expected_beginning_count
);
51 EXPECT_EQ(grouped_changes_ended_count_
, expected_ended_count
);
56 // BaseBookmarkModelObserver:
57 void BookmarkModelChanged() override
{}
59 void GroupedBookmarkChangesBeginning(BookmarkModel
* model
) override
{
60 ++grouped_changes_beginning_count_
;
63 void GroupedBookmarkChangesEnded(BookmarkModel
* model
) override
{
64 ++grouped_changes_ended_count_
;
67 int grouped_changes_beginning_count_
;
68 int grouped_changes_ended_count_
;
70 // Clipboard requires a message loop.
71 base::MessageLoopForUI loop_
;
73 DISALLOW_COPY_AND_ASSIGN(BookmarkUtilsTest
);
76 TEST_F(BookmarkUtilsTest
, GetBookmarksMatchingPropertiesWordPhraseQuery
) {
77 TestBookmarkClient client
;
78 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
79 const BookmarkNode
* node1
= model
->AddURL(model
->other_node(),
81 ASCIIToUTF16("foo bar"),
82 GURL("http://www.google.com"));
83 const BookmarkNode
* node2
= model
->AddURL(model
->other_node(),
85 ASCIIToUTF16("baz buz"),
86 GURL("http://www.cnn.com"));
87 const BookmarkNode
* folder1
=
88 model
->AddFolder(model
->other_node(), 0, ASCIIToUTF16("foo"));
89 std::vector
<const BookmarkNode
*> nodes
;
91 query
.word_phrase_query
.reset(new base::string16
);
92 // No nodes are returned for empty string.
93 *query
.word_phrase_query
= ASCIIToUTF16("");
94 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
95 EXPECT_TRUE(nodes
.empty());
98 // No nodes are returned for space-only string.
99 *query
.word_phrase_query
= ASCIIToUTF16(" ");
100 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
101 EXPECT_TRUE(nodes
.empty());
104 // Node "foo bar" and folder "foo" are returned in search results.
105 *query
.word_phrase_query
= ASCIIToUTF16("foo");
106 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
107 ASSERT_EQ(2U, nodes
.size());
108 EXPECT_TRUE(nodes
[0] == folder1
);
109 EXPECT_TRUE(nodes
[1] == node1
);
112 // Ensure url matches return in search results.
113 *query
.word_phrase_query
= ASCIIToUTF16("cnn");
114 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
115 ASSERT_EQ(1U, nodes
.size());
116 EXPECT_TRUE(nodes
[0] == node2
);
119 // Ensure folder "foo" is not returned in more specific search.
120 *query
.word_phrase_query
= ASCIIToUTF16("foo bar");
121 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
122 ASSERT_EQ(1U, nodes
.size());
123 EXPECT_TRUE(nodes
[0] == node1
);
126 // Bookmark Bar and Other Bookmarks are not returned in search results.
127 *query
.word_phrase_query
= ASCIIToUTF16("Bookmark");
128 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
129 ASSERT_EQ(0U, nodes
.size());
133 // Check exact matching against a URL query.
134 TEST_F(BookmarkUtilsTest
, GetBookmarksMatchingPropertiesUrl
) {
135 TestBookmarkClient client
;
136 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
137 const BookmarkNode
* node1
= model
->AddURL(model
->other_node(),
139 ASCIIToUTF16("Google"),
140 GURL("https://www.google.com/"));
141 model
->AddURL(model
->other_node(),
143 ASCIIToUTF16("Google Calendar"),
144 GURL("https://www.google.com/calendar"));
146 model
->AddFolder(model
->other_node(), 0, ASCIIToUTF16("Folder"));
148 std::vector
<const BookmarkNode
*> nodes
;
150 query
.url
.reset(new base::string16
);
151 *query
.url
= ASCIIToUTF16("https://www.google.com/");
152 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
153 ASSERT_EQ(1U, nodes
.size());
154 EXPECT_TRUE(nodes
[0] == node1
);
157 *query
.url
= ASCIIToUTF16("calendar");
158 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
159 ASSERT_EQ(0U, nodes
.size());
162 // Empty URL should not match folders.
163 *query
.url
= ASCIIToUTF16("");
164 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
165 ASSERT_EQ(0U, nodes
.size());
169 // Check exact matching against a title query.
170 TEST_F(BookmarkUtilsTest
, GetBookmarksMatchingPropertiesTitle
) {
171 TestBookmarkClient client
;
172 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
173 const BookmarkNode
* node1
= model
->AddURL(model
->other_node(),
175 ASCIIToUTF16("Google"),
176 GURL("https://www.google.com/"));
177 model
->AddURL(model
->other_node(),
179 ASCIIToUTF16("Google Calendar"),
180 GURL("https://www.google.com/calendar"));
182 const BookmarkNode
* folder1
=
183 model
->AddFolder(model
->other_node(), 0, ASCIIToUTF16("Folder"));
185 std::vector
<const BookmarkNode
*> nodes
;
187 query
.title
.reset(new base::string16
);
188 *query
.title
= ASCIIToUTF16("Google");
189 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
190 ASSERT_EQ(1U, nodes
.size());
191 EXPECT_TRUE(nodes
[0] == node1
);
194 *query
.title
= ASCIIToUTF16("Calendar");
195 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
196 ASSERT_EQ(0U, nodes
.size());
199 // Title should match folders.
200 *query
.title
= ASCIIToUTF16("Folder");
201 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
202 ASSERT_EQ(1U, nodes
.size());
203 EXPECT_TRUE(nodes
[0] == folder1
);
207 // Check matching against a query with multiple predicates.
208 TEST_F(BookmarkUtilsTest
, GetBookmarksMatchingPropertiesConjunction
) {
209 TestBookmarkClient client
;
210 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
211 const BookmarkNode
* node1
= model
->AddURL(model
->other_node(),
213 ASCIIToUTF16("Google"),
214 GURL("https://www.google.com/"));
215 model
->AddURL(model
->other_node(),
217 ASCIIToUTF16("Google Calendar"),
218 GURL("https://www.google.com/calendar"));
220 model
->AddFolder(model
->other_node(), 0, ASCIIToUTF16("Folder"));
222 std::vector
<const BookmarkNode
*> nodes
;
225 // Test all fields matching.
226 query
.word_phrase_query
.reset(new base::string16(ASCIIToUTF16("www")));
227 query
.url
.reset(new base::string16(ASCIIToUTF16("https://www.google.com/")));
228 query
.title
.reset(new base::string16(ASCIIToUTF16("Google")));
229 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
230 ASSERT_EQ(1U, nodes
.size());
231 EXPECT_TRUE(nodes
[0] == node1
);
234 scoped_ptr
<base::string16
>* fields
[] = {
235 &query
.word_phrase_query
, &query
.url
, &query
.title
};
237 // Test two fields matching.
238 for (size_t i
= 0; i
< arraysize(fields
); i
++) {
239 scoped_ptr
<base::string16
> original_value(fields
[i
]->release());
240 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
241 ASSERT_EQ(1U, nodes
.size());
242 EXPECT_TRUE(nodes
[0] == node1
);
244 fields
[i
]->reset(original_value
.release());
247 // Test two fields matching with one non-matching field.
248 for (size_t i
= 0; i
< arraysize(fields
); i
++) {
249 scoped_ptr
<base::string16
> original_value(fields
[i
]->release());
250 fields
[i
]->reset(new base::string16(ASCIIToUTF16("fjdkslafjkldsa")));
251 GetBookmarksMatchingProperties(model
.get(), query
, 100, string(), &nodes
);
252 ASSERT_EQ(0U, nodes
.size());
254 fields
[i
]->reset(original_value
.release());
258 // Copy and paste is not yet supported on iOS. http://crbug.com/228147
260 TEST_F(BookmarkUtilsTest
, PasteBookmarkFromURL
) {
261 TestBookmarkClient client
;
262 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
263 const base::string16 url_text
= ASCIIToUTF16("http://www.google.com/");
264 const BookmarkNode
* new_folder
= model
->AddFolder(
265 model
->bookmark_bar_node(), 0, ASCIIToUTF16("New_Folder"));
267 // Write blank text to clipboard.
269 ui::ScopedClipboardWriter
clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE
);
270 clipboard_writer
.WriteText(base::string16());
272 // Now we shouldn't be able to paste from the clipboard.
273 EXPECT_FALSE(CanPasteFromClipboard(model
.get(), new_folder
));
275 // Write some valid url to the clipboard.
277 ui::ScopedClipboardWriter
clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE
);
278 clipboard_writer
.WriteText(url_text
);
280 // Now we should be able to paste from the clipboard.
281 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), new_folder
));
283 PasteFromClipboard(model
.get(), new_folder
, 0);
284 ASSERT_EQ(1, new_folder
->child_count());
286 // Url for added node should be same as url_text.
287 EXPECT_EQ(url_text
, ASCIIToUTF16(new_folder
->GetChild(0)->url().spec()));
290 TEST_F(BookmarkUtilsTest
, CopyPaste
) {
291 TestBookmarkClient client
;
292 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
293 const BookmarkNode
* node
= model
->AddURL(model
->other_node(),
295 ASCIIToUTF16("foo bar"),
296 GURL("http://www.google.com"));
298 // Copy a node to the clipboard.
299 std::vector
<const BookmarkNode
*> nodes
;
300 nodes
.push_back(node
);
301 CopyToClipboard(model
.get(), nodes
, false);
303 // And make sure we can paste a bookmark from the clipboard.
304 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), model
->bookmark_bar_node()));
306 // Write some text to the clipboard.
308 ui::ScopedClipboardWriter
clipboard_writer(
309 ui::CLIPBOARD_TYPE_COPY_PASTE
);
310 clipboard_writer
.WriteText(ASCIIToUTF16("foo"));
313 // Now we shouldn't be able to paste from the clipboard.
314 EXPECT_FALSE(CanPasteFromClipboard(model
.get(), model
->bookmark_bar_node()));
317 // Test for updating title such that url and title pair are unique among the
318 // children of parent.
319 TEST_F(BookmarkUtilsTest
, MakeTitleUnique
) {
320 TestBookmarkClient client
;
321 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
322 const base::string16 url_text
= ASCIIToUTF16("http://www.google.com/");
323 const base::string16 title_text
= ASCIIToUTF16("foobar");
324 const BookmarkNode
* bookmark_bar_node
= model
->bookmark_bar_node();
326 const BookmarkNode
* node
=
327 model
->AddURL(bookmark_bar_node
, 0, title_text
, GURL(url_text
));
330 ASCIIToUTF16(bookmark_bar_node
->GetChild(0)->url().spec()));
331 EXPECT_EQ(title_text
, bookmark_bar_node
->GetChild(0)->GetTitle());
333 // Copy a node to the clipboard.
334 std::vector
<const BookmarkNode
*> nodes
;
335 nodes
.push_back(node
);
336 CopyToClipboard(model
.get(), nodes
, false);
338 // Now we should be able to paste from the clipboard.
339 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), bookmark_bar_node
));
341 PasteFromClipboard(model
.get(), bookmark_bar_node
, 1);
342 ASSERT_EQ(2, bookmark_bar_node
->child_count());
344 // Url for added node should be same as url_text.
346 ASCIIToUTF16(bookmark_bar_node
->GetChild(1)->url().spec()));
347 // Title for added node should be numeric subscript suffix with copied node
349 EXPECT_EQ(ASCIIToUTF16("foobar (1)"),
350 bookmark_bar_node
->GetChild(1)->GetTitle());
353 TEST_F(BookmarkUtilsTest
, CopyPasteMetaInfo
) {
354 TestBookmarkClient client
;
355 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
356 const BookmarkNode
* node
= model
->AddURL(model
->other_node(),
358 ASCIIToUTF16("foo bar"),
359 GURL("http://www.google.com"));
360 model
->SetNodeMetaInfo(node
, "somekey", "somevalue");
361 model
->SetNodeMetaInfo(node
, "someotherkey", "someothervalue");
363 // Copy a node to the clipboard.
364 std::vector
<const BookmarkNode
*> nodes
;
365 nodes
.push_back(node
);
366 CopyToClipboard(model
.get(), nodes
, false);
368 // Paste node to a different folder.
369 const BookmarkNode
* folder
=
370 model
->AddFolder(model
->bookmark_bar_node(), 0, ASCIIToUTF16("Folder"));
371 EXPECT_EQ(0, folder
->child_count());
373 // And make sure we can paste a bookmark from the clipboard.
374 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), folder
));
376 PasteFromClipboard(model
.get(), folder
, 0);
377 ASSERT_EQ(1, folder
->child_count());
379 // Verify that the pasted node contains the same meta info.
380 const BookmarkNode
* pasted
= folder
->GetChild(0);
381 ASSERT_TRUE(pasted
->GetMetaInfoMap());
382 EXPECT_EQ(2u, pasted
->GetMetaInfoMap()->size());
384 EXPECT_TRUE(pasted
->GetMetaInfo("somekey", &value
));
385 EXPECT_EQ("somevalue", value
);
386 EXPECT_TRUE(pasted
->GetMetaInfo("someotherkey", &value
));
387 EXPECT_EQ("someothervalue", value
);
390 #if defined(OS_LINUX) || defined(OS_MACOSX)
391 // http://crbug.com/396472
392 #define MAYBE_CutToClipboard DISABLED_CutToClipboard
394 #define MAYBE_CutToClipboard CutToClipboard
396 TEST_F(BookmarkUtilsTest
, MAYBE_CutToClipboard
) {
397 TestBookmarkClient client
;
398 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
399 model
->AddObserver(this);
401 base::string16
title(ASCIIToUTF16("foo"));
402 GURL
url("http://foo.com");
403 const BookmarkNode
* n1
= model
->AddURL(model
->other_node(), 0, title
, url
);
404 const BookmarkNode
* n2
= model
->AddURL(model
->other_node(), 1, title
, url
);
406 // Cut the nodes to the clipboard.
407 std::vector
<const BookmarkNode
*> nodes
;
410 CopyToClipboard(model
.get(), nodes
, true);
412 // Make sure the nodes were removed.
413 EXPECT_EQ(0, model
->other_node()->child_count());
415 // Make sure observers were notified the set of changes should be grouped.
416 ExpectGroupedChangeCount(1, 1);
418 // And make sure we can paste from the clipboard.
419 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), model
->other_node()));
422 TEST_F(BookmarkUtilsTest
, PasteNonEditableNodes
) {
423 TestBookmarkClient client
;
424 // Load a model with an extra node that is not editable.
425 BookmarkPermanentNode
* extra_node
= new BookmarkPermanentNode(100);
426 BookmarkPermanentNodeList extra_nodes
;
427 extra_nodes
.push_back(extra_node
);
428 client
.SetExtraNodesToLoad(extra_nodes
.Pass());
430 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
431 const BookmarkNode
* node
= model
->AddURL(model
->other_node(),
433 ASCIIToUTF16("foo bar"),
434 GURL("http://www.google.com"));
436 // Copy a node to the clipboard.
437 std::vector
<const BookmarkNode
*> nodes
;
438 nodes
.push_back(node
);
439 CopyToClipboard(model
.get(), nodes
, false);
441 // And make sure we can paste a bookmark from the clipboard.
442 EXPECT_TRUE(CanPasteFromClipboard(model
.get(), model
->bookmark_bar_node()));
444 // But it can't be pasted into a non-editable folder.
445 BookmarkClient
* upcast
= &client
;
446 EXPECT_FALSE(upcast
->CanBeEditedByUser(extra_node
));
447 EXPECT_FALSE(CanPasteFromClipboard(model
.get(), extra_node
));
449 #endif // !defined(OS_IOS)
451 TEST_F(BookmarkUtilsTest
, GetParentForNewNodes
) {
452 TestBookmarkClient client
;
453 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
454 // This tests the case where selection contains one item and that item is a
456 std::vector
<const BookmarkNode
*> nodes
;
457 nodes
.push_back(model
->bookmark_bar_node());
459 const BookmarkNode
* real_parent
=
460 GetParentForNewNodes(model
->bookmark_bar_node(), nodes
, &index
);
461 EXPECT_EQ(real_parent
, model
->bookmark_bar_node());
466 // This tests the case where selection contains one item and that item is an
468 const BookmarkNode
* page1
= model
->AddURL(model
->bookmark_bar_node(),
470 ASCIIToUTF16("Google"),
471 GURL("http://google.com"));
472 nodes
.push_back(page1
);
473 real_parent
= GetParentForNewNodes(model
->bookmark_bar_node(), nodes
, &index
);
474 EXPECT_EQ(real_parent
, model
->bookmark_bar_node());
477 // This tests the case where selection has more than one item.
478 const BookmarkNode
* folder1
=
479 model
->AddFolder(model
->bookmark_bar_node(), 1, ASCIIToUTF16("Folder 1"));
480 nodes
.push_back(folder1
);
481 real_parent
= GetParentForNewNodes(model
->bookmark_bar_node(), nodes
, &index
);
482 EXPECT_EQ(real_parent
, model
->bookmark_bar_node());
485 // This tests the case where selection doesn't contain any items.
487 real_parent
= GetParentForNewNodes(model
->bookmark_bar_node(), nodes
, &index
);
488 EXPECT_EQ(real_parent
, model
->bookmark_bar_node());
492 // Verifies that meta info is copied when nodes are cloned.
493 TEST_F(BookmarkUtilsTest
, CloneMetaInfo
) {
494 TestBookmarkClient client
;
495 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
496 // Add a node containing meta info.
497 const BookmarkNode
* node
= model
->AddURL(model
->other_node(),
499 ASCIIToUTF16("foo bar"),
500 GURL("http://www.google.com"));
501 model
->SetNodeMetaInfo(node
, "somekey", "somevalue");
502 model
->SetNodeMetaInfo(node
, "someotherkey", "someothervalue");
504 // Clone node to a different folder.
505 const BookmarkNode
* folder
=
506 model
->AddFolder(model
->bookmark_bar_node(), 0, ASCIIToUTF16("Folder"));
507 std::vector
<BookmarkNodeData::Element
> elements
;
508 BookmarkNodeData::Element
node_data(node
);
509 elements
.push_back(node_data
);
510 EXPECT_EQ(0, folder
->child_count());
511 CloneBookmarkNode(model
.get(), elements
, folder
, 0, false);
512 ASSERT_EQ(1, folder
->child_count());
514 // Verify that the cloned node contains the same meta info.
515 const BookmarkNode
* clone
= folder
->GetChild(0);
516 ASSERT_TRUE(clone
->GetMetaInfoMap());
517 EXPECT_EQ(2u, clone
->GetMetaInfoMap()->size());
519 EXPECT_TRUE(clone
->GetMetaInfo("somekey", &value
));
520 EXPECT_EQ("somevalue", value
);
521 EXPECT_TRUE(clone
->GetMetaInfo("someotherkey", &value
));
522 EXPECT_EQ("someothervalue", value
);
525 // Verifies that meta info fields in the non cloned set are not copied when
526 // cloning a bookmark.
527 TEST_F(BookmarkUtilsTest
, CloneBookmarkResetsNonClonedKey
) {
528 TestBookmarkClient client
;
529 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
530 model
->AddNonClonedKey("foo");
531 const BookmarkNode
* parent
= model
->other_node();
532 const BookmarkNode
* node
= model
->AddURL(
533 parent
, 0, ASCIIToUTF16("title"), GURL("http://www.google.com"));
534 model
->SetNodeMetaInfo(node
, "foo", "ignored value");
535 model
->SetNodeMetaInfo(node
, "bar", "kept value");
536 std::vector
<BookmarkNodeData::Element
> elements
;
537 BookmarkNodeData::Element
node_data(node
);
538 elements
.push_back(node_data
);
540 // Cloning a bookmark should clear the non cloned key.
541 CloneBookmarkNode(model
.get(), elements
, parent
, 0, true);
542 ASSERT_EQ(2, parent
->child_count());
544 EXPECT_FALSE(parent
->GetChild(0)->GetMetaInfo("foo", &value
));
546 // Other keys should still be cloned.
547 EXPECT_TRUE(parent
->GetChild(0)->GetMetaInfo("bar", &value
));
548 EXPECT_EQ("kept value", value
);
551 // Verifies that meta info fields in the non cloned set are not copied when
553 TEST_F(BookmarkUtilsTest
, CloneFolderResetsNonClonedKey
) {
554 TestBookmarkClient client
;
555 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
556 model
->AddNonClonedKey("foo");
557 const BookmarkNode
* parent
= model
->other_node();
558 const BookmarkNode
* node
= model
->AddFolder(parent
, 0, ASCIIToUTF16("title"));
559 model
->SetNodeMetaInfo(node
, "foo", "ignored value");
560 model
->SetNodeMetaInfo(node
, "bar", "kept value");
561 std::vector
<BookmarkNodeData::Element
> elements
;
562 BookmarkNodeData::Element
node_data(node
);
563 elements
.push_back(node_data
);
565 // Cloning a folder should clear the non cloned key.
566 CloneBookmarkNode(model
.get(), elements
, parent
, 0, true);
567 ASSERT_EQ(2, parent
->child_count());
569 EXPECT_FALSE(parent
->GetChild(0)->GetMetaInfo("foo", &value
));
571 // Other keys should still be cloned.
572 EXPECT_TRUE(parent
->GetChild(0)->GetMetaInfo("bar", &value
));
573 EXPECT_EQ("kept value", value
);
576 TEST_F(BookmarkUtilsTest
, RemoveAllBookmarks
) {
577 TestBookmarkClient client
;
578 // Load a model with an extra node that is not editable.
579 BookmarkPermanentNode
* extra_node
= new BookmarkPermanentNode(100);
580 BookmarkPermanentNodeList extra_nodes
;
581 extra_nodes
.push_back(extra_node
);
582 client
.SetExtraNodesToLoad(extra_nodes
.Pass());
584 scoped_ptr
<BookmarkModel
> model(client
.CreateModel());
585 EXPECT_TRUE(model
->bookmark_bar_node()->empty());
586 EXPECT_TRUE(model
->other_node()->empty());
587 EXPECT_TRUE(model
->mobile_node()->empty());
588 EXPECT_TRUE(extra_node
->empty());
590 const base::string16 title
= base::ASCIIToUTF16("Title");
591 const GURL
url("http://google.com");
592 model
->AddURL(model
->bookmark_bar_node(), 0, title
, url
);
593 model
->AddURL(model
->other_node(), 0, title
, url
);
594 model
->AddURL(model
->mobile_node(), 0, title
, url
);
595 model
->AddURL(extra_node
, 0, title
, url
);
597 std::vector
<const BookmarkNode
*> nodes
;
598 model
->GetNodesByURL(url
, &nodes
);
599 ASSERT_EQ(4u, nodes
.size());
601 RemoveAllBookmarks(model
.get(), url
);
604 model
->GetNodesByURL(url
, &nodes
);
605 ASSERT_EQ(1u, nodes
.size());
606 EXPECT_TRUE(model
->bookmark_bar_node()->empty());
607 EXPECT_TRUE(model
->other_node()->empty());
608 EXPECT_TRUE(model
->mobile_node()->empty());
609 EXPECT_EQ(1, extra_node
->child_count());
613 } // namespace bookmarks