| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/ntp_snippets/reading_list/reading_list_suggestions_provider.h" |
| |
| #include <memory> |
| |
| #include "base/test/simple_test_clock.h" |
| #include "components/ntp_snippets/mock_content_suggestions_provider_observer.h" |
| #include "components/reading_list/core/reading_list_model_impl.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace ntp_snippets { |
| |
| namespace { |
| |
| const char kTitleUnread1[] = "title1"; |
| const char kTitleUnread2[] = "title2"; |
| const char kTitleUnread3[] = "title3"; |
| const char kTitleUnread4[] = "title4"; |
| const char kTitleRead1[] = "title_read1"; |
| |
| using ::testing::_; |
| using ::testing::ElementsAre; |
| using ::testing::IsEmpty; |
| using ::testing::Property; |
| |
| class ReadingListSuggestionsProviderTest : public ::testing::Test { |
| public: |
| ReadingListSuggestionsProviderTest() { |
| model_ = std::make_unique<ReadingListModelImpl>( |
| /*storage_layer=*/nullptr, /*pref_service=*/nullptr, &clock_); |
| } |
| |
| void CreateProvider() { |
| EXPECT_CALL(observer_, |
| OnCategoryStatusChanged(_, ReadingListCategory(), |
| CategoryStatus::AVAILABLE_LOADING)) |
| .RetiresOnSaturation(); |
| EXPECT_CALL(observer_, OnCategoryStatusChanged(_, ReadingListCategory(), |
| CategoryStatus::AVAILABLE)) |
| .RetiresOnSaturation(); |
| provider_ = std::make_unique<ReadingListSuggestionsProvider>(&observer_, |
| model_.get()); |
| } |
| |
| Category ReadingListCategory() { |
| return Category::FromKnownCategory(KnownCategories::READING_LIST); |
| } |
| |
| void AddEntries() { |
| model_->AddEntry(url_unread1_, kTitleUnread1, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| clock_.Advance(base::TimeDelta::FromMilliseconds(10)); |
| model_->AddEntry(url_unread2_, kTitleUnread2, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| clock_.Advance(base::TimeDelta::FromMilliseconds(10)); |
| model_->AddEntry(url_read1_, kTitleRead1, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| model_->SetReadStatus(url_read1_, true); |
| clock_.Advance(base::TimeDelta::FromMilliseconds(10)); |
| model_->AddEntry(url_unread3_, kTitleUnread3, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| clock_.Advance(base::TimeDelta::FromMilliseconds(10)); |
| model_->AddEntry(url_unread4_, kTitleUnread4, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| } |
| |
| protected: |
| base::SimpleTestClock clock_; |
| std::unique_ptr<ReadingListModelImpl> model_; |
| testing::StrictMock<MockContentSuggestionsProviderObserver> observer_; |
| std::unique_ptr<ReadingListSuggestionsProvider> provider_; |
| |
| const GURL url_unread1_{"http://www.foo1.bar"}; |
| const GURL url_unread2_{"http://www.foo2.bar"}; |
| const GURL url_unread3_{"http://www.foo3.bar"}; |
| const GURL url_unread4_{"http://www.foo4.bar"}; |
| const GURL url_read1_{"http://www.bar.foor"}; |
| }; |
| |
| TEST_F(ReadingListSuggestionsProviderTest, CategoryInfo) { |
| EXPECT_CALL(observer_, OnNewSuggestions(_, ReadingListCategory(), IsEmpty())) |
| .RetiresOnSaturation(); |
| CreateProvider(); |
| |
| CategoryInfo categoryInfo = provider_->GetCategoryInfo(ReadingListCategory()); |
| EXPECT_EQ(ContentSuggestionsAdditionalAction::VIEW_ALL, |
| categoryInfo.additional_action()); |
| } |
| |
| TEST_F(ReadingListSuggestionsProviderTest, ReturnsThreeLatestUnreadSuggestion) { |
| AddEntries(); |
| |
| EXPECT_CALL( |
| observer_, |
| OnNewSuggestions( |
| _, ReadingListCategory(), |
| ElementsAre(Property(&ContentSuggestion::url, url_unread4_), |
| Property(&ContentSuggestion::url, url_unread3_), |
| Property(&ContentSuggestion::url, url_unread2_)))); |
| |
| CreateProvider(); |
| } |
| |
| // Tests that the provider returns only unread suggestions even if there is less |
| // unread suggestions than the maximum number of suggestions. |
| TEST_F(ReadingListSuggestionsProviderTest, ReturnsOnlyUnreadSuggestion) { |
| GURL url_unread1 = GURL("http://www.foo1.bar"); |
| GURL url_read1 = GURL("http://www.bar.foor"); |
| std::string title_unread1 = "title1"; |
| std::string title_read1 = "title_read1"; |
| model_->AddEntry(url_unread1, title_unread1, |
| reading_list::ADDED_VIA_CURRENT_APP); |
| clock_.Advance(base::TimeDelta::FromMilliseconds(10)); |
| model_->AddEntry(url_read1, title_read1, reading_list::ADDED_VIA_CURRENT_APP); |
| model_->SetReadStatus(url_read1, true); |
| |
| EXPECT_CALL(observer_, |
| OnNewSuggestions( |
| _, ReadingListCategory(), |
| ElementsAre(Property(&ContentSuggestion::url, url_unread1)))); |
| |
| CreateProvider(); |
| } |
| |
| TEST_F(ReadingListSuggestionsProviderTest, DismissesEntry) { |
| AddEntries(); |
| |
| EXPECT_CALL( |
| observer_, |
| OnNewSuggestions( |
| _, ReadingListCategory(), |
| ElementsAre(Property(&ContentSuggestion::url, url_unread4_), |
| Property(&ContentSuggestion::url, url_unread3_), |
| Property(&ContentSuggestion::url, url_unread2_)))); |
| |
| CreateProvider(); |
| |
| EXPECT_CALL( |
| observer_, |
| OnNewSuggestions( |
| _, ReadingListCategory(), |
| ElementsAre(Property(&ContentSuggestion::url, url_unread4_), |
| Property(&ContentSuggestion::url, url_unread2_), |
| Property(&ContentSuggestion::url, url_unread1_)))); |
| |
| provider_->DismissSuggestion( |
| ContentSuggestion::ID(ReadingListCategory(), url_unread3_.spec())); |
| } |
| |
| } // namespace |
| |
| } // namespace ntp_snippets |