284 lines
14 KiB
Swift
284 lines
14 KiB
Swift
|
import XCTest
|
||
|
@testable import WMF
|
||
|
|
||
|
class URLParsingAndRoutingTests: XCTestCase {
|
||
|
let configuration = Configuration.current
|
||
|
let router = Configuration.current.router
|
||
|
|
||
|
func testWikiResourcePath() {
|
||
|
XCTAssertEqual("/wiki//æ/_raising".wikiResourcePath, "/æ/_raising")
|
||
|
XCTAssertNil("/w//æ/_raising".wikiResourcePath)
|
||
|
XCTAssertEqual("/wiki/อักษรละติน".wikiResourcePath, "อักษรละติน")
|
||
|
}
|
||
|
|
||
|
func testWResourcePath() {
|
||
|
XCTAssertEqual("/w/index.php?title=/æ/_raising&oldid=905679984".wResourcePath, "index.php?title=/æ/_raising&oldid=905679984")
|
||
|
}
|
||
|
|
||
|
func testNamespace() {
|
||
|
XCTAssertEqual("The_Clash:_Westway_to_the_World".namespaceOfWikiResourcePath(with: "en"), .main)
|
||
|
XCTAssertEqual("The_Clash:_Westway_to_the_World".namespaceAndTitleOfWikiResourcePath(with: "en").title, "The_Clash:_Westway_to_the_World")
|
||
|
}
|
||
|
|
||
|
func testMainPage() {
|
||
|
let enMainPageURL = URL(string: "https://en.m.wikipedia.org/wiki/Main_Page")!
|
||
|
let dest = router.destination(for: enMainPageURL, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .inAppLink(let linkURL):
|
||
|
XCTAssertEqual(linkURL, enMainPageURL.canonical)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testSpecialDestinations() {
|
||
|
let myTalkURL = URL(string: "https://en.wikipedia.org/wiki/Special:MyTalk")!
|
||
|
let myTalkDest = router.destination(for: myTalkURL, loggedInUsername: "Jimbo Wales")
|
||
|
|
||
|
switch myTalkDest {
|
||
|
case .userTalk:
|
||
|
XCTAssertTrue(true)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
let myContributionsURL = URL(string: "https://en.wikipedia.org/wiki/Special:MyContributions")!
|
||
|
let myContributionsDest = router.destination(for: myContributionsURL, loggedInUsername: "Jimbo Wales")
|
||
|
|
||
|
switch myContributionsDest {
|
||
|
case .inAppLink:
|
||
|
XCTAssertTrue(true)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
let userLoginURL1 = URL(string: "https://en.wikipedia.org/wiki/Special:UserLogin")!
|
||
|
let userLoginDest1 = router.destination(for: userLoginURL1, loggedInUsername: nil)
|
||
|
|
||
|
switch userLoginDest1 {
|
||
|
case .login:
|
||
|
XCTAssertTrue(true)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
let userLoginURL2 = URL(string: "https://en.wikipedia.org/w/index.php?title=Special:UserLogin")!
|
||
|
let userLoginDest2 = router.destination(for: userLoginURL2, loggedInUsername: nil)
|
||
|
|
||
|
switch userLoginDest2 {
|
||
|
case .login:
|
||
|
XCTAssertTrue(true)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
let importReadingListsURL = URL(string: "https://en.wikipedia.org/wiki/Special:ReadingLists?limport=eyJsaXN0Ijp7ImVuIjpbMjE4NjksMzI3NDUsNDQ0NjksNDQ0NzQsODI3ODBdfX0=")!
|
||
|
let importReadingListsDest = router.destination(for: importReadingListsURL, loggedInUsername: nil)
|
||
|
|
||
|
switch importReadingListsDest {
|
||
|
case .readingListsImport:
|
||
|
XCTAssertTrue(true)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testWikiResourcePathActivity() {
|
||
|
guard var components = URLComponents(string: "//en.wikipedia.org/wiki/User_talk:Pink_Bull") else {
|
||
|
XCTAssertTrue(false)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var dest = router.destination(for: components.url!, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .userTalk(let linkURL):
|
||
|
XCTAssertEqual(linkURL, components.url!.canonical)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
components.path = "/wiki//æ/_raising"
|
||
|
dest = router.destination(for: components.url!, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .article(let linkURL):
|
||
|
XCTAssertEqual(linkURL, components.url!.canonical)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
components.host = "fr.m.wikipedia.org"
|
||
|
components.path = "/wiki/France"
|
||
|
dest = router.destination(for: components.url!, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .article(let linkURL):
|
||
|
XCTAssertEqual(linkURL, components.url!.canonical)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
// Special should work on frwiki because it's a canonical namespace
|
||
|
components.path = "/wiki/Special:MobileDiff/24601"
|
||
|
dest = router.destination(for: components.url!, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .articleDiffSingle(let linkURL, _, let toRevID):
|
||
|
XCTAssertEqual(linkURL, components.url!.canonical)
|
||
|
XCTAssertEqual(toRevID, 24601)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
|
||
|
components.host = "zh.m.wikipedia.org"
|
||
|
components.path = "/wiki/特殊:MobileDiff/24601"
|
||
|
dest = router.destination(for: components.url!, loggedInUsername: nil)
|
||
|
switch dest {
|
||
|
case .articleDiffSingle(let linkURL, _, let toRevID):
|
||
|
XCTAssertEqual(linkURL, components.url!.canonical)
|
||
|
XCTAssertEqual(toRevID, 24601)
|
||
|
default:
|
||
|
XCTAssertTrue(false)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testTitlesWithForwardSlashes() {
|
||
|
var url = URL(string: "https://en.wikipedia.org/wiki/G/O_Media")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("./Gizmodo")?.absoluteString, "https://en.wikipedia.org/wiki/Gizmodo")
|
||
|
url = URL(string: "https://en.wikipedia.org/wiki//dev/random")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref(".//dev/null")?.absoluteString, "https://en.wikipedia.org/wiki//dev/null")
|
||
|
}
|
||
|
|
||
|
/// Ensure the 'transcoded' path component is inserted after the language path component for audio hosted on Wikipedia
|
||
|
func testWikipediaCompatibilityAdjustments() {
|
||
|
let url = URL(string: "https://upload.wikimedia.org/wikipedia/en/3/3f/DeanScream.ogg")!
|
||
|
let expected = URL(string: "https://upload.wikimedia.org/wikipedia/en/transcoded/3/3f/DeanScream.ogg/DeanScream.ogg.mp3")!
|
||
|
XCTAssertEqual(url.byMakingAudioFileCompatibilityAdjustments, expected)
|
||
|
}
|
||
|
|
||
|
/// Ensure the 'transcoded' path component is inserted after the 'commons' path component for audio hosted on Commons
|
||
|
func testCommonsCompatibilityAdjustments() {
|
||
|
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/8/8a/En-Paprika_%28American%29.oga")!
|
||
|
let expected = URL(string: "https://upload.wikimedia.org/wikipedia/commons/transcoded/8/8a/En-Paprika_(American).oga/En-Paprika_(American).oga.mp3")!
|
||
|
XCTAssertEqual(url.byMakingAudioFileCompatibilityAdjustments, expected)
|
||
|
}
|
||
|
|
||
|
/// Ensure non audio and non-upload.wikimedia.org links aren't transcoded and don't break in unexpected ways
|
||
|
func testInvalidCompatibilityAdjustment() {
|
||
|
var url = URL(string: "https://upload.wikimedia.org/commons/3/3f/DeanScream.ogv")!
|
||
|
XCTAssertFalse(url.isWikimediaHostedAudioFileLink)
|
||
|
url = URL(string: "https://en.wikipedia.org/commons/3/3f/DeanScream.ogg")!
|
||
|
XCTAssertFalse(url.isWikimediaHostedAudioFileLink)
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersEncodedOnWiki() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("./COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")?.absoluteString, "https://de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersUnencodedOnWiki() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("./COVID-19-Pandemie_in_Baden-Württemberg")?.absoluteString, "https://de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersEncodedOnAnotherWiki() {
|
||
|
let url = URL(string: "https://en.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")?.absoluteString, "https://de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersUnencodedOnAnotherWiki() {
|
||
|
let url = URL(string: "https://en.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-Württemberg")?.absoluteString, "https://de.wikipedia.org/wiki/COVID-19-Pandemie_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersEncodedOnCommons() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg")?.absoluteString, "https://commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersUnencodedOnCommons() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-Württemberg")?.absoluteString, "https://commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersEncodedOffWiki() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//www.p%C3%BCzzledpint.com")?.absoluteString, "https://www.p%C3%BCzzledpint.com")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersUnencodedOffWiki() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//www.püzzledpint.com")?.absoluteString, "https://www.p%C3%BCzzledpint.com")
|
||
|
}
|
||
|
|
||
|
func testQuestionMark() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//www.puzzledpint.com/page?test=yes")?.absoluteString, "https://www.puzzledpint.com/page?test=yes")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersEncodedWithQuestionMark() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg?uselang=de")?.absoluteString, "https://commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg?uselang=de")
|
||
|
}
|
||
|
|
||
|
func testSpecialCharactersUnencodedWithQuestionMark() {
|
||
|
let url = URL(string: "https://de.wikipedia.org/wiki/Grinnell_College")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-Württemberg?uselang=de")?.absoluteString, "https://commons.wikimedia.org/wiki/Category:COVID-19_pandemic_in_Baden-W%C3%BCrttemberg?uselang=de")
|
||
|
}
|
||
|
|
||
|
func testQuestionMarkInPath() {
|
||
|
let url = URL(string: "https://en.wikipedia.org/wiki/Main_Page")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("./Who's_the_Man%3F")?.absoluteString, "https://en.wikipedia.org/wiki/Who's_the_Man%3F")
|
||
|
}
|
||
|
|
||
|
func testCaret() {
|
||
|
let url = URL(string: "https://en.wikipedia.org/wiki/Main_Page")!
|
||
|
XCTAssertEqual(url.resolvingRelativeWikiHref("//commons.wikimedia.org/wiki/File:^8_Schickelgruber._He_was_sick_two_days_last_week_-_NARA_-_535224.jpg")?.absoluteString, "https://commons.wikimedia.org/wiki/File:%5E8_Schickelgruber._He_was_sick_two_days_last_week_-_NARA_-_535224.jpg")
|
||
|
}
|
||
|
|
||
|
func testLanguageVariantCodeProperty() {
|
||
|
var url = URL(string: "https://zh.wikipedia.org")!
|
||
|
XCTAssertNil(url.wmf_languageVariantCode)
|
||
|
let languageVariantCode = "zh-hant"
|
||
|
url.wmf_languageVariantCode = languageVariantCode
|
||
|
XCTAssertEqual(url.wmf_languageVariantCode, languageVariantCode)
|
||
|
|
||
|
// Assignment of value type URL preserves the language variant code associated object
|
||
|
// Both are backed by the same copy-on-write NSURL instance
|
||
|
let url2 = url
|
||
|
XCTAssertEqual(url2.wmf_languageVariantCode, languageVariantCode)
|
||
|
|
||
|
// Creating new URL instances based on the original DOES NOT automatically
|
||
|
// propagate the language variant code associated object
|
||
|
let url3 = url.appendingPathComponent("test")
|
||
|
XCTAssertNotEqual(url3.wmf_languageVariantCode, languageVariantCode)
|
||
|
}
|
||
|
|
||
|
func testContentLanguageCodeProperty() {
|
||
|
let languageCode = "zh"
|
||
|
let languageVariantCode = "zh-hans"
|
||
|
var url = URL(string: "https://\(languageCode).wikipedia.org")!
|
||
|
|
||
|
// If languageVariantCode is non-nil and non-empty string, wmf_contentLanguageCode returns languageVariantCode
|
||
|
url.wmf_languageVariantCode = languageVariantCode
|
||
|
XCTAssertEqual(url.wmf_contentLanguageCode, languageVariantCode)
|
||
|
|
||
|
// If languageVariantCode is nil, contentLanguageCode returns languageCode
|
||
|
url.wmf_languageVariantCode = nil
|
||
|
XCTAssertEqual(url.wmf_contentLanguageCode, languageCode)
|
||
|
|
||
|
// If languageVariantCode is an empty string, contentLanguageCode returns languageCode
|
||
|
url.wmf_languageVariantCode = ""
|
||
|
XCTAssertEqual(url.wmf_contentLanguageCode, languageCode)
|
||
|
}
|
||
|
|
||
|
func testLanguageVariantCodePropertyFromURLComponents() {
|
||
|
let components = URLComponents(string: "https://sr.wikipedia.org")
|
||
|
let languageVariantCode = "sr-ec"
|
||
|
XCTAssertNotNil(components)
|
||
|
if let components = components {
|
||
|
let url = components.wmf_URLWithLanguageVariantCode(languageVariantCode)
|
||
|
XCTAssertNotNil(url)
|
||
|
XCTAssertEqual(url?.wmf_languageVariantCode, languageVariantCode)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|