| 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 "base/file_path.h" | |
| 6 #include "base/file_util.h" | |
| 7 #include "base/path_service.h" | |
| 8 #include "base/scoped_temp_dir.h" | |
| 9 #include "base/string_util.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "chrome/browser/history/url_database.h" | |
| 12 #include "sql/connection.h" | |
| 13 #include "testing/gtest/include/gtest/gtest.h" | |
| 14 | |
| 15 using base::Time; | |
| 16 using base::TimeDelta; | |
| 17 | |
| 18 namespace history { | |
| 19 | |
| 20 namespace { | |
| 21 | |
| 22 bool IsURLRowEqual(const URLRow& a, | |
| 23 const URLRow& b) { | |
| 24 // TODO(brettw) when the database stores an actual Time value rather than | |
| 25 // a time_t, do a reaul comparison. Instead, we have to do a more rough | |
| 26 // comparison since the conversion reduces the precision. | |
| 27 return a.title() == b.title() && | |
| 28 a.visit_count() == b.visit_count() && | |
| 29 a.typed_count() == b.typed_count() && | |
| 30 a.last_visit() - b.last_visit() <= TimeDelta::FromSeconds(1) && | |
| 31 a.hidden() == b.hidden(); | |
| 32 } | |
| 33 | |
| 34 } // namespace | |
| 35 | |
| 36 class URLDatabaseTest : public testing::Test, | |
| 37 public URLDatabase { | |
| 38 public: | |
| 39 URLDatabaseTest() { | |
| 40 } | |
| 41 | |
| 42 protected: | |
| 43 // Provided for URL/VisitDatabase. | |
| 44 virtual sql::Connection& GetDB() { | |
| 45 return db_; | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 // Test setup. | |
| 50 void SetUp() { | |
| 51 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
| 52 FilePath db_file = temp_dir_.path().AppendASCII("URLTest.db"); | |
| 53 | |
| 54 EXPECT_TRUE(db_.Open(db_file)); | |
| 55 | |
| 56 // Initialize the tables for this test. | |
| 57 CreateURLTable(false); | |
| 58 CreateMainURLIndex(); | |
| 59 InitKeywordSearchTermsTable(); | |
| 60 CreateKeywordSearchTermsIndices(); | |
| 61 } | |
| 62 void TearDown() { | |
| 63 db_.Close(); | |
| 64 } | |
| 65 | |
| 66 ScopedTempDir temp_dir_; | |
| 67 sql::Connection db_; | |
| 68 }; | |
| 69 | |
| 70 // Test add and query for the URL table in the HistoryDatabase. | |
| 71 TEST_F(URLDatabaseTest, AddURL) { | |
| 72 // First, add two URLs. | |
| 73 const GURL url1("http://www.google.com/"); | |
| 74 URLRow url_info1(url1); | |
| 75 url_info1.set_title(UTF8ToUTF16("Google")); | |
| 76 url_info1.set_visit_count(4); | |
| 77 url_info1.set_typed_count(2); | |
| 78 url_info1.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 79 url_info1.set_hidden(false); | |
| 80 EXPECT_TRUE(AddURL(url_info1)); | |
| 81 | |
| 82 const GURL url2("http://mail.google.com/"); | |
| 83 URLRow url_info2(url2); | |
| 84 url_info2.set_title(UTF8ToUTF16("Google Mail")); | |
| 85 url_info2.set_visit_count(3); | |
| 86 url_info2.set_typed_count(0); | |
| 87 url_info2.set_last_visit(Time::Now() - TimeDelta::FromDays(2)); | |
| 88 url_info2.set_hidden(true); | |
| 89 EXPECT_TRUE(AddURL(url_info2)); | |
| 90 | |
| 91 // Query both of them. | |
| 92 URLRow info; | |
| 93 EXPECT_TRUE(GetRowForURL(url1, &info)); | |
| 94 EXPECT_TRUE(IsURLRowEqual(url_info1, info)); | |
| 95 URLID id2 = GetRowForURL(url2, &info); | |
| 96 EXPECT_TRUE(id2); | |
| 97 EXPECT_TRUE(IsURLRowEqual(url_info2, info)); | |
| 98 | |
| 99 // Update the second. | |
| 100 url_info2.set_title(UTF8ToUTF16("Google Mail Too")); | |
| 101 url_info2.set_visit_count(4); | |
| 102 url_info2.set_typed_count(1); | |
| 103 url_info2.set_typed_count(91011); | |
| 104 url_info2.set_hidden(false); | |
| 105 EXPECT_TRUE(UpdateURLRow(id2, url_info2)); | |
| 106 | |
| 107 // Make sure it got updated. | |
| 108 URLRow info2; | |
| 109 EXPECT_TRUE(GetRowForURL(url2, &info2)); | |
| 110 EXPECT_TRUE(IsURLRowEqual(url_info2, info2)); | |
| 111 | |
| 112 // Query a nonexistent URL. | |
| 113 EXPECT_EQ(0, GetRowForURL(GURL("http://news.google.com/"), &info)); | |
| 114 | |
| 115 // Delete all urls in the domain. | |
| 116 // TODO(acw): test the new url based delete domain | |
| 117 // EXPECT_TRUE(db.DeleteDomain(kDomainID)); | |
| 118 | |
| 119 // Make sure the urls have been properly removed. | |
| 120 // TODO(acw): commented out because remove no longer works. | |
| 121 // EXPECT_TRUE(db.GetURLInfo(url1, NULL) == NULL); | |
| 122 // EXPECT_TRUE(db.GetURLInfo(url2, NULL) == NULL); | |
| 123 } | |
| 124 | |
| 125 // Tests adding, querying and deleting keyword visits. | |
| 126 TEST_F(URLDatabaseTest, KeywordSearchTermVisit) { | |
| 127 URLRow url_info1(GURL("http://www.google.com/")); | |
| 128 url_info1.set_title(UTF8ToUTF16("Google")); | |
| 129 url_info1.set_visit_count(4); | |
| 130 url_info1.set_typed_count(2); | |
| 131 url_info1.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 132 url_info1.set_hidden(false); | |
| 133 URLID url_id = AddURL(url_info1); | |
| 134 ASSERT_TRUE(url_id != 0); | |
| 135 | |
| 136 // Add a keyword visit. | |
| 137 TemplateURLID keyword_id = 100; | |
| 138 string16 keyword = UTF8ToUTF16("visit"); | |
| 139 ASSERT_TRUE(SetKeywordSearchTermsForURL(url_id, keyword_id, keyword)); | |
| 140 | |
| 141 // Make sure we get it back. | |
| 142 std::vector<KeywordSearchTermVisit> matches; | |
| 143 GetMostRecentKeywordSearchTerms(keyword_id, keyword, 10, &matches); | |
| 144 ASSERT_EQ(1U, matches.size()); | |
| 145 ASSERT_EQ(keyword, matches[0].term); | |
| 146 | |
| 147 KeywordSearchTermRow keyword_search_term_row; | |
| 148 ASSERT_TRUE(GetKeywordSearchTermRow(url_id, &keyword_search_term_row)); | |
| 149 EXPECT_EQ(keyword_id, keyword_search_term_row.keyword_id); | |
| 150 EXPECT_EQ(url_id, keyword_search_term_row.url_id); | |
| 151 EXPECT_EQ(keyword, keyword_search_term_row.term); | |
| 152 | |
| 153 // Delete the keyword visit. | |
| 154 DeleteAllSearchTermsForKeyword(keyword_id); | |
| 155 | |
| 156 // Make sure we don't get it back when querying. | |
| 157 matches.clear(); | |
| 158 GetMostRecentKeywordSearchTerms(keyword_id, keyword, 10, &matches); | |
| 159 ASSERT_EQ(0U, matches.size()); | |
| 160 | |
| 161 ASSERT_FALSE(GetKeywordSearchTermRow(url_id, &keyword_search_term_row)); | |
| 162 } | |
| 163 | |
| 164 // Make sure deleting a URL also deletes a keyword visit. | |
| 165 TEST_F(URLDatabaseTest, DeleteURLDeletesKeywordSearchTermVisit) { | |
| 166 URLRow url_info1(GURL("http://www.google.com/")); | |
| 167 url_info1.set_title(UTF8ToUTF16("Google")); | |
| 168 url_info1.set_visit_count(4); | |
| 169 url_info1.set_typed_count(2); | |
| 170 url_info1.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 171 url_info1.set_hidden(false); | |
| 172 URLID url_id = AddURL(url_info1); | |
| 173 ASSERT_TRUE(url_id != 0); | |
| 174 | |
| 175 // Add a keyword visit. | |
| 176 ASSERT_TRUE(SetKeywordSearchTermsForURL(url_id, 1, UTF8ToUTF16("visit"))); | |
| 177 | |
| 178 // Delete the url. | |
| 179 ASSERT_TRUE(DeleteURLRow(url_id)); | |
| 180 | |
| 181 // Make sure the keyword visit was deleted. | |
| 182 std::vector<KeywordSearchTermVisit> matches; | |
| 183 GetMostRecentKeywordSearchTerms(1, UTF8ToUTF16("visit"), 10, &matches); | |
| 184 ASSERT_EQ(0U, matches.size()); | |
| 185 } | |
| 186 | |
| 187 TEST_F(URLDatabaseTest, EnumeratorForSignificant) { | |
| 188 std::set<std::string> good_urls; | |
| 189 // Add URLs which do and don't meet the criteria. | |
| 190 URLRow url_no_match(GURL("http://www.url_no_match.com/")); | |
| 191 EXPECT_TRUE(AddURL(url_no_match)); | |
| 192 | |
| 193 std::string url_string2("http://www.url_match_visit_count.com/"); | |
| 194 good_urls.insert("http://www.url_match_visit_count.com/"); | |
| 195 URLRow url_match_visit_count(GURL("http://www.url_match_visit_count.com/")); | |
| 196 url_match_visit_count.set_visit_count(kLowQualityMatchVisitLimit); | |
| 197 EXPECT_TRUE(AddURL(url_match_visit_count)); | |
| 198 | |
| 199 good_urls.insert("http://www.url_match_typed_count.com/"); | |
| 200 URLRow url_match_typed_count(GURL("http://www.url_match_typed_count.com/")); | |
| 201 url_match_typed_count.set_typed_count(kLowQualityMatchTypedLimit); | |
| 202 EXPECT_TRUE(AddURL(url_match_typed_count)); | |
| 203 | |
| 204 good_urls.insert("http://www.url_match_last_visit.com/"); | |
| 205 URLRow url_match_last_visit(GURL("http://www.url_match_last_visit.com/")); | |
| 206 url_match_last_visit.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 207 EXPECT_TRUE(AddURL(url_match_last_visit)); | |
| 208 | |
| 209 URLRow url_no_match_last_visit(GURL( | |
| 210 "http://www.url_no_match_last_visit.com/")); | |
| 211 url_no_match_last_visit.set_last_visit(Time::Now() - | |
| 212 TimeDelta::FromDays(kLowQualityMatchAgeLimitInDays + 1)); | |
| 213 EXPECT_TRUE(AddURL(url_no_match_last_visit)); | |
| 214 | |
| 215 URLDatabase::URLEnumerator history_enum; | |
| 216 EXPECT_TRUE(InitURLEnumeratorForSignificant(&history_enum)); | |
| 217 URLRow row; | |
| 218 int row_count = 0; | |
| 219 for (; history_enum.GetNextURL(&row); ++row_count) | |
| 220 EXPECT_EQ(1U, good_urls.count(row.url().spec())); | |
| 221 EXPECT_EQ(3, row_count); | |
| 222 } | |
| 223 | |
| 224 TEST_F(URLDatabaseTest, IconMappingEnumerator) { | |
| 225 const GURL url1("http://www.google.com/"); | |
| 226 URLRow url_info1(url1); | |
| 227 url_info1.set_title(UTF8ToUTF16("Google")); | |
| 228 url_info1.set_visit_count(4); | |
| 229 url_info1.set_typed_count(2); | |
| 230 url_info1.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 231 url_info1.set_hidden(false); | |
| 232 | |
| 233 // Insert a row with favicon | |
| 234 URLID url_id1 = AddURL(url_info1); | |
| 235 ASSERT_TRUE(url_id1 != 0); | |
| 236 | |
| 237 FaviconID icon_id = 1; | |
| 238 sql::Statement statement(GetDB().GetCachedStatement( | |
| 239 SQL_FROM_HERE, | |
| 240 "UPDATE urls SET favicon_id =? WHERE id=?")); | |
| 241 | |
| 242 ASSERT_TRUE(statement.is_valid()); | |
| 243 | |
| 244 statement.BindInt64(0, icon_id); | |
| 245 statement.BindInt64(1, url_id1); | |
| 246 ASSERT_TRUE(statement.Run()); | |
| 247 | |
| 248 // Insert another row without favicon | |
| 249 const GURL url2("http://www.google.com/no_icon"); | |
| 250 URLRow url_info2(url2); | |
| 251 url_info2.set_title(UTF8ToUTF16("Google")); | |
| 252 url_info2.set_visit_count(4); | |
| 253 url_info2.set_typed_count(2); | |
| 254 url_info2.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 255 url_info2.set_hidden(false); | |
| 256 | |
| 257 // Insert a row with favicon | |
| 258 URLID url_id2 = AddURL(url_info2); | |
| 259 ASSERT_TRUE(url_id2 != 0); | |
| 260 | |
| 261 IconMappingEnumerator e; | |
| 262 InitIconMappingEnumeratorForEverything(&e); | |
| 263 IconMapping icon_mapping; | |
| 264 ASSERT_TRUE(e.GetNextIconMapping(&icon_mapping)); | |
| 265 ASSERT_EQ(url1, icon_mapping.page_url); | |
| 266 ASSERT_EQ(icon_id, icon_mapping.icon_id); | |
| 267 ASSERT_FALSE(e.GetNextIconMapping(&icon_mapping)); | |
| 268 } | |
| 269 | |
| 270 // Test GetKeywordSearchTermRows and DeleteSearchTerm | |
| 271 TEST_F(URLDatabaseTest, GetAndDeleteKeywordSearchTermByTerm) { | |
| 272 URLRow url_info1(GURL("http://www.google.com/")); | |
| 273 url_info1.set_title(UTF8ToUTF16("Google")); | |
| 274 url_info1.set_visit_count(4); | |
| 275 url_info1.set_typed_count(2); | |
| 276 url_info1.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 277 url_info1.set_hidden(false); | |
| 278 URLID url_id1 = AddURL(url_info1); | |
| 279 ASSERT_NE(0, url_id1); | |
| 280 | |
| 281 // Add a keyword visit. | |
| 282 TemplateURLID keyword_id = 100; | |
| 283 string16 keyword = UTF8ToUTF16("visit"); | |
| 284 ASSERT_TRUE(SetKeywordSearchTermsForURL(url_id1, keyword_id, keyword)); | |
| 285 | |
| 286 URLRow url_info2(GURL("https://www.google.com/")); | |
| 287 url_info2.set_title(UTF8ToUTF16("Google")); | |
| 288 url_info2.set_visit_count(4); | |
| 289 url_info2.set_typed_count(2); | |
| 290 url_info2.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 291 url_info2.set_hidden(false); | |
| 292 URLID url_id2 = AddURL(url_info2); | |
| 293 ASSERT_NE(0, url_id2); | |
| 294 // Add the same keyword for url_info2. | |
| 295 ASSERT_TRUE(SetKeywordSearchTermsForURL(url_id2, keyword_id, keyword)); | |
| 296 | |
| 297 // Add another URL for different keyword. | |
| 298 URLRow url_info3(GURL("https://www.google.com/search")); | |
| 299 url_info3.set_title(UTF8ToUTF16("Google")); | |
| 300 url_info3.set_visit_count(4); | |
| 301 url_info3.set_typed_count(2); | |
| 302 url_info3.set_last_visit(Time::Now() - TimeDelta::FromDays(1)); | |
| 303 url_info3.set_hidden(false); | |
| 304 URLID url_id3 = AddURL(url_info3); | |
| 305 ASSERT_NE(0, url_id3); | |
| 306 string16 keyword2 = UTF8ToUTF16("Search"); | |
| 307 | |
| 308 ASSERT_TRUE(SetKeywordSearchTermsForURL(url_id3, keyword_id, keyword2)); | |
| 309 | |
| 310 // We should get 2 rows for |keyword|. | |
| 311 std::vector<KeywordSearchTermRow> rows; | |
| 312 ASSERT_TRUE(GetKeywordSearchTermRows(keyword, &rows)); | |
| 313 ASSERT_EQ(2u, rows.size()); | |
| 314 if (rows[0].url_id == url_id1) { | |
| 315 EXPECT_EQ(keyword, rows[0].term); | |
| 316 EXPECT_EQ(keyword, rows[1].term); | |
| 317 EXPECT_EQ(url_id2, rows[1].url_id); | |
| 318 } else { | |
| 319 EXPECT_EQ(keyword, rows[0].term); | |
| 320 EXPECT_EQ(url_id1, rows[1].url_id); | |
| 321 EXPECT_EQ(keyword, rows[1].term); | |
| 322 EXPECT_EQ(url_id2, rows[0].url_id); | |
| 323 } | |
| 324 | |
| 325 // We should get 1 row for |keyword2|. | |
| 326 rows.clear(); | |
| 327 ASSERT_TRUE(GetKeywordSearchTermRows(keyword2, &rows)); | |
| 328 ASSERT_EQ(1u, rows.size()); | |
| 329 EXPECT_EQ(keyword2, rows[0].term); | |
| 330 EXPECT_EQ(url_id3, rows[0].url_id); | |
| 331 | |
| 332 // Delete all rows have keyword. | |
| 333 ASSERT_TRUE(DeleteKeywordSearchTerm(keyword)); | |
| 334 rows.clear(); | |
| 335 // We should still find keyword2. | |
| 336 ASSERT_TRUE(GetKeywordSearchTermRows(keyword2, &rows)); | |
| 337 ASSERT_EQ(1u, rows.size()); | |
| 338 EXPECT_EQ(keyword2, rows[0].term); | |
| 339 EXPECT_EQ(url_id3, rows[0].url_id); | |
| 340 rows.clear(); | |
| 341 // No row for keyword. | |
| 342 ASSERT_TRUE(GetKeywordSearchTermRows(keyword, &rows)); | |
| 343 EXPECT_TRUE(rows.empty()); | |
| 344 } | |
| 345 | |
| 346 } // namespace history | |
| OLD | NEW |