| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/offline_pages/offline_page_model_impl.h" | 5 #include "components/offline_pages/offline_page_model_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
| 13 #include "base/feature_list.h" | 13 #include "base/feature_list.h" |
| 14 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
| 15 #include "base/files/scoped_temp_dir.h" | 15 #include "base/files/scoped_temp_dir.h" |
| 16 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/statistics_recorder.h" | 17 #include "base/metrics/statistics_recorder.h" |
| 17 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 18 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 21 #include "base/test/histogram_tester.h" | 22 #include "base/test/histogram_tester.h" |
| 22 #include "base/test/scoped_feature_list.h" | 23 #include "base/test/scoped_feature_list.h" |
| 23 #include "base/test/test_mock_time_task_runner.h" | 24 #include "base/test/test_mock_time_task_runner.h" |
| 24 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
| 25 #include "base/time/time.h" | 26 #include "base/time/time.h" |
| 26 #include "components/offline_pages/client_namespace_constants.h" | 27 #include "components/offline_pages/client_namespace_constants.h" |
| 27 #include "components/offline_pages/client_policy_controller.h" | 28 #include "components/offline_pages/client_policy_controller.h" |
| 28 #include "components/offline_pages/offline_page_client_policy.h" | 29 #include "components/offline_pages/offline_page_client_policy.h" |
| 29 #include "components/offline_pages/offline_page_feature.h" | 30 #include "components/offline_pages/offline_page_feature.h" |
| 30 #include "components/offline_pages/offline_page_item.h" | 31 #include "components/offline_pages/offline_page_item.h" |
| 31 #include "components/offline_pages/offline_page_storage_manager.h" | 32 #include "components/offline_pages/offline_page_storage_manager.h" |
| 32 #include "components/offline_pages/offline_page_test_archiver.h" | 33 #include "components/offline_pages/offline_page_test_archiver.h" |
| 33 #include "components/offline_pages/offline_page_test_store.h" | 34 #include "components/offline_pages/offline_page_test_store.h" |
| 34 #include "components/offline_pages/offline_page_types.h" | 35 #include "components/offline_pages/offline_page_types.h" |
| 35 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 36 #include "url/gurl.h" | 37 #include "url/gurl.h" |
| 37 | 38 |
| 38 namespace offline_pages { | 39 namespace offline_pages { |
| 39 | 40 |
| 40 namespace { | 41 namespace { |
| 41 const char kTestClientNamespace[] = "CLIENT_NAMESPACE"; | 42 const char kTestClientNamespace[] = "default"; |
| 42 const char kUserRequestedNamespace[] = "download"; | 43 const char kUserRequestedNamespace[] = "download"; |
| 43 const GURL kTestUrl("http://example.com"); | 44 const GURL kTestUrl("http://example.com"); |
| 44 const GURL kTestUrl2("http://other.page.com"); | 45 const GURL kTestUrl2("http://other.page.com"); |
| 45 const GURL kTestUrl3("http://test.xyz"); | 46 const GURL kTestUrl3("http://test.xyz"); |
| 46 const GURL kTestUrl4("http://page.net"); | 47 const GURL kTestUrl4("http://page.net"); |
| 47 const GURL kFileUrl("file:///foo"); | 48 const GURL kFileUrl("file:///foo"); |
| 48 const GURL kTestUrlWithFragment("http://example.com#frag"); | 49 const GURL kTestUrlWithFragment("http://example.com#frag"); |
| 49 const GURL kTestUrl2WithFragment("http://other.page.com#frag"); | 50 const GURL kTestUrl2WithFragment("http://other.page.com#frag"); |
| 50 const GURL kTestUrl2WithFragment2("http://other.page.com#frag2"); | 51 const GURL kTestUrl2WithFragment2("http://other.page.com#frag2"); |
| 51 const ClientId kTestClientId1(kTestClientNamespace, "1234"); | 52 const ClientId kTestClientId1(kTestClientNamespace, "1234"); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 82 | 83 |
| 83 // OfflinePageTestArchiver::Observer implementation. | 84 // OfflinePageTestArchiver::Observer implementation. |
| 84 void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override; | 85 void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override; |
| 85 | 86 |
| 86 // OfflinePageModel callbacks. | 87 // OfflinePageModel callbacks. |
| 87 void OnSavePageDone(SavePageResult result, int64_t offline_id); | 88 void OnSavePageDone(SavePageResult result, int64_t offline_id); |
| 88 void OnDeletePageDone(DeletePageResult result); | 89 void OnDeletePageDone(DeletePageResult result); |
| 89 void OnCheckPagesExistOfflineDone(const CheckPagesExistOfflineResult& result); | 90 void OnCheckPagesExistOfflineDone(const CheckPagesExistOfflineResult& result); |
| 90 void OnGetOfflineIdsForClientIdDone(MultipleOfflineIdResult* storage, | 91 void OnGetOfflineIdsForClientIdDone(MultipleOfflineIdResult* storage, |
| 91 const MultipleOfflineIdResult& result); | 92 const MultipleOfflineIdResult& result); |
| 92 void OnGetSingleOfflinePageItemResult(const OfflinePageItem** storage, | 93 void OnGetSingleOfflinePageItemResult( |
| 93 const OfflinePageItem* result); | 94 std::unique_ptr<OfflinePageItem>* storage, |
| 95 const OfflinePageItem* result); |
| 94 void OnGetMultipleOfflinePageItemsResult( | 96 void OnGetMultipleOfflinePageItemsResult( |
| 95 MultipleOfflinePageItemResult* storage, | 97 MultipleOfflinePageItemResult* storage, |
| 96 const MultipleOfflinePageItemResult& result); | 98 const MultipleOfflinePageItemResult& result); |
| 97 void OnPagesExpired(bool result); | 99 void OnPagesExpired(bool result); |
| 98 | 100 |
| 99 // OfflinePageMetadataStore callbacks. | 101 // OfflinePageMetadataStore callbacks. |
| 100 void OnStoreUpdateDone(bool /* success */); | 102 void OnStoreUpdateDone(bool /* success */); |
| 101 | 103 |
| 102 std::unique_ptr<OfflinePageTestArchiver> BuildArchiver( | 104 std::unique_ptr<OfflinePageTestArchiver> BuildArchiver( |
| 103 const GURL& url, | 105 const GURL& url, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 offline_ids.push_back(offline_id); | 138 offline_ids.push_back(offline_id); |
| 137 model()->DeletePagesByOfflineId(offline_ids, callback); | 139 model()->DeletePagesByOfflineId(offline_ids, callback); |
| 138 } | 140 } |
| 139 | 141 |
| 140 bool HasPages(std::string name_space); | 142 bool HasPages(std::string name_space); |
| 141 | 143 |
| 142 CheckPagesExistOfflineResult CheckPagesExistOffline(std::set<GURL>); | 144 CheckPagesExistOfflineResult CheckPagesExistOffline(std::set<GURL>); |
| 143 | 145 |
| 144 MultipleOfflineIdResult GetOfflineIdsForClientId(const ClientId& client_id); | 146 MultipleOfflineIdResult GetOfflineIdsForClientId(const ClientId& client_id); |
| 145 | 147 |
| 146 const OfflinePageItem* GetPageByOfflineId(int64_t offline_id); | 148 std::unique_ptr<OfflinePageItem> GetPageByOfflineId(int64_t offline_id); |
| 147 | 149 |
| 148 MultipleOfflinePageItemResult GetPagesByOnlineURL(const GURL& online_url); | 150 MultipleOfflinePageItemResult GetPagesByOnlineURL(const GURL& online_url); |
| 149 | 151 |
| 150 OfflinePageModelImpl* model() { return model_.get(); } | 152 OfflinePageModelImpl* model() { return model_.get(); } |
| 151 | 153 |
| 152 int64_t last_save_offline_id() const { return last_save_offline_id_; } | 154 int64_t last_save_offline_id() const { return last_save_offline_id_; } |
| 153 | 155 |
| 154 SavePageResult last_save_result() const { return last_save_result_; } | 156 SavePageResult last_save_result() const { return last_save_result_; } |
| 155 | 157 |
| 156 DeletePageResult last_delete_result() const { return last_delete_result_; } | 158 DeletePageResult last_delete_result() const { return last_delete_result_; } |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 PumpLoop(); | 373 PumpLoop(); |
| 372 return result; | 374 return result; |
| 373 } | 375 } |
| 374 | 376 |
| 375 void OfflinePageModelImplTest::OnGetOfflineIdsForClientIdDone( | 377 void OfflinePageModelImplTest::OnGetOfflineIdsForClientIdDone( |
| 376 MultipleOfflineIdResult* storage, | 378 MultipleOfflineIdResult* storage, |
| 377 const MultipleOfflineIdResult& result) { | 379 const MultipleOfflineIdResult& result) { |
| 378 *storage = result; | 380 *storage = result; |
| 379 } | 381 } |
| 380 | 382 |
| 381 const OfflinePageItem* OfflinePageModelImplTest::GetPageByOfflineId( | 383 std::unique_ptr<OfflinePageItem> OfflinePageModelImplTest::GetPageByOfflineId( |
| 382 int64_t offline_id) { | 384 int64_t offline_id) { |
| 383 const OfflinePageItem* result = nullptr; | 385 std::unique_ptr<OfflinePageItem> result = nullptr; |
| 384 model()->GetPageByOfflineId( | 386 model()->GetPageByOfflineId( |
| 385 offline_id, | 387 offline_id, |
| 386 base::Bind(&OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult, | 388 base::Bind(&OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult, |
| 387 AsWeakPtr(), base::Unretained(&result))); | 389 AsWeakPtr(), base::Unretained(&result))); |
| 388 PumpLoop(); | 390 PumpLoop(); |
| 389 return result; | 391 return result; |
| 390 } | 392 } |
| 391 | 393 |
| 392 void OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult( | 394 void OfflinePageModelImplTest::OnGetSingleOfflinePageItemResult( |
| 393 const OfflinePageItem** storage, | 395 std::unique_ptr<OfflinePageItem>* storage, |
| 394 const OfflinePageItem* result) { | 396 const OfflinePageItem* result) { |
| 395 *storage = result; | 397 if (result == nullptr) { |
| 398 storage->reset(nullptr); |
| 399 return; |
| 400 } |
| 401 |
| 402 *storage = base::MakeUnique<OfflinePageItem>(*result); |
| 396 } | 403 } |
| 397 | 404 |
| 398 void OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult( | 405 void OfflinePageModelImplTest::OnGetMultipleOfflinePageItemsResult( |
| 399 MultipleOfflinePageItemResult* storage, | 406 MultipleOfflinePageItemResult* storage, |
| 400 const MultipleOfflinePageItemResult& result) { | 407 const MultipleOfflinePageItemResult& result) { |
| 401 *storage = result; | 408 *storage = result; |
| 402 } | 409 } |
| 403 | 410 |
| 404 void OfflinePageModelImplTest::OnPagesExpired(bool result) { | 411 void OfflinePageModelImplTest::OnPagesExpired(bool result) { |
| 405 last_expire_page_result_ = result; | 412 last_expire_page_result_ = result; |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 EXPECT_EQ(DeletePageResult::STORE_FAILURE, last_delete_result()); | 775 EXPECT_EQ(DeletePageResult::STORE_FAILURE, last_delete_result()); |
| 769 } | 776 } |
| 770 | 777 |
| 771 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissing) { | 778 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissing) { |
| 772 // Save a page. | 779 // Save a page. |
| 773 SavePage(kTestUrl, kTestClientId1); | 780 SavePage(kTestUrl, kTestClientId1); |
| 774 int64_t offline_id = last_save_offline_id(); | 781 int64_t offline_id = last_save_offline_id(); |
| 775 | 782 |
| 776 ResetResults(); | 783 ResetResults(); |
| 777 | 784 |
| 778 const OfflinePageItem* page = GetPageByOfflineId(offline_id); | 785 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); |
| 779 | 786 |
| 780 // Delete the offline copy of the page. | 787 // Delete the offline copy of the page. |
| 781 base::DeleteFile(page->file_path, false); | 788 base::DeleteFile(page->file_path, false); |
| 782 | 789 |
| 783 // Resetting the model will cause a consistency check. | 790 // Resetting the model will cause a consistency check. |
| 784 ResetModel(); | 791 ResetModel(); |
| 785 | 792 |
| 786 PumpLoop(); | 793 PumpLoop(); |
| 787 | 794 |
| 788 // Check if the page has been expired. | 795 // Check if the page has been expired. |
| 789 EXPECT_EQ(0UL, GetAllPages().size()); | 796 EXPECT_EQ(0UL, GetAllPages().size()); |
| 790 } | 797 } |
| 791 | 798 |
| 792 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissingAfterLoad) { | 799 TEST_F(OfflinePageModelImplTest, DetectThatOfflineCopyIsMissingAfterLoad) { |
| 793 // Save a page. | 800 // Save a page. |
| 794 SavePage(kTestUrl, kTestClientId1); | 801 SavePage(kTestUrl, kTestClientId1); |
| 795 PumpLoop(); | 802 PumpLoop(); |
| 796 int64_t offline_id = last_save_offline_id(); | 803 int64_t offline_id = last_save_offline_id(); |
| 797 | 804 |
| 798 ResetResults(); | 805 ResetResults(); |
| 799 | 806 |
| 800 const OfflinePageItem* page = GetPageByOfflineId(offline_id); | 807 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); |
| 801 // Delete the offline copy of the page and check the metadata. | 808 // Delete the offline copy of the page and check the metadata. |
| 802 base::DeleteFile(page->file_path, false); | 809 base::DeleteFile(page->file_path, false); |
| 803 // Reseting the model should trigger the metadata consistency check as well. | 810 // Reseting the model should trigger the metadata consistency check as well. |
| 804 ResetModel(); | 811 ResetModel(); |
| 805 PumpLoop(); | 812 PumpLoop(); |
| 806 | 813 |
| 807 // Check if the page has been expired. | 814 // Check if the page has been expired. |
| 808 EXPECT_EQ(0UL, GetAllPages().size()); | 815 EXPECT_EQ(0UL, GetAllPages().size()); |
| 809 } | 816 } |
| 810 | 817 |
| 811 TEST_F(OfflinePageModelImplTest, DetectThatHeadlessPageIsDeleted) { | 818 TEST_F(OfflinePageModelImplTest, DetectThatHeadlessPageIsDeleted) { |
| 812 // Save a page. | 819 // Save a page. |
| 813 SavePage(kTestUrl, kTestClientId1); | 820 SavePage(kTestUrl, kTestClientId1); |
| 814 PumpLoop(); | 821 PumpLoop(); |
| 815 int64_t offline_id = last_save_offline_id(); | 822 int64_t offline_id = last_save_offline_id(); |
| 816 | 823 |
| 817 ResetResults(); | 824 ResetResults(); |
| 818 const OfflinePageItem* page = GetPageByOfflineId(offline_id); | 825 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline_id); |
| 819 base::FilePath path = page->file_path; | 826 base::FilePath path = page->file_path; |
| 820 EXPECT_TRUE(base::PathExists(path)); | 827 EXPECT_TRUE(base::PathExists(path)); |
| 821 GetStore()->ClearAllPages(); | 828 GetStore()->ClearAllPages(); |
| 822 | 829 |
| 823 EXPECT_TRUE(base::PathExists(path)); | 830 EXPECT_TRUE(base::PathExists(path)); |
| 824 // Since we've manually changed the store, we have to reload the model to | 831 // Since we've manually changed the store, we have to reload the model to |
| 825 // actually refresh the in-memory copy in model. Otherwise GetAllPages() would | 832 // actually refresh the in-memory copy in model. Otherwise GetAllPages() would |
| 826 // still have the page we saved above. | 833 // still have the page we saved above. |
| 827 ResetModel(); | 834 ResetModel(); |
| 828 PumpLoop(); | 835 PumpLoop(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); | 881 EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result()); |
| 875 EXPECT_EQ(1u, store->GetAllPages().size()); | 882 EXPECT_EQ(1u, store->GetAllPages().size()); |
| 876 } | 883 } |
| 877 | 884 |
| 878 TEST_F(OfflinePageModelImplTest, GetPageByOfflineId) { | 885 TEST_F(OfflinePageModelImplTest, GetPageByOfflineId) { |
| 879 SavePage(kTestUrl, kTestClientId1); | 886 SavePage(kTestUrl, kTestClientId1); |
| 880 int64_t offline1 = last_save_offline_id(); | 887 int64_t offline1 = last_save_offline_id(); |
| 881 SavePage(kTestUrl2, kTestClientId2); | 888 SavePage(kTestUrl2, kTestClientId2); |
| 882 int64_t offline2 = last_save_offline_id(); | 889 int64_t offline2 = last_save_offline_id(); |
| 883 | 890 |
| 884 const OfflinePageItem* page = GetPageByOfflineId(offline1); | 891 std::unique_ptr<OfflinePageItem> page = GetPageByOfflineId(offline1); |
| 885 EXPECT_TRUE(page); | 892 ASSERT_TRUE(page); |
| 886 EXPECT_EQ(kTestUrl, page->url); | 893 EXPECT_EQ(kTestUrl, page->url); |
| 887 EXPECT_EQ(kTestClientId1, page->client_id); | 894 EXPECT_EQ(kTestClientId1, page->client_id); |
| 888 EXPECT_EQ(kTestFileSize, page->file_size); | 895 EXPECT_EQ(kTestFileSize, page->file_size); |
| 889 | 896 |
| 890 page = GetPageByOfflineId(offline2); | 897 page = GetPageByOfflineId(offline2); |
| 891 EXPECT_TRUE(page); | 898 ASSERT_TRUE(page); |
| 892 EXPECT_EQ(kTestUrl2, page->url); | 899 EXPECT_EQ(kTestUrl2, page->url); |
| 893 EXPECT_EQ(kTestClientId2, page->client_id); | 900 EXPECT_EQ(kTestClientId2, page->client_id); |
| 894 EXPECT_EQ(kTestFileSize, page->file_size); | 901 EXPECT_EQ(kTestFileSize, page->file_size); |
| 895 | 902 |
| 896 page = GetPageByOfflineId(-42); | 903 page = GetPageByOfflineId(-42); |
| 897 EXPECT_FALSE(page); | 904 EXPECT_FALSE(page); |
| 898 } | 905 } |
| 899 | 906 |
| 900 TEST_F(OfflinePageModelImplTest, GetPagesByOnlineURL) { | 907 TEST_F(OfflinePageModelImplTest, GetPagesByOnlineURL) { |
| 901 SavePage(kTestUrl, kTestClientId1); | 908 SavePage(kTestUrl, kTestClientId1); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 // Check if feature is correctly enabled by command-line flag. | 1245 // Check if feature is correctly enabled by command-line flag. |
| 1239 scoped_feature_list.reset(new base::test::ScopedFeatureList); | 1246 scoped_feature_list.reset(new base::test::ScopedFeatureList); |
| 1240 scoped_feature_list->InitFromCommandLine( | 1247 scoped_feature_list->InitFromCommandLine( |
| 1241 std::string(kOfflineBookmarksFeature.name) + "," + | 1248 std::string(kOfflineBookmarksFeature.name) + "," + |
| 1242 kOfflinePagesSharingFeature.name, | 1249 kOfflinePagesSharingFeature.name, |
| 1243 ""); | 1250 ""); |
| 1244 EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled()); | 1251 EXPECT_TRUE(offline_pages::IsOfflinePagesSharingEnabled()); |
| 1245 } | 1252 } |
| 1246 | 1253 |
| 1247 } // namespace offline_pages | 1254 } // namespace offline_pages |
| OLD | NEW |