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

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: 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 13 matching lines...) Expand all
24 #include "base/time/time.h" 24 #include "base/time/time.h"
25 #include "components/image_fetcher/image_decoder.h" 25 #include "components/image_fetcher/image_decoder.h"
26 #include "components/image_fetcher/image_fetcher.h" 26 #include "components/image_fetcher/image_fetcher.h"
27 #include "components/image_fetcher/image_fetcher_delegate.h" 27 #include "components/image_fetcher/image_fetcher_delegate.h"
28 #include "components/ntp_snippets/category_factory.h" 28 #include "components/ntp_snippets/category_factory.h"
29 #include "components/ntp_snippets/category_info.h" 29 #include "components/ntp_snippets/category_info.h"
30 #include "components/ntp_snippets/ntp_snippets_constants.h" 30 #include "components/ntp_snippets/ntp_snippets_constants.h"
31 #include "components/ntp_snippets/pref_names.h" 31 #include "components/ntp_snippets/pref_names.h"
32 #include "components/ntp_snippets/remote/ntp_snippet.h" 32 #include "components/ntp_snippets/remote/ntp_snippet.h"
33 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" 33 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
34 #include "components/ntp_snippets/remote/ntp_snippets_scheduler.h"
35 #include "components/ntp_snippets/remote/remote_suggestions_database.h" 34 #include "components/ntp_snippets/remote/remote_suggestions_database.h"
35 #include "components/ntp_snippets/remote/remote_suggestions_hard_scheduler.h"
36 #include "components/ntp_snippets/remote/test_utils.h" 36 #include "components/ntp_snippets/remote/test_utils.h"
37 #include "components/ntp_snippets/user_classifier.h" 37 #include "components/ntp_snippets/user_classifier.h"
38 #include "components/prefs/testing_pref_service.h" 38 #include "components/prefs/testing_pref_service.h"
39 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" 39 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
40 #include "components/signin/core/browser/fake_signin_manager.h" 40 #include "components/signin/core/browser/fake_signin_manager.h"
41 #include "components/variations/variations_params_manager.h" 41 #include "components/variations/variations_params_manager.h"
42 #include "net/url_request/test_url_fetcher_factory.h" 42 #include "net/url_request/test_url_fetcher_factory.h"
43 #include "net/url_request/url_request_test_util.h" 43 #include "net/url_request/url_request_test_util.h"
44 #include "testing/gmock/include/gmock/gmock.h" 44 #include "testing/gmock/include/gmock/gmock.h"
45 #include "testing/gtest/include/gtest/gtest.h" 45 #include "testing/gtest/include/gtest/gtest.h"
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 int id, 299 int id,
300 const GURL& url, 300 const GURL& url,
301 net::URLFetcher::RequestType request_type, 301 net::URLFetcher::RequestType request_type,
302 net::URLFetcherDelegate* d) override { 302 net::URLFetcherDelegate* d) override {
303 return base::MakeUnique<net::FakeURLFetcher>( 303 return base::MakeUnique<net::FakeURLFetcher>(
304 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, 304 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND,
305 net::URLRequestStatus::FAILED); 305 net::URLRequestStatus::FAILED);
306 } 306 }
307 }; 307 };
308 308
309 class MockScheduler : public NTPSnippetsScheduler { 309 class MockHardScheduler : public RemoteSuggestionsHardScheduler {
310 public: 310 public:
311 MOCK_METHOD2(Schedule, 311 MOCK_METHOD2(Schedule,
312 bool(base::TimeDelta period_wifi, 312 bool(base::TimeDelta period_wifi,
313 base::TimeDelta period_fallback)); 313 base::TimeDelta period_fallback));
314 MOCK_METHOD0(Unschedule, bool()); 314 MOCK_METHOD0(Unschedule, bool());
315 }; 315 };
316 316
317 class MockImageFetcher : public ImageFetcher { 317 class MockImageFetcher : public ImageFetcher {
318 public: 318 public:
319 MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*)); 319 MOCK_METHOD1(SetImageFetcherDelegate, void(ImageFetcherDelegate*));
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>(); 444 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>();
445 445
446 image_fetcher_ = image_fetcher.get(); 446 image_fetcher_ = image_fetcher.get();
447 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); 447 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_));
448 auto image_decoder = base::MakeUnique<FakeImageDecoder>(); 448 auto image_decoder = base::MakeUnique<FakeImageDecoder>();
449 image_decoder_ = image_decoder.get(); 449 image_decoder_ = image_decoder.get();
450 EXPECT_FALSE(observer_); 450 EXPECT_FALSE(observer_);
451 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); 451 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>();
452 return base::MakeUnique<RemoteSuggestionsProvider>( 452 return base::MakeUnique<RemoteSuggestionsProvider>(
453 observer_.get(), &category_factory_, utils_.pref_service(), "fr", 453 observer_.get(), &category_factory_, utils_.pref_service(), "fr",
454 &user_classifier_, &scheduler_, std::move(snippets_fetcher), 454 &user_classifier_, &hard_scheduler_, std::move(snippets_fetcher),
455 std::move(image_fetcher), std::move(image_decoder), 455 std::move(image_fetcher), std::move(image_decoder),
456 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(), 456 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(),
457 task_runner), 457 task_runner),
458 base::MakeUnique<RemoteSuggestionsStatusService>( 458 base::MakeUnique<RemoteSuggestionsStatusService>(
459 utils_.fake_signin_manager(), utils_.pref_service())); 459 utils_.fake_signin_manager(), utils_.pref_service()));
460 } 460 }
461 461
462 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service, 462 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service,
463 bool set_empty_response) { 463 bool set_empty_response) {
464 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); 464 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_);
(...skipping 30 matching lines...) Expand all
495 495
496 Category other_category() { return category_factory_.FromRemoteCategory(2); } 496 Category other_category() { return category_factory_.FromRemoteCategory(2); }
497 497
498 Category unknown_category() { 498 Category unknown_category() {
499 return category_factory_.FromRemoteCategory(kUnknownRemoteCategoryId); 499 return category_factory_.FromRemoteCategory(kUnknownRemoteCategoryId);
500 } 500 }
501 501
502 protected: 502 protected:
503 const GURL& test_url() { return test_url_; } 503 const GURL& test_url() { return test_url_; }
504 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } 504 FakeContentSuggestionsProviderObserver& observer() { return *observer_; }
505 MockScheduler& mock_scheduler() { return scheduler_; } 505 MockHardScheduler& mock_scheduler() { return hard_scheduler_; }
506 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary 506 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary
507 // network requests. 507 // network requests.
508 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } 508 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; }
509 FakeImageDecoder* image_decoder() { return image_decoder_; } 509 FakeImageDecoder* image_decoder() { return image_decoder_; }
510 PrefService* pref_service() { return utils_.pref_service(); } 510 PrefService* pref_service() { return utils_.pref_service(); }
511 511
512 // Provide the json to be returned by the fake fetcher. 512 // Provide the json to be returned by the fake fetcher.
513 void SetUpFetchResponse(const std::string& json) { 513 void SetUpFetchResponse(const std::string& json) {
514 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, 514 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK,
515 net::URLRequestStatus::SUCCESS); 515 net::URLRequestStatus::SUCCESS);
(...skipping 19 matching lines...) Expand all
535 private: 535 private:
536 variations::testing::VariationParamsManager params_manager_; 536 variations::testing::VariationParamsManager params_manager_;
537 test::RemoteSuggestionsTestUtils utils_; 537 test::RemoteSuggestionsTestUtils utils_;
538 base::MessageLoop message_loop_; 538 base::MessageLoop message_loop_;
539 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; 539 FailingFakeURLFetcherFactory failing_url_fetcher_factory_;
540 // Instantiation of factory automatically sets itself as URLFetcher's factory. 540 // Instantiation of factory automatically sets itself as URLFetcher's factory.
541 net::FakeURLFetcherFactory fake_url_fetcher_factory_; 541 net::FakeURLFetcherFactory fake_url_fetcher_factory_;
542 const GURL test_url_; 542 const GURL test_url_;
543 std::unique_ptr<OAuth2TokenService> fake_token_service_; 543 std::unique_ptr<OAuth2TokenService> fake_token_service_;
544 UserClassifier user_classifier_; 544 UserClassifier user_classifier_;
545 NiceMock<MockScheduler> scheduler_; 545 NiceMock<MockHardScheduler> hard_scheduler_;
546 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; 546 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_;
547 CategoryFactory category_factory_; 547 CategoryFactory category_factory_;
548 NiceMock<MockImageFetcher>* image_fetcher_; 548 NiceMock<MockImageFetcher>* image_fetcher_;
549 FakeImageDecoder* image_decoder_; 549 FakeImageDecoder* image_decoder_;
550 550
551 base::ScopedTempDir database_dir_; 551 base::ScopedTempDir database_dir_;
552 552
553 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest); 553 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest);
554 }; 554 };
555 555
556 TEST_F(RemoteSuggestionsProviderTest, ScheduleOnStart) {
557 // We should get two |Schedule| calls: The first when initialization
558 // completes, the second one after the automatic (since the service doesn't
559 // have any data yet) fetch finishes.
560 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
561 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
562 auto service = MakeSnippetsService();
563
564 // When we have no snippets are all, loading the service initiates a fetch.
565 EXPECT_EQ("OK", service->snippets_fetcher()->last_status());
566 }
567
568 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleOnStart) {
569 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
570 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
571 SetUpFetchResponse(GetTestJson({GetSnippet()}));
572 auto service = MakeSnippetsService(/*set_empty_response=*/false);
573
574 // When recreating the service, we should not get any |Schedule| calls:
575 // The tasks are already scheduled with the correct intervals, so nothing on
576 // initialization, and the service has data from the DB, so no automatic fetch
577 // should happen.
578 Mock::VerifyAndClearExpectations(&mock_scheduler());
579 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
580 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
581 ResetSnippetsService(&service);
582 }
583
584 TEST_F(RemoteSuggestionsProviderTest, RescheduleAfterSuccessfulFetch) {
585 // We should get two |Schedule| calls: The first when initialization
586 // completes, the second one after the automatic (since the service doesn't
587 // have any data yet) fetch finishes.
588 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
589 auto service = MakeSnippetsService();
590
591 // A successful fetch should trigger another |Schedule|.
592 EXPECT_CALL(mock_scheduler(), Schedule(_, _));
593 LoadFromJSONString(service.get(), GetTestJson({GetSnippet()}));
594 }
595
596 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleAfterFailedFetch) { 556 TEST_F(RemoteSuggestionsProviderTest, DontRescheduleAfterFailedFetch) {
597 // We should get two |Schedule| calls: The first when initialization 557 // We should get two |Schedule| calls: The first when initialization
598 // completes, the second one after the automatic (since the service doesn't 558 // completes, the second one after the automatic (since the service doesn't
599 // have any data yet) fetch finishes. 559 // have any data yet) fetch finishes.
600 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 560 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
601 auto service = MakeSnippetsService(); 561 auto service = MakeSnippetsService();
602 562
603 // A failed fetch should NOT trigger another |Schedule|. 563 // A failed fetch should NOT trigger another |Schedule|.
604 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0); 564 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(0);
605 LoadFromJSONString(service.get(), GetTestJson({GetInvalidSnippet()})); 565 LoadFromJSONString(service.get(), GetTestJson({GetInvalidSnippet()}));
606 } 566 }
607 567
608 TEST_F(RemoteSuggestionsProviderTest, IgnoreRescheduleBeforeInit) {
609 // We should get two |Schedule| calls: The first when initialization
610 // completes, the second one after the automatic (since the service doesn't
611 // have any data yet) fetch finishes.
612 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
613 // The |RescheduleFetching| call shouldn't do anything (in particular not
614 // result in an |Unschedule|), since the service isn't initialized yet.
615 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
616 auto service = MakeSnippetsServiceWithoutInitialization();
617 service->RescheduleFetching(false);
618 WaitForSnippetsServiceInitialization(service.get(),
619 /*set_empty_response=*/true);
620 }
621
622 TEST_F(RemoteSuggestionsProviderTest, HandleForcedRescheduleBeforeInit) {
623 {
624 InSequence s;
625 // The |RescheduleFetching| call with force=true should result in an
626 // |Unschedule|, since the service isn't initialized yet.
627 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1);
628 // We should get two |Schedule| calls: The first when initialization
629 // completes, the second one after the automatic (since the service doesn't
630 // have any data yet) fetch finishes.
631 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
632 }
633 auto service = MakeSnippetsServiceWithoutInitialization();
634 service->RescheduleFetching(true);
635 WaitForSnippetsServiceInitialization(service.get(),
636 /*set_empty_response=*/true);
637 }
638
639 TEST_F(RemoteSuggestionsProviderTest, RescheduleOnStateChange) { 568 TEST_F(RemoteSuggestionsProviderTest, RescheduleOnStateChange) {
640 { 569 {
641 InSequence s; 570 InSequence s;
642 // Initial startup. 571 // Initial startup.
643 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 572 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
644 // Service gets disabled. 573 // Service gets disabled.
645 EXPECT_CALL(mock_scheduler(), Unschedule()); 574 EXPECT_CALL(mock_scheduler(), Unschedule());
646 // Service gets enabled again. 575 // Service gets enabled again.
647 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2); 576 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
648 } 577 }
649 auto service = MakeSnippetsService(); 578 auto service = MakeSnippetsService();
650 ASSERT_TRUE(service->ready()); 579 ASSERT_TRUE(service->ready());
651 580
652 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, 581 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN,
653 RemoteSuggestionsStatus::EXPLICITLY_DISABLED); 582 RemoteSuggestionsStatus::EXPLICITLY_DISABLED);
654 ASSERT_FALSE(service->ready()); 583 ASSERT_FALSE(service->ready());
655 base::RunLoop().RunUntilIdle(); 584 base::RunLoop().RunUntilIdle();
656 585
657 service->OnStatusChanged(RemoteSuggestionsStatus::EXPLICITLY_DISABLED, 586 service->OnStatusChanged(RemoteSuggestionsStatus::EXPLICITLY_DISABLED,
658 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); 587 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT);
659 ASSERT_TRUE(service->ready()); 588 ASSERT_TRUE(service->ready());
660 base::RunLoop().RunUntilIdle(); 589 base::RunLoop().RunUntilIdle();
661 } 590 }
662 591
663 TEST_F(RemoteSuggestionsProviderTest, DontUnscheduleOnShutdown) {
664 EXPECT_CALL(mock_scheduler(), Schedule(_, _)).Times(2);
665 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(0);
666
667 auto service = MakeSnippetsService();
668
669 service.reset();
670 base::RunLoop().RunUntilIdle();
671 }
672 592
673 TEST_F(RemoteSuggestionsProviderTest, Full) { 593 TEST_F(RemoteSuggestionsProviderTest, Full) {
674 std::string json_str(GetTestJson({GetSnippet()})); 594 std::string json_str(GetTestJson({GetSnippet()}));
675 595
676 auto service = MakeSnippetsService(); 596 auto service = MakeSnippetsService();
677 597
678 LoadFromJSONString(service.get(), json_str); 598 LoadFromJSONString(service.get(), json_str);
679 599
680 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), 600 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()),
681 SizeIs(1)); 601 SizeIs(1));
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1587 base::StringPrintf("http://localhost/snippet-id-%d", i))); 1507 base::StringPrintf("http://localhost/snippet-id-%d", i)));
1588 } 1508 }
1589 LoadFromJSONString(service.get(), GetTestJson(suggestions)); 1509 LoadFromJSONString(service.get(), GetTestJson(suggestions));
1590 // TODO(tschumann): We should probably trim out any additional results and 1510 // TODO(tschumann): We should probably trim out any additional results and
1591 // only serve the MaxSnippetCount items. 1511 // only serve the MaxSnippetCount items.
1592 EXPECT_THAT(service->GetSnippetsForTesting(articles_category()), 1512 EXPECT_THAT(service->GetSnippetsForTesting(articles_category()),
1593 SizeIs(service->GetMaxSnippetCountForTesting() + 1)); 1513 SizeIs(service->GetMaxSnippetCountForTesting() + 1));
1594 } 1514 }
1595 1515
1596 } // namespace ntp_snippets 1516 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698