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