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.h" | 5 #include "components/offline_pages/offline_page_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/strings/string16.h" | 15 #include "base/strings/string16.h" |
16 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "components/bookmarks/browser/bookmark_model.h" |
18 #include "components/bookmarks/browser/bookmark_node.h" | 19 #include "components/bookmarks/browser/bookmark_node.h" |
| 20 #include "components/bookmarks/test/test_bookmark_client.h" |
19 #include "components/offline_pages/offline_page_item.h" | 21 #include "components/offline_pages/offline_page_item.h" |
20 #include "components/offline_pages/offline_page_metadata_store.h" | 22 #include "components/offline_pages/offline_page_metadata_store.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
22 #include "url/gurl.h" | 24 #include "url/gurl.h" |
23 | 25 |
24 using SavePageResult = offline_pages::OfflinePageModel::SavePageResult; | 26 using SavePageResult = offline_pages::OfflinePageModel::SavePageResult; |
25 using DeletePageResult = offline_pages::OfflinePageModel::DeletePageResult; | 27 using DeletePageResult = offline_pages::OfflinePageModel::DeletePageResult; |
26 | 28 |
27 namespace offline_pages { | 29 namespace offline_pages { |
28 | 30 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 210 |
209 // OfflinePageMetadataStore callbacks. | 211 // OfflinePageMetadataStore callbacks. |
210 void OnStoreUpdateDone(bool /* success */); | 212 void OnStoreUpdateDone(bool /* success */); |
211 | 213 |
212 scoped_ptr<OfflinePageTestArchiver> BuildArchiver( | 214 scoped_ptr<OfflinePageTestArchiver> BuildArchiver( |
213 const GURL& url, | 215 const GURL& url, |
214 OfflinePageArchiver::ArchiverResult result); | 216 OfflinePageArchiver::ArchiverResult result); |
215 scoped_ptr<OfflinePageMetadataStore> BuildStore(); | 217 scoped_ptr<OfflinePageMetadataStore> BuildStore(); |
216 scoped_ptr<OfflinePageModel> BuildModel( | 218 scoped_ptr<OfflinePageModel> BuildModel( |
217 scoped_ptr<OfflinePageMetadataStore> store); | 219 scoped_ptr<OfflinePageMetadataStore> store); |
218 void ResetModel(); | 220 void ResetModel(bookmarks::BookmarkModel* bookmarks); |
219 | 221 |
220 // Utility methods. | 222 // Utility methods. |
221 void PumpLoop(); | 223 void PumpLoop(); |
222 void ResetResults(); | 224 void ResetResults(); |
223 | 225 |
224 scoped_refptr<base::SingleThreadTaskRunner> task_runner() { | 226 scoped_refptr<base::SingleThreadTaskRunner> task_runner() { |
225 return message_loop_.task_runner(); | 227 return message_loop_.task_runner(); |
226 } | 228 } |
227 | 229 |
228 OfflinePageModel* model() { return model_.get(); } | 230 OfflinePageModel* model() { return model_.get(); } |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 return scoped_ptr<OfflinePageMetadataStore>( | 355 return scoped_ptr<OfflinePageMetadataStore>( |
354 new OfflinePageTestStore(task_runner())); | 356 new OfflinePageTestStore(task_runner())); |
355 } | 357 } |
356 | 358 |
357 scoped_ptr<OfflinePageModel> OfflinePageModelTest::BuildModel( | 359 scoped_ptr<OfflinePageModel> OfflinePageModelTest::BuildModel( |
358 scoped_ptr<OfflinePageMetadataStore> store) { | 360 scoped_ptr<OfflinePageMetadataStore> store) { |
359 return scoped_ptr<OfflinePageModel>( | 361 return scoped_ptr<OfflinePageModel>( |
360 new OfflinePageModel(store.Pass(), temp_dir_.path(), task_runner())); | 362 new OfflinePageModel(store.Pass(), temp_dir_.path(), task_runner())); |
361 } | 363 } |
362 | 364 |
363 void OfflinePageModelTest::ResetModel() { | 365 void OfflinePageModelTest::ResetModel(bookmarks::BookmarkModel* bookmarks) { |
364 model_->RemoveObserver(this); | 366 model_->RemoveObserver(this); |
365 OfflinePageTestStore* old_store = GetStore(); | 367 OfflinePageTestStore* old_store = GetStore(); |
366 scoped_ptr<OfflinePageMetadataStore> new_store( | 368 scoped_ptr<OfflinePageMetadataStore> new_store( |
367 new OfflinePageTestStore(*old_store)); | 369 new OfflinePageTestStore(*old_store)); |
368 model_ = BuildModel(new_store.Pass()).Pass(); | 370 model_ = BuildModel(new_store.Pass()).Pass(); |
369 model_->AddObserver(this); | 371 model_->AddObserver(this); |
| 372 if (bookmarks) |
| 373 model_->Start(bookmarks); |
370 PumpLoop(); | 374 PumpLoop(); |
371 } | 375 } |
372 | 376 |
373 void OfflinePageModelTest::PumpLoop() { | 377 void OfflinePageModelTest::PumpLoop() { |
374 base::RunLoop().RunUntilIdle(); | 378 base::RunLoop().RunUntilIdle(); |
375 } | 379 } |
376 | 380 |
377 void OfflinePageModelTest::ResetResults() { | 381 void OfflinePageModelTest::ResetResults() { |
378 last_save_result_ = SavePageResult::CANCELLED; | 382 last_save_result_ = SavePageResult::CANCELLED; |
379 last_delete_result_ = DeletePageResult::CANCELLED; | 383 last_delete_result_ = DeletePageResult::CANCELLED; |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 // Try to delete this page. | 720 // Try to delete this page. |
717 GetStore()->set_test_scenario( | 721 GetStore()->set_test_scenario( |
718 OfflinePageTestStore::TestScenario::REMOVE_FAILED); | 722 OfflinePageTestStore::TestScenario::REMOVE_FAILED); |
719 model()->DeletePageByBookmarkId( | 723 model()->DeletePageByBookmarkId( |
720 kTestPageBookmarkId1, base::Bind(&OfflinePageModelTest::OnDeletePageDone, | 724 kTestPageBookmarkId1, base::Bind(&OfflinePageModelTest::OnDeletePageDone, |
721 AsWeakPtr())); | 725 AsWeakPtr())); |
722 PumpLoop(); | 726 PumpLoop(); |
723 EXPECT_EQ(DeletePageResult::STORE_FAILURE, last_delete_result()); | 727 EXPECT_EQ(DeletePageResult::STORE_FAILURE, last_delete_result()); |
724 } | 728 } |
725 | 729 |
| 730 // Test for case, where offline copy is missing and it is detected by a |
| 731 // metadata check called directly. |
726 TEST_F(OfflinePageModelTest, DetectThatOfflineCopyIsMissing) { | 732 TEST_F(OfflinePageModelTest, DetectThatOfflineCopyIsMissing) { |
| 733 bookmarks::TestBookmarkClient test_bookmark_client; |
| 734 scoped_ptr<bookmarks::BookmarkModel> bookmarks_model( |
| 735 test_bookmark_client.CreateModel()); |
| 736 model()->Start(bookmarks_model.get()); |
| 737 |
| 738 const bookmarks::BookmarkNode* root = bookmarks_model->bookmark_bar_node(); |
| 739 const base::string16 title(base::ASCIIToUTF16("foo")); |
| 740 const bookmarks::BookmarkNode* new_node = |
| 741 bookmarks_model->AddURL(root, 0, title, kTestUrl); |
| 742 |
| 743 // Save a page. |
| 744 scoped_ptr<OfflinePageTestArchiver> archiver( |
| 745 BuildArchiver(kTestUrl, |
| 746 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) |
| 747 .Pass()); |
| 748 model()->SavePage( |
| 749 kTestUrl, new_node->id(), archiver.Pass(), |
| 750 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); |
| 751 PumpLoop(); |
| 752 |
| 753 ResetResults(); |
| 754 |
| 755 const OfflinePageItem* page = model()->GetPageByBookmarkId(new_node->id()); |
| 756 // Delete the offline copy of the page and check the metadata. |
| 757 base::DeleteFile(page->file_path, false); |
| 758 model()->CheckMetadataConsistency(false); |
| 759 PumpLoop(); |
| 760 |
| 761 EXPECT_EQ(last_deleted_bookmark_id(), new_node->id()); |
| 762 EXPECT_EQ(0UL, model()->GetAllPages().size()); |
| 763 } |
| 764 |
| 765 // Test for case, where offline copy is missing and it is detected by a |
| 766 // metadata check initiated as part of offline page model load. |
| 767 TEST_F(OfflinePageModelTest, DetectThatOfflineCopyIsMissingAfterLoad) { |
| 768 bookmarks::TestBookmarkClient test_bookmark_client; |
| 769 scoped_ptr<bookmarks::BookmarkModel> bookmarks_model( |
| 770 test_bookmark_client.CreateModel()); |
| 771 model()->Start(bookmarks_model.get()); |
| 772 |
| 773 const bookmarks::BookmarkNode* root = bookmarks_model->bookmark_bar_node(); |
| 774 const base::string16 title(base::ASCIIToUTF16("foo")); |
| 775 const bookmarks::BookmarkNode* new_node = |
| 776 bookmarks_model->AddURL(root, 0, title, kTestUrl); |
| 777 |
| 778 // Save a page. |
| 779 scoped_ptr<OfflinePageTestArchiver> archiver( |
| 780 BuildArchiver(kTestUrl, |
| 781 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) |
| 782 .Pass()); |
| 783 model()->SavePage( |
| 784 kTestUrl, new_node->id(), archiver.Pass(), |
| 785 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); |
| 786 PumpLoop(); |
| 787 |
| 788 ResetResults(); |
| 789 |
| 790 const OfflinePageItem* page = model()->GetPageByBookmarkId(new_node->id()); |
| 791 // Delete the offline copy of the page and check the metadata. |
| 792 base::DeleteFile(page->file_path, false); |
| 793 ResetModel(bookmarks_model.get()); |
| 794 // Reseting the model should trigger the metadata consistency check as well. |
| 795 PumpLoop(); |
| 796 |
| 797 EXPECT_EQ(last_deleted_bookmark_id(), new_node->id()); |
| 798 EXPECT_EQ(0UL, model()->GetAllPages().size()); |
| 799 } |
| 800 |
| 801 // Test for offline page missing a bookmark in the bookmarks model. |
| 802 TEST_F(OfflinePageModelTest, DetectThatBookmarkIsMissingAfterLoad) { |
727 // Save a page. | 803 // Save a page. |
728 scoped_ptr<OfflinePageTestArchiver> archiver( | 804 scoped_ptr<OfflinePageTestArchiver> archiver( |
729 BuildArchiver(kTestUrl, | 805 BuildArchiver(kTestUrl, |
730 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) | 806 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) |
731 .Pass()); | 807 .Pass()); |
732 model()->SavePage( | 808 model()->SavePage( |
733 kTestUrl, kTestPageBookmarkId1, archiver.Pass(), | 809 kTestUrl, kTestPageBookmarkId1, archiver.Pass(), |
734 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); | 810 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); |
735 PumpLoop(); | 811 PumpLoop(); |
736 | 812 |
737 ResetResults(); | 813 ResetResults(); |
738 | 814 |
739 const OfflinePageItem* page = | 815 // There will be a bookmark model to check against, where the bookmark ID |
740 model()->GetPageByBookmarkId(kTestPageBookmarkId1); | 816 // cannot be found. |
741 // Delete the offline copy of the page and check the metadata. | 817 bookmarks::TestBookmarkClient test_bookmark_client; |
742 base::DeleteFile(page->file_path, false); | 818 scoped_ptr<bookmarks::BookmarkModel> bookmarks_model( |
743 model()->CheckForExternalFileDeletion(); | 819 test_bookmark_client.CreateModel()); |
| 820 ResetModel(bookmarks_model.get()); |
744 PumpLoop(); | 821 PumpLoop(); |
745 | 822 |
746 EXPECT_EQ(last_deleted_bookmark_id(), kTestPageBookmarkId1); | 823 EXPECT_EQ(last_deleted_bookmark_id(), kTestPageBookmarkId1); |
747 EXPECT_EQ(0UL, model()->GetAllPages().size()); | |
748 } | |
749 | |
750 TEST_F(OfflinePageModelTest, DetectThatOfflineCopyIsMissingAfterLoad) { | |
751 // Save a page. | |
752 scoped_ptr<OfflinePageTestArchiver> archiver( | |
753 BuildArchiver(kTestUrl, | |
754 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) | |
755 .Pass()); | |
756 model()->SavePage( | |
757 kTestUrl, kTestPageBookmarkId1, archiver.Pass(), | |
758 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); | |
759 PumpLoop(); | |
760 | |
761 ResetResults(); | |
762 | |
763 const OfflinePageItem* page = | |
764 model()->GetPageByBookmarkId(kTestPageBookmarkId1); | |
765 // Delete the offline copy of the page and check the metadata. | |
766 base::DeleteFile(page->file_path, false); | |
767 // Reseting the model should trigger the metadata consistency check as well. | |
768 ResetModel(); | |
769 PumpLoop(); | |
770 | |
771 EXPECT_EQ(last_deleted_bookmark_id(), kTestPageBookmarkId1); | |
772 EXPECT_EQ(0UL, model()->GetAllPages().size()); | 824 EXPECT_EQ(0UL, model()->GetAllPages().size()); |
773 } | 825 } |
774 | 826 |
775 TEST_F(OfflinePageModelTest, GetPageByBookmarkId) { | 827 TEST_F(OfflinePageModelTest, GetPageByBookmarkId) { |
776 scoped_ptr<OfflinePageTestArchiver> archiver( | 828 scoped_ptr<OfflinePageTestArchiver> archiver( |
777 BuildArchiver(kTestUrl, | 829 BuildArchiver(kTestUrl, |
778 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) | 830 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) |
779 .Pass()); | 831 .Pass()); |
780 model()->SavePage( | 832 model()->SavePage( |
781 kTestUrl, kTestPageBookmarkId1, archiver.Pass(), | 833 kTestUrl, kTestPageBookmarkId1, archiver.Pass(), |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 BuildArchiver(kTestUrl3, | 963 BuildArchiver(kTestUrl3, |
912 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) | 964 OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED) |
913 .Pass()); | 965 .Pass()); |
914 model()->SavePage( | 966 model()->SavePage( |
915 kTestUrl3, kTestPageBookmarkId3, archiver3.Pass(), | 967 kTestUrl3, kTestPageBookmarkId3, archiver3.Pass(), |
916 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); | 968 base::Bind(&OfflinePageModelTest::OnSavePageDone, AsWeakPtr())); |
917 PumpLoop(); | 969 PumpLoop(); |
918 GetStore()->UpdateLastAccessTime(kTestPageBookmarkId3, | 970 GetStore()->UpdateLastAccessTime(kTestPageBookmarkId3, |
919 now - base::TimeDelta::FromDays(29)); | 971 now - base::TimeDelta::FromDays(29)); |
920 | 972 |
921 ResetModel(); | 973 ResetModel(nullptr); |
922 | 974 |
923 // Only page_1 and page_2 are expected to be picked up by the model as page_3 | 975 // Only page_1 and page_2 are expected to be picked up by the model as page_3 |
924 // has not been in the store long enough. | 976 // has not been in the store long enough. |
925 std::vector<OfflinePageItem> pages_to_clean_up = model()->GetPagesToCleanUp(); | 977 std::vector<OfflinePageItem> pages_to_clean_up = model()->GetPagesToCleanUp(); |
926 EXPECT_EQ(2UL, pages_to_clean_up.size()); | 978 EXPECT_EQ(2UL, pages_to_clean_up.size()); |
927 EXPECT_EQ(kTestUrl, pages_to_clean_up[0].url); | 979 EXPECT_EQ(kTestUrl, pages_to_clean_up[0].url); |
928 EXPECT_EQ(kTestPageBookmarkId1, pages_to_clean_up[0].bookmark_id); | 980 EXPECT_EQ(kTestPageBookmarkId1, pages_to_clean_up[0].bookmark_id); |
929 EXPECT_EQ(kTestUrl2, pages_to_clean_up[1].url); | 981 EXPECT_EQ(kTestUrl2, pages_to_clean_up[1].url); |
930 EXPECT_EQ(kTestPageBookmarkId2, pages_to_clean_up[1].bookmark_id); | 982 EXPECT_EQ(kTestPageBookmarkId2, pages_to_clean_up[1].bookmark_id); |
931 } | 983 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 | 1060 |
1009 // Chrome should not crash when a bookmark with no offline copy is changed. | 1061 // Chrome should not crash when a bookmark with no offline copy is changed. |
1010 // http://crbug.com/560518 | 1062 // http://crbug.com/560518 |
1011 bookmark_node.set_url(kTestUrl); | 1063 bookmark_node.set_url(kTestUrl); |
1012 model()->BookmarkNodeChanged(nullptr, &bookmark_node); | 1064 model()->BookmarkNodeChanged(nullptr, &bookmark_node); |
1013 PumpLoop(); | 1065 PumpLoop(); |
1014 EXPECT_EQ(0UL, model()->GetAllPages().size()); | 1066 EXPECT_EQ(0UL, model()->GetAllPages().size()); |
1015 } | 1067 } |
1016 | 1068 |
1017 } // namespace offline_pages | 1069 } // namespace offline_pages |
OLD | NEW |