feat: Adds basic tests for database client.
This commit is contained in:
194
Tests/DatabaseClientTests/DatabaseClientTests.swift
Normal file
194
Tests/DatabaseClientTests/DatabaseClientTests.swift
Normal file
@@ -0,0 +1,194 @@
|
||||
@testable import DatabaseClientLive
|
||||
import Dependencies
|
||||
import FluentSQLiteDriver
|
||||
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
|
||||
func employees() async throws {
|
||||
try await withDatabase(migrations: Employee.Migrate()) {
|
||||
$0.database.employees = .live(database: $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
|
||||
func vendors() async throws {
|
||||
try await withDatabase(migrations: Vendor.Migrate(), VendorBranch.Migrate()) {
|
||||
$0.database.vendors = .live(database: $1)
|
||||
$0.database.vendorBranches = .live(database: $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, .init(name: "Johnstone"))
|
||||
#expect(updated.name == "Johnstone")
|
||||
|
||||
try await vendors.delete(vendor.id)
|
||||
|
||||
let shouldBeNone = try await vendors.fetchAll()
|
||||
#expect(shouldBeNone.count == 0)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func vendorBranches() async throws {
|
||||
try await withDatabase(migrations: Vendor.Migrate(), VendorBranch.Migrate()) {
|
||||
$0.database.vendors = .live(database: $1)
|
||||
$0.database.vendorBranches = .live(database: $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 {
|
||||
setupDependencies(&$0, database)
|
||||
} operation: {
|
||||
try await operation()
|
||||
}
|
||||
|
||||
for migration in migrations {
|
||||
try await migration.revert(on: database)
|
||||
}
|
||||
|
||||
await dbs.shutdownAsync()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user