219 lines
6.6 KiB
Swift
219 lines
6.6 KiB
Swift
@testable import DatabaseClientLive
|
|
import Dependencies
|
|
import FluentSQLiteDriver
|
|
import Foundation
|
|
import Logging
|
|
import NIO
|
|
import SharedModels
|
|
import Testing
|
|
|
|
@Suite("DatabaseClientTests")
|
|
struct DatabaseClientTests {
|
|
|
|
let logger: Logger
|
|
|
|
init() async throws {
|
|
let logger = Logger(label: "database-client-tests")
|
|
self.logger = logger
|
|
}
|
|
|
|
@Test
|
|
func users() async throws {
|
|
try await withDatabase(migrations: User.Migrate()) {
|
|
$0.database.users = .live(database: $1)
|
|
} operation: {
|
|
@Dependency(\.database.users) var users
|
|
|
|
let user = try await users.create(.init(
|
|
username: "blob",
|
|
email: "blob@example.com",
|
|
password: "super-secret",
|
|
confirmPassword: "super-secret"
|
|
))
|
|
#expect(user.username == "blob")
|
|
#expect(user.email == "blob@example.com")
|
|
#expect(user.createdAt != nil)
|
|
#expect(user.updatedAt != nil)
|
|
|
|
let allUsers = try await users.fetchAll()
|
|
#expect(allUsers.count == 1)
|
|
#expect(allUsers.first == user)
|
|
|
|
let fetched = try await users.get(user.id)
|
|
#expect(fetched != nil)
|
|
#expect(fetched == user)
|
|
|
|
try await users.delete(user.id)
|
|
let allUsers2 = try await users.fetchAll()
|
|
#expect(allUsers2.count == 0)
|
|
}
|
|
}
|
|
|
|
@Test(arguments: EmployeeTestFactory.testCases)
|
|
func employees(factory: EmployeeTestFactory) async throws {
|
|
try await withDatabase(migrations: Employee.Migrate()) {
|
|
$0.uuid = .incrementing
|
|
$0.date = .init { Date() }
|
|
$0.database.employees = factory.handler($1)
|
|
} operation: {
|
|
@Dependency(\.database.employees) var employees
|
|
|
|
let employee = try await employees.create(.init(
|
|
firstName: "Blob",
|
|
lastName: "Esquire"
|
|
))
|
|
|
|
#expect(employee.firstName == "Blob")
|
|
#expect(employee.lastName == "Esquire")
|
|
#expect(employee.active)
|
|
|
|
let allEmployees = try await employees.fetchAll()
|
|
#expect(allEmployees.count == 1)
|
|
#expect(allEmployees.first == employee)
|
|
|
|
let inActiveEmployees = try await employees.fetchAll(.inactive)
|
|
#expect(inActiveEmployees.count == 0)
|
|
|
|
let activeEmployees = try await employees.fetchAll(.active)
|
|
#expect(activeEmployees == allEmployees)
|
|
|
|
let fetched = try await employees.get(employee.id)
|
|
#expect(fetched == employee)
|
|
|
|
let updated = try await employees.update(employee.id, Employee.Update(active: false))
|
|
#expect(updated.active == false)
|
|
|
|
let inActiveEmployees2 = try await employees.fetchAll(.inactive)
|
|
#expect(inActiveEmployees2.count == 1)
|
|
|
|
try await employees.delete(employee.id)
|
|
|
|
let shouldBeNone = try await employees.fetchAll()
|
|
#expect(shouldBeNone.count == 0)
|
|
}
|
|
}
|
|
|
|
@Test(arguments: VendorTestFactory.testCases)
|
|
func vendors(factory: VendorTestFactory) async throws {
|
|
try await withDatabase(migrations: Vendor.Migrate(), VendorBranch.Migrate()) {
|
|
$0.database.vendorBranches = factory.handler($1).0
|
|
$0.database.vendors = factory.handler($1).1
|
|
} operation: {
|
|
@Dependency(\.database.vendorBranches) var branches
|
|
@Dependency(\.database.vendors) var vendors
|
|
|
|
let vendor = try await vendors.create(.init(name: "Corken"))
|
|
#expect(vendor.name == "Corken")
|
|
|
|
let branch = try await branches.create(.init(name: "Monroe", vendorID: vendor.id))
|
|
#expect(branch.name == "Monroe")
|
|
|
|
let all = try await vendors.fetchAll()
|
|
#expect(all.count == 1)
|
|
#expect(all.first == vendor)
|
|
|
|
let allWithBranches = try await vendors.fetchAll(.withBranches)
|
|
#expect(allWithBranches.count == 1)
|
|
#expect(allWithBranches.first!.branches!.first == branch)
|
|
|
|
let fetched = try await vendors.get(vendor.id)
|
|
#expect(fetched == vendor)
|
|
|
|
let fetchedWithBranches = try await vendors.get(vendor.id, .withBranches)
|
|
#expect(fetchedWithBranches!.branches!.first == branch)
|
|
|
|
let updated = try await vendors.update(vendor.id, with: .init(name: "Johnstone"))
|
|
#expect(updated.name == "Johnstone")
|
|
|
|
try await vendors.delete(vendor.id)
|
|
|
|
let shouldBeNone = try await vendors.fetchAll()
|
|
#expect(shouldBeNone.count == 0)
|
|
}
|
|
}
|
|
|
|
@Test(arguments: VendorTestFactory.testCases)
|
|
func vendorBranches(factory: VendorTestFactory) async throws {
|
|
try await withDatabase(migrations: Vendor.Migrate(), VendorBranch.Migrate()) {
|
|
$0.database.vendorBranches = factory.handler($1).0
|
|
$0.database.vendors = factory.handler($1).1
|
|
} operation: {
|
|
@Dependency(\.database.vendorBranches) var branches
|
|
@Dependency(\.database.vendors) var vendors
|
|
|
|
let vendor = try await vendors.create(.init(name: "Corken"))
|
|
#expect(vendor.name == "Corken")
|
|
|
|
let branch = try await branches.create(.init(name: "Monroe", vendorID: vendor.id))
|
|
#expect(branch.name == "Monroe")
|
|
|
|
let all = try await branches.fetchAll()
|
|
#expect(all.count == 1)
|
|
|
|
let fetched = try await branches.get(branch.id)
|
|
#expect(fetched == branch)
|
|
|
|
let updated = try await branches.update(branch.id, .init(name: "Covington"))
|
|
#expect(updated.name == "Covington")
|
|
|
|
try await branches.delete(branch.id)
|
|
|
|
let shouldBeNone = try await branches.fetchAll()
|
|
#expect(shouldBeNone.count == 0)
|
|
}
|
|
}
|
|
|
|
// Helper to create an in-memory database for testing.
|
|
func withDatabase(
|
|
migrations: (any AsyncMigration)...,
|
|
setupDependencies: (inout DependencyValues, any Database) -> Void,
|
|
operation: () async throws -> Void
|
|
) async throws {
|
|
let dbs = Databases(threadPool: NIOThreadPool.singleton, on: MultiThreadedEventLoopGroup.singleton)
|
|
dbs.use(.sqlite(.memory), as: .sqlite)
|
|
|
|
let database = dbs.database(
|
|
.sqlite,
|
|
logger: .init(label: "test.sqlite"),
|
|
on: MultiThreadedEventLoopGroup.singleton.any()
|
|
)!
|
|
|
|
for migration in migrations {
|
|
try await migration.prepare(on: database)
|
|
}
|
|
|
|
try await withDependencies {
|
|
$0.uuid = .incrementing
|
|
$0.date = .init { Date() }
|
|
setupDependencies(&$0, database)
|
|
} operation: {
|
|
try await operation()
|
|
}
|
|
|
|
for migration in migrations {
|
|
try await migration.revert(on: database)
|
|
}
|
|
|
|
await dbs.shutdownAsync()
|
|
}
|
|
}
|
|
|
|
struct EmployeeTestFactory {
|
|
let handler: (any Database) -> DatabaseClient.Employees
|
|
|
|
static var testCases: [Self] { [
|
|
.init(handler: { .live(database: $0) }),
|
|
.init(handler: { _ in .mock([]) })
|
|
] }
|
|
}
|
|
|
|
struct VendorTestFactory {
|
|
let handler: (any Database) -> (DatabaseClient.VendorBranches, DatabaseClient.Vendors)
|
|
|
|
static var testCases: [Self] { [
|
|
.init(handler: { (.live(database: $0), .live(database: $0)) }),
|
|
.init(handler: { _ in (.mock([]), .mock([])) })
|
|
] }
|
|
|
|
}
|