Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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/ntp_snippets_fetcher.h" | 5 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 UserClassifier::RegisterProfilePrefs(pref_service_->registry()); | 166 UserClassifier::RegisterProfilePrefs(pref_service_->registry()); |
| 167 user_classifier_ = base::MakeUnique<UserClassifier>(pref_service_.get()); | 167 user_classifier_ = base::MakeUnique<UserClassifier>(pref_service_.get()); |
| 168 | 168 |
| 169 snippets_fetcher_ = base::MakeUnique<NTPSnippetsFetcher>( | 169 snippets_fetcher_ = base::MakeUnique<NTPSnippetsFetcher>( |
| 170 fake_signin_manager_.get(), fake_token_service_.get(), | 170 fake_signin_manager_.get(), fake_token_service_.get(), |
| 171 scoped_refptr<net::TestURLRequestContextGetter>( | 171 scoped_refptr<net::TestURLRequestContextGetter>( |
| 172 new net::TestURLRequestContextGetter(mock_task_runner_.get())), | 172 new net::TestURLRequestContextGetter(mock_task_runner_.get())), |
| 173 pref_service_.get(), &category_factory_, nullptr, | 173 pref_service_.get(), &category_factory_, nullptr, |
| 174 base::Bind(&ParseJsonDelayed), kAPIKey, user_classifier_.get()); | 174 base::Bind(&ParseJsonDelayed), kAPIKey, user_classifier_.get()); |
| 175 | 175 |
| 176 snippets_fetcher_->SetCallback( | |
| 177 base::Bind(&MockSnippetsAvailableCallback::WrappedRun, | |
| 178 base::Unretained(&mock_callback_))); | |
| 179 snippets_fetcher_->SetTickClockForTesting( | 176 snippets_fetcher_->SetTickClockForTesting( |
| 180 mock_task_runner_->GetMockTickClock()); | 177 mock_task_runner_->GetMockTickClock()); |
| 181 // Increase initial time such that ticks are non-zero. | 178 // Increase initial time such that ticks are non-zero. |
| 182 mock_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1234)); | 179 mock_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1234)); |
| 183 } | 180 } |
| 184 | 181 |
| 182 NTPSnippetsFetcher::SnippetsAvailableCallback MakeMockCallback() { | |
| 183 return base::BindOnce(&MockSnippetsAvailableCallback::WrappedRun, | |
| 184 base::Unretained(&mock_callback_)); | |
| 185 } | |
| 186 | |
| 187 base::Optional<Category> NoExclusiveCategory() { | |
| 188 return base::Optional<Category>(); | |
| 189 } | |
| 190 | |
| 191 base::Optional<Category> OptionalArticlesCategory() { | |
| 192 return base::Optional<Category>( | |
| 193 CategoryFactory().FromKnownCategory(KnownCategories::ARTICLES)); | |
| 194 } | |
| 195 | |
| 185 NTPSnippetsFetcher& snippets_fetcher() { return *snippets_fetcher_; } | 196 NTPSnippetsFetcher& snippets_fetcher() { return *snippets_fetcher_; } |
| 186 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } | 197 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } |
| 187 void FastForwardUntilNoTasksRemain() { | 198 void FastForwardUntilNoTasksRemain() { |
| 188 mock_task_runner_->FastForwardUntilNoTasksRemain(); | 199 mock_task_runner_->FastForwardUntilNoTasksRemain(); |
| 189 } | 200 } |
| 190 base::HistogramTester& histogram_tester() { return histogram_tester_; } | 201 base::HistogramTester& histogram_tester() { return histogram_tester_; } |
| 191 | 202 |
| 192 NTPSnippetsFetcher::Params test_params() { | 203 NTPSnippetsFetcher::Params test_params() { |
| 193 NTPSnippetsFetcher::Params result; | 204 NTPSnippetsFetcher::Params result; |
| 194 result.count_to_fetch = 1; | 205 result.count_to_fetch = 1; |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 649 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); |
| 639 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 650 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); |
| 640 EXPECT_THAT(histogram_tester().GetAllSamples( | 651 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 641 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 652 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 642 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 653 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 643 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 654 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 644 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 655 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 645 /*count=*/1))); | 656 /*count=*/1))); |
| 646 } | 657 } |
| 647 | 658 |
| 659 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, ExclusiveCategoryOnly) { | |
| 660 const std::string kJsonStr = | |
| 661 "{\"categories\" : [{" | |
| 662 " \"id\": 1," | |
| 663 " \"localizedTitle\": \"Articles for You\"," | |
| 664 " \"suggestions\" : [{" | |
| 665 " \"ids\" : [\"http://localhost/foobar\"]," | |
| 666 " \"title\" : \"Foo Barred from Baz\"," | |
| 667 " \"snippet\" : \"...\"," | |
| 668 " \"fullPageUrl\" : \"http://localhost/foobar\"," | |
| 669 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | |
| 670 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | |
| 671 " \"attribution\" : \"Foo News\"," | |
| 672 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," | |
| 673 " \"ampUrl\" : \"http://localhost/amp\"," | |
| 674 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | |
| 675 " }]" | |
| 676 "}, {" | |
| 677 " \"id\": 2," | |
| 678 " \"localizedTitle\": \"Articles for Me\"," | |
| 679 " \"suggestions\" : [{" | |
| 680 " \"ids\" : [\"http://localhost/foo2\"]," | |
| 681 " \"title\" : \"Foo Barred from Baz\"," | |
| 682 " \"snippet\" : \"...\"," | |
| 683 " \"fullPageUrl\" : \"http://localhost/foo2\"," | |
| 684 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | |
| 685 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | |
| 686 " \"attribution\" : \"Foo News\"," | |
| 687 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," | |
| 688 " \"ampUrl\" : \"http://localhost/amp\"," | |
| 689 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | |
| 690 " }]" | |
| 691 "}]}"; | |
| 692 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | |
| 693 net::URLRequestStatus::SUCCESS); | |
| 694 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories; | |
| 695 EXPECT_CALL(mock_callback(), Run(_)) | |
| 696 .WillOnce(WithArg<0>(MovePointeeTo(&fetched_categories))); | |
| 697 auto params = test_params(); | |
| 698 params.exclusive_category = OptionalArticlesCategory(); | |
| 699 snippets_fetcher().FetchSnippets(params); | |
| 700 FastForwardUntilNoTasksRemain(); | |
| 701 | |
| 702 ASSERT_TRUE(fetched_categories); | |
| 703 ASSERT_THAT(fetched_categories->size(), Eq(1u)); | |
| 704 for (const auto& category : *fetched_categories) { | |
|
vitaliii
2016/11/01 23:29:57
There is no need to have a loop if there is an ASS
fhorschig
2016/11/02 05:05:27
Correct. Dropped in CL 2446163005.
| |
| 705 const auto& articles = category.snippets; | |
| 706 switch (category.category.id()) { | |
|
vitaliii
2016/11/01 23:29:57
Replace with an |if|.
fhorschig
2016/11/02 05:05:27
Also correct. Also dropped in CL 2446163005.
| |
| 707 case static_cast<int>(KnownCategories::ARTICLES): | |
| 708 ASSERT_THAT(articles.size(), Eq(1u)); | |
| 709 EXPECT_THAT(articles[0]->best_source().url.spec(), | |
| 710 Eq("http://localhost/foobar")); | |
| 711 break; | |
| 712 default: | |
| 713 FAIL() << "unexpected category with ID " << category.category.id(); | |
| 714 } | |
| 715 } | |
| 716 } | |
| 717 | |
| 718 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, EmptyExclusiveCategory) { | |
| 719 const std::string kJsonStr = | |
| 720 "{\"categories\" : [{" | |
| 721 " \"id\": 2," | |
| 722 " \"localizedTitle\": \"No Articles for You\"," | |
| 723 " \"suggestions\" : [{" | |
| 724 " \"ids\" : [\"http://localhost/foobar\"]," | |
| 725 " \"title\" : \"Foo Barred from Baz\"," | |
| 726 " \"snippet\" : \"...\"," | |
| 727 " \"fullPageUrl\" : \"http://localhost/foobar\"," | |
| 728 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | |
| 729 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | |
| 730 " \"attribution\" : \"Foo News\"," | |
| 731 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," | |
| 732 " \"ampUrl\" : \"http://localhost/amp\"," | |
| 733 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | |
| 734 " }]" | |
| 735 "}]}"; | |
| 736 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | |
| 737 net::URLRequestStatus::SUCCESS); | |
| 738 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories; | |
| 739 EXPECT_CALL(mock_callback(), Run(_)) | |
| 740 .WillOnce(WithArg<0>(MovePointeeTo(&fetched_categories))); | |
| 741 auto params = test_params(); | |
| 742 params.exclusive_category = OptionalArticlesCategory(); | |
| 743 snippets_fetcher().FetchSnippets(params); | |
| 744 FastForwardUntilNoTasksRemain(); | |
| 745 | |
| 746 ASSERT_TRUE(fetched_categories); | |
| 747 ASSERT_THAT(fetched_categories->size(), Eq(0u)); | |
|
vitaliii
2016/11/01 23:29:57
nit: EXPECT_THAT
fhorschig
2016/11/02 05:05:27
Done in CL 2446163005.
| |
| 748 } | |
| 749 | |
| 648 TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { | 750 TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { |
| 649 const std::string kJsonStr = "{\"recos\": []}"; | 751 const std::string kJsonStr = "{\"recos\": []}"; |
| 650 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 752 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 651 net::URLRequestStatus::SUCCESS); | 753 net::URLRequestStatus::SUCCESS); |
| 652 EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); | 754 EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); |
| 653 snippets_fetcher().FetchSnippets(test_params()); | 755 snippets_fetcher().FetchSnippets(test_params()); |
| 654 FastForwardUntilNoTasksRemain(); | 756 FastForwardUntilNoTasksRemain(); |
| 655 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 757 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); |
| 656 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 758 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); |
| 657 EXPECT_THAT( | 759 EXPECT_THAT( |
| 658 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 760 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 659 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); | 761 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); |
| 660 EXPECT_THAT(histogram_tester().GetAllSamples( | 762 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 661 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 763 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 662 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 764 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 663 } | 765 } |
| 664 | 766 |
| 665 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) { | 767 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) { |
| 666 net::TestURLFetcherFactory test_url_fetcher_factory; | 768 net::TestURLFetcherFactory test_url_fetcher_factory; |
| 667 NTPSnippetsFetcher::Params params = test_params(); | 769 auto params = test_params(); |
| 668 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; | 770 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; |
| 669 params.count_to_fetch = 17; | 771 params.count_to_fetch = 17; |
| 670 snippets_fetcher().FetchSnippets(params); | 772 snippets_fetcher().FetchSnippets(params); |
| 671 net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0); | 773 net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0); |
| 672 ASSERT_THAT(fetcher, NotNull()); | 774 ASSERT_THAT(fetcher, NotNull()); |
| 673 std::unique_ptr<base::Value> value = | 775 std::unique_ptr<base::Value> value = |
| 674 base::JSONReader::Read(fetcher->upload_data()); | 776 base::JSONReader::Read(fetcher->upload_data()); |
| 675 ASSERT_TRUE(value) << " failed to parse JSON: " | 777 ASSERT_TRUE(value) << " failed to parse JSON: " |
| 676 << PrintToString(fetcher->upload_data()); | 778 << PrintToString(fetcher->upload_data()); |
| 677 const base::DictionaryValue* dict = nullptr; | 779 const base::DictionaryValue* dict = nullptr; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { | 921 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { |
| 820 if (fetched_categories) { | 922 if (fetched_categories) { |
| 821 // Matchers above aren't any more precise than this, so this is sufficient | 923 // Matchers above aren't any more precise than this, so this is sufficient |
| 822 // for test-failure diagnostics. | 924 // for test-failure diagnostics. |
| 823 return os << "list with " << fetched_categories->size() << " elements"; | 925 return os << "list with " << fetched_categories->size() << " elements"; |
| 824 } | 926 } |
| 825 return os << "null"; | 927 return os << "null"; |
| 826 } | 928 } |
| 827 | 929 |
| 828 } // namespace ntp_snippets | 930 } // namespace ntp_snippets |
| OLD | NEW |