import Dependencies import DependenciesMacros import SharedModels import Vapor public extension DatabaseClient { @DependencyClient struct Employees: Sendable { public var create: @Sendable (Employee.Create) async throws -> Employee public var delete: @Sendable (Employee.ID) async throws -> Void public var fetchAll: @Sendable (FetchRequest) async throws -> [Employee] public var get: @Sendable (Employee.ID) async throws -> Employee? public var update: @Sendable (Employee.ID, Employee.Update) async throws -> Employee public func fetchAll() async throws -> [Employee] { try await fetchAll(.all) } public enum FetchRequest: String, Content { case active case all case inactive } } } extension Employee: Content {} extension Employee.Create: Content {} extension Employee.Update: Content {} extension DatabaseClient.Employees: TestDependencyKey { public static let testValue = Self() } #if DEBUG typealias EmployeeMockStorage = MockStorage< Employee, Employee.Create, DatabaseClient.Employees.FetchRequest, Void, Employee.Update > private extension EmployeeMockStorage { init(_ mocks: [Employee]) { @Dependency(\.date.now) var now @Dependency(\.uuid) var uuid self.init( mocks, create: { employee in Employee( id: uuid(), active: employee.active ?? true, createdAt: now, firstName: employee.firstName, lastName: employee.lastName, updatedAt: now ) }, fetch: { request in switch request { case .all: return { _ in true } case .active: return { $0.active == true } case .inactive: return { $0.active == false } } }, update: { employee, updates in let model = Employee( id: employee.id, active: updates.active ?? employee.active, createdAt: employee.createdAt, firstName: updates.firstName ?? employee.firstName, lastName: updates.lastName ?? employee.lastName, updatedAt: now ) employee = model } ) } } public extension DatabaseClient.Employees { static func mock(_ mocks: [Employee] = []) -> Self { let storage = EmployeeMockStorage(mocks) return .init( create: { try await storage.create($0) }, delete: { try await storage.delete($0) }, fetchAll: { try await storage.fetchAll($0) }, get: { try await storage.get($0) }, update: { try await storage.update($0, $1) } ) } } #endif