diff --git a/Sources/DiscogsService/Internal/Use Cases/ValidateInputUseCase.swift b/Sources/DiscogsService/Internal/Use Cases/ValidateInputUseCase.swift new file mode 100644 index 000000000..85186c92d --- /dev/null +++ b/Sources/DiscogsService/Internal/Use Cases/ValidateInputUseCase.swift @@ -0,0 +1,53 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the DiscogsService open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors +// Licensed under Apache license v2.0 +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of DiscogsService project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +// ===----------------------------------------------------------------------=== + +/// A use case that validates an input against a set of validation rules. +struct ValidateInputUseCase { + + // MARK: Properties + + /// A list of validation rules to match an input against. + private let rules: [any InputValidationRule] + + // MARK: Initializers + + /// Initializes this use case. + /// - Parameter rules: A list of validation rules to match an input against. + init(rules: any InputValidationRule...) { + self.rules = rules + } + + // MARK: Functions + +#if swift(>=6.0) + /// Validates an input against a set of validation rules. + /// - Parameter input: An input to be validated against a set of rules, if any. + /// - Throws: An error of type ``InputValidationError`` in case an input failed any validation. + func callAsFunction(_ input: String?) throws(InputValidationError) { + for rule in rules { + try rule.validate(input) + } + } +#else + /// Validates an input against a set of validation rules. + /// - Parameter input: An input to be validated against a set of rules, if any. + /// - Throws: An error of type ``InputValidationError`` in case an input failed any validation. + func callAsFunction(_ input: String?) throws { + for rule in rules { + try rule.validate(input) + } + } +#endif + +} diff --git a/Tests/DiscogsService/Cases/Internal/Use Cases/ValidateInputUesCaseTests.swift b/Tests/DiscogsService/Cases/Internal/Use Cases/ValidateInputUesCaseTests.swift new file mode 100644 index 000000000..631fd12ff --- /dev/null +++ b/Tests/DiscogsService/Cases/Internal/Use Cases/ValidateInputUesCaseTests.swift @@ -0,0 +1,97 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the DiscogsService open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors +// Licensed under Apache license v2.0 +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of DiscogsService project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +// ===----------------------------------------------------------------------=== + +import Testing + +@testable import DiscogsService + +@Suite("Validate Input Use Cases") +struct ValidateInputUseCaseTests { + + // MARK: Functions + +#if swift(>=6.2) + @Test(arguments: zip( + Input.inputsToValidate, + Output.inputsToValidate + )) func `validate`( + input: String?, + expects error: InputValidationError? + ) async throws { + try assertValidate( + input: input, + expects: error + ) + } +#else + @Test("validate", arguments: zip( + Input.inputsToValidate, + Output.inputsToValidate + )) func validate( + input: String?, + expects error: InputValidationError? + ) async throws { + try assertValidate( + input: input, + expects: error + ) + } +#endif + +} + +// MARK: - Assertions + +private extension ValidateInputUseCaseTests { + + // MARK: Functions + + /// Asserts an input validation of a ``ValidateInputUseCase`` use case. + /// - Parameters: + /// - input: An input to validate, if any. + /// - error: An expected error, if any. + /// - Throws: An error of type ``InputValidationError`` in case of an unexpected test case scenario. + func assertValidate( + input: String?, + expects error: InputValidationError? + ) throws { + // GIVEN + let validate = ValidateInputUseCase(rules: .notNil, .notEmpty) + + // WHEN + // THEN + if let error { + #expect(throws: error) { + try validate(input) + } + } else { + #expect(throws: Never.self) { + try validate(input) + } + } + } + +} + +// MARK: - Constants + +private extension Input { + /// A list of inputs to validate against a set of validation rules. + static let inputsToValidate: [String?] = [nil, .empty, "SomeInput"] +} + +private extension Output { + /// A list of expected input validation errors to be thrown (if necessary). + static let inputsToValidate: [InputValidationError?] = [.inputIsNil, .inputIsEmpty, nil] +} diff --git a/Tests/DiscogsService/Cases/Public/Middlewares/UserAgentMiddlewareTests.swift b/Tests/DiscogsService/Cases/Public/Middlewares/UserAgentMiddlewareTests.swift new file mode 100644 index 000000000..a4c0b9a47 --- /dev/null +++ b/Tests/DiscogsService/Cases/Public/Middlewares/UserAgentMiddlewareTests.swift @@ -0,0 +1,25 @@ +// ===----------------------------------------------------------------------=== +// +// This source file is part of the DiscogsService open source project +// +// Copyright (c) 2025 Röck+Cöde VoF. and the DiscogsService project authors +// Licensed under Apache license v2.0 +// +// See LICENSE for license information +// See CONTRIBUTORS for the list of DiscogsService project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +// ===----------------------------------------------------------------------=== + +import DiscogsService +import Testing + +@Suite("User Agent Middleware", .tags(.middleware)) +struct UserAgentMiddlewareTests { + +// @Test func <#test function name#>() async throws { +// // Write your test here and use APIs like `#expect(...)` to check expected conditions. +// } + +}