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