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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 }; | 337 }; |
| 338 | 338 |
| 339 class NTPSnippetsContentSuggestionsFetcherTest : public NTPSnippetsFetcherTest { | 339 class NTPSnippetsContentSuggestionsFetcherTest : public NTPSnippetsFetcherTest { |
| 340 public: | 340 public: |
| 341 NTPSnippetsContentSuggestionsFetcherTest() | 341 NTPSnippetsContentSuggestionsFetcherTest() |
| 342 : NTPSnippetsFetcherTest( | 342 : NTPSnippetsFetcherTest( |
| 343 GURL(kTestChromeContentSuggestionsUrl), | 343 GURL(kTestChromeContentSuggestionsUrl), |
| 344 {{"content_suggestions_backend", kContentSuggestionsServer}}) {} | 344 {{"content_suggestions_backend", kContentSuggestionsServer}}) {} |
| 345 }; | 345 }; |
| 346 | 346 |
| 347 // If you need access to the generated URLFetcher (i.e. all outgoing requests) | |
| 348 // or don't need to know about the SnippetsAvailableCallback, use this class. | |
| 349 // Tests derived from this class will never leak a SnippetsAvailableCallback. | |
| 350 // TODO(fhorschig): Move this class and related tests to separate test file when | |
| 351 // the NTPSnippetsFetcher::RequestBuilder gets moved to snippets::internal. | |
| 352 class NTPSnippetsInternalUrlFetcherTest : public NTPSnippetsFetcherTest { | |
|
tschumann
2016/12/06 18:18:25
sorry for the bystander, but it seems like inherit
fhorschig
2016/12/08 10:20:58
Thank you for the bystander comment! I was already
| |
| 353 public: | |
| 354 NTPSnippetsInternalUrlFetcherTest() : NTPSnippetsFetcherTest() {} | |
| 355 | |
| 356 void TearDown() override { | |
| 357 net::TestURLFetcher* fetcher = GetLastCreatedUrlFetcher(); | |
| 358 if (fetcher) { | |
| 359 CloseLastUrlFetcher(); | |
| 360 } | |
| 361 } | |
| 362 | |
| 363 net::TestURLFetcher* GetLastCreatedUrlFetcher() const { | |
| 364 net::TestURLFetcher* fetcher = test_url_fetcher_factory_.GetFetcherByID(0); | |
|
Marc Treib
2016/12/06 16:06:56
optional, to make this slightly less magic: It's p
fhorschig
2016/12/08 10:20:58
Done.
| |
| 365 return fetcher; | |
|
Marc Treib
2016/12/06 16:06:56
nit: just
return test_url_fetcher_factory_.GetFetc
fhorschig
2016/12/08 10:20:58
Done.
| |
| 366 } | |
| 367 | |
| 368 NTPSnippetsFetcher::SnippetsAvailableCallback | |
| 369 CreateSnippetsAvailableCallback() { | |
| 370 // If this expectation is triggered, the SnippetsAvailableCallback was not | |
| 371 // called. Did you trigger the creation of a new URLFetcher without calling | |
| 372 // |CloseLastUrlFetcher| to properly call the delegate of the last? | |
| 373 EXPECT_CALL(mock_callback(), Run(/*snippets=*/_)).Times(1); | |
| 374 return ToSnippetsAvailableCallback(&mock_callback()); | |
| 375 } | |
| 376 | |
| 377 // Call the last delegate callback manually as the TestURLFetcher deletes any | |
| 378 // call to the delegate that usually happens on |Start|. | |
| 379 // Without the call to the delegate, it leaks the request that owns itself. | |
| 380 void CloseLastUrlFetcher() { | |
| 381 // An 4XX response needs the least configuration to successfully invoke the | |
| 382 // callback properly. | |
| 383 net::TestURLFetcher* fetcher = GetLastCreatedUrlFetcher(); | |
| 384 ASSERT_THAT(fetcher->delegate(), NotNull()); | |
|
Marc Treib
2016/12/06 16:06:56
Also assert that |fetcher| itself isn't null?
fhorschig
2016/12/08 10:20:58
Done.
| |
| 385 fetcher->set_response_code(net::HTTP_NOT_FOUND); | |
| 386 fetcher->set_status( | |
| 387 net::URLRequestStatus(net::URLRequestStatus::FAILED, -2)); | |
|
Marc Treib
2016/12/06 16:06:56
nit: What's -2? Maybe add a /*name=*/?
fhorschig
2016/12/08 10:20:58
Done.
| |
| 388 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 389 test_url_fetcher_factory_.RemoveFetcherFromMap(0); | |
| 390 } | |
| 391 | |
| 392 private: | |
| 393 net::TestURLFetcherFactory test_url_fetcher_factory_; | |
| 394 }; | |
| 395 | |
| 347 TEST_F(NTPSnippetsFetcherTest, BuildRequestAuthenticated) { | 396 TEST_F(NTPSnippetsFetcherTest, BuildRequestAuthenticated) { |
| 348 NTPSnippetsFetcher::RequestBuilder builder; | 397 NTPSnippetsFetcher::RequestBuilder builder; |
| 349 NTPSnippetsFetcher::Params params; | 398 NTPSnippetsFetcher::Params params; |
| 350 params.hosts = {"chromium.org"}; | 399 params.hosts = {"chromium.org"}; |
| 351 params.excluded_ids = {"1234567890"}; | 400 params.excluded_ids = {"1234567890"}; |
| 352 params.count_to_fetch = 25; | 401 params.count_to_fetch = 25; |
| 353 params.interactive_request = false; | 402 params.interactive_request = false; |
| 354 builder.SetParams(params) | 403 builder.SetParams(params) |
| 355 .SetAuthentication("0BFUSGAIA", "headerstuff") | 404 .SetAuthentication("0BFUSGAIA", "headerstuff") |
| 356 .SetPersonalization(NTPSnippetsFetcher::Personalization::kPersonal) | 405 .SetPersonalization(NTPSnippetsFetcher::Personalization::kPersonal) |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 948 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); |
| 900 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 949 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); |
| 901 EXPECT_THAT( | 950 EXPECT_THAT( |
| 902 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 951 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 903 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); | 952 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); |
| 904 EXPECT_THAT(histogram_tester().GetAllSamples( | 953 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 905 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 954 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 906 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 955 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 907 } | 956 } |
| 908 | 957 |
| 909 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) { | 958 TEST_F(NTPSnippetsInternalUrlFetcherTest, ShouldRestrictToHosts) { |
| 910 net::TestURLFetcherFactory test_url_fetcher_factory; | |
| 911 NTPSnippetsFetcher::Params params = test_params(); | 959 NTPSnippetsFetcher::Params params = test_params(); |
| 912 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; | 960 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; |
| 913 params.count_to_fetch = 17; | 961 params.count_to_fetch = 17; |
| 914 snippets_fetcher().FetchSnippets( | 962 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); |
| 915 params, ToSnippetsAvailableCallback(&mock_callback())); | 963 net::TestURLFetcher* fetcher = GetLastCreatedUrlFetcher(); |
| 916 net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0); | |
| 917 ASSERT_THAT(fetcher, NotNull()); | 964 ASSERT_THAT(fetcher, NotNull()); |
| 918 std::unique_ptr<base::Value> value = | 965 std::unique_ptr<base::Value> value = |
| 919 base::JSONReader::Read(fetcher->upload_data()); | 966 base::JSONReader::Read(fetcher->upload_data()); |
| 920 ASSERT_TRUE(value) << " failed to parse JSON: " | 967 ASSERT_TRUE(value) << " failed to parse JSON: " |
| 921 << PrintToString(fetcher->upload_data()); | 968 << PrintToString(fetcher->upload_data()); |
| 922 const base::DictionaryValue* dict = nullptr; | 969 const base::DictionaryValue* dict = nullptr; |
| 923 ASSERT_TRUE(value->GetAsDictionary(&dict)); | 970 ASSERT_TRUE(value->GetAsDictionary(&dict)); |
| 924 const base::DictionaryValue* local_scoring_params = nullptr; | 971 const base::DictionaryValue* local_scoring_params = nullptr; |
| 925 ASSERT_TRUE(dict->GetDictionary("advanced_options.local_scoring_params", | 972 ASSERT_TRUE(dict->GetDictionary("advanced_options.local_scoring_params", |
| 926 &local_scoring_params)); | 973 &local_scoring_params)); |
| 927 const base::ListValue* content_selectors = nullptr; | 974 const base::ListValue* content_selectors = nullptr; |
| 928 ASSERT_TRUE( | 975 ASSERT_TRUE( |
| 929 local_scoring_params->GetList("content_selectors", &content_selectors)); | 976 local_scoring_params->GetList("content_selectors", &content_selectors)); |
| 930 ASSERT_THAT(content_selectors->GetSize(), Eq(static_cast<size_t>(2))); | 977 ASSERT_THAT(content_selectors->GetSize(), Eq(static_cast<size_t>(2))); |
| 931 const base::DictionaryValue* content_selector = nullptr; | 978 const base::DictionaryValue* content_selector = nullptr; |
| 932 ASSERT_TRUE(content_selectors->GetDictionary(0, &content_selector)); | 979 ASSERT_TRUE(content_selectors->GetDictionary(0, &content_selector)); |
| 933 std::string content_selector_value; | 980 std::string content_selector_value; |
| 934 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); | 981 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); |
| 935 EXPECT_THAT(content_selector_value, Eq("www.somehost1.com")); | 982 EXPECT_THAT(content_selector_value, Eq("www.somehost1.com")); |
| 936 ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector)); | 983 ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector)); |
| 937 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); | 984 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); |
| 938 EXPECT_THAT(content_selector_value, Eq("www.somehost2.com")); | 985 EXPECT_THAT(content_selector_value, Eq("www.somehost2.com")); |
| 939 // Call the delegate callback manually as the TestURLFetcher deletes any | 986 } |
| 940 // call to the delegate that usually happens on |Start|. | 987 |
| 941 // Without the call to the delegate, it leaks the request that owns itself. | 988 TEST_F(NTPSnippetsInternalUrlFetcherTest, RetryOnlyInteractiveRequests) { |
| 942 ASSERT_THAT(fetcher->delegate(), NotNull()); | 989 NTPSnippetsFetcher::Params params = test_params(); |
| 943 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); | 990 |
| 944 // An 4XX response needs the least configuration to successfully invoke the | 991 // Fetch interactive and expect that the created fechter would retry on 5xx. |
|
Marc Treib
2016/12/06 16:06:56
nit: s/fechter/fetcher/
fhorschig
2016/12/08 10:20:58
Done.
| |
| 945 // callback properly as the results are not important in this test. | 992 params.interactive_request = true; |
| 946 fetcher->set_response_code(net::HTTP_NOT_FOUND); | 993 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); |
| 947 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -2)); | 994 EXPECT_THAT(GetLastCreatedUrlFetcher()->GetMaxRetriesOn5xx(), Eq(2)); |
| 948 fetcher->delegate()->OnURLFetchComplete(fetcher); | 995 |
| 996 CloseLastUrlFetcher(); | |
|
Marc Treib
2016/12/06 16:06:56
nit: Split this into two tests, so that this expli
fhorschig
2016/12/08 10:20:58
Done.
| |
| 997 | |
| 998 // Fetch non-interactive and expect that the created fechter would not retry. | |
| 999 params.interactive_request = false; | |
| 1000 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); | |
| 1001 EXPECT_THAT(GetLastCreatedUrlFetcher()->GetMaxRetriesOn5xx(), Eq(0)); | |
| 949 } | 1002 } |
| 950 | 1003 |
| 951 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) { | 1004 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) { |
| 952 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 1005 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| 953 net::URLRequestStatus::FAILED); | 1006 net::URLRequestStatus::FAILED); |
| 954 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); | 1007 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); |
| 955 snippets_fetcher().FetchSnippets( | 1008 snippets_fetcher().FetchSnippets( |
| 956 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 1009 test_params(), ToSnippetsAvailableCallback(&mock_callback())); |
| 957 FastForwardUntilNoTasksRemain(); | 1010 FastForwardUntilNoTasksRemain(); |
| 958 EXPECT_THAT(snippets_fetcher().last_status(), | 1011 EXPECT_THAT(snippets_fetcher().last_status(), |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1088 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { | 1141 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { |
| 1089 if (fetched_categories) { | 1142 if (fetched_categories) { |
| 1090 // Matchers above aren't any more precise than this, so this is sufficient | 1143 // Matchers above aren't any more precise than this, so this is sufficient |
| 1091 // for test-failure diagnostics. | 1144 // for test-failure diagnostics. |
| 1092 return os << "list with " << fetched_categories->size() << " elements"; | 1145 return os << "list with " << fetched_categories->size() << " elements"; |
| 1093 } | 1146 } |
| 1094 return os << "null"; | 1147 return os << "null"; |
| 1095 } | 1148 } |
| 1096 | 1149 |
| 1097 } // namespace ntp_snippets | 1150 } // namespace ntp_snippets |
| OLD | NEW |