From 2590cb457f0640b96813bdd22434b1fb7cb46e23 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Mon, 22 Sep 2025 18:01:16 +0200 Subject: [PATCH] Implemented the CheckURIUseCase use case type in the library target. --- .../Extensions/String+Constants.swift | 20 +++ .../Internal/Use Cases/CheckURIUseCase.swift | 35 ++++++ .../Use Cases/CheckURIUseCaseTests.swift | 116 ++++++++++++++++++ .../Types/Extensions/Tag+Constants.swift | 2 + 4 files changed, 173 insertions(+) create mode 100644 Sources/DocCMiddleware/Internal/Extensions/String+Constants.swift create mode 100644 Sources/DocCMiddleware/Internal/Use Cases/CheckURIUseCase.swift create mode 100644 Tests/DocCMiddleware/Tests/Internal/Use Cases/CheckURIUseCaseTests.swift diff --git a/Sources/DocCMiddleware/Internal/Extensions/String+Constants.swift b/Sources/DocCMiddleware/Internal/Extensions/String+Constants.swift new file mode 100644 index 0000000..267dab8 --- /dev/null +++ b/Sources/DocCMiddleware/Internal/Extensions/String+Constants.swift @@ -0,0 +1,20 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +extension String { + /// An empty string. + static let empty = "" + /// A forwarding slash. + static let forwardSlash = "/" + /// An indication of a previous folder in a path component. + static let previousFolder = ".." +} diff --git a/Sources/DocCMiddleware/Internal/Use Cases/CheckURIUseCase.swift b/Sources/DocCMiddleware/Internal/Use Cases/CheckURIUseCase.swift new file mode 100644 index 0000000..ad6b9fb --- /dev/null +++ b/Sources/DocCMiddleware/Internal/Use Cases/CheckURIUseCase.swift @@ -0,0 +1,35 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import struct HummingbirdCore.URI + +/// A use case that checks whether a given URI against a set of conditions, to determine whether the URI could be used by the middleware or not. +struct CheckURIUseCase { + + // MARK: Functions + + /// Checks whether a provided URI against a set of conditions, so it could be used by the middleware. + /// - Parameter uri: A URI to check. + /// - Returns: A non-encoded URI, which is ready to be used by the middleware. + func callAsFunction(_ uri: URI) -> String? { + guard + let uriPath = uri.path.removingPercentEncoding, + !uriPath.contains(.previousFolder), + uriPath.hasPrefix(.forwardSlash) + else { + return nil + } + + return uriPath + } + +} diff --git a/Tests/DocCMiddleware/Tests/Internal/Use Cases/CheckURIUseCaseTests.swift b/Tests/DocCMiddleware/Tests/Internal/Use Cases/CheckURIUseCaseTests.swift new file mode 100644 index 0000000..fc3c5c7 --- /dev/null +++ b/Tests/DocCMiddleware/Tests/Internal/Use Cases/CheckURIUseCaseTests.swift @@ -0,0 +1,116 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the Hummingbird DocC Middleware open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the Hummingbird DocC Middleware project authors +// Licensed under the EUPL 1.2 or later. +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of Hummingbird DocC Middleware project authors +// +// ===----------------------------------------------------------------------=== + +import Testing + +import struct HummingbirdCore.URI + +@testable import struct DocCMiddleware.CheckURIUseCase + +@Suite("Check URI use case", .tags(.useCase)) +struct CheckURIUseCaseTests { + + // MARK: Properties + + private let useCase: CheckURIUseCase = .init() + + // MARK: Use case tests + +#if swift(>=6.2) + @Test(arguments: zip( + Input.nonEncodedURIs, + Output.nonEncodedURIs + )) + func `check non encoded URIs`( + uri uriPath: String, + expects result: String? + ) { + assertURI(uriPath, expects: result) + } + + @Test(arguments: zip( + Input.percentEncodedURIs, + Output.percentEncodedURIs + )) + func `check percent-encoded URIs`( + uri uriPath: String, + expects result: String? + ) { + assertURI(uriPath, expects: result) + } +#else + @Test("check non-encoded URIs", arguments: zip( + Input.nonEncodedURIs, + Output.nonEncodedURIs + )) + func checkNonEncodedURIs( + uri uriPath: String, + expects result: String? + ) { + assertURI(uriPath, expects: result) + } + + @Test("check percent-encoded URIs", arguments: zip( + Input.percentEncodedURIs, + Output.percentEncodedURIs + )) + func checkPercentEncodedURIs( + uri uriPath: String, + expects result: String? + ) { + assertURI(uriPath, expects: result) + } +#endif + +} + +// MARK: - Assertions + +private extension CheckURIUseCaseTests { + + // MARK: Functions + + /// Asserts a URI type based on a given path and an expected result. + /// - Parameters: + /// - uriPath: A URI path to use with a URI type. + /// - result: An expected result coming out of the use case. + func assertURI( + _ uriPath: String, + expects result: String? + ) { + // GIVEN + let uri = URI(uriPath) + + // WHEN + let output = useCase(uri) + + // THEN + #expect(output == result) + } + +} + +// MARK: - Constants + +enum Input { + /// A list of non-encoded URI samples. + static let nonEncodedURIs: [String] = ["/", "/some/known/path", "", "/some/../path", "some/other/path"] + /// A list of percent-encoded URI samples. + static let percentEncodedURIs: [String] = ["%2F", "/some%2Fknown%3Fpath", "%20", "/some/%2E%2E/path", "some%2Fother%3Fpath"] +} + +enum Output { + /// A list of expected outputs for the non-encoded URI samples. + static let nonEncodedURIs: [String?] = ["/", "/some/known/path", "/", nil, nil] + /// A list of expected outputs for the percent-encoded URI samples. + static let percentEncodedURIs: [String?] = ["/", "/some/known?path", nil, nil, nil] +} diff --git a/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift index d180d37..7c6b32f 100644 --- a/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift +++ b/Tests/DocCMiddleware/Types/Extensions/Tag+Constants.swift @@ -18,5 +18,7 @@ extension Tag { /// Tag that indicate a test case for a type initialization. @Tag static var initializer: Self + /// Tag that indicate a test case for a use case type. + @Tag static var useCase: Self }