I noticed that the username, something that’s often considered unique, is never checked for uniqueness. This might be eventually described and fixed in the section regarding authentication once it comes out, so apologies if I’m skipping ahead, but for those interested, here’s how you can implement that yourself even now.
In the Models/User.swift
, remove automatic conformance to the Migration
protocol and instead implement it yourself, like this:
extension User: Migration {
static func prepare(on connection: PostgreSQLConnection) -> Future<Void> {
return Database.create(self, on: connection) { builder in
try addProperties(to: builder)
try builder.addIndex(to: \.username, isUnique: true)
}
}
}
Revert the database to drop the users
table and re-create it again – except this time username
should be checked for uniqueness on a database level.
Once you try re-running your tests, however, you’ll find a lot of them suddenly failing. That’s happening because the User.create
helper method located in the AppTests/Models+Testable.swift
file happily creates new user anytime it’s called, and it’s called often, creating duplicate users. You can modify it like this:
extension User {
static func create(name: String = "Luke", username: String = "lukes", on connection: PostgreSQLConnection) throws -> User {
// Required due to the added UNIQUE constraint
if let existing = try User.query(on: connection).filter(\.username == username).first().wait() {
return existing
}
let user = User(name: name, username: username)
return try user.save(on: connection).wait()
}
}
And now your tests should be passing again.