Implemented the GenerateHashUseCase use case in the library target.

This commit is contained in:
2025-10-03 21:28:34 +02:00
parent 30a49353e8
commit 25dd2fc789
3 changed files with 168 additions and 0 deletions
@@ -0,0 +1,60 @@
//===----------------------------------------------------------------------===
//
// This source file is part of the MarvelService open source project
//
// Copyright (c) -2025 Röck+Cöde VoF. and the MarvelService project authors
// Licensed under the EUPL 1.2 or later.
//
// See LICENSE for license information
// See CONTRIBUTORS for the list of MarvelService project authors
//
//===----------------------------------------------------------------------===
import CryptoKit
import struct Foundation.Data
import struct Foundation.TimeInterval
/// A use case that generates a MD5 hash value, which is required to authenticate any request.
struct GenerateHashUseCase {
// MARK: Properties
/// A private key.
private let privateKey: String
/// A public key.
private let publicKey: String
// MARK: Initializers
/// Initializes this use case.
/// - Parameters:
/// - privateKey: A private key.
/// - publicKey: A public key.
init(
privateKey: String,
publicKey: String,
) {
self.privateKey = privateKey
self.publicKey = publicKey
}
// MARK: Functions
/// Generates a MD5 hash value out of a given public key, private key and a timestamp.
/// - Parameter timestamp: A timestamp that changes on a request-by-request basis.
/// - Returns: A MD5 hash generated out of a private key, an public key, and a timestamp.
func callAsFunction(
timestamp: TimeInterval
) -> String {
let stringToHash = timestamp.asString + self.privateKey + self.publicKey
let dataToHash = Data(stringToHash.utf8)
return Insecure.MD5
.hash(data: dataToHash)
.map { String(format: "%02x", $0) }
.joined()
}
}
@@ -0,0 +1,105 @@
//===----------------------------------------------------------------------===
//
// This source file is part of the MarvelService open source project
//
// Copyright (c) 2025 Röck+Cöde VoF. and the MarvelService project authors
// Licensed under the EUPL 1.2 or later.
//
// See LICENSE for license information
// See CONTRIBUTORS for the list of MarvelService project authors
//
//===----------------------------------------------------------------------===
import Testing
import struct Foundation.TimeInterval
@testable import struct MarvelService.GenerateHashUseCase
@Suite("Generate Hash Use Case", .tags(.useCase))
struct GenerateHashUseCaseTests {
// MARK: Functions
#if swift(>=6.2)
@Test(arguments: zip(
Input.timestamps,
Output.generatedHashes
))
func `hash`(
timestamp: TimeInterval,
expects hash: String
) async throws {
assertHash(
timestamp: timestamp,
expects: hash
)
}
#else
@Test("hash", arguments: zip(
Input.timestamps,
Output.generatedHashes
))
func hash(
timestamp: TimeInterval,
expects hash: String
) async throws {
assertHash(
timestamp: timestamp,
expects: hash
)
}
#endif
}
// MARK: - Assertions
private extension GenerateHashUseCaseTests {
// MARK: Functions
/// Asserts the MD5 hash generated from the use case.
/// - Parameters:
/// - timestamp: A timestamp to use in the hash generation.
/// - hash: An expected MD5 hash string as a result of the use case.
func assertHash(
timestamp: TimeInterval,
expects hash: String
) {
// GIVEN
let useCase: GenerateHashUseCase = .init(
privateKey: .Key.private,
publicKey: .Key.public
)
// WHEN
let result = useCase(timestamp: timestamp)
// THEN
#expect(result == hash)
}
}
// MARK: - Constants
private extension Output {
/// A list of outcomes that are expected from the hash generation.
static let generatedHashes: [String] = [
"ef9ca6f930e56fb4f8a109a9003580fe",
"b500748e9f0aabc67ffc640ae9b87695",
"b537f18579112902b7ce046dddad558a",
"00fec88a254d42e3a439d49e14cd60d1"
]
}
private extension String {
/// A namespace assigned for Marvel API key samples.
enum Key {
/// A Marvel API private key sample.
static let `private` = "SomePrivateKey"
/// A Marvel API public key sample.
static let `public` = "SomePublicKey"
}
}
@@ -18,4 +18,7 @@ extension Tag {
/// A flag that indicates tests for a type extension.
@Tag static var `extension`: Self
/// A flag that indicates tests for a use case type.
@Tag static var useCase: Self
}