summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine A <>2024-03-15 16:00:35 +0100
committerAntoine A <>2024-03-15 16:00:35 +0100
commite121d549fcc02efe00350ab4fe01a22220d9f149 (patch)
tree4954defa40234de4b3e5456a8c78f55785749a5f
parent53942fc404c3c801a749a0158e06c87575f5b311 (diff)
downloadlibeufin-e121d549fcc02efe00350ab4fe01a22220d9f149.tar.gz
libeufin-e121d549fcc02efe00350ab4fe01a22220d9f149.tar.bz2
libeufin-e121d549fcc02efe00350ab4fe01a22220d9f149.zip
FIx cashin idempotency when conversion is enabled
-rw-r--r--database-versioning/libeufin-nexus-procedures.sql17
-rw-r--r--testbench/src/main/kotlin/Main.kt2
-rw-r--r--testbench/src/test/kotlin/IntegrationTest.kt21
3 files changed, 21 insertions, 19 deletions
diff --git a/database-versioning/libeufin-nexus-procedures.sql b/database-versioning/libeufin-nexus-procedures.sql
index ed68ecc9..b941a739 100644
--- a/database-versioning/libeufin-nexus-procedures.sql
+++ b/database-versioning/libeufin-nexus-procedures.sql
@@ -216,13 +216,16 @@ SELECT reg.out_found, reg.out_tx_id
INTO out_found, out_tx_id;
-- Register as talerable bounce
-INSERT INTO talerable_incoming_transactions (
- incoming_transaction_id
- ,reserve_public_key
-) VALUES (
- out_tx_id
- ,in_reserve_public_key
-) ON CONFLICT (incoming_transaction_id) DO NOTHING;
+IF NOT EXISTS(SELECT 1 FROM talerable_incoming_transactions WHERE incoming_transaction_id = out_tx_id) THEN
+ -- We cannot use ON CONFLICT here because conversion use a trigger before insertion that isn't idempotent
+ INSERT INTO talerable_incoming_transactions (
+ incoming_transaction_id
+ ,reserve_public_key
+ ) VALUES (
+ out_tx_id
+ ,in_reserve_public_key
+ );
+END IF;
END $$;
COMMENT ON FUNCTION register_incoming_and_talerable IS '
Creates one row in the incoming transactions table and one row
diff --git a/testbench/src/main/kotlin/Main.kt b/testbench/src/main/kotlin/Main.kt
index cc553ee8..7c6b9db4 100644
--- a/testbench/src/main/kotlin/Main.kt
+++ b/testbench/src/main/kotlin/Main.kt
@@ -132,7 +132,7 @@ class Cli : CliktCommand("Run integration tests on banks provider") {
})
}
put("reset-db", "dbinit -r $flags")
- put("recover", "Recover old transactions", "ebics-fetch $ebicsFlags --pinned-start 2022-01-01 notification")
+ put("recover", "Recover old transactions", "ebics-fetch $ebicsFlags --pinned-start 2024-01-01 notification")
put("fetch", "Fetch all documents", "ebics-fetch $ebicsFlags")
put("ack", "Fetch CustomerAcknowledgement", "ebics-fetch $ebicsFlags acknowledgement")
put("status", "Fetch CustomerPaymentStatusReport", "ebics-fetch $ebicsFlags status")
diff --git a/testbench/src/test/kotlin/IntegrationTest.kt b/testbench/src/test/kotlin/IntegrationTest.kt
index 2f529a90..b6ede6c0 100644
--- a/testbench/src/test/kotlin/IntegrationTest.kt
+++ b/testbench/src/test/kotlin/IntegrationTest.kt
@@ -119,15 +119,10 @@ class IntegrationTest {
suspend fun checkCount(db: NexusDb, nbIncoming: Int, nbBounce: Int, nbTalerable: Int) {
db.conn { conn ->
- conn.prepareStatement("SELECT count(*) FROM incoming_transactions").oneOrNull {
- assertEquals(nbIncoming, it.getInt(1))
- }
- conn.prepareStatement("SELECT count(*) FROM bounced_transactions").oneOrNull {
- assertEquals(nbBounce, it.getInt(1))
- }
- conn.prepareStatement("SELECT count(*) FROM talerable_incoming_transactions").oneOrNull {
- assertEquals(nbTalerable, it.getInt(1))
- }
+ val cIncoming = conn.prepareStatement("SELECT count(*) FROM incoming_transactions").one { it.getInt(1) }
+ val cBounce = conn.prepareStatement("SELECT count(*) FROM bounced_transactions").one { it.getInt(1) }
+ val cTalerable = conn.prepareStatement("SELECT count(*) FROM talerable_incoming_transactions").one { it.getInt(1) }
+ assertEquals(Triple(nbIncoming, nbBounce, nbTalerable), Triple(cIncoming, cBounce, cTalerable))
}
}
@@ -202,18 +197,22 @@ class IntegrationTest {
}.assertNoContent()
// Check success
- ingestIncomingPayment(db, IncomingPayment(
+ val valid_payment = IncomingPayment(
amount = TalerAmount("EUR:10"),
debitPaytoUri = userPayTo.toString(),
wireTransferSubject = "Success ${Base32Crockford32B.rand().encoded()}",
executionTime = Instant.now(),
bankId = "success"
- ))
+ )
+ ingestIncomingPayment(db, valid_payment)
checkCount(db, 2, 1, 1)
client.get("http://0.0.0.0:8080/accounts/exchange/transactions") {
basicAuth("exchange", "password")
}.assertOkJson<BankAccountTransactionsResponse>()
+ // Check idempotency
+ ingestIncomingPayment(db, valid_payment)
+ checkCount(db, 2, 1, 1)
// TODO check double insert cashin with different subject
}
}