OLD | NEW |
| (Empty) |
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 "components/omnibox/browser/shortcuts_database.h" | |
6 | |
7 #include "base/files/scoped_temp_dir.h" | |
8 #include "base/format_macros.h" | |
9 #include "base/path_service.h" | |
10 #include "base/strings/stringprintf.h" | |
11 #include "base/strings/utf_string_conversions.h" | |
12 #include "base/time/time.h" | |
13 #include "chrome/common/chrome_paths.h" | |
14 #include "chrome/test/base/testing_profile.h" | |
15 #include "components/omnibox/browser/autocomplete_match_type.h" | |
16 #include "components/omnibox/browser/shortcuts_constants.h" | |
17 #include "content/public/test/test_browser_thread_bundle.h" | |
18 #include "sql/statement.h" | |
19 #include "sql/test/test_helpers.h" | |
20 #include "testing/gtest/include/gtest/gtest.h" | |
21 #include "ui/base/page_transition_types.h" | |
22 | |
23 using base::ASCIIToUTF16; | |
24 | |
25 // Helpers -------------------------------------------------------------------- | |
26 | |
27 namespace { | |
28 | |
29 struct ShortcutsDatabaseTestInfo { | |
30 std::string guid; | |
31 std::string text; | |
32 std::string fill_into_edit; | |
33 std::string destination_url; | |
34 std::string contents; | |
35 std::string contents_class; | |
36 std::string description; | |
37 std::string description_class; | |
38 ui::PageTransition transition; | |
39 AutocompleteMatchType::Type type; | |
40 std::string keyword; | |
41 int days_from_now; | |
42 int number_of_hits; | |
43 } shortcut_test_db[] = { | |
44 { "BD85DBA2-8C29-49F9-84AE-48E1E90880DF", "goog", "www.google.com", | |
45 "http://www.google.com/", "Google", "0,1,4,0", "Google", "0,1", | |
46 ui::PAGE_TRANSITION_GENERATED, AutocompleteMatchType::SEARCH_HISTORY, | |
47 "google.com", 1, 100, }, | |
48 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E0", "slash", "slashdot.org", | |
49 "http://slashdot.org/", "slashdot.org", "0,1", | |
50 "Slashdot - News for nerds, stuff that matters", "0,0", | |
51 ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::HISTORY_URL, "", 0, | |
52 100}, | |
53 { "BD85DBA2-8C29-49F9-84AE-48E1E90880E1", "news", "slashdot.org", | |
54 "http://slashdot.org/", "slashdot.org", "0,1", | |
55 "Slashdot - News for nerds, stuff that matters", "0,0", | |
56 ui::PAGE_TRANSITION_LINK, AutocompleteMatchType::HISTORY_TITLE, "", 0, | |
57 5}, | |
58 }; | |
59 | |
60 typedef testing::Test ShortcutsDatabaseMigrationTest; | |
61 | |
62 // Checks that the database at |db| has the version 2 columns iff |is_v2|. | |
63 void CheckV2ColumnExistence(const base::FilePath& db_path, bool is_v2) { | |
64 sql::Connection connection; | |
65 ASSERT_TRUE(connection.Open(db_path)); | |
66 EXPECT_EQ(is_v2, connection.DoesColumnExist("omni_box_shortcuts", | |
67 "fill_into_edit")); | |
68 EXPECT_EQ(is_v2, connection.DoesColumnExist("omni_box_shortcuts", | |
69 "transition")); | |
70 EXPECT_EQ(is_v2, connection.DoesColumnExist("omni_box_shortcuts", "type")); | |
71 EXPECT_EQ(is_v2, connection.DoesColumnExist("omni_box_shortcuts", "keyword")); | |
72 } | |
73 | |
74 } // namespace | |
75 | |
76 // ShortcutsDatabaseTest ------------------------------------------------------ | |
77 | |
78 class ShortcutsDatabaseTest : public testing::Test { | |
79 public: | |
80 void SetUp() override; | |
81 void TearDown() override; | |
82 | |
83 void ClearDB(); | |
84 size_t CountRecords() const; | |
85 | |
86 ShortcutsDatabase::Shortcut ShortcutFromTestInfo( | |
87 const ShortcutsDatabaseTestInfo& info); | |
88 | |
89 void AddAll(); | |
90 | |
91 content::TestBrowserThreadBundle thread_bundle_; | |
92 scoped_ptr<TestingProfile> profile_; | |
93 scoped_refptr<ShortcutsDatabase> db_; | |
94 }; | |
95 | |
96 void ShortcutsDatabaseTest::SetUp() { | |
97 profile_.reset(new TestingProfile()); | |
98 db_ = new ShortcutsDatabase( | |
99 profile_->GetPath().Append(kShortcutsDatabaseName)); | |
100 ASSERT_TRUE(db_->Init()); | |
101 ClearDB(); | |
102 } | |
103 | |
104 void ShortcutsDatabaseTest::TearDown() { | |
105 db_ = NULL; | |
106 } | |
107 | |
108 void ShortcutsDatabaseTest::ClearDB() { | |
109 sql::Statement | |
110 s(db_->db_.GetUniqueStatement("DELETE FROM omni_box_shortcuts")); | |
111 EXPECT_TRUE(s.Run()); | |
112 } | |
113 | |
114 size_t ShortcutsDatabaseTest::CountRecords() const { | |
115 sql::Statement s(db_->db_.GetUniqueStatement( | |
116 "SELECT count(*) FROM omni_box_shortcuts")); | |
117 EXPECT_TRUE(s.Step()); | |
118 return static_cast<size_t>(s.ColumnInt(0)); | |
119 } | |
120 | |
121 ShortcutsDatabase::Shortcut ShortcutsDatabaseTest::ShortcutFromTestInfo( | |
122 const ShortcutsDatabaseTestInfo& info) { | |
123 return ShortcutsDatabase::Shortcut( | |
124 info.guid, ASCIIToUTF16(info.text), | |
125 ShortcutsDatabase::Shortcut::MatchCore( | |
126 ASCIIToUTF16(info.fill_into_edit), GURL(info.destination_url), | |
127 ASCIIToUTF16(info.contents), info.contents_class, | |
128 ASCIIToUTF16(info.description), info.description_class, | |
129 info.transition, info.type, ASCIIToUTF16(info.keyword)), | |
130 base::Time::Now() - base::TimeDelta::FromDays(info.days_from_now), | |
131 info.number_of_hits); | |
132 } | |
133 | |
134 void ShortcutsDatabaseTest::AddAll() { | |
135 ClearDB(); | |
136 for (size_t i = 0; i < arraysize(shortcut_test_db); ++i) | |
137 db_->AddShortcut(ShortcutFromTestInfo(shortcut_test_db[i])); | |
138 EXPECT_EQ(arraysize(shortcut_test_db), CountRecords()); | |
139 } | |
140 | |
141 | |
142 // Actual tests --------------------------------------------------------------- | |
143 | |
144 TEST_F(ShortcutsDatabaseTest, AddShortcut) { | |
145 ClearDB(); | |
146 EXPECT_EQ(0U, CountRecords()); | |
147 EXPECT_TRUE(db_->AddShortcut(ShortcutFromTestInfo(shortcut_test_db[0]))); | |
148 EXPECT_EQ(1U, CountRecords()); | |
149 EXPECT_TRUE(db_->AddShortcut(ShortcutFromTestInfo(shortcut_test_db[1]))); | |
150 EXPECT_EQ(2U, CountRecords()); | |
151 EXPECT_TRUE(db_->AddShortcut(ShortcutFromTestInfo(shortcut_test_db[2]))); | |
152 EXPECT_EQ(3U, CountRecords()); | |
153 } | |
154 | |
155 TEST_F(ShortcutsDatabaseTest, UpdateShortcut) { | |
156 AddAll(); | |
157 ShortcutsDatabase::Shortcut shortcut( | |
158 ShortcutFromTestInfo(shortcut_test_db[1])); | |
159 shortcut.match_core.contents = ASCIIToUTF16("gro.todhsals"); | |
160 EXPECT_TRUE(db_->UpdateShortcut(shortcut)); | |
161 ShortcutsDatabase::GuidToShortcutMap shortcuts; | |
162 db_->LoadShortcuts(&shortcuts); | |
163 ShortcutsDatabase::GuidToShortcutMap::const_iterator it( | |
164 shortcuts.find(shortcut.id)); | |
165 EXPECT_TRUE(it != shortcuts.end()); | |
166 EXPECT_TRUE(it->second.match_core.contents == shortcut.match_core.contents); | |
167 } | |
168 | |
169 TEST_F(ShortcutsDatabaseTest, DeleteShortcutsWithIds) { | |
170 AddAll(); | |
171 std::vector<std::string> shortcut_ids; | |
172 shortcut_ids.push_back(shortcut_test_db[0].guid); | |
173 shortcut_ids.push_back(shortcut_test_db[2].guid); | |
174 EXPECT_TRUE(db_->DeleteShortcutsWithIDs(shortcut_ids)); | |
175 EXPECT_EQ(arraysize(shortcut_test_db) - 2, CountRecords()); | |
176 | |
177 ShortcutsDatabase::GuidToShortcutMap shortcuts; | |
178 db_->LoadShortcuts(&shortcuts); | |
179 | |
180 ShortcutsDatabase::GuidToShortcutMap::iterator it = | |
181 shortcuts.find(shortcut_test_db[0].guid); | |
182 EXPECT_TRUE(it == shortcuts.end()); | |
183 | |
184 it = shortcuts.find(shortcut_test_db[1].guid); | |
185 EXPECT_TRUE(it != shortcuts.end()); | |
186 | |
187 it = shortcuts.find(shortcut_test_db[2].guid); | |
188 EXPECT_TRUE(it == shortcuts.end()); | |
189 } | |
190 | |
191 TEST_F(ShortcutsDatabaseTest, DeleteShortcutsWithURL) { | |
192 AddAll(); | |
193 | |
194 EXPECT_TRUE(db_->DeleteShortcutsWithURL("http://slashdot.org/")); | |
195 EXPECT_EQ(arraysize(shortcut_test_db) - 2, CountRecords()); | |
196 | |
197 ShortcutsDatabase::GuidToShortcutMap shortcuts; | |
198 db_->LoadShortcuts(&shortcuts); | |
199 | |
200 ShortcutsDatabase::GuidToShortcutMap::iterator it = | |
201 shortcuts.find(shortcut_test_db[0].guid); | |
202 EXPECT_TRUE(it != shortcuts.end()); | |
203 | |
204 it = shortcuts.find(shortcut_test_db[1].guid); | |
205 EXPECT_TRUE(it == shortcuts.end()); | |
206 | |
207 it = shortcuts.find(shortcut_test_db[2].guid); | |
208 EXPECT_TRUE(it == shortcuts.end()); | |
209 } | |
210 | |
211 | |
212 TEST_F(ShortcutsDatabaseTest, DeleteAllShortcuts) { | |
213 AddAll(); | |
214 ShortcutsDatabase::GuidToShortcutMap shortcuts; | |
215 db_->LoadShortcuts(&shortcuts); | |
216 EXPECT_EQ(arraysize(shortcut_test_db), shortcuts.size()); | |
217 EXPECT_TRUE(db_->DeleteAllShortcuts()); | |
218 db_->LoadShortcuts(&shortcuts); | |
219 EXPECT_EQ(0U, shortcuts.size()); | |
220 } | |
221 | |
222 TEST(ShortcutsDatabaseMigrationTest, MigrateTableAddFillIntoEdit) { | |
223 // Use the pre-v0 test file to create a test database in a temp dir. | |
224 base::FilePath sql_path; | |
225 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &sql_path)); | |
226 sql_path = sql_path.AppendASCII("History").AppendASCII( | |
227 #if defined(OS_ANDROID) | |
228 "Shortcuts.v1.sql"); | |
229 #else | |
230 "Shortcuts.no_fill_into_edit.sql"); | |
231 #endif | |
232 base::ScopedTempDir temp_dir; | |
233 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
234 base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts1.db")); | |
235 ASSERT_TRUE(sql::test::CreateDatabaseFromSQL(db_path, sql_path)); | |
236 | |
237 CheckV2ColumnExistence(db_path, false); | |
238 | |
239 // Create a ShortcutsDatabase from the test database, which will migrate the | |
240 // test database to the current version. | |
241 { | |
242 scoped_refptr<ShortcutsDatabase> db(new ShortcutsDatabase(db_path)); | |
243 db->Init(); | |
244 } | |
245 | |
246 CheckV2ColumnExistence(db_path, true); | |
247 | |
248 // Check the values in each of the new columns. | |
249 sql::Connection connection; | |
250 ASSERT_TRUE(connection.Open(db_path)); | |
251 sql::Statement statement(connection.GetUniqueStatement( | |
252 "SELECT fill_into_edit, url, transition, type, keyword " | |
253 "FROM omni_box_shortcuts")); | |
254 ASSERT_TRUE(statement.is_valid()); | |
255 while (statement.Step()) { | |
256 // |fill_into_edit| should have been copied from the |url|. | |
257 EXPECT_EQ(statement.ColumnString(1), statement.ColumnString(0)); | |
258 | |
259 // The other three columns have default values. | |
260 EXPECT_EQ(ui::PAGE_TRANSITION_TYPED, | |
261 ui::PageTransitionFromInt(statement.ColumnInt(2))); | |
262 EXPECT_EQ(AutocompleteMatchType::HISTORY_TITLE, | |
263 static_cast<AutocompleteMatchType::Type>(statement.ColumnInt(3))); | |
264 EXPECT_TRUE(statement.ColumnString(4).empty()); | |
265 } | |
266 EXPECT_TRUE(statement.Succeeded()); | |
267 #if !defined(OS_WIN) | |
268 EXPECT_TRUE(temp_dir.Delete()); | |
269 #endif | |
270 } | |
271 | |
272 TEST(ShortcutsDatabaseMigrationTest, MigrateV0ToV1) { | |
273 // Use the v0 test file to create a test database in a temp dir. | |
274 base::FilePath sql_path; | |
275 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &sql_path)); | |
276 sql_path = sql_path.AppendASCII("History").AppendASCII("Shortcuts.v0.sql"); | |
277 base::ScopedTempDir temp_dir; | |
278 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
279 base::FilePath db_path(temp_dir.path().AppendASCII("TestShortcuts2.db")); | |
280 ASSERT_TRUE(sql::test::CreateDatabaseFromSQL(db_path, sql_path)); | |
281 | |
282 // Create a ShortcutsDatabase from the test database, which will migrate the | |
283 // test database to the current version. | |
284 { | |
285 scoped_refptr<ShortcutsDatabase> db(new ShortcutsDatabase(db_path)); | |
286 db->Init(); | |
287 } | |
288 | |
289 // Check that all the old type values got converted to new values. | |
290 sql::Connection connection; | |
291 ASSERT_TRUE(connection.Open(db_path)); | |
292 sql::Statement statement(connection.GetUniqueStatement( | |
293 "SELECT count(1) FROM omni_box_shortcuts WHERE type in (9, 10, 11, 12)")); | |
294 ASSERT_TRUE(statement.is_valid()); | |
295 while (statement.Step()) | |
296 EXPECT_EQ(0, statement.ColumnInt(0)); | |
297 EXPECT_TRUE(statement.Succeeded()); | |
298 #if !defined(OS_WIN) | |
299 EXPECT_TRUE(temp_dir.Delete()); | |
300 #endif | |
301 } | |
OLD | NEW |