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

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

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Tim's comments and splitting RemoteSuggestionsProvider and RemoteSuggestionsProviderImpl Created 4 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6
7 #include <memory>
8 #include <set>
9 #include <string>
10 #include <utility>
11 #include <vector>
12
13 #include "base/command_line.h"
14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/run_loop.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/time/time.h"
20 #include "components/ntp_snippets/features.h"
21 #include "components/ntp_snippets/ntp_snippets_constants.h"
22 #include "components/ntp_snippets/pref_names.h"
23 #include "components/ntp_snippets/remote/persistent_scheduler.h"
24 #include "components/ntp_snippets/remote/remote_suggestions_provider.h"
25 #include "components/ntp_snippets/remote/test_utils.h"
26 #include "components/ntp_snippets/user_classifier.h"
27 #include "components/prefs/testing_pref_service.h"
28 #include "components/variations/variations_params_manager.h"
29 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31
32 using testing::ElementsAre;
33 using testing::Eq;
34 using testing::InSequence;
35 using testing::Invoke;
36 using testing::IsEmpty;
37 using testing::Mock;
38 using testing::MockFunction;
39 using testing::NiceMock;
40 using testing::Not;
41 using testing::SaveArg;
42 using testing::SizeIs;
43 using testing::StartsWith;
44 using testing::WithArgs;
45 using testing::_;
46
47 namespace ntp_snippets {
48
49 namespace {
50
51 const char* kDifferentWiFiInterval = "2";
52
53 class MockPersistentScheduler : public PersistentScheduler {
54 public:
55 MOCK_METHOD2(Schedule,
56 bool(base::TimeDelta period_wifi,
57 base::TimeDelta period_fallback));
58 MOCK_METHOD0(Unschedule, bool());
59 };
60
61 class MockRemoteSuggestionsProvider : public RemoteSuggestionsProvider {
62 public:
63 MOCK_METHOD2(Schedule,
64 bool(base::TimeDelta period_wifi,
65 base::TimeDelta period_fallback));
66 MOCK_METHOD0(Unschedule, bool());
67 };
68
69 } // namespace
70
71 class SchedulingRemoteSuggestionsProviderTest : public ::testing::Test {
72 public:
73 SchedulingRemoteSuggestionsProviderTest()
74 : user_classifier_(/*pref_service=*/nullptr) {
75 SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
76 utils_.pref_service()->registry());
77 }
78
79 std::unique_ptr<SchedulingRemoteSuggestionsProvider> MakeProvider {
80 auto provider = base::MakeUnique<MockRemoteSuggestionsProvider>();
81 provider_ = provider_.get();
82
83 auto scheduling_provider =
84 base::MakeUnique<SchedulingRemoteSuggestionsProvider>(
85 /*observer=*/nullptr, /*category_factory=*/nullptr,
86 std::move(provider), mock_persistent_scheduler(), &user_classifier_,
87 utils_.pref_service());
88 return scheduler;
89 }
90
91 protected:
92 MockPersistentScheduler* mock_persistent_scheduler() {
93 return &persistent_scheduler_;
94 }
95
96 private:
97 test::RemoteSuggestionsTestUtils utils_;
98 UserClassifier user_classifier_;
99 NiceMock<MockPersistentScheduler> persistent_scheduler_;
100 NiceMock<MockUpdater> updater_;
101 MockRemoteSuggestionsProvider* provider_;
102
103 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsSchedulerTest);
104 };
105
106
107
108 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleAfterFailedFetch) {
109 // We should get two |Schedule| calls: The first when initialization
110 // completes, the second one after the automatic (since the service doesn't
111 // have any data yet) fetch finishes.
112 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(2);
113 auto service = MakeSnippetsService();
114
115 // A failed fetch should NOT trigger another |Schedule|.
116 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(0);
117 LoadFromJSONString(service.get(), GetTestJson({GetInvalidSnippet()}));
118 }
119
120 TEST_F(RemoteSuggestionsProviderTest, RescheduleOnStateChange) {
121 {
122 InSequence s;
123 // Initial startup.
124 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(2);
125 // Service gets disabled.
126 EXPECT_CALL(mock_persistent_scheduler(), Unschedule());
127 // Service gets enabled again.
128 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(2);
129 }
130 auto service = MakeSnippetsService();
131 ASSERT_TRUE(service->ready());
132
133 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN,
134 RemoteSuggestionsStatus::EXPLICITLY_DISABLED);
135 ASSERT_FALSE(service->ready());
136 base::RunLoop().RunUntilIdle();
137
138 service->OnStatusChanged(RemoteSuggestionsStatus::EXPLICITLY_DISABLED,
139 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT);
140 ASSERT_TRUE(service->ready());
141 base::RunLoop().RunUntilIdle();
142 }
143
144
tschumann 2016/12/19 11:07:19 drop consecutive blank lines. same in line 106/107
jkrcal 2016/12/20 16:39:47 Done.
145
146
147 TEST_F(RemoteSuggestionsSchedulerTest, SchedulesOnStart) {
148 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
149 EXPECT_CALL(mock_persistent_scheduler(), Unschedule()).Times(0);
150
151 auto scheduler = MakeScheduler(/*enabled=*/true);
152 }
153
154 TEST_F(RemoteSuggestionsSchedulerTest, UnschedulesAfterBeingScheduled) {
155 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
156 auto scheduler = MakeScheduler(/*enabled=*/true);
157
158 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
159 EXPECT_CALL(mock_persistent_scheduler(), Unschedule());
160 scheduler->Unschedule();
161 }
162
163 TEST_F(RemoteSuggestionsSchedulerTest, DoesNotUnscheduleOnShutdown) {
164 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
165 EXPECT_CALL(mock_persistent_scheduler(), Unschedule()).Times(0);
166
167 auto scheduler = MakeScheduler(/*enabled=*/true);
168
169 // The scheduler will go out of scope and gets destroyed.
170 }
171
172 TEST_F(RemoteSuggestionsSchedulerTest, UnschedulesOnlyOnce) {
173 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
174 auto scheduler = MakeScheduler(/*enabled=*/true);
175
176 // Unschedule for the first time.
177 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
178 EXPECT_CALL(mock_persistent_scheduler(), Unschedule());
179 scheduler->Unschedule();
180
181 // When unscheduling again, we should not get any |Schedule| calls:
182 // The tasks are already unscheduled, so no need to do it again.
183 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
184 EXPECT_CALL(mock_persistent_scheduler(), Unschedule()).Times(0);
185 scheduler->Unschedule();
186 }
187
188 TEST_F(RemoteSuggestionsSchedulerTest, SchedulesOnlyOnce) {
189 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
190
191 auto scheduler = MakeScheduler(/*enabled=*/true);
192
193 // When scheduling again, we should not get any |Schedule| calls:
194 // The tasks are already scheduled with the correct intervals, so no need to
195 // do it again.
196 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
197 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(0);
198 scheduler->Schedule();
199 }
200
201 TEST_F(RemoteSuggestionsSchedulerTest, ReschedulesWhenWifiParamChanges) {
202 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
203 auto scheduler = MakeScheduler(/*enabled=*/true);
204
205 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
206 // null. Change the wifi interval for this class.
207 variations::testing::VariationParamsManager params_manager(
208 ntp_snippets::kStudyName,
209 {{"fetching_interval_hours-wifi-active_ntp_user",
210 kDifferentWiFiInterval}},
211 {kArticleSuggestionsFeature.name});
212
213 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
214 // After the change of a paramter, it should reschedule.
215 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
216 scheduler->Schedule();
217 }
218
219 TEST_F(RemoteSuggestionsSchedulerTest, ReschedulesWhenFallbackParamChanges) {
220 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
221 auto scheduler = MakeScheduler(/*enabled=*/true);
222
223 // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
224 // null. Change the wifi interval for this class.
225 variations::testing::VariationParamsManager params_manager(
226 ntp_snippets::kStudyName,
227 {{"fetching_interval_hours-fallback-active_ntp_user",
228 kDifferentWiFiInterval}},
229 {kArticleSuggestionsFeature.name});
230
231 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
232 // After the change of a paramter, it should reschedule.
233 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
234 scheduler->Schedule();
235 }
236
237 TEST_F(RemoteSuggestionsSchedulerTest, HandlesForcedReschedules) {
238 {
239 InSequence s;
240 // The initial scheduling.
241 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
242 // Forced rescheduling.
243 EXPECT_CALL(mock_persistent_scheduler(), Unschedule());
244 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
245 }
246
247 auto scheduler = MakeScheduler(/*enabled=*/true);
248 // Forced reschedule
249 scheduler->Unschedule();
250 scheduler->Schedule();
251 }
252
253 TEST_F(RemoteSuggestionsSchedulerTest, ReschedulesAfterSuccessfulUpdate) {
254 // The initial scheduling.
255 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
256 auto scheduler = MakeScheduler(/*enabled=*/true);
257 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
258
259 // Simulate a successful update.
260 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
261 scheduler->PerformHardUpdate();
262 }
263
264 TEST_F(RemoteSuggestionsSchedulerTest, DoesNotRescheduleAfterFailedUpdate) {
265 // The initial scheduling.
266 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
267 auto scheduler = MakeScheduler(/*enabled=*/true);
268 Mock::VerifyAndClearExpectations(mock_persistent_scheduler());
269
270 // Simulate a succesfull update.
271 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _)).Times(0);
272 scheduler->PerformHardUpdate();
273 // Failed -> do not call OnSuccessfulUpdate().
274 }
275
276 TEST_F(RemoteSuggestionsSchedulerTest, CallsUpdater) {
277 // The initial scheduling.
278 EXPECT_CALL(mock_persistent_scheduler(), Schedule(_, _));
279 auto scheduler = MakeScheduler(/*enabled=*/true);
280
281 // Simulate a succesfull update.
282 EXPECT_CALL(updater(), UpdateRemoteSuggestionsBySchedule());
283 scheduler->PerformHardUpdate();
284 }
285
286 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698