diff options
25 files changed, 331 insertions, 122 deletions
diff --git a/packages/taler-util/src/taleruri.ts b/packages/taler-util/src/taleruri.ts index 09c70682a..b487c73ae 100644 --- a/packages/taler-util/src/taleruri.ts +++ b/packages/taler-util/src/taleruri.ts @@ -57,6 +57,13 @@ export function parseWithdrawUri(s: string): WithdrawUriResult | undefined { const host = parts[0].toLowerCase(); const pathSegments = parts.slice(1, parts.length - 1); + /** + * The statement below does not tolerate a slash-ended URI. + * This results in (1) the withdrawalId being passed as the + * empty string, and (2) the bankIntegrationApi ending with the + * actual withdrawal operation ID. That can be fixed by + * trimming the parts-list. FIXME + */ const withdrawId = parts[parts.length - 1]; const p = [host, ...pathSegments].join("/"); diff --git a/packages/taler-wallet-cli/src/harness/harness.ts b/packages/taler-wallet-cli/src/harness/harness.ts index f8dd15738..4944e3471 100644 --- a/packages/taler-wallet-cli/src/harness/harness.ts +++ b/packages/taler-wallet-cli/src/harness/harness.ts @@ -65,6 +65,8 @@ import { EddsaKeyPair, encodeCrock, getRandomBytes, + hash, + stringToBytes } from "@gnu-taler/taler-util"; import { CoinConfig } from "./denomStructures.js"; import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js"; @@ -431,8 +433,7 @@ function setCoin(config: Configuration, c: CoinConfig) { } /** - * Send an HTTP request until it succeeds or the - * process dies. + * Send an HTTP request until it suceeds or the process dies. */ export async function pingProc( proc: ProcessWrapper | undefined, @@ -523,22 +524,26 @@ export namespace BankApi { password: string, ): Promise<BankUser> { const url = new URL("testing/register", bank.baseUrl); - await axios.post(url.href, { + let resp = await axios.post(url.href, { username, password, }); + let paytoUri = `payto://x-taler-bank/localhost/${username}`; + if (process.env.WALLET_HARNESS_WITH_EUFIN) { + paytoUri = resp.data.paytoUri; + } return { password, username, - accountPaytoUri: `payto://x-taler-bank/localhost/${username}`, + accountPaytoUri: paytoUri, }; } export async function createRandomBankUser( bank: BankServiceInterface, ): Promise<BankUser> { - const username = "user-" + encodeCrock(getRandomBytes(10)); - const password = "pw-" + encodeCrock(getRandomBytes(10)); + const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase(); return await registerAccount(bank, username, password); } @@ -551,9 +556,14 @@ export namespace BankApi { debitAccountPayto: string; }, ) { - const url = new URL( + + let maybeBaseUrl = bank.baseUrl; + if (process.env.WALLET_HARNESS_WITH_EUFIN) { + maybeBaseUrl = (bank as EufinBankService).baseUrlDemobank; + } + let url = new URL( `taler-wire-gateway/${params.exchangeBankAccount.accountName}/admin/add-incoming`, - bank.baseUrl, + maybeBaseUrl, ); await axios.post( url.href, @@ -623,28 +633,55 @@ class BankServiceBase { * Work in progress. The key point is that both Sandbox and Nexus * will be configured and started by this class. */ -class LibeufinBankService extends BankServiceBase implements BankService { +class EufinBankService extends BankServiceBase implements BankServiceInterface { sandboxProc: ProcessWrapper | undefined; nexusProc: ProcessWrapper | undefined; static async create( gc: GlobalTestState, bc: BankConfig, - ): Promise<BankService> { + ): Promise<EufinBankService> { - return new LibeufinBankService(gc, bc, "foo"); + return new EufinBankService(gc, bc, "foo"); } get port() { return this.bankConfig.httpPort; } + get nexusPort() { + return this.bankConfig.httpPort + 1000; + + } + + get nexusDbConn(): string { + return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`; + } + + get sandboxDbConn(): string { + return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`; + + } get nexusBaseUrl(): string { - return `http://localhost:${this.bankConfig.httpPort + 1}`; + return `http://localhost:${this.nexusPort}`; + } + + get baseUrlDemobank(): string { + let url = new URL("demobanks/default/", this.baseUrlNetloc); + return url.href; + } + + get baseUrlAccessApi(): string { + let url = new URL("access-api/", this.baseUrlDemobank); + return url.href; + } + + get baseUrlNetloc(): string { + return `http://localhost:${this.bankConfig.httpPort}/`; } get baseUrl(): string { - return `http://localhost:${this.bankConfig.httpPort}/demobanks/default/access-api`; + return this.baseUrlAccessApi; } async setSuggestedExchange( @@ -654,7 +691,11 @@ class LibeufinBankService extends BankServiceBase implements BankService { await sh( this.globalTestState, "libeufin-sandbox-set-default-exchange", - `libeufin-sandbox default-exchange ${exchangePayto}` + `libeufin-sandbox default-exchange ${e.baseUrl} ${exchangePayto}`, + { + ...process.env, + LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn, + }, ); } @@ -663,38 +704,45 @@ class LibeufinBankService extends BankServiceBase implements BankService { accountName: string, password: string, ): Promise<HarnessExchangeBankAccount> { - + console.log("Create Exchange account(s)!"); + /** + * Many test cases try to create a Exchange account before + * starting the bank; that's because the Pybank did it entirely + * via the configuration file. + */ + await this.start(); + await this.pingUntilAvailable(); await LibeufinSandboxApi.createDemobankAccount( accountName, password, - { baseUrl: this.baseUrl } + { baseUrl: this.baseUrlAccessApi } ); - let bankAccountLabel = `${accountName}-acct` + let bankAccountLabel = accountName; await LibeufinSandboxApi.createDemobankEbicsSubscriber( { - hostID: "talertest-ebics-host", - userID: "exchange-ebics-user", - partnerID: "exchange-ebics-partner", + hostID: "talertestEbicsHost", + userID: "exchangeEbicsUser", + partnerID: "exchangeEbicsPartner", }, bankAccountLabel, - { baseUrl: this.baseUrl } + { baseUrl: this.baseUrlDemobank } ); await LibeufinNexusApi.createUser( { baseUrl: this.nexusBaseUrl }, { - username: `${accountName}-nexus-username`, - password: `${password}-nexus-password` + username: accountName, + password: password } ); await LibeufinNexusApi.createEbicsBankConnection( { baseUrl: this.nexusBaseUrl }, { name: "ebics-connection", // connection name. - ebicsURL: `http://localhost:${this.bankConfig.httpPort}/ebicsweb`, - hostID: "talertest-ebics-host", - userID: "exchange-ebics-user", - partnerID: "exchange-ebics-partner", + ebicsURL: (new URL("ebicsweb", this.baseUrlNetloc)).href, + hostID: "talertestEbicsHost", + userID: "exchangeEbicsUser", + partnerID: "exchangeEbicsPartner", } ); await LibeufinNexusApi.connectBankConnection( @@ -706,7 +754,7 @@ class LibeufinBankService extends BankServiceBase implements BankService { await LibeufinNexusApi.importConnectionAccount( { baseUrl: this.nexusBaseUrl }, "ebics-connection", // connection name - `${accountName}-acct`, // offered account label + accountName, // offered account label `${accountName}-nexus-label` // bank account label at Nexus ); await LibeufinNexusApi.createTwgFacade( @@ -724,7 +772,7 @@ class LibeufinBankService extends BankServiceBase implements BankService { { action: "grant", permission: { - subjectId: `${accountName}-nexus-username`, + subjectId: accountName, subjectType: "user", resourceType: "facade", resourceId: "exchange-facade", // facade name @@ -737,7 +785,7 @@ class LibeufinBankService extends BankServiceBase implements BankService { { action: "grant", permission: { - subjectId: `${accountName}-nexus-username`, + subjectId: accountName, subjectType: "user", resourceType: "facade", resourceId: "exchange-facade", // facade name @@ -745,12 +793,35 @@ class LibeufinBankService extends BankServiceBase implements BankService { }, } ); + // Set fetch task. + await LibeufinNexusApi.postTask( + { baseUrl: this.nexusBaseUrl }, + `${accountName}-nexus-label`, + { + name: "wirewatch-task", + cronspec: "* * *", + type: "fetch", + params: { + level: "all", + rangeType: "all", + }, + }); + await LibeufinNexusApi.postTask( + { baseUrl: this.nexusBaseUrl }, + `${accountName}-nexus-label`, + { + name: "aggregator-task", + cronspec: "* * *", + type: "submit", + params: {}, + } + ); let facadesResp = await LibeufinNexusApi.getAllFacades({ baseUrl: this.nexusBaseUrl }); let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo( - accountName, // username - password, - { baseUrl: this.nexusBaseUrl }, - `${accountName}acct` // bank account label. + "admin", + "secret", + { baseUrl: this.baseUrlAccessApi }, + accountName // bank account label. ); return { accountName: accountName, @@ -761,15 +832,36 @@ class LibeufinBankService extends BankServiceBase implements BankService { } async start(): Promise<void> { - let sandboxDb = `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`; - let nexusDb = `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`; + /** + * Because many test cases try to create a Exchange bank + * account _before_ starting the bank (Pybank did it only via + * the config), it is possible that at this point Sandbox and + * Nexus are already running. Hence, this method only launches + * them if they weren't launched earlier. + */ + + // Only go ahead if BOTH aren't running. + if (this.sandboxProc || this.nexusProc) { + console.log("Nexus or Sandbox already running, not taking any action."); + return; + } + await sh( + this.globalTestState, + "libeufin-sandbox-config-demobank", + `libeufin-sandbox config --currency=${this.bankConfig.currency} default`, + { + ...process.env, + LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn, + LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret", + }, + ); this.sandboxProc = this.globalTestState.spawnService( "libeufin-sandbox", ["serve", "--port", `${this.port}`], "libeufin-sandbox", { ...process.env, - LIBEUFIN_SANDBOX_DB_CONNECTION: sandboxDb, + LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn, LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret", }, ); @@ -780,34 +872,48 @@ class LibeufinBankService extends BankServiceBase implements BankService { ["superuser", "admin", "--password", "test"], { ...process.env, - LIBEUFIN_NEXUS_DB_CONNECTION: nexusDb, + LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn, }, ); - this.nexusProc = this.globalTestState.spawnService( "libeufin-nexus", - ["serve", "--port", `${this.port + 1}`], + ["serve", "--port", `${this.nexusPort}`], "libeufin-nexus", { ...process.env, - LIBEUFIN_NEXUS_DB_CONNECTION: nexusDb, + LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn, }, ); + // need to wait here, because at this point + // a Ebics host needs to be created (RESTfully) + await this.pingUntilAvailable(); + LibeufinSandboxApi.createEbicsHost( + { baseUrl: this.baseUrlNetloc }, + "talertestEbicsHost" + ); } async pingUntilAvailable(): Promise<void> { - await pingProc(this.sandboxProc, this.baseUrl, "libeufin-sandbox"); - await pingProc(this.nexusProc, `${this.baseUrl}config`, "libeufin-nexus"); + await pingProc( + this.sandboxProc, + `http://localhost:${this.bankConfig.httpPort}`, + "libeufin-sandbox" + ); + await pingProc( + this.nexusProc, + `${this.nexusBaseUrl}/config`, + "libeufin-nexus" + ); } } -export class BankService extends BankServiceBase implements BankServiceInterface { +class PybankService extends BankServiceBase implements BankServiceInterface { proc: ProcessWrapper | undefined; static async create( gc: GlobalTestState, bc: BankConfig, - ): Promise<BankService> { + ): Promise<PybankService> { const config = new Configuration(); setTalerPaths(config, gc.testDir + "/talerhome"); config.setString("taler", "currency", bc.currency); @@ -835,7 +941,7 @@ export class BankService extends BankServiceBase implements BankServiceInterface `taler-bank-manage -c '${cfgFilename}' django provide_accounts`, ); - return new BankService(gc, bc, cfgFilename); + return new PybankService(gc, bc, cfgFilename); } setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) { @@ -870,7 +976,7 @@ export class BankService extends BankServiceBase implements BankServiceInterface return { accountName: accountName, accountPassword: password, - accountPaytoUri: `payto://x-taler-bank/${accountName}`, + accountPaytoUri: getPayto(accountName), wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`, }; } @@ -893,11 +999,31 @@ export class BankService extends BankServiceBase implements BankServiceInterface } } -// Still work in progress.. -if (false && process.env.WALLET_HARNESS_WITH_EUFIN) { - BankService.create = LibeufinBankService.create; - BankService.prototype = Object.create(LibeufinBankService.prototype); -} + +/** + * Return a euFin or a pyBank implementation of + * the exported BankService class. This allows + * to "dynamically export" such class depending + * on a particular env variable. + */ +function getBankServiceImpl(): { + prototype: typeof PybankService.prototype, + create: typeof PybankService.create +} { + + if (process.env.WALLET_HARNESS_WITH_EUFIN) + return { + prototype: EufinBankService.prototype, + create: EufinBankService.create + } + return { + prototype: PybankService.prototype, + create: PybankService.create + } +} + +export type BankService = PybankService; +export const BankService = getBankServiceImpl(); export class FakeBankService { proc: ProcessWrapper | undefined; @@ -1038,6 +1164,10 @@ export class ExchangeService implements ExchangeServiceInterface { } async runWirewatchOnce() { + if (process.env.WALLET_HARNESS_WITH_EUFIN) { + // Not even 2 secods showed to be enough! + await waitMs(4000); + } await runCommand( this.globalState, `exchange-${this.name}-wirewatch-once`, @@ -1699,7 +1829,7 @@ export class MerchantService implements MerchantServiceInterface { return await this.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], auth: { method: "external", }, @@ -1956,3 +2086,46 @@ export class WalletCli { ); } } + +export function getRandomIban(salt: string | null = null): string { + + function getBban(salt: string | null): string { + if (!salt) + return Math.random().toString().substring(2, 6); + let hashed = hash(stringToBytes(salt)); + let ret = ""; + for (let i = 0; i < hashed.length; i++) { + ret += hashed[i].toString(); + } + return ret.substring(0, 4); + } + + let cc_no_check = "131400"; // == DE00 + let bban = getBban(salt) + let check_digits = (98 - (Number.parseInt(`${bban}${cc_no_check}`) % 97)).toString(); + if (check_digits.length == 1) { + check_digits = `0${check_digits}`; + } + return `DE${check_digits}${bban}`; +} + +// Only used in one tipping test. +export function getWireMethod(): string { + if (process.env.WALLET_HARNESS_WITH_EUFIN) + return "iban" + return "x-taler-bank" +} + +/** + * Generate a payto address, whose authority depends + * on whether the banking is served by euFin or Pybank. + */ +export function getPayto(label: string): string { + if (process.env.WALLET_HARNESS_WITH_EUFIN) + return `payto://iban/SANDBOXX/${getRandomIban(label)}?receiver-name=${label}` + return `payto://x-taler-bank/${label}` +} + +function waitMs(ms: number): Promise<void> { + return new Promise(resolve => setTimeout(resolve, ms)); +} diff --git a/packages/taler-wallet-cli/src/harness/helpers.ts b/packages/taler-wallet-cli/src/harness/helpers.ts index 6ff62504b..bac2eefc1 100644 --- a/packages/taler-wallet-cli/src/harness/helpers.ts +++ b/packages/taler-wallet-cli/src/harness/helpers.ts @@ -50,6 +50,7 @@ import { MerchantPrivateApi, HarnessExchangeBankAccount, WithAuthorization, + getPayto } from "./harness.js"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -94,7 +95,7 @@ export async function createSimpleTestkudosEnvironment( }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -118,13 +119,13 @@ export async function createSimpleTestkudosEnvironment( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); @@ -186,7 +187,7 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -213,13 +214,13 @@ export async function createFaultInjectedMerchantTestkudosEnvironment( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); @@ -263,16 +264,19 @@ export async function startWithdrawViaBank( await wallet.runPending(); - // Confirm it - - await BankApi.confirmWithdrawalOperation(bank, user, wop); - - // Withdraw + // Withdraw (AKA select) await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { exchangeBaseUrl: exchange.baseUrl, talerWithdrawUri: wop.taler_withdraw_uri, }); + + // Confirm it + + await BankApi.confirmWithdrawalOperation(bank, user, wop); + + await wallet.runPending(); + await wallet.runUntilDone(); } /** diff --git a/packages/taler-wallet-cli/src/harness/libeufin-apis.ts b/packages/taler-wallet-cli/src/harness/libeufin-apis.ts index 68a25d92f..13d27c467 100644 --- a/packages/taler-wallet-cli/src/harness/libeufin-apis.ts +++ b/packages/taler-wallet-cli/src/harness/libeufin-apis.ts @@ -184,7 +184,7 @@ export namespace LibeufinSandboxApi { libeufinSandboxService: LibeufinSandboxServiceInterface, accountLabel: string ) { - let url = new URL(`${libeufinSandboxService.baseUrl}/accounts/${accountLabel}`); + let url = new URL(`accounts/${accountLabel}`,libeufinSandboxService.baseUrl); return await axios.get(url.href, { auth: { username: username, @@ -199,7 +199,7 @@ export namespace LibeufinSandboxApi { password: string, libeufinSandboxService: LibeufinSandboxServiceInterface, ) { - let url = new URL(`${libeufinSandboxService.baseUrl}/testing/register`); + let url = new URL("testing/register", libeufinSandboxService.baseUrl); await axios.post(url.href, { username: username, password: password @@ -214,11 +214,11 @@ export namespace LibeufinSandboxApi { password: string = "secret", ) { // baseUrl should already be pointed to one demobank. - let url = new URL(libeufinSandboxService.baseUrl); + let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl); await axios.post(url.href, { userID: req.userID, hostID: req.hostID, - partnerID: req.userID, + partnerID: req.partnerID, demobankAccountLabel: demobankAccountLabel, }, { auth: { diff --git a/packages/taler-wallet-cli/src/harness/libeufin.ts b/packages/taler-wallet-cli/src/harness/libeufin.ts index d101efa52..0107d5a8b 100644 --- a/packages/taler-wallet-cli/src/harness/libeufin.ts +++ b/packages/taler-wallet-cli/src/harness/libeufin.ts @@ -36,8 +36,8 @@ import { runCommand, setupDb, sh, + getRandomIban } from "../harness/harness.js"; - import { LibeufinSandboxApi, LibeufinNexusApi, @@ -183,10 +183,6 @@ export interface LibeufinPreparedPaymentDetails { nexusBankAccountName: string; } -function getRandomIban(countryCode: string): string { - return `${countryCode}715001051796${(Math.random().toString().substring(2, 8))}` -} - export class LibeufinSandboxService implements LibeufinSandboxServiceInterface { static async create( gc: GlobalTestState, @@ -405,7 +401,7 @@ export class SandboxUserBundle { constructor(salt: string) { this.ebicsBankAccount = { bic: "BELADEBEXXX", - iban: getRandomIban("DE"), + iban: getRandomIban(), label: `remote-account-${salt}`, name: `Taler Exchange: ${salt}`, subscriber: { diff --git a/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts index 0f8af05e5..2259dd8bb 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts @@ -27,6 +27,7 @@ import { BankApi, BankAccessApi, CreditDebitIndicator, + getPayto } from "../harness/harness.js"; import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util"; import { defaultCoinConfig } from "../harness/denomStructures"; @@ -61,7 +62,7 @@ export async function runBankApiTest(t: GlobalTestState) { }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -85,13 +86,13 @@ export async function runBankApiTest(t: GlobalTestState) { await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-deposit.ts b/packages/taler-wallet-cli/src/integrationtests/test-deposit.ts index f33c8338b..07382c43e 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-deposit.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-deposit.ts @@ -18,7 +18,7 @@ * Imports. */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { GlobalTestState } from "../harness/harness.js"; +import { GlobalTestState, getPayto } from "../harness/harness.js"; import { createSimpleTestkudosEnvironment, withdrawViaBank } from "../harness/helpers.js"; /** @@ -44,7 +44,7 @@ export async function runDepositTest(t: GlobalTestState) { WalletApiOperation.CreateDepositGroup, { amount: "TESTKUDOS:10", - depositPaytoUri: "payto://x-taler-bank/localhost/foo", + depositPaytoUri: getPayto("foo"), }, ); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts index 8a5d563ce..91e9bdec5 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts @@ -26,6 +26,7 @@ import { MerchantService, BankApi, BankAccessApi, + getPayto } from "../harness/harness.js"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { @@ -69,7 +70,7 @@ export async function runExchangeManagementTest(t: GlobalTestState) { }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -98,13 +99,13 @@ export async function runExchangeManagementTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts index 56684f70a..9badfd501 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-exchange-timetravel.ts @@ -40,6 +40,7 @@ import { MerchantService, setupDb, WalletCli, + getPayto } from "../harness/harness.js"; import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js"; @@ -103,7 +104,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -127,13 +128,13 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts index 025e12226..d3ff89ae4 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts @@ -25,6 +25,7 @@ import { MerchantService, setupDb, WalletCli, + getPayto } from "../harness/harness.js"; import { withdrawViaBank, @@ -63,7 +64,7 @@ export async function createMyTestkudosEnvironment( }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -140,7 +141,7 @@ export async function createMyTestkudosEnvironment( await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-merchant-exchange-confusion.ts b/packages/taler-wallet-cli/src/integrationtests/test-merchant-exchange-confusion.ts index 8e8f966b9..1e958fd73 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-merchant-exchange-confusion.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-exchange-confusion.ts @@ -25,6 +25,7 @@ import { MerchantService, setupDb, WalletCli, + getPayto } from "../harness/harness.js"; import { withdrawViaBank, @@ -80,7 +81,7 @@ export async function createConfusedMerchantTestkudosEnvironment( const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -108,13 +109,13 @@ export async function createConfusedMerchantTestkudosEnvironment( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")] }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-delete.ts b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-delete.ts index 589c79120..ef926c4af 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-delete.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-delete.ts @@ -25,6 +25,7 @@ import { MerchantApiClient, MerchantService, setupDb, + getPayto } from "../harness/harness.js"; /** @@ -74,7 +75,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], auth: { method: "external", }, @@ -84,7 +85,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) { await merchant.addInstance({ id: "myinst", name: "Second Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], auth: { method: "external", }, diff --git a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts index fc5e7305a..6f76e2325 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts @@ -24,6 +24,7 @@ import { MerchantApiClient, MerchantService, setupDb, + getPayto } from "../harness/harness.js"; /** @@ -71,7 +72,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { default_wire_transfer_delay: { d_ms: 60000 }, jurisdiction: {}, name: "My Default Instance", - payto_uris: ["payto://x-taler-bank/foo/bar"], + payto_uris: [getPayto("bar")], auth: { method: "token", token: "secret-token:i-am-default", @@ -88,7 +89,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { default_wire_transfer_delay: { d_ms: 60000 }, jurisdiction: {}, name: "My Second Instance", - payto_uris: ["payto://x-taler-bank/foo/bar"], + payto_uris: [getPayto("bar")], auth: { method: "token", token: "secret-token:i-am-myinst", diff --git a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances.ts b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances.ts index 46af87922..1bf6be4cd 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances.ts @@ -25,6 +25,7 @@ import { MerchantApiClient, MerchantService, setupDb, + getPayto } from "../harness/harness.js"; /** @@ -74,7 +75,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], auth: { method: "external", }, @@ -84,7 +85,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) { await merchant.addInstance({ id: "myinst", name: "Second Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], auth: { method: "external", }, diff --git a/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts index 2be01d919..7e421cc35 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts @@ -31,6 +31,7 @@ import { MerchantPrivateApi, BankApi, BankAccessApi, + getPayto } from "../harness/harness.js"; import { FaultInjectedExchangeService, @@ -64,7 +65,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); @@ -107,7 +108,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); console.log("setup done!"); @@ -131,18 +132,21 @@ export async function runPaymentFaultTest(t: GlobalTestState) { await wallet.runPending(); - // Confirm it - - await BankApi.confirmWithdrawalOperation(bank, user, wop); - // Withdraw await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { exchangeBaseUrl: faultyExchange.baseUrl, talerWithdrawUri: wop.taler_withdraw_uri, }); + await wallet.runPending(); + + // Confirm it + + await BankApi.confirmWithdrawalOperation(bank, user, wop); + await wallet.runUntilDone(); + // Check balance await wallet.client.call(WalletApiOperation.GetBalances, {}); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts index 754c3a0e8..3084ecfe0 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts @@ -25,6 +25,7 @@ import { MerchantService, WalletCli, MerchantPrivateApi, + getPayto } from "../harness/harness.js"; import { withdrawViaBank } from "../harness/helpers.js"; import { coin_ct10, coin_u1 } from "../harness/denomStructures"; @@ -54,7 +55,7 @@ async function setupTest( }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); @@ -86,13 +87,13 @@ async function setupTest( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts index 276c532b5..87c4d958b 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts @@ -27,6 +27,7 @@ import { setupDb, BankService, delayMs, + getPayto } from "../harness/harness.js"; import { withdrawViaBank, @@ -84,7 +85,7 @@ async function createTestEnvironment( }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -121,13 +122,13 @@ async function createTestEnvironment( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts index e20d8bdad..b55be9f82 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts @@ -36,6 +36,7 @@ import { MerchantService, setupDb, WalletCli, + getPayto } from "../harness/harness.js"; import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js"; @@ -97,7 +98,7 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -121,13 +122,13 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) { await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); await merchant.addInstance({ id: "minst1", name: "minst1", - paytoUris: ["payto://x-taler-bank/minst1"], + paytoUris: [getPayto("minst1")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts index c6a7f8402..f31220e24 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts @@ -18,7 +18,7 @@ * Imports. */ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { GlobalTestState, MerchantPrivateApi, BankApi } from "../harness/harness.js"; +import { GlobalTestState, MerchantPrivateApi, BankApi, getWireMethod } from "../harness/harness.js"; import { createSimpleTestkudosEnvironment } from "../harness/helpers.js"; /** @@ -43,7 +43,7 @@ export async function runTippingTest(t: GlobalTestState) { { exchange_url: exchange.baseUrl, initial_balance: "TESTKUDOS:10", - wire_method: "x-taler-bank", + wire_method: getWireMethod(), }, ); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts index c21a7279b..c42ae5adf 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts @@ -32,6 +32,7 @@ import { MerchantService, setupDb, WalletCli, + getPayto } from "../harness/harness.js"; import { SimpleTestEnvironment } from "../harness/helpers.js"; @@ -69,7 +70,7 @@ export async function createMyEnvironment( }); const exchangeBankAccount = await bank.createExchangeAccount( - "MyExchange", + "myexchange", "x", ); exchange.addBankAccount("1", exchangeBankAccount); @@ -93,7 +94,7 @@ export async function createMyEnvironment( await merchant.addInstance({ id: "default", name: "Default Instance", - paytoUris: [`payto://x-taler-bank/merchant-default`], + paytoUris: [getPayto("merchant-default")], }); console.log("setup done!"); diff --git a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts index fe719ea62..5ba1fa893 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts @@ -47,12 +47,18 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) { await wallet.runPending(); - // Confirm it + // Abort it await BankApi.abortWithdrawalOperation(bank, user, wop); // Withdraw + // Difference: + // -> with euFin, the wallet selects + // -> with PyBank, the wallet stops _before_ + // + // WHY ?! + // const e = await t.assertThrowsOperationErrorAsync(async () => { await wallet.client.call( WalletApiOperation.AcceptBankIntegratedWithdrawal, diff --git a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts index 35969c78f..25df19e46 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts @@ -47,16 +47,18 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) { await wallet.runPending(); - // Confirm it - - await BankApi.confirmWithdrawalOperation(bank, user, wop); - // Withdraw const r2 = await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { exchangeBaseUrl: exchange.baseUrl, talerWithdrawUri: wop.taler_withdraw_uri, }); + await wallet.runPending(); + + // Confirm it + + await BankApi.confirmWithdrawalOperation(bank, user, wop); + await wallet.runUntilDone(); // Check balance diff --git a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts index b93d1b500..2f88b3024 100644 --- a/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts @@ -50,6 +50,7 @@ export async function runTestWithdrawalManualTest(t: GlobalTestState) { const reservePub: string = wres.reservePub; + // Bug. await BankApi.adminAddIncoming(bank, { exchangeBankAccount, amount: "TESTKUDOS:10", diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index a42480f40..acc592a72 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -175,7 +175,7 @@ export async function getEffectiveDepositAmount( for (let i = 0; i < pcs.coinPubs.length; i++) { const coin = await tx.coins.get(pcs.coinPubs[i]); if (!coin) { - throw Error("can't calculate deposit amountt, coin not found"); + throw Error("can't calculate deposit amount, coin not found"); } const denom = await tx.denominations.get([ coin.exchangeBaseUrl, @@ -193,6 +193,9 @@ export async function getEffectiveDepositAmount( if (!exchangeDetails) { continue; } + // FIXME/NOTE: the line below _likely_ throws exception + // about "find method not found on undefined" when the wireType + // is not supported by the Exchange. const fee = exchangeDetails.wireInfo.feesForType[wireType].find((x) => { return timestampIsBetween( getTimestampNow(), diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index d2071cd53..d6f0626dd 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -174,7 +174,8 @@ async function registerRandomBankUser( const reqUrl = new URL("testing/register", bankBaseUrl).href; const randId = makeId(8); const bankUser: BankUser = { - username: `testuser-${randId}`, + // euFin doesn't allow resource names to have upper case letters. + username: `testuser-${randId.toLowerCase()}`, password: `testpw-${randId}`, }; |