gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated (9c7079e5 -> 4b831469)


From: gnunet
Subject: [libeufin] branch master updated (9c7079e5 -> 4b831469)
Date: Tue, 04 Apr 2023 21:08:33 +0200

This is an automated email from the git hooks/post-receive script.

ms pushed a change to branch master
in repository libeufin.

    from 9c7079e5 Amount comparison.
     new 4990150b testing zero-check for amounts
     new 4b831469 Introducing account-less Access API's endpoints.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 nexus/src/test/kotlin/SandboxAccessApiTest.kt      |  72 +++++++++++
 .../src/main/kotlin/tech/libeufin/sandbox/Main.kt  | 144 ++++++++++++---------
 util/src/test/kotlin/AmountTest.kt                 |   8 +-
 3 files changed, 164 insertions(+), 60 deletions(-)

diff --git a/nexus/src/test/kotlin/SandboxAccessApiTest.kt 
b/nexus/src/test/kotlin/SandboxAccessApiTest.kt
index 4c0232c9..ca4f2f08 100644
--- a/nexus/src/test/kotlin/SandboxAccessApiTest.kt
+++ b/nexus/src/test/kotlin/SandboxAccessApiTest.kt
@@ -5,15 +5,87 @@ import io.ktor.client.request.*
 import io.ktor.client.statement.*
 import io.ktor.http.*
 import io.ktor.server.testing.*
+import io.ktor.util.*
 import kotlinx.coroutines.runBlocking
 import org.jetbrains.exposed.sql.and
 import org.jetbrains.exposed.sql.transactions.transaction
 import org.junit.Test
