Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_impl.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_provider_impl.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 private: | 375 private: |
| 376 gfx::Image decoded_image_; | 376 gfx::Image decoded_image_; |
| 377 }; | 377 }; |
| 378 | 378 |
| 379 class MockScheduler : public RemoteSuggestionsScheduler { | 379 class MockScheduler : public RemoteSuggestionsScheduler { |
| 380 public: | 380 public: |
| 381 MOCK_METHOD0(OnProviderActivated, void()); | 381 MOCK_METHOD0(OnProviderActivated, void()); |
| 382 MOCK_METHOD0(OnProviderDeactivated, void()); | 382 MOCK_METHOD0(OnProviderDeactivated, void()); |
| 383 MOCK_METHOD0(OnSuggestionsCleared, void()); | 383 MOCK_METHOD0(OnSuggestionsCleared, void()); |
| 384 MOCK_METHOD0(OnHistoryCleared, void()); | 384 MOCK_METHOD0(OnHistoryCleared, void()); |
| 385 MOCK_METHOD0(AcquireQuotaForInteractiveFetch, bool()); | |
| 386 MOCK_METHOD1(OnInteractiveFetchFinished, void(Status fetch_status)); | |
| 385 MOCK_METHOD0(OnBrowserForegrounded, void()); | 387 MOCK_METHOD0(OnBrowserForegrounded, void()); |
| 386 MOCK_METHOD0(OnBrowserColdStart, void()); | 388 MOCK_METHOD0(OnBrowserColdStart, void()); |
| 387 MOCK_METHOD0(OnNTPOpened, void()); | 389 MOCK_METHOD0(OnNTPOpened, void()); |
| 388 MOCK_METHOD0(OnPersistentSchedulerWakeUp, void()); | 390 MOCK_METHOD0(OnPersistentSchedulerWakeUp, void()); |
| 389 MOCK_METHOD0(RescheduleFetching, void()); | 391 MOCK_METHOD0(RescheduleFetching, void()); |
| 390 }; | 392 }; |
| 391 | 393 |
| 392 } // namespace | 394 } // namespace |
| 393 | 395 |
| 394 class RemoteSuggestionsProviderImplTest : public ::testing::Test { | 396 class RemoteSuggestionsProviderImplTest : public ::testing::Test { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); | 453 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); |
| 452 ON_CALL(*image_fetcher, GetImageDecoder()) | 454 ON_CALL(*image_fetcher, GetImageDecoder()) |
| 453 .WillByDefault(Return(&image_decoder_)); | 455 .WillByDefault(Return(&image_decoder_)); |
| 454 EXPECT_FALSE(observer_); | 456 EXPECT_FALSE(observer_); |
| 455 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); | 457 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); |
| 456 auto database = base::MakeUnique<RemoteSuggestionsDatabase>( | 458 auto database = base::MakeUnique<RemoteSuggestionsDatabase>( |
| 457 database_dir_.GetPath(), task_runner); | 459 database_dir_.GetPath(), task_runner); |
| 458 database_ = database.get(); | 460 database_ = database.get(); |
| 459 return base::MakeUnique<RemoteSuggestionsProviderImpl>( | 461 return base::MakeUnique<RemoteSuggestionsProviderImpl>( |
| 460 observer_.get(), utils_.pref_service(), "fr", category_ranker_.get(), | 462 observer_.get(), utils_.pref_service(), "fr", category_ranker_.get(), |
| 461 std::move(suggestions_fetcher), std::move(image_fetcher), | 463 &scheduler_, std::move(suggestions_fetcher), std::move(image_fetcher), |
| 462 std::move(database), | 464 std::move(database), |
| 463 base::MakeUnique<RemoteSuggestionsStatusService>( | 465 base::MakeUnique<RemoteSuggestionsStatusService>( |
| 464 utils_.fake_signin_manager(), utils_.pref_service())); | 466 utils_.fake_signin_manager(), utils_.pref_service())); |
| 465 } | 467 } |
| 466 | 468 |
| 467 void WaitForSuggestionsProviderInitialization( | 469 void WaitForSuggestionsProviderInitialization( |
| 468 RemoteSuggestionsProviderImpl* service, | 470 RemoteSuggestionsProviderImpl* service, |
| 469 bool set_empty_response) { | 471 bool set_empty_response) { |
| 470 EXPECT_EQ(RemoteSuggestionsProviderImpl::State::NOT_INITED, | 472 EXPECT_EQ(RemoteSuggestionsProviderImpl::State::NOT_INITED, |
| 471 service->state_); | 473 service->state_); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } | 521 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } |
| 520 RemoteSuggestionsFetcher* suggestions_fetcher() { | 522 RemoteSuggestionsFetcher* suggestions_fetcher() { |
| 521 return suggestions_fetcher_; | 523 return suggestions_fetcher_; |
| 522 } | 524 } |
| 523 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary | 525 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary |
| 524 // network requests. | 526 // network requests. |
| 525 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } | 527 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } |
| 526 FakeImageDecoder* image_decoder() { return &image_decoder_; } | 528 FakeImageDecoder* image_decoder() { return &image_decoder_; } |
| 527 PrefService* pref_service() { return utils_.pref_service(); } | 529 PrefService* pref_service() { return utils_.pref_service(); } |
| 528 RemoteSuggestionsDatabase* database() { return database_; } | 530 RemoteSuggestionsDatabase* database() { return database_; } |
| 531 MockScheduler* scheduler() { return &scheduler_; } | |
| 529 | 532 |
| 530 // Provide the json to be returned by the fake fetcher. | 533 // Provide the json to be returned by the fake fetcher. |
| 531 void SetUpFetchResponse(const std::string& json) { | 534 void SetUpFetchResponse(const std::string& json) { |
| 532 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, | 535 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, |
| 533 net::URLRequestStatus::SUCCESS); | 536 net::URLRequestStatus::SUCCESS); |
| 534 } | 537 } |
| 535 | 538 |
| 536 // Have the fake fetcher fail due to a HTTP error like a 404. | 539 // Have the fake fetcher fail due to a HTTP error like a 404. |
| 537 void SetUpHttpError() { | 540 void SetUpHttpError() { |
| 538 fake_url_fetcher_factory_.SetFakeResponse(test_url_, /*json=*/std::string(), | 541 fake_url_fetcher_factory_.SetFakeResponse(test_url_, /*json=*/std::string(), |
| 539 net::HTTP_NOT_FOUND, | 542 net::HTTP_NOT_FOUND, |
| 540 net::URLRequestStatus::SUCCESS); | 543 net::URLRequestStatus::SUCCESS); |
| 541 } | 544 } |
| 542 | 545 |
| 543 void LoadFromJSONString(RemoteSuggestionsProviderImpl* service, | 546 void LoadFromJSONString(RemoteSuggestionsProviderImpl* service, |
| 544 const std::string& json) { | 547 const std::string& json) { |
| 545 SetUpFetchResponse(json); | 548 SetUpFetchResponse(json); |
| 546 service->FetchSuggestions(/*interactive_request=*/true, | 549 service->FetchSuggestions(/*interactive_request=*/true, |
| 547 /*callback=*/nullptr); | 550 /*callback=*/nullptr); |
| 548 base::RunLoop().RunUntilIdle(); | 551 base::RunLoop().RunUntilIdle(); |
| 549 } | 552 } |
| 550 | 553 |
| 551 void LoadMoreFromJSONString(RemoteSuggestionsProviderImpl* service, | 554 void LoadMoreFromJSONString(RemoteSuggestionsProviderImpl* service, |
| 552 const Category& category, | 555 const Category& category, |
| 553 const std::string& json, | 556 const std::string& json, |
| 554 const std::set<std::string>& known_ids, | 557 const std::set<std::string>& known_ids, |
| 555 FetchDoneCallback callback) { | 558 FetchDoneCallback callback) { |
| 556 SetUpFetchResponse(json); | 559 SetUpFetchResponse(json); |
| 560 ON_CALL(scheduler_, AcquireQuotaForInteractiveFetch()) | |
| 561 .WillByDefault(Return(true)); | |
|
Marc Treib
2017/03/27 11:31:00
Hm. Could this be an EXPECT_CALL with RetiresOnSat
jkrcal
2017/03/27 14:09:31
Done.
| |
| 557 service->Fetch(category, known_ids, callback); | 562 service->Fetch(category, known_ids, callback); |
| 558 base::RunLoop().RunUntilIdle(); | 563 base::RunLoop().RunUntilIdle(); |
| 559 } | 564 } |
| 560 | 565 |
| 561 private: | 566 private: |
| 562 variations::testing::VariationParamsManager params_manager_; | 567 variations::testing::VariationParamsManager params_manager_; |
| 563 test::RemoteSuggestionsTestUtils utils_; | 568 test::RemoteSuggestionsTestUtils utils_; |
| 564 base::MessageLoop message_loop_; | 569 base::MessageLoop message_loop_; |
| 565 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; | 570 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; |
| 566 // Instantiation of factory automatically sets itself as URLFetcher's factory. | 571 // Instantiation of factory automatically sets itself as URLFetcher's factory. |
| 567 net::FakeURLFetcherFactory fake_url_fetcher_factory_; | 572 net::FakeURLFetcherFactory fake_url_fetcher_factory_; |
| 568 const GURL test_url_; | 573 const GURL test_url_; |
| 569 std::unique_ptr<CategoryRanker> category_ranker_; | 574 std::unique_ptr<CategoryRanker> category_ranker_; |
| 570 UserClassifier user_classifier_; | 575 UserClassifier user_classifier_; |
| 571 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; | 576 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; |
| 572 RemoteSuggestionsFetcher* suggestions_fetcher_; | 577 RemoteSuggestionsFetcher* suggestions_fetcher_; |
| 573 NiceMock<MockImageFetcher>* image_fetcher_; | 578 NiceMock<MockImageFetcher>* image_fetcher_; |
| 574 FakeImageDecoder image_decoder_; | 579 FakeImageDecoder image_decoder_; |
| 580 NiceMock<MockScheduler> scheduler_; | |
|
Marc Treib
2017/03/27 11:31:00
Hm hm. Okay for now I think, but could we add a TO
jkrcal
2017/03/27 14:09:31
The only reason is not to plague every unit-test w
Marc Treib
2017/03/27 14:27:20
Hm. Maybe? :)
I'm a bit worried that with a NiceMo
jkrcal
2017/03/29 10:55:57
Done.
| |
| 575 | 581 |
| 576 base::ScopedTempDir database_dir_; | 582 base::ScopedTempDir database_dir_; |
| 577 RemoteSuggestionsDatabase* database_; | 583 RemoteSuggestionsDatabase* database_; |
| 578 | 584 |
| 579 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderImplTest); | 585 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderImplTest); |
| 580 }; | 586 }; |
| 581 | 587 |
| 582 TEST_F(RemoteSuggestionsProviderImplTest, Full) { | 588 TEST_F(RemoteSuggestionsProviderImplTest, Full) { |
| 583 std::string json_str(GetTestJson({GetSuggestion()})); | 589 std::string json_str(GetTestJson({GetSuggestion()})); |
| 584 | 590 |
| (...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1717 service->RefetchInTheBackground(/*callback=*/nullptr); | 1723 service->RefetchInTheBackground(/*callback=*/nullptr); |
| 1718 base::RunLoop().RunUntilIdle(); | 1724 base::RunLoop().RunUntilIdle(); |
| 1719 // TODO(jkrcal): Move together with the pref storage into the scheduler. | 1725 // TODO(jkrcal): Move together with the pref storage into the scheduler. |
| 1720 EXPECT_EQ( | 1726 EXPECT_EQ( |
| 1721 simple_test_clock_ptr->Now().ToInternalValue(), | 1727 simple_test_clock_ptr->Now().ToInternalValue(), |
| 1722 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); | 1728 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); |
| 1723 // TODO(markusheintz): Add a test that simulates a browser restart once the | 1729 // TODO(markusheintz): Add a test that simulates a browser restart once the |
| 1724 // scheduler refactoring is done (crbug.com/672434). | 1730 // scheduler refactoring is done (crbug.com/672434). |
| 1725 } | 1731 } |
| 1726 | 1732 |
| 1727 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerIfInited) { | |
| 1728 // Initiate the service so that it is already READY. | |
| 1729 auto service = MakeSuggestionsProvider(); | |
| 1730 StrictMock<MockScheduler> scheduler; | |
| 1731 // The scheduler should be notified of activation of the provider. | |
| 1732 EXPECT_CALL(scheduler, OnProviderActivated()); | |
| 1733 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1734 } | |
| 1735 | |
| 1736 TEST_F(RemoteSuggestionsProviderImplTest, DoesNotCallSchedulerIfNotInited) { | |
| 1737 auto service = MakeSuggestionsProviderWithoutInitialization(); | |
| 1738 StrictMock<MockScheduler> scheduler; | |
| 1739 // The provider is not initialized yet, no callback should be called on | |
| 1740 // registering. | |
| 1741 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1742 } | |
| 1743 | |
| 1744 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenReady) { | 1733 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenReady) { |
| 1745 auto service = MakeSuggestionsProviderWithoutInitialization(); | 1734 auto service = MakeSuggestionsProviderWithoutInitialization(); |
| 1746 StrictMock<MockScheduler> scheduler; | |
| 1747 // The provider is not initialized yet, no callback should be called yet. | |
| 1748 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1749 | 1735 |
| 1750 // Should be called when becoming ready. | 1736 // Should be called when becoming ready. |
| 1751 EXPECT_CALL(scheduler, OnProviderActivated()); | 1737 EXPECT_CALL(*scheduler(), OnProviderActivated()); |
| 1752 WaitForSuggestionsProviderInitialization(service.get(), | 1738 WaitForSuggestionsProviderInitialization(service.get(), |
| 1753 /*set_empty_response=*/true); | 1739 /*set_empty_response=*/true); |
| 1754 } | 1740 } |
| 1755 | 1741 |
| 1756 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerOnError) { | 1742 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerOnError) { |
| 1757 auto service = MakeSuggestionsProviderWithoutInitialization(); | 1743 auto service = MakeSuggestionsProviderWithoutInitialization(); |
| 1758 StrictMock<MockScheduler> scheduler; | |
| 1759 // The provider is not initialized yet, no callback should be called yet. | |
| 1760 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1761 | 1744 |
| 1762 // Should be called on error. | 1745 // Should be called on error. |
| 1763 EXPECT_CALL(scheduler, OnProviderDeactivated()); | 1746 EXPECT_CALL(*scheduler(), OnProviderDeactivated()); |
| 1764 service->EnterState(RemoteSuggestionsProviderImpl::State::ERROR_OCCURRED); | 1747 service->EnterState(RemoteSuggestionsProviderImpl::State::ERROR_OCCURRED); |
| 1765 } | 1748 } |
| 1766 | 1749 |
| 1767 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenDisabled) { | 1750 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenDisabled) { |
| 1768 auto service = MakeSuggestionsProviderWithoutInitialization(); | 1751 auto service = MakeSuggestionsProviderWithoutInitialization(); |
| 1769 StrictMock<MockScheduler> scheduler; | |
| 1770 // The provider is not initialized yet, no callback should be called yet. | |
| 1771 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1772 | 1752 |
| 1773 // Should be called when becoming disabled. First deactivate and only after | 1753 // Should be called when becoming disabled. First deactivate and only after |
| 1774 // that clear the suggestions so that they are not fetched again. | 1754 // that clear the suggestions so that they are not fetched again. |
| 1775 { | 1755 { |
| 1776 InSequence s; | 1756 InSequence s; |
| 1777 EXPECT_CALL(scheduler, OnProviderDeactivated()); | 1757 EXPECT_CALL(*scheduler(), OnProviderDeactivated()); |
| 1778 ASSERT_THAT(service->ready(), Eq(false)); | 1758 ASSERT_THAT(service->ready(), Eq(false)); |
| 1779 EXPECT_CALL(scheduler, OnSuggestionsCleared()); | 1759 EXPECT_CALL(*scheduler(), OnSuggestionsCleared()); |
| 1780 } | 1760 } |
| 1781 service->EnterState(RemoteSuggestionsProviderImpl::State::DISABLED); | 1761 service->EnterState(RemoteSuggestionsProviderImpl::State::DISABLED); |
| 1782 } | 1762 } |
| 1783 | 1763 |
| 1784 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenHistoryCleared) { | 1764 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenHistoryCleared) { |
| 1785 // Initiate the service so that it is already READY. | 1765 // Initiate the service so that it is already READY. |
| 1786 auto service = MakeSuggestionsProvider(); | 1766 auto service = MakeSuggestionsProvider(); |
| 1787 StrictMock<MockScheduler> scheduler; | 1767 |
| 1788 // The scheduler should be notified of activation of the provider. | |
| 1789 EXPECT_CALL(scheduler, OnProviderActivated()); | |
| 1790 // The scheduler should be notified of clearing the history. | 1768 // The scheduler should be notified of clearing the history. |
| 1791 EXPECT_CALL(scheduler, OnHistoryCleared()); | 1769 EXPECT_CALL(*scheduler(), OnHistoryCleared()); |
| 1792 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1793 service->ClearHistory(GetDefaultCreationTime(), GetDefaultExpirationTime(), | 1770 service->ClearHistory(GetDefaultCreationTime(), GetDefaultExpirationTime(), |
| 1794 base::Callback<bool(const GURL& url)>()); | 1771 base::Callback<bool(const GURL& url)>()); |
| 1795 } | 1772 } |
| 1796 | 1773 |
| 1797 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenSignedIn) { | 1774 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenSignedIn) { |
| 1798 // Initiate the service so that it is already READY. | 1775 // Initiate the service so that it is already READY. |
| 1799 auto service = MakeSuggestionsProvider(); | 1776 auto service = MakeSuggestionsProvider(); |
| 1800 StrictMock<MockScheduler> scheduler; | 1777 |
| 1801 // The scheduler should be notified of activation of the provider. | |
| 1802 EXPECT_CALL(scheduler, OnProviderActivated()); | |
| 1803 // The scheduler should be notified of clearing the history. | 1778 // The scheduler should be notified of clearing the history. |
| 1804 EXPECT_CALL(scheduler, OnSuggestionsCleared()); | 1779 EXPECT_CALL(*scheduler(), OnSuggestionsCleared()); |
| 1805 | |
| 1806 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1807 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, | 1780 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, |
| 1808 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); | 1781 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT); |
| 1809 } | 1782 } |
| 1810 | 1783 |
| 1811 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenSignedOut) { | 1784 TEST_F(RemoteSuggestionsProviderImplTest, CallsSchedulerWhenSignedOut) { |
| 1812 // Initiate the service so that it is already READY. | 1785 // Initiate the service so that it is already READY. |
| 1813 auto service = MakeSuggestionsProvider(); | 1786 auto service = MakeSuggestionsProvider(); |
| 1814 StrictMock<MockScheduler> scheduler; | 1787 |
| 1815 // The scheduler should be notified of activation of the provider. | |
| 1816 EXPECT_CALL(scheduler, OnProviderActivated()); | |
| 1817 // The scheduler should be notified of clearing the history. | 1788 // The scheduler should be notified of clearing the history. |
| 1818 EXPECT_CALL(scheduler, OnSuggestionsCleared()); | 1789 EXPECT_CALL(*scheduler(), OnSuggestionsCleared()); |
| 1819 | |
| 1820 service->SetRemoteSuggestionsScheduler(&scheduler); | |
| 1821 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT, | 1790 service->OnStatusChanged(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT, |
| 1822 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN); | 1791 RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN); |
| 1823 } | 1792 } |
| 1824 | 1793 |
| 1825 } // namespace ntp_snippets | 1794 } // namespace ntp_snippets |
| OLD | NEW |