remote_suggestions_scheduler_impl_unittest.cc 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314
  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. #include "components/ntp_snippets/remote/remote_suggestions_scheduler_impl.h"
  5. #include <map>
  6. #include <memory>
  7. #include <set>
  8. #include <string>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/command_line.h"
  12. #include "base/run_loop.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/test/scoped_feature_list.h"
  15. #include "base/test/simple_test_clock.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/threading/thread_task_runner_handle.h"
  18. #include "base/time/clock.h"
  19. #include "base/time/default_clock.h"
  20. #include "base/time/time.h"
  21. #include "components/ntp_snippets/features.h"
  22. #include "components/ntp_snippets/ntp_snippets_constants.h"
  23. #include "components/ntp_snippets/pref_names.h"
  24. #include "components/ntp_snippets/remote/persistent_scheduler.h"
  25. #include "components/ntp_snippets/remote/remote_suggestions_provider.h"
  26. #include "components/ntp_snippets/remote/test_utils.h"
  27. #include "components/ntp_snippets/status.h"
  28. #include "components/ntp_snippets/user_classifier.h"
  29. #include "components/prefs/testing_pref_service.h"
  30. #include "components/sync_preferences/testing_pref_service_syncable.h"
  31. #include "components/web_resource/web_resource_pref_names.h"
  32. #include "net/base/mock_network_change_notifier.h"
  33. #include "net/base/network_change_notifier.h"
  34. #include "testing/gmock/include/gmock/gmock.h"
  35. #include "testing/gtest/include/gtest/gtest.h"
  36. using testing::AnyNumber;
  37. using testing::ElementsAre;
  38. using testing::Eq;
  39. using testing::Field;
  40. using testing::InSequence;
  41. using testing::Invoke;
  42. using testing::InvokeArgument;
  43. using testing::IsEmpty;
  44. using testing::Mock;
  45. using testing::MockFunction;
  46. using testing::Not;
  47. using testing::Return;
  48. using testing::SaveArg;
  49. using testing::SaveArgPointee;
  50. using testing::SizeIs;
  51. using testing::StartsWith;
  52. using testing::StrictMock;
  53. using testing::WithArgs;
  54. using testing::_;
  55. namespace ntp_snippets {
  56. class RemoteSuggestionsFetcher;
  57. namespace {
  58. const int kDefaultStartupIntervalHours = 24;
  59. ACTION_TEMPLATE(SaveArgByMove,
  60. HAS_1_TEMPLATE_PARAMS(int, k),
  61. AND_1_VALUE_PARAMS(pointer)) {
  62. *pointer = std::move(*::testing::get<k>(args));
  63. }
  64. class MockPersistentScheduler : public PersistentScheduler {
  65. public:
  66. MOCK_METHOD2(Schedule,
  67. bool(base::TimeDelta period_wifi,
  68. base::TimeDelta period_fallback));
  69. MOCK_METHOD0(Unschedule, bool());
  70. MOCK_METHOD0(IsOnUnmeteredConnection, bool());
  71. };
  72. // TODO(jkrcal): Move into its own library to reuse in other unit-tests?
  73. class MockRemoteSuggestionsProvider : public RemoteSuggestionsProvider {
  74. public:
  75. explicit MockRemoteSuggestionsProvider(Observer* observer)
  76. : RemoteSuggestionsProvider(observer) {}
  77. // Gmock cannot mock a method with movable-only type callback
  78. // FetchStatusCallback as a parameter. As a work-around, this function calls
  79. // the mock function with value passed by pointer. The mock function may then
  80. // be checked with EXPECT_CALL.
  81. void RefetchInTheBackground(
  82. RemoteSuggestionsProvider::FetchStatusCallback callback) override {
  83. RefetchInTheBackground(&callback);
  84. }
  85. MOCK_METHOD1(RefetchInTheBackground,
  86. void(RemoteSuggestionsProvider::FetchStatusCallback*));
  87. // Gmock cannot mock a method with movable-only type callback
  88. // FetchStatusCallback as a parameter. As a work-around, this function calls
  89. // the mock function with value passed by pointer. The mock function may then
  90. // be checked with EXPECT_CALL.
  91. void RefetchWhileDisplaying(
  92. RemoteSuggestionsProvider::FetchStatusCallback callback) override {
  93. RefetchWhileDisplaying(&callback);
  94. }
  95. MOCK_METHOD1(RefetchWhileDisplaying,
  96. void(RemoteSuggestionsProvider::FetchStatusCallback*));
  97. MOCK_CONST_METHOD0(suggestions_fetcher_for_debugging,
  98. const RemoteSuggestionsFetcher*());
  99. MOCK_CONST_METHOD1(GetUrlWithFavicon,
  100. GURL(const ContentSuggestion::ID& suggestion_id));
  101. MOCK_CONST_METHOD0(IsDisabled, bool());
  102. MOCK_CONST_METHOD0(ready, bool());
  103. MOCK_METHOD1(GetCategoryStatus, CategoryStatus(Category));
  104. MOCK_METHOD1(GetCategoryInfo, CategoryInfo(Category));
  105. MOCK_METHOD3(
  106. ClearHistory,
  107. void(base::Time begin,
  108. base::Time end,
  109. const base::RepeatingCallback<bool(const GURL& url)>& filter));
  110. // Gmock cannot mock a method with movable-only type callback
  111. // FetchDoneCallback as a parameter. As a work-around, this function calls the
  112. // mock function with value passed by pointer. The mock function may then be
  113. // checked with EXPECT_CALL.
  114. void Fetch(const Category& category,
  115. const std::set<std::string>& set,
  116. FetchDoneCallback callback) override {
  117. Fetch(category, set, &callback);
  118. }
  119. MOCK_METHOD3(Fetch,
  120. void(const Category&,
  121. const std::set<std::string>&,
  122. FetchDoneCallback*));
  123. MOCK_METHOD0(ReloadSuggestions, void());
  124. MOCK_METHOD0(ClearCachedSuggestions, void());
  125. MOCK_METHOD1(ClearDismissedSuggestionsForDebugging, void(Category));
  126. MOCK_METHOD1(DismissSuggestion, void(const ContentSuggestion::ID&));
  127. // Gmock cannot mock a method with movable-only type callback
  128. // ImageFetchedCallback as a parameter. As a work-around, this function calls
  129. // the mock function with value passed by pointer. The mock function may then
  130. // be checked with EXPECT_CALL.
  131. void FetchSuggestionImage(const ContentSuggestion::ID& id,
  132. ImageFetchedCallback callback) override {
  133. FetchSuggestionImage(id, &callback);
  134. }
  135. MOCK_METHOD2(FetchSuggestionImage,
  136. void(const ContentSuggestion::ID&, ImageFetchedCallback*));
  137. void FetchSuggestionImageData(const ContentSuggestion::ID& suggestion_id,
  138. ImageDataFetchedCallback callback) override {
  139. FetchSuggestionImageData(suggestion_id, &callback);
  140. }
  141. MOCK_METHOD2(FetchSuggestionImageData,
  142. void(const ContentSuggestion::ID&, ImageDataFetchedCallback*));
  143. void GetDismissedSuggestionsForDebugging(
  144. Category category,
  145. DismissedSuggestionsCallback callback) override {
  146. GetDismissedSuggestionsForDebugging(category, &callback);
  147. }
  148. MOCK_METHOD2(GetDismissedSuggestionsForDebugging,
  149. void(Category category, DismissedSuggestionsCallback* callback));
  150. MOCK_METHOD1(OnSignInStateChanged, void(bool));
  151. };
  152. class FakeOfflineNetworkChangeNotifier {
  153. public:
  154. FakeOfflineNetworkChangeNotifier() {
  155. notifier_->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
  156. }
  157. private:
  158. std::unique_ptr<net::test::MockNetworkChangeNotifier> notifier_ =
  159. net::test::MockNetworkChangeNotifier::Create();
  160. };
  161. } // namespace
  162. class RemoteSuggestionsSchedulerImplTest : public ::testing::Test {
  163. public:
  164. RemoteSuggestionsSchedulerImplTest()
  165. : // For the test we enabled all trigger types.
  166. default_variation_params_{{"scheduler_trigger_types",
  167. "persistent_scheduler_wake_up,ntp_opened,"
  168. "browser_foregrounded,browser_cold_start"}},
  169. user_classifier_(/*pref_service=*/nullptr,
  170. base::DefaultClock::GetInstance()) {
  171. scoped_feature_list_.InitAndEnableFeatureWithParameters(
  172. ntp_snippets::kArticleSuggestionsFeature, default_variation_params_);
  173. RemoteSuggestionsSchedulerImpl::RegisterProfilePrefs(
  174. utils_.pref_service()->registry());
  175. RequestThrottler::RegisterProfilePrefs(utils_.pref_service()->registry());
  176. // TODO(jkrcal) Create a static function in EulaAcceptedNotifier that
  177. // registers this pref and replace the call in browser_process_impl.cc & in
  178. // eula_accepted_notifier_unittest.cc with the new static function.
  179. local_state_.registry()->RegisterBooleanPref(::prefs::kEulaAccepted, false);
  180. // By default pretend we are on WiFi.
  181. EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
  182. .WillRepeatedly(Return(true));
  183. ResetProvider();
  184. }
  185. RemoteSuggestionsSchedulerImplTest(
  186. const RemoteSuggestionsSchedulerImplTest&) = delete;
  187. RemoteSuggestionsSchedulerImplTest& operator=(
  188. const RemoteSuggestionsSchedulerImplTest&) = delete;
  189. void ResetProvider() {
  190. provider_ = std::make_unique<StrictMock<MockRemoteSuggestionsProvider>>(
  191. /*observer=*/nullptr);
  192. test_clock_.SetNow(base::Time::Now());
  193. scheduler_ = std::make_unique<RemoteSuggestionsSchedulerImpl>(
  194. &persistent_scheduler_, &user_classifier_, utils_.pref_service(),
  195. &local_state_, &test_clock_);
  196. scheduler_->SetProvider(provider_.get());
  197. }
  198. void SetVariationParameter(const std::string& param_name,
  199. const std::string& param_value) {
  200. std::map<std::string, std::string> params = default_variation_params_;
  201. params[param_name] = param_value;
  202. scoped_feature_list_.Reset();
  203. scoped_feature_list_.InitAndEnableFeatureWithParameters(
  204. ntp_snippets::kArticleSuggestionsFeature, params);
  205. }
  206. bool IsEulaNotifierAvailable() {
  207. // Create() returns a unique_ptr, so this is no leak.
  208. return web_resource::EulaAcceptedNotifier::Create(&local_state_) != nullptr;
  209. }
  210. void SetEulaAcceptedPref() {
  211. local_state_.SetBoolean(::prefs::kEulaAccepted, true);
  212. }
  213. // GMock cannot deal with move-only types. We need to pass the vector to the
  214. // mock function as const ref using this wrapper callback.
  215. void FetchDoneWrapper(
  216. MockFunction<void(Status status_code,
  217. const std::vector<ContentSuggestion>& suggestions)>*
  218. fetch_done,
  219. Status status_code,
  220. std::vector<ContentSuggestion> suggestions) {
  221. fetch_done->Call(status_code, suggestions);
  222. }
  223. protected:
  224. std::map<std::string, std::string> default_variation_params_;
  225. base::test::ScopedFeatureList scoped_feature_list_;
  226. void ActivateProviderAndEula() {
  227. SetEulaAcceptedPref();
  228. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(true));
  229. scheduler_->OnProviderActivated();
  230. }
  231. void ActivateProvider() {
  232. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(true));
  233. scheduler_->OnProviderActivated();
  234. }
  235. void DeactivateProvider() {
  236. scheduler_->OnProviderDeactivated();
  237. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(true));
  238. }
  239. void ExpectOneRetiringRefetchInTheBackground() {
  240. // After a successful fetch, the client updates it's schedule, so we expect
  241. // another call here.
  242. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).RetiresOnSaturation();
  243. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  244. .WillOnce(Invoke(
  245. [](RemoteSuggestionsProvider::FetchStatusCallback* callback) {
  246. std::move(*callback).Run(Status::Success());
  247. }))
  248. .RetiresOnSaturation();
  249. }
  250. MockPersistentScheduler* persistent_scheduler() {
  251. return &persistent_scheduler_;
  252. }
  253. base::SimpleTestClock* test_clock() { return &test_clock_; }
  254. MockRemoteSuggestionsProvider* provider() { return provider_.get(); }
  255. RemoteSuggestionsSchedulerImpl* scheduler() { return scheduler_.get(); }
  256. private:
  257. // Required to instantiate a net::test::MockNetworkChangeNotifier, because it
  258. // uses ObserverListThreadSafe.
  259. base::test::TaskEnvironment task_environment_;
  260. test::RemoteSuggestionsTestUtils utils_;
  261. UserClassifier user_classifier_;
  262. TestingPrefServiceSimple local_state_;
  263. StrictMock<MockPersistentScheduler> persistent_scheduler_;
  264. base::SimpleTestClock test_clock_;
  265. std::unique_ptr<MockRemoteSuggestionsProvider> provider_;
  266. std::unique_ptr<RemoteSuggestionsSchedulerImpl> scheduler_;
  267. };
  268. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldIgnoreSignalsWhenNotEnabled) {
  269. // The signals should be ignored even if the provider itself claims it is
  270. // ready.
  271. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(true));
  272. scheduler()->OnPersistentSchedulerWakeUp();
  273. scheduler()->OnSuggestionsSurfaceOpened();
  274. scheduler()->OnBrowserForegrounded();
  275. scheduler()->OnBrowserColdStart();
  276. }
  277. TEST_F(RemoteSuggestionsSchedulerImplTest,
  278. ShouldIgnoreEulaStateOnPlatformsWhereNotAvaiable) {
  279. // Only run this tests on platforms that don't support Eula.
  280. if (IsEulaNotifierAvailable()) {
  281. return;
  282. }
  283. // Activating the provider should schedule the persistent background fetches.
  284. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  285. ActivateProvider();
  286. // Verify fetches get triggered.
  287. ExpectOneRetiringRefetchInTheBackground();
  288. scheduler()->OnPersistentSchedulerWakeUp();
  289. }
  290. TEST_F(RemoteSuggestionsSchedulerImplTest,
  291. ShouldIgnoreSignalsWhenEulaNotAccepted) {
  292. // Only run this tests on platforms supporting Eula.
  293. if (!IsEulaNotifierAvailable()) {
  294. return;
  295. }
  296. // Activating the provider should schedule the persistent background fetches.
  297. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  298. ActivateProvider();
  299. // All signals are ignored because of Eula not being accepted.
  300. scheduler()->OnPersistentSchedulerWakeUp();
  301. scheduler()->OnSuggestionsSurfaceOpened();
  302. scheduler()->OnBrowserForegrounded();
  303. scheduler()->OnBrowserColdStart();
  304. }
  305. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldFetchWhenEulaGetsAccepted) {
  306. // Only run this tests on platforms supporting Eula.
  307. if (!IsEulaNotifierAvailable()) {
  308. return;
  309. }
  310. // Activating the provider should schedule the persistent background fetches.
  311. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  312. ActivateProvider();
  313. // Make one (ignored) call to make sure we are interested in eula state.
  314. scheduler()->OnPersistentSchedulerWakeUp();
  315. // Accepting Eula afterwards results in a background fetch.
  316. ExpectOneRetiringRefetchInTheBackground();
  317. SetEulaAcceptedPref();
  318. }
  319. TEST_F(RemoteSuggestionsSchedulerImplTest,
  320. ShouldQueueBackgroundRequestIfEulaIsMissing) {
  321. // Only run this tests on platforms supporting Eula.
  322. if (!IsEulaNotifierAvailable()) {
  323. return;
  324. }
  325. // Eula is not ready -- no fetch. But request should get queued.
  326. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  327. scheduler()->OnPersistentSchedulerWakeUp();
  328. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  329. // Activate provider -- this should set up the schedule but cannot trigger a
  330. // fetch due to Eula missing.
  331. ActivateProvider();
  332. // Accepting Eula picks up the queued fetch.
  333. ExpectOneRetiringRefetchInTheBackground();
  334. SetEulaAcceptedPref();
  335. }
  336. TEST_F(RemoteSuggestionsSchedulerImplTest,
  337. ShouldQueueBackgroundRequestBeforeActivated) {
  338. // Set the Eula bit to be sure we queue them because of not being activated.
  339. SetEulaAcceptedPref();
  340. // Activate provider -- this should set up the schedule and store it to prefs.
  341. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).RetiresOnSaturation();
  342. ActivateProvider();
  343. // Reset the provider after we have the schedule stored in prefs.
  344. ResetProvider();
  345. // Provider is not active -- no fetch. But request should get queued.
  346. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  347. scheduler()->OnPersistentSchedulerWakeUp();
  348. ExpectOneRetiringRefetchInTheBackground();
  349. // Activate provider -- this should trigger the fetch (the schedule was set up
  350. // previously).
  351. ActivateProvider();
  352. }
  353. TEST_F(RemoteSuggestionsSchedulerImplTest,
  354. ShouldIgnoreSignalsWhenDisabledByParam) {
  355. // First set an empty list of allowed trigger types.
  356. SetVariationParameter("scheduler_trigger_types", "-");
  357. ResetProvider();
  358. // Then enable the scheduler.
  359. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  360. ActivateProviderAndEula();
  361. scheduler()->OnPersistentSchedulerWakeUp();
  362. scheduler()->OnSuggestionsSurfaceOpened();
  363. scheduler()->OnBrowserForegrounded();
  364. scheduler()->OnBrowserColdStart();
  365. }
  366. TEST_F(RemoteSuggestionsSchedulerImplTest,
  367. ShouldHandleEmptyParamForTriggerTypes) {
  368. // First set an empty param for allowed trigger types -> should result in the
  369. // default list.
  370. SetVariationParameter("scheduler_trigger_types", "");
  371. ResetProvider();
  372. // Then enable the scheduler.
  373. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  374. ActivateProviderAndEula();
  375. // For instance, persistent scheduler wake up should be enabled by default.
  376. ExpectOneRetiringRefetchInTheBackground();
  377. scheduler()->OnPersistentSchedulerWakeUp();
  378. }
  379. TEST_F(RemoteSuggestionsSchedulerImplTest,
  380. ShouldHandleIncorrentParamForTriggerTypes) {
  381. // First set an invalid list of allowed trigger types.
  382. SetVariationParameter("scheduler_trigger_types", "ntp_opened,foo;");
  383. ResetProvider();
  384. // Then enable the scheduler.
  385. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  386. ActivateProviderAndEula();
  387. // For instance, persistent scheduler wake up should be enabled by default.
  388. ExpectOneRetiringRefetchInTheBackground();
  389. scheduler()->OnPersistentSchedulerWakeUp();
  390. }
  391. TEST_F(RemoteSuggestionsSchedulerImplTest,
  392. ShouldFetchOnPersistentSchedulerWakeUp) {
  393. // First set only this type to be allowed.
  394. SetVariationParameter("scheduler_trigger_types",
  395. "persistent_scheduler_wake_up");
  396. ResetProvider();
  397. // Then enable the scheduler.
  398. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  399. ActivateProviderAndEula();
  400. ExpectOneRetiringRefetchInTheBackground();
  401. scheduler()->OnPersistentSchedulerWakeUp();
  402. }
  403. TEST_F(RemoteSuggestionsSchedulerImplTest,
  404. ShouldFetchOnPersistentSchedulerWakeUpRepeated) {
  405. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  406. {
  407. InSequence s;
  408. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  409. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  410. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  411. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  412. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  413. }
  414. // First enable the scheduler -- calling Schedule() for the first time.
  415. ActivateProviderAndEula();
  416. // Make the first persistent fetch successful -- calling Schedule() again.
  417. scheduler()->OnPersistentSchedulerWakeUp();
  418. std::move(signal_fetch_done).Run(Status::Success());
  419. // Make the second fetch.
  420. scheduler()->OnPersistentSchedulerWakeUp();
  421. }
  422. TEST_F(RemoteSuggestionsSchedulerImplTest,
  423. ShouldNotTriggerBackgroundFetchIfAlreadyInProgess) {
  424. {
  425. InSequence s;
  426. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  427. // We do not capture and execute the callback to keep the fetch in-flight.
  428. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  429. // Refetch is not called after the second trigger.
  430. }
  431. // First enable the scheduler -- calling Schedule() for the first time.
  432. ActivateProviderAndEula();
  433. // Make the first persistent fetch never finish.
  434. scheduler()->OnPersistentSchedulerWakeUp();
  435. // Make the second fetch.
  436. scheduler()->OnPersistentSchedulerWakeUp();
  437. }
  438. TEST_F(RemoteSuggestionsSchedulerImplTest,
  439. ShouldFetchOnSuggestionsSurfaceOpenedForTheFirstTime) {
  440. // First set only this type to be allowed.
  441. SetVariationParameter("scheduler_trigger_types", "ntp_opened");
  442. ResetProvider();
  443. // Then enable the scheduler.
  444. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  445. ActivateProviderAndEula();
  446. ExpectOneRetiringRefetchInTheBackground();
  447. scheduler()->OnSuggestionsSurfaceOpened();
  448. }
  449. TEST_F(RemoteSuggestionsSchedulerImplTest,
  450. ShouldFetchOnBrowserForegroundedForTheFirstTime) {
  451. // First set only this type to be allowed.
  452. SetVariationParameter("scheduler_trigger_types", "browser_foregrounded");
  453. ResetProvider();
  454. // Then enable the scheduler.
  455. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  456. ActivateProviderAndEula();
  457. ExpectOneRetiringRefetchInTheBackground();
  458. scheduler()->OnBrowserForegrounded();
  459. }
  460. TEST_F(RemoteSuggestionsSchedulerImplTest,
  461. ShouldFetchOnBrowserColdStartForTheFirstTime) {
  462. // Then enable the scheduler.
  463. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  464. ActivateProviderAndEula();
  465. ExpectOneRetiringRefetchInTheBackground();
  466. scheduler()->OnBrowserColdStart();
  467. }
  468. TEST_F(RemoteSuggestionsSchedulerImplTest,
  469. ShouldQueueBackgroundFetchSignalsOnPersistentSchedulerWakeUp) {
  470. // Enable EULA to make this test not depend on that setting (or it being
  471. // flipped)
  472. SetEulaAcceptedPref();
  473. // On activation, the Schedule should get updated and the queued background
  474. // fetch should get propagated.
  475. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  476. scheduler()->OnPersistentSchedulerWakeUp();
  477. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  478. ExpectOneRetiringRefetchInTheBackground();
  479. ActivateProviderAndEula();
  480. }
  481. TEST_F(RemoteSuggestionsSchedulerImplTest,
  482. ShouldQueueBackgroundFetchSignalsOnSurfaceOpened) {
  483. // Enable EULA to make this test not depend on that setting (or it being
  484. // flipped)
  485. SetEulaAcceptedPref();
  486. // On activation, the Schedule should get updated and the queued background
  487. // fetch should get propagated.
  488. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  489. scheduler()->OnSuggestionsSurfaceOpened();
  490. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  491. ExpectOneRetiringRefetchInTheBackground();
  492. ActivateProviderAndEula();
  493. }
  494. TEST_F(RemoteSuggestionsSchedulerImplTest,
  495. ShouldQueueBackgroundFetchSignalsOnBrowserForegrounded) {
  496. // Enable EULA to make this test not depend on that setting (or it being
  497. // flipped)
  498. SetEulaAcceptedPref();
  499. // On activation, the Schedule should get updated and the queued background
  500. // fetch should get propagated.
  501. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  502. scheduler()->OnBrowserForegrounded();
  503. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  504. ExpectOneRetiringRefetchInTheBackground();
  505. ActivateProviderAndEula();
  506. }
  507. TEST_F(RemoteSuggestionsSchedulerImplTest,
  508. ShouldQueueBackgroundFetchSignalsOnBrowserColdStart) {
  509. // Enable EULA to make this test not depend on that setting (or it being
  510. // flipped)
  511. SetEulaAcceptedPref();
  512. // On activation, the Schedule should get updated and the queued background
  513. // fetch should get propagated.
  514. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  515. scheduler()->OnBrowserColdStart();
  516. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  517. ExpectOneRetiringRefetchInTheBackground();
  518. ActivateProviderAndEula();
  519. }
  520. TEST_F(RemoteSuggestionsSchedulerImplTest,
  521. ShouldQueueMultipleBackgroundFetchSignals) {
  522. // Enable EULA to make this test not depend on that setting (or it being
  523. // flipped)
  524. SetEulaAcceptedPref();
  525. // We want to store multiple events to respect lower thresholds for specific
  526. // events properly. To test this, we do the following setup:
  527. // (1) Force a fetch.
  528. // (2) Simulate a stop of the browser, wait until surface-opened would trigger
  529. // a fetch but start-up would not trigger a fetch yet.
  530. // (3) simulate a very slow initialization, where the scheduler sees both
  531. // events (cold start and surface opened) before being activated.
  532. // (4) make sure that activation triggers a background fetch.
  533. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(AnyNumber());
  534. ActivateProviderAndEula();
  535. ExpectOneRetiringRefetchInTheBackground();
  536. scheduler()->OnBrowserColdStart();
  537. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER - we work with the
  538. // default interval for this class here. This time would allow for a fetch on
  539. // NTP open but not on cold start.
  540. test_clock()->Advance(base::Hours(13));
  541. // This should *not* trigger a fetch.
  542. scheduler()->OnBrowserColdStart();
  543. // Simulate a restart.
  544. EXPECT_CALL(*persistent_scheduler(), Unschedule());
  545. scheduler()->OnProviderDeactivated();
  546. ResetProvider(); // Also resets the scheduler and test clock.
  547. test_clock()->Advance(base::Hours(13));
  548. EXPECT_CALL(*provider(), ready()).WillRepeatedly(Return(false));
  549. scheduler()->OnSuggestionsSurfaceOpened();
  550. scheduler()->OnBrowserColdStart();
  551. ExpectOneRetiringRefetchInTheBackground();
  552. // Signal the provider is ready (EULA check should still pass from the first
  553. // start). We don't want to trigger EULA again as it will simulate a
  554. // persistent fetch.
  555. ActivateProviderAndEula();
  556. }
  557. TEST_F(RemoteSuggestionsSchedulerImplTest,
  558. ShouldNotFetchOnSuggestionsSurfaceOpenedAfterSuccessfulSoftFetch) {
  559. // First enable the scheduler; the second Schedule is called after the
  560. // successful fetch.
  561. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  562. ActivateProviderAndEula();
  563. // Make the first soft fetch successful.
  564. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  565. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  566. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  567. scheduler()->OnSuggestionsSurfaceOpened();
  568. std::move(signal_fetch_done).Run(Status::Success());
  569. // The second call is ignored if it happens right after the first one.
  570. scheduler()->OnSuggestionsSurfaceOpened();
  571. }
  572. TEST_F(RemoteSuggestionsSchedulerImplTest,
  573. ShouldNotFetchOnSuggestionsSurfaceOpenedAfterSuccessfulPersistentFetch) {
  574. // First enable the scheduler; the second Schedule is called after the
  575. // successful fetch.
  576. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  577. ActivateProviderAndEula();
  578. // Make the first persistent fetch successful.
  579. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  580. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  581. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  582. scheduler()->OnPersistentSchedulerWakeUp();
  583. std::move(signal_fetch_done).Run(Status::Success());
  584. // The second call is ignored if it happens right after the first one.
  585. scheduler()->OnSuggestionsSurfaceOpened();
  586. }
  587. TEST_F(RemoteSuggestionsSchedulerImplTest,
  588. ShouldNotFetchOnSuggestionsSurfaceOpenedAfterFailedSoftFetch) {
  589. // First enable the scheduler.
  590. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  591. ActivateProviderAndEula();
  592. // Make the first soft fetch failed.
  593. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  594. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  595. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  596. scheduler()->OnSuggestionsSurfaceOpened();
  597. std::move(signal_fetch_done).Run(Status(StatusCode::PERMANENT_ERROR, ""));
  598. // The second call is ignored if it happens right after the first one.
  599. scheduler()->OnSuggestionsSurfaceOpened();
  600. }
  601. TEST_F(RemoteSuggestionsSchedulerImplTest,
  602. ShouldNotFetchOnSuggestionsSurfaceOpenedAfterFailedPersistentFetch) {
  603. // First enable the scheduler.
  604. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  605. ActivateProviderAndEula();
  606. // Make the first persistent fetch failed.
  607. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  608. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  609. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  610. scheduler()->OnPersistentSchedulerWakeUp();
  611. std::move(signal_fetch_done).Run(Status(StatusCode::PERMANENT_ERROR, ""));
  612. // The second call is ignored if it happens right after the first one.
  613. scheduler()->OnSuggestionsSurfaceOpened();
  614. }
  615. TEST_F(RemoteSuggestionsSchedulerImplTest,
  616. ShouldFetchAgainOnBrowserForgroundLaterAgain) {
  617. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  618. {
  619. InSequence s;
  620. // Initial scheduling after being enabled.
  621. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  622. // The first call to NTPOpened results in a fetch.
  623. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  624. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  625. // Rescheduling after a succesful fetch.
  626. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  627. // The second call to NTPOpened 4hrs later again results in a fetch.
  628. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  629. }
  630. // First enable the scheduler.
  631. ActivateProviderAndEula();
  632. // Make the first soft fetch successful.
  633. scheduler()->OnBrowserForegrounded();
  634. std::move(signal_fetch_done).Run(Status::Success());
  635. test_clock()->Advance(base::Hours(kDefaultStartupIntervalHours));
  636. scheduler()->OnBrowserForegrounded();
  637. }
  638. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldRescheduleOnBrowserUpgraded) {
  639. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  640. scheduler()->OnBrowserUpgraded();
  641. }
  642. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldScheduleOnActivation) {
  643. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  644. ActivateProviderAndEula();
  645. }
  646. TEST_F(RemoteSuggestionsSchedulerImplTest,
  647. ShouldUnscheduleOnLaterInactivation) {
  648. {
  649. InSequence s;
  650. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  651. EXPECT_CALL(*persistent_scheduler(), Unschedule());
  652. }
  653. ActivateProviderAndEula();
  654. DeactivateProvider();
  655. }
  656. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldScheduleOnLaterActivation) {
  657. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  658. // There is no schedule yet, so inactivation does not trigger unschedule.
  659. DeactivateProvider();
  660. ActivateProviderAndEula();
  661. }
  662. TEST_F(RemoteSuggestionsSchedulerImplTest,
  663. ShouldRescheduleAfterSuccessfulFetch) {
  664. // First reschedule on becoming active.
  665. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  666. ActivateProviderAndEula();
  667. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  668. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  669. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  670. // Trigger a fetch.
  671. scheduler()->OnPersistentSchedulerWakeUp();
  672. // Second reschedule after a successful fetch.
  673. std::move(signal_fetch_done).Run(Status::Success());
  674. }
  675. TEST_F(RemoteSuggestionsSchedulerImplTest,
  676. ShouldNotRescheduleAfterFailedFetch) {
  677. // Only reschedule on becoming active.
  678. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  679. ActivateProviderAndEula();
  680. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  681. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  682. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  683. // Trigger a fetch.
  684. scheduler()->OnPersistentSchedulerWakeUp();
  685. // No furter reschedule after a failure.
  686. std::move(signal_fetch_done).Run(Status(StatusCode::PERMANENT_ERROR, ""));
  687. }
  688. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldScheduleOnlyOnce) {
  689. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  690. ActivateProviderAndEula();
  691. // No further call to Schedule on a second status callback.
  692. ActivateProviderAndEula();
  693. }
  694. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldUnscheduleOnlyOnce) {
  695. {
  696. InSequence s;
  697. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  698. EXPECT_CALL(*persistent_scheduler(), Unschedule());
  699. }
  700. // First schedule so that later we really unschedule.
  701. ActivateProviderAndEula();
  702. DeactivateProvider();
  703. // No further call to Unschedule on second status callback.
  704. DeactivateProvider();
  705. }
  706. TEST_F(RemoteSuggestionsSchedulerImplTest,
  707. ReschedulesWhenPersistentWifiParamChanges) {
  708. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  709. ActivateProviderAndEula();
  710. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  711. // null. Change the wifi interval for this class.
  712. SetVariationParameter("fetching_interval_hours-wifi-active_ntp_user", "1.5");
  713. // Schedule() should get called for the second time after params have changed.
  714. ActivateProviderAndEula();
  715. }
  716. TEST_F(RemoteSuggestionsSchedulerImplTest,
  717. ReschedulesWhenPersistentFallbackParamChanges) {
  718. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  719. ActivateProviderAndEula();
  720. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  721. // null. Change the fallback interval for this class.
  722. SetVariationParameter("fetching_interval_hours-fallback-active_ntp_user",
  723. "1.5");
  724. // Schedule() should get called for the second time after params have changed.
  725. ActivateProviderAndEula();
  726. }
  727. TEST_F(RemoteSuggestionsSchedulerImplTest,
  728. ReschedulesWhenShownWifiParamChanges) {
  729. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  730. ActivateProviderAndEula();
  731. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  732. // null. Change the on usage interval for this class.
  733. SetVariationParameter("soft_fetching_interval_hours-wifi-active_ntp_user",
  734. "1.5");
  735. // Schedule() should get called for the second time after params have changed.
  736. ActivateProviderAndEula();
  737. }
  738. TEST_F(RemoteSuggestionsSchedulerImplTest,
  739. ReschedulesWhenShownFallbackParamChanges) {
  740. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  741. ActivateProviderAndEula();
  742. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  743. // null. Change the fallback interval for this class.
  744. SetVariationParameter("soft_fetching_interval_hours-fallback-active_ntp_user",
  745. "1.5");
  746. // Schedule() should get called for the second time after params have changed.
  747. ActivateProviderAndEula();
  748. }
  749. TEST_F(RemoteSuggestionsSchedulerImplTest,
  750. ReschedulesWhenStartupWifiParamChanges) {
  751. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  752. ActivateProviderAndEula();
  753. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  754. // null. Change the on usage interval for this class.
  755. SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
  756. "1.5");
  757. // Schedule() should get called for the second time after params have changed.
  758. ActivateProviderAndEula();
  759. }
  760. TEST_F(RemoteSuggestionsSchedulerImplTest,
  761. ReschedulesWhenStartupFallbackParamChanges) {
  762. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  763. ActivateProviderAndEula();
  764. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  765. // null. Change the fallback interval for this class.
  766. SetVariationParameter(
  767. "startup_fetching_interval_hours-fallback-active_ntp_user", "1.5");
  768. // Schedule() should get called for the second time after params have changed.
  769. ActivateProviderAndEula();
  770. }
  771. TEST_F(RemoteSuggestionsSchedulerImplTest, FetchIntervalForShownTriggerOnWifi) {
  772. // Pretend we are on WiFi (already done in ctor, we make it explicit here).
  773. EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
  774. .WillRepeatedly(Return(true));
  775. // Initial scheduling after being enabled.
  776. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  777. ActivateProviderAndEula();
  778. // The first call to NTPOpened results in a fetch.
  779. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  780. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  781. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  782. scheduler()->OnSuggestionsSurfaceOpened();
  783. // Rescheduling after a succesful fetch.
  784. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  785. std::move(signal_fetch_done).Run(Status::Success());
  786. // Open NTP again after too short delay (one minute missing). UserClassifier
  787. // defaults to UserClass::ACTIVE_NTP_USER - we work with the default interval
  788. // for this class here. This time no fetch is executed.
  789. test_clock()->Advance(base::Hours(4) - base::Minutes(1));
  790. scheduler()->OnSuggestionsSurfaceOpened();
  791. // Open NTP after another delay, now together long enough to issue a fetch.
  792. test_clock()->Advance(base::Minutes(2));
  793. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  794. scheduler()->OnSuggestionsSurfaceOpened();
  795. }
  796. TEST_F(RemoteSuggestionsSchedulerImplTest,
  797. OverrideFetchIntervalForShownTriggerOnWifi) {
  798. // Pretend we are on WiFi (already done in ctor, we make it explicit here).
  799. EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
  800. .WillRepeatedly(Return(true));
  801. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  802. // null. Change the interval for this class from 4h to 30min.
  803. SetVariationParameter("soft_fetching_interval_hours-wifi-active_ntp_user",
  804. "0.5");
  805. // Initial scheduling after being enabled.
  806. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  807. ActivateProviderAndEula();
  808. // The first call to NTPOpened results in a fetch.
  809. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  810. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  811. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  812. scheduler()->OnSuggestionsSurfaceOpened();
  813. // Rescheduling after a succesful fetch.
  814. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  815. std::move(signal_fetch_done).Run(Status::Success());
  816. // Open NTP again after too short delay. This time no fetch is executed.
  817. test_clock()->Advance(base::Minutes(20));
  818. scheduler()->OnSuggestionsSurfaceOpened();
  819. // Open NTP after another delay, now together long enough to issue a fetch.
  820. test_clock()->Advance(base::Minutes(10));
  821. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  822. scheduler()->OnSuggestionsSurfaceOpened();
  823. }
  824. TEST_F(RemoteSuggestionsSchedulerImplTest,
  825. FetchIntervalForShownTriggerOnFallback) {
  826. // Pretend we are not on wifi -> fallback connection.
  827. EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
  828. .WillRepeatedly(Return(false));
  829. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER which uses a 12h time
  830. // interval by default for shown trigger not on WiFi.
  831. // Initial scheduling after being enabled.
  832. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  833. ActivateProviderAndEula();
  834. // The first call to NTPOpened results in a fetch.
  835. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  836. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  837. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  838. scheduler()->OnSuggestionsSurfaceOpened();
  839. // Rescheduling after a succesful fetch.
  840. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  841. std::move(signal_fetch_done).Run(Status::Success());
  842. // Open NTP again after too short delay. This time no fetch is executed.
  843. test_clock()->Advance(base::Hours(4) - base::Minutes(1));
  844. scheduler()->OnSuggestionsSurfaceOpened();
  845. // Open NTP after another delay, now together long enough to issue a fetch.
  846. test_clock()->Advance(base::Minutes(2));
  847. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  848. scheduler()->OnSuggestionsSurfaceOpened();
  849. }
  850. TEST_F(RemoteSuggestionsSchedulerImplTest,
  851. OverrideFetchIntervalForShownTriggerOnFallback) {
  852. // Pretend we are not on wifi -> fallback connection.
  853. EXPECT_CALL(*persistent_scheduler(), IsOnUnmeteredConnection())
  854. .WillRepeatedly(Return(false));
  855. // UserClassifier defaults to UserClass::ACTIVE_NTP_USER if PrefService is
  856. // null. Change the interval for this class from 4h to 30min.
  857. SetVariationParameter("soft_fetching_interval_hours-fallback-active_ntp_user",
  858. "0.5");
  859. // Initial scheduling after being enabled.
  860. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  861. ActivateProviderAndEula();
  862. // The first call to NTPOpened results in a fetch.
  863. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  864. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  865. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  866. scheduler()->OnSuggestionsSurfaceOpened();
  867. // Rescheduling after a succesful fetch.
  868. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  869. std::move(signal_fetch_done).Run(Status::Success());
  870. // Open NTP again after too short delay. This time no fetch is executed.
  871. test_clock()->Advance(base::Minutes(20));
  872. scheduler()->OnSuggestionsSurfaceOpened();
  873. // Open NTP after another delay, now together long enough to issue a fetch.
  874. test_clock()->Advance(base::Minutes(10));
  875. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  876. scheduler()->OnSuggestionsSurfaceOpened();
  877. }
  878. TEST_F(RemoteSuggestionsSchedulerImplTest,
  879. ShouldBlockFetchingForSomeTimeAfterHistoryCleared) {
  880. // First enable the scheduler -- this will trigger the persistent scheduling.
  881. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  882. ActivateProviderAndEula();
  883. // Clear the history.
  884. scheduler()->OnHistoryCleared();
  885. // A trigger after 15 minutes is ignored.
  886. test_clock()->Advance(base::Minutes(15));
  887. scheduler()->OnBrowserForegrounded();
  888. // A trigger after another 16 minutes is performed (more than 30m after
  889. // clearing the history).
  890. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_));
  891. test_clock()->Advance(base::Minutes(16));
  892. scheduler()->OnBrowserForegrounded();
  893. }
  894. TEST_F(RemoteSuggestionsSchedulerImplTest,
  895. ShouldImmediatelyFetchAfterSuggestionsCleared) {
  896. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  897. // First enable the scheduler -- this will trigger the persistent scheduling.
  898. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  899. ActivateProviderAndEula();
  900. // The first trigger results in a fetch.
  901. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  902. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  903. scheduler()->OnBrowserForegrounded();
  904. // Make the fetch successful -- this results in rescheduling.
  905. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  906. std::move(signal_fetch_done).Run(Status::Success());
  907. // Clear the suggestions - results in an immediate fetch.
  908. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_));
  909. scheduler()->OnSuggestionsCleared();
  910. }
  911. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldThrottleInteractiveRequests) {
  912. // Change the quota for interactive requests ("active NTP user" is the default
  913. // class in tests).
  914. SetVariationParameter("interactive_quota_SuggestionFetcherActiveNTPUser",
  915. "10");
  916. ResetProvider();
  917. for (int x = 0; x < 10; ++x) {
  918. EXPECT_THAT(scheduler()->AcquireQuotaForInteractiveFetch(), Eq(true));
  919. }
  920. // Now the quota is over.
  921. EXPECT_THAT(scheduler()->AcquireQuotaForInteractiveFetch(), Eq(false));
  922. }
  923. TEST_F(RemoteSuggestionsSchedulerImplTest,
  924. ShouldThrottleNonInteractiveRequests) {
  925. // Change the quota for interactive requests ("active NTP user" is the default
  926. // class in tests).
  927. SetVariationParameter("quota_SuggestionFetcherActiveNTPUser", "5");
  928. ResetProvider();
  929. // One scheduling on start, 5 times after successful fetches.
  930. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(6);
  931. // First enable the scheduler -- this will trigger the persistent scheduling.
  932. ActivateProviderAndEula();
  933. // As long as the quota suffices, the call gets through.
  934. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  935. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  936. .Times(5)
  937. .WillRepeatedly(SaveArgByMove<0>(&signal_fetch_done));
  938. for (int x = 0; x < 5; ++x) {
  939. scheduler()->OnPersistentSchedulerWakeUp();
  940. std::move(signal_fetch_done).Run(Status::Success());
  941. }
  942. // For the 6th time, it is blocked by the scheduling provider.
  943. scheduler()->OnPersistentSchedulerWakeUp();
  944. }
  945. TEST_F(RemoteSuggestionsSchedulerImplTest,
  946. ShouldIgnoreSubsequentStartupSignalsForM58) {
  947. base::test::ScopedFeatureList feature_list;
  948. feature_list.InitAndEnableFeature(
  949. kRemoteSuggestionsEmulateM58FetchingSchedule);
  950. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  951. // First enable the scheduler -- this will trigger the persistent scheduling.
  952. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  953. ActivateProviderAndEula();
  954. // The startup triggers are ignored.
  955. EXPECT_CALL(*provider(), RefetchInTheBackground(_)).Times(0);
  956. scheduler()->OnBrowserForegrounded();
  957. scheduler()->OnBrowserColdStart();
  958. // Foreground the browser again after a very long delay. Again, no fetch is
  959. // executed for neither Foregrounded, nor ColdStart.
  960. test_clock()->Advance(base::Hours(100000));
  961. scheduler()->OnBrowserForegrounded();
  962. scheduler()->OnBrowserColdStart();
  963. }
  964. TEST_F(RemoteSuggestionsSchedulerImplTest, ShouldIgnoreSignalsWhenOffline) {
  965. // Simulate being offline. NetworkChangeNotifier is a singleton, thus, this
  966. // instance is actually globally accessible (from the static function
  967. // NetworkChangeNotifier::IsOffline() that is called from the scheduler).
  968. FakeOfflineNetworkChangeNotifier fake;
  969. // Activating the provider should schedule the persistent background fetches.
  970. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _));
  971. ActivateProviderAndEula();
  972. // All signals are ignored because of being offline.
  973. EXPECT_CALL(*provider(), RefetchInTheBackground(_)).Times(0);
  974. scheduler()->OnPersistentSchedulerWakeUp();
  975. scheduler()->OnSuggestionsSurfaceOpened();
  976. scheduler()->OnBrowserForegrounded();
  977. scheduler()->OnBrowserColdStart();
  978. }
  979. TEST_F(RemoteSuggestionsSchedulerImplTest,
  980. ShouldNotRefetchWhileDisplayingBeforeDefaultDelay) {
  981. // Activating the provider should schedule the persistent background fetches.
  982. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  983. // First enable the scheduler -- this will trigger the persistent scheduling.
  984. ActivateProviderAndEula();
  985. // The first refetch is never considered due to staleness.
  986. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  987. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  988. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  989. scheduler()->OnBrowserForegrounded();
  990. std::move(signal_fetch_done).Run(Status::Success());
  991. // The staleness threshold by default equals to the startup interval.
  992. test_clock()->Advance(base::Hours(kDefaultStartupIntervalHours) -
  993. base::Minutes(1));
  994. // Not long enough: non-stale.
  995. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_)).Times(0);
  996. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  997. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  998. // allows to test both short and long delay in the same way.
  999. scheduler()->OnSuggestionsSurfaceOpened();
  1000. }
  1001. TEST_F(RemoteSuggestionsSchedulerImplTest,
  1002. ShouldRefetchWhileDisplayingAfterDefaultDelay) {
  1003. // Activating the provider should schedule the persistent background fetches.
  1004. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  1005. // First enable the scheduler -- this will trigger the persistent scheduling.
  1006. ActivateProviderAndEula();
  1007. // The first refetch is never considered due to staleness.
  1008. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  1009. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  1010. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  1011. scheduler()->OnBrowserForegrounded();
  1012. std::move(signal_fetch_done).Run(Status::Success());
  1013. // The staleness threshold by default equals to the startup interval.
  1014. test_clock()->Advance(base::Hours(kDefaultStartupIntervalHours) +
  1015. base::Minutes(1));
  1016. // Long enough: stale.
  1017. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_));
  1018. EXPECT_CALL(*provider(), RefetchInTheBackground(_)).Times(0);
  1019. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  1020. // allows to test both short and long delay in the same way.
  1021. scheduler()->OnSuggestionsSurfaceOpened();
  1022. }
  1023. TEST_F(RemoteSuggestionsSchedulerImplTest,
  1024. ShouldNotRefetchWhileDisplayingBeforeConfigurableDelay) {
  1025. constexpr int kStaleHours = 18;
  1026. SetVariationParameter("min_age_for_stale_fetch_hours",
  1027. base::NumberToString(kStaleHours));
  1028. // Activating the provider should schedule the persistent background fetches.
  1029. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  1030. // First enable the scheduler -- this will trigger the persistent scheduling.
  1031. ActivateProviderAndEula();
  1032. // The first refetch is never considered due to staleness.
  1033. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  1034. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  1035. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  1036. scheduler()->OnBrowserForegrounded();
  1037. std::move(signal_fetch_done).Run(Status::Success());
  1038. // The staleness threshold by default equals to the startup interval.
  1039. test_clock()->Advance(base::Hours(kStaleHours) - base::Minutes(1));
  1040. // Not long enough: non-stale.
  1041. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_)).Times(0);
  1042. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  1043. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  1044. // allows to test both short and long delay in the same way.
  1045. scheduler()->OnSuggestionsSurfaceOpened();
  1046. }
  1047. TEST_F(RemoteSuggestionsSchedulerImplTest,
  1048. ShouldRefetchWhileDisplayingAfterConfigurableDelay) {
  1049. constexpr int kStaleHours = 18;
  1050. SetVariationParameter("min_age_for_stale_fetch_hours",
  1051. base::NumberToString(kStaleHours));
  1052. // Activating the provider should schedule the persistent background fetches.
  1053. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  1054. // First enable the scheduler -- this will trigger the persistent scheduling.
  1055. ActivateProviderAndEula();
  1056. // The first refetch is never considered due to staleness.
  1057. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  1058. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  1059. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  1060. scheduler()->OnBrowserForegrounded();
  1061. std::move(signal_fetch_done).Run(Status::Success());
  1062. test_clock()->Advance(base::Hours(kStaleHours) + base::Minutes(1));
  1063. // Long enough: stale.
  1064. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_));
  1065. EXPECT_CALL(*provider(), RefetchInTheBackground(_)).Times(0);
  1066. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  1067. // allows to test both short and long delay in the same way.
  1068. scheduler()->OnSuggestionsSurfaceOpened();
  1069. }
  1070. TEST_F(RemoteSuggestionsSchedulerImplTest,
  1071. ShouldNotRefetchWhileDisplayingBeforeFallbackConfigurableDelay) {
  1072. constexpr int kStartupHours = 12;
  1073. SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
  1074. base::NumberToString(kStartupHours));
  1075. // Activating the provider should schedule the persistent background fetches.
  1076. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  1077. // First enable the scheduler -- this will trigger the persistent scheduling.
  1078. ActivateProviderAndEula();
  1079. // The first refetch is never considered due to staleness.
  1080. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  1081. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  1082. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  1083. scheduler()->OnBrowserForegrounded();
  1084. std::move(signal_fetch_done).Run(Status::Success());
  1085. // The staleness threshold by default equals to the startup interval.
  1086. test_clock()->Advance(base::Hours(kStartupHours) - base::Minutes(1));
  1087. // Not long enough: non-stale.
  1088. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_)).Times(0);
  1089. EXPECT_CALL(*provider(), RefetchInTheBackground(_));
  1090. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  1091. // allows to test both short and long delay in the same way.
  1092. scheduler()->OnSuggestionsSurfaceOpened();
  1093. }
  1094. TEST_F(RemoteSuggestionsSchedulerImplTest,
  1095. ShouldRefetchWhileDisplayingAfterFallbackConfigurableDelay) {
  1096. constexpr int kStartupHours = 12;
  1097. SetVariationParameter("startup_fetching_interval_hours-wifi-active_ntp_user",
  1098. base::NumberToString(kStartupHours));
  1099. // Activating the provider should schedule the persistent background fetches.
  1100. EXPECT_CALL(*persistent_scheduler(), Schedule(_, _)).Times(2);
  1101. // First enable the scheduler -- this will trigger the persistent scheduling.
  1102. ActivateProviderAndEula();
  1103. // The first refetch is never considered due to staleness.
  1104. RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
  1105. EXPECT_CALL(*provider(), RefetchInTheBackground(_))
  1106. .WillOnce(SaveArgByMove<0>(&signal_fetch_done));
  1107. scheduler()->OnBrowserForegrounded();
  1108. std::move(signal_fetch_done).Run(Status::Success());
  1109. test_clock()->Advance(base::Hours(kStartupHours) + base::Minutes(1));
  1110. // Long enough: stale.
  1111. EXPECT_CALL(*provider(), RefetchWhileDisplaying(_));
  1112. EXPECT_CALL(*provider(), RefetchInTheBackground(_)).Times(0);
  1113. // Use the SurfaceOpened trigger as this has the shortest intervals and thus
  1114. // allows to test both short and long delay in the same way.
  1115. scheduler()->OnSuggestionsSurfaceOpened();
  1116. }
  1117. } // namespace ntp_snippets