+import tech.libeufin.nexus.bankaccount.getBankAccount
 import tech.libeufin.sandbox.*
 
 class SandboxAccessApiTest {
     val mapper = ObjectMapper()
 
+    /**
+     * Testing that ..access-api/withdrawals/{wopid} and
+     * ..access-api/accounts/{account_name}/withdrawals/{wopid}
+     * are handled in the same way.
+     */
+    @Test
+    fun doubleUriStyle() {
+        // Creating one withdrawal operation.
+        withTestDatabase {
+            prepSandboxDb()
+            val wo: TalerWithdrawalEntity = transaction {
+                TalerWithdrawalEntity.new {
+                    this.amount = "TESTKUDOS:3.3"
+                    walletBankAccount = getBankAccountFromLabel("foo")
+                    selectedExchangePayto = 
"payto://iban/SANDBOXX/${BAR_USER_IBAN}"
+                    reservePub = "not used"
+                    selectionDone = true
+                }
+            }
+            testApplication {
+                application(sandboxApp)
+                // Showing withdrawal info.
+                val get_with_account = 
client.get("/demobanks/default/access-api/accounts/foo/withdrawals/${wo.wopid}")
 {
+                    expectSuccess = true
+                }
+                val get_without_account = 
client.get("/demobanks/default/access-api/withdrawals/${wo.wopid}") {
+                    expectSuccess = true
+                }
+                assert(get_without_account.bodyAsText() == 
get_with_account.bodyAsText())
+                assert(get_with_account.bodyAsText() == 
get_without_account.bodyAsText())
+                // Confirming a withdrawal.
+                val confirm_with_account = 
client.post("/demobanks/default/access-api/accounts/foo/withdrawals/${wo.wopid}/confirm")
 {
+                    expectSuccess = true
+                }
+                val confirm_without_account = 
client.post("/demobanks/default/access-api/withdrawals/${wo.wopid}/confirm") {
+                    expectSuccess = true
+                }
+                assert(confirm_with_account.status.value == 
confirm_without_account.status.value)
+                assert(confirm_with_account.bodyAsText() == 
confirm_without_account.bodyAsText())
+                // Aborting one withdrawal.
+                var wo_to_abort = transaction {
+                    TalerWithdrawalEntity.new {
+                        this.amount = "TESTKUDOS:3.3"
+                        walletBankAccount = getBankAccountFromLabel("foo")
+                        selectedExchangePayto = 
"payto://iban/SANDBOXX/${BAR_USER_IBAN}"
+                        reservePub = "not used"
+                        selectionDone = true
+                    }
+                }
+                val abort_with_account = 
client.post("/demobanks/default/access-api/accounts/foo/withdrawals/${wo_to_abort.wopid}/abort")
 {
+                    expectSuccess = true
+                }
+                wo_to_abort = transaction {
+                    TalerWithdrawalEntity.new {
+                        this.amount = "TESTKUDOS:3.3"
+                        walletBankAccount = getBankAccountFromLabel("foo")
+                        selectedExchangePayto = 
"payto://iban/SANDBOXX/${BAR_USER_IBAN}"
+                        reservePub = "not used"
+                        selectionDone = true
+                    }
+                }
+                val abort_without_account = 
client.post("/demobanks/default/access-api/withdrawals/${wo_to_abort.wopid}/abort")
 {
+                    expectSuccess = true
+                }
+                assert(abort_with_account.status.value == 
abort_without_account.status.value)
+                // Not checking the content as they abort two different 
operations.
+            }
+        }
+    }
+
     // Move funds between accounts.
     @Test
     fun wireTransfer() {
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 9c8f8121..4aedf41c 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -487,6 +487,73 @@ fun setJsonHandler(ctx: ObjectMapper) {
     )
 }
 
+private suspend fun getWithdrawal(call: ApplicationCall) {
+    val op = getWithdrawalOperation(call.expectUriComponent("withdrawal_id"))
+    if (!op.selectionDone && op.reservePub != null) throw internalServerError(
+        "Unselected withdrawal has a reserve public key",
+        LibeufinErrorCode.LIBEUFIN_EC_INCONSISTENT_STATE
+    )
+    call.respond(object {
+        val amount = op.amount
+        val aborted = op.aborted
+        val confirmation_done = op.confirmationDone
+        val selection_done = op.selectionDone
+        val selected_reserve_pub = op.reservePub
+        val selected_exchange_account = op.selectedExchangePayto
+    })
+}
+
+private suspend fun confirmWithdrawal(call: ApplicationCall) {
+    val withdrawalId = call.expectUriComponent("withdrawal_id")
+    transaction {
+        val wo = getWithdrawalOperation(withdrawalId)
+        if (wo.aborted) throw SandboxError(
+            HttpStatusCode.Conflict,
+            "Cannot confirm an aborted withdrawal."
+        )
+        if (!wo.selectionDone) throw SandboxError(
+            HttpStatusCode.UnprocessableEntity,
+            "Cannot confirm a unselected withdrawal: " +
+                    "specify exchange and reserve public key via Integration 
API first."
+        )
+        /**
+         * The wallet chose not to select any exchange, use the default.
+         */
+        val demobank = ensureDemobank(call)
+        if (wo.selectedExchangePayto == null) {
+            wo.selectedExchangePayto = demobank.config.suggestedExchangePayto
+        }
+        val exchangeBankAccount = getBankAccountFromPayto(
+            wo.selectedExchangePayto ?: throw internalServerError(
+                "Cannot withdraw without an exchange."
+            )
+        )
+        if (!wo.confirmationDone) {
+            wireTransfer(
+                debitAccount = wo.walletBankAccount,
+                creditAccount = exchangeBankAccount,
+                amount = wo.amount,
+                subject = wo.reservePub ?: throw internalServerError(
+                    "Cannot transfer funds without reserve public key."
+                ),
+                // provide the currency.
+                demobank = ensureDemobank(call)
+            )
+            wo.confirmationDone = true
+        }
+        wo.confirmationDone
+    }
+    call.respond(object {})
+}
+
+private suspend fun abortWithdrawal(call: ApplicationCall) {
+    val withdrawalId = call.expectUriComponent("withdrawal_id")
+    val operation = getWithdrawalOperation(withdrawalId)
+    if (operation.confirmationDone) throw conflict("Cannot abort paid 
withdrawal.")
+    transaction { operation.aborted = true }
+    call.respond(object {})
+}
+
 val sandboxApp: Application.() -> Unit = {
     install(CallLogging) {
         this.level = Level.DEBUG
@@ -1283,19 +1350,12 @@ val sandboxApp: Application.() -> Unit = {
                 }
                 // Information about one withdrawal.
                 get("/accounts/{account_name}/withdrawals/{withdrawal_id}") {
-                    val op = 
getWithdrawalOperation(call.expectUriComponent("withdrawal_id"))
-                    if (!op.selectionDone && op.reservePub != null) throw 
internalServerError(
-                        "Unselected withdrawal has a reserve public key",
-                        LibeufinErrorCode.LIBEUFIN_EC_INCONSISTENT_STATE
-                    )
-                    call.respond(object {
-                        val amount = op.amount
-                        val aborted = op.aborted
-                        val confirmation_done = op.confirmationDone
-                        val selection_done = op.selectionDone
-                        val selected_reserve_pub = op.reservePub
-                        val selected_exchange_account = 
op.selectedExchangePayto
-                    })
+                    getWithdrawal(call)
+                    return@get
+                }
+                // account-less style:
+                get("/withdrawals/{withdrawal_id}") {
+                    getWithdrawal(call)
                     return@get
                 }
                 // Create a new withdrawal operation.
@@ -1372,54 +1432,22 @@ val sandboxApp: Application.() -> Unit = {
                 }
                 // Confirm a withdrawal: no basic auth, because the ID should 
be unguessable.
                 
post("/accounts/{account_name}/withdrawals/{withdrawal_id}/confirm") {
-                    val withdrawalId = call.expectUriComponent("withdrawal_id")
-                    transaction {
-                        val wo = getWithdrawalOperation(withdrawalId)
-                        if (wo.aborted) throw SandboxError(
-                            HttpStatusCode.Conflict,
-                            "Cannot confirm an aborted withdrawal."
-                        )
-                        if (!wo.selectionDone) throw SandboxError(
-                            HttpStatusCode.UnprocessableEntity,
-                            "Cannot confirm a unselected withdrawal: " +
-                                    "specify exchange and reserve public key 
via Integration API first."
-                        )
-                        /**
-                         * The wallet chose not to select any exchange, use 
the default.
-                         */
-                        val demobank = ensureDemobank(call)
-                        if (wo.selectedExchangePayto == null) {
-                            wo.selectedExchangePayto = 
demobank.config.suggestedExchangePayto
-                        }
-                        val exchangeBankAccount = getBankAccountFromPayto(
-                            wo.selectedExchangePayto ?: throw 
internalServerError(
-                                "Cannot withdraw without an exchange."
-                            )
-                        )
-                        if (!wo.confirmationDone) {
-                            wireTransfer(
-                                debitAccount = wo.walletBankAccount,
-                                creditAccount = exchangeBankAccount,
-                                amount = wo.amount,
-                                subject = wo.reservePub ?: throw 
internalServerError(
-                                    "Cannot transfer funds without reserve 
public key."
-                                ),
-                                // provide the currency.
-                                demobank = ensureDemobank(call)
-                            )
-                            wo.confirmationDone = true
-                        }
-                        wo.confirmationDone
-                    }
-                    call.respond(object {})
+                    confirmWithdrawal(call)
                     return@post
                 }
+                // account-less style:
+                post("/withdrawals/{withdrawal_id}/confirm") {
+                    confirmWithdrawal(call)
+                    return@post
+                }
+                // Aborting withdrawals:
                 
post("/accounts/{account_name}/withdrawals/{withdrawal_id}/abort") {
-                    val withdrawalId = call.expectUriComponent("withdrawal_id")
-                    val operation = getWithdrawalOperation(withdrawalId)
-                    if (operation.confirmationDone) throw conflict("Cannot 
abort paid withdrawal.")
-                    transaction { operation.aborted = true }
-                    call.respond(object {})
+                    abortWithdrawal(call)
+                    return@post
+                }
+                // account-less style:
+                post("/withdrawals/{withdrawal_id}/abort") {
+                    abortWithdrawal(call)
                     return@post
                 }
                 // Bank account basic information.
diff --git a/util/src/test/kotlin/AmountTest.kt 
b/util/src/test/kotlin/AmountTest.kt
index 5ae1e05f..eb7d8493 100644
--- a/util/src/test/kotlin/AmountTest.kt
+++ b/util/src/test/kotlin/AmountTest.kt
@@ -19,8 +19,12 @@ inline fun <reified ExceptionType> assertException(block: () 
-> Unit) {
 class AmountTest {
     @Test
     fun equalTest() {
-        val z = BigDecimal("-0000000000.0000000000")
-        assert(isAmountZero(z))
+        assert(isAmountZero(BigDecimal("-0000000000.0000000000")))
+        assert(!isAmountZero(BigDecimal("1")))
+        assert(isAmountZero(BigDecimal("0.00")))
+        assert(isAmountZero(BigDecimal("0")))
+        assert(!isAmountZero(BigDecimal("00000000000001")))
+        assert(!isAmountZero(BigDecimal("-1.00000000")))
     }
 
     @Test

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]