libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 6f774b6f5a19b2f46efc0fff1168714b77b56958
parent 0a3956ee07af2d66b1f726198b2dd8def187b372
Author: MS <ms@taler.net>
Date:   Mon, 18 Sep 2023 13:56:39 +0200

Testing GET /accounts/{USERNAME}

Diffstat:
Mbank/src/main/kotlin/tech/libeufin/bank/Database.kt | 7+++++--
Mbank/src/main/kotlin/tech/libeufin/bank/accountsMgmtHandlers.kt | 4++--
Mbank/src/main/kotlin/tech/libeufin/bank/types.kt | 11++++++++---
Mbank/src/test/kotlin/Common.kt | 1+
Mbank/src/test/kotlin/LibeuFinApiTest.kt | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt @@ -188,8 +188,7 @@ class Database(private val dbConfig: String) { email, phone, cashout_payto, - cashout_currency, - has_debit + cashout_currency FROM customers WHERE login=? """) @@ -268,6 +267,10 @@ class Database(private val dbConfig: String) { // Returns false on conflicts. fun bankAccountCreate(bankAccount: BankAccount): Boolean { reconnect() + if (bankAccount.balance != null) + throw internalServerError( + "Do not pass a balance upon bank account creation, do a wire transfer instead." + ) // FIXME: likely to be changed to only do internal_payto_uri val stmt = prepare(""" INSERT INTO bank_accounts diff --git a/bank/src/main/kotlin/tech/libeufin/bank/accountsMgmtHandlers.kt b/bank/src/main/kotlin/tech/libeufin/bank/accountsMgmtHandlers.kt @@ -126,8 +126,8 @@ fun Routing.accountsMgmtHandlers() { val bankAccountData = db.bankAccountGetFromOwnerId(customerInternalId) ?: throw internalServerError("Customer '${c.login} had no bank account despite they are customer.'") call.respond(AccountData( name = customerData.name, - balance = bankAccountData.balance, - debit_threshold = bankAccountData.maxDebt, + balance = bankAccountData.balance.toString(), + debit_threshold = bankAccountData.maxDebt.toString(), payto_uri = bankAccountData.internalPaytoUri, contact_data = ChallengeContactData( email = customerData.email, diff --git a/bank/src/main/kotlin/tech/libeufin/bank/types.kt b/bank/src/main/kotlin/tech/libeufin/bank/types.kt @@ -172,6 +172,10 @@ class TalerAmount( other.frac == this.frac && other.currency == this.currency } + + override fun toString(): String { + return "$currency:$value.$frac" + } } /** @@ -196,7 +200,7 @@ data class BankAccount( * being wired by wallet owners. */ val lastNexusFetchRowId: Long = 0L, - val balance: TalerAmount, + val balance: TalerAmount? = null, // null when a new bank account gets created. val hasDebt: Boolean, val maxDebt: TalerAmount ) @@ -340,11 +344,12 @@ data class Config( ) // GET /accounts/$USERNAME response. +@Serializable data class AccountData( val name: String, - val balance: TalerAmount, + val balance: String, val payto_uri: String, - val debit_threshold: TalerAmount, + val debit_threshold: String, val contact_data: ChallengeContactData? = null, val cashout_payto_uri: String? = null, val has_debit: Boolean diff --git a/bank/src/test/kotlin/Common.kt b/bank/src/test/kotlin/Common.kt @@ -20,6 +20,7 @@ import tech.libeufin.bank.Database import tech.libeufin.util.execCommand +// Init the database and sets the currency to KUDOS. fun initDb(): Database { System.setProperty( "BANK_DB_CONNECTION_STRING", diff --git a/bank/src/test/kotlin/LibeuFinApiTest.kt b/bank/src/test/kotlin/LibeuFinApiTest.kt @@ -4,6 +4,7 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.testing.* +import kotlinx.serialization.json.Json import net.taler.wallet.crypto.Base32Crockford import org.junit.Test import tech.libeufin.bank.* @@ -62,6 +63,57 @@ class LibeuFinApiTest { } } } + + /** + * Testing the retrieval of account information. + * The tested logic is the one usually needed by SPAs + * to show customers their status. + */ + @Test + fun getAccountTest() { + // Artificially insert a customer and bank account in the database. + val db = initDb() + val customerRowId = db.customerCreate(Customer( + "foo", + CryptoUtil.hashpw("pw"), + "Foo" + )) + assert(customerRowId != null) + assert(db.bankAccountCreate( + BankAccount( + hasDebt = false, + internalPaytoUri = "payto://iban/SANDBOXX/FOO-IBAN", + maxDebt = TalerAmount(100, 0), + owningCustomerId = customerRowId!! + ) + )) + testApplication { + application(webApp) + val r = client.get("/accounts/foo") { + expectSuccess = true + basicAuth("foo", "pw") + } + val obj: AccountData = Json.decodeFromString(r.bodyAsText()) + assert(obj.name == "Foo") + // Checking admin can. + val adminRowId = db.customerCreate(Customer( + "admin", + CryptoUtil.hashpw("admin"), + "Admin" + )) + assert(adminRowId != null) + assert(db.bankAccountCreate(BankAccount( + hasDebt = false, + internalPaytoUri = "payto://iban/SANDBOXX/ADMIN-IBAN", + maxDebt = TalerAmount(100, 0), + owningCustomerId = adminRowId!! + ))) + client.get("/accounts/foo") { + expectSuccess = true + basicAuth("admin", "admin") + } + } + } /** * Testing the account creation, its idempotency and * the restriction to admin to create accounts.