commit fec38bd1934f3da7cc94872dfe6bc6679b9e92f9
parent 2f4ac08b02f763a941d1ee0154ff6e2ed5b9c024
Author: Antoine A <>
Date: Tue, 6 Feb 2024 16:11:41 +0100
Make more config values mandatory
Diffstat:
16 files changed, 300 insertions(+), 292 deletions(-)
diff --git a/bank/conf/test.conf b/bank/conf/test.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
DEFAULT_DEBT_LIMIT = KUDOS:100
SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.example.com
ALLOW_REGISTRATION = yes
diff --git a/bank/conf/test_bonus.conf b/bank/conf/test_bonus.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
REGISTRATION_BONUS = KUDOS:100
ALLOW_REGISTRATION = yes
ALLOW_ACCOUNT_DELETION = yes
diff --git a/bank/conf/test_no_conversion.conf b/bank/conf/test_no_conversion.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
ALLOW_REGISTRATION = yes
ALLOW_ACCOUNT_DELETION = yes
diff --git a/bank/conf/test_restrict.conf b/bank/conf/test_restrict.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
DEFAULT_DEBT_LIMIT = KUDOS:100
allow_conversion = YES
FIAT_CURRENCY = EUR
diff --git a/bank/conf/test_tan_err.conf b/bank/conf/test_tan_err.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
DEFAULT_DEBT_LIMIT = KUDOS:100
SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.example.com
allow_conversion = YES
diff --git a/bank/conf/test_x_taler_bank.conf b/bank/conf/test_x_taler_bank.conf
@@ -1,12 +1,13 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = x-taler-bank
+X_TALER_BANK_PAYTO_HOSTNAME = bank.hostname.test
DEFAULT_DEBT_LIMIT = KUDOS:100
SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.example.com
ALLOW_REGISTRATION = yes
ALLOW_ACCOUNT_DELETION = yes
ALLOW_EDIT_NAME = yes
ALLOW_EDIT_CASHOUT_PAYTO_URI = yes
-WIRE_TYPE = x-taler-bank
-X_TALER_BANK_PAYTO_HOSTNAME = bank.hostname.test
[libeufin-bankdb-postgres]
CONFIG = postgresql:///libeufincheck
diff --git a/common/src/main/kotlin/TalerConfig.kt b/common/src/main/kotlin/TalerConfig.kt
@@ -38,10 +38,10 @@ private val reDirective = Regex("^\\s*@([a-zA-Z-_]+)@\\s*(.*?)\\s*$")
class TalerConfigError private constructor (m: String) : Exception(m) {
companion object {
- fun missing(type: String, option: String, section: String): TalerConfigError =
+ fun missing(type: String, section: String, option: String): TalerConfigError =
TalerConfigError("Missing $type option '$option' in section '$section'")
- fun invalid(type: String, option: String, section: String, err: String): TalerConfigError =
+ fun invalid(type: String, section: String, option: String, err: String): TalerConfigError =
TalerConfigError("Expected $type option '$option' in section '$section': $err")
fun generic(msg: String): TalerConfigError =
@@ -430,7 +430,10 @@ class TalerConfig internal constructor(
fun lookupString(section: String, option: String): String? {
val canonSection = section.uppercase()
val canonOption = option.uppercase()
- return this.sectionMap[canonSection]?.entries?.get(canonOption)
+ val str = this.sectionMap[canonSection]?.entries?.get(canonOption)
+ if (str == null) return null
+ if (str == "") return null
+ return str
}
fun requireString(section: String, option: String): String =
diff --git a/contrib/bank.conf b/contrib/bank.conf
@@ -1,15 +1,15 @@
[libeufin-bank]
# Internal currency of the libeufin-bank
-CURRENCY = KUDOS
+CURRENCY =
# Supported payment target type, this can either be iban or x-taler-bank
-WIRE_TYPE = iban
+WIRE_TYPE =
-# Bank BIC used in generated iban payto URI
-IBAN_PAYTO_BIC = SANDBOXX
+# Bank BIC used in generated iban payto URI. Required if WIRE_TYPE = iban
+# IBAN_PAYTO_BIC =
-# Bank hostname used in generated x-taler-bank payto URI
+# Bank hostname used in generated x-taler-bank payto URI. Required if WIRE_TYPE = x-taler-bank
# X_TALER_BANK_PAYTO_HOSTNAME = bank.$FOO.taler.net
# Default debt limit for newly created accounts Default is CURRENCY:0
diff --git a/contrib/nexus.conf b/contrib/nexus.conf
@@ -4,26 +4,31 @@ LIBEUFIN_NEXUS_HOME = /var/lib/libeufin-nexus
[nexus-ebics]
# Currency used by the bank where Nexus is client.
-CURRENCY = KUDOS
+CURRENCY =
# Base URL of the bank server.
-HOST_BASE_URL = http://ebics.bank.com/
+HOST_BASE_URL =
# EBICS host ID.
-HOST_ID = mybank
+HOST_ID =
# EBICS user ID, as assigned by the bank.
-USER_ID = myuser
+USER_ID =
# EBICS partner ID, as assigned by the bank.
-PARTNER_ID = myorg
+PARTNER_ID =
# EBICS partner ID, as assigned by the bank.
-SYSTEM_ID = banksys
+SYSTEM_ID =
-IBAN = CH9789144829733648596
-BIC = POFICHBE
-NAME = LibEuFin
+# IBAN of the bank account that is associated with the EBICS subscriber
+IBAN =
+
+# BIC of the bank account that is associated with the EBICS subscriber
+BIC =
+
+# Legal entity that is associated with the EBICS subscriber
+NAME =
# File that holds the bank EBICS keys.
BANK_PUBLIC_KEYS_FILE = ${LIBEUFIN_NEXUS_HOME}/bank-ebics-keys.json
diff --git a/nexus/conf/test.conf b/nexus/conf/test.conf
@@ -1,5 +1,5 @@
[nexus-ebics]
-currency = CHF
+CURRENCY = CHF
BANK_DIALECT = postfinance
HOST_BASE_URL = https://isotest.postfinance.ch/ebicsweb/ebicsweb
BANK_PUBLIC_KEYS_FILE = test/tmp/bank-keys.json
@@ -8,6 +8,8 @@ IBAN = CH7789144474425692816
HOST_ID = PFEBICS
USER_ID = PFC00563
PARTNER_ID = PFC00563
+BIC = BIC
+NAME = myname
[libeufin-nexusdb-postgres]
CONFIG = postgres:///libeufincheck
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/Common.kt b/nexus/src/test/kotlin/Common.kt
@@ -22,10 +22,12 @@ import io.ktor.client.engine.mock.*
import io.ktor.client.request.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
+import kotlinx.coroutines.*
import tech.libeufin.nexus.*
import tech.libeufin.common.*
import java.security.interfaces.RSAPrivateCrtKey
import java.time.Instant
+import kotlin.io.path.*
val j = Json {
this.serializersModule = SerializersModule {
@@ -33,28 +35,33 @@ val j = Json {
}
}
-val config: EbicsSetupConfig = run {
- val handle = NEXUS_CONFIG_SOURCE.fromFile(null)
- EbicsSetupConfig(handle)
+fun conf(
+ conf: String = "test.conf",
+ lambda: suspend (EbicsSetupConfig) -> Unit
+) {
+ val config = NEXUS_CONFIG_SOURCE.fromFile(Path("conf/$conf"))
+ val ctx = EbicsSetupConfig(config)
+ runBlocking {
+ lambda(ctx)
+ }
}
-fun prepDb(cfg: TalerConfig): Database {
- val dbCfg = DatabaseConfig(
- dbConnStr = "postgresql:///libeufincheck",
- sqlDir = cfg.requirePath("paths", "datadir").resolve("sql")
- )
- pgDataSource(dbCfg.dbConnStr).pgConnection().use { conn ->
- println("SQL dir for testing: ${dbCfg.sqlDir}")
- try {
- resetDatabaseTables(conn, dbCfg, "libeufin-nexus")
- } catch (e: Exception) {
- logger.warn("Resetting an empty database throws, tolerating this...")
- logger.warn(e.message)
+fun setup(
+ conf: String = "test.conf",
+ lambda: suspend (Database, EbicsSetupConfig) -> Unit
+) {
+ val config = NEXUS_CONFIG_SOURCE.fromFile(Path("conf/$conf"))
+ val dbCfg = config.dbConfig()
+ val ctx = EbicsSetupConfig(config)
+ Database(dbCfg.dbConnStr).use {
+ runBlocking {
+ it.conn { conn ->
+ resetDatabaseTables(conn, dbCfg, "libeufin-nexus")
+ initializeDatabaseTables(conn, dbCfg, "libeufin-nexus")
+ }
+ lambda(it, ctx)
}
- initializeDatabaseTables(conn, dbCfg, "libeufin-nexus")
}
-
- return Database(dbCfg.dbConnStr)
}
val clientKeys = generateNewKeys()
@@ -73,27 +80,6 @@ fun getMockedClient(
}
}
-// Partial config to talk to PostFinance.
-fun getPofiConfig(
- userId: String,
- partnerId: String,
- accountOwner: String? = "NotGiven"
- ) = """
- [nexus-ebics]
- CURRENCY = KUDOS
- HOST_BASE_URL = https://isotest.postfinance.ch/ebicsweb/ebicsweb
- HOST_ID = PFEBICS
- USER_ID = $userId
- PARTNER_ID = $partnerId
- SYSTEM_ID = not-used
- IBAN = CH9789144829733648596
- BIC = POFICHBE
- NAME = LibEuFin
- BANK_PUBLIC_KEYS_FILE = /tmp/pofi-testplatform-bank-keys.json
- CLIENT_PRIVATE_KEYS_FILE = /tmp/pofi-testplatform-subscriber-keys.json
- BANK_DIALECT = postfinance
-""".trimIndent()
-
// Generates a payment initiation, given its subject.
fun genInitPay(
subject: String = "init payment",
diff --git a/nexus/src/test/kotlin/ConfigLoading.kt b/nexus/src/test/kotlin/ConfigLoading.kt
@@ -25,23 +25,6 @@ import kotlin.test.*
import tech.libeufin.common.*
class ConfigLoading {
- /**
- * Tests that the default configuration has _at least_ the options
- * that are expected by the memory representation of config.
- */
- @Test
- fun loadRequiredValues() {
- val handle = NEXUS_CONFIG_SOURCE.fromFile(null)
- val cfg = EbicsSetupConfig(handle)
- cfg._dump()
- }
-
- @Test
- fun loadPath() {
- val handle = NEXUS_CONFIG_SOURCE.fromFile(null)
- val cfg = EbicsSetupConfig(handle)
- }
-
// Checks converting human-readable durations to seconds.
@Test
fun timeParsing() {
diff --git a/nexus/src/test/kotlin/DatabaseTest.kt b/nexus/src/test/kotlin/DatabaseTest.kt
@@ -25,37 +25,35 @@ import java.time.Instant
import kotlin.random.Random
import kotlin.test.*
import kotlin.test.assertEquals
+import kotlin.io.path.*
class OutgoingPaymentsTest {
@Test
- fun register() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- // With reconciling
- genOutPay("paid by nexus", "first").run {
- assertEquals(
- PaymentInitiationOutcome.SUCCESS,
- db.initiatedPaymentCreate(genInitPay("waiting for reconciliation", "first"))
- )
- db.registerOutgoing(this).run {
- assertTrue(new,)
- assertTrue(initiated)
- }
- db.registerOutgoing(this).run {
- assertFalse(new)
- assertTrue(initiated)
- }
+ fun register() = setup { db, _ ->
+ // With reconciling
+ genOutPay("paid by nexus", "first").run {
+ assertEquals(
+ PaymentInitiationOutcome.SUCCESS,
+ db.initiatedPaymentCreate(genInitPay("waiting for reconciliation", "first"))
+ )
+ db.registerOutgoing(this).run {
+ assertTrue(new,)
+ assertTrue(initiated)
}
- // Without reconciling
- genOutPay("not paid by nexus", "second").run {
- db.registerOutgoing(this).run {
- assertTrue(new)
- assertFalse(initiated)
- }
- db.registerOutgoing(this).run {
- assertFalse(new)
- assertFalse(initiated)
- }
+ db.registerOutgoing(this).run {
+ assertFalse(new)
+ assertTrue(initiated)
+ }
+ }
+ // Without reconciling
+ genOutPay("not paid by nexus", "second").run {
+ db.registerOutgoing(this).run {
+ assertTrue(new)
+ assertFalse(initiated)
+ }
+ db.registerOutgoing(this).run {
+ assertFalse(new)
+ assertFalse(initiated)
}
}
}
@@ -64,146 +62,132 @@ class OutgoingPaymentsTest {
class IncomingPaymentsTest {
// Tests creating and bouncing incoming payments in one DB transaction.
@Test
- fun bounce() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- // creating and bouncing one incoming transaction.
- val payment = genInPay("incoming and bounced")
- db.registerMalformedIncoming(
- payment,
- TalerAmount("KUDOS:2.53"),
- Instant.now()
- ).run {
- assertTrue(new)
- }
- db.registerMalformedIncoming(
- payment,
- TalerAmount("KUDOS:2.53"),
- Instant.now()
- ).run {
- assertFalse(new)
- }
- db.conn {
- // Checking one incoming got created
- val checkIncoming = it.prepareStatement("""
- SELECT (amount).val as amount_value, (amount).frac as amount_frac
- FROM incoming_transactions WHERE incoming_transaction_id = 1
- """).executeQuery()
- assertTrue(checkIncoming.next())
- assertEquals(payment.amount.value, checkIncoming.getLong("amount_value"))
- assertEquals(payment.amount.frac, checkIncoming.getInt("amount_frac"))
- // Checking the bounced table got its row.
- val checkBounced = it.prepareStatement("""
- SELECT 1 FROM bounced_transactions
- WHERE incoming_transaction_id = 1 AND initiated_outgoing_transaction_id = 1
- """).executeQuery()
- assertTrue(checkBounced.next())
- // check the related initiated payment exists.
- val checkInitiated = it.prepareStatement("""
- SELECT
- (amount).val as amount_value
- ,(amount).frac as amount_frac
- FROM initiated_outgoing_transactions
- WHERE initiated_outgoing_transaction_id = 1
- """).executeQuery()
- assertTrue(checkInitiated.next())
- assertEquals(
- 53000000,
- checkInitiated.getInt("amount_frac")
- )
- assertEquals(
- 2,
- checkInitiated.getInt("amount_value")
- )
- }
+ fun bounce() = setup { db, _ ->
+ // creating and bouncing one incoming transaction.
+ val payment = genInPay("incoming and bounced")
+ db.registerMalformedIncoming(
+ payment,
+ TalerAmount("KUDOS:2.53"),
+ Instant.now()
+ ).run {
+ assertTrue(new)
+ }
+ db.registerMalformedIncoming(
+ payment,
+ TalerAmount("KUDOS:2.53"),
+ Instant.now()
+ ).run {
+ assertFalse(new)
+ }
+ db.conn {
+ // Checking one incoming got created
+ val checkIncoming = it.prepareStatement("""
+ SELECT (amount).val as amount_value, (amount).frac as amount_frac
+ FROM incoming_transactions WHERE incoming_transaction_id = 1
+ """).executeQuery()
+ assertTrue(checkIncoming.next())
+ assertEquals(payment.amount.value, checkIncoming.getLong("amount_value"))
+ assertEquals(payment.amount.frac, checkIncoming.getInt("amount_frac"))
+ // Checking the bounced table got its row.
+ val checkBounced = it.prepareStatement("""
+ SELECT 1 FROM bounced_transactions
+ WHERE incoming_transaction_id = 1 AND initiated_outgoing_transaction_id = 1
+ """).executeQuery()
+ assertTrue(checkBounced.next())
+ // check the related initiated payment exists.
+ val checkInitiated = it.prepareStatement("""
+ SELECT
+ (amount).val as amount_value
+ ,(amount).frac as amount_frac
+ FROM initiated_outgoing_transactions
+ WHERE initiated_outgoing_transaction_id = 1
+ """).executeQuery()
+ assertTrue(checkInitiated.next())
+ assertEquals(
+ 53000000,
+ checkInitiated.getInt("amount_frac")
+ )
+ assertEquals(
+ 2,
+ checkInitiated.getInt("amount_value")
+ )
}
}
// Tests the creation of a talerable incoming payment.
@Test
- fun talerable() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
+ fun talerable() = setup { db, _ ->
val reservePub = ByteArray(32)
Random.nextBytes(reservePub)
- runBlocking {
- val inc = genInPay("reserve-pub")
- // Checking the reserve is not found.
- assertFalse(db.isReservePubFound(reservePub))
- assertTrue(db.registerTalerableIncoming(inc, reservePub).new)
- // Checking the reserve is not found.
- assertTrue(db.isReservePubFound(reservePub))
- assertFalse(db.registerTalerableIncoming(inc, reservePub).new)
- }
+ val inc = genInPay("reserve-pub")
+ // Checking the reserve is not found.
+ assertFalse(db.isReservePubFound(reservePub))
+ assertTrue(db.registerTalerableIncoming(inc, reservePub).new)
+ // Checking the reserve is not found.
+ assertTrue(db.isReservePubFound(reservePub))
+ assertFalse(db.registerTalerableIncoming(inc, reservePub).new)
}
}
class PaymentInitiationsTest {
// Testing the insertion of the failure message.
@Test
- fun setFailureMessage() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- assertEquals(
- db.initiatedPaymentCreate(genInitPay("not submitted, has row ID == 1")),
- PaymentInitiationOutcome.SUCCESS
- )
- assertFalse(db.initiatedPaymentSetFailureMessage(3, "3 not existing"))
- assertTrue(db.initiatedPaymentSetFailureMessage(1, "expired"))
- // Checking the value from the database.
- db.conn { conn ->
- val idOne = conn.execSQLQuery("""
- SELECT failure_message
- FROM initiated_outgoing_transactions
- WHERE initiated_outgoing_transaction_id = 1;
- """.trimIndent())
- assertTrue(idOne.next())
- val maybeMessage = idOne.getString("failure_message")
- assertEquals("expired", maybeMessage)
- }
+ fun setFailureMessage() = setup { db, _ ->
+ assertEquals(
+ db.initiatedPaymentCreate(genInitPay("not submitted, has row ID == 1")),
+ PaymentInitiationOutcome.SUCCESS
+ )
+ assertFalse(db.initiatedPaymentSetFailureMessage(3, "3 not existing"))
+ assertTrue(db.initiatedPaymentSetFailureMessage(1, "expired"))
+ // Checking the value from the database.
+ db.conn { conn ->
+ val idOne = conn.execSQLQuery("""
+ SELECT failure_message
+ FROM initiated_outgoing_transactions
+ WHERE initiated_outgoing_transaction_id = 1;
+ """.trimIndent())
+ assertTrue(idOne.next())
+ val maybeMessage = idOne.getString("failure_message")
+ assertEquals("expired", maybeMessage)
}
}
// Tests the flagging of payments as submitted.
@Test
- fun paymentInitiationSetAsSubmitted() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
+ fun paymentInitiationSetAsSubmitted() = setup { db, _ ->
val getRowOne = """
SELECT submitted
FROM initiated_outgoing_transactions
WHERE initiated_outgoing_transaction_id=1
"""
- runBlocking {
- // Creating the record first. Defaults to submitted == false.
- assertEquals(
- PaymentInitiationOutcome.SUCCESS,
- db.initiatedPaymentCreate(genInitPay("not submitted, has row ID == 1")),
- )
- // Asserting on the false default submitted state.
- db.conn { conn ->
- val isSubmitted = conn.execSQLQuery(getRowOne)
- assertTrue(isSubmitted.next())
- assertEquals("unsubmitted", isSubmitted.getString("submitted"))
- }
- // Switching the submitted state to success.
- assertTrue(db.initiatedPaymentSetSubmittedState(1, DatabaseSubmissionState.success))
- // Asserting on the submitted state being TRUE now.
- db.conn { conn ->
- val isSubmitted = conn.execSQLQuery(getRowOne)
- assertTrue(isSubmitted.next())
- assertEquals("success", isSubmitted.getString("submitted"))
- }
+
+ // Creating the record first. Defaults to submitted == false.
+ assertEquals(
+ PaymentInitiationOutcome.SUCCESS,
+ db.initiatedPaymentCreate(genInitPay("not submitted, has row ID == 1")),
+ )
+ // Asserting on the false default submitted state.
+ db.conn { conn ->
+ val isSubmitted = conn.execSQLQuery(getRowOne)
+ assertTrue(isSubmitted.next())
+ assertEquals("unsubmitted", isSubmitted.getString("submitted"))
+ }
+ // Switching the submitted state to success.
+ assertTrue(db.initiatedPaymentSetSubmittedState(1, DatabaseSubmissionState.success))
+ // Asserting on the submitted state being TRUE now.
+ db.conn { conn ->
+ val isSubmitted = conn.execSQLQuery(getRowOne)
+ assertTrue(isSubmitted.next())
+ assertEquals("success", isSubmitted.getString("submitted"))
}
}
// Tests creation, unique constraint violation handling, and
// retrieving only one non-submitted payment.
@Test
- fun paymentInitiation() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- val beEmpty = db.initiatedPaymentsSubmittableGet("KUDOS") // expect no records.
- assertEquals(beEmpty.size, 0)
- }
+ fun paymentInitiation() = setup { db, _ ->
+ val beEmpty = db.initiatedPaymentsSubmittableGet("KUDOS") // expect no records.
+ assertEquals(beEmpty.size, 0)
val initPay = InitiatedPayment(
id = -1,
amount = TalerAmount(44, 0, "KUDOS"),
@@ -212,19 +196,17 @@ class PaymentInitiationsTest {
requestUid = "unique",
initiationTime = Instant.now()
)
- runBlocking {
- assertNull(db.initiatedPaymentGetFromUid("unique"))
- assertEquals(db.initiatedPaymentCreate(initPay), PaymentInitiationOutcome.SUCCESS)
- assertEquals(db.initiatedPaymentCreate(initPay), PaymentInitiationOutcome.UNIQUE_CONSTRAINT_VIOLATION)
- val haveOne = db.initiatedPaymentsSubmittableGet("KUDOS")
- assertTrue("Size ${haveOne.size} instead of 1") {
- haveOne.size == 1
- && haveOne.first().id == 1L
- && haveOne.first().requestUid == "unique"
- }
- assertTrue(db.initiatedPaymentSetSubmittedState(1, DatabaseSubmissionState.success))
- assertNotNull(db.initiatedPaymentGetFromUid("unique"))
+ assertNull(db.initiatedPaymentGetFromUid("unique"))
+ assertEquals(db.initiatedPaymentCreate(initPay), PaymentInitiationOutcome.SUCCESS)
+ assertEquals(db.initiatedPaymentCreate(initPay), PaymentInitiationOutcome.UNIQUE_CONSTRAINT_VIOLATION)
+ val haveOne = db.initiatedPaymentsSubmittableGet("KUDOS")
+ assertTrue("Size ${haveOne.size} instead of 1") {
+ haveOne.size == 1
+ && haveOne.first().id == 1L
+ && haveOne.first().requestUid == "unique"
}
+ assertTrue(db.initiatedPaymentSetSubmittedState(1, DatabaseSubmissionState.success))
+ assertNotNull(db.initiatedPaymentGetFromUid("unique"))
}
/**
@@ -232,67 +214,61 @@ class PaymentInitiationsTest {
* statuses from them. Checking it here.
*/
@Test
- fun submittablePayments() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- val beEmpty = db.initiatedPaymentsSubmittableGet("KUDOS")
- assertEquals(0, beEmpty.size)
- assertEquals(
- db.initiatedPaymentCreate(genInitPay(requestUid = "first")),
- PaymentInitiationOutcome.SUCCESS
- )
- assertEquals(
- db.initiatedPaymentCreate(genInitPay(requestUid = "second")),
- PaymentInitiationOutcome.SUCCESS
- )
- assertEquals(
- db.initiatedPaymentCreate(genInitPay(requestUid = "third")),
- PaymentInitiationOutcome.SUCCESS
- )
+ fun submittablePayments() = setup { db, _ ->
+ val beEmpty = db.initiatedPaymentsSubmittableGet("KUDOS")
+ assertEquals(0, beEmpty.size)
+ assertEquals(
+ db.initiatedPaymentCreate(genInitPay(requestUid = "first")),
+ PaymentInitiationOutcome.SUCCESS
+ )
+ assertEquals(
+ db.initiatedPaymentCreate(genInitPay(requestUid = "second")),
+ PaymentInitiationOutcome.SUCCESS
+ )
+ assertEquals(
+ db.initiatedPaymentCreate(genInitPay(requestUid = "third")),
+ PaymentInitiationOutcome.SUCCESS
+ )
- // Setting the first as "transient_failure", must be found.
- assertTrue(db.initiatedPaymentSetSubmittedState(
- 1, DatabaseSubmissionState.transient_failure
- ))
- // Setting the second as "success", must not be found.
- assertTrue(db.initiatedPaymentSetSubmittedState(
- 2, DatabaseSubmissionState.success
- ))
- val expectTwo = db.initiatedPaymentsSubmittableGet("KUDOS")
- // the third initiation keeps the default "unsubmitted"
- // state, must be found. Total 2.
- assertEquals(2, expectTwo.size)
- }
+ // Setting the first as "transient_failure", must be found.
+ assertTrue(db.initiatedPaymentSetSubmittedState(
+ 1, DatabaseSubmissionState.transient_failure
+ ))
+ // Setting the second as "success", must not be found.
+ assertTrue(db.initiatedPaymentSetSubmittedState(
+ 2, DatabaseSubmissionState.success
+ ))
+ val expectTwo = db.initiatedPaymentsSubmittableGet("KUDOS")
+ // the third initiation keeps the default "unsubmitted"
+ // state, must be found. Total 2.
+ assertEquals(2, expectTwo.size)
}
// Tests how the fetch method gets the list of
// multiple unsubmitted payment initiations.
@Test
- fun paymentInitiationsMultiple() {
- val db = prepDb(NEXUS_CONFIG_SOURCE.fromFile(null))
- runBlocking {
- assertEquals(db.initiatedPaymentCreate(genInitPay("#1", "unique1")), PaymentInitiationOutcome.SUCCESS)
- assertEquals(db.initiatedPaymentCreate(genInitPay("#2", "unique2")), PaymentInitiationOutcome.SUCCESS)
- assertEquals(db.initiatedPaymentCreate(genInitPay("#3", "unique3")), PaymentInitiationOutcome.SUCCESS)
- assertEquals(db.initiatedPaymentCreate(genInitPay("#4", "unique4")), PaymentInitiationOutcome.SUCCESS)
+ fun paymentInitiationsMultiple() = setup { db, _ ->
+ assertEquals(db.initiatedPaymentCreate(genInitPay("#1", "unique1")), PaymentInitiationOutcome.SUCCESS)
+ assertEquals(db.initiatedPaymentCreate(genInitPay("#2", "unique2")), PaymentInitiationOutcome.SUCCESS)
+ assertEquals(db.initiatedPaymentCreate(genInitPay("#3", "unique3")), PaymentInitiationOutcome.SUCCESS)
+ assertEquals(db.initiatedPaymentCreate(genInitPay("#4", "unique4")), PaymentInitiationOutcome.SUCCESS)
- // Marking one as submitted, hence not expecting it in the results.
- db.conn { conn ->
- conn.execSQLUpdate("""
- UPDATE initiated_outgoing_transactions
- SET submitted='success'
- WHERE initiated_outgoing_transaction_id=3;
- """.trimIndent())
- }
+ // Marking one as submitted, hence not expecting it in the results.
+ db.conn { conn ->
+ conn.execSQLUpdate("""
+ UPDATE initiated_outgoing_transactions
+ SET submitted='success'
+ WHERE initiated_outgoing_transaction_id=3;
+ """.trimIndent())
+ }
- // Expecting all the payments BUT the #3 in the result.
- db.initiatedPaymentsSubmittableGet("KUDOS").apply {
+ // Expecting all the payments BUT the #3 in the result.
+ db.initiatedPaymentsSubmittableGet("KUDOS").apply {
- assertEquals(3, this.size)
- assertEquals("#1", this[0].wireTransferSubject)
- assertEquals("#2", this[1].wireTransferSubject)
- assertEquals("#4", this[2].wireTransferSubject)
- }
+ assertEquals(3, this.size)
+ assertEquals("#1", this[0].wireTransferSubject)
+ assertEquals("#2", this[1].wireTransferSubject)
+ assertEquals("#4", this[2].wireTransferSubject)
}
}
}
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/Ebics.kt b/nexus/src/test/kotlin/Ebics.kt
@@ -33,7 +33,7 @@ import kotlin.io.path.*
class Ebics {
// Checks XML is valid and INI.
@Test
- fun iniMessage() {
+ fun iniMessage() = conf { config ->
val msg = generateIniMessage(config, clientKeys)
val ini = XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(msg) // ensures is valid
assertEquals(ini.value.header.static.orderDetails.orderType, "INI") // ensures is INI
@@ -41,7 +41,7 @@ class Ebics {
// Checks XML is valid and HIA.
@Test
- fun hiaMessage() {
+ fun hiaMessage() = conf { config ->
val msg = generateHiaMessage(config, clientKeys)
val ini = XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(msg) // ensures is valid
assertEquals(ini.value.header.static.orderDetails.orderType, "HIA") // ensures is HIA
@@ -49,7 +49,7 @@ class Ebics {
// Checks XML is valid and HPB.
@Test
- fun hpbMessage() {
+ fun hpbMessage() = conf { config ->
val msg = generateHpbMessage(config, clientKeys)
val ini = XMLUtil.convertStringToJaxb<EbicsUnsecuredRequest>(msg) // ensures is valid
assertEquals(ini.value.header.static.orderDetails.orderType, "HPB") // ensures is HPB
@@ -58,7 +58,7 @@ class Ebics {
// the main branches: unreachable bank, non-200 status
// code, and 200.
@Test
- fun postMessage() {
+ fun postMessage() = conf { config ->
val client404 = getMockedClient {
respondError(HttpStatusCode.NotFound)
}
@@ -68,17 +68,15 @@ class Ebics {
val clientOk = getMockedClient {
respondOk("Not EBICS anyway.")
}
- runBlocking {
- assertNull(client404.postToBank("http://ignored.example.com/", "ignored"))
- assertNull(clientNoResponse.postToBank("http://ignored.example.com/", "ignored"))
- assertNotNull(clientOk.postToBank("http://ignored.example.com/", "ignored"))
- }
+ assertNull(client404.postToBank("http://ignored.example.com/", "ignored"))
+ assertNull(clientNoResponse.postToBank("http://ignored.example.com/", "ignored"))
+ assertNotNull(clientOk.postToBank("http://ignored.example.com/", "ignored"))
}
// Tests that internal repr. of keys lead to valid PDF.
// Mainly tests that the function does not throw any error.
@Test
- fun keysPdf() {
+ fun keysPdf() = conf { config ->
val pdf = generateKeysPdf(clientKeys, config)
Path("/tmp/libeufin-nexus-test-keys.pdf").writeBytes(pdf)
}
diff --git a/testbench/conf/integration.conf b/testbench/conf/integration.conf
@@ -1,4 +1,7 @@
[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
SUGGESTED_WITHDRAWAL_EXCHANGE = https://exchange.example.com
ALLOW_REGISTRATION = yes
ALLOW_ACCOUNT_DELETION = yes
@@ -7,11 +10,25 @@ FIAT_CURRENCY = EUR
tan_sms = libeufin-tan-file.sh
tan_email = libeufin-tan-fail.sh
-[libeufin-bankdb-postgres]
-CONFIG = postgresql:///libeufincheck
-
[nexus-ebics]
-currency = EUR
+CURRENCY = EUR
+
+# Bank
+HOST_BASE_URL = http://bank.example.com/
+BANK_DIALECT = postfinance
+
+# EBICS IDs
+HOST_ID = mybank
+USER_ID = myuser
+PARTNER_ID = myorg
+
+# Account information
+IBAN = myiban
+BIC = mybic
+NAME = myname
[libeufin-bankdb-postgres]
+CONFIG = postgresql:///libeufincheck
+
+[libeufin-nexusdb-postgres]
CONFIG = postgres:///libeufincheck
diff --git a/testbench/conf/mini.conf b/testbench/conf/mini.conf
@@ -1,3 +1,25 @@
+[libeufin-bank]
+CURRENCY = KUDOS
+WIRE_TYPE = iban
+IBAN_PAYTO_BIC = SANDBOXX
+
+[nexus-ebics]
+CURRENCY = CHF
+
+# Bank
+HOST_BASE_URL = http://bank.example.com/
+BANK_DIALECT = postfinance
+
+# EBICS IDs
+HOST_ID = mybank
+USER_ID = myuser
+PARTNER_ID = myorg
+
+# Account information
+IBAN = myiban
+BIC = mybic
+NAME = myname
+
[libeufin-bankdb-postgres]
CONFIG = postgresql:///libeufincheck