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

Side by Side Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc

Issue 2611523004: [Background fetching] Background fetching when opening an NTP. (Closed)
Patch Set: Tim's comments + unit-tests Created 3 years, 11 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/remote/scheduling_remote_suggestions_provider. h" 5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h" 17 #include "base/run_loop.h"
18 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/time/clock.h"
19 #include "base/time/time.h" 20 #include "base/time/time.h"
20 #include "components/ntp_snippets/features.h" 21 #include "components/ntp_snippets/features.h"
21 #include "components/ntp_snippets/ntp_snippets_constants.h" 22 #include "components/ntp_snippets/ntp_snippets_constants.h"
22 #include "components/ntp_snippets/pref_names.h" 23 #include "components/ntp_snippets/pref_names.h"
23 #include "components/ntp_snippets/remote/persistent_scheduler.h" 24 #include "components/ntp_snippets/remote/persistent_scheduler.h"
24 #include "components/ntp_snippets/remote/remote_suggestions_provider.h" 25 #include "components/ntp_snippets/remote/remote_suggestions_provider.h"
25 #include "components/ntp_snippets/remote/test_utils.h" 26 #include "components/ntp_snippets/remote/test_utils.h"
26 #include "components/ntp_snippets/status.h" 27 #include "components/ntp_snippets/status.h"
27 #include "components/ntp_snippets/user_classifier.h" 28 #include "components/ntp_snippets/user_classifier.h"
28 #include "components/prefs/testing_pref_service.h" 29 #include "components/prefs/testing_pref_service.h"
29 #include "components/variations/variations_params_manager.h" 30 #include "components/variations/variations_params_manager.h"
30 #include "testing/gmock/include/gmock/gmock.h" 31 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
32 33
33 using testing::ElementsAre; 34 using testing::ElementsAre;
34 using testing::Eq; 35 using testing::Eq;
35 using testing::InSequence; 36 using testing::InSequence;
36 using testing::Invoke; 37 using testing::Invoke;
37 using testing::IsEmpty; 38 using testing::IsEmpty;
38 using testing::Mock; 39 using testing::Mock;
39 using testing::MockFunction; 40 using testing::MockFunction;
40 using testing::Not; 41 using testing::Not;
42 using testing::Return;
41 using testing::SaveArg; 43 using testing::SaveArg;
42 using testing::SaveArgPointee; 44 using testing::SaveArgPointee;
43 using testing::SizeIs; 45 using testing::SizeIs;
44 using testing::StartsWith; 46 using testing::StartsWith;
45 using testing::StrictMock; 47 using testing::StrictMock;
46 using testing::WithArgs; 48 using testing::WithArgs;
47 using testing::_; 49 using testing::_;
48 50
49 namespace ntp_snippets { 51 namespace ntp_snippets {
50 52
51 class NTPSnippetsFetcher; 53 class NTPSnippetsFetcher;
52 54
53 namespace { 55 namespace {
54 56
55 class MockPersistentScheduler : public PersistentScheduler { 57 class MockPersistentScheduler : public PersistentScheduler {
56 public: 58 public:
57 MOCK_METHOD2(Schedule, 59 MOCK_METHOD2(Schedule,
58 bool(base::TimeDelta period_wifi, 60 bool(base::TimeDelta period_wifi,
59 base::TimeDelta period_fallback)); 61 base::TimeDelta period_fallback));
60 MOCK_METHOD0(Unschedule, bool()); 62 MOCK_METHOD0(Unschedule, bool());
61 }; 63 };
62 64
65 class MockClock : public base::Clock {
tschumann 2017/01/04 10:43:52 for clocks, you usually don't want behavioral test
jkrcal 2017/01/04 14:19:04 Done.
66 public:
67 MOCK_METHOD0(Now, base::Time());
68 };
69
63 // TODO(jkrcal): Move into its own library to reuse in other unit-tests? 70 // TODO(jkrcal): Move into its own library to reuse in other unit-tests?
64 class MockRemoteSuggestionsProvider : public RemoteSuggestionsProvider { 71 class MockRemoteSuggestionsProvider : public RemoteSuggestionsProvider {
65 public: 72 public:
66 MockRemoteSuggestionsProvider(Observer* observer) 73 MockRemoteSuggestionsProvider(Observer* observer)
67 : RemoteSuggestionsProvider(observer) {} 74 : RemoteSuggestionsProvider(observer) {}
68 75
69 // Move-only params are not supported by GMock. We want to mock out 76 // Move-only params are not supported by GMock. We want to mock out
70 // RefetchInTheBackground() which takes a unique_ptr<>. Instead, we add a new 77 // RefetchInTheBackground() which takes a unique_ptr<>. Instead, we add a new
71 // mock function which takes a copy of the callback and override the 78 // mock function which takes a copy of the callback and override the
72 // RemoteSuggestionsProvider's method to forward the call into the new mock 79 // RemoteSuggestionsProvider's method to forward the call into the new mock
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 158 }
152 159
153 private: 160 private:
154 test::RemoteSuggestionsTestUtils utils_; 161 test::RemoteSuggestionsTestUtils utils_;
155 UserClassifier user_classifier_; 162 UserClassifier user_classifier_;
156 163
157 DISALLOW_COPY_AND_ASSIGN(SchedulingRemoteSuggestionsProviderTest); 164 DISALLOW_COPY_AND_ASSIGN(SchedulingRemoteSuggestionsProviderTest);
158 }; 165 };
159 166
160 TEST_F(SchedulingRemoteSuggestionsProviderTest, 167 TEST_F(SchedulingRemoteSuggestionsProviderTest,
168 ShouldIgnoreSignalsWhenNotEnabled) {
169 scheduling_provider_->OnPersistentSchedulerWakeUp();
170 scheduling_provider_->OnNTPOpened();
171 }
172
173 TEST_F(SchedulingRemoteSuggestionsProviderTest,
161 ShouldFetchOnPersistentSchedulerWakeUp) { 174 ShouldFetchOnPersistentSchedulerWakeUp) {
175 // First enable the scheduler.
176 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
177 ChangeStatusOfUnderlyingProvider(
178 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
179
162 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)); 180 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
163 scheduling_provider_->OnPersistentSchedulerWakeUp(); 181 scheduling_provider_->OnPersistentSchedulerWakeUp();
164 } 182 }
165 183
166 TEST_F(SchedulingRemoteSuggestionsProviderTest, 184 TEST_F(SchedulingRemoteSuggestionsProviderTest,
tschumann 2017/01/04 10:43:52 there's one similar test missing: ShouldNotTrigger
jkrcal 2017/01/04 14:19:03 Ah, sure! Done. EDIT: This added test showed ther
tschumann 2017/01/04 15:15:24 hehehe... I just know that I cannot spot bugs well
185 ShouldFetchOnPersistentSchedulerWakeUpRepeated) {
186 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
187 {
188 InSequence s;
189 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
190 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
191 .WillOnce(SaveArg<0>(&signal_fetch_done));
192 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
193 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
194 }
195 // First enable the scheduler -- calling Schedule() for the first time.
196 ChangeStatusOfUnderlyingProvider(
197 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
198 // Make the first persistent fetch successful -- calling Schedule() again.
199 scheduling_provider_->OnPersistentSchedulerWakeUp();
200 signal_fetch_done.Run(Status::Success());
201 // Make the second fetch.
202 scheduling_provider_->OnPersistentSchedulerWakeUp();
203 }
204
205 TEST_F(SchedulingRemoteSuggestionsProviderTest,
206 ShouldFetchOnNTPOpenedForTheFirstTime) {
207 // First enable the scheduler.
208 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
209 ChangeStatusOfUnderlyingProvider(
210 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
211
212 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
213 scheduling_provider_->OnNTPOpened();
214 }
215
216 TEST_F(SchedulingRemoteSuggestionsProviderTest,
217 ShouldNotFetchOnNTPOpenedAfterSuccessfulSoftFetch) {
218 // First enable the scheduler; the second Schedule is called after the
219 // successful fetch.
220 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2);
221 ChangeStatusOfUnderlyingProvider(
222 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
223
224 // Make the first soft fetch successful.
225 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
226 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
227 .WillOnce(SaveArg<0>(&signal_fetch_done));
228 scheduling_provider_->OnNTPOpened();
229 signal_fetch_done.Run(Status::Success());
230 // The second call is ignored if it happens right after the first one.
231 scheduling_provider_->OnNTPOpened();
232 }
233
234 TEST_F(SchedulingRemoteSuggestionsProviderTest,
235 ShouldNotFetchOnNTPOpenedAfterSuccessfulPersistentFetch) {
236 // First enable the scheduler; the second Schedule is called after the
237 // successful fetch.
238 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2);
239 ChangeStatusOfUnderlyingProvider(
240 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
241
242 // Make the first soft fetch successful.
tschumann 2017/01/04 10:43:52 that's not a soft fetch, right?
jkrcal 2017/01/04 14:19:03 Done.
243 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
244 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
245 .WillOnce(SaveArg<0>(&signal_fetch_done));
246 scheduling_provider_->OnPersistentSchedulerWakeUp();
247 signal_fetch_done.Run(Status::Success());
248 // The second call is ignored if it happens right after the first one.
249 scheduling_provider_->OnNTPOpened();
250 }
251
252 TEST_F(SchedulingRemoteSuggestionsProviderTest,
253 ShouldNotFetchOnNTPOpenedAfterFailedSoftFetch) {
254 // First enable the scheduler.
255 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
256 ChangeStatusOfUnderlyingProvider(
257 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
258
259 // Make the first soft fetch failed.
260 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
261 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
262 .WillOnce(SaveArg<0>(&signal_fetch_done));
263 scheduling_provider_->OnNTPOpened();
264 signal_fetch_done.Run(Status(StatusCode::PERMANENT_ERROR, ""));
265
266 // The second call is ignored if it happens right after the first one.
267 scheduling_provider_->OnNTPOpened();
268 }
269
270 TEST_F(SchedulingRemoteSuggestionsProviderTest,
271 ShouldNotFetchOnNTPOpenedAfterFailedPersistentFetch) {
272 // First enable the scheduler.
273 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
274 ChangeStatusOfUnderlyingProvider(
275 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
276
277 // Make the first soft fetch failed.
tschumann 2017/01/04 10:43:52 first hard fetch?
jkrcal 2017/01/04 14:19:04 Done.
278 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
279 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
280 .WillOnce(SaveArg<0>(&signal_fetch_done));
281 scheduling_provider_->OnPersistentSchedulerWakeUp();
282 signal_fetch_done.Run(Status(StatusCode::PERMANENT_ERROR, ""));
283
284 // The second call is ignored if it happens right after the first one.
285 scheduling_provider_->OnNTPOpened();
286 }
287
288 TEST_F(SchedulingRemoteSuggestionsProviderTest,
289 ShouldFetchAgainOnNTPOpenedLaterAgain) {
290 // First enable the scheduler.
291 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
292 ChangeStatusOfUnderlyingProvider(
293 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
294
295 auto ptr = base::MakeUnique<MockClock>();
296 MockClock* mock_clock = ptr.get();
297 scheduling_provider_->SetClockForTesting(std::move(ptr));
298 base::Time first_time = base::Time::Now();
299
300 {
301 InSequence s;
302 // The first call to NTPOpened at |first_time| results in a fetch.
303 EXPECT_CALL(*mock_clock, Now()).WillOnce(Return(first_time));
304 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
305
306 // The second call to NTPOpened at |first_time| + 2hrs again results in a
307 // fetch.
308 EXPECT_CALL(*mock_clock, Now())
309 .WillOnce(Return(first_time + base::TimeDelta::FromHours(2)));
310 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
311 }
312 scheduling_provider_->OnNTPOpened();
313 scheduling_provider_->OnNTPOpened();
314 }
315
316 TEST_F(SchedulingRemoteSuggestionsProviderTest,
167 ShouldRescheduleOnRescheduleFetching) { 317 ShouldRescheduleOnRescheduleFetching) {
168 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); 318 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
169 scheduling_provider_->RescheduleFetching(); 319 scheduling_provider_->RescheduleFetching();
170 } 320 }
171 321
172 TEST_F(SchedulingRemoteSuggestionsProviderTest, ShouldScheduleOnActivation) { 322 TEST_F(SchedulingRemoteSuggestionsProviderTest, ShouldScheduleOnActivation) {
173 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); 323 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
174 ChangeStatusOfUnderlyingProvider( 324 ChangeStatusOfUnderlyingProvider(
175 RemoteSuggestionsProvider::ProviderStatus::ACTIVE); 325 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
176 } 326 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 TEST_F(SchedulingRemoteSuggestionsProviderTest, 410 TEST_F(SchedulingRemoteSuggestionsProviderTest,
261 ReschedulesWhenWifiParamChanges) { 411 ReschedulesWhenWifiParamChanges) {
262 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2); 412 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2);
263 ChangeStatusOfUnderlyingProvider( 413 ChangeStatusOfUnderlyingProvider(
264 RemoteSuggestionsProvider::ProviderStatus::ACTIVE); 414 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
265 415
266 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is 416 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
267 // null. Change the wifi interval for this class. 417 // null. Change the wifi interval for this class.
268 variations::testing::VariationParamsManager params_manager( 418 variations::testing::VariationParamsManager params_manager(
269 ntp_snippets::kStudyName, 419 ntp_snippets::kStudyName,
270 {{"fetching_interval_hours-wifi-active_ntp_user", "2"}}, 420 {{"fetching_interval_hours-wifi-active_ntp_user", "1.5"}},
271 {kArticleSuggestionsFeature.name}); 421 {kArticleSuggestionsFeature.name});
272 422
273 // Schedule() should get called for the second time after params have changed. 423 // Schedule() should get called for the second time after params have changed.
274 ChangeStatusOfUnderlyingProvider( 424 ChangeStatusOfUnderlyingProvider(
275 RemoteSuggestionsProvider::ProviderStatus::ACTIVE); 425 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
276 } 426 }
277 427
278 TEST_F(SchedulingRemoteSuggestionsProviderTest, 428 TEST_F(SchedulingRemoteSuggestionsProviderTest,
279 ReschedulesWhenFallbackParamChanges) { 429 ReschedulesWhenFallbackParamChanges) {
280 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2); 430 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2);
281 ChangeStatusOfUnderlyingProvider( 431 ChangeStatusOfUnderlyingProvider(
282 RemoteSuggestionsProvider::ProviderStatus::ACTIVE); 432 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
283 433
284 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is 434 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
285 // null. Change the wifi interval for this class. 435 // null. Change the wifi interval for this class.
286 variations::testing::VariationParamsManager params_manager( 436 variations::testing::VariationParamsManager params_manager(
287 ntp_snippets::kStudyName, 437 ntp_snippets::kStudyName,
288 {{"fetching_interval_hours-fallback-active_ntp_user", "2"}}, 438 {{"fetching_interval_hours-fallback-active_ntp_user", "1.5"}},
289 {kArticleSuggestionsFeature.name}); 439 {kArticleSuggestionsFeature.name});
290 440
291 // Schedule() should get called for the second time after params have changed. 441 // Schedule() should get called for the second time after params have changed.
442 ChangeStatusOfUnderlyingProvider(
443 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
444 }
445
446 TEST_F(SchedulingRemoteSuggestionsProviderTest,
447 ReschedulesWhenOnUsageEventParamChanges) {
448 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(2);
449 ChangeStatusOfUnderlyingProvider(
450 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
451
452 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
453 // null. Change the wifi interval for this class.
454 variations::testing::VariationParamsManager params_manager(
455 ntp_snippets::kStudyName,
456 {{"soft_fetching_interval_hours-active-active_ntp_user", "1.5"}},
457 {kArticleSuggestionsFeature.name});
458
459 // Schedule() should get called for the second time after params have changed.
292 ChangeStatusOfUnderlyingProvider( 460 ChangeStatusOfUnderlyingProvider(
293 RemoteSuggestionsProvider::ProviderStatus::ACTIVE); 461 RemoteSuggestionsProvider::ProviderStatus::ACTIVE);
294 } 462 }
295 463
296 } // namespace ntp_snippets 464 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698