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/remote_suggestions_fetcher.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_fetcher.h" |
| 6 | 6 |
| 7 #include <deque> | 7 #include <deque> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 16 #include "base/test/histogram_tester.h" | 16 #include "base/test/histogram_tester.h" |
| 17 #include "base/test/test_mock_time_task_runner.h" | 17 #include "base/test/test_mock_time_task_runner.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 20 #include "base/values.h" | 20 #include "base/values.h" |
| 21 #include "components/ntp_snippets/category.h" | 21 #include "components/ntp_snippets/category.h" |
| 22 #include "components/ntp_snippets/features.h" | 22 #include "components/ntp_snippets/features.h" |
| 23 #include "components/ntp_snippets/ntp_snippets_constants.h" | 23 #include "components/ntp_snippets/ntp_snippets_constants.h" |
| 24 #include "components/ntp_snippets/remote/remote_suggestion.h" | 24 #include "components/ntp_snippets/remote/remote_suggestion.h" |
| 25 #include "components/ntp_snippets/remote/request_params.h" | 25 #include "components/ntp_snippets/remote/request_params.h" |
| 26 #include "components/ntp_snippets/remote/test_utils.h" | |
| 26 #include "components/ntp_snippets/user_classifier.h" | 27 #include "components/ntp_snippets/user_classifier.h" |
| 27 #include "components/prefs/testing_pref_service.h" | 28 #include "components/prefs/testing_pref_service.h" |
| 28 #include "components/signin/core/browser/account_tracker_service.h" | |
| 29 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" | 29 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
| 30 #include "components/signin/core/browser/fake_signin_manager.h" | 30 #include "components/signin/core/browser/fake_signin_manager.h" |
| 31 #include "components/signin/core/browser/test_signin_client.h" | |
| 32 #include "components/variations/entropy_provider.h" | 31 #include "components/variations/entropy_provider.h" |
| 33 #include "components/variations/variations_params_manager.h" | 32 #include "components/variations/variations_params_manager.h" |
| 33 #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" | |
| 34 #include "net/url_request/test_url_fetcher_factory.h" | 34 #include "net/url_request/test_url_fetcher_factory.h" |
| 35 #include "net/url_request/url_request_test_util.h" | 35 #include "net/url_request/url_request_test_util.h" |
| 36 #include "testing/gmock/include/gmock/gmock.h" | 36 #include "testing/gmock/include/gmock/gmock.h" |
| 37 #include "testing/gtest/include/gtest/gtest.h" | 37 #include "testing/gtest/include/gtest/gtest.h" |
| 38 | 38 |
| 39 namespace ntp_snippets { | 39 namespace ntp_snippets { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 using testing::_; | 43 using testing::_; |
| 44 using testing::AllOf; | 44 using testing::AllOf; |
| 45 using testing::ElementsAre; | 45 using testing::ElementsAre; |
| 46 using testing::Eq; | 46 using testing::Eq; |
| 47 using testing::Field; | 47 using testing::Field; |
| 48 using testing::IsEmpty; | 48 using testing::IsEmpty; |
| 49 using testing::Not; | 49 using testing::Not; |
| 50 using testing::NotNull; | 50 using testing::NotNull; |
| 51 using testing::Pointee; | 51 using testing::Pointee; |
| 52 using testing::PrintToString; | 52 using testing::PrintToString; |
| 53 using testing::Return; | 53 using testing::Return; |
| 54 using testing::StartsWith; | 54 using testing::StartsWith; |
| 55 using testing::WithArg; | 55 using testing::WithArg; |
| 56 | 56 |
| 57 const char kAPIKey[] = "fakeAPIkey"; | 57 const char kAPIKey[] = "fakeAPIkey"; |
| 58 const char kTestChromeReaderUrl[] = | 58 const char kTestChromeReaderUrl[] = |
| 59 "https://chromereader-pa.googleapis.com/v1/fetch?key=fakeAPIkey"; | 59 "https://chromereader-pa.googleapis.com/v1/fetch?key=fakeAPIkey"; |
| 60 const char kTestChromeContentSuggestionsUrl[] = | 60 const char kTestChromeContentSuggestionsSignedOutUrl[] = |
| 61 "https://chromecontentsuggestions-pa.googleapis.com/v1/suggestions/" | 61 "https://chromecontentsuggestions-pa.googleapis.com/v1/suggestions/" |
| 62 "fetch?key=fakeAPIkey"; | 62 "fetch?key=fakeAPIkey"; |
| 63 const char kTestChromeContentSuggestionsSignedInUrl[] = | |
| 64 "https://chromecontentsuggestions-pa.googleapis.com/v1/suggestions/fetch"; | |
| 65 | |
| 66 const char kTestEmail[] = "foo@bar.com"; | |
| 63 | 67 |
| 64 // Artificial time delay for JSON parsing. | 68 // Artificial time delay for JSON parsing. |
| 65 const int64_t kTestJsonParsingLatencyMs = 20; | 69 const int64_t kTestJsonParsingLatencyMs = 20; |
| 66 | 70 |
| 67 ACTION_P(MoveArgument1PointeeTo, ptr) { | 71 ACTION_P(MoveArgument1PointeeTo, ptr) { |
| 68 *ptr = std::move(*arg1); | 72 *ptr = std::move(*arg1); |
| 69 } | 73 } |
| 70 | 74 |
| 71 MATCHER(HasValue, "") { | 75 MATCHER(HasValue, "") { |
| 72 return static_cast<bool>(*arg); | 76 return static_cast<bool>(*arg); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 success_callback.Run(std::move(value)); | 257 success_callback.Run(std::move(value)); |
| 254 } else { | 258 } else { |
| 255 error_callback.Run(json_reader.GetErrorMessage()); | 259 error_callback.Run(json_reader.GetErrorMessage()); |
| 256 } | 260 } |
| 257 } | 261 } |
| 258 | 262 |
| 259 void ParseJsonDelayed(const std::string& json, | 263 void ParseJsonDelayed(const std::string& json, |
| 260 const SuccessCallback& success_callback, | 264 const SuccessCallback& success_callback, |
| 261 const ErrorCallback& error_callback) { | 265 const ErrorCallback& error_callback) { |
| 262 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 266 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 263 FROM_HERE, base::Bind(&ParseJson, json, std::move(success_callback), | 267 FROM_HERE, |
| 264 std::move(error_callback)), | 268 base::Bind(&ParseJson, json, std::move(success_callback), |
|
jkrcal
2017/02/07 08:44:18
I did many find-and-replace changes so I used clan
Marc Treib
2017/02/07 09:18:12
Acknowledged.
| |
| 269 std::move(error_callback)), | |
| 265 base::TimeDelta::FromMilliseconds(kTestJsonParsingLatencyMs)); | 270 base::TimeDelta::FromMilliseconds(kTestJsonParsingLatencyMs)); |
| 266 } | 271 } |
| 267 | 272 |
| 268 } // namespace | 273 } // namespace |
| 269 | 274 |
| 270 // TODO(jkrcal): Add unit-tests with signin client being signed in (covering | 275 // TODO(jkrcal): Add unit-tests with signin client being signed in (covering |
| 271 // sign-in / refresh tokens / access token code). crbug.com/688310 | 276 // sign-in / refresh tokens / access token code). crbug.com/688310 |
|
Marc Treib
2017/02/07 09:18:12
I guess this comment can be removed now :) (or ma
jkrcal
2017/02/07 09:27:33
Done.
| |
| 272 class RemoteSuggestionsFetcherTestBase : public testing::Test { | 277 class RemoteSuggestionsFetcherTestBase : public testing::Test { |
| 273 public: | 278 public: |
| 274 explicit RemoteSuggestionsFetcherTestBase(const GURL& gurl) | 279 explicit RemoteSuggestionsFetcherTestBase(const GURL& gurl) |
| 275 : default_variation_params_( | 280 : default_variation_params_( |
| 276 {{"send_top_languages", "true"}, {"send_user_class", "true"}}), | 281 {{"send_top_languages", "true"}, {"send_user_class", "true"}}), |
| 277 params_manager_(ntp_snippets::kStudyName, | 282 params_manager_(ntp_snippets::kStudyName, |
| 278 default_variation_params_, | 283 default_variation_params_, |
| 279 {ntp_snippets::kArticleSuggestionsFeature.name}), | 284 {ntp_snippets::kArticleSuggestionsFeature.name}), |
| 280 mock_task_runner_(new base::TestMockTimeTaskRunner()), | 285 mock_task_runner_(new base::TestMockTimeTaskRunner()), |
| 281 mock_task_runner_handle_(mock_task_runner_), | 286 mock_task_runner_handle_(mock_task_runner_), |
| 282 signin_client_(base::MakeUnique<TestSigninClient>(nullptr)), | |
| 283 account_tracker_(base::MakeUnique<AccountTrackerService>()), | |
| 284 fake_signin_manager_( | |
| 285 base::MakeUnique<FakeSigninManagerBase>(signin_client_.get(), | |
| 286 account_tracker_.get())), | |
| 287 fake_token_service_(base::MakeUnique<FakeProfileOAuth2TokenService>()), | |
| 288 pref_service_(base::MakeUnique<TestingPrefServiceSimple>()), | |
| 289 test_url_(gurl) { | 287 test_url_(gurl) { |
| 290 RequestThrottler::RegisterProfilePrefs(pref_service_->registry()); | 288 RequestThrottler::RegisterProfilePrefs(utils_.pref_service()->registry()); |
| 291 UserClassifier::RegisterProfilePrefs(pref_service_->registry()); | 289 UserClassifier::RegisterProfilePrefs(utils_.pref_service()->registry()); |
| 292 user_classifier_ = base::MakeUnique<UserClassifier>(pref_service_.get()); | 290 user_classifier_ = base::MakeUnique<UserClassifier>(utils_.pref_service()); |
| 293 // Increase initial time such that ticks are non-zero. | 291 // Increase initial time such that ticks are non-zero. |
| 294 mock_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1234)); | 292 mock_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1234)); |
| 295 ResetSnippetsFetcher(); | 293 ResetFetcher(); |
| 296 } | 294 } |
| 297 | 295 |
| 298 void ResetSnippetsFetcher() { | 296 void ResetFetcher() { |
|
jkrcal
2017/02/07 08:44:18
A bit non-conceptional: I took the chance to remov
Marc Treib
2017/02/07 09:18:12
Yay!
| |
| 299 snippets_fetcher_ = base::MakeUnique<RemoteSuggestionsFetcher>( | 297 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = |
| 300 fake_signin_manager_.get(), fake_token_service_.get(), | 298 new net::TestURLRequestContextGetter(mock_task_runner_.get()); |
| 301 scoped_refptr<net::TestURLRequestContextGetter>( | |
| 302 new net::TestURLRequestContextGetter(mock_task_runner_.get())), | |
| 303 pref_service_.get(), nullptr, base::Bind(&ParseJsonDelayed), kAPIKey, | |
| 304 user_classifier_.get()); | |
| 305 | 299 |
| 306 snippets_fetcher_->SetTickClockForTesting( | 300 fake_token_service_delegate_ = |
| 307 mock_task_runner_->GetMockTickClock()); | 301 new FakeOAuth2TokenServiceDelegate(request_context_getter.get()); |
| 302 // Not a memleak because OAuth2TokenService takes ownership of the raw | |
| 303 // pointer (crbug.com/688387). | |
| 304 fake_token_service_ = base::MakeUnique<FakeProfileOAuth2TokenService>( | |
| 305 fake_token_service_delegate_); | |
| 306 | |
| 307 fetcher_ = base::MakeUnique<RemoteSuggestionsFetcher>( | |
| 308 utils_.fake_signin_manager(), fake_token_service_.get(), | |
| 309 std::move(request_context_getter), utils_.pref_service(), nullptr, | |
| 310 base::Bind(&ParseJsonDelayed), kAPIKey, user_classifier_.get()); | |
| 311 | |
| 312 fetcher_->SetTickClockForTesting(mock_task_runner_->GetMockTickClock()); | |
| 313 } | |
| 314 | |
| 315 void SignIn() { utils_.fake_signin_manager()->SignIn(kTestEmail); } | |
| 316 | |
| 317 void IssueRefreshToken() { | |
| 318 fake_token_service_delegate_->UpdateCredentials(kTestEmail, "token"); | |
| 319 } | |
| 320 | |
| 321 void IssueOAuth2Token() { | |
| 322 fake_token_service_->IssueAllTokensForAccount(kTestEmail, "access_token", | |
| 323 base::Time::Max()); | |
| 324 } | |
| 325 | |
| 326 void CancelOAuth2TokenRequests() { | |
| 327 fake_token_service_->IssueErrorForAllPendingRequestsForAccount( | |
| 328 kTestEmail, GoogleServiceAuthError( | |
| 329 GoogleServiceAuthError::State::REQUEST_CANCELED)); | |
| 308 } | 330 } |
| 309 | 331 |
| 310 RemoteSuggestionsFetcher::SnippetsAvailableCallback | 332 RemoteSuggestionsFetcher::SnippetsAvailableCallback |
| 311 ToSnippetsAvailableCallback(MockSnippetsAvailableCallback* callback) { | 333 ToSnippetsAvailableCallback(MockSnippetsAvailableCallback* callback) { |
| 312 return base::BindOnce(&MockSnippetsAvailableCallback::WrappedRun, | 334 return base::BindOnce(&MockSnippetsAvailableCallback::WrappedRun, |
| 313 base::Unretained(callback)); | 335 base::Unretained(callback)); |
| 314 } | 336 } |
| 315 | 337 |
| 316 RemoteSuggestionsFetcher& snippets_fetcher() { return *snippets_fetcher_; } | 338 RemoteSuggestionsFetcher& fetcher() { return *fetcher_; } |
| 317 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } | 339 MockSnippetsAvailableCallback& mock_callback() { return mock_callback_; } |
| 318 void FastForwardUntilNoTasksRemain() { | 340 void FastForwardUntilNoTasksRemain() { |
| 319 mock_task_runner_->FastForwardUntilNoTasksRemain(); | 341 mock_task_runner_->FastForwardUntilNoTasksRemain(); |
| 320 } | 342 } |
| 321 base::HistogramTester& histogram_tester() { return histogram_tester_; } | 343 base::HistogramTester& histogram_tester() { return histogram_tester_; } |
| 322 | 344 |
| 323 RequestParams test_params() { | 345 RequestParams test_params() { |
| 324 RequestParams result; | 346 RequestParams result; |
| 325 result.count_to_fetch = 1; | 347 result.count_to_fetch = 1; |
| 326 result.interactive_request = true; | 348 result.interactive_request = true; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 348 } | 370 } |
| 349 | 371 |
| 350 void SetFakeResponse(const std::string& response_data, | 372 void SetFakeResponse(const std::string& response_data, |
| 351 net::HttpStatusCode response_code, | 373 net::HttpStatusCode response_code, |
| 352 net::URLRequestStatus::Status status) { | 374 net::URLRequestStatus::Status status) { |
| 353 InitFakeURLFetcherFactory(); | 375 InitFakeURLFetcherFactory(); |
| 354 fake_url_fetcher_factory_->SetFakeResponse(test_url_, response_data, | 376 fake_url_fetcher_factory_->SetFakeResponse(test_url_, response_data, |
| 355 response_code, status); | 377 response_code, status); |
| 356 } | 378 } |
| 357 | 379 |
| 358 TestingPrefServiceSimple* pref_service() const { return pref_service_.get(); } | |
| 359 | |
| 360 protected: | 380 protected: |
| 361 std::map<std::string, std::string> default_variation_params_; | 381 std::map<std::string, std::string> default_variation_params_; |
| 362 | 382 |
| 363 private: | 383 private: |
| 384 test::RemoteSuggestionsTestUtils utils_; | |
| 364 variations::testing::VariationParamsManager params_manager_; | 385 variations::testing::VariationParamsManager params_manager_; |
| 365 scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; | 386 scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; |
| 366 base::ThreadTaskRunnerHandle mock_task_runner_handle_; | 387 base::ThreadTaskRunnerHandle mock_task_runner_handle_; |
| 367 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; | 388 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; |
| 368 // Initialized lazily in SetFakeResponse(). | 389 // Initialized lazily in SetFakeResponse(). |
| 369 std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_; | 390 std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_; |
| 370 std::unique_ptr<TestSigninClient> signin_client_; | 391 FakeOAuth2TokenServiceDelegate* fake_token_service_delegate_; |
| 371 std::unique_ptr<AccountTrackerService> account_tracker_; | 392 std::unique_ptr<FakeProfileOAuth2TokenService> fake_token_service_; |
| 372 std::unique_ptr<SigninManagerBase> fake_signin_manager_; | 393 std::unique_ptr<RemoteSuggestionsFetcher> fetcher_; |
| 373 std::unique_ptr<OAuth2TokenService> fake_token_service_; | |
| 374 std::unique_ptr<RemoteSuggestionsFetcher> snippets_fetcher_; | |
| 375 std::unique_ptr<TestingPrefServiceSimple> pref_service_; | |
| 376 std::unique_ptr<UserClassifier> user_classifier_; | 394 std::unique_ptr<UserClassifier> user_classifier_; |
| 377 MockSnippetsAvailableCallback mock_callback_; | 395 MockSnippetsAvailableCallback mock_callback_; |
| 378 const GURL test_url_; | 396 const GURL test_url_; |
| 379 base::HistogramTester histogram_tester_; | 397 base::HistogramTester histogram_tester_; |
| 380 | 398 |
| 381 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsFetcherTestBase); | 399 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsFetcherTestBase); |
| 382 }; | 400 }; |
| 383 | 401 |
| 384 class ChromeReaderSnippetsFetcherTest | 402 class RemoteSuggestionsChromeReaderFetcherTest |
|
jkrcal
2017/02/07 08:44:18
When creating a new class, I took the chance to re
Marc Treib
2017/02/07 09:18:12
Acknowledged.
| |
| 385 : public RemoteSuggestionsFetcherTestBase { | 403 : public RemoteSuggestionsFetcherTestBase { |
| 386 public: | 404 public: |
| 387 ChromeReaderSnippetsFetcherTest() | 405 RemoteSuggestionsChromeReaderFetcherTest() |
| 388 : RemoteSuggestionsFetcherTestBase(GURL(kTestChromeReaderUrl)) { | 406 : RemoteSuggestionsFetcherTestBase(GURL(kTestChromeReaderUrl)) { |
| 389 default_variation_params_["content_suggestions_backend"] = | 407 default_variation_params_["content_suggestions_backend"] = |
| 390 kChromeReaderServer; | 408 kChromeReaderServer; |
| 391 SetVariationParam("content_suggestions_backend", kChromeReaderServer); | 409 SetVariationParam("content_suggestions_backend", kChromeReaderServer); |
| 392 ResetSnippetsFetcher(); | 410 ResetFetcher(); |
| 393 } | 411 } |
| 394 }; | 412 }; |
| 395 | 413 |
| 396 class NTPSnippetsContentSuggestionsFetcherTest | 414 class RemoteSuggestionsSignedOutFetcherTest |
| 397 : public RemoteSuggestionsFetcherTestBase { | 415 : public RemoteSuggestionsFetcherTestBase { |
| 398 public: | 416 public: |
| 399 NTPSnippetsContentSuggestionsFetcherTest() | 417 RemoteSuggestionsSignedOutFetcherTest() |
| 400 : RemoteSuggestionsFetcherTestBase( | 418 : RemoteSuggestionsFetcherTestBase( |
| 401 GURL(kTestChromeContentSuggestionsUrl)) {} | 419 GURL(kTestChromeContentSuggestionsSignedOutUrl)) {} |
| 402 }; | 420 }; |
| 403 | 421 |
| 404 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldNotFetchOnCreation) { | 422 class RemoteSuggestionsSignedInFetcherTest |
| 423 : public RemoteSuggestionsFetcherTestBase { | |
| 424 public: | |
| 425 RemoteSuggestionsSignedInFetcherTest() | |
| 426 : RemoteSuggestionsFetcherTestBase( | |
| 427 GURL(kTestChromeContentSuggestionsSignedInUrl)) {} | |
| 428 }; | |
| 429 | |
| 430 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldNotFetchOnCreation) { | |
| 405 // The lack of registered baked in responses would cause any fetch to fail. | 431 // The lack of registered baked in responses would cause any fetch to fail. |
| 406 FastForwardUntilNoTasksRemain(); | 432 FastForwardUntilNoTasksRemain(); |
| 407 EXPECT_THAT(histogram_tester().GetAllSamples( | 433 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 408 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 434 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 409 IsEmpty()); | 435 IsEmpty()); |
| 410 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 436 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 411 IsEmpty()); | 437 IsEmpty()); |
| 412 EXPECT_THAT(snippets_fetcher().last_status(), IsEmpty()); | 438 EXPECT_THAT(fetcher().last_status(), IsEmpty()); |
| 413 } | 439 } |
| 414 | 440 |
| 415 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldFetchSuccessfully) { | 441 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldFetchSuccessfully) { |
| 416 const std::string kJsonStr = | 442 const std::string kJsonStr = |
| 417 "{\"recos\": [{" | 443 "{\"recos\": [{" |
| 418 " \"contentInfo\": {" | 444 " \"contentInfo\": {" |
| 419 " \"url\" : \"http://localhost/foobar\"," | 445 " \"url\" : \"http://localhost/foobar\"," |
| 420 " \"sourceCorpusInfo\" : [{" | 446 " \"sourceCorpusInfo\" : [{" |
| 421 " \"ampUrl\" : \"http://localhost/amp\"," | 447 " \"ampUrl\" : \"http://localhost/amp\"," |
| 422 " \"corpusId\" : \"http://localhost/foobar\"," | 448 " \"corpusId\" : \"http://localhost/foobar\"," |
| 423 " \"publisherData\": { \"sourceName\" : \"Foo News\" }" | 449 " \"publisherData\": { \"sourceName\" : \"Foo News\" }" |
| 424 " }]" | 450 " }]" |
| 425 " }" | 451 " }" |
| 426 "}]}"; | 452 "}]}"; |
| 427 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 453 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 428 net::URLRequestStatus::SUCCESS); | 454 net::URLRequestStatus::SUCCESS); |
| 429 EXPECT_CALL(mock_callback(), | 455 EXPECT_CALL(mock_callback(), |
| 430 Run(IsSuccess(), | 456 Run(IsSuccess(), |
| 431 AllOf(IsSingleArticle("http://localhost/foobar"), | 457 AllOf(IsSingleArticle("http://localhost/foobar"), |
| 432 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); | 458 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); |
| 433 snippets_fetcher().FetchSnippets( | 459 fetcher().FetchSnippets(test_params(), |
| 434 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 460 ToSnippetsAvailableCallback(&mock_callback())); |
| 435 FastForwardUntilNoTasksRemain(); | 461 FastForwardUntilNoTasksRemain(); |
| 436 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 462 EXPECT_THAT(fetcher().last_status(), Eq("OK")); |
| 437 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 463 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); |
| 438 EXPECT_THAT(histogram_tester().GetAllSamples( | 464 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 439 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 465 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 440 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 466 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 467 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | |
| 468 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | |
| 469 /*count=*/1))); | |
| 470 } | |
| 471 | |
| 472 TEST_F(RemoteSuggestionsSignedOutFetcherTest, ShouldFetchSuccessfully) { | |
| 473 const std::string kJsonStr = | |
| 474 "{\"categories\" : [{" | |
| 475 " \"id\": 1," | |
| 476 " \"localizedTitle\": \"Articles for You\"," | |
| 477 " \"suggestions\" : [{" | |
| 478 " \"ids\" : [\"http://localhost/foobar\"]," | |
| 479 " \"title\" : \"Foo Barred from Baz\"," | |
| 480 " \"snippet\" : \"...\"," | |
| 481 " \"fullPageUrl\" : \"http://localhost/foobar\"," | |
| 482 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | |
| 483 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | |
| 484 " \"attribution\" : \"Foo News\"," | |
| 485 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," | |
| 486 " \"ampUrl\" : \"http://localhost/amp\"," | |
| 487 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | |
| 488 " }]" | |
| 489 "}]}"; | |
| 490 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | |
| 491 net::URLRequestStatus::SUCCESS); | |
| 492 EXPECT_CALL(mock_callback(), | |
| 493 Run(IsSuccess(), | |
| 494 AllOf(IsSingleArticle("http://localhost/foobar"), | |
| 495 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); | |
| 496 fetcher().FetchSnippets(test_params(), | |
| 497 ToSnippetsAvailableCallback(&mock_callback())); | |
| 498 FastForwardUntilNoTasksRemain(); | |
| 499 EXPECT_THAT(fetcher().last_status(), Eq("OK")); | |
| 500 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); | |
| 501 EXPECT_THAT(histogram_tester().GetAllSamples( | |
| 502 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | |
| 503 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | |
| 504 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | |
| 505 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | |
| 506 /*count=*/1))); | |
| 507 } | |
| 508 | |
| 509 TEST_F(RemoteSuggestionsSignedInFetcherTest, ShouldFetchSuccessfully) { | |
| 510 SignIn(); | |
| 511 IssueRefreshToken(); | |
| 512 | |
| 513 const std::string kJsonStr = | |
| 514 "{\"categories\" : [{" | |
| 515 " \"id\": 1," | |
| 516 " \"localizedTitle\": \"Articles for You\"," | |
| 517 " \"suggestions\" : [{" | |
| 518 " \"ids\" : [\"http://localhost/foobar\"]," | |
| 519 " \"title\" : \"Foo Barred from Baz\"," | |
| 520 " \"snippet\" : \"...\"," | |
| 521 " \"fullPageUrl\" : \"http://localhost/foobar\"," | |
| 522 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | |
| 523 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | |
| 524 " \"attribution\" : \"Foo News\"," | |
| 525 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," | |
| 526 " \"ampUrl\" : \"http://localhost/amp\"," | |
| 527 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | |
| 528 " }]" | |
| 529 "}]}"; | |
| 530 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | |
| 531 net::URLRequestStatus::SUCCESS); | |
| 532 EXPECT_CALL(mock_callback(), | |
| 533 Run(IsSuccess(), | |
| 534 AllOf(IsSingleArticle("http://localhost/foobar"), | |
| 535 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); | |
| 536 | |
| 537 fetcher().FetchSnippets(test_params(), | |
| 538 ToSnippetsAvailableCallback(&mock_callback())); | |
| 539 | |
| 540 IssueOAuth2Token(); | |
| 541 // Wait for the fake response. | |
| 542 FastForwardUntilNoTasksRemain(); | |
| 543 | |
| 544 EXPECT_THAT(fetcher().last_status(), Eq("OK")); | |
| 545 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); | |
| 546 EXPECT_THAT(histogram_tester().GetAllSamples( | |
| 547 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | |
| 548 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | |
| 441 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 549 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 442 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 550 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 443 /*count=*/1))); | 551 /*count=*/1))); |
| 444 } | 552 } |
| 445 | 553 |
| 446 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, ShouldFetchSuccessfully) { | 554 TEST_F(RemoteSuggestionsSignedInFetcherTest, |
| 555 ShouldRetryWhenOAuthCancelled) { | |
| 556 SignIn(); | |
| 557 IssueRefreshToken(); | |
| 558 | |
| 447 const std::string kJsonStr = | 559 const std::string kJsonStr = |
| 448 "{\"categories\" : [{" | 560 "{\"categories\" : [{" |
| 449 " \"id\": 1," | 561 " \"id\": 1," |
| 450 " \"localizedTitle\": \"Articles for You\"," | 562 " \"localizedTitle\": \"Articles for You\"," |
| 451 " \"suggestions\" : [{" | 563 " \"suggestions\" : [{" |
| 452 " \"ids\" : [\"http://localhost/foobar\"]," | 564 " \"ids\" : [\"http://localhost/foobar\"]," |
| 453 " \"title\" : \"Foo Barred from Baz\"," | 565 " \"title\" : \"Foo Barred from Baz\"," |
| 454 " \"snippet\" : \"...\"," | 566 " \"snippet\" : \"...\"," |
| 455 " \"fullPageUrl\" : \"http://localhost/foobar\"," | 567 " \"fullPageUrl\" : \"http://localhost/foobar\"," |
| 456 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | 568 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," |
| 457 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | 569 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," |
| 458 " \"attribution\" : \"Foo News\"," | 570 " \"attribution\" : \"Foo News\"," |
| 459 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," | 571 " \"imageUrl\" : \"http://localhost/foobar.jpg\"," |
| 460 " \"ampUrl\" : \"http://localhost/amp\"," | 572 " \"ampUrl\" : \"http://localhost/amp\"," |
| 461 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | 573 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " |
| 462 " }]" | 574 " }]" |
| 463 "}]}"; | 575 "}]}"; |
| 464 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 576 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 465 net::URLRequestStatus::SUCCESS); | 577 net::URLRequestStatus::SUCCESS); |
| 466 EXPECT_CALL(mock_callback(), | 578 EXPECT_CALL(mock_callback(), |
| 467 Run(IsSuccess(), | 579 Run(IsSuccess(), |
| 468 AllOf(IsSingleArticle("http://localhost/foobar"), | 580 AllOf(IsSingleArticle("http://localhost/foobar"), |
| 469 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); | 581 FirstCategoryHasInfo(IsCategoryInfoForArticles())))); |
| 470 snippets_fetcher().FetchSnippets( | 582 |
| 471 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 583 fetcher().FetchSnippets(test_params(), |
| 584 ToSnippetsAvailableCallback(&mock_callback())); | |
| 585 | |
| 586 CancelOAuth2TokenRequests(); | |
| 587 IssueOAuth2Token(); | |
| 588 // Wait for the fake response. | |
| 472 FastForwardUntilNoTasksRemain(); | 589 FastForwardUntilNoTasksRemain(); |
| 473 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 590 |
| 474 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 591 EXPECT_THAT(fetcher().last_status(), Eq("OK")); |
| 592 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); | |
| 475 EXPECT_THAT(histogram_tester().GetAllSamples( | 593 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 476 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 594 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 477 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 595 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 478 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 596 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 479 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 597 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 480 /*count=*/1))); | 598 /*count=*/1))); |
| 481 } | 599 } |
| 482 | 600 |
| 483 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, EmptyCategoryIsOK) { | 601 TEST_F(RemoteSuggestionsSignedOutFetcherTest, EmptyCategoryIsOK) { |
| 484 const std::string kJsonStr = | 602 const std::string kJsonStr = |
| 485 "{\"categories\" : [{" | 603 "{\"categories\" : [{" |
| 486 " \"id\": 1," | 604 " \"id\": 1," |
| 487 " \"localizedTitle\": \"Articles for You\"" | 605 " \"localizedTitle\": \"Articles for You\"" |
| 488 "}]}"; | 606 "}]}"; |
| 489 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 607 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 490 net::URLRequestStatus::SUCCESS); | 608 net::URLRequestStatus::SUCCESS); |
| 491 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())); | 609 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())); |
| 492 snippets_fetcher().FetchSnippets( | 610 fetcher().FetchSnippets(test_params(), |
| 493 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 611 ToSnippetsAvailableCallback(&mock_callback())); |
| 494 FastForwardUntilNoTasksRemain(); | 612 FastForwardUntilNoTasksRemain(); |
| 495 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 613 EXPECT_THAT(fetcher().last_status(), Eq("OK")); |
| 496 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 614 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); |
| 497 EXPECT_THAT(histogram_tester().GetAllSamples( | 615 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 498 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 616 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 499 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 617 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 500 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 618 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 501 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 619 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 502 /*count=*/1))); | 620 /*count=*/1))); |
| 503 } | 621 } |
| 504 | 622 |
| 505 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, ServerCategories) { | 623 TEST_F(RemoteSuggestionsSignedOutFetcherTest, ServerCategories) { |
| 506 const std::string kJsonStr = | 624 const std::string kJsonStr = |
| 507 "{\"categories\" : [{" | 625 "{\"categories\" : [{" |
| 508 " \"id\": 1," | 626 " \"id\": 1," |
| 509 " \"localizedTitle\": \"Articles for You\"," | 627 " \"localizedTitle\": \"Articles for You\"," |
| 510 " \"suggestions\" : [{" | 628 " \"suggestions\" : [{" |
| 511 " \"ids\" : [\"http://localhost/foobar\"]," | 629 " \"ids\" : [\"http://localhost/foobar\"]," |
| 512 " \"title\" : \"Foo Barred from Baz\"," | 630 " \"title\" : \"Foo Barred from Baz\"," |
| 513 " \"snippet\" : \"...\"," | 631 " \"snippet\" : \"...\"," |
| 514 " \"fullPageUrl\" : \"http://localhost/foobar\"," | 632 " \"fullPageUrl\" : \"http://localhost/foobar\"," |
| 515 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | 633 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 534 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," | 652 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," |
| 535 " \"ampUrl\" : \"http://localhost/amp\"," | 653 " \"ampUrl\" : \"http://localhost/amp\"," |
| 536 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | 654 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " |
| 537 " }]" | 655 " }]" |
| 538 "}]}"; | 656 "}]}"; |
| 539 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 657 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 540 net::URLRequestStatus::SUCCESS); | 658 net::URLRequestStatus::SUCCESS); |
| 541 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; | 659 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; |
| 542 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) | 660 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) |
| 543 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); | 661 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); |
| 544 snippets_fetcher().FetchSnippets( | 662 fetcher().FetchSnippets(test_params(), |
| 545 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 663 ToSnippetsAvailableCallback(&mock_callback())); |
| 546 FastForwardUntilNoTasksRemain(); | 664 FastForwardUntilNoTasksRemain(); |
| 547 | 665 |
| 548 ASSERT_TRUE(fetched_categories); | 666 ASSERT_TRUE(fetched_categories); |
| 549 ASSERT_THAT(fetched_categories->size(), Eq(2u)); | 667 ASSERT_THAT(fetched_categories->size(), Eq(2u)); |
| 550 for (const auto& category : *fetched_categories) { | 668 for (const auto& category : *fetched_categories) { |
| 551 const auto& articles = category.suggestions; | 669 const auto& articles = category.suggestions; |
| 552 if (category.category.IsKnownCategory(KnownCategories::ARTICLES)) { | 670 if (category.category.IsKnownCategory(KnownCategories::ARTICLES)) { |
| 553 ASSERT_THAT(articles.size(), Eq(1u)); | 671 ASSERT_THAT(articles.size(), Eq(1u)); |
| 554 EXPECT_THAT(articles[0]->url().spec(), Eq("http://localhost/foobar")); | 672 EXPECT_THAT(articles[0]->url().spec(), Eq("http://localhost/foobar")); |
| 555 EXPECT_THAT(category.info, IsCategoryInfoForArticles()); | 673 EXPECT_THAT(category.info, IsCategoryInfoForArticles()); |
| 556 } else if (category.category == Category::FromRemoteCategory(2)) { | 674 } else if (category.category == Category::FromRemoteCategory(2)) { |
| 557 ASSERT_THAT(articles.size(), Eq(1u)); | 675 ASSERT_THAT(articles.size(), Eq(1u)); |
| 558 EXPECT_THAT(articles[0]->url().spec(), Eq("http://localhost/foo2")); | 676 EXPECT_THAT(articles[0]->url().spec(), Eq("http://localhost/foo2")); |
| 559 EXPECT_THAT(category.info.has_fetch_action(), Eq(true)); | 677 EXPECT_THAT(category.info.has_fetch_action(), Eq(true)); |
| 560 EXPECT_THAT(category.info.has_view_all_action(), Eq(false)); | 678 EXPECT_THAT(category.info.has_view_all_action(), Eq(false)); |
| 561 EXPECT_THAT(category.info.show_if_empty(), Eq(false)); | 679 EXPECT_THAT(category.info.show_if_empty(), Eq(false)); |
| 562 } else { | 680 } else { |
| 563 FAIL() << "unknown category ID " << category.category.id(); | 681 FAIL() << "unknown category ID " << category.category.id(); |
| 564 } | 682 } |
| 565 } | 683 } |
| 566 | 684 |
| 567 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 685 EXPECT_THAT(fetcher().last_status(), Eq("OK")); |
| 568 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 686 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); |
| 569 EXPECT_THAT(histogram_tester().GetAllSamples( | 687 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 570 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 688 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 571 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 689 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 572 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 690 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 573 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 691 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 574 /*count=*/1))); | 692 /*count=*/1))); |
| 575 } | 693 } |
| 576 | 694 |
| 577 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, | 695 TEST_F(RemoteSuggestionsSignedOutFetcherTest, |
| 578 SupportMissingAllowFetchingMoreResultsOption) { | 696 SupportMissingAllowFetchingMoreResultsOption) { |
| 579 // This tests makes sure we handle the missing option although it's required | 697 // This tests makes sure we handle the missing option although it's required |
| 580 // by the interface. It's just that the Service doesn't follow that | 698 // by the interface. It's just that the Service doesn't follow that |
| 581 // requirement (yet). TODO(tschumann): remove this test once not needed | 699 // requirement (yet). TODO(tschumann): remove this test once not needed |
| 582 // anymore. | 700 // anymore. |
| 583 const std::string kJsonStr = | 701 const std::string kJsonStr = |
| 584 "{\"categories\" : [{" | 702 "{\"categories\" : [{" |
| 585 " \"id\": 2," | 703 " \"id\": 2," |
| 586 " \"localizedTitle\": \"Articles for Me\"," | 704 " \"localizedTitle\": \"Articles for Me\"," |
| 587 " \"suggestions\" : [{" | 705 " \"suggestions\" : [{" |
| 588 " \"ids\" : [\"http://localhost/foo2\"]," | 706 " \"ids\" : [\"http://localhost/foo2\"]," |
| 589 " \"title\" : \"Foo Barred from Baz\"," | 707 " \"title\" : \"Foo Barred from Baz\"," |
| 590 " \"snippet\" : \"...\"," | 708 " \"snippet\" : \"...\"," |
| 591 " \"fullPageUrl\" : \"http://localhost/foo2\"," | 709 " \"fullPageUrl\" : \"http://localhost/foo2\"," |
| 592 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | 710 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," |
| 593 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | 711 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," |
| 594 " \"attribution\" : \"Foo News\"," | 712 " \"attribution\" : \"Foo News\"," |
| 595 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," | 713 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," |
| 596 " \"ampUrl\" : \"http://localhost/amp\"," | 714 " \"ampUrl\" : \"http://localhost/amp\"," |
| 597 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | 715 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " |
| 598 " }]" | 716 " }]" |
| 599 "}]}"; | 717 "}]}"; |
| 600 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 718 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 601 net::URLRequestStatus::SUCCESS); | 719 net::URLRequestStatus::SUCCESS); |
| 602 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; | 720 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; |
| 603 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) | 721 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) |
| 604 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); | 722 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); |
| 605 snippets_fetcher().FetchSnippets( | 723 fetcher().FetchSnippets(test_params(), |
| 606 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 724 ToSnippetsAvailableCallback(&mock_callback())); |
| 607 FastForwardUntilNoTasksRemain(); | 725 FastForwardUntilNoTasksRemain(); |
| 608 | 726 |
| 609 ASSERT_TRUE(fetched_categories); | 727 ASSERT_TRUE(fetched_categories); |
| 610 ASSERT_THAT(fetched_categories->size(), Eq(1u)); | 728 ASSERT_THAT(fetched_categories->size(), Eq(1u)); |
| 611 EXPECT_THAT(fetched_categories->front().info.has_fetch_action(), Eq(false)); | 729 EXPECT_THAT(fetched_categories->front().info.has_fetch_action(), Eq(false)); |
| 612 EXPECT_THAT(fetched_categories->front().info.title(), | 730 EXPECT_THAT(fetched_categories->front().info.title(), |
| 613 Eq(base::UTF8ToUTF16("Articles for Me"))); | 731 Eq(base::UTF8ToUTF16("Articles for Me"))); |
| 614 } | 732 } |
| 615 | 733 |
| 616 TEST_F(NTPSnippetsContentSuggestionsFetcherTest, ExclusiveCategoryOnly) { | 734 TEST_F(RemoteSuggestionsSignedOutFetcherTest, ExclusiveCategoryOnly) { |
| 617 const std::string kJsonStr = | 735 const std::string kJsonStr = |
| 618 "{\"categories\" : [{" | 736 "{\"categories\" : [{" |
| 619 " \"id\": 1," | 737 " \"id\": 1," |
| 620 " \"localizedTitle\": \"Articles for You\"," | 738 " \"localizedTitle\": \"Articles for You\"," |
| 621 " \"suggestions\" : [{" | 739 " \"suggestions\" : [{" |
| 622 " \"ids\" : [\"http://localhost/foobar\"]," | 740 " \"ids\" : [\"http://localhost/foobar\"]," |
| 623 " \"title\" : \"Foo Barred from Baz\"," | 741 " \"title\" : \"Foo Barred from Baz\"," |
| 624 " \"snippet\" : \"...\"," | 742 " \"snippet\" : \"...\"," |
| 625 " \"fullPageUrl\" : \"http://localhost/foobar\"," | 743 " \"fullPageUrl\" : \"http://localhost/foobar\"," |
| 626 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | 744 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 664 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 782 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 665 net::URLRequestStatus::SUCCESS); | 783 net::URLRequestStatus::SUCCESS); |
| 666 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; | 784 RemoteSuggestionsFetcher::OptionalFetchedCategories fetched_categories; |
| 667 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) | 785 EXPECT_CALL(mock_callback(), Run(IsSuccess(), _)) |
| 668 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); | 786 .WillOnce(MoveArgument1PointeeTo(&fetched_categories)); |
| 669 | 787 |
| 670 RequestParams params = test_params(); | 788 RequestParams params = test_params(); |
| 671 params.exclusive_category = | 789 params.exclusive_category = |
| 672 base::Optional<Category>(Category::FromRemoteCategory(2)); | 790 base::Optional<Category>(Category::FromRemoteCategory(2)); |
| 673 | 791 |
| 674 snippets_fetcher().FetchSnippets( | 792 fetcher().FetchSnippets(params, |
| 675 params, ToSnippetsAvailableCallback(&mock_callback())); | 793 ToSnippetsAvailableCallback(&mock_callback())); |
| 676 FastForwardUntilNoTasksRemain(); | 794 FastForwardUntilNoTasksRemain(); |
| 677 | 795 |
| 678 ASSERT_TRUE(fetched_categories); | 796 ASSERT_TRUE(fetched_categories); |
| 679 ASSERT_THAT(fetched_categories->size(), Eq(1u)); | 797 ASSERT_THAT(fetched_categories->size(), Eq(1u)); |
| 680 const auto& category = (*fetched_categories)[0]; | 798 const auto& category = (*fetched_categories)[0]; |
| 681 EXPECT_THAT(category.category.id(), Eq(Category::FromRemoteCategory(2).id())); | 799 EXPECT_THAT(category.category.id(), Eq(Category::FromRemoteCategory(2).id())); |
| 682 ASSERT_THAT(category.suggestions.size(), Eq(1u)); | 800 ASSERT_THAT(category.suggestions.size(), Eq(1u)); |
| 683 EXPECT_THAT(category.suggestions[0]->url().spec(), | 801 EXPECT_THAT(category.suggestions[0]->url().spec(), |
| 684 Eq("http://localhost/foo2")); | 802 Eq("http://localhost/foo2")); |
| 685 } | 803 } |
| 686 | 804 |
| 687 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { | 805 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, |
| 806 ShouldFetchSuccessfullyEmptyList) { | |
| 688 const std::string kJsonStr = "{\"recos\": []}"; | 807 const std::string kJsonStr = "{\"recos\": []}"; |
| 689 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 808 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 690 net::URLRequestStatus::SUCCESS); | 809 net::URLRequestStatus::SUCCESS); |
| 691 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())); | 810 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())); |
| 692 snippets_fetcher().FetchSnippets( | 811 fetcher().FetchSnippets(test_params(), |
| 693 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 812 ToSnippetsAvailableCallback(&mock_callback())); |
| 694 FastForwardUntilNoTasksRemain(); | 813 FastForwardUntilNoTasksRemain(); |
| 695 EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); | 814 EXPECT_THAT(fetcher().last_status(), Eq("OK")); |
| 696 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 815 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); |
| 697 EXPECT_THAT( | 816 EXPECT_THAT( |
| 698 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 817 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 699 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); | 818 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1))); |
| 700 EXPECT_THAT(histogram_tester().GetAllSamples( | 819 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 701 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 820 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 702 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 821 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 703 } | 822 } |
| 704 | 823 |
| 705 TEST_F(ChromeReaderSnippetsFetcherTest, RetryOnInteractiveRequests) { | 824 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, RetryOnInteractiveRequests) { |
| 706 DelegateCallingTestURLFetcherFactory fetcher_factory; | 825 DelegateCallingTestURLFetcherFactory fetcher_factory; |
| 707 RequestParams params = test_params(); | 826 RequestParams params = test_params(); |
| 708 params.interactive_request = true; | 827 params.interactive_request = true; |
| 709 | 828 |
| 710 snippets_fetcher().FetchSnippets( | 829 fetcher().FetchSnippets(params, |
| 711 params, ToSnippetsAvailableCallback(&mock_callback())); | 830 ToSnippetsAvailableCallback(&mock_callback())); |
| 712 | 831 |
| 713 net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher(); | 832 net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher(); |
| 714 ASSERT_THAT(fetcher, NotNull()); | 833 ASSERT_THAT(fetcher, NotNull()); |
| 715 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(2)); | 834 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(2)); |
| 716 } | 835 } |
| 717 | 836 |
| 718 TEST_F(ChromeReaderSnippetsFetcherTest, | 837 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, |
| 719 RetriesConfigurableOnNonInteractiveRequests) { | 838 RetriesConfigurableOnNonInteractiveRequests) { |
| 720 struct ExpectationForVariationParam { | 839 struct ExpectationForVariationParam { |
| 721 std::string param_value; | 840 std::string param_value; |
| 722 int expected_value; | 841 int expected_value; |
| 723 std::string description; | 842 std::string description; |
| 724 }; | 843 }; |
| 725 const std::vector<ExpectationForVariationParam> retry_config_expectation = { | 844 const std::vector<ExpectationForVariationParam> retry_config_expectation = { |
| 726 {"", 0, "Do not retry by default"}, | 845 {"", 0, "Do not retry by default"}, |
| 727 {"0", 0, "Do not retry on param value 0"}, | 846 {"0", 0, "Do not retry on param value 0"}, |
| 728 {"-1", 0, "Do not retry on negative param values."}, | 847 {"-1", 0, "Do not retry on negative param values."}, |
| 729 {"4", 4, "Retry as set in param value."}}; | 848 {"4", 4, "Retry as set in param value."}}; |
| 730 | 849 |
| 731 RequestParams params = test_params(); | 850 RequestParams params = test_params(); |
| 732 params.interactive_request = false; | 851 params.interactive_request = false; |
| 733 | 852 |
| 734 for (const auto& retry_config : retry_config_expectation) { | 853 for (const auto& retry_config : retry_config_expectation) { |
| 735 DelegateCallingTestURLFetcherFactory fetcher_factory; | 854 DelegateCallingTestURLFetcherFactory fetcher_factory; |
| 736 SetVariationParam("background_5xx_retries_count", retry_config.param_value); | 855 SetVariationParam("background_5xx_retries_count", retry_config.param_value); |
| 737 | 856 |
| 738 snippets_fetcher().FetchSnippets( | 857 fetcher().FetchSnippets(params, |
| 739 params, ToSnippetsAvailableCallback(&mock_callback())); | 858 ToSnippetsAvailableCallback(&mock_callback())); |
| 740 | 859 |
| 741 net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher(); | 860 net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher(); |
| 742 ASSERT_THAT(fetcher, NotNull()); | 861 ASSERT_THAT(fetcher, NotNull()); |
| 743 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(retry_config.expected_value)) | 862 EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(retry_config.expected_value)) |
| 744 << retry_config.description; | 863 << retry_config.description; |
| 745 } | 864 } |
| 746 } | 865 } |
| 747 | 866 |
| 748 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldReportUrlStatusError) { | 867 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldReportUrlStatusError) { |
| 749 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 868 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| 750 net::URLRequestStatus::FAILED); | 869 net::URLRequestStatus::FAILED); |
| 751 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 870 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 752 /*snippets=*/Not(HasValue()))) | 871 /*snippets=*/Not(HasValue()))) |
| 753 .Times(1); | 872 .Times(1); |
| 754 snippets_fetcher().FetchSnippets( | 873 fetcher().FetchSnippets(test_params(), |
| 755 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 874 ToSnippetsAvailableCallback(&mock_callback())); |
| 756 FastForwardUntilNoTasksRemain(); | 875 FastForwardUntilNoTasksRemain(); |
| 757 EXPECT_THAT(snippets_fetcher().last_status(), | 876 EXPECT_THAT(fetcher().last_status(), Eq("URLRequestStatus error -2")); |
| 758 Eq("URLRequestStatus error -2")); | 877 EXPECT_THAT(fetcher().last_json(), IsEmpty()); |
| 759 EXPECT_THAT(snippets_fetcher().last_json(), IsEmpty()); | |
| 760 EXPECT_THAT( | 878 EXPECT_THAT( |
| 761 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 879 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 762 ElementsAre(base::Bucket(/*min=*/2, /*count=*/1))); | 880 ElementsAre(base::Bucket(/*min=*/2, /*count=*/1))); |
| 763 EXPECT_THAT(histogram_tester().GetAllSamples( | 881 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 764 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 882 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 765 ElementsAre(base::Bucket(/*min=*/-2, /*count=*/1))); | 883 ElementsAre(base::Bucket(/*min=*/-2, /*count=*/1))); |
| 766 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 884 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 767 Not(IsEmpty())); | 885 Not(IsEmpty())); |
| 768 } | 886 } |
| 769 | 887 |
| 770 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldReportHttpError) { | 888 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldReportHttpError) { |
| 771 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 889 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| 772 net::URLRequestStatus::SUCCESS); | 890 net::URLRequestStatus::SUCCESS); |
| 773 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 891 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 774 /*snippets=*/Not(HasValue()))) | 892 /*snippets=*/Not(HasValue()))) |
| 775 .Times(1); | 893 .Times(1); |
| 776 snippets_fetcher().FetchSnippets( | 894 fetcher().FetchSnippets(test_params(), |
| 777 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 895 ToSnippetsAvailableCallback(&mock_callback())); |
| 778 FastForwardUntilNoTasksRemain(); | 896 FastForwardUntilNoTasksRemain(); |
| 779 EXPECT_THAT(snippets_fetcher().last_json(), IsEmpty()); | 897 EXPECT_THAT(fetcher().last_json(), IsEmpty()); |
| 780 EXPECT_THAT( | 898 EXPECT_THAT( |
| 781 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 899 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 782 ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); | 900 ElementsAre(base::Bucket(/*min=*/3, /*count=*/1))); |
| 783 EXPECT_THAT(histogram_tester().GetAllSamples( | 901 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 784 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 902 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 785 ElementsAre(base::Bucket(/*min=*/404, /*count=*/1))); | 903 ElementsAre(base::Bucket(/*min=*/404, /*count=*/1))); |
| 786 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 904 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 787 Not(IsEmpty())); | 905 Not(IsEmpty())); |
| 788 } | 906 } |
| 789 | 907 |
| 790 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldReportJsonError) { | 908 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldReportJsonError) { |
| 791 const std::string kInvalidJsonStr = "{ \"recos\": []"; | 909 const std::string kInvalidJsonStr = "{ \"recos\": []"; |
| 792 SetFakeResponse(/*response_data=*/kInvalidJsonStr, net::HTTP_OK, | 910 SetFakeResponse(/*response_data=*/kInvalidJsonStr, net::HTTP_OK, |
| 793 net::URLRequestStatus::SUCCESS); | 911 net::URLRequestStatus::SUCCESS); |
| 794 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 912 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 795 /*snippets=*/Not(HasValue()))) | 913 /*snippets=*/Not(HasValue()))) |
| 796 .Times(1); | 914 .Times(1); |
| 797 snippets_fetcher().FetchSnippets( | 915 fetcher().FetchSnippets(test_params(), |
| 798 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 916 ToSnippetsAvailableCallback(&mock_callback())); |
| 799 FastForwardUntilNoTasksRemain(); | 917 FastForwardUntilNoTasksRemain(); |
| 800 EXPECT_THAT(snippets_fetcher().last_status(), | 918 EXPECT_THAT(fetcher().last_status(), |
| 801 StartsWith("Received invalid JSON (error ")); | 919 StartsWith("Received invalid JSON (error ")); |
| 802 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kInvalidJsonStr)); | 920 EXPECT_THAT(fetcher().last_json(), Eq(kInvalidJsonStr)); |
| 803 EXPECT_THAT( | 921 EXPECT_THAT( |
| 804 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 922 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 805 ElementsAre(base::Bucket(/*min=*/4, /*count=*/1))); | 923 ElementsAre(base::Bucket(/*min=*/4, /*count=*/1))); |
| 806 EXPECT_THAT(histogram_tester().GetAllSamples( | 924 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 807 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 925 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 808 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 926 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 809 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 927 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 810 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 928 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 811 /*count=*/1))); | 929 /*count=*/1))); |
| 812 } | 930 } |
| 813 | 931 |
| 814 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldReportJsonErrorForEmptyResponse) { | 932 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, |
| 933 ShouldReportJsonErrorForEmptyResponse) { | |
| 815 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_OK, | 934 SetFakeResponse(/*response_data=*/std::string(), net::HTTP_OK, |
| 816 net::URLRequestStatus::SUCCESS); | 935 net::URLRequestStatus::SUCCESS); |
| 817 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 936 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 818 /*snippets=*/Not(HasValue()))) | 937 /*snippets=*/Not(HasValue()))) |
| 819 .Times(1); | 938 .Times(1); |
| 820 snippets_fetcher().FetchSnippets( | 939 fetcher().FetchSnippets(test_params(), |
| 821 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 940 ToSnippetsAvailableCallback(&mock_callback())); |
| 822 FastForwardUntilNoTasksRemain(); | 941 FastForwardUntilNoTasksRemain(); |
| 823 EXPECT_THAT(snippets_fetcher().last_json(), std::string()); | 942 EXPECT_THAT(fetcher().last_json(), std::string()); |
| 824 EXPECT_THAT( | 943 EXPECT_THAT( |
| 825 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 944 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 826 ElementsAre(base::Bucket(/*min=*/4, /*count=*/1))); | 945 ElementsAre(base::Bucket(/*min=*/4, /*count=*/1))); |
| 827 EXPECT_THAT(histogram_tester().GetAllSamples( | 946 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 828 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 947 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 829 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 948 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 830 } | 949 } |
| 831 | 950 |
| 832 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldReportInvalidListError) { | 951 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, ShouldReportInvalidListError) { |
| 833 const std::string kJsonStr = | 952 const std::string kJsonStr = |
| 834 "{\"recos\": [{ \"contentInfo\": { \"foo\" : \"bar\" }}]}"; | 953 "{\"recos\": [{ \"contentInfo\": { \"foo\" : \"bar\" }}]}"; |
| 835 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 954 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 836 net::URLRequestStatus::SUCCESS); | 955 net::URLRequestStatus::SUCCESS); |
| 837 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 956 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 838 /*snippets=*/Not(HasValue()))) | 957 /*snippets=*/Not(HasValue()))) |
| 839 .Times(1); | 958 .Times(1); |
| 840 snippets_fetcher().FetchSnippets( | 959 fetcher().FetchSnippets(test_params(), |
| 841 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 960 ToSnippetsAvailableCallback(&mock_callback())); |
| 842 FastForwardUntilNoTasksRemain(); | 961 FastForwardUntilNoTasksRemain(); |
| 843 EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); | 962 EXPECT_THAT(fetcher().last_json(), Eq(kJsonStr)); |
| 844 EXPECT_THAT( | 963 EXPECT_THAT( |
| 845 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 964 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 846 ElementsAre(base::Bucket(/*min=*/5, /*count=*/1))); | 965 ElementsAre(base::Bucket(/*min=*/5, /*count=*/1))); |
| 847 EXPECT_THAT(histogram_tester().GetAllSamples( | 966 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 848 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 967 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 849 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 968 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 850 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 969 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 851 Not(IsEmpty())); | 970 Not(IsEmpty())); |
| 852 } | 971 } |
| 853 | 972 |
| 854 // This test actually verifies that the test setup itself is sane, to prevent | 973 // This test actually verifies that the test setup itself is sane, to prevent |
| 855 // hard-to-reproduce test failures. | 974 // hard-to-reproduce test failures. |
| 856 TEST_F(ChromeReaderSnippetsFetcherTest, | 975 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, |
| 857 ShouldReportHttpErrorForMissingBakedResponse) { | 976 ShouldReportHttpErrorForMissingBakedResponse) { |
| 858 InitFakeURLFetcherFactory(); | 977 InitFakeURLFetcherFactory(); |
| 859 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), | 978 EXPECT_CALL(mock_callback(), Run(HasCode(StatusCode::TEMPORARY_ERROR), |
| 860 /*snippets=*/Not(HasValue()))) | 979 /*snippets=*/Not(HasValue()))) |
| 861 .Times(1); | 980 .Times(1); |
| 862 snippets_fetcher().FetchSnippets( | 981 fetcher().FetchSnippets(test_params(), |
| 863 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 982 ToSnippetsAvailableCallback(&mock_callback())); |
| 864 FastForwardUntilNoTasksRemain(); | 983 FastForwardUntilNoTasksRemain(); |
| 865 } | 984 } |
| 866 | 985 |
| 867 TEST_F(ChromeReaderSnippetsFetcherTest, ShouldProcessConcurrentFetches) { | 986 TEST_F(RemoteSuggestionsChromeReaderFetcherTest, |
| 987 ShouldProcessConcurrentFetches) { | |
| 868 const std::string kJsonStr = "{ \"recos\": [] }"; | 988 const std::string kJsonStr = "{ \"recos\": [] }"; |
| 869 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 989 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 870 net::URLRequestStatus::SUCCESS); | 990 net::URLRequestStatus::SUCCESS); |
| 871 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())).Times(5); | 991 EXPECT_CALL(mock_callback(), Run(IsSuccess(), IsEmptyArticleList())).Times(5); |
| 872 snippets_fetcher().FetchSnippets( | 992 fetcher().FetchSnippets(test_params(), |
| 873 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 993 ToSnippetsAvailableCallback(&mock_callback())); |
| 874 // More calls to FetchSnippets() do not interrupt the previous. | 994 // More calls to FetchSnippets() do not interrupt the previous. |
| 875 // Callback is expected to be called once each time. | 995 // Callback is expected to be called once each time. |
| 876 snippets_fetcher().FetchSnippets( | 996 fetcher().FetchSnippets(test_params(), |
| 877 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 997 ToSnippetsAvailableCallback(&mock_callback())); |
| 878 snippets_fetcher().FetchSnippets( | 998 fetcher().FetchSnippets(test_params(), |
| 879 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 999 ToSnippetsAvailableCallback(&mock_callback())); |
| 880 snippets_fetcher().FetchSnippets( | 1000 fetcher().FetchSnippets(test_params(), |
| 881 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 1001 ToSnippetsAvailableCallback(&mock_callback())); |
| 882 snippets_fetcher().FetchSnippets( | 1002 fetcher().FetchSnippets(test_params(), |
| 883 test_params(), ToSnippetsAvailableCallback(&mock_callback())); | 1003 ToSnippetsAvailableCallback(&mock_callback())); |
| 884 FastForwardUntilNoTasksRemain(); | 1004 FastForwardUntilNoTasksRemain(); |
| 885 EXPECT_THAT( | 1005 EXPECT_THAT( |
| 886 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), | 1006 histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchResult"), |
| 887 ElementsAre(base::Bucket(/*min=*/0, /*count=*/5))); | 1007 ElementsAre(base::Bucket(/*min=*/0, /*count=*/5))); |
| 888 EXPECT_THAT(histogram_tester().GetAllSamples( | 1008 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 889 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 1009 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 890 ElementsAre(base::Bucket(/*min=*/200, /*count=*/5))); | 1010 ElementsAre(base::Bucket(/*min=*/200, /*count=*/5))); |
| 891 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 1011 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 892 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 1012 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 893 /*count=*/5))); | 1013 /*count=*/5))); |
| 894 } | 1014 } |
| 895 | 1015 |
| 896 ::std::ostream& operator<<( | 1016 ::std::ostream& operator<<( |
| 897 ::std::ostream& os, | 1017 ::std::ostream& os, |
| 898 const RemoteSuggestionsFetcher::OptionalFetchedCategories& | 1018 const RemoteSuggestionsFetcher::OptionalFetchedCategories& |
| 899 fetched_categories) { | 1019 fetched_categories) { |
| 900 if (fetched_categories) { | 1020 if (fetched_categories) { |
| 901 // Matchers above aren't any more precise than this, so this is sufficient | 1021 // Matchers above aren't any more precise than this, so this is sufficient |
| 902 // for test-failure diagnostics. | 1022 // for test-failure diagnostics. |
| 903 return os << "list with " << fetched_categories->size() << " elements"; | 1023 return os << "list with " << fetched_categories->size() << " elements"; |
| 904 } | 1024 } |
| 905 return os << "null"; | 1025 return os << "null"; |
| 906 } | 1026 } |
| 907 | 1027 |
| 908 } // namespace ntp_snippets | 1028 } // namespace ntp_snippets |
| OLD | NEW |