diff --git a/Sources/DatabaseClient/MockStorage.swift b/Sources/DatabaseClient/MockStorage.swift index 32d1622..f2782a8 100644 --- a/Sources/DatabaseClient/MockStorage.swift +++ b/Sources/DatabaseClient/MockStorage.swift @@ -14,7 +14,7 @@ private var storage: [Model.ID: Model] - private let modelFromCreate: @Sendable (Create) -> Model + private let modelFromCreate: @Sendable (Create) async throws -> Model private let fetchToPredicate: @Sendable (Fetch) -> ((Model) -> Bool) private let fetchExtras: @Sendable (Fetch, [Model]) async throws -> [Model] private let applyUpdates: @Sendable (inout Model, Update, Get?) async throws -> Void @@ -22,7 +22,7 @@ init( _ mocks: [Model] = [], - create modelFromCreate: @Sendable @escaping (Create) -> Model, + create modelFromCreate: @Sendable @escaping (Create) async throws -> Model, fetch fetchToPredicate: @Sendable @escaping (Fetch) -> ((Model) -> Bool), fetchExtras: @Sendable @escaping (Fetch, [Model]) async throws -> [Model] = { $1 }, get getExtras: @Sendable @escaping (Get?, Model) async throws -> Model, @@ -41,7 +41,7 @@ } func create(_ create: Create) async throws -> Model { - let model = modelFromCreate(create) + let model = try await modelFromCreate(create) storage[model.id] = model return model } @@ -75,7 +75,7 @@ extension MockStorage where Get == Void { init( _ mocks: [Model] = [], - create modelFromCreate: @Sendable @escaping (Create) -> Model, + create modelFromCreate: @Sendable @escaping (Create) async throws -> Model, fetch fetchToPredicate: @Sendable @escaping (Fetch) -> ((Model) -> Bool), fetchExtras: @Sendable @escaping (Fetch, [Model]) async throws -> [Model] = { $1 }, update applyUpdates: @Sendable @escaping (inout Model, Update) async throws -> Void @@ -103,7 +103,7 @@ extension MockStorage where Fetch == Void { init( _ mocks: [Model] = [], - create modelFromCreate: @Sendable @escaping (Create) -> Model, + create modelFromCreate: @Sendable @escaping (Create) async throws -> Model, fetchExtras: @Sendable @escaping (Fetch, [Model]) async throws -> [Model] = { $1 }, get getExtras: @Sendable @escaping (Get?, Model) async throws -> Model, update applyUpdates: @Sendable @escaping (inout Model, Update, Get?) async throws -> Void @@ -126,7 +126,7 @@ extension MockStorage where Fetch == Void, Get == Void { init( _ mocks: [Model] = [], - create modelFromCreate: @Sendable @escaping (Create) -> Model, + create modelFromCreate: @Sendable @escaping (Create) async throws -> Model, fetchExtras: @Sendable @escaping (Fetch, [Model]) async throws -> [Model] = { $1 }, update applyUpdates: @Sendable @escaping (inout Model, Update) async throws -> Void ) { @@ -138,6 +138,5 @@ update: { model, updates, _ in try await applyUpdates(&model, updates) } ) } - } #endif diff --git a/Sources/DatabaseClient/PurchaseOrders.swift b/Sources/DatabaseClient/PurchaseOrders.swift index 9381372..212d3f1 100644 --- a/Sources/DatabaseClient/PurchaseOrders.swift +++ b/Sources/DatabaseClient/PurchaseOrders.swift @@ -22,3 +22,74 @@ extension PurchaseOrder.Create: Content {} extension DatabaseClient.PurchaseOrders: TestDependencyKey { public static let testValue: DatabaseClient.PurchaseOrders = Self() } + +#if DEBUG + typealias PurchaseOrderMockStorage = MockStorage< + PurchaseOrder, + PurchaseOrder.Create, + Void, + Void, + Void + > + + public extension DependencyValues { + var purchaseOrderID: PurchaseOrderIDGenerator { + get { self[PurchaseOrderIDGenerator.self] } + set { self[PurchaseOrderIDGenerator.self] = newValue } + } + } + + @DependencyClient + public struct PurchaseOrderIDGenerator: Sendable { + var nextID: @Sendable () async throws -> Int + } + + extension PurchaseOrderIDGenerator: DependencyKey { + public static let testValue: PurchaseOrderIDGenerator = .liveValue + + public static var liveValue: Self { + let counter = Counter() + return .init(nextID: { await counter.nextID() }) + } + + actor Counter { + private var count: Int + + init(starting: Int = 1) { + self.count = starting + } + + func nextID() async -> Int { + count += 1 + return count + } + } + } + + // private extension PurchaseOrderMockStorage { + // static func make(_ mocks: [PurchaseOrder]) -> Self { + // @Dependency(\.date.now) var now + // @Dependency(\.purchaseOrderID) var purchaseOrderID + // + // return .init( + // mocks, + // create: { model in + // try await PurchaseOrder( + // id: purchaseOrderID.nextID(), + // workOrder: model.workOrder, + // materials: model.materials, + // customer: model.customer, + // truckStock: model.truckStock, + // createdBy: model.createdForID, + // createdFor: model.createdForID, + // vendorBranch: .i + // + // ) + // }, + // update: { _, _ in + // fatalError() + // } + // ) + // } + // } +#endif diff --git a/Sources/DatabaseClient/Users.swift b/Sources/DatabaseClient/Users.swift index 242feff..c49ae0e 100644 --- a/Sources/DatabaseClient/Users.swift +++ b/Sources/DatabaseClient/Users.swift @@ -28,3 +28,66 @@ 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 diff --git a/Sources/SharedModels/PurchaseOrder.swift b/Sources/SharedModels/PurchaseOrder.swift index 686835d..fca5fc6 100644 --- a/Sources/SharedModels/PurchaseOrder.swift +++ b/Sources/SharedModels/PurchaseOrder.swift @@ -40,6 +40,8 @@ public struct PurchaseOrder: Codable, Equatable, Identifiable, Sendable { } public extension PurchaseOrder { + + // TODO: Add created by id. struct Create: Codable, Sendable { public let id: Int?