Revision control

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
import UIKit
6
import XCTest
7
@testable import Shared
8
9
class NSURLExtensionsTests: XCTestCase {
10
func testRemovesHTTPFromURL() {
11
let url = URL(string: "http://google.com")
12
if let actual = url?.absoluteDisplayString {
13
XCTAssertEqual(actual, "google.com")
14
} else {
15
XCTFail("Actual url is nil")
16
}
17
}
18
19
func testRemovesHTTPAndTrailingSlashFromURL() {
20
let url = URL(string: "http://google.com/")
21
if let actual = url?.absoluteDisplayString {
22
XCTAssertEqual(actual, "google.com")
23
} else {
24
XCTFail("Actual url is nil")
25
}
26
}
27
28
func testRemovesHTTPButNotTrailingSlashFromURL() {
29
let url = URL(string: "http://google.com/foo/")
30
if let actual = url?.absoluteDisplayString {
31
XCTAssertEqual(actual, "google.com/foo/")
32
} else {
33
XCTFail("Actual url is nil")
34
}
35
}
36
37
func testKeepsHTTPSInURL() {
38
let url = URL(string: "https://google.com")
39
if let actual = url?.absoluteDisplayString {
40
XCTAssertEqual(actual, "https://google.com")
41
} else {
42
XCTFail("Actual url is nil")
43
}
44
}
45
46
func testKeepsHTTPSAndRemovesTrailingSlashInURL() {
47
let url = URL(string: "https://google.com/")
48
if let actual = url?.absoluteDisplayString {
49
XCTAssertEqual(actual, "https://google.com")
50
} else {
51
XCTFail("Actual url is nil")
52
}
53
}
54
55
func testKeepsHTTPSAndTrailingSlashInURL() {
56
let url = URL(string: "https://google.com/foo/")
57
if let actual = url?.absoluteDisplayString {
58
XCTAssertEqual(actual, "https://google.com/foo/")
59
} else {
60
XCTFail("Actual url is nil")
61
}
62
}
63
64
func testKeepsAboutSchemeInURL() {
65
let url = URL(string: "about:home")
66
if let actual = url?.absoluteDisplayString {
67
XCTAssertEqual(actual, "about:home")
68
} else {
69
XCTFail("Actual url is nil")
70
}
71
}
72
73
//MARK: Public Suffix
74
func testNormalBaseDomainWithSingleSubdomain() {
75
// TLD Entry: co.uk
76
let url = "http://a.bbc.co.uk".asURL!
77
let expected = url.publicSuffix!
78
XCTAssertEqual("co.uk", expected)
79
}
80
81
func testCanadaComputers() {
83
let actual = url.baseDomain!
84
XCTAssertEqual("canadacomputers.com", actual)
85
}
86
87
func testMultipleSuffixesInsideURL() {
89
let actual = url.baseDomain!
90
XCTAssertEqual("canadacomputers.co.uk", actual)
91
}
92
93
func testNormalBaseDomainWithManySubdomains() {
94
// TLD Entry: co.uk
96
let expected = url.publicSuffix!
97
XCTAssertEqual("co.uk", expected)
98
}
99
100
func testWildCardDomainWithSingleSubdomain() {
101
// TLD Entry: *.kawasaki.jp
102
let url = "http://a.kawasaki.jp".asURL!
103
let expected = url.publicSuffix!
104
XCTAssertEqual("a.kawasaki.jp", expected)
105
}
106
107
func testWildCardDomainWithManySubdomains() {
108
// TLD Entry: *.kawasaki.jp
110
let expected = url.publicSuffix!
111
XCTAssertEqual("d.kawasaki.jp", expected)
112
}
113
114
func testExceptionDomain() {
115
// TLD Entry: !city.kawasaki.jp
117
let expected = url.publicSuffix!
118
XCTAssertEqual("kawasaki.jp", expected)
119
}
120
121
//MARK: Base Domain
122
func testNormalBaseSubdomain() {
123
// TLD Entry: co.uk
124
let url = "http://bbc.co.uk".asURL!
125
let expected = url.baseDomain!
126
XCTAssertEqual("bbc.co.uk", expected)
127
}
128
129
func testNormalBaseSubdomainWithAdditionalSubdomain() {
130
// TLD Entry: co.uk
131
let url = "http://a.bbc.co.uk".asURL!
132
let expected = url.baseDomain!
133
XCTAssertEqual("bbc.co.uk", expected)
134
}
135
136
func testBaseDomainForWildcardDomain() {
137
// TLD Entry: *.kawasaki.jp
139
let expected = url.baseDomain!
140
XCTAssertEqual("a.b.kawasaki.jp", expected)
141
}
142
143
func testBaseDomainForWildcardDomainWithAdditionalSubdomain() {
144
// TLD Entry: *.kawasaki.jp
146
let expected = url.baseDomain!
147
XCTAssertEqual("b.c.kawasaki.jp", expected)
148
}
149
150
func testBaseDomainForExceptionDomain() {
151
// TLD Entry: !city.kawasaki.jp
153
let expected = url.baseDomain!
154
XCTAssertEqual("city.kawasaki.jp", expected)
155
}
156
157
func testBaseDomainForExceptionDomainWithAdditionalSubdomain() {
158
// TLD Entry: !city.kawasaki.jp
160
let expected = url.baseDomain!
161
XCTAssertEqual("city.kawasaki.jp", expected)
162
}
163
164
func testBugzillaURLDomain() {
166
let nsURL = url.asURL
167
XCTAssertNotNil(nsURL, "URL parses.")
168
169
let host = nsURL!.normalizedHost
170
XCTAssertEqual(host!, "bugzilla.mozilla.org")
171
XCTAssertEqual(nsURL!.fragment!, "h=dupes%7CData%20%26%20BI%20Services%20Team%7C")
172
}
173
174
func testIPv6Domain() {
175
let url = "http://[::1]/foo/bar".asURL!
176
XCTAssertTrue(url.isIPv6)
177
XCTAssertNil(url.baseDomain)
178
XCTAssertEqual(url.normalizedHost!, "[::1]")
179
}
180
181
private func checkUrls(goodurls: [String], badurls: [String], checker: ((InternalURL) -> Bool)) {
182
goodurls.forEach {
183
var result = false
184
if let url = InternalURL(URL(string:$0)!) { result = checker(url) }
185
XCTAssertTrue(result)
186
}
187
badurls.forEach {
188
var result = false
189
if let url = InternalURL(URL(string:$0)!) { result = checker(url) }
190
XCTAssertFalse(result)
191
}
192
}
193
194
func testisAboutHomeURL() {
195
let goodurls = [
196
"\(InternalURL.baseUrl)/sessionrestore?url=\(InternalURL.baseUrl)/about/home%23panel%3D1",
197
"\(InternalURL.baseUrl)/about/home#panel=0"
198
]
199
let badurls = [
204
]
205
206
checkUrls(goodurls: goodurls, badurls: badurls, checker: { url in
207
return url.isAboutHomeURL
208
})
209
}
210
211
func testisAboutURL() {
212
let goodurls = [
213
"\(InternalURL.baseUrl)/about/home#panel=0",
214
"\(InternalURL.baseUrl)/about/license"
215
]
216
let badurls = [
221
]
222
223
checkUrls(goodurls: goodurls, badurls: badurls, checker: { url in
224
return url.isAboutURL
225
})
226
}
227
228
func testisErrorPage() {
229
let goodurls = [
230
"\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A//mozilla.com",
231
]
232
let badurls = [
236
]
237
238
checkUrls(goodurls: goodurls, badurls: badurls, checker: { url in
239
return url.isErrorPage
240
})
241
}
242
243
func testoriginalURLFromErrorURL() {
244
let goodurls = [
245
("\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A//mozilla.com", URL(string: "http://mozilla.com")),
246
("\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A//localhost%3A\(AppInfo.webserverPort)/about/home/%23panel%3D1", URL(string: "http://localhost:\(AppInfo.webserverPort)/about/home/#panel=1")),
247
]
248
249
goodurls.forEach {
250
var result = false
251
if let url = InternalURL(URL(string:$0.0)!) { result = (url.originalURLFromErrorPage == $0.1) }
252
XCTAssertTrue(result)
253
}
254
}
255
256
func testisReaderModeURL() {
257
let goodurls = [
260
]
261
let badurls = [
265
]
266
267
checkUrls(goodurls: goodurls, badurls: badurls) { url in
268
return url.url.isReaderModeURL
269
}
270
}
271
272
func testisSyncedReaderModeURL() {
273
let goodurls = [
274
"about:reader?url=",
275
"about:reader?url=http://example.com",
276
"about:reader?url=https%3A%2F%2Fen%2Em%2Ewikipedia%2Eorg%2Fwiki%2FMain%5FPage"
277
]
278
let badurls = [
281
"about:reader",
283
]
284
285
goodurls.forEach { XCTAssertTrue(URL(string:$0)!.isSyncedReaderModeURL, $0) }
286
badurls.forEach { XCTAssertFalse(URL(string:$0)!.isSyncedReaderModeURL, $0) }
287
}
288
289
func testdecodeReaderModeURL() {
290
let goodurls = [
292
("about:reader?url=https%3A%2F%2Fen%2Em%2Ewikipedia%2Eorg%2Fwiki%2FMain%5FPage&uuidkey=AAAAA", URL(string: "https://en.m.wikipedia.org/wiki/Main_Page")),
293
("about:reader?url=http%3A%2F%2Fexample%2Ecom%3Furl%3Dparam%26key%3Dvalue&uuidkey=AAAAA", URL(string: "http://example.com?url=param&key=value"))
294
]
295
let badurls = [
300
"about:reader?url="
301
]
302
303
goodurls.forEach { XCTAssertEqual(URL(string:$0.0)!.decodeReaderModeURL, $0.1) }
304
badurls.forEach { XCTAssertNil(URL(string:$0)!.decodeReaderModeURL, $0) } }
305
306
func testencodeReaderModeURL() {
308
let goodurls = [
310
]
311
goodurls.forEach { XCTAssertEqual(URL(string:$0.0)!.encodeReaderModeURL(ReaderURL), $0.1) }
312
}
313
314
func testhavingRemovedAuthorisationComponents() {
315
let goodurls = [
318
]
319
320
goodurls.forEach { XCTAssertEqual(URL(string:$0.0)!.havingRemovedAuthorisationComponents().absoluteString, $0.1) }
321
}
322
323
func testschemeIsValid() {
324
let goodurls = [
327
"tel:6044044004"
328
]
329
let badurls = [
333
]
334
335
goodurls.forEach { XCTAssertTrue(URL(string:$0)!.schemeIsValid, $0) }
336
badurls.forEach { XCTAssertFalse(URL(string:$0)!.schemeIsValid, $0) }
337
}
338
339
func testisWebPage() {
340
let goodurls = [
344
345
]
346
let badurls = [
348
"tel:6044044004",
350
]
351
352
goodurls.forEach { XCTAssertTrue(URL(string:$0)!.isWebPage(), $0) }
353
badurls.forEach { XCTAssertFalse(URL(string:$0)!.isWebPage(), $0) }
354
}
355
356
func testdomainURL() {
357
let urls = [
361
]
362
urls.forEach { XCTAssertEqual(URL(string:$0.0)!.domainURL.absoluteString, $0.1) }
363
}
364
365
func testdisplayURL() {
366
let goodurls = [
368
("\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A//mozilla.com", "http://mozilla.com"),
369
("\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A//mozilla.com", "http://mozilla.com"),
370
("\(InternalURL.baseUrl)/\(InternalURL.Path.errorpage)?url=http%3A%2F%2Flocalhost%3A\(AppInfo.webserverPort)%2Freader-mode%2Fpage%3Furl%3Dhttps%253A%252F%252Fen%252Em%252Ewikipedia%252Eorg%252Fwiki%252F", "https://en.m.wikipedia.org/wiki/"),
372
]
373
let badurls = [
376
377
]
378
379
goodurls.forEach { XCTAssertEqual(URL(string:$0.0)!.displayURL?.absoluteString, $0.1) }
380
badurls.forEach { XCTAssertNil(URL(string:$0)!.displayURL) }
381
}
382
383
func testnormalizedHostAndPath() {
384
let goodurls = [
385
("https://www.example.com/index.html", "example.com/index.html"),
386
("https://mail.example.com/index.html", "mail.example.com/index.html"),
387
("https://mail.example.co.uk/index.html", "mail.example.co.uk/index.html"),
388
("https://m.example.co.uk/index.html", "example.co.uk/index.html")
389
]
390
let badurls = [
393
]
394
395
goodurls.forEach { XCTAssertEqual(URL(string:$0.0)!.normalizedHostAndPath, $0.1) }
396
badurls.forEach { XCTAssertNil(URL(string:$0)!.normalizedHostAndPath) }
397
}
398
399
func testShortDisplayString() {
400
let urls = [
406
407
]
408
urls.forEach { XCTAssertEqual(URL(string:$0.0)!.shortDisplayString, $0.1) }
409
}
410
411
func testorigin() {
412
let urls = [
415
]
416
417
let badurls = [
419
]
420
urls.forEach { XCTAssertEqual(URL(string:$0.0)!.origin, $0.1) }
421
badurls.forEach { XCTAssertNil(URL(string:$0)!.origin) }
422
}
423
424
func testhostPort() {
425
let urls = [
426
("https://www.example.com", "www.example.com"),
427
("https://user:pass@www.example.com", "www.example.com"),
428
("http://localhost:6000/blah", "localhost:6000")
429
]
430
431
let badurls = [
432
"blah",
433
"http://"
434
]
435
urls.forEach { XCTAssertEqual(URL(string:$0.0)!.hostPort, $0.1) }
436
badurls.forEach { XCTAssertNil(URL(string:$0)!.hostPort) }
437
}
438
439
func testgetQuery() {
440
let url = URL(string: "http://example.com/path?a=1&b=2&c=3")!
441
let params = ["a": "1", "b": "2", "c": "3"]
442
443
let urlParams = url.getQuery()
444
params.forEach { XCTAssertEqual(urlParams[$0], $1, "The values in params should be the same in urlParams") }
445
}
446
447
func testwithQueryParams() {
448
let url = URL(string: "http://example.com/path")!
449
let params = ["a": "1", "b": "2", "c": "3"]
450
451
let newURL = url.withQueryParams(params.map { URLQueryItem(name: $0, value: $1) })
452
453
//make sure the new url has all the right params.
454
let newURLParams = newURL.getQuery()
455
params.forEach { XCTAssertEqual(newURLParams[$0], $1, "The values in params should be the same in newURLParams") }
456
}
457
458
func testWithQueryParam() {
459
let urlA = URL(string: "http://foo.com/bar/")!
460
let urlB = URL(string: "http://bar.com/noo")!
461
let urlC = urlA.withQueryParam("ppp", value: "123")
462
let urlD = urlB.withQueryParam("qqq", value: "123")
463
let urlE = urlC.withQueryParam("rrr", value: "aaa")
464
465
XCTAssertEqual("http://foo.com/bar/?ppp=123", urlC.absoluteString)
466
XCTAssertEqual("http://bar.com/noo?qqq=123", urlD.absoluteString)
467
XCTAssertEqual("http://foo.com/bar/?ppp=123&rrr=aaa", urlE.absoluteString)
468
}
469
470
func testHidingFromDataDetectors() {
471
guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
472
XCTFail()
473
return
474
}
475
476
let urls = ["https://example.com", "example.com", "http://example.com"]
477
for u in urls {
478
let url = URL(string: u)!
479
480
let original = url.absoluteDisplayString
481
let matches = detector.matches(in: original, options: [], range: NSMakeRange(0, original.count))
482
guard matches.count > 0 else {
483
print("\(url) doesn't match as a URL")
484
continue
485
}
486
487
let modified = url.absoluteDisplayExternalString
488
XCTAssertNotEqual(original, modified)
489
490
let newMatches = detector.matches(in: modified, options: [], range: NSMakeRange(0, modified.count))
491
492
XCTAssertEqual(0, newMatches.count, "\(modified) is not a valid URL")
493
}
494
495
}
496
497
}