Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(766)

Unified Diff: components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc

Issue 2684973014: Only show Last N Pages in the UI when the corresponding tab is visible. (Closed)
Patch Set: Add unit tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
diff --git a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
index bc3d6d2f7f00a875bb94981200df1a53a62c2228..fc12a383adad5fcdcae6a2169307e9076248a730 100644
--- a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
+++ b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
@@ -10,14 +10,18 @@
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
+#include "base/test/test_simple_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/ntp_snippets/category.h"
#include "components/ntp_snippets/content_suggestions_provider.h"
#include "components/ntp_snippets/mock_content_suggestions_provider_observer.h"
#include "components/ntp_snippets/offline_pages/offline_pages_test_utils.h"
+#include "components/offline_pages/core/background/request_coordinator_stub_taco.h"
#include "components/offline_pages/core/client_namespace_constants.h"
+#include "components/offline_pages/core/downloads/download_ui_adapter.h"
#include "components/offline_pages/core/offline_page_item.h"
-#include "components/offline_pages/core/stub_offline_page_model.h"
+#include "components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_delegate.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -27,7 +31,6 @@ using ntp_snippets::test::FakeOfflinePageModel;
using offline_pages::ClientId;
using offline_pages::MultipleOfflinePageItemCallback;
using offline_pages::OfflinePageItem;
-using offline_pages::StubOfflinePageModel;
using testing::_;
using testing::IsEmpty;
using testing::Mock;
@@ -38,11 +41,16 @@ namespace ntp_snippets {
namespace {
-OfflinePageItem CreateDummyRecentTab(int id) {
- OfflinePageItem item =
- test::CreateDummyOfflinePageItem(id, offline_pages::kLastNNamespace);
- item.client_id.id = base::IntToString(id);
- return item;
+// This global is used to assign unique tab IDs to pages. Since offline IDs are
+// typically small integers like 1, 2, 3 etc, we start at 100 to ensure that
+// they are different, and can catch bugs where offline page ID is used in place
+// of tab ID and vice versa.
+int current_tab_id = 100;
vitaliii 2017/02/15 10:12:16 Since tab_id is never checked in the tests explici
dewittj 2017/02/15 19:49:45 Good idea, done.
+
+OfflinePageItem CreateDummyRecentTab(int offline_id) {
+ std::string tab_id = base::IntToString(++current_tab_id);
+ ClientId client_id(offline_pages::kLastNNamespace, tab_id);
+ return test::CreateDummyOfflinePageItem(offline_id, client_id);
}
std::vector<OfflinePageItem> CreateDummyRecentTabs(
@@ -66,12 +74,24 @@ OfflinePageItem CreateDummyRecentTab(int id, base::Time time) {
class RecentTabSuggestionsProviderTest : public testing::Test {
public:
RecentTabSuggestionsProviderTest()
- : pref_service_(new TestingPrefServiceSimple()) {
+ : task_runner_(new base::TestSimpleTaskRunner()),
+ task_runner_handle_(task_runner_),
+ pref_service_(new TestingPrefServiceSimple()) {
RecentTabSuggestionsProvider::RegisterProfilePrefs(
pref_service()->registry());
- provider_.reset(
- new RecentTabSuggestionsProvider(&observer_, &model_, pref_service()));
+ taco_ = base::MakeUnique<offline_pages::RequestCoordinatorStubTaco>();
+ taco_->CreateRequestCoordinator();
+
+ provider_.reset(new RecentTabSuggestionsProvider(
+ &observer_, &model_, taco_->request_coordinator(), pref_service()));
+
+ ui_adapter_ = offline_pages::RecentTabsUIAdapterDelegate::
+ GetOrCreateRecentTabsUIAdapter(&model_, taco_->request_coordinator());
+ // The UI adapter always fires asynchronously upon loading, so we want to
+ // run past that moment before each test.
+ task_runner_->RunUntilIdle();
+ Mock::VerifyAndClearExpectations(observer());
}
Category recent_tabs_category() {
@@ -82,18 +102,36 @@ class RecentTabSuggestionsProviderTest : public testing::Test {
return ContentSuggestion::ID(recent_tabs_category(), base::IntToString(id));
}
+ void AddTabAndOfflinePageToModel(const OfflinePageItem& item) {
+ AddTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
+ item.client_id));
+ AddOfflinePageToModel(item);
+ }
+
+ void AddTab(int tab_id) {
+ offline_pages::RecentTabsUIAdapterDelegate* delegate_ =
vitaliii 2017/02/15 10:12:15 Why does this have trailing underscore? Should we
dewittj 2017/02/15 19:49:45 Done.
+ offline_pages::RecentTabsUIAdapterDelegate::FromDownloadUIAdapter(
+ ui_adapter_);
+ delegate_->RegisterTab(tab_id);
+ }
+
+ void RemoveTab(int tab_id) {
+ offline_pages::RecentTabsUIAdapterDelegate* delegate_ =
+ offline_pages::RecentTabsUIAdapterDelegate::FromDownloadUIAdapter(
+ ui_adapter_);
+ delegate_->UnregisterTab(tab_id);
+ }
+
void AddOfflinePageToModel(const OfflinePageItem& item) {
- model_.mutable_items()->push_back(item);
- provider_->OfflinePageAdded(&model_, item);
+ ui_adapter_->OfflinePageAdded(&model_, item);
}
void FireOfflinePageDeleted(const OfflinePageItem& item) {
- auto iter = std::remove(model_.mutable_items()->begin(),
- model_.mutable_items()->end(), item);
- auto end = model_.mutable_items()->end();
- model_.mutable_items()->erase(iter, end);
+ ui_adapter_->OfflinePageDeleted(item.offline_id, item.client_id);
- provider_->OfflinePageDeleted(item.offline_id, item.client_id);
+ int tab_id = offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
+ item.client_id);
+ RemoveTab(tab_id);
vitaliii 2017/02/15 10:12:15 Wouldn't removing tab before |OfflinePageDeleted|
dewittj 2017/02/15 19:49:45 Done.
}
std::set<std::string> ReadDismissedIDsFromPrefs() {
@@ -101,12 +139,15 @@ class RecentTabSuggestionsProviderTest : public testing::Test {
}
RecentTabSuggestionsProvider* provider() { return provider_.get(); }
- FakeOfflinePageModel* model() { return &model_; }
MockContentSuggestionsProviderObserver* observer() { return &observer_; }
TestingPrefServiceSimple* pref_service() { return pref_service_.get(); }
private:
FakeOfflinePageModel model_;
+ offline_pages::DownloadUIAdapter* ui_adapter_;
+ scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+ base::ThreadTaskRunnerHandle task_runner_handle_;
+ std::unique_ptr<offline_pages::RequestCoordinatorStubTaco> taco_;
MockContentSuggestionsProviderObserver observer_;
std::unique_ptr<TestingPrefServiceSimple> pref_service_;
// Last so that the dependencies are deleted after the provider.
@@ -116,11 +157,7 @@ class RecentTabSuggestionsProviderTest : public testing::Test {
};
TEST_F(RecentTabSuggestionsProviderTest, ShouldConvertToSuggestions) {
- auto recent_tabs_list = CreateDummyRecentTabs({1, 2});
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(2);
- for (OfflinePageItem& recent_tab : recent_tabs_list)
- AddOfflinePageToModel(recent_tab);
-
EXPECT_CALL(
*observer(),
OnNewSuggestions(_, recent_tabs_category(),
@@ -131,7 +168,10 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldConvertToSuggestions) {
GURL("http://dummy.com/2")),
Property(&ContentSuggestion::url,
GURL("http://dummy.com/3")))));
- AddOfflinePageToModel(CreateDummyRecentTab(3));
+
+ auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3});
+ for (OfflinePageItem& recent_tab : recent_tabs_list)
vitaliii 2017/02/15 10:12:15 Please add curly brackets { }. In NTP we use curly
dewittj 2017/02/15 19:49:45 Done.
+ AddTabAndOfflinePageToModel(recent_tab);
}
TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) {
@@ -148,7 +188,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) {
OnNewSuggestions(_, recent_tabs_category(),
ElementsAre(Property(&ContentSuggestion::url,
GURL("http://dummy.com/1")))));
- AddOfflinePageToModel(CreateDummyRecentTab(1, now));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(1, now));
EXPECT_CALL(
*observer(),
@@ -157,7 +197,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) {
ElementsAre(
Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
- AddOfflinePageToModel(CreateDummyRecentTab(2, yesterday));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(2, yesterday));
offline_pages[1].last_access_time =
offline_pages[0].last_access_time + base::TimeDelta::FromHours(1);
@@ -172,7 +212,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) {
GURL("http://dummy.com/1")),
Property(&ContentSuggestion::url,
GURL("http://dummy.com/2")))));
- AddOfflinePageToModel(CreateDummyRecentTab(3, tomorrow));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(3, tomorrow));
}
TEST_F(RecentTabSuggestionsProviderTest, ShouldDeliverCorrectCategoryInfo) {
@@ -189,9 +229,11 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) {
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3});
for (OfflinePageItem& recent_tab : recent_tabs_list) {
- AddOfflinePageToModel(recent_tab);
+ AddTabAndOfflinePageToModel(recent_tab);
}
+ Mock::VerifyAndClearExpectations(observer());
vitaliii 2017/02/15 10:12:15 Why is this needed here?
dewittj 2017/02/15 19:49:45 I think I added it during testing. It separates th
vitaliii 2017/02/16 08:11:04 I guess it implicitly resets the expected number o
tschumann 2017/02/16 09:22:11 drive-by: gmock builds up a stack of expectations.
+
// Dismiss 2 and 3.
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
provider()->DismissSuggestion(GetDummySuggestionId(2));
@@ -207,7 +249,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) {
Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
Property(&ContentSuggestion::url, GURL("http://dummy.com/4")))));
- AddOfflinePageToModel(CreateDummyRecentTab(4));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(4));
Mock::VerifyAndClearExpectations(observer());
// And appear in the dismissed suggestions.
@@ -235,7 +277,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) {
// And appear in the reported suggestions for the category again.
EXPECT_CALL(*observer(),
OnNewSuggestions(_, recent_tabs_category(), SizeIs(5)));
- AddOfflinePageToModel(CreateDummyRecentTab(5));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(5));
Mock::VerifyAndClearExpectations(observer());
}
@@ -244,7 +286,7 @@ TEST_F(RecentTabSuggestionsProviderTest,
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
for (OfflinePageItem& recent_tab : offline_pages)
- AddOfflinePageToModel(recent_tab);
+ AddTabAndOfflinePageToModel(recent_tab);
// Invalidation of suggestion 2 should be forwarded.
EXPECT_CALL(*observer(), OnSuggestionInvalidated(_, GetDummySuggestionId(2)));
@@ -255,7 +297,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnInvalidate) {
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
for (OfflinePageItem& recent_tab : offline_pages)
- AddOfflinePageToModel(recent_tab);
+ AddTabAndOfflinePageToModel(recent_tab);
EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty());
provider()->DismissSuggestion(GetDummySuggestionId(2));
@@ -269,7 +311,7 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnFetch) {
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
for (OfflinePageItem& recent_tab : offline_pages)
- AddOfflinePageToModel(recent_tab);
+ AddTabAndOfflinePageToModel(recent_tab);
provider()->DismissSuggestion(GetDummySuggestionId(2));
provider()->DismissSuggestion(GetDummySuggestionId(3));
@@ -294,8 +336,8 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldNotShowSameUrlMutlipleTimes) {
// We leave IDs different, but make the URLs the same.
offline_pages[2].url = offline_pages[0].url;
- AddOfflinePageToModel(offline_pages[0]);
- AddOfflinePageToModel(offline_pages[1]);
+ AddTabAndOfflinePageToModel(offline_pages[0]);
+ AddTabAndOfflinePageToModel(offline_pages[1]);
Mock::VerifyAndClearExpectations(observer());
EXPECT_CALL(*observer(),
OnNewSuggestions(
@@ -304,13 +346,11 @@ TEST_F(RecentTabSuggestionsProviderTest, ShouldNotShowSameUrlMutlipleTimes) {
Property(&ContentSuggestion::publish_date, now),
Property(&ContentSuggestion::publish_date, tomorrow))));
- AddOfflinePageToModel(offline_pages[2]);
+ AddTabAndOfflinePageToModel(offline_pages[2]);
}
TEST_F(RecentTabSuggestionsProviderTest,
ShouldNotFetchIfAddedOfflinePageIsNotRecentTab) {
- // The provider is not notified about the first recent tab yet.
- model()->mutable_items()->push_back(CreateDummyRecentTab(1));
// It should not fetch when not a recent tab is added, thus, it should not
// report the first recent tab (which it is not aware about).
EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
vitaliii 2017/02/15 10:12:16 Removal of the recent tab changes meaning a bit. C
dewittj 2017/02/15 19:49:45 It's not clear what exactly you are trying to test
vitaliii 2017/02/16 08:11:04 Previously, if an offline page is added, the provi
@@ -321,7 +361,7 @@ TEST_F(RecentTabSuggestionsProviderTest,
TEST_F(RecentTabSuggestionsProviderTest,
ShouldFetchIfAddedOfflinePageIsRecentTab) {
// The provider is not notified about the first recent tab yet.
vitaliii 2017/02/15 10:12:15 I am confused. In the test above you removed exact
dewittj 2017/02/15 19:49:45 I think the premise of this test doesn't exist any
vitaliii 2017/02/16 08:11:03 ACK. Yes, fair enough!
- model()->mutable_items()->push_back(CreateDummyRecentTab(1));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(1));
// However, it must return the first recent tab (i.e. manually fetch it) even
// when notified about a different recent tab.
EXPECT_CALL(
@@ -331,7 +371,44 @@ TEST_F(RecentTabSuggestionsProviderTest,
UnorderedElementsAre(
Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
- AddOfflinePageToModel(CreateDummyRecentTab(2));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(2));
+}
+
+TEST_F(RecentTabSuggestionsProviderTest, ShouldNotShowPagesWithoutTab) {
vitaliii 2017/02/15 10:12:15 Could you also test that InvalidateSuggestion is f
dewittj 2017/02/15 19:49:45 Done.
+ EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
+ // The provider is not notified about the first recent tab yet (no tab).
+ OfflinePageItem tab = CreateDummyRecentTab(1);
+ AddOfflinePageToModel(tab);
vitaliii 2017/02/15 10:12:15 I guess this actually notifies the provider and so
dewittj 2017/02/15 19:49:45 No, this doesn't add the tab, but the name of the
+
+ Mock::VerifyAndClearExpectations(observer());
+ EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(1);
+ EXPECT_CALL(
+ *observer(),
+ OnNewSuggestions(
+ _, recent_tabs_category(),
+ UnorderedElementsAre(
+ Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
+ Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
+
+ AddTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
+ tab.client_id));
+ OfflinePageItem tab2 = CreateDummyRecentTab(2);
vitaliii 2017/02/15 10:12:16 Could you please use "first_tab" and "second_tab"
dewittj 2017/02/15 19:49:45 Done.
+ AddTabAndOfflinePageToModel(tab2);
+
+ Mock::VerifyAndClearExpectations(observer());
+
+ EXPECT_CALL(
+ *observer(),
+ OnNewSuggestions(
+ _, recent_tabs_category(),
+ UnorderedElementsAre(
+ Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
+ Property(&ContentSuggestion::url, GURL("http://dummy.com/3")))));
+
+ // Remove Tab by itself doesn't cause OnNewSuggestions to be called.
vitaliii 2017/02/15 10:12:15 |RemoveTab| or "Tab removal" If it does not cause
dewittj 2017/02/15 19:49:45 Done. I added another expectation in addition.
+ RemoveTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
+ tab2.client_id));
+ AddTabAndOfflinePageToModel(CreateDummyRecentTab(3));
}
} // namespace ntp_snippets

Powered by Google App Engine
This is Rietveld 408576698