Skip to content

Commit

Permalink
prevent to create wallets with duplicate name for same user
Browse files Browse the repository at this point in the history
  • Loading branch information
hsharghi committed Aug 16, 2023
1 parent 0ea427d commit 333a639
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 6 deletions.
9 changes: 7 additions & 2 deletions Sources/VaporWallet/Errors/WalletErrors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Vapor

enum WalletError: DebuggableError {
case walletNotFound(name: String)
case duplicateWalletType(name: String)
case insufficientBalance
case invalidTransaction(reason: String)
case transactionFailed(reason: String)
Expand All @@ -13,10 +14,10 @@ extension WalletError: AbortError {
case .walletNotFound(_):
return .notFound
case .insufficientBalance,
.transactionFailed(_),
.duplicateWalletType(_),
.invalidTransaction(_):
return .badRequest
case .transactionFailed(_):
return .badRequest
}
}

Expand All @@ -28,6 +29,8 @@ extension WalletError: AbortError {
return "Insufficient balance"
case .transactionFailed(let reason):
return "Transaction failed. Reason: \(reason)"
case .duplicateWalletType(let name):
return "Duplicate wallet type. Wallet type `\(name)` allready exists."
case .invalidTransaction(reason: let reason):
return "Transaction failed. Reason: \(reason)"
}
Expand All @@ -41,6 +44,8 @@ extension WalletError: AbortError {
return "insufficient_balance"
case .transactionFailed(_):
return "transaction_failed"
case .duplicateWalletType(_):
return "duplicate_wallet"
case .invalidTransaction(_):
return "invalid_transaction"
}
Expand Down
11 changes: 8 additions & 3 deletions Sources/VaporWallet/WalletRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ extension WalletsRepository {
}

public func create(type name: WalletType = .default, decimalPlaces: UInt8 = 2, minAllowedBalance: Int = 0) async throws {
guard try await Wallet.query(on: db)
.filter(\.$ownerType == self.type)
.filter(\.$owner == self.id)
.filter(\.$name == name.value)
.count() == 0 else {
throw WalletError.duplicateWalletType(name: name.value)
}
let wallet: Wallet = Wallet(ownerType: self.type,
ownerID: self.id,
name: name.value,
Expand All @@ -65,9 +72,7 @@ extension WalletsRepository {
if (withTransactions) {
walletQuery = walletQuery.with(\.$transactions)
}
let wallet = try await walletQuery.first()

guard let wallet = wallet else {
guard let wallet = try await walletQuery.first() else {
throw WalletError.walletNotFound(name: name.value)
}
return wallet
Expand Down
9 changes: 8 additions & 1 deletion Tests/VaporWalletTests/VaporWalletTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ class VaporWalletTests: XCTestCase {

}

func testCreateWalletWithDuplicateName() async throws {
let (_, wallets) = try await setupUserAndWalletsRepo(on: app.db)
try await wallets.create(type: .init(name: "savings"))
await XCTAssertThrowsError(try await wallets.create(type: .init(name: "savings")), "expected throw") { (error) in
XCTAssertEqual(error as! WalletError, WalletError.duplicateWalletType(name: "savings"))
}
}

func testWalletDeposit() async throws {
app.databases.middleware.use(WalletMiddleware<User>())
let (_, wallets) = try await setupUserAndWalletsRepo(on: app.db)
Expand Down Expand Up @@ -187,7 +195,6 @@ class VaporWalletTests: XCTestCase {
balance = try await wallets.balance(type: magical)
XCTAssertEqual(balance, 0)

try await wallets.create(type: magical, minAllowedBalance: -50)
try await wallets.deposit(to: magical, amount: 100)
try await wallets.empty(magical, strategy: .toMinAllowed)
balance = try await wallets.balance(type: magical)
Expand Down

0 comments on commit 333a639

Please sign in to comment.