blob: 4378db94547f44e5eb40186ef3c857347a593f67 [file] [log] [blame]
[email protected]51bcc5d2013-04-24 01:41:371// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]07abf6ab2013-04-10 21:41:042// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]e7bba5f82013-04-10 20:10:524
avic0c60312015-12-21 21:03:505#include <stddef.h>
6
viettrungluu4b6915862014-10-16 03:42:497#include "base/macros.h"
[email protected]e7bba5f82013-04-10 20:10:528#include "testing/gtest/include/gtest/gtest.h"
[email protected]318076b2013-04-18 21:19:459#include "url/gurl.h"
10#include "url/url_canon.h"
11#include "url/url_test_utils.h"
[email protected]e7bba5f82013-04-10 20:10:5212
[email protected]0318f922014-04-22 00:09:2313namespace url {
14
15using test_utils::WStringToUTF16;
16using test_utils::ConvertUTF8ToUTF16;
[email protected]e7bba5f82013-04-10 20:10:5217
18namespace {
19
20template<typename CHAR>
[email protected]0318f922014-04-22 00:09:2321void SetupReplacement(
22 void (Replacements<CHAR>::*func)(const CHAR*, const Component&),
23 Replacements<CHAR>* replacements,
24 const CHAR* str) {
[email protected]e7bba5f82013-04-10 20:10:5225 if (str) {
[email protected]0318f922014-04-22 00:09:2326 Component comp;
[email protected]e7bba5f82013-04-10 20:10:5227 if (str[0])
28 comp.len = static_cast<int>(strlen(str));
29 (replacements->*func)(str, comp);
30 }
31}
32
33// Returns the canonicalized string for the given URL string for the
34// GURLTest.Types test.
35std::string TypesTestCase(const char* src) {
36 GURL gurl(src);
37 return gurl.possibly_invalid_spec();
38}
39
40} // namespace
41
[email protected]47e365d2014-05-02 00:02:2542// Different types of URLs should be handled differently, and handed off to
43// different canonicalizers.
[email protected]e7bba5f82013-04-10 20:10:5244TEST(GURLTest, Types) {
45 // URLs with unknown schemes should be treated as path URLs, even when they
46 // have things like "://".
47 EXPECT_EQ("something:///HOSTNAME.com/",
48 TypesTestCase("something:///HOSTNAME.com/"));
49
qyearsley2bc727d2015-08-14 20:17:1550 // Conversely, URLs with known schemes should always trigger standard URL
51 // handling.
[email protected]e7bba5f82013-04-10 20:10:5252 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:HOSTNAME.com"));
53 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:/HOSTNAME.com"));
54 EXPECT_EQ("http://hostname.com/", TypesTestCase("http://HOSTNAME.com"));
55 EXPECT_EQ("http://hostname.com/", TypesTestCase("http:///HOSTNAME.com"));
56
57#ifdef WIN32
qyearsley2bc727d2015-08-14 20:17:1558 // URLs that look like Windows absolute path specs.
[email protected]e7bba5f82013-04-10 20:10:5259 EXPECT_EQ("file:///C:/foo.txt", TypesTestCase("c:\\foo.txt"));
60 EXPECT_EQ("file:///Z:/foo.txt", TypesTestCase("Z|foo.txt"));
61 EXPECT_EQ("file://server/foo.txt", TypesTestCase("\\\\server\\foo.txt"));
62 EXPECT_EQ("file://server/foo.txt", TypesTestCase("//server/foo.txt"));
63#endif
64}
65
qyearsley2bc727d2015-08-14 20:17:1566// Test the basic creation and querying of components in a GURL. We assume that
[email protected]e7bba5f82013-04-10 20:10:5267// the parser is already tested and works, so we are mostly interested if the
68// object does the right thing with the results.
69TEST(GURLTest, Components) {
mblsha93895b12016-01-18 14:07:5270 GURL empty_url(WStringToUTF16(L""));
71 EXPECT_TRUE(empty_url.is_empty());
72 EXPECT_FALSE(empty_url.is_valid());
73
[email protected]e7bba5f82013-04-10 20:10:5274 GURL url(WStringToUTF16(L"http://user:[email protected]:99/foo;bar?q=a#ref"));
mblsha93895b12016-01-18 14:07:5275 EXPECT_FALSE(url.is_empty());
[email protected]e7bba5f82013-04-10 20:10:5276 EXPECT_TRUE(url.is_valid());
77 EXPECT_TRUE(url.SchemeIs("http"));
78 EXPECT_FALSE(url.SchemeIsFile());
79
80 // This is the narrow version of the URL, which should match the wide input.
81 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url.spec());
82
83 EXPECT_EQ("http", url.scheme());
84 EXPECT_EQ("user", url.username());
85 EXPECT_EQ("pass", url.password());
86 EXPECT_EQ("google.com", url.host());
87 EXPECT_EQ("99", url.port());
88 EXPECT_EQ(99, url.IntPort());
89 EXPECT_EQ("/foo;bar", url.path());
90 EXPECT_EQ("q=a", url.query());
91 EXPECT_EQ("ref", url.ref());
[email protected]e9185c82014-04-18 10:06:5092
93 // Test parsing userinfo with special characters.
94 GURL url_special_pass("http://user:%40!$&'()*+,;=:@google.com:12345");
95 EXPECT_TRUE(url_special_pass.is_valid());
96 // GURL canonicalizes some delimiters.
97 EXPECT_EQ("%40!$&%27()*+,%3B%3D%3A", url_special_pass.password());
98 EXPECT_EQ("google.com", url_special_pass.host());
99 EXPECT_EQ("12345", url_special_pass.port());
[email protected]e7bba5f82013-04-10 20:10:52100}
101
102TEST(GURLTest, Empty) {
103 GURL url;
104 EXPECT_FALSE(url.is_valid());
105 EXPECT_EQ("", url.spec());
106
107 EXPECT_EQ("", url.scheme());
108 EXPECT_EQ("", url.username());
109 EXPECT_EQ("", url.password());
110 EXPECT_EQ("", url.host());
111 EXPECT_EQ("", url.port());
[email protected]0318f922014-04-22 00:09:23112 EXPECT_EQ(PORT_UNSPECIFIED, url.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52113 EXPECT_EQ("", url.path());
114 EXPECT_EQ("", url.query());
115 EXPECT_EQ("", url.ref());
116}
117
118TEST(GURLTest, Copy) {
119 GURL url(WStringToUTF16(L"http://user:[email protected]:99/foo;bar?q=a#ref"));
120
121 GURL url2(url);
122 EXPECT_TRUE(url2.is_valid());
123
124 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url2.spec());
125 EXPECT_EQ("http", url2.scheme());
126 EXPECT_EQ("user", url2.username());
127 EXPECT_EQ("pass", url2.password());
128 EXPECT_EQ("google.com", url2.host());
129 EXPECT_EQ("99", url2.port());
130 EXPECT_EQ(99, url2.IntPort());
131 EXPECT_EQ("/foo;bar", url2.path());
132 EXPECT_EQ("q=a", url2.query());
133 EXPECT_EQ("ref", url2.ref());
134
135 // Copying of invalid URL should be invalid
136 GURL invalid;
137 GURL invalid2(invalid);
138 EXPECT_FALSE(invalid2.is_valid());
139 EXPECT_EQ("", invalid2.spec());
140 EXPECT_EQ("", invalid2.scheme());
141 EXPECT_EQ("", invalid2.username());
142 EXPECT_EQ("", invalid2.password());
143 EXPECT_EQ("", invalid2.host());
144 EXPECT_EQ("", invalid2.port());
[email protected]0318f922014-04-22 00:09:23145 EXPECT_EQ(PORT_UNSPECIFIED, invalid2.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52146 EXPECT_EQ("", invalid2.path());
147 EXPECT_EQ("", invalid2.query());
148 EXPECT_EQ("", invalid2.ref());
149}
150
[email protected]8093a31b2013-10-24 21:56:33151TEST(GURLTest, Assign) {
152 GURL url(WStringToUTF16(L"http://user:[email protected]:99/foo;bar?q=a#ref"));
153
154 GURL url2;
155 url2 = url;
156 EXPECT_TRUE(url2.is_valid());
157
158 EXPECT_EQ("http://user:[email protected]:99/foo;bar?q=a#ref", url2.spec());
159 EXPECT_EQ("http", url2.scheme());
160 EXPECT_EQ("user", url2.username());
161 EXPECT_EQ("pass", url2.password());
162 EXPECT_EQ("google.com", url2.host());
163 EXPECT_EQ("99", url2.port());
164 EXPECT_EQ(99, url2.IntPort());
165 EXPECT_EQ("/foo;bar", url2.path());
166 EXPECT_EQ("q=a", url2.query());
167 EXPECT_EQ("ref", url2.ref());
168
169 // Assignment of invalid URL should be invalid
170 GURL invalid;
171 GURL invalid2;
172 invalid2 = invalid;
173 EXPECT_FALSE(invalid2.is_valid());
174 EXPECT_EQ("", invalid2.spec());
175 EXPECT_EQ("", invalid2.scheme());
176 EXPECT_EQ("", invalid2.username());
177 EXPECT_EQ("", invalid2.password());
178 EXPECT_EQ("", invalid2.host());
179 EXPECT_EQ("", invalid2.port());
[email protected]0318f922014-04-22 00:09:23180 EXPECT_EQ(PORT_UNSPECIFIED, invalid2.IntPort());
[email protected]8093a31b2013-10-24 21:56:33181 EXPECT_EQ("", invalid2.path());
182 EXPECT_EQ("", invalid2.query());
183 EXPECT_EQ("", invalid2.ref());
184}
185
qyearsley2bc727d2015-08-14 20:17:15186// This is a regression test for http://crbug.com/309975.
[email protected]8093a31b2013-10-24 21:56:33187TEST(GURLTest, SelfAssign) {
188 GURL a("filesystem:http://example.com/temporary/");
189 // This should not crash.
190 a = a;
191}
192
[email protected]e7bba5f82013-04-10 20:10:52193TEST(GURLTest, CopyFileSystem) {
194 GURL url(WStringToUTF16(L"filesystem:https://user:[email protected]:99/t/foo;bar?q=a#ref"));
195
196 GURL url2(url);
197 EXPECT_TRUE(url2.is_valid());
198
199 EXPECT_EQ("filesystem:https://user:[email protected]:99/t/foo;bar?q=a#ref", url2.spec());
200 EXPECT_EQ("filesystem", url2.scheme());
201 EXPECT_EQ("", url2.username());
202 EXPECT_EQ("", url2.password());
203 EXPECT_EQ("", url2.host());
204 EXPECT_EQ("", url2.port());
[email protected]0318f922014-04-22 00:09:23205 EXPECT_EQ(PORT_UNSPECIFIED, url2.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52206 EXPECT_EQ("/foo;bar", url2.path());
207 EXPECT_EQ("q=a", url2.query());
208 EXPECT_EQ("ref", url2.ref());
209
210 const GURL* inner = url2.inner_url();
211 ASSERT_TRUE(inner);
212 EXPECT_EQ("https", inner->scheme());
213 EXPECT_EQ("user", inner->username());
214 EXPECT_EQ("pass", inner->password());
215 EXPECT_EQ("google.com", inner->host());
216 EXPECT_EQ("99", inner->port());
217 EXPECT_EQ(99, inner->IntPort());
218 EXPECT_EQ("/t", inner->path());
219 EXPECT_EQ("", inner->query());
220 EXPECT_EQ("", inner->ref());
221}
222
[email protected]e9185c82014-04-18 10:06:50223TEST(GURLTest, IsValid) {
224 const char* valid_cases[] = {
225 "http://google.com",
226 "unknown://google.com",
227 "http://user:[email protected]",
228 "http://google.com:12345",
229 "http://google.com/path",
230 "http://google.com//path",
231 "http://google.com?k=v#fragment",
232 "http://user:[email protected]:12345/path?k=v#fragment",
233 "http:/path",
234 "http:path",
235 "://google.com",
236 };
viettrungluu4b6915862014-10-16 03:42:49237 for (size_t i = 0; i < arraysize(valid_cases); i++) {
[email protected]e9185c82014-04-18 10:06:50238 EXPECT_TRUE(GURL(valid_cases[i]).is_valid())
239 << "Case: " << valid_cases[i];
240 }
241
242 const char* invalid_cases[] = {
243 "http://?k=v",
244 "http:://google.com",
245 "http//google.com",
246 "http://google.com:12three45",
247 "path",
248 };
viettrungluu4b6915862014-10-16 03:42:49249 for (size_t i = 0; i < arraysize(invalid_cases); i++) {
[email protected]e9185c82014-04-18 10:06:50250 EXPECT_FALSE(GURL(invalid_cases[i]).is_valid())
251 << "Case: " << invalid_cases[i];
252 }
253}
254
255TEST(GURLTest, ExtraSlashesBeforeAuthority) {
qyearsley2bc727d2015-08-14 20:17:15256 // According to RFC3986, the hierarchical part for URI with an authority
257 // must use only two slashes; GURL intentionally just ignores extra slashes
258 // if there are more than 2, and parses the following part as an authority.
[email protected]e9185c82014-04-18 10:06:50259 GURL url("http:///host");
260 EXPECT_EQ("host", url.host());
261 EXPECT_EQ("/", url.path());
262}
263
[email protected]e7bba5f82013-04-10 20:10:52264// Given an invalid URL, we should still get most of the components.
[email protected]e9185c82014-04-18 10:06:50265TEST(GURLTest, ComponentGettersWorkEvenForInvalidURL) {
[email protected]e7bba5f82013-04-10 20:10:52266 GURL url("http:google.com:foo");
267 EXPECT_FALSE(url.is_valid());
268 EXPECT_EQ("http://google.com:foo/", url.possibly_invalid_spec());
269
270 EXPECT_EQ("http", url.scheme());
271 EXPECT_EQ("", url.username());
272 EXPECT_EQ("", url.password());
273 EXPECT_EQ("google.com", url.host());
274 EXPECT_EQ("foo", url.port());
[email protected]0318f922014-04-22 00:09:23275 EXPECT_EQ(PORT_INVALID, url.IntPort());
[email protected]e7bba5f82013-04-10 20:10:52276 EXPECT_EQ("/", url.path());
277 EXPECT_EQ("", url.query());
278 EXPECT_EQ("", url.ref());
279}
280
281TEST(GURLTest, Resolve) {
282 // The tricky cases for relative URL resolving are tested in the
283 // canonicalizer unit test. Here, we just test that the GURL integration
284 // works properly.
285 struct ResolveCase {
286 const char* base;
287 const char* relative;
288 bool expected_valid;
289 const char* expected;
290 } resolve_cases[] = {
291 {"http://www.google.com/", "foo.html", true, "http://www.google.com/foo.html"},
maxbogueac0afb82015-01-27 03:10:49292 {"http://www.google.com/foo/", "bar", true, "http://www.google.com/foo/bar"},
293 {"http://www.google.com/foo/", "/bar", true, "http://www.google.com/bar"},
294 {"http://www.google.com/foo", "bar", true, "http://www.google.com/bar"},
[email protected]e7bba5f82013-04-10 20:10:52295 {"http://www.google.com/", "http://images.google.com/foo.html", true, "http://images.google.com/foo.html"},
296 {"http://www.google.com/blah/bloo?c#d", "../../../hello/./world.html?a#b", true, "http://www.google.com/hello/world.html?a#b"},
297 {"http://www.google.com/foo#bar", "#com", true, "http://www.google.com/foo#com"},
298 {"http://www.google.com/", "Https:images.google.com", true, "https://images.google.com/"},
299 // A non-standard base can be replaced with a standard absolute URL.
300 {"data:blahblah", "http://google.com/", true, "http://google.com/"},
301 {"data:blahblah", "http:google.com", true, "http://google.com/"},
302 // Filesystem URLs have different paths to test.
303 {"filesystem:http://www.google.com/type/", "foo.html", true, "filesystem:http://www.google.com/type/foo.html"},
304 {"filesystem:http://www.google.com/type/", "../foo.html", true, "filesystem:http://www.google.com/type/foo.html"},
305 };
306
viettrungluu4b6915862014-10-16 03:42:49307 for (size_t i = 0; i < arraysize(resolve_cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52308 // 8-bit code path.
309 GURL input(resolve_cases[i].base);
310 GURL output = input.Resolve(resolve_cases[i].relative);
311 EXPECT_EQ(resolve_cases[i].expected_valid, output.is_valid()) << i;
312 EXPECT_EQ(resolve_cases[i].expected, output.spec()) << i;
313 EXPECT_EQ(output.SchemeIsFileSystem(), output.inner_url() != NULL);
314
315 // Wide code path.
316 GURL inputw(ConvertUTF8ToUTF16(resolve_cases[i].base));
317 GURL outputw =
318 input.Resolve(ConvertUTF8ToUTF16(resolve_cases[i].relative));
319 EXPECT_EQ(resolve_cases[i].expected_valid, outputw.is_valid()) << i;
320 EXPECT_EQ(resolve_cases[i].expected, outputw.spec()) << i;
321 EXPECT_EQ(outputw.SchemeIsFileSystem(), outputw.inner_url() != NULL);
322 }
323}
324
325TEST(GURLTest, GetOrigin) {
326 struct TestCase {
327 const char* input;
328 const char* expected;
329 } cases[] = {
330 {"http://www.google.com", "http://www.google.com/"},
331 {"javascript:window.alert(\"hello,world\");", ""},
332 {"http://user:[email protected]:21/blah#baz", "http://www.google.com:21/"},
333 {"http://[email protected]", "http://www.google.com/"},
334 {"http://:[email protected]", "http://www.google.com/"},
335 {"http://:@www.google.com", "http://www.google.com/"},
336 {"filesystem:http://www.google.com/temp/foo?q#b", "http://www.google.com/"},
337 {"filesystem:http://user:[email protected]:21/blah#baz", "http://google.com:21/"},
338 };
viettrungluu4b6915862014-10-16 03:42:49339 for (size_t i = 0; i < arraysize(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52340 GURL url(cases[i].input);
341 GURL origin = url.GetOrigin();
342 EXPECT_EQ(cases[i].expected, origin.spec());
343 }
344}
345
[email protected]6b775ee2014-03-20 20:27:25346TEST(GURLTest, GetAsReferrer) {
347 struct TestCase {
348 const char* input;
349 const char* expected;
350 } cases[] = {
351 {"http://www.google.com", "http://www.google.com/"},
352 {"http://user:[email protected]:21/blah#baz", "http://www.google.com:21/blah"},
353 {"http://[email protected]", "http://www.google.com/"},
354 {"http://:[email protected]", "http://www.google.com/"},
355 {"http://:@www.google.com", "http://www.google.com/"},
356 {"http://www.google.com/temp/foo?q#b", "http://www.google.com/temp/foo?q"},
jochen42450392014-11-24 19:47:22357 {"not a url", ""},
358 {"unknown-scheme://foo.html", ""},
359 {"file:///tmp/test.html", ""},
360 {"https://www.google.com", "https://www.google.com/"},
[email protected]6b775ee2014-03-20 20:27:25361 };
viettrungluu4b6915862014-10-16 03:42:49362 for (size_t i = 0; i < arraysize(cases); i++) {
[email protected]6b775ee2014-03-20 20:27:25363 GURL url(cases[i].input);
364 GURL origin = url.GetAsReferrer();
365 EXPECT_EQ(cases[i].expected, origin.spec());
366 }
367}
368
[email protected]e7bba5f82013-04-10 20:10:52369TEST(GURLTest, GetWithEmptyPath) {
370 struct TestCase {
371 const char* input;
372 const char* expected;
373 } cases[] = {
374 {"http://www.google.com", "http://www.google.com/"},
375 {"javascript:window.alert(\"hello, world\");", ""},
376 {"http://www.google.com/foo/bar.html?baz=22", "http://www.google.com/"},
377 {"filesystem:http://www.google.com/temporary/bar.html?baz=22", "filesystem:http://www.google.com/temporary/"},
378 {"filesystem:file:///temporary/bar.html?baz=22", "filesystem:file:///temporary/"},
379 };
380
viettrungluu4b6915862014-10-16 03:42:49381 for (size_t i = 0; i < arraysize(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52382 GURL url(cases[i].input);
383 GURL empty_path = url.GetWithEmptyPath();
384 EXPECT_EQ(cases[i].expected, empty_path.spec());
385 }
386}
387
388TEST(GURLTest, Replacements) {
qyearsley2bc727d2015-08-14 20:17:15389 // The URL canonicalizer replacement test will handle most of these case.
[email protected]e7bba5f82013-04-10 20:10:52390 // The most important thing to do here is to check that the proper
391 // canonicalizer gets called based on the scheme of the input.
392 struct ReplaceCase {
393 const char* base;
394 const char* scheme;
395 const char* username;
396 const char* password;
397 const char* host;
398 const char* port;
399 const char* path;
400 const char* query;
401 const char* ref;
402 const char* expected;
403 } replace_cases[] = {
mmenke73cea7e4a2016-06-13 19:04:57404 {"http://www.google.com/foo/bar.html?foo#bar", NULL, NULL, NULL, NULL,
405 NULL, "/", "", "", "http://www.google.com/"},
406 {"http://www.google.com/foo/bar.html?foo#bar", "javascript", "", "", "",
407 "", "window.open('foo');", "", "", "javascript:window.open('foo');"},
408 {"file:///C:/foo/bar.txt", "http", NULL, NULL, "www.google.com", "99",
409 "/foo", "search", "ref", "http://www.google.com:99/foo?search#ref"},
[email protected]e7bba5f82013-04-10 20:10:52410#ifdef WIN32
mmenke73cea7e4a2016-06-13 19:04:57411 {"http://www.google.com/foo/bar.html?foo#bar", "file", "", "", "", "",
412 "c:\\", "", "", "file:///C:/"},
[email protected]e7bba5f82013-04-10 20:10:52413#endif
mmenke73cea7e4a2016-06-13 19:04:57414 {"filesystem:http://www.google.com/foo/bar.html?foo#bar", NULL, NULL,
415 NULL, NULL, NULL, "/", "", "", "filesystem:http://www.google.com/foo/"},
416 // Lengthen the URL instead of shortening it, to test creation of
417 // inner_url.
418 {"filesystem:http://www.google.com/foo/", NULL, NULL, NULL, NULL, NULL,
419 "bar.html", "foo", "bar",
420 "filesystem:http://www.google.com/foo/bar.html?foo#bar"},
[email protected]e7bba5f82013-04-10 20:10:52421 };
422
viettrungluu4b6915862014-10-16 03:42:49423 for (size_t i = 0; i < arraysize(replace_cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52424 const ReplaceCase& cur = replace_cases[i];
425 GURL url(cur.base);
426 GURL::Replacements repl;
427 SetupReplacement(&GURL::Replacements::SetScheme, &repl, cur.scheme);
428 SetupReplacement(&GURL::Replacements::SetUsername, &repl, cur.username);
429 SetupReplacement(&GURL::Replacements::SetPassword, &repl, cur.password);
430 SetupReplacement(&GURL::Replacements::SetHost, &repl, cur.host);
431 SetupReplacement(&GURL::Replacements::SetPort, &repl, cur.port);
432 SetupReplacement(&GURL::Replacements::SetPath, &repl, cur.path);
433 SetupReplacement(&GURL::Replacements::SetQuery, &repl, cur.query);
434 SetupReplacement(&GURL::Replacements::SetRef, &repl, cur.ref);
435 GURL output = url.ReplaceComponents(repl);
436
437 EXPECT_EQ(replace_cases[i].expected, output.spec());
mmenke73cea7e4a2016-06-13 19:04:57438
[email protected]e7bba5f82013-04-10 20:10:52439 EXPECT_EQ(output.SchemeIsFileSystem(), output.inner_url() != NULL);
mmenke73cea7e4a2016-06-13 19:04:57440 if (output.SchemeIsFileSystem()) {
441 // TODO(mmenke): inner_url()->spec() is currently the same as the spec()
442 // for the GURL itself. This should be fixed.
443 // See https://crbug.com/619596
444 EXPECT_EQ(replace_cases[i].expected, output.inner_url()->spec());
445 }
[email protected]e7bba5f82013-04-10 20:10:52446 }
447}
448
[email protected]369e84f72013-11-23 01:53:52449TEST(GURLTest, ClearFragmentOnDataUrl) {
450 // http://crbug.com/291747 - a data URL may legitimately have trailing
451 // whitespace in the spec after the ref is cleared. Test this does not trigger
[email protected]0318f922014-04-22 00:09:23452 // the Parsed importing validation DCHECK in GURL.
[email protected]369e84f72013-11-23 01:53:52453 GURL url(" data: one ? two # three ");
454
455 // By default the trailing whitespace will have been stripped.
456 EXPECT_EQ("data: one ? two # three", url.spec());
457 GURL::Replacements repl;
458 repl.ClearRef();
459 GURL url_no_ref = url.ReplaceComponents(repl);
460
461 EXPECT_EQ("data: one ? two ", url_no_ref.spec());
462
qyearsley2bc727d2015-08-14 20:17:15463 // Importing a parsed URL via this constructor overload will retain trailing
[email protected]369e84f72013-11-23 01:53:52464 // whitespace.
465 GURL import_url(url_no_ref.spec(),
466 url_no_ref.parsed_for_possibly_invalid_spec(),
467 url_no_ref.is_valid());
468 EXPECT_EQ(url_no_ref, import_url);
469 EXPECT_EQ(import_url.query(), " two ");
470}
471
[email protected]e7bba5f82013-04-10 20:10:52472TEST(GURLTest, PathForRequest) {
473 struct TestCase {
474 const char* input;
475 const char* expected;
476 const char* inner_expected;
477 } cases[] = {
478 {"http://www.google.com", "/", NULL},
479 {"http://www.google.com/", "/", NULL},
480 {"http://www.google.com/foo/bar.html?baz=22", "/foo/bar.html?baz=22", NULL},
481 {"http://www.google.com/foo/bar.html#ref", "/foo/bar.html", NULL},
482 {"http://www.google.com/foo/bar.html?query#ref", "/foo/bar.html?query", NULL},
483 {"filesystem:http://www.google.com/temporary/foo/bar.html?query#ref", "/foo/bar.html?query", "/temporary"},
484 {"filesystem:http://www.google.com/temporary/foo/bar.html?query", "/foo/bar.html?query", "/temporary"},
485 };
486
viettrungluu4b6915862014-10-16 03:42:49487 for (size_t i = 0; i < arraysize(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52488 GURL url(cases[i].input);
489 std::string path_request = url.PathForRequest();
490 EXPECT_EQ(cases[i].expected, path_request);
491 EXPECT_EQ(cases[i].inner_expected == NULL, url.inner_url() == NULL);
492 if (url.inner_url() && cases[i].inner_expected)
493 EXPECT_EQ(cases[i].inner_expected, url.inner_url()->PathForRequest());
494 }
495}
496
497TEST(GURLTest, EffectiveIntPort) {
498 struct PortTest {
499 const char* spec;
500 int expected_int_port;
501 } port_tests[] = {
502 // http
503 {"http://www.google.com/", 80},
504 {"http://www.google.com:80/", 80},
505 {"http://www.google.com:443/", 443},
506
507 // https
508 {"https://www.google.com/", 443},
509 {"https://www.google.com:443/", 443},
510 {"https://www.google.com:80/", 80},
511
512 // ftp
513 {"ftp://www.google.com/", 21},
514 {"ftp://www.google.com:21/", 21},
515 {"ftp://www.google.com:80/", 80},
516
517 // gopher
518 {"gopher://www.google.com/", 70},
519 {"gopher://www.google.com:70/", 70},
520 {"gopher://www.google.com:80/", 80},
521
522 // file - no port
[email protected]0318f922014-04-22 00:09:23523 {"file://www.google.com/", PORT_UNSPECIFIED},
524 {"file://www.google.com:443/", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52525
526 // data - no port
[email protected]0318f922014-04-22 00:09:23527 {"data:www.google.com:90", PORT_UNSPECIFIED},
528 {"data:www.google.com", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52529
530 // filesystem - no port
[email protected]0318f922014-04-22 00:09:23531 {"filesystem:http://www.google.com:90/t/foo", PORT_UNSPECIFIED},
532 {"filesystem:file:///t/foo", PORT_UNSPECIFIED},
[email protected]e7bba5f82013-04-10 20:10:52533 };
534
viettrungluu4b6915862014-10-16 03:42:49535 for (size_t i = 0; i < arraysize(port_tests); i++) {
[email protected]e7bba5f82013-04-10 20:10:52536 GURL url(port_tests[i].spec);
537 EXPECT_EQ(port_tests[i].expected_int_port, url.EffectiveIntPort());
538 }
539}
540
541TEST(GURLTest, IPAddress) {
542 struct IPTest {
543 const char* spec;
544 bool expected_ip;
545 } ip_tests[] = {
546 {"http://www.google.com/", false},
547 {"http://192.168.9.1/", true},
548 {"http://192.168.9.1.2/", false},
549 {"http://192.168.m.1/", false},
550 {"http://2001:db8::1/", false},
551 {"http://[2001:db8::1]/", true},
552 {"", false},
553 {"some random input!", false},
554 };
555
viettrungluu4b6915862014-10-16 03:42:49556 for (size_t i = 0; i < arraysize(ip_tests); i++) {
[email protected]e7bba5f82013-04-10 20:10:52557 GURL url(ip_tests[i].spec);
558 EXPECT_EQ(ip_tests[i].expected_ip, url.HostIsIPAddress());
559 }
560}
561
562TEST(GURLTest, HostNoBrackets) {
563 struct TestCase {
564 const char* input;
565 const char* expected_host;
566 const char* expected_plainhost;
567 } cases[] = {
568 {"http://www.google.com", "www.google.com", "www.google.com"},
569 {"http://[2001:db8::1]/", "[2001:db8::1]", "2001:db8::1"},
570 {"http://[::]/", "[::]", "::"},
571
572 // Don't require a valid URL, but don't crash either.
573 {"http://[]/", "[]", ""},
574 {"http://[x]/", "[x]", "x"},
575 {"http://[x/", "[x", "[x"},
576 {"http://x]/", "x]", "x]"},
577 {"http://[/", "[", "["},
578 {"http://]/", "]", "]"},
579 {"", "", ""},
580 };
viettrungluu4b6915862014-10-16 03:42:49581 for (size_t i = 0; i < arraysize(cases); i++) {
[email protected]e7bba5f82013-04-10 20:10:52582 GURL url(cases[i].input);
583 EXPECT_EQ(cases[i].expected_host, url.host());
584 EXPECT_EQ(cases[i].expected_plainhost, url.HostNoBrackets());
585 }
586}
587
588TEST(GURLTest, DomainIs) {
qyearsley7ffaa682015-08-03 07:03:49589 GURL url_1("http://google.com/foo");
590 EXPECT_TRUE(url_1.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52591
qyearsley7ffaa682015-08-03 07:03:49592 // Subdomain and port are ignored.
593 GURL url_2("http://www.google.com:99/foo");
594 EXPECT_TRUE(url_2.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52595
qyearsley7ffaa682015-08-03 07:03:49596 // Different top-level domain.
597 GURL url_3("http://www.google.com.cn/foo");
598 EXPECT_FALSE(url_3.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52599
qyearsley7ffaa682015-08-03 07:03:49600 // Different host name.
601 GURL url_4("http://www.iamnotgoogle.com/foo");
602 EXPECT_FALSE(url_4.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52603
qyearsley7ffaa682015-08-03 07:03:49604 // The input must be lower-cased otherwise DomainIs returns false.
605 GURL url_5("http://www.google.com/foo");
606 EXPECT_FALSE(url_5.DomainIs("Google.com"));
[email protected]e7bba5f82013-04-10 20:10:52607
qyearsley7ffaa682015-08-03 07:03:49608 // If the URL is invalid, DomainIs returns false.
609 GURL invalid_url("google.com");
610 EXPECT_FALSE(invalid_url.is_valid());
611 EXPECT_FALSE(invalid_url.DomainIs("google.com"));
612}
[email protected]e7bba5f82013-04-10 20:10:52613
qyearsley7ffaa682015-08-03 07:03:49614TEST(GURLTest, DomainIsTerminatingDotBehavior) {
615 // If the host part ends with a dot, it matches input domains
616 // with or without a dot.
617 GURL url_with_dot("http://www.google.com./foo");
618 EXPECT_TRUE(url_with_dot.DomainIs("google.com"));
619 EXPECT_TRUE(url_with_dot.DomainIs("google.com."));
620 EXPECT_TRUE(url_with_dot.DomainIs(".com"));
621 EXPECT_TRUE(url_with_dot.DomainIs(".com."));
[email protected]e7bba5f82013-04-10 20:10:52622
qyearsley7ffaa682015-08-03 07:03:49623 // But, if the host name doesn't end with a dot and the input
624 // domain does, then it's considered to not match.
625 GURL url_without_dot("http://google.com/foo");
626 EXPECT_FALSE(url_without_dot.DomainIs("google.com."));
[email protected]e7bba5f82013-04-10 20:10:52627
qyearsley7ffaa682015-08-03 07:03:49628 // If the URL ends with two dots, it doesn't match.
629 GURL url_with_two_dots("http://www.google.com../foo");
630 EXPECT_FALSE(url_with_two_dots.DomainIs("google.com"));
631}
[email protected]e7bba5f82013-04-10 20:10:52632
qyearsley7ffaa682015-08-03 07:03:49633TEST(GURLTest, DomainIsWithFilesystemScheme) {
634 GURL url_1("filesystem:http://www.google.com:99/foo/");
635 EXPECT_TRUE(url_1.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52636
qyearsley7ffaa682015-08-03 07:03:49637 GURL url_2("filesystem:http://www.iamnotgoogle.com/foo/");
638 EXPECT_FALSE(url_2.DomainIs("google.com"));
[email protected]e7bba5f82013-04-10 20:10:52639}
640
641// Newlines should be stripped from inputs.
642TEST(GURLTest, Newlines) {
643 // Constructor.
644 GURL url_1(" \t ht\ntp://\twww.goo\rgle.com/as\ndf \n ");
645 EXPECT_EQ("http://www.google.com/asdf", url_1.spec());
646
647 // Relative path resolver.
648 GURL url_2 = url_1.Resolve(" \n /fo\to\r ");
649 EXPECT_EQ("http://www.google.com/foo", url_2.spec());
650
651 // Note that newlines are NOT stripped from ReplaceComponents.
652}
653
654TEST(GURLTest, IsStandard) {
655 GURL a("http:foo/bar");
656 EXPECT_TRUE(a.IsStandard());
657
658 GURL b("foo:bar/baz");
659 EXPECT_FALSE(b.IsStandard());
660
661 GURL c("foo://bar/baz");
662 EXPECT_FALSE(c.IsStandard());
663}
[email protected]9690b992013-11-22 07:40:46664
665TEST(GURLTest, SchemeIsHTTPOrHTTPS) {
666 EXPECT_TRUE(GURL("http://bar/").SchemeIsHTTPOrHTTPS());
667 EXPECT_TRUE(GURL("HTTPS://BAR").SchemeIsHTTPOrHTTPS());
668 EXPECT_FALSE(GURL("ftp://bar/").SchemeIsHTTPOrHTTPS());
669}
670
671TEST(GURLTest, SchemeIsWSOrWSS) {
672 EXPECT_TRUE(GURL("WS://BAR/").SchemeIsWSOrWSS());
673 EXPECT_TRUE(GURL("wss://bar/").SchemeIsWSOrWSS());
674 EXPECT_FALSE(GURL("http://bar/").SchemeIsWSOrWSS());
675}
[email protected]0318f922014-04-22 00:09:23676
amogh.bihaniee85a112014-09-01 06:06:51677TEST(GURLTest, SchemeIsBlob) {
678 EXPECT_TRUE(GURL("BLOB://BAR/").SchemeIsBlob());
679 EXPECT_TRUE(GURL("blob://bar/").SchemeIsBlob());
680 EXPECT_FALSE(GURL("http://bar/").SchemeIsBlob());
681}
682
mkwst414920e2015-07-28 05:30:07683TEST(GURLTest, ContentAndPathForNonStandardURLs) {
684 struct TestCase {
685 const char* url;
686 const char* expected;
687 } cases[] = {
688 {"null", ""},
689 {"not-a-standard-scheme:this is arbitrary content",
690 "this is arbitrary content"},
691 {"view-source:http://example.com/path", "http://example.com/path"},
692 {"blob:http://example.com/GUID", "http://example.com/GUID"},
693 {"blob://http://example.com/GUID", "//http://example.com/GUID"},
694 {"blob:http://user:[email protected]/GUID",
695 "http://user:[email protected]/GUID"},
696
697 // TODO(mkwst): This seems like a bug. https://crbug.com/513600
698 {"filesystem:http://example.com/path", "/"},
699 };
700
701 for (const auto& test : cases) {
702 GURL url(test.url);
703 EXPECT_EQ(test.expected, url.path()) << test.url;
704 EXPECT_EQ(test.expected, url.GetContent()) << test.url;
705 }
706}
707
[email protected]0318f922014-04-22 00:09:23708} // namespace url