| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" | 5 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 56 |
| 57 ACTION_P(MovePointeeTo, ptr) { | 57 ACTION_P(MovePointeeTo, ptr) { |
| 58 *ptr = std::move(*arg0); | 58 *ptr = std::move(*arg0); |
| 59 } | 59 } |
| 60 | 60 |
| 61 MATCHER(HasValue, "") { | 61 MATCHER(HasValue, "") { |
| 62 return static_cast<bool>(*arg); | 62 return static_cast<bool>(*arg); |
| 63 } | 63 } |
| 64 | 64 |
| 65 MATCHER(IsEmptyArticleList, "is an empty list of articles") { | 65 MATCHER(IsEmptyArticleList, "is an empty list of articles") { |
| 66 NTPSnippetsFetcher::OptionalSnippets& snippets = *arg; | 66 NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories = *arg; |
| 67 return snippets && snippets->size() == 1 && | 67 return fetched_categories && fetched_categories->size() == 1 && |
| 68 snippets->begin()->snippets.empty(); | 68 fetched_categories->begin()->snippets.empty(); |
| 69 } | 69 } |
| 70 | 70 |
| 71 MATCHER_P(IsSingleArticle, url, "is a list with the single article %(url)s") { | 71 MATCHER_P(IsSingleArticle, url, "is a list with the single article %(url)s") { |
| 72 NTPSnippetsFetcher::OptionalSnippets& snippets = *arg; | 72 NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories = *arg; |
| 73 return snippets && snippets->size() == 1 && | 73 return fetched_categories && fetched_categories->size() == 1 && |
| 74 snippets->begin()->snippets.size() == 1 && | 74 fetched_categories->begin()->snippets.size() == 1 && |
| 75 snippets->begin()->snippets[0]->best_source().url.spec() == url; | 75 fetched_categories->begin()->snippets[0]->best_source().url.spec() == |
| 76 url; |
| 76 } | 77 } |
| 77 | 78 |
| 78 MATCHER_P(EqualsJSON, json, "equals JSON") { | 79 MATCHER_P(EqualsJSON, json, "equals JSON") { |
| 79 std::unique_ptr<base::Value> expected = base::JSONReader::Read(json); | 80 std::unique_ptr<base::Value> expected = base::JSONReader::Read(json); |
| 80 if (!expected) { | 81 if (!expected) { |
| 81 *result_listener << "INTERNAL ERROR: couldn't parse expected JSON"; | 82 *result_listener << "INTERNAL ERROR: couldn't parse expected JSON"; |
| 82 return false; | 83 return false; |
| 83 } | 84 } |
| 84 | 85 |
| 85 std::string err_msg; | 86 std::string err_msg; |
| 86 int err_line, err_col; | 87 int err_line, err_col; |
| 87 std::unique_ptr<base::Value> actual = base::JSONReader::ReadAndReturnError( | 88 std::unique_ptr<base::Value> actual = base::JSONReader::ReadAndReturnError( |
| 88 arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col); | 89 arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col); |
| 89 if (!actual) { | 90 if (!actual) { |
| 90 *result_listener << "input:" << err_line << ":" << err_col << ": " | 91 *result_listener << "input:" << err_line << ":" << err_col << ": " |
| 91 << "parse error: " << err_msg; | 92 << "parse error: " << err_msg; |
| 92 return false; | 93 return false; |
| 93 } | 94 } |
| 94 return base::Value::Equals(actual.get(), expected.get()); | 95 return base::Value::Equals(actual.get(), expected.get()); |
| 95 } | 96 } |
| 96 | 97 |
| 97 class MockSnippetsAvailableCallback { | 98 class MockSnippetsAvailableCallback { |
| 98 public: | 99 public: |
| 99 // Workaround for gMock's lack of support for movable arguments. | 100 // Workaround for gMock's lack of support for movable arguments. |
| 100 void WrappedRun(NTPSnippetsFetcher::OptionalSnippets snippets) { | 101 void WrappedRun( |
| 101 Run(&snippets); | 102 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories) { |
| 103 Run(&fetched_categories); |
| 102 } | 104 } |
| 103 | 105 |
| 104 MOCK_METHOD1(Run, void(NTPSnippetsFetcher::OptionalSnippets* snippets)); | 106 MOCK_METHOD1( |
| 107 Run, |
| 108 void(NTPSnippetsFetcher::OptionalFetchedCategories* fetched_categories)); |
| 105 }; | 109 }; |
| 106 | 110 |
| 107 // Factory for FakeURLFetcher objects that always generate errors. | 111 // Factory for FakeURLFetcher objects that always generate errors. |
| 108 class FailingFakeURLFetcherFactory : public net::URLFetcherFactory { | 112 class FailingFakeURLFetcherFactory : public net::URLFetcherFactory { |
| 109 public: | 113 public: |
| 110 std::unique_ptr<net::URLFetcher> CreateURLFetcher( | 114 std::unique_ptr<net::URLFetcher> CreateURLFetcher( |
| 111 int id, const GURL& url, net::URLFetcher::RequestType request_type, | 115 int id, const GURL& url, net::URLFetcher::RequestType request_type, |
| 112 net::URLFetcherDelegate* d) override { | 116 net::URLFetcherDelegate* d) override { |
| 113 return base::MakeUnique<net::FakeURLFetcher>( | 117 return base::MakeUnique<net::FakeURLFetcher>( |
| 114 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 118 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," | 525 " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," |
| 522 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," | 526 " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," |
| 523 " \"attribution\" : \"Foo News\"," | 527 " \"attribution\" : \"Foo News\"," |
| 524 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," | 528 " \"imageUrl\" : \"http://localhost/foo2.jpg\"," |
| 525 " \"ampUrl\" : \"http://localhost/amp\"," | 529 " \"ampUrl\" : \"http://localhost/amp\"," |
| 526 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " | 530 " \"faviconUrl\" : \"http://localhost/favicon.ico\" " |
| 527 " }]" | 531 " }]" |
| 528 "}]}"; | 532 "}]}"; |
| 529 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, | 533 SetFakeResponse(/*response_data=*/kJsonStr, net::HTTP_OK, |
| 530 net::URLRequestStatus::SUCCESS); | 534 net::URLRequestStatus::SUCCESS); |
| 531 NTPSnippetsFetcher::OptionalSnippets snippets; | 535 NTPSnippetsFetcher::OptionalFetchedCategories fetched_categories; |
| 532 EXPECT_CALL(mock_callback(), Run(_)) | 536 EXPECT_CALL(mock_callback(), Run(_)) |
| 533 .WillOnce(WithArg<0>(MovePointeeTo(&snippets))); | 537 .WillOnce(WithArg<0>(MovePointeeTo(&fetched_categories))); |
| 534 snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), | 538 snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), |
| 535 test_excluded(), | 539 test_excluded(), |
| 536 /*count=*/1, | 540 /*count=*/1, |
| 537 /*interactive_request=*/true); | 541 /*interactive_request=*/true); |
| 538 FastForwardUntilNoTasksRemain(); | 542 FastForwardUntilNoTasksRemain(); |
| 539 | 543 |
| 540 ASSERT_TRUE(snippets); | 544 ASSERT_TRUE(fetched_categories); |
| 541 ASSERT_THAT(snippets->size(), Eq(2u)); | 545 ASSERT_THAT(fetched_categories->size(), Eq(2u)); |
| 542 for (const auto& category : *snippets) { | 546 for (const auto& category : *fetched_categories) { |
| 543 const auto& articles = category.snippets; | 547 const auto& articles = category.snippets; |
| 544 switch (category.category.id()) { | 548 switch (category.category.id()) { |
| 545 case static_cast<int>(KnownCategories::ARTICLES): | 549 case static_cast<int>(KnownCategories::ARTICLES): |
| 546 ASSERT_THAT(articles.size(), Eq(1u)); | 550 ASSERT_THAT(articles.size(), Eq(1u)); |
| 547 EXPECT_THAT(articles[0]->best_source().url.spec(), | 551 EXPECT_THAT(articles[0]->best_source().url.spec(), |
| 548 Eq("http://localhost/foobar")); | 552 Eq("http://localhost/foobar")); |
| 549 break; | 553 break; |
| 550 case static_cast<int>(KnownCategories::ARTICLES) + 1: | 554 case static_cast<int>(KnownCategories::ARTICLES) + 1: |
| 551 ASSERT_THAT(articles.size(), Eq(1u)); | 555 ASSERT_THAT(articles.size(), Eq(1u)); |
| 552 EXPECT_THAT(articles[0]->best_source().url.spec(), | 556 EXPECT_THAT(articles[0]->best_source().url.spec(), |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 EXPECT_THAT(histogram_tester().GetAllSamples( | 762 EXPECT_THAT(histogram_tester().GetAllSamples( |
| 759 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), | 763 "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), |
| 760 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); | 764 ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); |
| 761 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), | 765 EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), |
| 762 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, | 766 ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, |
| 763 /*count=*/1))); | 767 /*count=*/1))); |
| 764 } | 768 } |
| 765 | 769 |
| 766 ::std::ostream& operator<<( | 770 ::std::ostream& operator<<( |
| 767 ::std::ostream& os, | 771 ::std::ostream& os, |
| 768 const NTPSnippetsFetcher::OptionalSnippets& snippets) { | 772 const NTPSnippetsFetcher::OptionalFetchedCategories& fetched_categories) { |
| 769 if (snippets) { | 773 if (fetched_categories) { |
| 770 // Matchers above aren't any more precise than this, so this is sufficient | 774 // Matchers above aren't any more precise than this, so this is sufficient |
| 771 // for test-failure diagnostics. | 775 // for test-failure diagnostics. |
| 772 return os << "list with " << snippets->size() << " elements"; | 776 return os << "list with " << fetched_categories->size() << " elements"; |
| 773 } | 777 } |
| 774 return os << "null"; | 778 return os << "null"; |
| 775 } | 779 } |
| 776 | 780 |
| 777 } // namespace ntp_snippets | 781 } // namespace ntp_snippets |
| OLD | NEW |