Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: components/ntp_snippets/remote/remote_suggestions_fetcher_unittest.cc

Issue 2672253003: [Remote fetcher] Add unit-tests for the authenticated case (Closed)
Patch Set: Marc's comments and a bit of renaming Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698