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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 class RequestBuilderWithMockedFlagsForTesting | 202 class RequestBuilderWithMockedFlagsForTesting |
| 203 : public NTPSnippetsFetcher::RequestBuilder { | 203 : public NTPSnippetsFetcher::RequestBuilder { |
| 204 public: | 204 public: |
| 205 RequestBuilderWithMockedFlagsForTesting() : RequestBuilder() {} | 205 RequestBuilderWithMockedFlagsForTesting() : RequestBuilder() {} |
| 206 | 206 |
| 207 private: | 207 private: |
| 208 bool IsSendingUserClassEnabled() const override { return true; } | 208 bool IsSendingUserClassEnabled() const override { return true; } |
| 209 bool IsSendingTopLanguagesEnabled() const override { return true; } | 209 bool IsSendingTopLanguagesEnabled() const override { return true; } |
| 210 }; | 210 }; |
| 211 | 211 |
| 212 class ScopedInjectedTestURLFetcherFactory { | |
|
tschumann
2016/12/08 13:27:53
now that I better understand the usage pattern, ma
fhorschig
2016/12/09 12:37:55
Moved.
Commented.
It is now a Factory itself and i
| |
| 213 public: | |
| 214 ScopedInjectedTestURLFetcherFactory() {} | |
| 215 ~ScopedInjectedTestURLFetcherFactory() { | |
| 216 net::TestURLFetcher* fetcher = GetLastCreatedUrlFetcher(); | |
|
tschumann
2016/12/08 13:27:53
either clearly document that we only support creat
fhorschig
2016/12/09 12:37:55
We support now creation of multiple fetchers [1],
| |
| 217 if (fetcher) { | |
| 218 // An 4XX response needs the least configuration to successfully invoke | |
| 219 // the callback properly. | |
| 220 fetcher->set_response_code(net::HTTP_NOT_FOUND); | |
| 221 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, | |
| 222 net::ERR_FAILED)); | |
| 223 fetcher->delegate()->OnURLFetchComplete(fetcher); | |
| 224 test_url_fetcher_factory_.RemoveFetcherFromMap(0); | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 net::TestURLFetcher* GetLastCreatedUrlFetcher() const { | |
| 229 // If there is a fetcher, the first fetcher is always at 0. | |
| 230 // If there is no fetcher, the resulting pointer will be nulltpr, no | |
| 231 // matter | |
| 232 // which index was used. | |
|
Marc Treib
2016/12/08 10:52:06
nit: some extra newlines here
fhorschig
2016/12/09 12:37:55
Done.
| |
| 233 // If you try to access another fetcher, the old fetcher must be destroyed | |
| 234 // manuall first (by calling |CloseLastUrlFetcher|) in order to secure | |
|
Marc Treib
2016/12/08 10:52:06
s/manuall/manually/
fhorschig
2016/12/09 12:37:55
Done.
| |
| 235 // that | |
| 236 // the delegate was called. This wouldn't happen by default and would leak | |
| 237 // a once-bound SnippetsAvailableCallback. | |
| 238 return test_url_fetcher_factory_.GetFetcherByID(0); | |
| 239 } | |
| 240 | |
| 241 private: | |
| 242 net::TestURLFetcherFactory test_url_fetcher_factory_; | |
| 243 }; | |
| 244 | |
| 212 NTPSnippetsFetcherTest() | 245 NTPSnippetsFetcherTest() |
| 213 : NTPSnippetsFetcherTest(GURL(kTestChromeReaderUrl), | 246 : NTPSnippetsFetcherTest(GURL(kTestChromeReaderUrl), |
| 214 std::map<std::string, std::string>()) {} | 247 std::map<std::string, std::string>()) {} |
| 215 | 248 |
| 216 NTPSnippetsFetcherTest(const GURL& gurl, | 249 NTPSnippetsFetcherTest(const GURL& gurl, |
| 217 const std::map<std::string, std::string>& params) | 250 const std::map<std::string, std::string>& params) |
| 218 : params_manager_( | 251 : params_manager_( |
| 219 base::MakeUnique<variations::testing::VariationParamsManager>( | 252 base::MakeUnique<variations::testing::VariationParamsManager>( |
| 220 ntp_snippets::kStudyName, | 253 ntp_snippets::kStudyName, |
| 221 params)), | 254 params)), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 243 fake_signin_manager_.get(), fake_token_service_.get(), | 276 fake_signin_manager_.get(), fake_token_service_.get(), |
| 244 scoped_refptr<net::TestURLRequestContextGetter>( | 277 scoped_refptr<net::TestURLRequestContextGetter>( |
| 245 new net::TestURLRequestContextGetter(mock_task_runner_.get())), | 278 new net::TestURLRequestContextGetter(mock_task_runner_.get())), |
| 246 pref_service_.get(), &category_factory_, nullptr, | 279 pref_service_.get(), &category_factory_, nullptr, |
| 247 base::Bind(&ParseJsonDelayed), kAPIKey, user_classifier_.get()); | 280 base::Bind(&ParseJsonDelayed), kAPIKey, user_classifier_.get()); |
| 248 | 281 |
| 249 snippets_fetcher_->SetTickClockForTesting( | 282 snippets_fetcher_->SetTickClockForTesting( |
| 250 mock_task_runner_->GetMockTickClock()); | 283 mock_task_runner_->GetMockTickClock()); |
| 251 } | 284 } |
| 252 | 285 |
| 286 NTPSnippetsFetcher::SnippetsAvailableCallback | |
| 287 CreateSnippetsAvailableCallback() { | |
| 288 // Make sure the callback gets executed. | |
| 289 EXPECT_CALL(mock_callback(), Run(/*snippets=*/_)).Times(1); | |
| 290 return ToSnippetsAvailableCallback(&mock_callback()); | |
|
Marc Treib
2016/12/08 10:52:06
Hm, how about inlining this into the tests themsel
tschumann
2016/12/08 13:27:53
+1
fhorschig
2016/12/09 12:37:55
Removed. As they cannot happen anymore with the de
| |
| 291 } | |
| 292 | |
| 253 NTPSnippetsFetcher::SnippetsAvailableCallback ToSnippetsAvailableCallback( | 293 NTPSnippetsFetcher::SnippetsAvailableCallback ToSnippetsAvailableCallback( |
| 254 MockSnippetsAvailableCallback* callback) { | 294 MockSnippetsAvailableCallback* callback) { |
| 255 return base::BindOnce(&MockSnippetsAvailableCallback::WrappedRun, | 295 return base::BindOnce(&MockSnippetsAvailableCallback::WrappedRun, |
| 256 base::Unretained(callback)); | 296 base::Unretained(callback)); |
| 257 } | 297 } |
| 258 | 298 |
| 259 NTPSnippetsFetcher& snippets_fetcher() { return *snippets_fetcher_; } | 299 NTPSnippetsFetcher& snippets_fetcher() { return *snippets_fetcher_; } |
| 260 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } | 300 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } |
| 261 void FastForwardUntilNoTasksRemain() { | 301 void FastForwardUntilNoTasksRemain() { |
| 262 mock_task_runner_->FastForwardUntilNoTasksRemain(); | 302 mock_task_runner_->FastForwardUntilNoTasksRemain(); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 273 void InitFakeURLFetcherFactory() { | 313 void InitFakeURLFetcherFactory() { |
| 274 if (fake_url_fetcher_factory_) { | 314 if (fake_url_fetcher_factory_) { |
| 275 return; | 315 return; |
| 276 } | 316 } |
| 277 // Instantiation of factory automatically sets itself as URLFetcher's | 317 // Instantiation of factory automatically sets itself as URLFetcher's |
| 278 // factory. | 318 // factory. |
| 279 fake_url_fetcher_factory_.reset(new net::FakeURLFetcherFactory( | 319 fake_url_fetcher_factory_.reset(new net::FakeURLFetcherFactory( |
| 280 /*default_factory=*/&failing_url_fetcher_factory_)); | 320 /*default_factory=*/&failing_url_fetcher_factory_)); |
| 281 } | 321 } |
| 282 | 322 |
| 283 void SetFetchingPersonalizationVariation( | 323 void SetVariationParameters( |
| 284 const std::string& personalization_string) { | 324 const std::map<std::string, std::string>& params) { |
| 285 params_manager_.reset(); | 325 params_manager_.reset(); |
| 286 std::map<std::string, std::string> params = { | |
| 287 {"fetching_personalization", personalization_string}}; | |
| 288 params_manager_ = | 326 params_manager_ = |
| 289 base::MakeUnique<variations::testing::VariationParamsManager>( | 327 base::MakeUnique<variations::testing::VariationParamsManager>( |
| 290 ntp_snippets::kStudyName, params); | 328 ntp_snippets::kStudyName, params); |
| 291 } | 329 } |
| 292 | 330 |
| 293 void SetFakeResponse(const std::string& response_data, | 331 void SetFakeResponse(const std::string& response_data, |
| 294 net::HttpStatusCode response_code, | 332 net::HttpStatusCode response_code, |
| 295 net::URLRequestStatus::Status status) { | 333 net::URLRequestStatus::Status status) { |
| 296 InitFakeURLFetcherFactory(); | 334 InitFakeURLFetcherFactory(); |
| 297 fake_url_fetcher_factory_->SetFakeResponse(test_url_, response_data, | 335 fake_url_fetcher_factory_->SetFakeResponse(test_url_, response_data, |
| (...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 865 Eq(CategoryFactory().FromRemoteCategory(2).id())); | 903 Eq(CategoryFactory().FromRemoteCategory(2).id())); |
| 866 ASSERT_THAT(category.snippets.size(), Eq(1u)); | 904 ASSERT_THAT(category.snippets.size(), Eq(1u)); |
| 867 EXPECT_THAT(category.snippets[0]->url().spec(), Eq("http://localhost/foo2")); | 905 EXPECT_THAT(category.snippets[0]->url().spec(), Eq("http://localhost/foo2")); |
| 868 } | 906 } |
| 869 | 907 |
| 870 TEST_F(NTPSnippetsFetcherTest, PersonalizesDependingOnVariations) { | 908 TEST_F(NTPSnippetsFetcherTest, PersonalizesDependingOnVariations) { |
| 871 // Default setting should be both personalization options. | 909 // Default setting should be both personalization options. |
| 872 EXPECT_THAT(snippets_fetcher().personalization(), | 910 EXPECT_THAT(snippets_fetcher().personalization(), |
| 873 Eq(NTPSnippetsFetcher::Personalization::kBoth)); | 911 Eq(NTPSnippetsFetcher::Personalization::kBoth)); |
| 874 | 912 |
| 875 SetFetchingPersonalizationVariation("personal"); | 913 SetVariationParameters({{"fetching_personalization", "personal"}}); |
| 876 ResetSnippetsFetcher(); | 914 ResetSnippetsFetcher(); |
| 877 EXPECT_THAT(snippets_fetcher().personalization(), | 915 EXPECT_THAT(snippets_fetcher().personalization(), |
| 878 Eq(NTPSnippetsFetcher::Personalization::kPersonal)); | 916 Eq(NTPSnippetsFetcher::Personalization::kPersonal)); |
| 879 | 917 |
| 880 SetFetchingPersonalizationVariation("non_personal"); | 918 SetVariationParameters({{"fetching_personalization", "non_personal"}}); |
| 881 ResetSnippetsFetcher(); | 919 ResetSnippetsFetcher(); |
| 882 EXPECT_THAT(snippets_fetcher().personalization(), | 920 EXPECT_THAT(snippets_fetcher().personalization(), |
| 883 Eq(NTPSnippetsFetcher::Personalization::kNonPersonal)); | 921 Eq(NTPSnippetsFetcher::Personalization::kNonPersonal)); |
| 884 | 922 |
| 885 SetFetchingPersonalizationVariation("both"); | 923 SetVariationParameters({{"fetching_personalization", "both"}}); |
| 886 ResetSnippetsFetcher(); | 924 ResetSnippetsFetcher(); |
| 887 EXPECT_THAT(snippets_fetcher().personalization(), | 925 EXPECT_THAT(snippets_fetcher().personalization(), |
| 888 Eq(NTPSnippetsFetcher::Personalization::kBoth)); | 926 Eq(NTPSnippetsFetcher::Personalization::kBoth)); |
| 889 } | 927 } |
| 890 | 928 |
| 891 TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { | 929 TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { |
| 892 const std::string kJsonStr = "{\"recos\": []}"; | 930 const std::string kJsonStr = "{\"recos\": []}"; |
| 893 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 931 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 894 net::URLRequestStatus::SUCCESS); | 932 net::URLRequestStatus::SUCCESS); |
| 895 EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); | 933 EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); |
| 896 snippets_fetcher().FetchSnippets( | 934 snippets_fetcher().FetchSnippets( |
| 897 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 935 test_params(), ToSnippetsAvailableCallback(&mock_callback())); |
| 898 FastForwardUntilNoTasksRemain(); | 936 FastForwardUntilNoTasksRemain(); |
| 899 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 937 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); |
| 900 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 938 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); |
| 901 EXPECT_THAT( | 939 EXPECT_THAT( |
| 902 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 940 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 903 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); | 941 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); |
| 904 EXPECT_THAT(histogram_tester().GetAllSamples( | 942 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 905 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 943 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 906 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 944 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 907 } | 945 } |
| 908 | 946 |
| 909 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) { | 947 TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) { |
| 910 net::TestURLFetcherFactory test_url_fetcher_factory; | |
| 911 NTPSnippetsFetcher::Params params = test_params(); | 948 NTPSnippetsFetcher::Params params = test_params(); |
| 912 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; | 949 params.hosts = {"www.somehost1.com", "www.somehost2.com"}; |
| 913 params.count_to_fetch = 17; | 950 params.count_to_fetch = 17; |
| 914 snippets_fetcher().FetchSnippets( | 951 std::unique_ptr<base::Value> value; |
| 915 params, ToSnippetsAvailableCallback(&mock_callback())); | 952 { |
| 916 net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0); | 953 ScopedInjectedTestURLFetcherFactory url_fetcher_factory; |
| 917 ASSERT_THAT(fetcher, NotNull()); | 954 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); |
| 918 std::unique_ptr<base::Value> value = | 955 |
| 919 base::JSONReader::Read(fetcher->upload_data()); | 956 net::TestURLFetcher* fetcher = |
| 920 ASSERT_TRUE(value) << " failed to parse JSON: " | 957 url_fetcher_factory.GetLastCreatedUrlFetcher(); |
| 921 << PrintToString(fetcher->upload_data()); | 958 ASSERT_THAT(fetcher, NotNull()); |
| 959 value = base::JSONReader::Read(fetcher->upload_data()); | |
| 960 ASSERT_TRUE(value) << " failed to parse JSON: " | |
| 961 << PrintToString(fetcher->upload_data()); | |
| 962 } | |
| 922 const base::DictionaryValue* dict = nullptr; | 963 const base::DictionaryValue* dict = nullptr; |
| 923 ASSERT_TRUE(value->GetAsDictionary(&dict)); | 964 ASSERT_TRUE(value->GetAsDictionary(&dict)); |
| 924 const base::DictionaryValue* local_scoring_params = nullptr; | 965 const base::DictionaryValue* local_scoring_params = nullptr; |
| 925 ASSERT_TRUE(dict->GetDictionary("advanced_options.local_scoring_params", | 966 ASSERT_TRUE(dict->GetDictionary("advanced_options.local_scoring_params", |
| 926 &local_scoring_params)); | 967 &local_scoring_params)); |
| 927 const base::ListValue* content_selectors = nullptr; | 968 const base::ListValue* content_selectors = nullptr; |
| 928 ASSERT_TRUE( | 969 ASSERT_TRUE( |
| 929 local_scoring_params->GetList("content_selectors", &content_selectors)); | 970 local_scoring_params->GetList("content_selectors", &content_selectors)); |
| 930 ASSERT_THAT(content_selectors->GetSize(), Eq(static_cast<size_t>(2))); | 971 ASSERT_THAT(content_selectors->GetSize(), Eq(static_cast<size_t>(2))); |
| 931 const base::DictionaryValue* content_selector = nullptr; | 972 const base::DictionaryValue* content_selector = nullptr; |
| 932 ASSERT_TRUE(content_selectors->GetDictionary(0, &content_selector)); | 973 ASSERT_TRUE(content_selectors->GetDictionary(0, &content_selector)); |
| 933 std::string content_selector_value; | 974 std::string content_selector_value; |
| 934 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); | 975 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); |
| 935 EXPECT_THAT(content_selector_value, Eq("www.somehost1.com")); | 976 EXPECT_THAT(content_selector_value, Eq("www.somehost1.com")); |
| 936 ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector)); | 977 ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector)); |
| 937 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); | 978 EXPECT_TRUE(content_selector->GetString("value", &content_selector_value)); |
| 938 EXPECT_THAT(content_selector_value, Eq("www.somehost2.com")); | 979 EXPECT_THAT(content_selector_value, Eq("www.somehost2.com")); |
| 939 // Call the delegate callback manually as the TestURLFetcher deletes any | 980 } |
| 940 // call to the delegate that usually happens on |Start|. | 981 |
| 941 // Without the call to the delegate, it leaks the request that owns itself. | 982 TEST_F(NTPSnippetsFetcherTest, RetryOnInteractiveRequests) { |
| 942 ASSERT_THAT(fetcher->delegate(), NotNull()); | 983 NTPSnippetsFetcher::Params params = test_params(); |
| 943 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); | 984 params.interactive_request = true; |
| 944 // An 4XX response needs the least configuration to successfully invoke the | 985 { |
| 945 // callback properly as the results are not important in this test. | 986 ScopedInjectedTestURLFetcherFactory url_fetcher_factory; |
| 946 fetcher->set_response_code(net::HTTP_NOT_FOUND); | 987 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); |
| 947 fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -2)); | 988 |
| 948 fetcher->delegate()->OnURLFetchComplete(fetcher); | 989 net::TestURLFetcher* fetcher = |
| 990 url_fetcher_factory.GetLastCreatedUrlFetcher(); | |
| 991 ASSERT_THAT(fetcher, NotNull()); | |
| 992 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(2)); | |
| 993 } | |
| 994 } | |
| 995 | |
| 996 TEST_F(NTPSnippetsFetcherTest, RetriesConfigurableOnNonInteractiveRequests) { | |
| 997 NTPSnippetsFetcher::Params params = test_params(); | |
| 998 params.interactive_request = false; | |
| 999 std::map<std::string, int> expected_retries_for_configurations = { | |
|
Marc Treib
2016/12/08 10:52:06
Make this const?
I'd also slightly prefer an array
tschumann
2016/12/08 13:27:53
Using a struct would be better indeed -- you seem
Marc Treib
2016/12/08 13:31:56
Right, vector also works, now that we have std::in
fhorschig
2016/12/09 12:37:55
Done.
| |
| 1000 {"", 0}, // Keep 2 retries if no variation is set. | |
| 1001 {"0", 0}, | |
| 1002 {"-1", 0}, // Allow no negative retry count. | |
| 1003 {"3", 3}}; | |
| 1004 | |
| 1005 for (auto retry_configuration : expected_retries_for_configurations) { | |
|
Marc Treib
2016/12/08 10:52:06
const auto&
?
fhorschig
2016/12/09 12:37:55
Done.
| |
| 1006 ScopedInjectedTestURLFetcherFactory url_fetcher_factory; | |
| 1007 SetVariationParameters( | |
| 1008 {{"number_of_non_interactive_5xx_retries", retry_configuration.first}}); | |
| 1009 | |
| 1010 snippets_fetcher().FetchSnippets(params, CreateSnippetsAvailableCallback()); | |
| 1011 | |
| 1012 net::TestURLFetcher* fetcher = | |
| 1013 url_fetcher_factory.GetLastCreatedUrlFetcher(); | |
| 1014 ASSERT_THAT(fetcher, NotNull()); | |
| 1015 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(retry_configuration.second)); | |
| 1016 } | |
| 949 } | 1017 } |
| 950 | 1018 |
| 951 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) { | 1019 TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) { |
| 952 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 1020 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| 953 net::URLRequestStatus::FAILED); | 1021 net::URLRequestStatus::FAILED); |
| 954 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); | 1022 EXPECT_CALL(mock_callback(), Run(/*snippets=*/Not(HasValue()))).Times(1); |
| 955 snippets_fetcher().FetchSnippets( | 1023 snippets_fetcher().FetchSnippets( |
| 956 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 1024 test_params(), ToSnippetsAvailableCallback(&mock_callback())); |
| 957 FastForwardUntilNoTasksRemain(); | 1025 FastForwardUntilNoTasksRemain(); |
| 958 EXPECT_THAT(snippets_fetcher().last_status(), | 1026 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) { | 1156 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { |
| 1089 if (fetched_categories) { | 1157 if (fetched_categories) { |
| 1090 // Matchers above aren't any more precise than this, so this is sufficient | 1158 // Matchers above aren't any more precise than this, so this is sufficient |
| 1091 // for test-failure diagnostics. | 1159 // for test-failure diagnostics. |
| 1092 return os << "list with " << fetched_categories->size() << " elements"; | 1160 return os << "list with " << fetched_categories->size() << " elements"; |
| 1093 } | 1161 } |
| 1094 return os << "null"; | 1162 return os << "null"; |
| 1095 } | 1163 } |
| 1096 | 1164 |
| 1097 } // namespace ntp_snippets | 1165 } // namespace ntp_snippets |
| OLD | NEW |