1 // Copyright 2013 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 "chrome/browser/bookmarks/bookmark_tag_model.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_tag_model_observer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using base::ASCIIToUTF16;
16 const std::string input_tag;
17 const std::string expected_tag;
18 } whitespace_test_cases[] = {
20 {"foo\nbar", "foo bar"},
21 {"foo\n\nbar", "foo bar"},
22 {"foo\n\n\nbar", "foo bar"},
23 {"foo\r\nbar", "foo bar"},
24 {"foo\r\n\r\nbar", "foo bar"},
25 {"\nfoo\nbar\n", "foo bar"},
27 {"foo bar", "foo bar"},
28 {" foo bar ", "foo bar"},
29 {" foo bar ", "foo bar"},
31 {"\tfoo\tbar\t", "foo bar"},
32 {"\tfoo bar\t", "foo bar"},
34 {"\tfoo\nbar\t", "foo bar"},
35 {"\tfoo\r\nbar\t", "foo bar"},
36 {" foo\tbar\n", "foo bar"},
37 {"\t foo \t bar \t", "foo bar"},
38 {"\n foo\r\n\tbar\n \t", "foo bar"},
42 OBSERVER_COUNTS_ADD = 0,
43 OBSERVER_COUNTS_BEFORE_REMOVE,
44 OBSERVER_COUNTS_REMOVE,
45 OBSERVER_COUNTS_BEFORE_CHANGE,
46 OBSERVER_COUNTS_CHANGE,
47 OBSERVER_COUNTS_BEFORE_TAG_CHANGE,
48 OBSERVER_COUNTS_TAG_CHANGE,
49 OBSERVER_COUNTS_FAVICON_CHANGE,
50 OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN,
51 OBSERVER_COUNTS_EXTENSIVE_CHANGE_END,
52 OBSERVER_COUNTS_BEFORE_REMOVE_ALL,
53 OBSERVER_COUNTS_REMOVE_ALL,
54 OBSERVER_COUNTS_TOTAL_NUMBER_OF_COUNTS
57 const std::string count_name[] = {
58 "OBSERVER_COUNTS_ADD",
59 "OBSERVER_COUNTS_BEFORE_REMOVE",
60 "OBSERVER_COUNTS_REMOVE",
61 "OBSERVER_COUNTS_BEFORE_CHANGE",
62 "OBSERVER_COUNTS_CHANGE",
63 "OBSERVER_COUNTS_BEFORE_TAG_CHANGE",
64 "OBSERVER_COUNTS_TAG_CHANGE",
65 "OBSERVER_COUNTS_FAVICON_CHANGE",
66 "OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN",
67 "OBSERVER_COUNTS_EXTENSIVE_CHANGE_END",
68 "OBSERVER_COUNTS_BEFORE_REMOVE_ALL",
69 "OBSERVER_COUNTS_REMOVE_ALL"
73 class BookmarkTagModelTest
74 : public testing::Test, public BookmarkTagModelObserver {
76 struct ObserverDetails {
77 ObserverDetails() : bookmark_(NULL) {}
79 void Set(const BookmarkNode* bookmark,
80 const std::set<BookmarkTag>& tags) {
85 void ExpectEquals(const BookmarkNode* bookmark,
86 const std::set<BookmarkTag>& tags) {
87 EXPECT_EQ(bookmark_, bookmark);
88 EXPECT_EQ(tags_, tags);
92 const BookmarkNode* bookmark_;
93 std::set<BookmarkTag> tags_;
96 BookmarkTagModelTest() : model_(NULL),
97 tag_model_(new BookmarkTagModel(&model_)) {
98 tag_model_->AddObserver(this);
102 virtual ~BookmarkTagModelTest() {
105 // BookmarkTagModelObserver:
106 virtual void BookmarkTagModelLoaded(BookmarkTagModel* model) OVERRIDE {
107 // We never load from the db, so that this should never get invoked.
111 // Invoked when a node has been added.
112 virtual void BookmarkNodeAdded(BookmarkTagModel* model,
113 const BookmarkNode* bookmark) OVERRIDE {
114 ++counts_[OBSERVER_COUNTS_ADD];
115 observer_details_.Set(bookmark, model->GetTagsForBookmark(bookmark));
118 // Invoked before a node is removed.
119 // |node| is the node to be removed.
120 virtual void OnWillRemoveBookmarks(BookmarkTagModel* model,
121 const BookmarkNode* bookmark) OVERRIDE {
122 ++counts_[OBSERVER_COUNTS_BEFORE_REMOVE];
125 // Invoked when a node has been removed, the item may still be starred though.
126 // |node| is the node that was removed.
127 virtual void BookmarkNodeRemoved(BookmarkTagModel* model,
128 const BookmarkNode* bookmark) OVERRIDE {
129 ++counts_[OBSERVER_COUNTS_REMOVE];
132 // Invoked before the title or url of a node is changed.
133 virtual void OnWillChangeBookmarkNode(BookmarkTagModel* model,
134 const BookmarkNode* bookmark) OVERRIDE {
135 ++counts_[OBSERVER_COUNTS_BEFORE_CHANGE];
138 // Invoked when the title or url of a node changes.
139 virtual void BookmarkNodeChanged(BookmarkTagModel* model,
140 const BookmarkNode* bookmark) OVERRIDE {
141 ++counts_[OBSERVER_COUNTS_CHANGE];
142 observer_details_.Set(bookmark, model->GetTagsForBookmark(bookmark));
145 virtual void OnWillChangeBookmarkTags(BookmarkTagModel* model,
146 const BookmarkNode* bookmark) OVERRIDE {
147 ++counts_[OBSERVER_COUNTS_BEFORE_TAG_CHANGE];
150 virtual void BookmarkTagsChanged(BookmarkTagModel* model,
151 const BookmarkNode* bookmark) OVERRIDE {
152 ++counts_[OBSERVER_COUNTS_TAG_CHANGE];
153 observer_details_.Set(bookmark, model->GetTagsForBookmark(bookmark));
156 virtual void BookmarkNodeFaviconChanged(BookmarkTagModel* model,
157 const BookmarkNode* node) OVERRIDE {
158 ++counts_[OBSERVER_COUNTS_FAVICON_CHANGE];
161 virtual void ExtensiveBookmarkChangesBeginning(BookmarkTagModel* model)
163 ++counts_[OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN];
166 virtual void ExtensiveBookmarkChangesEnded(BookmarkTagModel* model) OVERRIDE {
167 ++counts_[OBSERVER_COUNTS_EXTENSIVE_CHANGE_END];
170 virtual void OnWillRemoveAllBookmarks(BookmarkTagModel* model) OVERRIDE {
171 ++counts_[OBSERVER_COUNTS_BEFORE_REMOVE_ALL];
174 virtual void BookmarkAllNodesRemoved(BookmarkTagModel* model) OVERRIDE {
175 ++counts_[OBSERVER_COUNTS_REMOVE_ALL];
179 for (unsigned int i = 0; i < OBSERVER_COUNTS_TOTAL_NUMBER_OF_COUNTS; ++i)
183 void AssertAndClearObserverCount(ObserverCounts count, int expected) {
184 ASSERT_EQ(expected, counts_[count]) << count_name[count];
188 void AssertAllCountsClear() {
189 for (unsigned int i = 0; i < OBSERVER_COUNTS_TOTAL_NUMBER_OF_COUNTS; ++i)
190 ASSERT_EQ(0, counts_[i]) << count_name[i];
193 const BookmarkNode* AddURLWithTags(
194 const std::string& name,
195 const std::set<BookmarkTag>& tags) {
196 const base::string16 title(ASCIIToUTF16(name));
197 const GURL url("http://" + name + ".com");
199 return tag_model_->AddURL(title, url, tags);
203 BookmarkModel model_;
204 scoped_ptr<BookmarkTagModel> tag_model_;
205 ObserverDetails observer_details_;
208 int counts_[OBSERVER_COUNTS_TOTAL_NUMBER_OF_COUNTS];
210 DISALLOW_COPY_AND_ASSIGN(BookmarkTagModelTest);
213 TEST_F(BookmarkTagModelTest, InitialState) {
214 std::vector<BookmarkTag> tags(tag_model_->TagsRelatedToTag(base::string16()));
215 EXPECT_EQ(0UL, tags.size());
218 TEST_F(BookmarkTagModelTest, AddURL) {
219 std::set<BookmarkTag> tags;
220 tags.insert(ASCIIToUTF16("bar"));
221 tags.insert(ASCIIToUTF16("baz"));
223 AddURLWithTags("orly", tags);
224 const BookmarkNode* new_node = AddURLWithTags("foo", tags);
225 AssertAndClearObserverCount(OBSERVER_COUNTS_ADD, 2);
226 AssertAllCountsClear();
228 observer_details_.ExpectEquals(new_node, tags);
230 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(ASCIIToUTF16("bar")).size());
231 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(ASCIIToUTF16("baz")).size());
232 EXPECT_EQ(tags, tag_model_->GetTagsForBookmark(new_node));
234 std::vector<BookmarkTag> alltags(
235 tag_model_->TagsRelatedToTag(base::string16()));
236 EXPECT_EQ(2UL, alltags.size());
239 TEST_F(BookmarkTagModelTest, RelatedTo) {
240 std::set<BookmarkTag> tags;
241 tags.insert(ASCIIToUTF16("bar"));
242 tags.insert(ASCIIToUTF16("baz"));
244 AddURLWithTags("orly", tags);
245 AddURLWithTags("foo", tags);
246 AssertAndClearObserverCount(OBSERVER_COUNTS_ADD, 2);
247 AssertAllCountsClear();
249 std::vector<BookmarkTag> bartags(tag_model_->TagsRelatedToTag(
250 ASCIIToUTF16("bar")));
251 EXPECT_EQ(1UL, bartags.size());
252 std::vector<BookmarkTag> baztags(tag_model_->TagsRelatedToTag(
253 ASCIIToUTF16("baz")));
254 EXPECT_EQ(1UL, baztags.size());
257 TEST_F(BookmarkTagModelTest, AddURLWithWhitespaceTitle) {
258 std::set<BookmarkTag> tags;
260 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i) {
261 const BookmarkNode* new_node = AddURLWithTags(
262 whitespace_test_cases[i].input_tag, tags);
264 EXPECT_EQ(ASCIIToUTF16(whitespace_test_cases[i].expected_tag),
265 new_node->GetTitle());
266 EXPECT_EQ(BookmarkNode::URL, new_node->type());
270 TEST_F(BookmarkTagModelTest, CheckTagsWithWhitespace) {
271 std::set<BookmarkTag> tags;
273 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i)
274 tags.insert(ASCIIToUTF16(whitespace_test_cases[i].input_tag));
276 AddURLWithTags("foo", tags);
278 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
281 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(whitespace_test_cases); ++i) {
282 EXPECT_EQ(0UL, tag_model_->BookmarksForTag(
283 ASCIIToUTF16(whitespace_test_cases[i].input_tag)).size());
284 EXPECT_EQ(1UL, tag_model_->BookmarksForTag(
285 ASCIIToUTF16(whitespace_test_cases[i].expected_tag)).size());
289 TEST_F(BookmarkTagModelTest, RemoveURL) {
290 std::set<BookmarkTag> tags;
291 tags.insert(ASCIIToUTF16("bar"));
292 tags.insert(ASCIIToUTF16("baz"));
294 const BookmarkNode* new_node = AddURLWithTags("foo", tags);
295 const BookmarkNode* new_node2 = AddURLWithTags("flou", tags);
298 tag_model_->Remove(new_node);
299 tag_model_->Remove(new_node2);
300 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_REMOVE, 2);
301 AssertAndClearObserverCount(OBSERVER_COUNTS_REMOVE, 2);
302 AssertAllCountsClear();
304 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
306 EXPECT_EQ(0UL, alltags.size());
309 TEST_F(BookmarkTagModelTest, AddTagToBookmarks) {
310 std::set<BookmarkTag> tags;
311 tags.insert(ASCIIToUTF16("bar"));
312 tags.insert(ASCIIToUTF16("baz"));
314 std::set<const BookmarkNode*> bookmarks;
315 bookmarks.insert(AddURLWithTags("foo", tags));
316 bookmarks.insert(AddURLWithTags("flou", tags));
319 std::set<BookmarkTag> new_tags;
320 new_tags.insert(ASCIIToUTF16("new_bar"));
321 new_tags.insert(ASCIIToUTF16("new_baz"));
323 tag_model_->AddTagsToBookmarks(new_tags, bookmarks);
324 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 2);
325 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 2);
326 AssertAllCountsClear();
328 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
330 EXPECT_EQ(4UL, alltags.size());
333 TEST_F(BookmarkTagModelTest, AddTagToBookmark) {
334 std::set<BookmarkTag> tags;
335 tags.insert(ASCIIToUTF16("bar"));
336 tags.insert(ASCIIToUTF16("baz"));
338 const BookmarkNode* bookmark = AddURLWithTags("foo", tags);
341 std::set<BookmarkTag> new_tags;
342 new_tags.insert(ASCIIToUTF16("new_bar"));
343 new_tags.insert(ASCIIToUTF16("new_baz"));
345 tag_model_->AddTagsToBookmark(new_tags, bookmark);
346 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 1);
347 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 1);
348 AssertAllCountsClear();
350 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
352 EXPECT_EQ(4UL, alltags.size());
355 TEST_F(BookmarkTagModelTest, RemoveTagFromBookmarks) {
356 std::set<BookmarkTag> tags;
357 tags.insert(ASCIIToUTF16("bar"));
358 tags.insert(ASCIIToUTF16("baz"));
360 std::set<const BookmarkNode*> bookmarks;
362 bookmarks.insert(AddURLWithTags("foo", tags));
363 bookmarks.insert(AddURLWithTags("flou", tags));
366 tag_model_->RemoveTagsFromBookmarks(tags, bookmarks);
367 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 2);
368 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 2);
369 AssertAllCountsClear();
371 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
373 EXPECT_EQ(0UL, alltags.size());
376 TEST_F(BookmarkTagModelTest, RemoveTagFromBookmark) {
377 std::set<BookmarkTag> tags;
378 tags.insert(ASCIIToUTF16("bar"));
379 tags.insert(ASCIIToUTF16("baz"));
381 const BookmarkNode* bookmark = AddURLWithTags("foo", tags);
384 tag_model_->RemoveTagsFromBookmark(tags, bookmark);
385 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 1);
386 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 1);
387 AssertAllCountsClear();
389 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
391 EXPECT_EQ(0UL, alltags.size());
394 TEST_F(BookmarkTagModelTest, RemoveAll) {
395 std::set<BookmarkTag> tags;
396 tags.insert(ASCIIToUTF16("bar"));
397 tags.insert(ASCIIToUTF16("baz"));
399 AddURLWithTags("foo", tags);
403 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN, 1);
404 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_REMOVE_ALL, 1);
405 AssertAndClearObserverCount(OBSERVER_COUNTS_REMOVE_ALL, 1);
406 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_END, 1);
407 AssertAllCountsClear();
409 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
411 EXPECT_EQ(0UL, alltags.size());
414 TEST_F(BookmarkTagModelTest, DuplicateFolders) {
415 const BookmarkNode* left = model_.AddFolder(model_.bookmark_bar_node(), 0,
416 ASCIIToUTF16("left"));
417 const BookmarkNode* right = model_.AddFolder(model_.bookmark_bar_node(), 0,
418 ASCIIToUTF16("right"));
419 const BookmarkNode* left_handed = model_.AddFolder(left, 0,
420 ASCIIToUTF16("handed"));
421 const BookmarkNode* right_handed = model_.AddFolder(right, 0,
422 ASCIIToUTF16("handed"));
424 left_handed, 0, ASCIIToUTF16("red"), GURL("http://random.com"));
426 right_handed, 0, ASCIIToUTF16("der"), GURL("http://random.com"));
428 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(ASCIIToUTF16("handed")).size());
429 EXPECT_EQ(1UL, tag_model_->BookmarksForTag(ASCIIToUTF16("left")).size());
430 EXPECT_EQ(1UL, tag_model_->BookmarksForTag(ASCIIToUTF16("right")).size());
431 std::set<BookmarkTag> tags;
432 tags.insert(ASCIIToUTF16("left"));
433 tags.insert(ASCIIToUTF16("handed"));
434 EXPECT_EQ(1UL, tag_model_->BookmarksForTags(tags).size());
437 class PreloadedBookmarkTagModelTest : public BookmarkTagModelTest {
439 PreloadedBookmarkTagModelTest() : BookmarkTagModelTest() {
440 PopulateUnderlyingModel();
443 void PopulateUnderlyingModel() {
445 top_node_ = model_.AddURL(model_.bookmark_bar_node(), 0,
446 ASCIIToUTF16("Tagless"), GURL("http://example.com"));
447 folder_1_ = model_.AddFolder(model_.bookmark_bar_node(), 0,
448 ASCIIToUTF16("folder1"));
449 one_tag_ = model_.AddURL(folder_1_, 0, ASCIIToUTF16("OneTag"),
450 GURL("http://random.com"));
451 folder_2_ = model_.AddFolder(folder_1_, 0, ASCIIToUTF16("folder2"));
452 two_tags_ = model_.AddURL(folder_2_, 0, ASCIIToUTF16("TwoTags"),
453 GURL("http://moveit.com"));
454 AssertAndClearObserverCount(OBSERVER_COUNTS_ADD, 3);
455 AssertAllCountsClear();
458 void AssertModelMatches() {
459 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(ASCIIToUTF16("folder1")).size());
460 EXPECT_EQ(1UL, tag_model_->BookmarksForTag(ASCIIToUTF16("folder2")).size());
462 std::set<BookmarkTag> tags;
463 tags.insert(ASCIIToUTF16("folder1"));
464 EXPECT_EQ(tags, tag_model_->GetTagsForBookmark(one_tag_));
466 tags.insert(ASCIIToUTF16("folder2"));
467 const BookmarkNode* two_tags = tag_model_->
468 GetMostRecentlyAddedBookmarkForURL(GURL("http://moveit.com"));
469 EXPECT_EQ(tags, tag_model_->GetTagsForBookmark(two_tags));
471 std::vector<BookmarkTag> alltags(tag_model_->TagsRelatedToTag(
473 EXPECT_EQ(2UL, alltags.size());
477 const BookmarkNode* folder_1_;
478 const BookmarkNode* folder_2_;
479 const BookmarkNode* top_node_;
480 const BookmarkNode* one_tag_;
481 const BookmarkNode* two_tags_;
483 DISALLOW_COPY_AND_ASSIGN(PreloadedBookmarkTagModelTest);
486 TEST_F(PreloadedBookmarkTagModelTest, InitialState) {
487 AssertAllCountsClear();
488 AssertModelMatches();
491 TEST_F(PreloadedBookmarkTagModelTest, FromExistingState) {
492 tag_model_.reset(new BookmarkTagModel(&model_));
493 tag_model_->AddObserver(this);
494 AssertAllCountsClear();
495 AssertModelMatches();
498 TEST_F(PreloadedBookmarkTagModelTest, BookmarkChange) {
499 AssertAllCountsClear();
500 tag_model_->SetTitle(top_node_, ASCIIToUTF16("newname"));
501 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_CHANGE, 1);
502 AssertAndClearObserverCount(OBSERVER_COUNTS_CHANGE, 1);
503 AssertAllCountsClear();
506 TEST_F(PreloadedBookmarkTagModelTest, UnchangedBookmarkMove) {
507 AssertAllCountsClear();
508 model_.Move(top_node_, folder_2_, 0);
509 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 1);
510 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 1);
511 AssertAllCountsClear();
514 TEST_F(PreloadedBookmarkTagModelTest, ChangedBookmarkMove) {
515 std::set<BookmarkTag> tags;
516 tags.insert(ASCIIToUTF16("bar"));
518 AssertAllCountsClear();
519 tag_model_->AddTagsToBookmark(tags, top_node_);
520 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 1);
521 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 1);
522 AssertAllCountsClear();
524 model_.Move(top_node_, folder_2_, 0);
525 AssertAllCountsClear();
528 TEST_F(PreloadedBookmarkTagModelTest, DuplicateBookmark) {
529 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());
530 model_.AddURL(folder_1_, 0, one_tag_->GetTitle(), one_tag_->url());
531 EXPECT_EQ(3UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());
534 TEST_F(PreloadedBookmarkTagModelTest, NamelessFolders) {
535 const BookmarkNode* folder = model_.AddFolder(model_.bookmark_bar_node(), 0,
537 model_.AddURL(folder, 0, ASCIIToUTF16("StillNotag"),
538 GURL("http://random.com"));
539 AssertModelMatches();
542 TEST_F(PreloadedBookmarkTagModelTest, FolderNameChange) {
543 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());
544 model_.SetTitle(folder_1_, ASCIIToUTF16("Bummer"));
545 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN, 1);
546 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_END, 1);
547 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 2);
548 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 2);
549 AssertAllCountsClear();
551 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());
554 TEST_F(PreloadedBookmarkTagModelTest, FolderMoved) {
555 EXPECT_EQ(2UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());
556 model_.Move(folder_2_, model_.bookmark_bar_node(), 0);
557 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_BEGIN, 1);
558 AssertAndClearObserverCount(OBSERVER_COUNTS_EXTENSIVE_CHANGE_END, 1);
559 AssertAndClearObserverCount(OBSERVER_COUNTS_BEFORE_TAG_CHANGE, 1);
560 AssertAndClearObserverCount(OBSERVER_COUNTS_TAG_CHANGE, 1);
561 AssertAllCountsClear();
563 EXPECT_EQ(1UL, tag_model_->BookmarksForTag(folder_1_->GetTitle()).size());