diff --git a/Sources/VaporWallet/HasWallet.swift b/Sources/VaporWallet/HasWallet.swift index f1313e2..91cde0e 100644 --- a/Sources/VaporWallet/HasWallet.swift +++ b/Sources/VaporWallet/HasWallet.swift @@ -31,7 +31,7 @@ extension Wallet { .query(on: db) .filter(\.$confirmed == true) .sum(\.$amount) - .get() + self.balance = balance ?? 0 try await self.update(on: db) return Double(self.balance) diff --git a/Sources/VaporWallet/Migrations/CreateWalletTransaction.swift b/Sources/VaporWallet/Migrations/CreateWalletTransaction.swift index 8c13d25..6c4843a 100644 --- a/Sources/VaporWallet/Migrations/CreateWalletTransaction.swift +++ b/Sources/VaporWallet/Migrations/CreateWalletTransaction.swift @@ -36,16 +36,19 @@ public struct CreateWalletTransactionAsync: AsyncMigration { public init() { } public func prepare(on database: Database) async throws { - _ = try await database.enum("type") + do { + try await database.enum("transaction_type").delete() + } catch { } + + let transactionType = try await database.enum("transaction_type") .case("deposit") .case("withdraw") .create() - let transactionType = try await database.enum("type").read() try await database.schema(WalletTransaction.schema) .id() .field("wallet_id", .uuid, .required, .references(Wallet.schema, "id", onDelete: .cascade)) - .field("type", transactionType, .required) + .field("transaction_type", transactionType, .required) .field("amount", .int, .required) .field("confirmed", .bool, .required) .field("meta", .json) @@ -56,7 +59,9 @@ public struct CreateWalletTransactionAsync: AsyncMigration { public func revert(on database: Database) async throws { - let _ = try await database.enum("type").delete() + do { + try await database.enum("transaction_type").delete() + } catch { } try await database.schema(WalletTransaction.schema).delete() } diff --git a/Sources/VaporWallet/Models/Entities/WalletTransaction.swift b/Sources/VaporWallet/Models/Entities/WalletTransaction.swift index 854810a..24e69f2 100644 --- a/Sources/VaporWallet/Models/Entities/WalletTransaction.swift +++ b/Sources/VaporWallet/Models/Entities/WalletTransaction.swift @@ -9,13 +9,14 @@ import Vapor import Fluent +enum TransactionType: String, Content { + case deposit, withdraw +} + public final class WalletTransaction: Model { public static let schema = "wallet_transactions" - - enum TransactionType: String, Content { - case deposit, withdraw - } + @ID(key: .id) public var id: UUID? @@ -23,8 +24,8 @@ public final class WalletTransaction: Model { @Parent(key: "wallet_id") var wallet: Wallet - @Enum(key: "type") - var type: TransactionType + @Enum(key: "transaction_type") + var transactionType: TransactionType @Field(key: "amount") var amount: Int @@ -46,7 +47,7 @@ public final class WalletTransaction: Model { init( id: UUID? = nil, walletID: UUID, - type: TransactionType, + transactionType: TransactionType, amount: Int, confirmed: Bool = true, meta: [String: String]? = nil, @@ -55,7 +56,7 @@ public final class WalletTransaction: Model { ) { self.id = id self.$wallet.id = walletID - self.type = type + self.transactionType = transactionType self.amount = amount self.meta = meta self.confirmed = confirmed diff --git a/Tests/VaporWalletTests/VaporWalletTests.swift b/Tests/VaporWalletTests/VaporWalletTests.swift index 8eafb37..d6dde8d 100644 --- a/Tests/VaporWalletTests/VaporWalletTests.swift +++ b/Tests/VaporWalletTests/VaporWalletTests.swift @@ -17,15 +17,15 @@ class VaporWalletTests: XCTestCase { app = Application(.testing) app.logger.logLevel = .debug -// app.databases.use(.postgres( -// hostname: "localhost", -// port: 5432, -// username: "catgpt", -// password: "catgpt", -// database: "catgpt" -// ), as: .psql) - // app.databases.use(.mysql(hostname: "127.0.0.1", port: 3306, username: "vapor", password: "vapor", database: "vp-test"), as: .mysql) - app.databases.use(.sqlite(.file("catgpt-sqlite-db.sqlite")), as: .sqlite) + app.databases.use(.postgres( + hostname: "localhost", + port: 5432, + username: "catgpt", + password: "catgpt", + database: "catgpt" + ), as: .psql) +// app.databases.use(.mysql(hostname: "127.0.0.1", port: 3306, username: "vapor", password: "vapor", database: "vp-test"), as: .mysql) +// app.databases.use(.sqlite(.memory), as: .sqlite) try! migrations(app) try! app.autoRevert().wait() @@ -368,25 +368,57 @@ class VaporWalletTests: XCTestCase { app.databases.middleware.use(AsyncWalletMiddleware()) app.databases.middleware.use(AsyncWalletTransactionMiddleware()) - let user = try await User.create(username: "user1", on: app.db) - let game = Game(id: user.id, name: "game1") - try await game.save(on: app.db) - - let repo1 = user.walletsRepository(on: app.db) - let repo2 = game.walletsRepository(on: app.db) + do { + let user = try await User.create(username: "user1", on: app.db) + let game = Game(id: user.id, name: "game1") + try await game.save(on: app.db) + + let repo1 = user.walletsRepository(on: app.db) + let repo2 = game.walletsRepository(on: app.db) + + try await repo1.depositAsync(amount: 100) + try await repo2.depositAsync(amount: 500) + + let balance1 = try await repo1.balanceAsync() + let balance2 = try await repo2.balanceAsync() + + XCTAssertEqual(balance1, 100) + XCTAssertEqual(balance2, 500) + } catch { + print("error: \(String(reflecting: error))") + } - try await repo1.depositAsync(amount: 100) -// try await repo2.depositAsync(amount: 500) + } -// let userWallet = try await repo1.getAsync(type: .default) -// let gameWallet = try await repo2.getAsync(type: .default) - -// let balance1 = try await repo1.balanceAsync() -// let balance2 = try await repo2.balanceAsync() -// -// XCTAssertEqual(balance1, 100) -// XCTAssertEqual(balance2, 500) + func testMultiModelWalletTransfer() async throws { + app.databases.middleware.use(AsyncWalletMiddleware()) + app.databases.middleware.use(AsyncWalletMiddleware()) + app.databases.middleware.use(AsyncWalletTransactionMiddleware()) + do { + let user = try await User.create(username: "user1", on: app.db) + let game = Game(id: user.id, name: "game1") + try await game.save(on: app.db) + + let repo1 = user.walletsRepository(on: app.db) + let repo2 = game.walletsRepository(on: app.db) + + try await repo1.depositAsync(amount: 100) + try await repo2.depositAsync(amount: 500) + + let userWallet = try await repo1.defaultAsync() + let gameWallet = try await repo2.defaultAsync() + + try await repo1.transferAsync(from: gameWallet, to: userWallet, amount: 100) + + let balance1 = try await repo1.balanceAsync() + let balance2 = try await repo2.balanceAsync() + + XCTAssertEqual(balance1, 200) + XCTAssertEqual(balance2, 400) + } catch { + print("###### error: #########\n\(String(reflecting: error))") + } } @@ -405,7 +437,7 @@ class VaporWalletTests: XCTestCase { app.migrations.add(CreateUser()) app.migrations.add(CreateGame()) app.migrations.add(CreateWallet()) - app.migrations.add(CreateWalletTransaction()) + app.migrations.add(CreateWalletTransactionAsync()) } }