Tests/KituraTests/TestRouteRegex.swift
/**
* Copyright IBM Corporation 2016, 2017
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
import Foundation
import XCTest
@testable import Kitura
@testable import KituraNet
fileprivate let helloworld = "Hello world"
// swiftlint:disable variable_name
fileprivate let id = "123"
// swiftlint:enable variable_name
fileprivate let mountpath = "/helloworld"
fileprivate let makeHandler = { (messageToSend: String) in
return { (req: RouterRequest, res: RouterResponse, next: () -> Void) throws in
let parameters = req.parameters
if parameters.isEmpty {
try res.send(messageToSend).end()
} else {
try res.send(json: parameters).end()
}
}
}
fileprivate let handler = makeHandler(helloworld)
fileprivate let subrouter = { () -> Router in
let subrouter = Router(mergeParameters: true)
subrouter.all(mountpath, handler: handler)
return subrouter
}()
final class TestRouteRegex: KituraTest, KituraTestSuite {
static var allTests: [(String, (TestRouteRegex) -> () throws -> Void)] {
return [
("testBuildRegexFromPattern", testBuildRegexFromPattern),
("testSimplePaths", testSimplePaths),
("testSimpleMatches", testSimpleMatches),
("testRouteWithPercentEncoding", testRouteWithPercentEncoding),
("testSimpleModifiers", testSimpleModifiers),
("testSimpleCustomMatches", testSimpleCustomMatches),
("testCustomMatchesWithModifiers", testCustomMatchesWithModifiers)
]
}
static let encoder = JSONEncoder()
static let decoder = JSONDecoder()
func testBuildRegexFromPattern() {
var regex: NSRegularExpression?
var isSimpleString = false
var strings: [String]?
var path: String
var range: NSRange
// Partial match false
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test", allowPartialMatch: false)
path = "/test"
XCTAssertNil(regex)
XCTAssert(isSimpleString)
XCTAssertNil(strings)
// Partial match true does not include '$' end of string special character
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test", allowPartialMatch: true)
path = "/test/hello/world"
XCTAssertNil(regex)
XCTAssert(isSimpleString)
XCTAssertNil(strings)
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test/:id", allowPartialMatch: true)
path = "/test/123/hello/world"
XCTAssertNotNil(regex)
range = regex!.rangeOfFirstMatch(in: path, options: [], range: NSMakeRange(0, path.count))
XCTAssertEqual(regex!.pattern, "^/test/(?:([^/]+?))(?:/(?=$))?(?=/|$)")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "id")
XCTAssertEqual(range.location, 0)
XCTAssertEqual(range.length, 9)
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test/:id+", allowPartialMatch: false)
XCTAssertNotNil(regex)
XCTAssertEqual(regex!.pattern, "^/test/([^/]+?(?:/[^/]+?)*)(?:/(?=$))?$")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "id")
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "test/:id*", allowPartialMatch: false)
XCTAssertNotNil(regex)
XCTAssertEqual(regex!.pattern, "^/test(?:/([^/]+?(?:/[^/]+?)*))?(?:/(?=$))?$")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "id")
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test/:id(\\d*)", allowPartialMatch: false)
XCTAssertNotNil(regex)
XCTAssertEqual(regex!.pattern, "^/test/(?:(\\d*))(?:/(?=$))?$")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "id")
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test/:id(Kitura\\d*)", allowPartialMatch: false)
XCTAssertNotNil(regex)
XCTAssertEqual(regex!.pattern, "^/test/(?:(Kitura\\d*))(?:/(?=$))?$")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "id")
(regex, isSimpleString, strings) = RouteRegex.sharedInstance.buildRegex(fromPattern: "/test/(Kitura\\d*)", allowPartialMatch: false)
XCTAssertNotNil(regex)
XCTAssertEqual(regex!.pattern, "^/test/(?:(Kitura\\d*))(?:/(?=$))?$")
XCTAssertFalse(isSimpleString)
XCTAssertNotNil(strings)
XCTAssertFalse(strings!.isEmpty)
XCTAssertEqual(strings![0], "0")
}
/// Tests for:
/// 1. ""
/// 2. "/"
/// 3. "/*"
func testSimplePaths() {
var router = Router()
router.all("", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/helloworld", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("", allowPartialMatch: false, middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
// Test broken due to router default response
// Disable for now
// XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/helloworld", callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/*", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/123/abc/456/def", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/*", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
}
/// Tests for:
/// 1. "test"
/// 2. "/:id"
func testSimpleMatches() {
var router = Router()
router.all("/test", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/test", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/test", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/test" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("\(error)")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id", allowPartialMatch: false, middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], String(mountpath.dropFirst()))
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
}
/// Tests for:
/// 1. "/:id?"
/// 2. "/:id*"
/// 3. "/:id+"
func testSimpleModifiers() {
var router = Router()
router.all("/:id?", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id?" + mountpath, handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id*", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/abc/456")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id*" + mountpath, handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/abc/456")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id+", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
// Test broken due to router default response
// Disable for now
// XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/abc/456")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
router = Router()
router.all("/:id+" + mountpath, handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/abc/456")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
}
/// Tests for:
/// 1. "/:id(\\d+)"
func testSimpleCustomMatches() {
var router = Router()
router.all("/:id(\\d+)", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/abc", callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/abc" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
}
/// Tests for:
/// 1. "/:id(\\d+)?"
/// 2. "/:id(\\d+)*"
/// 3. "/:id(\\d+)+"
func testCustomMatchesWithModifiers() {
var router = Router()
router.all("/:id(\\d+)?", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/abc", callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)?", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/abc" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)*", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/456/789", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/456/789")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456", callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)*", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
do {
let body = try response?.readString()
XCTAssertEqual(body, helloworld)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/456/789" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/456/789")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)+", handler: handler)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "", callback: { response in
// Test broken due to router default response
// Disable for now
// XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/456/789", callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/456/789")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456", callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
router = Router()
router.all("/:id(\\d+)+", middleware: subrouter)
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/" + id + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], id)
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/456/789" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .OK)
var data = Data()
do {
try response?.readAllData(into: &data)
let dict = try TestRouteRegex.decoder.decode([String: String].self, from: data)
XCTAssertEqual(dict["id"], "123/456/789")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
}, { expectation in
self.performRequest("get", path: "/123/abc/456" + mountpath, callback: { response in
XCTAssertEqual(response?.statusCode, .notFound)
expectation.fulfill()
})
})
}
func testRouteWithPercentEncoding() {
let router = Router()
router.get("/say hello", handler: makeHandler(helloworld + " with whitespace"))
router.get("/say%20hello", handler: makeHandler(helloworld + " with %20"))
router.get("/say+hello", handler: makeHandler(helloworld + " with +"))
performServerTest(router, asyncTasks: { expectation in
self.performRequest("get", path: "/say%20hello", callback: { response in
guard let response = response else {
XCTFail("ClientRequest response object was nil")
expectation.fulfill()
return
}
XCTAssertEqual(response.statusCode, .OK)
do {
let body = try response.readString()
XCTAssertEqual(body, helloworld + " with %20")
} catch {
XCTFail("Unable to read response body")
}
expectation.fulfill()
})
})
}
}