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

Side by Side 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 unified diff | Download patch
OLDNEW
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/ntp_snippets/offline_pages/recent_tab_suggestions_provider. h" 5 #include "components/ntp_snippets/offline_pages/recent_tab_suggestions_provider. h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "base/threading/thread_task_runner_handle.h"
13 #include "base/time/time.h" 15 #include "base/time/time.h"
14 #include "components/ntp_snippets/category.h" 16 #include "components/ntp_snippets/category.h"
15 #include "components/ntp_snippets/content_suggestions_provider.h" 17 #include "components/ntp_snippets/content_suggestions_provider.h"
16 #include "components/ntp_snippets/mock_content_suggestions_provider_observer.h" 18 #include "components/ntp_snippets/mock_content_suggestions_provider_observer.h"
17 #include "components/ntp_snippets/offline_pages/offline_pages_test_utils.h" 19 #include "components/ntp_snippets/offline_pages/offline_pages_test_utils.h"
20 #include "components/offline_pages/core/background/request_coordinator_stub_taco .h"
18 #include "components/offline_pages/core/client_namespace_constants.h" 21 #include "components/offline_pages/core/client_namespace_constants.h"
22 #include "components/offline_pages/core/downloads/download_ui_adapter.h"
19 #include "components/offline_pages/core/offline_page_item.h" 23 #include "components/offline_pages/core/offline_page_item.h"
20 #include "components/offline_pages/core/stub_offline_page_model.h" 24 #include "components/offline_pages/core/recent_tabs/recent_tabs_ui_adapter_deleg ate.h"
21 #include "components/prefs/testing_pref_service.h" 25 #include "components/prefs/testing_pref_service.h"
22 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
24 28
25 using ntp_snippets::test::CaptureDismissedSuggestions; 29 using ntp_snippets::test::CaptureDismissedSuggestions;
26 using ntp_snippets::test::FakeOfflinePageModel; 30 using ntp_snippets::test::FakeOfflinePageModel;
27 using offline_pages::ClientId; 31 using offline_pages::ClientId;
28 using offline_pages::MultipleOfflinePageItemCallback; 32 using offline_pages::MultipleOfflinePageItemCallback;
29 using offline_pages::OfflinePageItem; 33 using offline_pages::OfflinePageItem;
30 using offline_pages::StubOfflinePageModel;
31 using testing::_; 34 using testing::_;
32 using testing::IsEmpty; 35 using testing::IsEmpty;
33 using testing::Mock; 36 using testing::Mock;
34 using testing::Property; 37 using testing::Property;
35 using testing::SizeIs; 38 using testing::SizeIs;
36 39
37 namespace ntp_snippets { 40 namespace ntp_snippets {
38 41
39 namespace { 42 namespace {
40 43
41 OfflinePageItem CreateDummyRecentTab(int id) { 44 // This global is used to assign unique tab IDs to pages. Since offline IDs are
42 OfflinePageItem item = 45 // typically small integers like 1, 2, 3 etc, we start at 100 to ensure that
43 test::CreateDummyOfflinePageItem(id, offline_pages::kLastNNamespace); 46 // they are different, and can catch bugs where offline page ID is used in place
44 item.client_id.id = base::IntToString(id); 47 // of tab ID and vice versa.
45 return item; 48 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.
49
50 OfflinePageItem CreateDummyRecentTab(int offline_id) {
51 std::string tab_id = base::IntToString(++current_tab_id);
52 ClientId client_id(offline_pages::kLastNNamespace, tab_id);
53 return test::CreateDummyOfflinePageItem(offline_id, client_id);
46 } 54 }
47 55
48 std::vector<OfflinePageItem> CreateDummyRecentTabs( 56 std::vector<OfflinePageItem> CreateDummyRecentTabs(
49 const std::vector<int>& ids) { 57 const std::vector<int>& ids) {
50 std::vector<OfflinePageItem> result; 58 std::vector<OfflinePageItem> result;
51 for (int id : ids) { 59 for (int id : ids) {
52 result.push_back(CreateDummyRecentTab(id)); 60 result.push_back(CreateDummyRecentTab(id));
53 } 61 }
54 return result; 62 return result;
55 } 63 }
56 64
57 OfflinePageItem CreateDummyRecentTab(int id, base::Time time) { 65 OfflinePageItem CreateDummyRecentTab(int id, base::Time time) {
58 OfflinePageItem item = CreateDummyRecentTab(id); 66 OfflinePageItem item = CreateDummyRecentTab(id);
59 item.creation_time = time; 67 item.creation_time = time;
60 item.last_access_time = time; 68 item.last_access_time = time;
61 return item; 69 return item;
62 } 70 }
63 71
64 } // namespace 72 } // namespace
65 73
66 class RecentTabSuggestionsProviderTest : public testing::Test { 74 class RecentTabSuggestionsProviderTest : public testing::Test {
67 public: 75 public:
68 RecentTabSuggestionsProviderTest() 76 RecentTabSuggestionsProviderTest()
69 : pref_service_(new TestingPrefServiceSimple()) { 77 : task_runner_(new base::TestSimpleTaskRunner()),
78 task_runner_handle_(task_runner_),
79 pref_service_(new TestingPrefServiceSimple()) {
70 RecentTabSuggestionsProvider::RegisterProfilePrefs( 80 RecentTabSuggestionsProvider::RegisterProfilePrefs(
71 pref_service()->registry()); 81 pref_service()->registry());
72 82
73 provider_.reset( 83 taco_ = base::MakeUnique<offline_pages::RequestCoordinatorStubTaco>();
74 new RecentTabSuggestionsProvider(&observer_, &model_, pref_service())); 84 taco_->CreateRequestCoordinator();
85
86 provider_.reset(new RecentTabSuggestionsProvider(
87 &observer_, &model_, taco_->request_coordinator(), pref_service()));
88
89 ui_adapter_ = offline_pages::RecentTabsUIAdapterDelegate::
90 GetOrCreateRecentTabsUIAdapter(&model_, taco_->request_coordinator());
91 // The UI adapter always fires asynchronously upon loading, so we want to
92 // run past that moment before each test.
93 task_runner_->RunUntilIdle();
94 Mock::VerifyAndClearExpectations(observer());
75 } 95 }
76 96
77 Category recent_tabs_category() { 97 Category recent_tabs_category() {
78 return Category::FromKnownCategory(KnownCategories::RECENT_TABS); 98 return Category::FromKnownCategory(KnownCategories::RECENT_TABS);
79 } 99 }
80 100
81 ContentSuggestion::ID GetDummySuggestionId(int id) { 101 ContentSuggestion::ID GetDummySuggestionId(int id) {
82 return ContentSuggestion::ID(recent_tabs_category(), base::IntToString(id)); 102 return ContentSuggestion::ID(recent_tabs_category(), base::IntToString(id));
83 } 103 }
84 104
105 void AddTabAndOfflinePageToModel(const OfflinePageItem& item) {
106 AddTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
107 item.client_id));
108 AddOfflinePageToModel(item);
109 }
110
111 void AddTab(int tab_id) {
112 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.
113 offline_pages::RecentTabsUIAdapterDelegate::FromDownloadUIAdapter(
114 ui_adapter_);
115 delegate_->RegisterTab(tab_id);
116 }
117
118 void RemoveTab(int tab_id) {
119 offline_pages::RecentTabsUIAdapterDelegate* delegate_ =
120 offline_pages::RecentTabsUIAdapterDelegate::FromDownloadUIAdapter(
121 ui_adapter_);
122 delegate_->UnregisterTab(tab_id);
123 }
124
85 void AddOfflinePageToModel(const OfflinePageItem& item) { 125 void AddOfflinePageToModel(const OfflinePageItem& item) {
86 model_.mutable_items()->push_back(item); 126 ui_adapter_->OfflinePageAdded(&model_, item);
87 provider_->OfflinePageAdded(&model_, item);
88 } 127 }
89 128
90 void FireOfflinePageDeleted(const OfflinePageItem& item) { 129 void FireOfflinePageDeleted(const OfflinePageItem& item) {
91 auto iter = std::remove(model_.mutable_items()->begin(), 130 ui_adapter_->OfflinePageDeleted(item.offline_id, item.client_id);
92 model_.mutable_items()->end(), item);
93 auto end = model_.mutable_items()->end();
94 model_.mutable_items()->erase(iter, end);
95 131
96 provider_->OfflinePageDeleted(item.offline_id, item.client_id); 132 int tab_id = offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
133 item.client_id);
134 RemoveTab(tab_id);
vitaliii 2017/02/15 10:12:15 Wouldn't removing tab before |OfflinePageDeleted|
dewittj 2017/02/15 19:49:45 Done.
97 } 135 }
98 136
99 std::set<std::string> ReadDismissedIDsFromPrefs() { 137 std::set<std::string> ReadDismissedIDsFromPrefs() {
100 return provider_->ReadDismissedIDsFromPrefs(); 138 return provider_->ReadDismissedIDsFromPrefs();
101 } 139 }
102 140
103 RecentTabSuggestionsProvider* provider() { return provider_.get(); } 141 RecentTabSuggestionsProvider* provider() { return provider_.get(); }
104 FakeOfflinePageModel* model() { return &model_; }
105 MockContentSuggestionsProviderObserver* observer() { return &observer_; } 142 MockContentSuggestionsProviderObserver* observer() { return &observer_; }
106 TestingPrefServiceSimple* pref_service() { return pref_service_.get(); } 143 TestingPrefServiceSimple* pref_service() { return pref_service_.get(); }
107 144
108 private: 145 private:
109 FakeOfflinePageModel model_; 146 FakeOfflinePageModel model_;
147 offline_pages::DownloadUIAdapter* ui_adapter_;
148 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
149 base::ThreadTaskRunnerHandle task_runner_handle_;
150 std::unique_ptr<offline_pages::RequestCoordinatorStubTaco> taco_;
110 MockContentSuggestionsProviderObserver observer_; 151 MockContentSuggestionsProviderObserver observer_;
111 std::unique_ptr<TestingPrefServiceSimple> pref_service_; 152 std::unique_ptr<TestingPrefServiceSimple> pref_service_;
112 // Last so that the dependencies are deleted after the provider. 153 // Last so that the dependencies are deleted after the provider.
113 std::unique_ptr<RecentTabSuggestionsProvider> provider_; 154 std::unique_ptr<RecentTabSuggestionsProvider> provider_;
114 155
115 DISALLOW_COPY_AND_ASSIGN(RecentTabSuggestionsProviderTest); 156 DISALLOW_COPY_AND_ASSIGN(RecentTabSuggestionsProviderTest);
116 }; 157 };
117 158
118 TEST_F(RecentTabSuggestionsProviderTest, ShouldConvertToSuggestions) { 159 TEST_F(RecentTabSuggestionsProviderTest, ShouldConvertToSuggestions) {
119 auto recent_tabs_list = CreateDummyRecentTabs({1, 2});
120 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(2); 160 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(2);
121 for (OfflinePageItem& recent_tab : recent_tabs_list)
122 AddOfflinePageToModel(recent_tab);
123
124 EXPECT_CALL( 161 EXPECT_CALL(
125 *observer(), 162 *observer(),
126 OnNewSuggestions(_, recent_tabs_category(), 163 OnNewSuggestions(_, recent_tabs_category(),
127 UnorderedElementsAre( 164 UnorderedElementsAre(
128 Property(&ContentSuggestion::url, 165 Property(&ContentSuggestion::url,
129 GURL("http://dummy.com/1")), 166 GURL("http://dummy.com/1")),
130 Property(&ContentSuggestion::url, 167 Property(&ContentSuggestion::url,
131 GURL("http://dummy.com/2")), 168 GURL("http://dummy.com/2")),
132 Property(&ContentSuggestion::url, 169 Property(&ContentSuggestion::url,
133 GURL("http://dummy.com/3"))))); 170 GURL("http://dummy.com/3")))));
134 AddOfflinePageToModel(CreateDummyRecentTab(3)); 171
172 auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3});
173 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.
174 AddTabAndOfflinePageToModel(recent_tab);
135 } 175 }
136 176
137 TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) { 177 TEST_F(RecentTabSuggestionsProviderTest, ShouldSortByCreationTime) {
138 base::Time now = base::Time::Now(); 178 base::Time now = base::Time::Now();
139 base::Time yesterday = now - base::TimeDelta::FromDays(1); 179 base::Time yesterday = now - base::TimeDelta::FromDays(1);
140 base::Time tomorrow = now + base::TimeDelta::FromDays(1); 180 base::Time tomorrow = now + base::TimeDelta::FromDays(1);
141 181
142 std::vector<OfflinePageItem> offline_pages = { 182 std::vector<OfflinePageItem> offline_pages = {
143 CreateDummyRecentTab(1, now), CreateDummyRecentTab(2, yesterday), 183 CreateDummyRecentTab(1, now), CreateDummyRecentTab(2, yesterday),
144 CreateDummyRecentTab(3, tomorrow)}; 184 CreateDummyRecentTab(3, tomorrow)};
145 185
146 EXPECT_CALL( 186 EXPECT_CALL(
147 *observer(), 187 *observer(),
148 OnNewSuggestions(_, recent_tabs_category(), 188 OnNewSuggestions(_, recent_tabs_category(),
149 ElementsAre(Property(&ContentSuggestion::url, 189 ElementsAre(Property(&ContentSuggestion::url,
150 GURL("http://dummy.com/1"))))); 190 GURL("http://dummy.com/1")))));
151 AddOfflinePageToModel(CreateDummyRecentTab(1, now)); 191 AddTabAndOfflinePageToModel(CreateDummyRecentTab(1, now));
152 192
153 EXPECT_CALL( 193 EXPECT_CALL(
154 *observer(), 194 *observer(),
155 OnNewSuggestions( 195 OnNewSuggestions(
156 _, recent_tabs_category(), 196 _, recent_tabs_category(),
157 ElementsAre( 197 ElementsAre(
158 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")), 198 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
159 Property(&ContentSuggestion::url, GURL("http://dummy.com/2"))))); 199 Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
160 AddOfflinePageToModel(CreateDummyRecentTab(2, yesterday)); 200 AddTabAndOfflinePageToModel(CreateDummyRecentTab(2, yesterday));
161 201
162 offline_pages[1].last_access_time = 202 offline_pages[1].last_access_time =
163 offline_pages[0].last_access_time + base::TimeDelta::FromHours(1); 203 offline_pages[0].last_access_time + base::TimeDelta::FromHours(1);
164 204
165 EXPECT_CALL( 205 EXPECT_CALL(
166 *observer(), 206 *observer(),
167 OnNewSuggestions( 207 OnNewSuggestions(
168 _, recent_tabs_category(), 208 _, recent_tabs_category(),
169 ElementsAre(Property(&ContentSuggestion::url, 209 ElementsAre(Property(&ContentSuggestion::url,
170 GURL("http://dummy.com/3")), 210 GURL("http://dummy.com/3")),
171 Property(&ContentSuggestion::url, 211 Property(&ContentSuggestion::url,
172 GURL("http://dummy.com/1")), 212 GURL("http://dummy.com/1")),
173 Property(&ContentSuggestion::url, 213 Property(&ContentSuggestion::url,
174 GURL("http://dummy.com/2"))))); 214 GURL("http://dummy.com/2")))));
175 AddOfflinePageToModel(CreateDummyRecentTab(3, tomorrow)); 215 AddTabAndOfflinePageToModel(CreateDummyRecentTab(3, tomorrow));
176 } 216 }
177 217
178 TEST_F(RecentTabSuggestionsProviderTest, ShouldDeliverCorrectCategoryInfo) { 218 TEST_F(RecentTabSuggestionsProviderTest, ShouldDeliverCorrectCategoryInfo) {
179 EXPECT_FALSE( 219 EXPECT_FALSE(
180 provider()->GetCategoryInfo(recent_tabs_category()).has_fetch_action()); 220 provider()->GetCategoryInfo(recent_tabs_category()).has_fetch_action());
181 EXPECT_FALSE(provider() 221 EXPECT_FALSE(provider()
182 ->GetCategoryInfo(recent_tabs_category()) 222 ->GetCategoryInfo(recent_tabs_category())
183 .has_view_all_action()); 223 .has_view_all_action());
184 } 224 }
185 225
186 // TODO(vitaliii): Break this test into multiple tests. Currently if it fails, 226 // TODO(vitaliii): Break this test into multiple tests. Currently if it fails,
187 // it takes long time to find which part of it actually fails. 227 // it takes long time to find which part of it actually fails.
188 TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) { 228 TEST_F(RecentTabSuggestionsProviderTest, ShouldDismiss) {
189 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3); 229 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
190 auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3}); 230 auto recent_tabs_list = CreateDummyRecentTabs({1, 2, 3});
191 for (OfflinePageItem& recent_tab : recent_tabs_list) { 231 for (OfflinePageItem& recent_tab : recent_tabs_list) {
192 AddOfflinePageToModel(recent_tab); 232 AddTabAndOfflinePageToModel(recent_tab);
193 } 233 }
194 234
235 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.
236
195 // Dismiss 2 and 3. 237 // Dismiss 2 and 3.
196 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0); 238 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
197 provider()->DismissSuggestion(GetDummySuggestionId(2)); 239 provider()->DismissSuggestion(GetDummySuggestionId(2));
198 provider()->DismissSuggestion(GetDummySuggestionId(3)); 240 provider()->DismissSuggestion(GetDummySuggestionId(3));
199 Mock::VerifyAndClearExpectations(observer()); 241 Mock::VerifyAndClearExpectations(observer());
200 242
201 // They should disappear from the reported suggestions. 243 // They should disappear from the reported suggestions.
202 EXPECT_CALL( 244 EXPECT_CALL(
203 *observer(), 245 *observer(),
204 OnNewSuggestions( 246 OnNewSuggestions(
205 _, recent_tabs_category(), 247 _, recent_tabs_category(),
206 UnorderedElementsAre( 248 UnorderedElementsAre(
207 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")), 249 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
208 Property(&ContentSuggestion::url, GURL("http://dummy.com/4"))))); 250 Property(&ContentSuggestion::url, GURL("http://dummy.com/4")))));
209 251
210 AddOfflinePageToModel(CreateDummyRecentTab(4)); 252 AddTabAndOfflinePageToModel(CreateDummyRecentTab(4));
211 Mock::VerifyAndClearExpectations(observer()); 253 Mock::VerifyAndClearExpectations(observer());
212 254
213 // And appear in the dismissed suggestions. 255 // And appear in the dismissed suggestions.
214 std::vector<ContentSuggestion> dismissed_suggestions; 256 std::vector<ContentSuggestion> dismissed_suggestions;
215 provider()->GetDismissedSuggestionsForDebugging( 257 provider()->GetDismissedSuggestionsForDebugging(
216 recent_tabs_category(), 258 recent_tabs_category(),
217 base::Bind(&CaptureDismissedSuggestions, &dismissed_suggestions)); 259 base::Bind(&CaptureDismissedSuggestions, &dismissed_suggestions));
218 EXPECT_THAT( 260 EXPECT_THAT(
219 dismissed_suggestions, 261 dismissed_suggestions,
220 UnorderedElementsAre(Property(&ContentSuggestion::url, 262 UnorderedElementsAre(Property(&ContentSuggestion::url,
221 GURL("http://dummy.com/2")), 263 GURL("http://dummy.com/2")),
222 Property(&ContentSuggestion::url, 264 Property(&ContentSuggestion::url,
223 GURL("http://dummy.com/3")))); 265 GURL("http://dummy.com/3"))));
224 266
225 // Clear dismissed suggestions. 267 // Clear dismissed suggestions.
226 provider()->ClearDismissedSuggestionsForDebugging(recent_tabs_category()); 268 provider()->ClearDismissedSuggestionsForDebugging(recent_tabs_category());
227 269
228 // They should be gone from the dismissed suggestions. 270 // They should be gone from the dismissed suggestions.
229 dismissed_suggestions.clear(); 271 dismissed_suggestions.clear();
230 provider()->GetDismissedSuggestionsForDebugging( 272 provider()->GetDismissedSuggestionsForDebugging(
231 recent_tabs_category(), 273 recent_tabs_category(),
232 base::Bind(&CaptureDismissedSuggestions, &dismissed_suggestions)); 274 base::Bind(&CaptureDismissedSuggestions, &dismissed_suggestions));
233 EXPECT_THAT(dismissed_suggestions, IsEmpty()); 275 EXPECT_THAT(dismissed_suggestions, IsEmpty());
234 276
235 // And appear in the reported suggestions for the category again. 277 // And appear in the reported suggestions for the category again.
236 EXPECT_CALL(*observer(), 278 EXPECT_CALL(*observer(),
237 OnNewSuggestions(_, recent_tabs_category(), SizeIs(5))); 279 OnNewSuggestions(_, recent_tabs_category(), SizeIs(5)));
238 AddOfflinePageToModel(CreateDummyRecentTab(5)); 280 AddTabAndOfflinePageToModel(CreateDummyRecentTab(5));
239 Mock::VerifyAndClearExpectations(observer()); 281 Mock::VerifyAndClearExpectations(observer());
240 } 282 }
241 283
242 TEST_F(RecentTabSuggestionsProviderTest, 284 TEST_F(RecentTabSuggestionsProviderTest,
243 ShouldInvalidateWhenOfflinePageDeleted) { 285 ShouldInvalidateWhenOfflinePageDeleted) {
244 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3); 286 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
245 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3}); 287 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
246 for (OfflinePageItem& recent_tab : offline_pages) 288 for (OfflinePageItem& recent_tab : offline_pages)
247 AddOfflinePageToModel(recent_tab); 289 AddTabAndOfflinePageToModel(recent_tab);
248 290
249 // Invalidation of suggestion 2 should be forwarded. 291 // Invalidation of suggestion 2 should be forwarded.
250 EXPECT_CALL(*observer(), OnSuggestionInvalidated(_, GetDummySuggestionId(2))); 292 EXPECT_CALL(*observer(), OnSuggestionInvalidated(_, GetDummySuggestionId(2)));
251 FireOfflinePageDeleted(offline_pages[1]); 293 FireOfflinePageDeleted(offline_pages[1]);
252 } 294 }
253 295
254 TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnInvalidate) { 296 TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnInvalidate) {
255 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3); 297 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
256 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3}); 298 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
257 for (OfflinePageItem& recent_tab : offline_pages) 299 for (OfflinePageItem& recent_tab : offline_pages)
258 AddOfflinePageToModel(recent_tab); 300 AddTabAndOfflinePageToModel(recent_tab);
259 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty()); 301 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty());
260 302
261 provider()->DismissSuggestion(GetDummySuggestionId(2)); 303 provider()->DismissSuggestion(GetDummySuggestionId(2));
262 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(1)); 304 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(1));
263 305
264 FireOfflinePageDeleted(offline_pages[1]); 306 FireOfflinePageDeleted(offline_pages[1]);
265 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty()); 307 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty());
266 } 308 }
267 309
268 TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnFetch) { 310 TEST_F(RecentTabSuggestionsProviderTest, ShouldClearDismissedOnFetch) {
269 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3); 311 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(3);
270 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3}); 312 std::vector<OfflinePageItem> offline_pages = CreateDummyRecentTabs({1, 2, 3});
271 for (OfflinePageItem& recent_tab : offline_pages) 313 for (OfflinePageItem& recent_tab : offline_pages)
272 AddOfflinePageToModel(recent_tab); 314 AddTabAndOfflinePageToModel(recent_tab);
273 315
274 provider()->DismissSuggestion(GetDummySuggestionId(2)); 316 provider()->DismissSuggestion(GetDummySuggestionId(2));
275 provider()->DismissSuggestion(GetDummySuggestionId(3)); 317 provider()->DismissSuggestion(GetDummySuggestionId(3));
276 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(2)); 318 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(2));
277 319
278 FireOfflinePageDeleted(offline_pages[0]); 320 FireOfflinePageDeleted(offline_pages[0]);
279 FireOfflinePageDeleted(offline_pages[2]); 321 FireOfflinePageDeleted(offline_pages[2]);
280 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(1)); 322 EXPECT_THAT(ReadDismissedIDsFromPrefs(), SizeIs(1));
281 323
282 FireOfflinePageDeleted(offline_pages[1]); 324 FireOfflinePageDeleted(offline_pages[1]);
283 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty()); 325 EXPECT_THAT(ReadDismissedIDsFromPrefs(), IsEmpty());
284 } 326 }
285 327
286 TEST_F(RecentTabSuggestionsProviderTest, ShouldNotShowSameUrlMutlipleTimes) { 328 TEST_F(RecentTabSuggestionsProviderTest, ShouldNotShowSameUrlMutlipleTimes) {
287 base::Time now = base::Time::Now(); 329 base::Time now = base::Time::Now();
288 base::Time yesterday = now - base::TimeDelta::FromDays(1); 330 base::Time yesterday = now - base::TimeDelta::FromDays(1);
289 base::Time tomorrow = now + base::TimeDelta::FromDays(1); 331 base::Time tomorrow = now + base::TimeDelta::FromDays(1);
290 std::vector<OfflinePageItem> offline_pages = { 332 std::vector<OfflinePageItem> offline_pages = {
291 CreateDummyRecentTab(1, yesterday), CreateDummyRecentTab(2, now), 333 CreateDummyRecentTab(1, yesterday), CreateDummyRecentTab(2, now),
292 CreateDummyRecentTab(3, tomorrow)}; 334 CreateDummyRecentTab(3, tomorrow)};
293 335
294 // We leave IDs different, but make the URLs the same. 336 // We leave IDs different, but make the URLs the same.
295 offline_pages[2].url = offline_pages[0].url; 337 offline_pages[2].url = offline_pages[0].url;
296 338
297 AddOfflinePageToModel(offline_pages[0]); 339 AddTabAndOfflinePageToModel(offline_pages[0]);
298 AddOfflinePageToModel(offline_pages[1]); 340 AddTabAndOfflinePageToModel(offline_pages[1]);
299 Mock::VerifyAndClearExpectations(observer()); 341 Mock::VerifyAndClearExpectations(observer());
300 EXPECT_CALL(*observer(), 342 EXPECT_CALL(*observer(),
301 OnNewSuggestions( 343 OnNewSuggestions(
302 _, recent_tabs_category(), 344 _, recent_tabs_category(),
303 UnorderedElementsAre( 345 UnorderedElementsAre(
304 Property(&ContentSuggestion::publish_date, now), 346 Property(&ContentSuggestion::publish_date, now),
305 Property(&ContentSuggestion::publish_date, tomorrow)))); 347 Property(&ContentSuggestion::publish_date, tomorrow))));
306 348
307 AddOfflinePageToModel(offline_pages[2]); 349 AddTabAndOfflinePageToModel(offline_pages[2]);
308 } 350 }
309 351
310 TEST_F(RecentTabSuggestionsProviderTest, 352 TEST_F(RecentTabSuggestionsProviderTest,
311 ShouldNotFetchIfAddedOfflinePageIsNotRecentTab) { 353 ShouldNotFetchIfAddedOfflinePageIsNotRecentTab) {
312 // The provider is not notified about the first recent tab yet.
313 model()->mutable_items()->push_back(CreateDummyRecentTab(1));
314 // It should not fetch when not a recent tab is added, thus, it should not 354 // It should not fetch when not a recent tab is added, thus, it should not
315 // report the first recent tab (which it is not aware about). 355 // report the first recent tab (which it is not aware about).
316 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0); 356 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
317 AddOfflinePageToModel(ntp_snippets::test::CreateDummyOfflinePageItem( 357 AddOfflinePageToModel(ntp_snippets::test::CreateDummyOfflinePageItem(
318 2, offline_pages::kDefaultNamespace)); 358 2, offline_pages::kDefaultNamespace));
319 } 359 }
320 360
321 TEST_F(RecentTabSuggestionsProviderTest, 361 TEST_F(RecentTabSuggestionsProviderTest,
322 ShouldFetchIfAddedOfflinePageIsRecentTab) { 362 ShouldFetchIfAddedOfflinePageIsRecentTab) {
323 // The provider is not notified about the first recent tab yet. 363 // 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!
324 model()->mutable_items()->push_back(CreateDummyRecentTab(1)); 364 AddTabAndOfflinePageToModel(CreateDummyRecentTab(1));
325 // However, it must return the first recent tab (i.e. manually fetch it) even 365 // However, it must return the first recent tab (i.e. manually fetch it) even
326 // when notified about a different recent tab. 366 // when notified about a different recent tab.
327 EXPECT_CALL( 367 EXPECT_CALL(
328 *observer(), 368 *observer(),
329 OnNewSuggestions( 369 OnNewSuggestions(
330 _, recent_tabs_category(), 370 _, recent_tabs_category(),
331 UnorderedElementsAre( 371 UnorderedElementsAre(
332 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")), 372 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
333 Property(&ContentSuggestion::url, GURL("http://dummy.com/2"))))); 373 Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
334 AddOfflinePageToModel(CreateDummyRecentTab(2)); 374 AddTabAndOfflinePageToModel(CreateDummyRecentTab(2));
375 }
376
377 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.
378 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(0);
379 // The provider is not notified about the first recent tab yet (no tab).
380 OfflinePageItem tab = CreateDummyRecentTab(1);
381 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
382
383 Mock::VerifyAndClearExpectations(observer());
384 EXPECT_CALL(*observer(), OnNewSuggestions(_, _, _)).Times(1);
385 EXPECT_CALL(
386 *observer(),
387 OnNewSuggestions(
388 _, recent_tabs_category(),
389 UnorderedElementsAre(
390 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
391 Property(&ContentSuggestion::url, GURL("http://dummy.com/2")))));
392
393 AddTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
394 tab.client_id));
395 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.
396 AddTabAndOfflinePageToModel(tab2);
397
398 Mock::VerifyAndClearExpectations(observer());
399
400 EXPECT_CALL(
401 *observer(),
402 OnNewSuggestions(
403 _, recent_tabs_category(),
404 UnorderedElementsAre(
405 Property(&ContentSuggestion::url, GURL("http://dummy.com/1")),
406 Property(&ContentSuggestion::url, GURL("http://dummy.com/3")))));
407
408 // 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.
409 RemoveTab(offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
410 tab2.client_id));
411 AddTabAndOfflinePageToModel(CreateDummyRecentTab(3));
335 } 412 }
336 413
337 } // namespace ntp_snippets 414 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698