Chromium Code Reviews| Index: components/ntp_snippets/remote/ntp_snippets_json_request_unittest.cc |
| diff --git a/components/ntp_snippets/remote/ntp_snippets_json_request_unittest.cc b/components/ntp_snippets/remote/ntp_snippets_json_request_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2e617a147af667dcb27a25e68fa61d27e0380bad |
| --- /dev/null |
| +++ b/components/ntp_snippets/remote/ntp_snippets_json_request_unittest.cc |
| @@ -0,0 +1,335 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/ntp_snippets/remote/ntp_snippets_json_request.h" |
| + |
| +#include <set> |
| +#include <utility> |
| + |
| +#include "base/json/json_reader.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "base/test/test_mock_time_task_runner.h" |
| +#include "base/time/tick_clock.h" |
| +#include "base/time/time.h" |
| +#include "base/values.h" |
| +#include "components/ntp_snippets/features.h" |
| +#include "components/ntp_snippets/ntp_snippets_constants.h" |
| +#include "components/ntp_snippets/remote/ntp_snippets_request_params.h" |
| +#include "components/prefs/testing_pref_service.h" |
| +#include "components/variations/variations_params_manager.h" |
| +#include "net/url_request/test_url_fetcher_factory.h" |
| +#include "net/url_request/url_request_test_util.h" |
| +#include "testing/gmock/include/gmock/gmock.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace ntp_snippets { |
| + |
| +namespace internal { |
| + |
| +namespace { |
| + |
| +using testing::_; |
| +using testing::Eq; |
| +using testing::Not; |
| +using testing::NotNull; |
| +using testing::StrEq; |
| + |
| +MATCHER_P(EqualsJSON, json, "equals JSON") { |
| + std::unique_ptr<base::Value> expected = base::JSONReader::Read(json); |
| + if (!expected) { |
| + *result_listener << "INTERNAL ERROR: couldn't parse expected JSON"; |
| + return false; |
| + } |
| + |
| + std::string err_msg; |
| + int err_line, err_col; |
| + std::unique_ptr<base::Value> actual = base::JSONReader::ReadAndReturnError( |
| + arg, base::JSON_PARSE_RFC, nullptr, &err_msg, &err_line, &err_col); |
| + if (!actual) { |
| + *result_listener << "input:" << err_line << ":" << err_col << ": " |
| + << "parse error: " << err_msg; |
| + return false; |
| + } |
| + return base::Value::Equals(actual.get(), expected.get()); |
| +} |
| + |
| +} // namespace |
| + |
| +class NTPSnippetsJsonRequestTest : public testing::Test { |
| + public: |
| + NTPSnippetsJsonRequestTest() |
| + : params_manager_( |
| + ntp_snippets::kStudyName, |
| + {{"send_top_languages", "true"}, {"send_user_class", "true"}}, |
| + {ntp_snippets::kArticleSuggestionsFeature.name}), |
| + pref_service_(base::MakeUnique<TestingPrefServiceSimple>()), |
| + mock_task_runner_(new base::TestMockTimeTaskRunner()), |
| + tick_clock_(mock_task_runner_->GetMockTickClock()), |
| + request_context_getter_( |
| + new net::TestURLRequestContextGetter(mock_task_runner_.get())) { |
| + translate::LanguageModel::RegisterProfilePrefs(pref_service_->registry()); |
| + } |
| + |
| + std::unique_ptr<translate::LanguageModel> MakeLanguageModel( |
| + const std::set<std::string>& codes) { |
| + std::unique_ptr<translate::LanguageModel> language_model = |
| + base::MakeUnique<translate::LanguageModel>(pref_service_.get()); |
| + // There must be at least 10 visits before the top languages are defined. |
| + for (int i = 0; i < 10; i++) { |
| + for (const auto& code : codes) { |
|
Bernhard Bauer
2016/12/20 10:49:35
Use the real type instead of auto?
fhorschig
2016/12/20 12:11:37
Done.
|
| + language_model->OnPageVisited(code); |
| + } |
| + } |
| + return language_model; |
| + } |
| + |
| + NTPSnippetsJsonRequest::Builder CreateMinimalBuilder() { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + builder.SetUrl(GURL("http://valid-url.test")) |
| + .SetTickClock(tick_clock_.get()) |
| + .SetUrlRequestContextGetter(request_context_getter_.get()); |
| + return builder; |
| + } |
| + |
| + private: |
| + variations::testing::VariationParamsManager params_manager_; |
| + std::unique_ptr<TestingPrefServiceSimple> pref_service_; |
| + scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; |
| + std::unique_ptr<base::TickClock> tick_clock_; |
| + scoped_refptr<net::TestURLRequestContextGetter> request_context_getter_; |
| + net::TestURLFetcherFactory fetcher_factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(NTPSnippetsJsonRequestTest); |
| +}; |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestAuthenticated) { |
| + NTPSnippetsJsonRequest::Builder builder = CreateMinimalBuilder(); |
| + NTPSnippetsRequestParams params; |
| + params.excluded_ids = {"1234567890"}; |
| + params.count_to_fetch = 25; |
| + params.interactive_request = false; |
| + builder.SetParams(params) |
| + .SetUrl(GURL("http://valid-url.test")) |
| + .SetUrl(GURL("http://valid-url.test")) |
| + .SetAuthentication("0BFUSGAIA", "headerstuff") |
| + .SetPersonalization(Personalization::kPersonal) |
| + .SetUserClassForTesting("ACTIVE_NTP_USER") |
| + .SetFetchAPI(FetchAPI::CHROME_READER_API) |
| + .Build(); |
| + |
| + EXPECT_THAT(builder.PreviewRequestHeadersForTesting(), |
| + StrEq("Content-Type: application/json; charset=UTF-8\r\n" |
| + "Authorization: headerstuff\r\n" |
| + "\r\n")); |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"response_detail_level\": \"STANDARD\"," |
| + " \"obfuscated_gaia_id\": \"0BFUSGAIA\"," |
| + " \"advanced_options\": {" |
| + " \"local_scoring_params\": {" |
| + " \"content_params\": {" |
| + " \"only_return_personalized_results\": true" |
| + " }," |
| + " \"content_restricts\": [" |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"TITLE\"" |
| + " }," |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"SNIPPET\"" |
| + " }," |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"THUMBNAIL\"" |
| + " }" |
| + " ]" |
| + " }," |
| + " \"global_scoring_params\": {" |
| + " \"num_to_return\": 25," |
| + " \"sort_type\": 1" |
| + " }" |
| + " }" |
| + "}")); |
| + |
| + builder.SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"BACKGROUND_PREFETCH\"," |
| + " \"excludedSuggestionIds\": [" |
| + " \"1234567890\"" |
| + " ]," |
| + " \"userActivenessClass\": \"ACTIVE_NTP_USER\"" |
| + "}")); |
| +} |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestUnauthenticated) { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + NTPSnippetsRequestParams params; |
| + params.interactive_request = true; |
| + params.count_to_fetch = 10; |
| + builder.SetParams(params) |
| + .SetUserClassForTesting("ACTIVE_NTP_USER") |
| + .SetPersonalization(Personalization::kNonPersonal) |
| + .SetFetchAPI(FetchAPI::CHROME_READER_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestHeadersForTesting(), |
| + StrEq("Content-Type: application/json; charset=UTF-8\r\n" |
| + "\r\n")); |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"response_detail_level\": \"STANDARD\"," |
| + " \"advanced_options\": {" |
| + " \"local_scoring_params\": {" |
| + " \"content_params\": {" |
| + " \"only_return_personalized_results\": false" |
| + " }," |
| + " \"content_restricts\": [" |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"TITLE\"" |
| + " }," |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"SNIPPET\"" |
| + " }," |
| + " {" |
| + " \"type\": \"METADATA\"," |
| + " \"value\": \"THUMBNAIL\"" |
| + " }" |
| + " ]" |
| + " }," |
| + " \"global_scoring_params\": {" |
| + " \"num_to_return\": 10," |
| + " \"sort_type\": 1" |
| + " }" |
| + " }" |
| + "}")); |
| + |
| + builder.SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"USER_ACTION\"," |
| + " \"excludedSuggestionIds\": []," |
| + " \"userActivenessClass\": \"ACTIVE_NTP_USER\"" |
| + "}")); |
| +} |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestExcludedIds) { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + NTPSnippetsRequestParams params; |
| + params.interactive_request = false; |
| + for (int i = 0; i < 200; ++i) { |
| + params.excluded_ids.insert(base::StringPrintf("%03d", i)); |
| + } |
| + builder.SetParams(params) |
| + .SetUserClassForTesting("ACTIVE_NTP_USER") |
| + .SetPersonalization(Personalization::kNonPersonal) |
| + .SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"BACKGROUND_PREFETCH\"," |
| + " \"excludedSuggestionIds\": [" |
| + " \"000\", \"001\", \"002\", \"003\", \"004\"," |
| + " \"005\", \"006\", \"007\", \"008\", \"009\"," |
| + " \"010\", \"011\", \"012\", \"013\", \"014\"," |
| + " \"015\", \"016\", \"017\", \"018\", \"019\"," |
| + " \"020\", \"021\", \"022\", \"023\", \"024\"," |
| + " \"025\", \"026\", \"027\", \"028\", \"029\"," |
| + " \"030\", \"031\", \"032\", \"033\", \"034\"," |
| + " \"035\", \"036\", \"037\", \"038\", \"039\"," |
| + " \"040\", \"041\", \"042\", \"043\", \"044\"," |
| + " \"045\", \"046\", \"047\", \"048\", \"049\"," |
| + " \"050\", \"051\", \"052\", \"053\", \"054\"," |
| + " \"055\", \"056\", \"057\", \"058\", \"059\"," |
| + " \"060\", \"061\", \"062\", \"063\", \"064\"," |
| + " \"065\", \"066\", \"067\", \"068\", \"069\"," |
| + " \"070\", \"071\", \"072\", \"073\", \"074\"," |
| + " \"075\", \"076\", \"077\", \"078\", \"079\"," |
| + " \"080\", \"081\", \"082\", \"083\", \"084\"," |
| + " \"085\", \"086\", \"087\", \"088\", \"089\"," |
| + " \"090\", \"091\", \"092\", \"093\", \"094\"," |
| + " \"095\", \"096\", \"097\", \"098\", \"099\"" |
| + // Truncated to 100 entries. Currently, they happen to |
| + // be those lexically first. |
| + " ]," |
| + " \"userActivenessClass\": \"ACTIVE_NTP_USER\"" |
| + "}")); |
| +} |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestNoUserClass) { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + NTPSnippetsRequestParams params; |
| + params.interactive_request = false; |
| + builder.SetPersonalization(Personalization::kNonPersonal) |
| + .SetParams(params) |
| + .SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"BACKGROUND_PREFETCH\"," |
| + " \"excludedSuggestionIds\": []" |
| + "}")); |
| +} |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestWithTwoLanguages) { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + std::unique_ptr<translate::LanguageModel> language_model = |
| + MakeLanguageModel({"de", "en"}); |
| + NTPSnippetsRequestParams params; |
| + params.interactive_request = true; |
| + params.language_code = "en"; |
| + builder.SetParams(params) |
| + .SetLanguageModel(language_model.get()) |
| + .SetPersonalization(Personalization::kNonPersonal) |
| + .SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"USER_ACTION\"," |
| + " \"uiLanguage\": \"en\"," |
| + " \"excludedSuggestionIds\": []," |
| + " \"topLanguages\": [" |
| + " {" |
| + " \"language\" : \"en\"," |
| + " \"frequency\" : 0.5" |
| + " }," |
| + " {" |
| + " \"language\" : \"de\"," |
| + " \"frequency\" : 0.5" |
| + " }" |
| + " ]" |
| + "}")); |
| +} |
| + |
| +TEST_F(NTPSnippetsJsonRequestTest, BuildRequestWithUILanguageOnly) { |
| + NTPSnippetsJsonRequest::Builder builder; |
| + std::unique_ptr<translate::LanguageModel> language_model = |
| + MakeLanguageModel({"en"}); |
| + NTPSnippetsRequestParams params; |
| + params.interactive_request = true; |
| + params.language_code = "en"; |
| + builder.SetParams(params) |
| + .SetLanguageModel(language_model.get()) |
| + .SetPersonalization(Personalization::kNonPersonal) |
| + .SetFetchAPI(FetchAPI::CHROME_CONTENT_SUGGESTIONS_API); |
| + |
| + EXPECT_THAT(builder.PreviewRequestBodyForTesting(), |
| + EqualsJSON("{" |
| + " \"priority\": \"USER_ACTION\"," |
| + " \"uiLanguage\": \"en\"," |
| + " \"excludedSuggestionIds\": []," |
| + " \"topLanguages\": [{" |
| + " \"language\" : \"en\"," |
| + " \"frequency\" : 1.0" |
| + " }]" |
| + "}")); |
| +} |
| + |
| +} // namespace internal |
| + |
| +} // namespace ntp_snippets |