bookmark_model_unittest.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set> 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/tree_node_iterator.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/tree_node_model.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/base_paths.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/file_util.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/hash_tables.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/path_service.h" 133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/string_split.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_codec.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h" 21731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_thread.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_notifications.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h" 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_registrar.h" 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/model_test_utils.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time; 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Helper to get a mutable bookmark node. 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic BookmarkNode* AsMutable(const BookmarkNode* node) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return const_cast<BookmarkNode*>(node); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SwapDateAdded(BookmarkNode* n1, BookmarkNode* n2) { 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time tmp = n1->date_added(); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n1->set_date_added(n2->date_added()); 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n2->set_date_added(tmp); 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // anonymous namespace 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BookmarkModelTest : public testing::Test, public BookmarkModelObserver { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct ObserverDetails { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ObserverDetails() { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Set(NULL, NULL, -1, -1); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Set(const BookmarkNode* node1, 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node2, 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index1, 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index2) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this->node1 = node1; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this->node2 = node2; 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this->index1 = index1; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch this->index2 = index2; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AssertEquals(const BookmarkNode* node1, 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node2, 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index1, 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index2) { 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(this->node1 == node1); 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(this->node2 == node2); 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(index1, this->index1); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(index2, this->index2); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node1; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node2; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index1; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index2; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModelTest() : model(NULL) { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.AddObserver(this); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void Loaded(BookmarkModel* model) { 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We never load from the db, so that this should never get invoked. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeMoved(BookmarkModel* model, 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* old_parent, 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int old_index, 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_parent, 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int new_index) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch moved_count++; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.Set(old_parent, new_parent, old_index, new_index); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeAdded(BookmarkModel* model, 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch added_count++; 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.Set(parent, NULL, index, -1); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeRemoved(BookmarkModel* model, 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int old_index, 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) { 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch removed_count++; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.Set(parent, NULL, old_index, -1); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeChanged(BookmarkModel* model, 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch changed_count++; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.Set(node, NULL, -1, -1); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reordered_count_++; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We never attempt to load favicons, so that this method never 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // gets invoked. 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void ClearCounts() { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reordered_count_ = moved_count = added_count = removed_count = 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch changed_count = 0; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AssertObserverCount(int added_count, 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int moved_count, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int removed_count, 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int changed_count, 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reordered_count) { 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(added_count, this->added_count); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(moved_count, this->moved_count); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(removed_count, this->removed_count); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(changed_count, this->changed_count); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(reordered_count, reordered_count_); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel model; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int moved_count; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int added_count; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int removed_count; 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int changed_count; 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int reordered_count_; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ObserverDetails observer_details; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, InitialState) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* bb_node = model.GetBookmarkBarNode(); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(bb_node != NULL); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, bb_node->GetChildCount()); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(BookmarkNode::BOOKMARK_BAR, bb_node->type()); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* other_node = model.other_node(); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(other_node != NULL); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, other_node->GetChildCount()); 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(BookmarkNode::OTHER_NODE, other_node->type()); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(bb_node->id() != other_node->id()); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, AddURL) { 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_node = model.AddURL(root, 0, title, url); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(1, 0, 0, 0, 0); 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1, root->GetChildCount()); 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(title, new_node->GetTitle()); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(url == new_node->GetURL()); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::URL, new_node->type()); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(new_node == model.GetMostRecentlyAddedNodeForURL(url)); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(new_node->id() != root->id() && 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_node->id() != model.other_node()->id()); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, AddGroup) { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_node = model.AddGroup(root, 0, title); 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(1, 0, 0, 0, 0); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1, root->GetChildCount()); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(title, new_node->GetTitle()); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::FOLDER, new_node->type()); 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(new_node->id() != root->id() && 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch new_node->id() != model.other_node()->id()); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add another group, just to make sure group_ids are incremented correctly. 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.AddGroup(root, 0, title); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(1, 0, 0, 0, 0); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, RemoveURL) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.AddURL(root, 0, title, url); 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(root, 0); 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(0, root->GetChildCount()); 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 1, 0, 0); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure there is no mapping for the URL. 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(model.GetMostRecentlyAddedNodeForURL(url) == NULL); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, RemoveGroup) { 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BookmarkNode* group = model.AddGroup(root, 0, ASCIIToUTF16("foo")); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a URL as a child. 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.AddURL(group, 0, title, url); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now remove the group. 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(root, 0); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(0, root->GetChildCount()); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 1, 0, 0); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure there is no mapping for the URL. 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(model.GetMostRecentlyAddedNodeForURL(url) == NULL); 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, SetTitle) { 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 title(ASCIIToUTF16("foo")); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = model.AddURL(root, 0, title, url); 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick title = ASCIIToUTF16("foo2"); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.SetTitle(node, title); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 0, 1, 0); 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(node, NULL, -1, -1); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(title, node->GetTitle()); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, SetURL) { 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url("http://foo.com"); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = model.AddURL(root, 0, title, url); 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url = GURL("http://foo2.com"); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.SetURL(node, url); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 0, 1, 0); 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(node, NULL, -1, -1); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(url, node->GetURL()); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, Move) { 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node = model.AddURL(root, 0, title, url); 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BookmarkNode* group1 = model.AddGroup(root, 0, ASCIIToUTF16("foo")); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Move(node, group1, 0); 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 1, 0, 0, 0); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, group1, 1, 0); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(group1 == node->GetParent()); 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1, root->GetChildCount()); 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(group1, root->GetChild(0)); 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1, group1->GetChildCount()); 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(node, group1->GetChild(0)); 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // And remove the group. 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(root, 0); 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 1, 0, 0); 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch observer_details.AssertEquals(root, NULL, 0, -1); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(model.GetMostRecentlyAddedNodeForURL(url) == NULL); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, root->GetChildCount()); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, Copy) { 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* root = model.GetBookmarkBarNode(); 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const std::string model_string("a 1:[ b c ] d 2:[ e f g ] h "); 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model_test_utils::AddNodesFromModelString(model, root, model_string); 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Validate initial model. 3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string actualModelString = model_test_utils::ModelStringFromNode(root); 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(model_string, actualModelString); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy 'd' to be after '1:b': URL item from bar to folder. 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* nodeToCopy = root->GetChild(2); 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* destination = root->GetChild(1); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, destination, 1); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a 1:[ b d c ] d 2:[ e f g ] h ", actualModelString); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy '1:d' to be after 'a': URL item from folder to bar. 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* group = root->GetChild(1); 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodeToCopy = group->GetChild(1); 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, root, 1); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a d 1:[ b d c ] d 2:[ e f g ] h ", actualModelString); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy '1' to be after '2:e': Folder from bar to folder. 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodeToCopy = root->GetChild(2); 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch destination = root->GetChild(4); 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, destination, 1); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a d 1:[ b d c ] d 2:[ e 1:[ b d c ] f g ] h ", actualModelString); 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy '2:1' to be after '2:f': Folder within same folder. 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch group = root->GetChild(4); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodeToCopy = group->GetChild(1); 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, group, 3); 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a d 1:[ b d c ] d 2:[ e 1:[ b d c ] f 1:[ b d c ] g ] h ", 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy first 'd' to be after 'h': URL item within the bar. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodeToCopy = root->GetChild(1); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, root, 6); 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a d 1:[ b d c ] d 2:[ e 1:[ b d c ] f 1:[ b d c ] g ] h d ", 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy '2' to be after 'a': Folder within the bar. 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodeToCopy = root->GetChild(4); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Copy(nodeToCopy, root, 1); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString = model_test_utils::ModelStringFromNode(root); 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ("a 2:[ e 1:[ b d c ] f 1:[ b d c ] g ] d 1:[ b d c ] " 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "d 2:[ e 1:[ b d c ] f 1:[ b d c ] g ] h d ", 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actualModelString); 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that adding a URL to a folder updates the last modified time. 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, ParentForNewNodes) { 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(model.GetBookmarkBarNode(), model.GetParentForNewNodes()); 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16 title(ASCIIToUTF16("foo")); 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com"); 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.AddURL(model.other_node(), 0, title, url); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(model.other_node(), model.GetParentForNewNodes()); 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure recently modified stays in sync when adding a URL. 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, MostRecentlyModifiedGroups) { 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a group. 3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const BookmarkNode* group = model.AddGroup(model.other_node(), 0, 3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASCIIToUTF16("foo")); 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a URL to it. 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.AddURL(group, 0, ASCIIToUTF16("blah"), GURL("http://foo.com")); 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure group is in the most recently modified. 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> most_recent_groups = 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::GetMostRecentlyModifiedGroups(&model, 1); 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1U, most_recent_groups.size()); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(group, most_recent_groups[0]); 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Nuke the group and do another fetch, making sure group isn't in the 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // returned list. 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(group->GetParent(), 0); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch most_recent_groups = 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::GetMostRecentlyModifiedGroups(&model, 1); 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1U, most_recent_groups.size()); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(most_recent_groups[0] != group); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure MostRecentlyAddedEntries stays in sync. 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, MostRecentlyAddedEntries) { 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a couple of nodes such that the following holds for the time of the 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // nodes: n1 > n2 > n3 > n4. 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time base_time = Time::Now(); 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n1 = AsMutable(model.AddURL(model.GetBookmarkBarNode(), 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 0, 4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASCIIToUTF16("blah"), 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://foo.com/0"))); 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n2 = AsMutable(model.AddURL(model.GetBookmarkBarNode(), 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1, 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASCIIToUTF16("blah"), 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://foo.com/1"))); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n3 = AsMutable(model.AddURL(model.GetBookmarkBarNode(), 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2, 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASCIIToUTF16("blah"), 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://foo.com/2"))); 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n4 = AsMutable(model.AddURL(model.GetBookmarkBarNode(), 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3, 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASCIIToUTF16("blah"), 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://foo.com/3"))); 426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n1->set_date_added(base_time + TimeDelta::FromDays(4)); 427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n2->set_date_added(base_time + TimeDelta::FromDays(3)); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n3->set_date_added(base_time + TimeDelta::FromDays(2)); 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n4->set_date_added(base_time + TimeDelta::FromDays(1)); 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure order is honored. 432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> recently_added; 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::GetMostRecentlyAddedEntries(&model, 2, &recently_added); 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2U, recently_added.size()); 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n1 == recently_added[0]); 436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n2 == recently_added[1]); 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // swap 1 and 2, then check again. 439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch recently_added.clear(); 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SwapDateAdded(n1, n2); 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::GetMostRecentlyAddedEntries(&model, 4, &recently_added); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(4U, recently_added.size()); 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n2 == recently_added[0]); 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n1 == recently_added[1]); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n3 == recently_added[2]); 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(n4 == recently_added[3]); 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure GetMostRecentlyAddedNodeForURL stays in sync. 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, GetMostRecentlyAddedNodeForURL) { 451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a couple of nodes such that the following holds for the time of the 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // nodes: n1 > n2 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Time base_time = Time::Now(); 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com/0"); 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n1 = AsMutable(model.AddURL( 4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.GetBookmarkBarNode(), 0, ASCIIToUTF16("blah"), url)); 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* n2 = AsMutable(model.AddURL( 4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.GetBookmarkBarNode(), 1, ASCIIToUTF16("blah"), url)); 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n1->set_date_added(base_time + TimeDelta::FromDays(4)); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n2->set_date_added(base_time + TimeDelta::FromDays(3)); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure order is honored. 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(n1, model.GetMostRecentlyAddedNodeForURL(url)); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // swap 1 and 2, then check again. 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SwapDateAdded(n1, n2); 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(n2, model.GetMostRecentlyAddedNodeForURL(url)); 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure GetBookmarks removes duplicates. 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, GetBookmarksWithDups) { 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com/0"); 4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.AddURL(model.GetBookmarkBarNode(), 0, ASCIIToUTF16("blah"), url); 4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.AddURL(model.GetBookmarkBarNode(), 1, ASCIIToUTF16("blah"), url); 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GURL> urls; 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.GetBookmarks(&urls); 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1U, urls.size()); 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(urls[0] == url); 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(BookmarkModelTest, HasBookmarks) { 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GURL url("http://foo.com/"); 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.AddURL(model.GetBookmarkBarNode(), 0, ASCIIToUTF16("bar"), url); 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(model.HasBookmarks()); 4873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NotificationObserver implementation used in verifying we've received the 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTIFY_URLS_STARRED method correctly. 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass StarredListener : public NotificationObserver { 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StarredListener() : notification_count_(0), details_(false) { 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch registrar_.Add(this, NotificationType::URLS_STARRED, Source<Profile>(NULL)); 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Observe(NotificationType type, 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type == NotificationType::URLS_STARRED) { 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch notification_count_++; 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch details_ = *(Details<history::URLsStarredDetails>(details).ptr()); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Number of times NOTIFY_URLS_STARRED has been observed. 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int notification_count_; 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Details from the last NOTIFY_URLS_STARRED. 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::URLsStarredDetails details_; 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationRegistrar registrar_; 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(StarredListener); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure NOTIFY_URLS_STARRED is sent correctly. 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, NotifyURLsStarred) { 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch StarredListener listener; 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL url("http://foo.com/0"); 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* n1 = model.AddURL( 5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.GetBookmarkBarNode(), 0, ASCIIToUTF16("blah"), url); 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Starred notification should be sent. 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1, listener.notification_count_); 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(listener.details_.starred); 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1U, listener.details_.changed_urls.size()); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(url == *(listener.details_.changed_urls.begin())); 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listener.notification_count_ = 0; 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch listener.details_.changed_urls.clear(); 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add another bookmark for the same URL. This should not send any 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // notification. 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* n2 = model.AddURL( 5403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model.GetBookmarkBarNode(), 1, ASCIIToUTF16("blah"), url); 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, listener.notification_count_); 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove n2. 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(n2->GetParent(), 1); 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch n2 = NULL; 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Shouldn't have received any notification as n1 still exists with the same 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // URL. 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, listener.notification_count_); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(model.GetMostRecentlyAddedNodeForURL(url) == n1); 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove n1. 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.Remove(n1->GetParent(), 0); 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Now we should get the notification. 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(1, listener.notification_count_); 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_FALSE(listener.details_.starred); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1U, listener.details_.changed_urls.size()); 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_TRUE(url == *(listener.details_.changed_urls.begin())); 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// See comment in PopulateNodeFromString. 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef TreeNodeWithValue<BookmarkNode::Type> TestNode; 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Does the work of PopulateNodeFromString. index gives the index of the current 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// element in description to process. 5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic void PopulateNodeImpl(const std::vector<std::string>& description, 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t* index, 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode* parent) { 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (*index < description.size()) { 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& element = description[*index]; 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (*index)++; 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (element == "[") { 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a new group and recurse to add all the children. 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Groups are given a unique named by way of an ever increasing integer 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // value. The groups need not have a name, but one is assigned to help 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // in debugging. 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static int next_group_id = 1; 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode* new_node = 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new TestNode(base::IntToString16(next_group_id++), 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode::FOLDER); 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent->Add(parent->GetChildCount(), new_node); 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateNodeImpl(description, index, new_node); 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else if (element == "]") { 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // End the current group. 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a new URL. 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // All tokens must be space separated. If there is a [ or ] in the name it 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // likely means a space was forgotten. 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(element.find('[') == std::string::npos); 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(element.find(']') == std::string::npos); 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent->Add(parent->GetChildCount(), 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick new TestNode(UTF8ToUTF16(element), BookmarkNode::URL)); 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates and adds nodes to parent based on description. description consists 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of the following tokens (all space separated): 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// [ : creates a new USER_GROUP node. All elements following the [ until the 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// next balanced ] is encountered are added as children to the node. 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ] : closes the last group created by [ so that any further nodes are added 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to the current groups parent. 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// text: creates a new URL node. 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// For example, "a [b] c" creates the following nodes: 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a 1 c 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// | 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// b 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// In words: a node of type URL with the title a, followed by a group node with 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the title 1 having the single child of type url with name b, followed by 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the url node with the title c. 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// NOTE: each name must be unique, and groups are assigned a unique title by way 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// of an increasing integer. 6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic void PopulateNodeFromString(const std::string& description, 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode* parent) { 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::vector<std::string> elements; 624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t index = 0; 6254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch base::SplitStringAlongWhitespace(description, &elements); 626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateNodeImpl(elements, &index, parent); 627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Populates the BookmarkNode with the children of parent. 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void PopulateBookmarkNode(TestNode* parent, 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* bb_node) { 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < parent->GetChildCount(); ++i) { 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode* child = parent->GetChild(i); 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (child->value == BookmarkNode::FOLDER) { 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_bb_node = 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddGroup(bb_node, i, child->GetTitle()); 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateBookmarkNode(child, model, new_bb_node); 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddURL(bb_node, i, child->GetTitle(), 6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GURL("http://" + UTF16ToASCII(child->GetTitle()))); 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test class that creates a BookmarkModel with a real history backend. 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BookmarkModelTestWithProfile : public testing::Test, 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public BookmarkModelObserver { 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModelTestWithProfile() 653731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : ui_thread_(BrowserThread::UI, &message_loop_), 654731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick file_thread_(BrowserThread::FILE, &message_loop_) {} 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void TearDown() { 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(NULL); 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The profile. 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<TestingProfile> profile_; 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verifies the contents of the bookmark bar node match the contents of the 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TestNode. 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyModelMatchesNode(TestNode* expected, const BookmarkNode* actual) { 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(expected->GetChildCount(), actual->GetChildCount()); 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < expected->GetChildCount(); ++i) { 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode* expected_child = expected->GetChild(i); 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* actual_child = actual->GetChild(i); 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(expected_child->GetTitle(), actual_child->GetTitle()); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (expected_child->value == BookmarkNode::FOLDER) { 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(actual_child->type() == BookmarkNode::FOLDER); 677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Recurse throught children. 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyModelMatchesNode(expected_child, actual_child); 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasFatalFailure()) 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // No need to check the URL, just the title is enough. 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(actual_child->type() == BookmarkNode::URL); 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyNoDuplicateIDs(BookmarkModel* model) { 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TreeNodeIterator<const BookmarkNode> it(model->root_node()); 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::hash_set<int64> ids; 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (it.has_next()) 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(ids.insert(it.Next()->id()).second); 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void BlockTillBookmarkModelLoaded() { 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bb_model_ = profile_->GetBookmarkModel(); 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bb_model_->IsLoaded()) 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillLoaded(bb_model_); 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bb_model_->AddObserver(this); 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Destroys the current profile, creates a new one and creates the history 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // service. 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RecreateProfile() { 706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Need to shutdown the old one before creating a new one. 707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(NULL); 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(new TestingProfile()); 709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateHistoryService(true, false); 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* bb_model_; 713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Blocks until the BookmarkModel has finished loading. 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void BlockTillLoaded(BookmarkModel* model) { 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model->AddObserver(this); 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Run(); 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // BookmarkModelObserver methods. 722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Loaded(BookmarkModel* model) { 723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Balances the call in BlockTillLoaded. 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoop::current()->Quit(); 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeMoved(BookmarkModel* model, 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* old_parent, 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int old_index, 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* new_parent, 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int new_index) {} 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeAdded(BookmarkModel* model, 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index) {} 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeRemoved(BookmarkModel* model, 735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent, 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int old_index, 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) {} 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeChanged(BookmarkModel* model, 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) {} 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeChildrenReordered(BookmarkModel* model, 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) {} 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model, 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* node) {} 744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MessageLoopForUI message_loop_; 746731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread ui_thread_; 747731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread file_thread_; 748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates a set of nodes in the bookmark bar model, then recreates the 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// bookmark bar model which triggers loading from the db and checks the loaded 752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// structure to make sure it is what we first created. 753c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTestWithProfile, CreateAndRestore) { 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch struct TestData { 755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Structure of the children of the bookmark bar model node. 7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string bbn_contents; 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Structure of the children of the other node. 7583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string other_contents; 759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } data[] = { 760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See PopulateNodeFromString for a description of these strings. 7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "", "" }, 7623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "a", "b" }, 7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "a [ b ]", "" }, 7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "", "[ b ] a [ c [ d e [ f ] ] ]" }, 7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "a [ b ]", "" }, 7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { "a b c [ d e [ f ] ]", "g h i [ j k [ l ] ]"}, 767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { 769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Recreate the profile. We need to reset with NULL first so that the last 770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // HistoryService releases the locks on the files it creates and we can 771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // delete them. 772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(NULL); 773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(new TestingProfile()); 774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(true); 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateHistoryService(true, false); 776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode bbn; 779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateNodeFromString(data[i].bbn_contents, &bbn); 780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateBookmarkNode(&bbn, bb_model_, bb_model_->GetBookmarkBarNode()); 781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode other; 783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateNodeFromString(data[i].other_contents, &other); 784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateBookmarkNode(&other, bb_model_, bb_model_->other_node()); 785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(false); 787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyModelMatchesNode(&bbn, bb_model_->GetBookmarkBarNode()); 790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyModelMatchesNode(&other, bb_model_->other_node()); 791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyNoDuplicateIDs(bb_model_); 792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test class that creates a BookmarkModel with a real history backend. 796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BookmarkModelTestWithProfile2 : public BookmarkModelTestWithProfile { 797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void SetUp() { 799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_.reset(new TestingProfile()); 800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected: 803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verifies the state of the model matches that of the state in the saved 804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // history file. 805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyExpectedState() { 806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Here's the structure we expect: 807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // bbn 808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // www.google.com - Google 809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // F1 810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://www.google.com/intl/en/ads/ - Google Advertising 811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // F11 812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://www.google.com/services/ - Google Business Solutions 813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // other 814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // OF1 815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // http://www.google.com/intl/en/about.html - About Google 816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* bbn = bb_model_->GetBookmarkBarNode(); 817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2, bbn->GetChildCount()); 818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* child = bbn->GetChild(0); 820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::URL, child->type()); 8213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("Google"), child->GetTitle()); 822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->GetURL() == GURL("http://www.google.com")); 823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = bbn->GetChild(1); 825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->is_folder()); 8263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("F1"), child->GetTitle()); 827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2, child->GetChildCount()); 828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent = child; 830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = parent->GetChild(0); 831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::URL, child->type()); 8323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("Google Advertising"), child->GetTitle()); 833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->GetURL() == GURL("http://www.google.com/intl/en/ads/")); 834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = parent->GetChild(1); 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->is_folder()); 8373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("F11"), child->GetTitle()); 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(1, child->GetChildCount()); 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent = child; 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = parent->GetChild(0); 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::URL, child->type()); 8433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("Google Business Solutions"), child->GetTitle()); 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->GetURL() == GURL("http://www.google.com/services/")); 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parent = bb_model_->other_node(); 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(2, parent->GetChildCount()); 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = parent->GetChild(0); 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->is_folder()); 8513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("OF1"), child->GetTitle()); 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(0, child->GetChildCount()); 853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch child = parent->GetChild(1); 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_EQ(BookmarkNode::URL, child->type()); 8563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_EQ(ASCIIToUTF16("About Google"), child->GetTitle()); 857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(child->GetURL() == 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL("http://www.google.com/intl/en/about.html")); 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(bb_model_->IsBookmarked(GURL("http://www.google.com"))); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyUniqueIDs() { 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<int64> ids; 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_unique = true; 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDImpl(bb_model_->GetBookmarkBarNode(), &ids, &has_unique); 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDImpl(bb_model_->other_node(), &ids, &has_unique); 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(has_unique); 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void VerifyUniqueIDImpl(const BookmarkNode* node, 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<int64>* ids, 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* has_unique) { 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*has_unique) 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ids->count(node->id()) != 0) { 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *has_unique = false; 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ids->insert(node->id()); 882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < node->GetChildCount(); ++i) { 883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDImpl(node->GetChild(i), ids, has_unique); 884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!*has_unique) 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests migrating bookmarks from db into file. This copies an old history db 891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// file containing bookmarks and make sure they are loaded correctly and 892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// persisted correctly. 893c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTestWithProfile2, MigrateFromDBToFileTest) { 894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Copy db file over that contains starred table. 895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath old_history_path; 896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PathService::Get(chrome::DIR_TEST_DATA, &old_history_path); 897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch old_history_path = old_history_path.AppendASCII("bookmarks"); 898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch old_history_path = old_history_path.AppendASCII("History_with_starred"); 899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath new_history_path = profile_->GetPath(); 900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::Delete(new_history_path, true); 901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch file_util::CreateDirectory(new_history_path); 902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath new_history_file = new_history_path.Append( 903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch chrome::kHistoryFilename); 904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(file_util::CopyFile(old_history_path, new_history_file)); 905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the history service making sure it doesn't blow away the file we 907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // just copied. 908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateHistoryService(false, false); 909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(true); 910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we loaded OK. 913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyExpectedState(); 914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasFatalFailure()) 915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure the ids are unique. 918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDs(); 919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasFatalFailure()) 920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create again. This time we shouldn't load from history at all. 923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(false); 924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we loaded OK. 927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyExpectedState(); 928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasFatalFailure()) 929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDs(); 932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (HasFatalFailure()) 933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Recreate the history service (with a clean db). Do this just to make sure 936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we're loading correctly from the bookmarks file. 937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateHistoryService(true, false); 938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(false); 939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyExpectedState(); 941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch VerifyUniqueIDs(); 942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Simple test that removes a bookmark. This test exercises the code paths in 945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// History that block till bookmark bar model is loaded. 946c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTestWithProfile2, RemoveNotification) { 947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateHistoryService(false, false); 948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->CreateBookmarkModel(true); 949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockTillBookmarkModelLoaded(); 950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Add a URL. 952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url("http://www.google.com"); 9533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bb_model_->SetURLStarred(url, string16(), true); 954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)->AddPage( 956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url, NULL, 1, GURL(), PageTransition::TYPED, 9573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick history::RedirectList(), history::SOURCE_BROWSED, false); 958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This won't actually delete the URL, rather it'll empty out the visits. 960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This triggers blocking on the BookmarkModel. 961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)->DeleteURL(url); 962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 964c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BookmarkModelTest, Sort) { 965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Populate the bookmark bar node with nodes for 'B', 'a', 'd' and 'C'. 966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 'C' and 'a' are folders. 967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestNode bbn; 9683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PopulateNodeFromString("B [ a ] d [ a ]", &bbn); 969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const BookmarkNode* parent = model.GetBookmarkBarNode(); 970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PopulateBookmarkNode(&bbn, &model, parent); 971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* child1 = AsMutable(parent->GetChild(1)); 9733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick child1->SetTitle(ASCIIToUTF16("a")); 974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete child1->Remove(0); 975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkNode* child3 = AsMutable(parent->GetChild(3)); 9763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick child3->SetTitle(ASCIIToUTF16("C")); 977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete child3->Remove(0); 978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ClearCounts(); 980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Sort the children of the bookmark bar node. 982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch model.SortChildren(parent); 983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure we were notified. 985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AssertObserverCount(0, 0, 0, 0, 1); 986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Make sure the order matches (remember, 'a' and 'C' are folders and 988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // come first). 9893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(parent->GetChild(0)->GetTitle(), ASCIIToUTF16("a")); 9903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(parent->GetChild(1)->GetTitle(), ASCIIToUTF16("C")); 9913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(parent->GetChild(2)->GetTitle(), ASCIIToUTF16("B")); 9923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(parent->GetChild(3)->GetTitle(), ASCIIToUTF16("d")); 993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 994