123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- //
- // ShaarliHtmlClientTest.swift
- // ShaarliOSTests
- //
- // Created by Marcus Rohrmoser on 09.06.19.
- // Copyright © 2019-2022 Marcus Rohrmoser mobile Software http://mro.name/me. All rights reserved.
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
- //
- import XCTest
- private let AGENT = "test"
- private let TO : TimeInterval = 4.0
- class ShaarliHtmlClientTest: XCTestCase {
- override func setUp() {
- // Put setup code here. This method is called before the invocation of each test method in the class.
- }
- override func tearDown() {
- URLSession.shared.reset() { print("URLSession.reset() done.")}
- }
- func testUrlEmpty () {
- XCTAssertEqual("", URLEmpty.absoluteString)
- }
- func testUrl() {
- let url = URL(string: "https://uid:pwd@example.com/foo")!
- XCTAssertEqual("https://uid:pwd@example.com/foo", url.absoluteString)
- XCTAssertEqual("https", url.scheme)
- XCTAssertEqual("example.com", url.host)
- XCTAssertEqual("uid", url.user)
- XCTAssertEqual("pwd", url.password)
- XCTAssertEqual("/foo", url.path)
- XCTAssertEqual(nil, url.query)
- XCTAssertEqual(nil, url.fragment)
- var b = URLComponents(string:url.absoluteString)!
- b.user = "foo"
- let u2 = b.url!
- XCTAssertEqual("foo", u2.user)
- XCTAssertEqual("pwd", u2.password)
- let url1 = URL(string: "a.b")!
- XCTAssertNil(url1.host)
- XCTAssertNil(url1.scheme)
- }
- func testIssue61() {
- let ur = issue61("http://example.com?a=b c")
- XCTAssertEqual("http://example.com?a=b+c", ur.absoluteString)
- }
- func testUrlCredential() {
- let cre = URLCredential(user:"", password:"", persistence:.permanent)
- XCTAssertEqual(true, cre.hasPassword)
- XCTAssertEqual("", cre.user)
- XCTAssertEqual("", cre.password)
- }
- func testBasic() {
- let str = httpBasic(URLCredential(user:"usr", password:"pwd", persistence:.forSession))
- XCTAssertEqual("Basic dXNyOnB3ZA==", str)
- guard let cre = httpBasic(str) else {
- XCTFail()
- return
- }
- XCTAssertTrue(cre.hasPassword)
- XCTAssertEqual("usr", cre.user)
- XCTAssertEqual("pwd", cre.password)
- let c : URLCredential? = nil
- XCTAssertNil(httpBasic(c))
- XCTAssertNil(httpBasic(URLCredential(user:"", password:"uhu", persistence:.permanent)))
- XCTAssertEqual("Basic dWh1Og==", httpBasic(URLCredential(user:"uhu", password:"", persistence:.forSession)))
-
- XCTAssertEqual("Basic ZGVtTzpkZW1PZGVtT2RlbU8=", httpBasic(URLCredential(user:"demO", password:"demOdemOdemO", persistence:.forSession)))
- }
- func testFormData() {
- XCTAssertEqual("1=a%26b", String(data: formData(["1":"a&b"]), encoding: .ascii))
- XCTAssertEqual("2%3D2=c%3Dc", String(data: formData(["2=2":"c=c"]), encoding: .ascii))
- XCTAssertEqual("3=d%0Ad", String(data: formData(["3":"d\nd"]), encoding: .ascii))
- var frm = ["3":"d\nd", LF_PRI:"on"]
- frm[LF_PRI] = nil
- XCTAssertEqual("3=d%0Ad", String(data: formData(frm), encoding: .ascii))
- }
- func testFormDataIssue59() {
- let pwd = ":8-$;(B%Z_rM]]?i?p{'+]1|xQk008]$,L}\\z2HxTB^%YpEl"
- let pw1 = ":8-$;(B%Z_rM]]?i?p{\'+]1|xQk008]$,L}\\z2HxTB^%YpEl"
- XCTAssertEqual(pw1, pwd, "literal escaping")
- // $ curl --trace-ascii - --data-urlencode password=':8-$;(B%Z_rM]]?i?p{\'+]1|xQk008]$,L}\\z2HxTB^%YpEl' https://demo.mro.name/
- let pwcurl = "%3A8-%24%3B%28B%25Z_rM%5D%5D%3Fi%3Fp%7B%27%2B%5D1%7CxQk008%5D%24%2CL%7D%5Cz2HxTB%5E%25YpEl"
- XCTAssertEqual("password=\(pwcurl)", String(data: formData(["password":pwd]), encoding: .ascii))
- }
- func testEncoding() {
- let str = "Hello, wörld!"
- let byt = str.data(using: .utf8, allowLossyConversion: false)!
- XCTAssertEqual(str, String(bytes: byt, encoding:.utf8))
- XCTAssertEqual("Hello, wörld!", String(bytes: byt, encoding:.isoLatin1))
- }
- func testUrlEscaping() {
- var uc = URLComponents(string: "scheme://uid:pwd@host:123/path?q=s#frag")!
- uc.user = "my uid_with_:_/_@_?_&_$_ä_🚀_end"
- uc.password = "my pwd_with_:_/_@_?_&_$_ä_🚀_end"
- XCTAssertEqual("scheme://my%20uid_with_%3A_%2F_%40_%3F_&_$_%C3%A4_%F0%9F%9A%80_end:my%20pwd_with_%3A_%2F_%40_%3F_&_$_%C3%A4_%F0%9F%9A%80_end@host:123/path?q=s#frag", uc.url?.absoluteString)
- XCTAssertEqual("my pwd_with_:_/_@_?_&_$_ä_🚀_end", uc.password)
- uc.scheme = HTTP_HTTPS
- uc.host = "demo.mro.name"
- uc.port = 8443
- uc.user = "demo"
- uc.password = "demo -/:;&@\"$#%"
- uc.path = "/shaarli-v0.11.1-issue28/"
- uc.query = nil
- uc.fragment = nil
- XCTAssertEqual("https://demo:demo%20-%2F%3A;&%40%22$%23%25@demo.mro.name:8443/shaarli-v0.11.1-issue28/", uc.url?.absoluteString)
- let u2 = uc.url!
- XCTAssertEqual(uc.scheme, u2.scheme)
- XCTAssertEqual(uc.host, u2.host)
- XCTAssertEqual(uc.port, u2.port)
- XCTAssertEqual(uc.user, u2.user)
- XCTAssertEqual("demo%20-%2F%3A;&%40%22$%23%25", u2.password) // URL.password is raw!
- XCTAssertEqual("/shaarli-v0.11.1-issue28", u2.path)
- XCTAssertEqual(uc.query, u2.query)
- XCTAssertEqual(uc.fragment, u2.fragment)
- }
- // https://nshipster.com/swift-regular-expressions/
- func testRegex() {
- let ra0 = "Fancy a game of Cluedo™️?".range(of: "Clue(do)?™️?", options:.regularExpression)
- XCTAssertEqual(16, ra0?.lowerBound.encodedOffset)
- let msg = "<script>alert(\"foo\"); // bar \");"
- let ra1 = msg.range(of: PAT_WRONG_LOGIN, options:.regularExpression)!
- XCTAssertEqual("<script>alert(\"foo\");", msg[ra1])
- }
- func testResponseLoginFormSunshine() {
- let raw = dataWithContentsOfFixture(me:self, fileName: "login.0", extensio:"html")
- let re = HTTPURLResponse(url: URLEmpty, statusCode: 200, httpVersion: "1.1", headerFields:[
- "Content-Type":"text/html; charset=utf-8",
- "Content-Length":"\(raw.count)",
- ])!
- XCTAssertEqual(200, re.statusCode)
- XCTAssertEqual("text/html", re.mimeType)
- XCTAssertEqual("utf-8", re.textEncodingName)
- XCTAssertEqual(2509, re.expectedContentLength)
- let res = check(raw, re, nil)
- XCTAssertEqual("", res.1)
- XCTAssertEqual(1, res.0.count)
- guard let lifo = res.0[LOGIN_FORM] else {
- XCTFail()
- return
- }
- XCTAssertEqual(3, lifo.count)
- XCTAssertEqual("http://links.mro.name/", lifo["returnurl"])
- XCTAssertEqual("Login", lifo[""])
- XCTAssertEqual("20119241badf78a3dcfa55ae58eab429a5d24bad", lifo["token"])
- }
- func testResponseLoginFormBanned() {
- let raw = dataWithContentsOfFixture(me:self, fileName: "login.banned", extensio:"html")
- let re = HTTPURLResponse(url: URLEmpty, statusCode: 200, httpVersion: "1.1", headerFields:[
- "Content-Type":"text/html; charset=utf-8",
- "Content-Length":"\(raw.count)",
- ])!
- XCTAssertEqual(200, re.statusCode)
- XCTAssertEqual("text/html", re.mimeType)
- XCTAssertEqual("utf-8", re.textEncodingName)
- XCTAssertEqual(1982, re.expectedContentLength)
- let res = check(raw, re, nil)
- XCTAssertEqual("You have been banned from login after too many failed attempts. Try later.", res.1)
- XCTAssertEqual(0, res.0.count)
- }
- func testProbeSunshine() {
- let demo = URL(string:"https://demo:demo@demo.shaarli.org/")! // credentials are public
- // let demo = URL(string:"https://demo:demodemodemo@demo.mro.name:8443/shaarli-v0.10.2/")! // credentials are public
- // let demo = URL(string:"https://demo:demo@shaarli-next.hoa.ro/")! // credentials are public
- // let demo = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.41b/")! // credentials are public
- // let demo = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarligo/")! // credentials are public
- let exp = self.expectation(description: "Probing") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
- let srv = ShaarliHtmlClient(AGENT)
- srv.probe(demo, nil, TO) { (url, tit, pride, tizo, err) in
- XCTAssertEqual("", err)
- // XCTAssertEqual("https://demo.shaarli.org/", url.absoluteString)
- XCTAssertEqual("Shaarli demo", tit)
- //XCTAssertEqual("https://demo:demodemodemo@demo.mro.name:8443/shaarli-v0.10.2/", url.absoluteString)
- XCTAssertEqual("https://demo:demo@demo.shaarli.org/", url.absoluteString)
- // XCTAssertEqual("https://demo:demo@shaarli-next.hoa.ro/", url.absoluteString)
- // XCTAssertEqual("https://demo:demodemodemo@demo.mro.name:8443/shaarli-v0.41b/", url.absoluteString)
- // XCTAssertEqual("https://demo:demodemodemo@demo.mro.name/shaarligo/shaarligo.cgi", url.absoluteString)
- // XCTAssertEqual("ShaarliGo 🚀", tit)
- XCTAssertEqual(false, pride)
- XCTAssertEqual(nil, tizo?.identifier)
- // XCTAssertEqual("Europe/Paris", tizo?.identifier)
- exp.fulfill()
- return
- }
- waitForExpectations(timeout: 3, handler: nil)
- }
- func testProbeSunshineIssue28() {
- var uc = URLComponents(string: "")!
- uc.scheme = HTTP_HTTPS
- uc.host = "demo.mro.name"
- uc.port = 8443
- uc.path = "/shaarli-v0.11.1-issue28/"
- // credentials are public
- uc.user = "demo"
- uc.password = "demo -/:;&@\"$#%"
- XCTAssertEqual("https://demo:demo%20-%2F%3A;&%40%22$%23%25@demo.mro.name:8443/shaarli-v0.11.1-issue28/", uc.url?.absoluteString)
- let demo = uc.url!
- XCTAssertEqual("demo", demo.user)
- XCTAssertEqual("demo%20-%2F%3A;&%40%22$%23%25", demo.password)
- let exp = self.expectation(description: "Probing") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
- let srv = ShaarliHtmlClient(AGENT)
- srv.probe(demo, nil, TO) { (url, tit, pride, tizo, err) in
- XCTAssertEqual("", err)
- XCTAssertEqual("https://demo:demo%20-%2F%3A;&%40%22$%23%25@demo.mro.name:8443/shaarli-v0.11.1-issue28/", url.absoluteString)
- XCTAssertEqual(false, pride)
- XCTAssertEqual("Europe/Berlin", tizo?.identifier)
- exp.fulfill()
- return
- }
- waitForExpectations(timeout: 5, handler: nil)
- }
- func testProbe403() {
- // let demo = URL(string:"https://demo:foo@demo.shaarli.org/")! // credentials are public
- let demo = URL(string:"https://tast:foo@demo.mro.name/shaarli-v0.10.2/")! // credentials are public
- // let demo = URL(string:"https://tast:foo@demo.mro.name/shaarli-v0.41b/")! // credentials are public
-
- let exp = self.expectation(description: "Probing") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
-
- let srv = ShaarliHtmlClient(AGENT)
- srv.probe(demo, nil, TO) { (url, pong, pride, tizo, err) in
- XCTAssertEqual(URLEmpty, url)
- XCTAssertEqual("", pong)
- XCTAssertEqual("Wrong login/password.", err)
- XCTAssertEqual(false, pride)
- XCTAssertEqual(nil, tizo?.identifier)
- // XCTAssertEqual(ShaarliHtmlClient.STR_BANNED, err)
- exp.fulfill()
- return
- }
- waitForExpectations(timeout: 2, handler: nil)
- }
- func testProbe404() {
- // let demo = URL(string:"https://demo:foo@demo.shaarli.org/hgr/")! // credentials are public
- // let demo = URL(string:"https://tast:foo@demo.mro.name/shaarli-v0.10.2/")! // credentials are public
- let demo = URL(string:"https://demo.mro.name/bogus")! // credentials are public
-
- let exp = self.expectation(description: "Probing") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
-
- let srv = ShaarliHtmlClient(AGENT)
- srv.probe(demo, nil, TO) { (url, pong, pride, tizo, err) in
- XCTAssertEqual(URLEmpty, url)
- XCTAssertEqual("", pong)
- XCTAssertEqual("Expected response HTTP status '200 Ok' but got '404 not found'", err)
- XCTAssertEqual(false, pride)
- XCTAssertEqual(nil, tizo?.identifier)
- exp.fulfill()
- return
- }
- waitForExpectations(timeout: 2, handler: nil)
- }
- func testGetSunshine() {
- // let end = URL(string:"https://demo:demo@demo.shaarli.org/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.11.1/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.10.4/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.10.2/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name:8443/shaarli-v0.10.2/")! // credentials are public
- let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.41b/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarligo")! // credentials are public
- let url = URL(string:"https://shaarli.readthedocs.io")!
- let cre = URLCredential(user:"demO", password:"demOdemOdemO", persistence:.forSession)
- let exp = self.expectation(description: "Reading") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
- let srv = ShaarliHtmlClient(AGENT)
- srv.get(end, cre, TO, url) { (_, act, frm, url, tit, dsc, tgs, pri, tim, seti, err) in
- XCTAssertEqual("https://demo.mro.name/shaarli-v0.41b/?post=https%3A%2F%2Fshaarli.readthedocs.io", act.absoluteString)
- XCTAssertEqual("https://shaarli.readthedocs.io", url.absoluteString)
- XCTAssertEqual("", tit)
- XCTAssertEqual([], tgs)
- XCTAssertFalse(pri)
- XCTAssertEqual("", err)
- // XCTAssertEqual([:], frm)
- exp.fulfill()
- }
- waitForExpectations(timeout: 2, handler: nil)
- }
- func testPostSunshine() {
- // let end = URL(string:"https://demo:demo@demo.shaarli.org/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.11.1/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.10.4/")! // credentials are public
- // let end = URL(string:"https://demo:demo@shaarli-next.hoa.ro/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.10.2/")! // credentials are public
- // let end = URL(string:"https://demo:demodemodemo@demo.mro.name:8443/shaarli-v0.10.2/")! // credentials are public
- let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.41b/")! // credentials are public
- let url = URL(string:"http://idlewords.com/talks/website_obesity.htm?foo=bar#minimalism")!
- let exp0 = self.expectation(description: "Reading") // https://medium.com/@johnsundell/unit-testing-asynchronous-swift-code-9805d1d0ac5e
- let exp1 = self.expectation(description: "Posting")
- let srv = ShaarliHtmlClient(AGENT)
- srv.get(end, nil, TO, url) { (ses, act, frm, url, tit, dsc, tgs, pri, tim, seti, err0) in
- XCTAssertEqual("", err0)
- // XCTAssertEqual("http://idlewords.com/talks/website_obesity.htm#minimalism", url.absoluteString)
- XCTAssertEqual("http://idlewords.com/talks/website_obesity.htm?foo=bar#minimalism", url.absoluteString)
- // XCTAssertEqual("The Website Obesity Crisis", tit)
- XCTAssertEqual("", dsc, "why is dsc empty?")
- XCTAssertEqual([], tgs)
- //XCTAssertFalse(pri)
- //XCTAssertNil(ctx[LF_PRI])
- exp0.fulfill()
- srv.add(ses, act, frm, url, tit, dsc, tgs, pri) { err1 in
- XCTAssertEqual("", err1)
- exp1.fulfill()
- }
- }
- waitForExpectations(timeout: 3, handler: nil)
- }
- func testPostUrlIssue61() {
- let end = URL(string:"https://demo:demodemodemo@demo.mro.name/shaarli-v0.11.1/")! // credentials are public
- let url0 = URL(string:"https://example.com?a=b+c")!
- let exp0 = self.expectation(description: "Reading")
- let exp1 = self.expectation(description: "Posting")
- let srv = ShaarliHtmlClient(AGENT)
- srv.get(end, nil, TO, url0) { (ses, act, frm, url, tit, dsc, tgs, pri, tim, seti, err0) in
- XCTAssertEqual("", err0)
- XCTAssertEqual("https://example.com?a=b+c", url.absoluteString)
- // XCTAssertEqual("The Website Obesity Crisis", tit)
- XCTAssertEqual("", dsc, "why is dsc empty?")
- XCTAssertEqual([], tgs)
- exp0.fulfill()
- srv.add(ses, act, frm, url, tit, dsc, tgs, pri) { err1 in
- XCTAssertEqual("", err1)
- exp1.fulfill()
- }
- }
- waitForExpectations(timeout: 3, handler: nil)
- }
- func testTime() {
- let cli = ShaarliHtmlClient(AGENT)
- let tz = TimeZone(secondsFromGMT:2*60*60)!
- XCTAssertNil(cli.timeShaarli(tz, nil))
- XCTAssertNil(cli.timeShaarli(tz, "bogus"))
- XCTAssertNil(cli.timeShaarli(tz, ""))
- XCTAssertEqual("2021-04-07 14:15:06 +0000", cli.timeShaarli(tz, "20210407_161506")?.description)
- }
- }
|