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

Side by Side Diff: components/ntp_tiles/popular_sites_unittest.cc

Issue 2471133004: Add PopularSites test. (Closed)
Patch Set: Add test deps. Created 4 years, 1 month 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 | « components/ntp_tiles/BUILD.gn ('k') | 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/ntp_tiles/popular_sites.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/json/json_parser.h"
14 #include "base/json/json_writer.h"
15 #include "base/run_loop.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/test/sequenced_worker_pool_owner.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/values.h"
20 #include "components/ntp_tiles/pref_names.h"
21 #include "components/pref_registry/pref_registry_syncable.h"
22 #include "components/pref_registry/testing_pref_service_syncable.h"
23 #include "net/http/http_status_code.h"
24 #include "net/url_request/test_url_fetcher_factory.h"
25 #include "net/url_request/url_request_status.h"
26 #include "net/url_request/url_request_test_util.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 using testing::Eq;
31 using testing::StrEq;
32
33 namespace ntp_tiles {
34 namespace {
35
36 const char kTitle[] = "title";
37 const char kUrl[] = "url";
38 const char kLargeIconUrl[] = "large_icon_url";
39 const char kFaviconUrl[] = "favicon_url";
40
41 using TestPopularSite = std::vector<std::pair<std::string, std::string>>;
42 using TestPopularSiteVector = std::vector<TestPopularSite>;
43
44 ::testing::Matcher<const base::string16&> Str16Eq(const std::string& s) {
45 return ::testing::Eq(base::UTF8ToUTF16(s));
46 }
47
48 ::testing::Matcher<const GURL&> URLEq(const std::string& s) {
49 return ::testing::Eq(GURL(s));
50 }
51
52 // Copied from iOS code. Perhaps should be in a shared location.
53 class JsonUnsafeParser {
54 public:
55 using SuccessCallback = base::Callback<void(std::unique_ptr<base::Value>)>;
56 using ErrorCallback = base::Callback<void(const std::string&)>;
57
58 // As with SafeJsonParser, runs either success_callback or error_callback on
59 // the calling thread, but not before the call returns.
60 static void Parse(const std::string& unsafe_json,
61 const SuccessCallback& success_callback,
62 const ErrorCallback& error_callback) {
63 base::ThreadTaskRunnerHandle::Get()->PostTask(
64 FROM_HERE,
65 base::Bind(
66 [](const std::string& unsafe_json,
67 const SuccessCallback& success_callback,
68 const ErrorCallback& error_callback) {
69 std::string error_msg;
70 int error_line, error_column;
71 std::unique_ptr<base::Value> value =
72 base::JSONReader::ReadAndReturnError(
73 unsafe_json, base::JSON_ALLOW_TRAILING_COMMAS, nullptr,
74 &error_msg, &error_line, &error_column);
75 if (value) {
76 success_callback.Run(std::move(value));
77 } else {
78 error_callback.Run(base::StringPrintf(
79 "%s (%d:%d)", error_msg.c_str(), error_line, error_column));
80 }
81 },
82 unsafe_json, success_callback, error_callback));
83 }
84
85 JsonUnsafeParser() = delete;
86 };
87
88 class PopularSitesTest : public ::testing::Test {
89 protected:
90 PopularSitesTest()
91 : worker_pool_owner_(2, "PopularSitesTest."),
92 url_fetcher_factory_(nullptr) {
93 PopularSites::RegisterProfilePrefs(prefs_.registry());
94 CHECK(cache_dir_.CreateUniqueTempDir());
95 }
96
97 void SetCountryAndVersion(const std::string& country,
98 const std::string& version) {
99 prefs_.SetString(prefs::kPopularSitesOverrideCountry, country);
100 prefs_.SetString(prefs::kPopularSitesOverrideVersion, version);
101 }
102
103 void RespondWithJSON(const std::string& url,
104 const TestPopularSiteVector& sites) {
105 base::ListValue sites_value;
106 for (const TestPopularSite& site : sites) {
107 auto site_value = base::MakeUnique<base::DictionaryValue>();
108 for (const std::pair<std::string, std::string>& kv : site) {
109 site_value->SetString(kv.first, kv.second);
110 }
111 sites_value.Append(std::move(site_value));
112 }
113 std::string sites_string;
114 base::JSONWriter::Write(sites_value, &sites_string);
115 url_fetcher_factory_.SetFakeResponse(GURL(url), sites_string, net::HTTP_OK,
116 net::URLRequestStatus::SUCCESS);
117 }
118
119 void RespondWith404(const std::string& url) {
120 url_fetcher_factory_.SetFakeResponse(GURL(url), "404", net::HTTP_NOT_FOUND,
121 net::URLRequestStatus::SUCCESS);
122 }
123
124 bool FetchPopularSites(bool force_download,
125 std::vector<PopularSites::Site>* sites) {
126 scoped_refptr<net::TestURLRequestContextGetter> url_request_context(
127 new net::TestURLRequestContextGetter(
128 base::ThreadTaskRunnerHandle::Get()));
129 PopularSites popular_sites(worker_pool_owner_.pool().get(), &prefs_,
130 /*template_url_service=*/nullptr,
131 /*variations_service=*/nullptr,
132 url_request_context.get(), cache_dir_.GetPath(),
133 base::Bind(JsonUnsafeParser::Parse));
134
135 base::RunLoop loop;
136 bool save_success = false;
137 popular_sites.StartFetch(
138 force_download,
139 base::Bind(
140 [](bool* save_success, base::RunLoop* loop, bool success) {
141 *save_success = success;
142 loop->Quit();
143 },
144 &save_success, &loop));
145 loop.Run();
146 *sites = popular_sites.sites();
147 return save_success;
148 }
149
150 base::MessageLoopForUI ui_loop_;
151 base::SequencedWorkerPoolOwner worker_pool_owner_;
152 base::ScopedTempDir cache_dir_;
153 user_prefs::TestingPrefServiceSyncable prefs_;
154 net::FakeURLFetcherFactory url_fetcher_factory_;
155 };
156
157 TEST_F(PopularSitesTest, Basic) {
158 SetCountryAndVersion("ZZ", "9");
159 RespondWithJSON(
160 "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json",
161 {{
162 {kTitle, "Wikipedia, fhta Ph'nglui mglw'nafh"},
163 {kUrl, "https://zz.m.wikipedia.org/"},
164 {kLargeIconUrl, "https://zz.m.wikipedia.org/wikipedia.png"},
165 }});
166
167 std::vector<PopularSites::Site> sites;
168 EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites));
169
170 ASSERT_THAT(sites.size(), Eq(1u));
171 EXPECT_THAT(sites[0].title, Str16Eq("Wikipedia, fhta Ph'nglui mglw'nafh"));
172 EXPECT_THAT(sites[0].url, URLEq("https://zz.m.wikipedia.org/"));
173 EXPECT_THAT(sites[0].large_icon_url,
174 URLEq("https://zz.m.wikipedia.org/wikipedia.png"));
175 EXPECT_THAT(sites[0].favicon_url, URLEq(""));
176 }
177
178 TEST_F(PopularSitesTest, Fallback) {
179 SetCountryAndVersion("ZZ", "9");
180 RespondWith404(
181 "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json");
182 RespondWithJSON(
183 "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json",
184 {{
185 {kTitle, "YouTube"},
186 {kUrl, "https://m.youtube.com/"},
187 {kLargeIconUrl, "https://s.ytimg.com/apple-touch-icon.png"},
188 },
189 {
190 {kTitle, "The Chromium Project"},
191 {kUrl, "https://www.chromium.org/"},
192 {kFaviconUrl, "https://www.chromium.org/favicon.ico"},
193 }});
194
195 std::vector<PopularSites::Site> sites;
196 EXPECT_TRUE(FetchPopularSites(/*force_download=*/false, &sites));
197
198 ASSERT_THAT(sites.size(), Eq(2u));
199 EXPECT_THAT(sites[0].title, Str16Eq("YouTube"));
200 EXPECT_THAT(sites[0].url, URLEq("https://m.youtube.com/"));
201 EXPECT_THAT(sites[0].large_icon_url,
202 URLEq("https://s.ytimg.com/apple-touch-icon.png"));
203 EXPECT_THAT(sites[0].favicon_url, URLEq(""));
204 EXPECT_THAT(sites[1].title, Str16Eq("The Chromium Project"));
205 EXPECT_THAT(sites[1].url, URLEq("https://www.chromium.org/"));
206 EXPECT_THAT(sites[1].large_icon_url, URLEq(""));
207 EXPECT_THAT(sites[1].favicon_url,
208 URLEq("https://www.chromium.org/favicon.ico"));
209 }
210
211 TEST_F(PopularSitesTest, Failure) {
212 SetCountryAndVersion("ZZ", "9");
213 RespondWith404(
214 "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json");
215 RespondWith404(
216 "https://www.gstatic.com/chrome/ntp/suggested_sites_DEFAULT_5.json");
217
218 std::vector<PopularSites::Site> sites;
219 EXPECT_FALSE(FetchPopularSites(/*force_download=*/false, &sites));
220 ASSERT_THAT(sites.size(), Eq(0u));
221 }
222
223 } // namespace
224 } // namespace ntp_tiles
OLDNEW
« no previous file with comments | « components/ntp_tiles/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698