From 02feb47626f32308d6bc157bafdd95aa2504dafd Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Sat, 6 Jan 2024 12:17:24 +0100 Subject: [PATCH] Add tests --- .../UUID.swift} | 12 +- .../UUIDTests.swift | 108 ++++++++++++++++++ 2 files changed, 115 insertions(+), 5 deletions(-) rename Sources/HummingbirdFoundation/{Extensions/Parameters+UUID.swift => Utils/UUID.swift} (84%) create mode 100644 Tests/HummingbirdFoundationTests/UUIDTests.swift diff --git a/Sources/HummingbirdFoundation/Extensions/Parameters+UUID.swift b/Sources/HummingbirdFoundation/Utils/UUID.swift similarity index 84% rename from Sources/HummingbirdFoundation/Extensions/Parameters+UUID.swift rename to Sources/HummingbirdFoundation/Utils/UUID.swift index d469a7ad1..5b368897d 100644 --- a/Sources/HummingbirdFoundation/Extensions/Parameters+UUID.swift +++ b/Sources/HummingbirdFoundation/Utils/UUID.swift @@ -17,12 +17,12 @@ import Hummingbird /// It is common for UUID's to be passed in as parameters. So lets add helper /// functions to extract them from HBParameters -public extension HBParameters { +extension HBParameters { /// Return parameter with specified id as a certain type /// - Parameters: /// - s: parameter id /// - as: type we want returned - func get(_ s: String, as: UUID.Type) -> UUID? { + public func get(_ s: String, as: UUID.Type) -> UUID? { return self[s[...]].map { UUID(uuidString: String($0)) } ?? nil } @@ -30,7 +30,7 @@ public extension HBParameters { /// - Parameters: /// - s: parameter id /// - as: type we want returned - func require(_ s: String, as: UUID.Type) throws -> UUID { + public func require(_ s: String, as: UUID.Type) throws -> UUID { guard let param = self[s[...]], let result = UUID(uuidString: String(param)) else { @@ -43,7 +43,7 @@ public extension HBParameters { /// - Parameters: /// - s: parameter id /// - as: type we want returned - func getAll(_ s: String, as: UUID.Type) -> [UUID] { + public func getAll(_ s: String, as: UUID.Type) -> [UUID] { return self[values: s[...]].compactMap { UUID(uuidString: String($0)) } } @@ -51,7 +51,7 @@ public extension HBParameters { /// - Parameters: /// - s: parameter id /// - as: type we want returned - func requireAll(_ s: String, as: UUID.Type) throws -> [UUID] { + public func requireAll(_ s: String, as: UUID.Type) throws -> [UUID] { return try self[values: s[...]].map { guard let result = UUID(uuidString: String($0)) else { throw HBHTTPError(.badRequest) @@ -60,3 +60,5 @@ public extension HBParameters { } } } + +extension UUID: HBResponseEncodable {} diff --git a/Tests/HummingbirdFoundationTests/UUIDTests.swift b/Tests/HummingbirdFoundationTests/UUIDTests.swift new file mode 100644 index 000000000..bea13cf62 --- /dev/null +++ b/Tests/HummingbirdFoundationTests/UUIDTests.swift @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Hummingbird server framework project +// +// Copyright (c) 2024 the Hummingbird authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See hummingbird/CONTRIBUTORS.txt for the list of Hummingbird authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Hummingbird +import HummingbirdFoundation +import Logging +import XCTest + +final class UUIDTests: XCTestCase { + /// Custom request context setting up JSON decoding and encoding + struct JSONRequestContext: HBRequestContext { + // Requirement of `HBRequestContext` + var coreContext: HBCoreRequestContext + + init(allocator: ByteBufferAllocator, logger: Logger) { + self.coreContext = .init( + requestDecoder: JSONDecoder(), + responseEncoder: JSONEncoder(), + allocator: allocator, + logger: logger + ) + } + } + + func testGetUUID() async throws { + let router = HBRouter(context: JSONRequestContext.self) + router.get(":id") { _, context -> UUID? in + return context.parameters.get("id", as: UUID.self) + } + let app = HBApplication(responder: router.buildResponder()) + try await app.test(.router) { client in + let uuid = UUID() + try await client.XCTExecute(uri: "\(uuid)", method: .get) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(response.status, .ok) + XCTAssertEqual(String(buffer: body), "\"\(uuid.uuidString)\"") + } + } + } + + func testRequireUUID() async throws { + let router = HBRouter(context: JSONRequestContext.self) + router.get(":id") { _, context -> UUID in + return try context.parameters.require("id", as: UUID.self) + } + let app = HBApplication(responder: router.buildResponder()) + try await app.test(.router) { client in + let uuid = UUID() + try await client.XCTExecute(uri: "\(uuid)", method: .get) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(response.status, .ok) + XCTAssertEqual(String(buffer: body), "\"\(uuid.uuidString)\"") + } + } + } + + func testGetUUIDs() async throws { + let router = HBRouter(context: JSONRequestContext.self) + router.get { request, _ -> [UUID] in + let queryParameters = request.uri.queryParameters + return queryParameters.getAll("id", as: UUID.self) + } + let app = HBApplication(responder: router.buildResponder()) + try await app.test(.router) { client in + let uuid = UUID() + let uuid2 = UUID() + try await client.XCTExecute(uri: "/?id=\(uuid)&id=\(uuid2)&id=Wrong", method: .get) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(response.status, .ok) + XCTAssertEqual(String(buffer: body), "[\"\(uuid.uuidString)\",\"\(uuid2.uuidString)\"]") + } + } + } + + func testRequireUUIDs() async throws { + let router = HBRouter(context: JSONRequestContext.self) + router.get { request, _ -> [UUID] in + let queryParameters = request.uri.queryParameters + return try queryParameters.requireAll("id", as: UUID.self) + } + let app = HBApplication(responder: router.buildResponder()) + try await app.test(.router) { client in + let uuid = UUID() + let uuid2 = UUID() + // test good request + try await client.XCTExecute(uri: "/?id=\(uuid)&id=\(uuid2)", method: .get) { response in + let body = try XCTUnwrap(response.body) + XCTAssertEqual(response.status, .ok) + XCTAssertEqual(String(buffer: body), "[\"\(uuid.uuidString)\",\"\(uuid2.uuidString)\"]") + } + // test bad request + try await client.XCTExecute(uri: "/?id=\(uuid)&id=\(uuid2)&id=Wrong", method: .get) { response in + XCTAssertEqual(response.status, .badRequest) + } + } + } +}