Files
vapor-po/Sources/DatabaseClient/Users.swift

94 lines
2.5 KiB
Swift

import Dependencies
import DependenciesMacros
import Foundation
import SharedModels
import Vapor
public extension DatabaseClient {
@DependencyClient
struct Users: Sendable {
public var count: @Sendable () async throws -> Int
public var create: @Sendable (User.Create) async throws -> User
public var delete: @Sendable (User.ID) async throws -> Void
public var fetchAll: @Sendable () async throws -> [User]
public var get: @Sendable (User.ID) async throws -> User?
public var login: @Sendable (User.Login) async throws -> User.Token
public var logout: @Sendable (User.Token.ID) async throws -> Void
public var token: @Sendable (User.ID) async throws -> User.Token
public var update: @Sendable (User.ID, User.Update) async throws -> User
}
}
extension User: Content {}
extension User.Create: Content {}
extension User.Token: Content {}
extension User.Update: Content {}
extension DatabaseClient.Users: TestDependencyKey {
public static let testValue: DatabaseClient.Users = Self()
}
#if DEBUG
typealias UserMockStorage = MockStorage<
User,
User.Create,
Void,
Void,
User.Update
>
private extension UserMockStorage {
static func make(_ mocks: [User]) -> Self {
@Dependency(\.date.now) var now
@Dependency(\.uuid) var uuid
return .init(
create: { model in
User(
id: uuid(),
email: model.email,
username: model.username,
createdAt: now,
updatedAt: now
)
},
update: { model, updates in
let user = User(
id: model.id,
email: updates.email ?? model.email,
username: updates.username ?? model.username,
createdAt: model.createdAt,
updatedAt: now
)
model = user
}
)
}
}
public extension User.Token {
static func mock(id: User.ID) -> Self {
.init(id: UUID(0), userID: id, value: "test")
}
}
public extension DatabaseClient.Users {
static func mock(_ mocks: [User]) -> Self {
let storage = UserMockStorage.make(mocks)
return .init(
count: { try await storage.count() },
create: { try await storage.create($0) },
delete: { try await storage.delete($0) },
fetchAll: { try await storage.fetchAll() },
get: { try await storage.get($0) },
login: { _ in .mock(id: UUID(0)) },
logout: { _ in },
token: { .mock(id: $0) },
update: { try await storage.update($0, $1) }
)
}
}
#endif