1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/history/android/bookmark_model_sql_handler.h" 6 7 #include "base/strings/utf_string_conversions.h" 8 #include "base/synchronization/waitable_event.h" 9 #include "chrome/browser/bookmarks/bookmark_model.h" 10 #include "chrome/browser/bookmarks/bookmark_model_factory.h" 11 #include "chrome/browser/history/history_database.h" 12 #include "chrome/browser/profiles/profile_manager.h" 13 #include "chrome/common/chrome_constants.h" 14 #include "chrome/test/base/testing_browser_process.h" 15 #include "chrome/test/base/testing_profile.h" 16 #include "chrome/test/base/testing_profile_manager.h" 17 #include "chrome/test/base/ui_test_utils.h" 18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/test/test_browser_thread.h" 20 #include "testing/gtest/include/gtest/gtest.h" 21 22 namespace history { 23 24 using content::BrowserThread; 25 26 class BookmarkModelSQLHandlerTest : public testing::Test { 27 public: 28 BookmarkModelSQLHandlerTest() 29 : profile_manager_( 30 TestingBrowserProcess::GetGlobal()), 31 bookmark_model_(NULL), 32 ui_thread_(BrowserThread::UI, &message_loop_), 33 file_thread_(BrowserThread::FILE, &message_loop_) { 34 } 35 virtual ~BookmarkModelSQLHandlerTest() {} 36 37 protected: 38 virtual void SetUp() OVERRIDE { 39 // Setup the testing profile, so the bookmark_model_sql_handler could 40 // get the bookmark model from it. 41 ASSERT_TRUE(profile_manager_.SetUp()); 42 // It seems that the name has to be chrome::kInitialProfile, so it 43 // could be found by ProfileManager::GetLastUsedProfile(). 44 TestingProfile* testing_profile = profile_manager_.CreateTestingProfile( 45 chrome::kInitialProfile); 46 // Create the BookmarkModel that doesn't need to invoke load(). 47 testing_profile->CreateBookmarkModel(true); 48 bookmark_model_ = BookmarkModelFactory::GetForProfile(testing_profile); 49 ui_test_utils::WaitForBookmarkModelToLoad(bookmark_model_); 50 ASSERT_TRUE(bookmark_model_); 51 // Get the BookmarkModel from LastUsedProfile, this is the same way that 52 // how the BookmarkModelSQLHandler gets the BookmarkModel. 53 Profile* profile = ProfileManager::GetLastUsedProfile(); 54 ASSERT_TRUE(profile); 55 56 // Create the directory for history database. 57 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 58 base::FilePath history_db_name = temp_dir_.path().AppendASCII( 59 chrome::kHistoryFilename); 60 history_db_.Init(history_db_name); 61 } 62 63 // Runs the MessageLoopForUI, and return till all pending messages were 64 // processed. 65 void RunMessageLoopForUI() { 66 content::RunAllPendingInMessageLoop(); 67 } 68 69 TestingProfileManager profile_manager_; 70 BookmarkModel* bookmark_model_; 71 base::MessageLoopForUI message_loop_; 72 content::TestBrowserThread ui_thread_; 73 content::TestBrowserThread file_thread_; 74 base::ScopedTempDir temp_dir_; 75 HistoryDatabase history_db_; 76 }; 77 78 TEST_F(BookmarkModelSQLHandlerTest, InsertIntoMobileFolder) { 79 HistoryAndBookmarkRow row; 80 row.set_raw_url("http://bookmark.com"); 81 row.set_url(GURL("http://bookmark.com")); 82 row.set_title(UTF8ToUTF16("Bookmark Title")); 83 row.set_is_bookmark(true); 84 85 BookmarkModelSQLHandler handler(&history_db_); 86 ASSERT_TRUE(handler.Insert(&row)); 87 RunMessageLoopForUI(); 88 std::vector<const BookmarkNode*> nodes; 89 bookmark_model_->GetNodesByURL(row.url(), &nodes); 90 ASSERT_EQ(1u, nodes.size()); 91 EXPECT_EQ(row.title(), nodes[0]->GetTitle()); 92 const BookmarkNode* parent = nodes[0]->parent(); 93 ASSERT_TRUE(parent); 94 EXPECT_EQ(bookmark_model_->mobile_node()->id(), parent->id()); 95 } 96 97 TEST_F(BookmarkModelSQLHandlerTest, InsertIntoSpecificFolder) { 98 HistoryAndBookmarkRow row; 99 row.set_raw_url("http://bookmark.com"); 100 row.set_url(GURL("http://bookmark.com")); 101 row.set_title(UTF8ToUTF16("Bookmark Title")); 102 row.set_is_bookmark(true); 103 // Set other folder as parent. 104 row.set_parent_id(bookmark_model_->other_node()->id()); 105 106 BookmarkModelSQLHandler handler(&history_db_); 107 ASSERT_TRUE(handler.Insert(&row)); 108 RunMessageLoopForUI(); 109 std::vector<const BookmarkNode*> nodes; 110 bookmark_model_->GetNodesByURL(row.url(), &nodes); 111 ASSERT_EQ(1u, nodes.size()); 112 EXPECT_EQ(row.title(), nodes[0]->GetTitle()); 113 const BookmarkNode* parent = nodes[0]->parent(); 114 ASSERT_TRUE(parent); 115 EXPECT_EQ(row.parent_id(), parent->id()); 116 } 117 118 TEST_F(BookmarkModelSQLHandlerTest, UpdateHistoryToBookmark) { 119 // Added a row in url database. 120 URLRow url_row(GURL("http://www.google.com")); 121 url_row.set_title(UTF8ToUTF16("Google")); 122 URLID url_id = history_db_.AddURL(url_row); 123 ASSERT_TRUE(url_id); 124 125 // Update the added row as bookmark. 126 HistoryAndBookmarkRow row; 127 row.set_url(url_row.url()); 128 row.set_is_bookmark(true); 129 130 TableIDRow id_row; 131 id_row.url_id = url_id; 132 id_row.url = url_row.url(); 133 TableIDRows id_rows; 134 id_rows.push_back(id_row); 135 136 BookmarkModelSQLHandler handler(&history_db_); 137 ASSERT_TRUE(handler.Update(row, id_rows)); 138 RunMessageLoopForUI(); 139 // Get all bookmarks and verify there is only one. 140 std::vector<BookmarkService::URLAndTitle> bookmarks; 141 bookmark_model_->GetBookmarks(&bookmarks); 142 ASSERT_EQ(1u, bookmarks.size()); 143 EXPECT_EQ(url_row.url(), bookmarks[0].url); 144 EXPECT_EQ(url_row.title(), bookmarks[0].title); 145 146 // Get the bookmark node. 147 std::vector<const BookmarkNode*> nodes; 148 bookmark_model_->GetNodesByURL(row.url(), &nodes); 149 ASSERT_EQ(1u, nodes.size()); 150 EXPECT_EQ(url_row.title(), nodes[0]->GetTitle()); 151 const BookmarkNode* parent = nodes[0]->parent(); 152 ASSERT_TRUE(parent); 153 EXPECT_EQ(bookmark_model_->mobile_node()->id(), parent->id()); 154 155 // Remove the bookmark 156 row.set_is_bookmark(false); 157 ASSERT_TRUE(handler.Update(row, id_rows)); 158 RunMessageLoopForUI(); 159 bookmarks.clear(); 160 bookmark_model_->GetBookmarks(&bookmarks); 161 EXPECT_TRUE(bookmarks.empty()); 162 163 // Update with the parent id. 164 row.set_parent_id(bookmark_model_->other_node()->id()); 165 row.set_is_bookmark(true); 166 ASSERT_TRUE(handler.Update(row, id_rows)); 167 RunMessageLoopForUI(); 168 // Get all bookmarks and verify there is only one. 169 bookmarks.clear(); 170 bookmark_model_->GetBookmarks(&bookmarks); 171 ASSERT_EQ(1u, bookmarks.size()); 172 EXPECT_EQ(url_row.url(), bookmarks[0].url); 173 EXPECT_EQ(url_row.title(), bookmarks[0].title); 174 // Get the bookmark node. 175 nodes.clear(); 176 bookmark_model_->GetNodesByURL(row.url(), &nodes); 177 ASSERT_EQ(1u, nodes.size()); 178 EXPECT_EQ(url_row.title(), nodes[0]->GetTitle()); 179 const BookmarkNode* parent1 = nodes[0]->parent(); 180 ASSERT_TRUE(parent1); 181 EXPECT_EQ(row.parent_id(), parent1->id()); 182 183 // Only update the title. 184 url_row.set_title(UTF8ToUTF16("Google Inc.")); 185 history_db_.UpdateURLRow(url_id, url_row); 186 HistoryAndBookmarkRow update_title; 187 update_title.set_title(url_row.title()); 188 ASSERT_TRUE(handler.Update(update_title, id_rows)); 189 RunMessageLoopForUI(); 190 // Get all bookmarks and verify there is only one. 191 bookmarks.clear(); 192 bookmark_model_->GetBookmarks(&bookmarks); 193 ASSERT_EQ(1u, bookmarks.size()); 194 EXPECT_EQ(url_row.url(), bookmarks[0].url); 195 EXPECT_EQ(url_row.title(), bookmarks[0].title); 196 // Get the bookmark node. 197 nodes.clear(); 198 bookmark_model_->GetNodesByURL(row.url(), &nodes); 199 ASSERT_EQ(1u, nodes.size()); 200 EXPECT_EQ(url_row.title(), nodes[0]->GetTitle()); 201 const BookmarkNode* parent2 = nodes[0]->parent(); 202 ASSERT_TRUE(parent2); 203 // The parent id shouldn't changed. 204 EXPECT_EQ(row.parent_id(), parent2->id()); 205 } 206 207 TEST_F(BookmarkModelSQLHandlerTest, Delete) { 208 // Insert 3 bookmarks, 2 of them have the same URL, but one is in mobile 209 // folder, another is in other folder, The 3rd one has different URL. 210 HistoryAndBookmarkRow row; 211 GURL url1 = GURL("http://bookmark.com"); 212 row.set_raw_url("http://bookmark.com"); 213 row.set_url(url1); 214 row.set_title(UTF8ToUTF16("Bookmark Title")); 215 row.set_is_bookmark(true); 216 217 BookmarkModelSQLHandler handler(&history_db_); 218 ASSERT_TRUE(handler.Insert(&row)); 219 220 // Set other folder as parent. 221 row.set_parent_id(bookmark_model_->other_node()->id()); 222 ASSERT_TRUE(handler.Insert(&row)); 223 224 row.set_url(GURL("http://google.com")); 225 ASSERT_TRUE(handler.Insert(&row)); 226 RunMessageLoopForUI(); 227 // Get all bookmarks and verify there are 3 bookmarks. 228 EXPECT_EQ(1, bookmark_model_->mobile_node()->child_count()); 229 EXPECT_EQ(2, bookmark_model_->other_node()->child_count()); 230 231 // Remove the third one. 232 TableIDRow id_row; 233 id_row.url = row.url(); 234 TableIDRows id_rows; 235 id_rows.push_back(id_row); 236 237 ASSERT_TRUE(handler.Delete(id_rows)); 238 RunMessageLoopForUI(); 239 // Verify the first 2 bookmarks still exist. 240 EXPECT_EQ(1, bookmark_model_->mobile_node()->child_count()); 241 EXPECT_EQ(1, bookmark_model_->other_node()->child_count()); 242 243 id_row.url = url1; 244 id_rows.clear(); 245 id_rows.push_back(id_row); 246 ASSERT_TRUE(handler.Delete(id_rows)); 247 RunMessageLoopForUI(); 248 // All bookmarks were deleted. 249 EXPECT_FALSE(bookmark_model_->HasBookmarks()); 250 } 251 252 } // namespace history 253