| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/reading_list/ios/reading_list_model.h" | 5 #include "components/reading_list/ios/reading_list_model.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #import "base/test/ios/wait_util.h" | 9 #import "base/test/ios/wait_util.h" |
| 10 #include "components/reading_list/ios/reading_list_model_impl.h" | 10 #include "components/reading_list/ios/reading_list_model_impl.h" |
| 11 #include "components/reading_list/ios/reading_list_model_storage.h" | 11 #include "components/reading_list/ios/reading_list_model_storage.h" |
| 12 #include "components/reading_list/ios/reading_list_store_delegate.h" | 12 #include "components/reading_list/ios/reading_list_store_delegate.h" |
| 13 #include "components/sync/model/metadata_change_list.h" | 13 #include "components/sync/model/metadata_change_list.h" |
| 14 #include "components/sync/model/model_error.h" | 14 #include "components/sync/model/model_error.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 const GURL callback_url("http://example.com"); | 19 const GURL callback_url("http://example.com"); |
| 20 const std::string callback_title("test title"); | 20 const std::string callback_title("test title"); |
| 21 | 21 |
| 22 // Returns the number of microseconds since Jan 1st 1970. |
| 23 int64_t Now() { |
| 24 return (base::Time::Now() - base::Time::UnixEpoch()).InMicroseconds(); |
| 25 } |
| 26 |
| 22 class TestReadingListStorageObserver { | 27 class TestReadingListStorageObserver { |
| 23 public: | 28 public: |
| 24 virtual void ReadingListDidSaveEntry() = 0; | 29 virtual void ReadingListDidSaveEntry() = 0; |
| 25 virtual void ReadingListDidRemoveEntry() = 0; | 30 virtual void ReadingListDidRemoveEntry() = 0; |
| 26 }; | 31 }; |
| 27 | 32 |
| 28 class TestReadingListStorage : public ReadingListModelStorage { | 33 class TestReadingListStorage : public ReadingListModelStorage { |
| 29 public: | 34 public: |
| 30 TestReadingListStorage(TestReadingListStorageObserver* observer) | 35 TestReadingListStorage(TestReadingListStorageObserver* observer) |
| 31 : ReadingListModelStorage( | 36 : ReadingListModelStorage( |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 } | 381 } |
| 377 | 382 |
| 378 // Tests updating entry from sync. | 383 // Tests updating entry from sync. |
| 379 TEST_F(ReadingListModelTest, SyncMergeEntry) { | 384 TEST_F(ReadingListModelTest, SyncMergeEntry) { |
| 380 auto storage = base::MakeUnique<TestReadingListStorage>(this); | 385 auto storage = base::MakeUnique<TestReadingListStorage>(this); |
| 381 SetStorage(std::move(storage)); | 386 SetStorage(std::move(storage)); |
| 382 model_->AddEntry(GURL("http://example.com"), "sample", | 387 model_->AddEntry(GURL("http://example.com"), "sample", |
| 383 reading_list::ADDED_VIA_CURRENT_APP); | 388 reading_list::ADDED_VIA_CURRENT_APP); |
| 384 const base::FilePath distilled_path("distilled/page.html"); | 389 const base::FilePath distilled_path("distilled/page.html"); |
| 385 const GURL distilled_url("http://example.com/distilled"); | 390 const GURL distilled_url("http://example.com/distilled"); |
| 391 int64_t size = 50; |
| 392 int64_t before = Now(); |
| 386 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, | 393 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, |
| 387 distilled_url); | 394 distilled_url, size); |
| 395 int64_t after = Now(); |
| 388 const ReadingListEntry* local_entry = | 396 const ReadingListEntry* local_entry = |
| 389 model_->GetEntryByURL(GURL("http://example.com")); | 397 model_->GetEntryByURL(GURL("http://example.com")); |
| 390 int64_t local_update_time = local_entry->UpdateTime(); | 398 int64_t local_update_time = local_entry->UpdateTime(); |
| 391 | 399 |
| 392 base::test::ios::SpinRunLoopWithMinDelay( | 400 base::test::ios::SpinRunLoopWithMinDelay( |
| 393 base::TimeDelta::FromMilliseconds(10)); | 401 base::TimeDelta::FromMilliseconds(10)); |
| 394 auto sync_entry = | 402 auto sync_entry = |
| 395 base::MakeUnique<ReadingListEntry>(GURL("http://example.com"), "sample"); | 403 base::MakeUnique<ReadingListEntry>(GURL("http://example.com"), "sample"); |
| 396 sync_entry->SetRead(true); | 404 sync_entry->SetRead(true); |
| 397 ASSERT_GT(sync_entry->UpdateTime(), local_update_time); | 405 ASSERT_GT(sync_entry->UpdateTime(), local_update_time); |
| 398 int64_t sync_update_time = sync_entry->UpdateTime(); | 406 int64_t sync_update_time = sync_entry->UpdateTime(); |
| 399 EXPECT_TRUE(sync_entry->DistilledPath().empty()); | 407 EXPECT_TRUE(sync_entry->DistilledPath().empty()); |
| 400 | 408 |
| 401 EXPECT_EQ(1ul, UnreadSize()); | 409 EXPECT_EQ(1ul, UnreadSize()); |
| 402 EXPECT_EQ(0ul, ReadSize()); | 410 EXPECT_EQ(0ul, ReadSize()); |
| 403 | 411 |
| 404 ReadingListEntry* merged_entry = | 412 ReadingListEntry* merged_entry = |
| 405 model_->SyncMergeEntry(std::move(sync_entry)); | 413 model_->SyncMergeEntry(std::move(sync_entry)); |
| 406 EXPECT_EQ(0ul, UnreadSize()); | 414 EXPECT_EQ(0ul, UnreadSize()); |
| 407 EXPECT_EQ(1ul, ReadSize()); | 415 EXPECT_EQ(1ul, ReadSize()); |
| 408 EXPECT_EQ(merged_entry->DistilledPath(), | 416 EXPECT_EQ(merged_entry->DistilledPath(), |
| 409 base::FilePath("distilled/page.html")); | 417 base::FilePath("distilled/page.html")); |
| 410 EXPECT_EQ(merged_entry->UpdateTime(), sync_update_time); | 418 EXPECT_EQ(merged_entry->UpdateTime(), sync_update_time); |
| 419 EXPECT_EQ(size, merged_entry->DistillationSize()); |
| 420 EXPECT_GE(merged_entry->DistillationTime(), before); |
| 421 EXPECT_GE(after, merged_entry->DistillationTime()); |
| 411 } | 422 } |
| 412 | 423 |
| 413 // Tests deleting entry. | 424 // Tests deleting entry. |
| 414 TEST_F(ReadingListModelTest, RemoveEntryByUrl) { | 425 TEST_F(ReadingListModelTest, RemoveEntryByUrl) { |
| 415 auto storage = base::MakeUnique<TestReadingListStorage>(this); | 426 auto storage = base::MakeUnique<TestReadingListStorage>(this); |
| 416 SetStorage(std::move(storage)); | 427 SetStorage(std::move(storage)); |
| 417 model_->AddEntry(GURL("http://example.com"), "sample", | 428 model_->AddEntry(GURL("http://example.com"), "sample", |
| 418 reading_list::ADDED_VIA_CURRENT_APP); | 429 reading_list::ADDED_VIA_CURRENT_APP); |
| 419 ClearCounts(); | 430 ClearCounts(); |
| 420 EXPECT_NE(model_->GetEntryByURL(GURL("http://example.com")), nullptr); | 431 EXPECT_NE(model_->GetEntryByURL(GURL("http://example.com")), nullptr); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 | 628 |
| 618 // Tests setting distillation info on unread entry. | 629 // Tests setting distillation info on unread entry. |
| 619 TEST_F(ReadingListModelTest, UpdateDistilledInfo) { | 630 TEST_F(ReadingListModelTest, UpdateDistilledInfo) { |
| 620 const GURL gurl("http://example.com"); | 631 const GURL gurl("http://example.com"); |
| 621 const ReadingListEntry& entry = | 632 const ReadingListEntry& entry = |
| 622 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); | 633 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); |
| 623 ClearCounts(); | 634 ClearCounts(); |
| 624 | 635 |
| 625 const base::FilePath distilled_path("distilled/page.html"); | 636 const base::FilePath distilled_path("distilled/page.html"); |
| 626 const GURL distilled_url("http://example.com/distilled"); | 637 const GURL distilled_url("http://example.com/distilled"); |
| 638 int64_t size = 50; |
| 639 int64_t before = Now(); |
| 627 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, | 640 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, |
| 628 distilled_url); | 641 distilled_url, size); |
| 642 int64_t after = Now(); |
| 629 AssertObserverCount(0, 0, 0, 0, 0, 0, 0, 1, 1); | 643 AssertObserverCount(0, 0, 0, 0, 0, 0, 0, 1, 1); |
| 630 EXPECT_EQ(ReadingListEntry::PROCESSED, entry.DistilledState()); | 644 EXPECT_EQ(ReadingListEntry::PROCESSED, entry.DistilledState()); |
| 631 EXPECT_EQ(distilled_path, entry.DistilledPath()); | 645 EXPECT_EQ(distilled_path, entry.DistilledPath()); |
| 632 EXPECT_EQ(distilled_url, entry.DistilledURL()); | 646 EXPECT_EQ(distilled_url, entry.DistilledURL()); |
| 647 EXPECT_EQ(size, entry.DistillationSize()); |
| 648 EXPECT_GE(entry.DistillationTime(), before); |
| 649 EXPECT_GE(after, entry.DistillationTime()); |
| 633 } | 650 } |
| 634 | 651 |
| 635 // Tests setting title on read entry. | 652 // Tests setting title on read entry. |
| 636 TEST_F(ReadingListModelTest, UpdateReadEntryTitle) { | 653 TEST_F(ReadingListModelTest, UpdateReadEntryTitle) { |
| 637 const GURL gurl("http://example.com"); | 654 const GURL gurl("http://example.com"); |
| 638 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); | 655 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); |
| 639 model_->SetReadStatus(gurl, true); | 656 model_->SetReadStatus(gurl, true); |
| 640 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); | 657 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); |
| 641 ClearCounts(); | 658 ClearCounts(); |
| 642 | 659 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 661 // Tests setting distillation info on read entry. | 678 // Tests setting distillation info on read entry. |
| 662 TEST_F(ReadingListModelTest, UpdateReadDistilledInfo) { | 679 TEST_F(ReadingListModelTest, UpdateReadDistilledInfo) { |
| 663 const GURL gurl("http://example.com"); | 680 const GURL gurl("http://example.com"); |
| 664 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); | 681 model_->AddEntry(gurl, "sample", reading_list::ADDED_VIA_CURRENT_APP); |
| 665 model_->SetReadStatus(gurl, true); | 682 model_->SetReadStatus(gurl, true); |
| 666 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); | 683 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); |
| 667 ClearCounts(); | 684 ClearCounts(); |
| 668 | 685 |
| 669 const base::FilePath distilled_path("distilled/page.html"); | 686 const base::FilePath distilled_path("distilled/page.html"); |
| 670 const GURL distilled_url("http://example.com/distilled"); | 687 const GURL distilled_url("http://example.com/distilled"); |
| 688 int64_t size = 50; |
| 689 int64_t before = Now(); |
| 671 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, | 690 model_->SetEntryDistilledInfo(GURL("http://example.com"), distilled_path, |
| 672 distilled_url); | 691 distilled_url, size); |
| 692 int64_t after = Now(); |
| 673 AssertObserverCount(0, 0, 0, 0, 0, 0, 0, 1, 1); | 693 AssertObserverCount(0, 0, 0, 0, 0, 0, 0, 1, 1); |
| 674 EXPECT_EQ(ReadingListEntry::PROCESSED, entry->DistilledState()); | 694 EXPECT_EQ(ReadingListEntry::PROCESSED, entry->DistilledState()); |
| 675 EXPECT_EQ(distilled_path, entry->DistilledPath()); | 695 EXPECT_EQ(distilled_path, entry->DistilledPath()); |
| 676 EXPECT_EQ(distilled_url, entry->DistilledURL()); | 696 EXPECT_EQ(distilled_url, entry->DistilledURL()); |
| 697 EXPECT_EQ(size, entry->DistillationSize()); |
| 698 EXPECT_GE(entry->DistillationTime(), before); |
| 699 EXPECT_GE(after, entry->DistillationTime()); |
| 677 } | 700 } |
| 678 | 701 |
| 679 // Tests that ReadingListModel calls CallbackModelBeingDeleted when destroyed. | 702 // Tests that ReadingListModel calls CallbackModelBeingDeleted when destroyed. |
| 680 TEST_F(ReadingListModelTest, CallbackModelBeingDeleted) { | 703 TEST_F(ReadingListModelTest, CallbackModelBeingDeleted) { |
| 681 AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); | 704 AssertObserverCount(1, 0, 0, 0, 0, 0, 0, 0, 0); |
| 682 model_.reset(); | 705 model_.reset(); |
| 683 AssertObserverCount(1, 0, 0, 1, 0, 0, 0, 0, 0); | 706 AssertObserverCount(1, 0, 0, 1, 0, 0, 0, 0, 0); |
| 684 } | 707 } |
| 685 | 708 |
| 686 // Tests that new line characters and spaces are collapsed in title. | 709 // Tests that new line characters and spaces are collapsed in title. |
| 687 TEST_F(ReadingListModelTest, TestTrimmingTitle) { | 710 TEST_F(ReadingListModelTest, TestTrimmingTitle) { |
| 688 const GURL gurl("http://example.com"); | 711 const GURL gurl("http://example.com"); |
| 689 std::string title = "\n This\ttitle \n contains new line \n characters "; | 712 std::string title = "\n This\ttitle \n contains new line \n characters "; |
| 690 model_->AddEntry(gurl, title, reading_list::ADDED_VIA_CURRENT_APP); | 713 model_->AddEntry(gurl, title, reading_list::ADDED_VIA_CURRENT_APP); |
| 691 model_->SetReadStatus(gurl, true); | 714 model_->SetReadStatus(gurl, true); |
| 692 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); | 715 const ReadingListEntry* entry = model_->GetEntryByURL(gurl); |
| 693 EXPECT_EQ(entry->Title(), "This title contains new line characters"); | 716 EXPECT_EQ(entry->Title(), "This title contains new line characters"); |
| 694 model_->SetEntryTitle(gurl, "test"); | 717 model_->SetEntryTitle(gurl, "test"); |
| 695 EXPECT_EQ(entry->Title(), "test"); | 718 EXPECT_EQ(entry->Title(), "test"); |
| 696 model_->SetEntryTitle(gurl, title); | 719 model_->SetEntryTitle(gurl, title); |
| 697 EXPECT_EQ(entry->Title(), "This title contains new line characters"); | 720 EXPECT_EQ(entry->Title(), "This title contains new line characters"); |
| 698 } | 721 } |
| 699 | 722 |
| 700 } // namespace | 723 } // namespace |
| OLD | NEW |