Skip to content

Commit

Permalink
Merge pull request #5 from hummingbird-project/more-tests
Browse files Browse the repository at this point in the history
Add APIGatewayV2, Error handling tests
  • Loading branch information
adam-fowler committed Feb 10, 2023
2 parents 69506d3 + b170625 commit 2e579de
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Sources/HummingbirdLambda/APIGatewayLambda.swift
Expand Up @@ -35,10 +35,10 @@ extension HBLambda where Output == APIGatewayResponse {
}
}

// conform `APIGateway.Request` to `APIRequest` so we can use HBRequest.init(context:application:from)
// conform `APIGatewayRequest` to `APIRequest` so we can use HBRequest.init(context:application:from)
extension APIGatewayRequest: APIRequest {}

// conform `APIGateway.Response` to `APIResponse` so we can use HBResponse.apiReponse()
// conform `APIGatewayResponse` to `APIResponse` so we can use HBResponse.apiReponse()
extension APIGatewayResponse: APIResponse {}

extension HBRequest {
Expand Down
6 changes: 3 additions & 3 deletions Sources/HummingbirdLambda/APIGatewayV2Lambda.swift
Expand Up @@ -35,7 +35,7 @@ extension HBLambda where Output == APIGatewayV2Response {
}
}

// conform `APIGateway.V2.Request` to `APIRequest` so we can use HBRequest.init(context:application:from)
// conform `APIGatewayV2Request` to `APIRequest` so we can use HBRequest.init(context:application:from)
extension APIGatewayV2Request: APIRequest {
var path: String {
// use routeKey as path has stage in it
Expand All @@ -47,7 +47,7 @@ extension APIGatewayV2Request: APIRequest {
var multiValueHeaders: HTTPMultiValueHeaders { [:] }
}

// conform `APIGateway.V2.Response` to `APIResponse` so we can use HBResponse.apiReponse()
// conform `APIGatewayV2Response` to `APIResponse` so we can use HBResponse.apiReponse()
extension APIGatewayV2Response: APIResponse {
init(
statusCode: AWSLambdaEvents.HTTPResponseStatus,
Expand All @@ -56,7 +56,7 @@ extension APIGatewayV2Response: APIResponse {
body: String?,
isBase64Encoded: Bool?
) {
precondition(multiValueHeaders == nil, "Multi value headers are unavailable in APIGatewayV2")
precondition(multiValueHeaders == nil || multiValueHeaders?.count == 0, "Multi value headers are unavailable in APIGatewayV2")
self.init(statusCode: statusCode, headers: headers, body: body, isBase64Encoded: isBase64Encoded, cookies: nil)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/HummingbirdLambda/Request+APIGateway.swift
Expand Up @@ -35,7 +35,7 @@ extension LambdaContext: HBRequestContext {

extension HBRequest {
/// Specialization of HBLambda.request where `In` is `APIGateway.Request`
init(context: LambdaContext, application: HBApplication, from: APIRequest) throws {
init<Request: APIRequest>(context: LambdaContext, application: HBApplication, from: Request) throws {
// construct URI with query parameters
var uri = from.path
var queryParams: [String] = []
Expand Down
101 changes: 101 additions & 0 deletions Tests/HummingbirdLambdaTests/LambdaTests.swift
Expand Up @@ -63,6 +63,65 @@ final class LambdaTests: XCTestCase {
return try JSONDecoder().decode(APIGatewayRequest.self, from: Data(request.utf8))
}

func newV2Event(uri: String, method: String) throws -> APIGatewayV2Request {
let request = """
{
"routeKey":"\(method) \(uri)",
"version":"2.0",
"rawPath":"\(uri)",
"stageVariables":{
"foo":"bar"
},
"requestContext":{
"timeEpoch":1587750461466,
"domainPrefix":"hello",
"authorizer":{
"jwt":{
"scopes":[
"hello"
],
"claims":{
"aud":"customers",
"iss":"https://hello.test.com/",
"iat":"1587749276",
"exp":"1587756476"
}
}
},
"accountId":"0123456789",
"stage":"$default",
"domainName":"hello.test.com",
"apiId":"pb5dg6g3rg",
"requestId":"LgLpnibOFiAEPCA=",
"http":{
"path":"\(uri)",
"userAgent":"Paw/3.1.10 (Macintosh; OS X/10.15.4) GCDHTTPRequest",
"method":"\(method)",
"protocol":"HTTP/1.1",
"sourceIp":"91.64.117.86"
},
"time":"24/Apr/2020:17:47:41 +0000"
},
"isBase64Encoded":false,
"rawQueryString":"foo=bar",
"queryStringParameters":{
"foo":"bar"
},
"headers":{
"x-forwarded-proto":"https",
"x-forwarded-for":"91.64.117.86",
"x-forwarded-port":"443",
"authorization":"Bearer abc123",
"host":"hello.test.com",
"x-amzn-trace-id":"Root=1-5ea3263d-07c5d5ddfd0788bed7dad831",
"user-agent":"Paw/3.1.10 (Macintosh; OS X/10.15.4) GCDHTTPRequest",
"content-length":"0"
}
}
"""
return try JSONDecoder().decode(APIGatewayV2Request.self, from: Data(request.utf8))
}

func testSimpleRoute() throws {
struct HelloLambda: HBLambda {
// define input and output
Expand Down Expand Up @@ -106,4 +165,46 @@ final class LambdaTests: XCTestCase {
XCTAssertEqual(response.isBase64Encoded, true)
XCTAssertEqual(response.body, String(base64Encoding: data))
}

func testAPIGatewayV2Decoding() throws {
struct HelloLambda: HBLambda {
// define input and output
typealias Event = APIGatewayV2Request
typealias Output = APIGatewayV2Response

init(_ app: HBApplication) {
app.middleware.add(HBLogRequestsMiddleware(.debug))
app.router.post { _ in
return "hello"
}
}
}
let lambda = try HBLambdaHandler<HelloLambda>.makeHandler(context: self.initializationContext).wait()
let context = self.newContext()
let event = try newV2Event(uri: "/", method: "POST")
let response = try lambda.handle(event, context: context).wait()
XCTAssertEqual(response.statusCode, .ok)
XCTAssertEqual(response.body, "hello")
}

func testErrorEncoding() throws {
struct HelloLambda: HBLambda {
// define input and output
typealias Event = APIGatewayV2Request
typealias Output = APIGatewayV2Response

init(_ app: HBApplication) {
app.middleware.add(HBLogRequestsMiddleware(.debug))
app.router.post { _ -> String in
throw HBHTTPError(.badRequest, message: "BadRequest")
}
}
}
let lambda = try HBLambdaHandler<HelloLambda>.makeHandler(context: self.initializationContext).wait()
let context = self.newContext()
let event = try newV2Event(uri: "/", method: "POST")
let response = try lambda.handle(event, context: context).wait()
XCTAssertEqual(response.statusCode, .badRequest)
XCTAssertEqual(response.body, "BadRequest")
}
}

0 comments on commit 2e579de

Please sign in to comment.