Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
| 11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/memory/ref_counted_memory.h" | 13 #include "base/memory/ref_counted_memory.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/strings/stringprintf.h" | |
| 16 #include "build/build_config.h" | |
| 17 #include "components/history/core/browser/history_backend_client.h" | |
|
pkotwicz
2017/07/10 05:23:28
Do you need this include?
jkrcal
2017/07/10 16:14:30
Ah, correct. Thanks!
| |
| 15 #include "components/history/core/browser/thumbnail_database.h" | 18 #include "components/history/core/browser/thumbnail_database.h" |
| 16 #include "components/history/core/test/database_test_utils.h" | 19 #include "components/history/core/test/database_test_utils.h" |
| 17 #include "sql/connection.h" | 20 #include "sql/connection.h" |
| 18 #include "sql/recovery.h" | 21 #include "sql/recovery.h" |
| 19 #include "sql/test/scoped_error_expecter.h" | 22 #include "sql/test/scoped_error_expecter.h" |
| 20 #include "sql/test/test_helpers.h" | 23 #include "sql/test/test_helpers.h" |
| 24 #include "testing/gmock/include/gmock/gmock.h" | |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #include "third_party/sqlite/sqlite3.h" | 26 #include "third_party/sqlite/sqlite3.h" |
| 23 #include "url/gurl.h" | 27 #include "url/gurl.h" |
| 24 | 28 |
| 29 using testing::AllOf; | |
| 30 using testing::ElementsAre; | |
| 31 using testing::Field; | |
| 32 using testing::StrictMock; | |
|
pkotwicz
2017/07/10 05:23:28
Do you need this line?
jkrcal
2017/07/10 16:14:30
Done.
| |
| 33 using testing::Pair; | |
| 34 using testing::Return; | |
| 35 | |
| 25 namespace history { | 36 namespace history { |
| 26 | 37 |
| 27 namespace { | 38 namespace { |
| 28 | 39 |
| 29 // Blobs for the bitmap tests. These aren't real bitmaps. Golden | 40 // Blobs for the bitmap tests. These aren't real bitmaps. Golden |
| 30 // database files store the same blobs (see VersionN tests). | 41 // database files store the same blobs (see VersionN tests). |
| 31 const unsigned char kBlob1[] = | 42 const unsigned char kBlob1[] = |
| 32 "12346102356120394751634516591348710478123649165419234519234512349134"; | 43 "12346102356120394751634516591348710478123649165419234519234512349134"; |
| 33 const unsigned char kBlob2[] = | 44 const unsigned char kBlob2[] = |
| 34 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef"; | 45 "goiwuegrqrcomizqyzkjalitbahxfjytrqvpqeroicxmnlkhlzunacxaneviawrtxcywhgef"; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 } | 173 } |
| 163 | 174 |
| 164 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) { | 175 bool CompareIconMappingIconUrl(const IconMapping& a, const IconMapping& b) { |
| 165 return a.icon_url < b.icon_url; | 176 return a.icon_url < b.icon_url; |
| 166 } | 177 } |
| 167 | 178 |
| 168 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) { | 179 void SortMappingsByIconUrl(std::vector<IconMapping>* mappings) { |
| 169 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl); | 180 std::sort(mappings->begin(), mappings->end(), &CompareIconMappingIconUrl); |
| 170 } | 181 } |
| 171 | 182 |
| 183 class MockHistoryBackendClient : public HistoryBackendClient { | |
| 184 public: | |
| 185 // MOCK_METHOD0(~HistoryBackendClient, void()); | |
| 186 MOCK_METHOD1(IsBookmarked, bool(const GURL& url)); | |
| 187 MOCK_METHOD1(GetBookmarks, void(std::vector<URLAndTitle>* bookmarks)); | |
| 188 MOCK_METHOD0(ShouldReportDatabaseError, bool()); | |
| 189 MOCK_METHOD1(IsWebSafe, bool(const GURL& url)); | |
| 190 | |
| 191 #if defined(OS_ANDROID) | |
| 192 MOCK_METHOD4(OnHistoryBackendInitialized, | |
| 193 void(HistoryBackend* history_backend, | |
| 194 HistoryDatabase* history_database, | |
| 195 ThumbnailDatabase* thumbnail_database, | |
| 196 const base::FilePath& history_dir)); | |
| 197 MOCK_METHOD2(OnHistoryBackendDestroyed, | |
| 198 void(HistoryBackend* history_backend, | |
| 199 const base::FilePath& history_dir)); | |
| 200 #endif // defined(OS_ANDROID) | |
| 201 }; | |
| 202 | |
| 172 } // namespace | 203 } // namespace |
| 173 | 204 |
| 174 class ThumbnailDatabaseTest : public testing::Test { | 205 class ThumbnailDatabaseTest : public testing::Test { |
| 175 public: | 206 public: |
| 176 ThumbnailDatabaseTest() {} | 207 ThumbnailDatabaseTest() {} |
| 177 ~ThumbnailDatabaseTest() override {} | 208 ~ThumbnailDatabaseTest() override {} |
| 178 | 209 |
| 179 // Initialize a thumbnail database instance from the SQL file at | 210 // Initialize a thumbnail database instance from the SQL file at |
| 180 // |golden_path| in the "History/" subdirectory of test data. | 211 // |golden_path| in the "History/" subdirectory of test data. |
| 181 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) { | 212 std::unique_ptr<ThumbnailDatabase> LoadFromGolden(const char* golden_path) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 db.TouchOnDemandFavicon(url, end); | 391 db.TouchOnDemandFavicon(url, end); |
| 361 | 392 |
| 362 base::Time last_updated; | 393 base::Time last_updated; |
| 363 base::Time last_requested; | 394 base::Time last_requested; |
| 364 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested, | 395 EXPECT_TRUE(db.GetFaviconBitmap(bitmap, &last_updated, &last_requested, |
| 365 nullptr, nullptr)); | 396 nullptr, nullptr)); |
| 366 EXPECT_EQ(start, last_updated); // Does not mess with last_updated. | 397 EXPECT_EQ(start, last_updated); // Does not mess with last_updated. |
| 367 EXPECT_EQ(base::Time(), last_requested); // No update. | 398 EXPECT_EQ(base::Time(), last_requested); // No update. |
| 368 } | 399 } |
| 369 | 400 |
| 401 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() returns on-demand icons | |
| 402 // which were requested prior to the passed in timestamp. | |
| 403 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsReturnsOld) { | |
| 404 ThumbnailDatabase db(nullptr); | |
| 405 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | |
| 406 db.BeginTransaction(); | |
| 407 | |
| 408 base::Time start; | |
| 409 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start)); | |
| 410 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); | |
| 411 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); | |
| 412 | |
| 413 // Icon: old unused case. | |
|
pkotwicz
2017/07/10 05:23:28
You don't need the comment here because you have a
jkrcal
2017/07/10 16:14:30
Done.
| |
| 414 GURL url("http://google.com/favicon.ico"); | |
| 415 favicon_base::FaviconID icon = | |
| 416 db.AddFavicon(url, favicon_base::FAVICON, favicon, | |
| 417 FaviconBitmapType::ON_DEMAND, start, gfx::Size()); | |
| 418 ASSERT_NE(0, icon); | |
| 419 // Associate two different URLs with the icon. | |
| 420 GURL page_url1("http://google.com/1"); | |
| 421 ASSERT_NE(0, db.AddIconMapping(page_url1, icon)); | |
| 422 GURL page_url2("http://google.com/2"); | |
| 423 ASSERT_NE(0, db.AddIconMapping(page_url2, icon)); | |
| 424 | |
| 425 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1); | |
| 426 auto map = db.GetOldOnDemandFavicons(get_older_than); | |
| 427 | |
| 428 // The icon is returned. | |
| 429 EXPECT_THAT(map, ElementsAre(Pair( | |
| 430 icon, AllOf(Field(&FaviconURLs::icon_url, url), | |
| 431 Field(&FaviconURLs::page_urls, | |
| 432 ElementsAre(page_url1, page_url2)))))); | |
| 433 } | |
| 434 | |
| 435 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() returns on-visit icons | |
| 436 // if the on-visit icons have expired. We need this behavior in order to delete | |
| 437 // icons stored via HistoryService::SetOnDemandFavicons() prior to on-demand | |
| 438 // icons setting the "last_requested" time. | |
| 439 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsReturnsExpired) { | |
| 440 ThumbnailDatabase db(nullptr); | |
| 441 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | |
| 442 db.BeginTransaction(); | |
| 443 | |
| 444 base::Time start; | |
| 445 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start)); | |
| 446 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); | |
| 447 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); | |
| 448 | |
| 449 // Icon: standard favicon (not on-demand) but expired. | |
| 450 GURL url("http://google.com/favicon.ico"); | |
| 451 favicon_base::FaviconID icon = | |
| 452 db.AddFavicon(url, favicon_base::FAVICON, favicon, | |
| 453 FaviconBitmapType::ON_VISIT, start, gfx::Size()); | |
| 454 ASSERT_NE(0, icon); | |
| 455 GURL page_url("http://google.com/"); | |
| 456 ASSERT_NE(0, db.AddIconMapping(page_url, icon)); | |
| 457 ASSERT_TRUE(db.SetFaviconOutOfDate(icon)); | |
| 458 | |
| 459 // The threshold is ignored for expired icons. | |
| 460 auto map = db.GetOldOnDemandFavicons(/*threshold=*/base::Time::Now()); | |
| 461 | |
| 462 // The icon is returned. | |
| 463 EXPECT_THAT(map, | |
| 464 ElementsAre(Pair(icon, AllOf(Field(&FaviconURLs::icon_url, url), | |
| 465 Field(&FaviconURLs::page_urls, | |
| 466 ElementsAre(page_url)))))); | |
| 467 } | |
| 468 | |
| 469 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() does not return | |
| 470 // on-demand icons which were requested after to the passed in timestamp. | |
|
pkotwicz
2017/07/10 05:23:28
Nit: "after to the" -> "after the"
jkrcal
2017/07/10 16:14:30
Done.
(sorry for not proof-reading your previous p
| |
| 471 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsDoesNotReturnFresh) { | |
| 472 ThumbnailDatabase db(nullptr); | |
| 473 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | |
| 474 db.BeginTransaction(); | |
| 475 | |
| 476 base::Time start; | |
| 477 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start)); | |
| 478 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); | |
| 479 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); | |
| 480 | |
| 481 // Icon: freshly used case. | |
| 482 GURL url("http://google.com/favicon.ico"); | |
| 483 favicon_base::FaviconID icon = | |
| 484 db.AddFavicon(url, favicon_base::FAVICON, favicon, | |
| 485 FaviconBitmapType::ON_DEMAND, start, gfx::Size()); | |
| 486 ASSERT_NE(0, icon); | |
| 487 ASSERT_NE(0, db.AddIconMapping(GURL("http://google.com/"), icon)); | |
| 488 | |
| 489 // Touch the icon 3 weeks later. | |
| 490 base::Time now = start + base::TimeDelta::FromDays(21); | |
| 491 EXPECT_TRUE(db.TouchOnDemandFavicon(url, now)); | |
| 492 | |
| 493 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1); | |
| 494 auto list = db.GetOldOnDemandFavicons(get_older_than); | |
| 495 | |
| 496 // No icon is returned. | |
| 497 EXPECT_TRUE(list.empty()); | |
| 498 } | |
| 499 | |
| 500 // Test that ThumbnailDatabase::GetOldOnDemandFavicons() does not return | |
| 501 // non-expired on-visit icons. | |
| 502 TEST_F(ThumbnailDatabaseTest, GetOldOnDemandFaviconsDoesNotDeleteStandard) { | |
| 503 ThumbnailDatabase db(nullptr); | |
| 504 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | |
| 505 db.BeginTransaction(); | |
| 506 | |
| 507 base::Time start; | |
| 508 ASSERT_TRUE(base::Time::FromUTCExploded({2017, 5, 0, 1, 0, 0, 0, 0}, &start)); | |
| 509 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); | |
| 510 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); | |
| 511 | |
| 512 // Icon: standard favicon (not on-demand). | |
| 513 favicon_base::FaviconID icon = db.AddFavicon( | |
| 514 GURL("http://google.com/favicon.ico"), favicon_base::FAVICON, favicon, | |
| 515 FaviconBitmapType::ON_VISIT, start, gfx::Size()); | |
| 516 ASSERT_NE(0, icon); | |
| 517 ASSERT_NE(0, db.AddIconMapping(GURL("http://google.com/"), icon)); | |
| 518 | |
| 519 base::Time get_older_than = start + base::TimeDelta::FromSeconds(1); | |
| 520 auto list = db.GetOldOnDemandFavicons(get_older_than); | |
| 521 | |
| 522 // No icon is returned. | |
| 523 EXPECT_TRUE(list.empty()); | |
| 524 } | |
| 525 | |
| 370 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) { | 526 TEST_F(ThumbnailDatabaseTest, DeleteIconMappings) { |
| 371 ThumbnailDatabase db(NULL); | 527 ThumbnailDatabase db(NULL); |
| 372 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); | 528 ASSERT_EQ(sql::INIT_OK, db.Init(file_name_)); |
| 373 db.BeginTransaction(); | 529 db.BeginTransaction(); |
| 374 | 530 |
| 375 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); | 531 std::vector<unsigned char> data(kBlob1, kBlob1 + sizeof(kBlob1)); |
| 376 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); | 532 scoped_refptr<base::RefCountedBytes> favicon(new base::RefCountedBytes(data)); |
| 377 | 533 |
| 378 GURL url("http://google.com"); | 534 GURL url("http://google.com"); |
| 379 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); | 535 favicon_base::FaviconID id = db.AddFavicon(url, favicon_base::TOUCH_ICON); |
| (...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1181 ThumbnailDatabase db(NULL); | 1337 ThumbnailDatabase db(NULL); |
| 1182 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); | 1338 ASSERT_EQ(sql::INIT_OK, db.Init(db_path)); |
| 1183 | 1339 |
| 1184 // Verify that the resulting schema is correct, whether it | 1340 // Verify that the resulting schema is correct, whether it |
| 1185 // involved razing the file or fixing things in place. | 1341 // involved razing the file or fixing things in place. |
| 1186 VerifyTablesAndColumns(&db.db_); | 1342 VerifyTablesAndColumns(&db.db_); |
| 1187 } | 1343 } |
| 1188 } | 1344 } |
| 1189 | 1345 |
| 1190 } // namespace history | 1346 } // namespace history |
| OLD | NEW |