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

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

Issue 2557363002: [NTP Snippets] Refactor background scheduling for remote suggestions (Closed)
Patch Set: Make unit-tests pass 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/remote_suggestions_provider.h" 5 #include "components/ntp_snippets/remote/remote_suggestions_provider.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 14 matching lines...) Expand all
25 #include "base/time/time.h" 25 #include "base/time/time.h"
26 #include "components/image_fetcher/image_decoder.h" 26 #include "components/image_fetcher/image_decoder.h"
27 #include "components/image_fetcher/image_fetcher.h" 27 #include "components/image_fetcher/image_fetcher.h"
28 #include "components/image_fetcher/image_fetcher_delegate.h" 28 #include "components/image_fetcher/image_fetcher_delegate.h"
29 #include "components/ntp_snippets/category_factory.h" 29 #include "components/ntp_snippets/category_factory.h"
30 #include "components/ntp_snippets/category_info.h" 30 #include "components/ntp_snippets/category_info.h"
31 #include "components/ntp_snippets/ntp_snippets_constants.h" 31 #include "components/ntp_snippets/ntp_snippets_constants.h"
32 #include "components/ntp_snippets/pref_names.h" 32 #include "components/ntp_snippets/pref_names.h"
33 #include "components/ntp_snippets/remote/ntp_snippet.h" 33 #include "components/ntp_snippets/remote/ntp_snippet.h"
34 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" 34 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
35 #include "components/ntp_snippets/remote/ntp_snippets_scheduler.h"
36 #include "components/ntp_snippets/remote/remote_suggestions_database.h" 35 #include "components/ntp_snippets/remote/remote_suggestions_database.h"
36 #include "components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h"
37 #include "components/ntp_snippets/remote/test_utils.h" 37 #include "components/ntp_snippets/remote/test_utils.h"
38 #include "components/ntp_snippets/user_classifier.h" 38 #include "components/ntp_snippets/user_classifier.h"
39 #include "components/prefs/testing_pref_service.h" 39 #include "components/prefs/testing_pref_service.h"
40 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" 40 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
41 #include "components/signin/core/browser/fake_signin_manager.h" 41 #include "components/signin/core/browser/fake_signin_manager.h"
42 #include "components/variations/variations_params_manager.h" 42 #include "components/variations/variations_params_manager.h"
43 #include "net/url_request/test_url_fetcher_factory.h" 43 #include "net/url_request/test_url_fetcher_factory.h"
44 #include "net/url_request/url_request_test_util.h" 44 #include "net/url_request/url_request_test_util.h"
45 #include "testing/gmock/include/gmock/gmock.h" 45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h" 46 #include "testing/gtest/include/gtest/gtest.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 int id, 300 int id,
301 const GURL& url, 301 const GURL& url,
302 net::URLFetcher::RequestType request_type, 302 net::URLFetcher::RequestType request_type,
303 net::URLFetcherDelegate* d) override { 303 net::URLFetcherDelegate* d) override {
304 return base::MakeUnique<net::FakeURLFetcher>( 304 return base::MakeUnique<net::FakeURLFetcher>(
305 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, 305 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND,
306 net::URLRequestStatus::FAILED); 306 net::URLRequestStatus::FAILED);
307 } 307 }
308 }; 308 };
309 309
310 class MockScheduler : public NTPSnippetsScheduler { 310 class MockHardScheduler : public RemoteSuggestionsHardScheduler {
311 public: 311 public:
312 MOCK_METHOD2(Schedule, 312 MOCK_METHOD2(Schedule,
313 bool(base::TimeDelta period_wifi, 313 bool(base::TimeDelta period_wifi,
314 base::TimeDelta period_fallback)); 314 base::TimeDelta period_fallback));
315 MOCK_METHOD0(Unschedule, bool()); 315 MOCK_METHOD0(Unschedule, bool());
316 }; 316 };
317 317
318 class MockImageFetcher : public ImageFetcher { 318 class MockImageFetcher : public ImageFetcher {
319 public: 319 public:
320 MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*)); 320 MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*));
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>(); 445 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>();
446 446
447 image_fetcher_ = image_fetcher.get(); 447 image_fetcher_ = image_fetcher.get();
448 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); 448 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_));
449 auto image_decoder = base::MakeUnique<FakeImageDecoder>(); 449 auto image_decoder = base::MakeUnique<FakeImageDecoder>();
450 image_decoder_ = image_decoder.get(); 450 image_decoder_ = image_decoder.get();
451 EXPECT_FALSE(observer_); 451 EXPECT_FALSE(observer_);
452 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); 452 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>();
453 return base::MakeUnique<RemoteSuggestionsProvider>( 453 return base::MakeUnique<RemoteSuggestionsProvider>(
454 observer_.get(), &category_factory_, utils_.pref_service(), "fr", 454 observer_.get(), &category_factory_, utils_.pref_service(), "fr",
455 &user_classifier_, &scheduler_, std::move(snippets_fetcher), 455 &user_classifier_, &hard_scheduler_, std::move(snippets_fetcher),
456 std::move(image_fetcher), std::move(image_decoder), 456 std::move(image_fetcher), std::move(image_decoder),
457 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(), 457 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(),
458 task_runner), 458 task_runner),
459 base::MakeUnique<RemoteSuggestionsStatusService>( 459 base::MakeUnique<RemoteSuggestionsStatusService>(
460 utils_.fake_signin_manager(), utils_.pref_service())); 460 utils_.fake_signin_manager(), utils_.pref_service()));
461 } 461 }
462 462
463 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service, 463 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service,
464 bool set_empty_response) { 464 bool set_empty_response) {
465 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); 465 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_);
(...skipping 30 matching lines...) Expand all
496 496
497 Category other_category() { return category_factory_.FromRemoteCategory(2); } 497 Category other_category() { return category_factory_.FromRemoteCategory(2); }
498 498
499 Category unknown_category() { 499 Category unknown_category() {
500 return category_factory_.FromRemoteCategory(kUnknownRemoteCategoryId); 500 return category_factory_.FromRemoteCategory(kUnknownRemoteCategoryId);
501 } 501 }
502 502
503 protected: 503 protected:
504 const GURL& test_url() { return test_url_; } 504 const GURL& test_url() { return test_url_; }
505 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } 505 FakeContentSuggestionsProviderObserver& observer() { return *observer_; }
506 MockScheduler& mock_scheduler() { return scheduler_; } 506 MockHardScheduler& mock_scheduler() { return hard_scheduler_; }
507 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary 507 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary
508 // network requests. 508 // network requests.
509 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } 509 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; }
510 FakeImageDecoder* image_decoder() { return image_decoder_; } 510 FakeImageDecoder* image_decoder() { return image_decoder_; }
511 PrefService* pref_service() { return utils_.pref_service(); } 511 PrefService* pref_service() { return utils_.pref_service(); }
512 512
513 // Provide the json to be returned by the fake fetcher. 513 // Provide the json to be returned by the fake fetcher.
514 void SetUpFetchResponse(const std::string& json) { 514 void SetUpFetchResponse(const std::string& json) {
515 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, 515 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK,
516 net::URLRequestStatus::SUCCESS); 516 net::URLRequestStatus::SUCCESS);
(...skipping 19 matching lines...) Expand all
536 private: 536 private:
537 variations::testing::VariationParamsManager params_manager_; 537 variations::testing::VariationParamsManager params_manager_;
538 test::RemoteSuggestionsTestUtils utils_; 538 test::RemoteSuggestionsTestUtils utils_;
539 base::MessageLoop message_loop_; 539 base::MessageLoop message_loop_;
540 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; 540 FailingFakeURLFetcherFactory failing_url_fetcher_factory_;
541 // Instantiation of factory automatically sets itself as URLFetcher's factory. 541 // Instantiation of factory automatically sets itself as URLFetcher's factory.
542 net::FakeURLFetcherFactory fake_url_fetcher_factory_; 542 net::FakeURLFetcherFactory fake_url_fetcher_factory_;
543 const GURL test_url_; 543 const GURL test_url_;
544 std::unique_ptr<OAuth2TokenService> fake_token_service_; 544 std::unique_ptr<OAuth2TokenService> fake_token_service_;
545 UserClassifier user_classifier_; 545 UserClassifier user_classifier_;
546 NiceMock<MockScheduler> scheduler_; 546 NiceMock<MockHardScheduler> hard_scheduler_;
547 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; 547 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_;
548 CategoryFactory category_factory_; 548 CategoryFactory category_factory_;
549 NiceMock<MockImageFetcher>* image_fetcher_; 549 NiceMock<MockImageFetcher>* image_fetcher_;
550 FakeImageDecoder* image_decoder_; 550 FakeImageDecoder* image_decoder_;
551 551
552 base::ScopedTempDir database_dir_; 552 base::ScopedTempDir database_dir_;
553 553
554 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest); 554 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest);
555 }; 555 };
556 556
557 TEST_F(RemoteSuggestionsProviderTest, ScheduleOnStart) {
Marc Treib 2016/12/09 12:25:26 I think some of the removed tests kinda still appl
jkrcal 2016/12/19 09:40:23 Not relevant any more. I've added some more tests
558 // We should get two |Schedule| calls: The first when initialization
559 // completes, the second one after the automatic (since the service doesn't
560 // have any data yet) fetch finishes.
561 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
562 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
563 auto service = MakeSnippetsService();
564
565 // When we have no snippets are all, loading the service initiates a fetch.
566 EXPECT_EQ("OK", service->snippets_fetcher()->last_status());
567 }
568
569 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleOnStart) {
570 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
571 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
572 SetUpFetchResponse(GetTestJson({GetSnippet()}));
573 auto service = MakeSnippetsService(/*set_empty_response=*/false);
574
575 // When recreating the service, we should not get any |Schedule| calls:
576 // The tasks are already scheduled with the correct intervals, so nothing on
577 // initialization, and the service has data from the DB, so no automatic fetch
578 // should happen.
579 Mock::VerifyAndClearExpectations(&mock_scheduler());
580 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
581 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
582 ResetSnippetsService(&service);
583 }
584
585 TEST_F(RemoteSuggestionsProviderTest, RescheduleAfterSuccessfulFetch) {
586 // We should get two |Schedule| calls: The first when initialization
587 // completes, the second one after the automatic (since the service doesn't
588 // have any data yet) fetch finishes.
589 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
590 auto service = MakeSnippetsService();
591
592 // A successful fetch should trigger another |Schedule|.
593 EXPECT_CALL(mock_scheduler(), Schedule(_, _));
594 LoadFromJSONString(service.get(), GetTestJson({GetSnippet()}));
595 }
596
597 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleAfterFailedFetch) { 557 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleAfterFailedFetch) {
598 // We should get two |Schedule| calls: The first when initialization 558 // We should get two |Schedule| calls: The first when initialization
599 // completes, the second one after the automatic (since the service doesn't 559 // completes, the second one after the automatic (since the service doesn't
600 // have any data yet) fetch finishes. 560 // have any data yet) fetch finishes.
601 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 561 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
602 auto service = MakeSnippetsService(); 562 auto service = MakeSnippetsService();
603 563
604 // A failed fetch should NOT trigger another |Schedule|. 564 // A failed fetch should NOT trigger another |Schedule|.
605 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0); 565 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
606 LoadFromJSONString(service.get(), GetTestJson({GetInvalidSnippet()})); 566 LoadFromJSONString(service.get(), GetTestJson({GetInvalidSnippet()}));
607 } 567 }
608 568
609 TEST_F(RemoteSuggestionsProviderTest, IgnoreRescheduleBeforeInit) {
610 // We should get two |Schedule| calls: The first when initialization
611 // completes, the second one after the automatic (since the service doesn't
612 // have any data yet) fetch finishes.
613 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
614 // The |RescheduleFetching| call shouldn't do anything (in particular not
615 // result in an |Unschedule|), since the service isn't initialized yet.
616 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
617 auto service = MakeSnippetsServiceWithoutInitialization();
618 service->RescheduleFetching(false);
619 WaitForSnippetsServiceInitialization(service.get(),
620 /*set_empty_response=*/true);
621 }
622
623 TEST_F(RemoteSuggestionsProviderTest, HandleForcedRescheduleBeforeInit) {
624 {
625 InSequence s;
626 // The |RescheduleFetching| call with force=true should result in an
627 // |Unschedule|, since the service isn't initialized yet.
628 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
629 // We should get two |Schedule| calls: The first when initialization
630 // completes, the second one after the automatic (since the service doesn't
631 // have any data yet) fetch finishes.
632 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
633 }
634 auto service = MakeSnippetsServiceWithoutInitialization();
635 service->RescheduleFetching(true);
636 WaitForSnippetsServiceInitialization(service.get(),
637 /*set_empty_response=*/true);
638 }
639
640 TEST_F(RemoteSuggestionsProviderTest, RescheduleOnStateChange) { 569 TEST_F(RemoteSuggestionsProviderTest, RescheduleOnStateChange) {
641 { 570 {
642 InSequence s; 571 InSequence s;
643 // Initial startup. 572 // Initial startup.
644 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 573 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
645 // Service gets disabled. 574 // Service gets disabled.
646 EXPECT_CALL(mock_scheduler(), Unschedule()); 575 EXPECT_CALL(mock_scheduler(), Unschedule());
647 // Service gets enabled again. 576 // Service gets enabled again.
648 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 577 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
649 } 578 }
650 auto service = MakeSnippetsService(); 579 auto service = MakeSnippetsService();
651 ASSERT_TRUE(service->ready()); 580 ASSERT_TRUE(service->ready());
652 581
653 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, 582 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN,
654 RemoteSuggestionsStatus::EXPLICITLY_DISABLED); 583 RemoteSuggestionsStatus::EXPLICITLY_DISABLED);
655 ASSERT_FALSE(service->ready()); 584 ASSERT_FALSE(service->ready());
656 base::RunLoop().RunUntilIdle(); 585 base::RunLoop().RunUntilIdle();
657 586
658 service->OnStatusChanged(RemoteSuggestionsStatus::EXPLICITLY_DISABLED, 587 service->OnStatusChanged(RemoteSuggestionsStatus::EXPLICITLY_DISABLED,
659 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); 588 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT);
660 ASSERT_TRUE(service->ready()); 589 ASSERT_TRUE(service->ready());
661 base::RunLoop().RunUntilIdle(); 590 base::RunLoop().RunUntilIdle();
662 } 591 }
663 592
664 TEST_F(RemoteSuggestionsProviderTest, DontUnscheduleOnShutdown) {
665 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
666 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
667
668 auto service = MakeSnippetsService();
669
670 service.reset();
671 base::RunLoop().RunUntilIdle();
672 }
673 593
674 TEST_F(RemoteSuggestionsProviderTest, Full) { 594 TEST_F(RemoteSuggestionsProviderTest, Full) {
675 std::string json_str(GetTestJson({GetSnippet()})); 595 std::string json_str(GetTestJson({GetSnippet()}));
676 596
677 auto service = MakeSnippetsService(); 597 auto service = MakeSnippetsService();
678 598
679 LoadFromJSONString(service.get(), json_str); 599 LoadFromJSONString(service.get(), json_str);
680 600
681 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), 601 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()),
682 SizeIs(1)); 602 SizeIs(1));
(...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 1531
1612 WaitForSnippetsServiceInitialization(service.get(), 1532 WaitForSnippetsServiceInitialization(service.get(),
1613 /*set_empty_response=*/true); 1533 /*set_empty_response=*/true);
1614 EXPECT_EQ( 1534 EXPECT_EQ(
1615 simple_test_tick_clock_ptr->NowTicks().ToInternalValue(), 1535 simple_test_tick_clock_ptr->NowTicks().ToInternalValue(),
1616 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); 1536 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime));
1617 1537
1618 // Advance the time and check whether the time was updated correctly after the 1538 // Advance the time and check whether the time was updated correctly after the
1619 // background fetch. 1539 // background fetch.
1620 simple_test_tick_clock_ptr->Advance(TimeDelta::FromHours(1)); 1540 simple_test_tick_clock_ptr->Advance(TimeDelta::FromHours(1));
1621 service->FetchSnippetsInTheBackground(); 1541
1542 // TODO(jkrcal): Move together with the pref storage into the scheduler.
1543 static_cast<RemoteSuggestionsScheduler::Updater*>(service.get())
1544 ->UpdateRemoteSuggestionsBySchedule();
1622 base::RunLoop().RunUntilIdle(); 1545 base::RunLoop().RunUntilIdle();
1623 EXPECT_EQ( 1546 EXPECT_EQ(
1624 simple_test_tick_clock_ptr->NowTicks().ToInternalValue(), 1547 simple_test_tick_clock_ptr->NowTicks().ToInternalValue(),
1625 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); 1548 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime));
1626 // TODO(markusheintz): Add a test that simulates a browser restart once the 1549 // TODO(markusheintz): Add a test that simulates a browser restart once the
1627 // scheduler refactoring is done (crbug.com/672434). 1550 // scheduler refactoring is done (crbug.com/672434).
1628 } 1551 }
1629 1552
1630 } // namespace ntp_snippets 1553 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698