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

Side by Side Diff: components/link_header_util/link_header_util_unittest.cc

Issue 1811163002: Share link header parsing code between blink and content. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@base-optional
Patch Set: Created 4 years, 8 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
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 "content/browser/service_worker/link_header_support.h" 5 #include "components/link_header_util/link_header_util.h"
6 6
7 #include "base/command_line.h"
8 #include "base/logging.h" 7 #include "base/logging.h"
9 #include "base/run_loop.h" 8 #include "base/run_loop.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_wrapper.h"
12 #include "content/browser/service_worker/service_worker_registration.h"
13 #include "content/public/browser/resource_request_info.h"
14 #include "content/public/common/content_switches.h"
15 #include "content/public/test/mock_resource_context.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "net/http/http_response_headers.h"
18 #include "net/url_request/url_request_test_job.h"
19 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
21 10
22 namespace content { 11 namespace link_header_util {
23 12
24 namespace { 13 namespace {
25 14
15 void SplitLinkHeaderForTesting(const std::string& header,
16 std::vector<std::string>* values) {
17 std::vector<StringIteratorPair> values_iterators = SplitLinkHeader(header);
18 values->clear();
19 for (const auto& pair : values_iterators)
20 values->push_back(std::string(pair.first, pair.second));
21 }
22
23 bool ParseLinkHeaderValueForTesting(
24 std::string value,
25 std::string* url,
26 std::unordered_map<std::string, base::Optional<std::string>>* params) {
27 return ParseLinkHeaderValue(value.begin(), value.end(), url, params);
28 }
29
26 TEST(LinkHeaderTest, SplitEmpty) { 30 TEST(LinkHeaderTest, SplitEmpty) {
27 std::vector<std::string> values; 31 std::vector<std::string> values;
28 SplitLinkHeaderForTesting("", &values); 32 SplitLinkHeaderForTesting("", &values);
29 ASSERT_EQ(0u, values.size()); 33 ASSERT_EQ(0u, values.size());
30 } 34 }
31 35
32 TEST(LinkHeaderTest, SplitSimple) { 36 TEST(LinkHeaderTest, SplitSimple) {
33 std::vector<std::string> values; 37 std::vector<std::string> values;
34 SplitLinkHeaderForTesting("hello", &values); 38 SplitLinkHeaderForTesting("hello", &values);
35 ASSERT_EQ(1u, values.size()); 39 ASSERT_EQ(1u, values.size());
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 void PrintTo(const SimpleParseTestData& test, std::ostream* os) { 90 void PrintTo(const SimpleParseTestData& test, std::ostream* os) {
87 *os << ::testing::PrintToString(test.link); 91 *os << ::testing::PrintToString(test.link);
88 } 92 }
89 93
90 class SimpleParseTest : public ::testing::TestWithParam<SimpleParseTestData> {}; 94 class SimpleParseTest : public ::testing::TestWithParam<SimpleParseTestData> {};
91 95
92 TEST_P(SimpleParseTest, Simple) { 96 TEST_P(SimpleParseTest, Simple) {
93 const SimpleParseTestData test = GetParam(); 97 const SimpleParseTestData test = GetParam();
94 98
95 std::string url; 99 std::string url;
96 std::unordered_map<std::string, std::string> params; 100 std::unordered_map<std::string, base::Optional<std::string>> params;
97 EXPECT_EQ(test.valid, 101 EXPECT_EQ(test.valid,
98 ParseLinkHeaderValueForTesting(test.link, &url, &params)); 102 ParseLinkHeaderValueForTesting(test.link, &url, &params));
99 if (test.valid) { 103 if (test.valid) {
100 EXPECT_EQ(test.url, url); 104 EXPECT_EQ(test.url, url);
101 EXPECT_EQ(test.rel, params["rel"]); 105 EXPECT_EQ(test.rel, params["rel"].value_or(""));
102 EXPECT_EQ(test.as, params["as"]); 106 EXPECT_EQ(test.as, params["as"].value_or(""));
103 } 107 }
104 } 108 }
105 109
106 // Test data mostly copied from blink::LinkHeaderTest. Expectations for some 110 // Test data mostly copied from blink::LinkHeaderTest. Expectations for some
107 // test cases are different though. Mostly because blink::LinkHeader is stricter 111 // test cases are different though. Mostly because blink::LinkHeader is stricter
108 // about validity while parsing (primarily things like mismatched quotes), and 112 // about validity while parsing (primarily things like mismatched quotes), and
109 // factors in knowledge about semantics of Link headers (parameters that are 113 // factors in knowledge about semantics of Link headers (parameters that are
110 // required to have a value if they occur, some parameters are auto-lower-cased, 114 // required to have a value if they occur, some parameters are auto-lower-cased,
111 // headers with an "anchor" parameter are rejected by base::LinkHeader). 115 // headers with an "anchor" parameter are rejected by base::LinkHeader).
112 // The code this tests purely parses without actually interpreting the data, as 116 // The code this tests purely parses without actually interpreting the data, as
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 {"<simple.css>; rel=\"", true, "simple.css", "", ""}, 215 {"<simple.css>; rel=\"", true, "simple.css", "", ""},
212 {"simple.css; rel=prefetch", false}, 216 {"simple.css; rel=prefetch", false},
213 {"<simple.css>; rel=prefetch; rel=foobar", true, "simple.css", "prefetch", 217 {"<simple.css>; rel=prefetch; rel=foobar", true, "simple.css", "prefetch",
214 ""}, 218 ""},
215 }; 219 };
216 220
217 INSTANTIATE_TEST_CASE_P(LinkHeaderTest, 221 INSTANTIATE_TEST_CASE_P(LinkHeaderTest,
218 SimpleParseTest, 222 SimpleParseTest,
219 testing::ValuesIn(simple_parse_tests)); 223 testing::ValuesIn(simple_parse_tests));
220 224
221 void SaveFoundRegistrationsCallback(
222 ServiceWorkerStatusCode expected_status,
223 bool* called,
224 std::vector<ServiceWorkerRegistrationInfo>* registrations,
225 ServiceWorkerStatusCode status,
226 const std::vector<ServiceWorkerRegistrationInfo>& result) {
227 EXPECT_EQ(expected_status, status);
228 *called = true;
229 *registrations = result;
230 }
231
232 ServiceWorkerContextWrapper::GetRegistrationsInfosCallback
233 SaveFoundRegistrations(
234 ServiceWorkerStatusCode expected_status,
235 bool* called,
236 std::vector<ServiceWorkerRegistrationInfo>* registrations) {
237 *called = false;
238 return base::Bind(&SaveFoundRegistrationsCallback, expected_status, called,
239 registrations);
240 }
241
242 class LinkHeaderServiceWorkerTest : public ::testing::Test {
243 public:
244 LinkHeaderServiceWorkerTest()
245 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
246 resource_context_(&request_context_) {
247 base::CommandLine::ForCurrentProcess()->AppendSwitch(
248 switches::kEnableExperimentalWebPlatformFeatures);
249 }
250 ~LinkHeaderServiceWorkerTest() override {}
251
252 void SetUp() override {
253 helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
254 }
255
256 void TearDown() override { helper_.reset(); }
257
258 ServiceWorkerContextWrapper* context_wrapper() {
259 return helper_->context_wrapper();
260 }
261
262 void ProcessLinkHeader(const GURL& request_url,
263 const std::string& link_header) {
264 scoped_ptr<net::URLRequest> request = request_context_.CreateRequest(
265 request_url, net::DEFAULT_PRIORITY, &request_delegate_);
266 ResourceRequestInfo::AllocateForTesting(
267 request.get(), RESOURCE_TYPE_SCRIPT, &resource_context_,
268 -1 /* render_process_id */, -1 /* render_view_id */,
269 -1 /* render_frame_id */, false /* is_main_frame */,
270 false /* parent_is_main_frame */, true /* allow_download */,
271 true /* is_async */, false /* is_using_lofi */);
272
273 ProcessLinkHeaderForRequest(request.get(), link_header, context_wrapper());
274 base::RunLoop().RunUntilIdle();
275 }
276
277 std::vector<ServiceWorkerRegistrationInfo> GetRegistrations() {
278 bool called;
279 std::vector<ServiceWorkerRegistrationInfo> registrations;
280 context_wrapper()->GetAllRegistrations(
281 SaveFoundRegistrations(SERVICE_WORKER_OK, &called, &registrations));
282 base::RunLoop().RunUntilIdle();
283 EXPECT_TRUE(called);
284 return registrations;
285 }
286
287 private:
288 TestBrowserThreadBundle thread_bundle_;
289 scoped_ptr<EmbeddedWorkerTestHelper> helper_;
290 net::TestURLRequestContext request_context_;
291 net::TestDelegate request_delegate_;
292 MockResourceContext resource_context_;
293 };
294
295 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_Basic) {
296 ProcessLinkHeader(GURL("https://example.com/foo/bar/"),
297 "<../foo.js>; rel=serviceworker");
298
299 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
300 ASSERT_EQ(1u, registrations.size());
301 EXPECT_EQ(GURL("https://example.com/foo/"), registrations[0].pattern);
302 EXPECT_EQ(GURL("https://example.com/foo/foo.js"),
303 registrations[0].active_version.script_url);
304 }
305
306 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeWithFragment) {
307 ProcessLinkHeader(GURL("https://example.com/foo/bar/"),
308 "<../bar.js>; rel=serviceworker; scope=\"scope#ref\"");
309
310 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
311 ASSERT_EQ(1u, registrations.size());
312 EXPECT_EQ(GURL("https://example.com/foo/bar/scope"),
313 registrations[0].pattern);
314 EXPECT_EQ(GURL("https://example.com/foo/bar.js"),
315 registrations[0].active_version.script_url);
316 }
317
318 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeAbsoluteUrl) {
319 ProcessLinkHeader(GURL("https://example.com/foo/bar/"),
320 "<bar.js>; rel=serviceworker; "
321 "scope=\"https://example.com:443/foo/bar/scope\"");
322
323 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
324 ASSERT_EQ(1u, registrations.size());
325 EXPECT_EQ(GURL("https://example.com/foo/bar/scope"),
326 registrations[0].pattern);
327 EXPECT_EQ(GURL("https://example.com/foo/bar/bar.js"),
328 registrations[0].active_version.script_url);
329 }
330
331 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeDifferentOrigin) {
332 ProcessLinkHeader(
333 GURL("https://example.com/foobar/"),
334 "<bar.js>; rel=serviceworker; scope=\"https://google.com/scope\"");
335
336 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
337 ASSERT_EQ(0u, registrations.size());
338 }
339
340 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScopeUrlEncodedSlash) {
341 ProcessLinkHeader(GURL("https://example.com/foobar/"),
342 "<bar.js>; rel=serviceworker; scope=\"./foo%2Fbar\"");
343
344 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
345 ASSERT_EQ(0u, registrations.size());
346 }
347
348 TEST_F(LinkHeaderServiceWorkerTest,
349 InstallServiceWorker_ScriptUrlEncodedSlash) {
350 ProcessLinkHeader(GURL("https://example.com/foobar/"),
351 "<foo%2Fbar.js>; rel=serviceworker");
352
353 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
354 ASSERT_EQ(0u, registrations.size());
355 }
356
357 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_ScriptAbsoluteUrl) {
358 ProcessLinkHeader(
359 GURL("https://example.com/foobar/"),
360 "<https://example.com/bar.js>; rel=serviceworker; scope=foo");
361
362 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
363 ASSERT_EQ(1u, registrations.size());
364 EXPECT_EQ(GURL("https://example.com/foobar/foo"), registrations[0].pattern);
365 EXPECT_EQ(GURL("https://example.com/bar.js"),
366 registrations[0].active_version.script_url);
367 }
368
369 TEST_F(LinkHeaderServiceWorkerTest,
370 InstallServiceWorker_ScriptDifferentOrigin) {
371 ProcessLinkHeader(
372 GURL("https://example.com/foobar/"),
373 "<https://google.com/bar.js>; rel=serviceworker; scope=foo");
374
375 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
376 ASSERT_EQ(0u, registrations.size());
377 }
378
379 TEST_F(LinkHeaderServiceWorkerTest, InstallServiceWorker_MultipleWorkers) {
380 ProcessLinkHeader(GURL("https://example.com/foobar/"),
381 "<bar.js>; rel=serviceworker; scope=foo, <baz.js>; "
382 "rel=serviceworker; scope=scope");
383
384 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
385 ASSERT_EQ(2u, registrations.size());
386 EXPECT_EQ(GURL("https://example.com/foobar/foo"), registrations[0].pattern);
387 EXPECT_EQ(GURL("https://example.com/foobar/bar.js"),
388 registrations[0].active_version.script_url);
389 EXPECT_EQ(GURL("https://example.com/foobar/scope"), registrations[1].pattern);
390 EXPECT_EQ(GURL("https://example.com/foobar/baz.js"),
391 registrations[1].active_version.script_url);
392 }
393
394 TEST_F(LinkHeaderServiceWorkerTest,
395 InstallServiceWorker_ValidAndInvalidValues) {
396 ProcessLinkHeader(
397 GURL("https://example.com/foobar/"),
398 "<https://google.com/bar.js>; rel=serviceworker; scope=foo, <baz.js>; "
399 "rel=serviceworker; scope=scope");
400
401 std::vector<ServiceWorkerRegistrationInfo> registrations = GetRegistrations();
402 ASSERT_EQ(1u, registrations.size());
403 EXPECT_EQ(GURL("https://example.com/foobar/scope"), registrations[0].pattern);
404 EXPECT_EQ(GURL("https://example.com/foobar/baz.js"),
405 registrations[0].active_version.script_url);
406 }
407
408 } // namespace 225 } // namespace
409 226
410 } // namespace content 227 } // namespace link_header_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698