taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit fb5b0be16750f7c5a11778a82ebb638938314100
parent 8dbf7d74d69703049bdcfd754a698f79165e93fd
Author: Florian Dold <florian@dold.me>
Date:   Mon, 25 Aug 2025 01:58:59 +0200

harness: add test for merchant account selection

Diffstat:
Apackages/taler-harness/src/integrationtests/test-merchant-acctsel.ts | 201+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
2 files changed, 203 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-merchant-acctsel.ts b/packages/taler-harness/src/integrationtests/test-merchant-acctsel.ts @@ -0,0 +1,201 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { + Duration, + j2s, + succeedOrThrow, + TalerMerchantInstanceHttpClient, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { createWalletDaemonWithClient } from "../harness/environments.js"; +import { + ExchangeService, + GlobalTestState, + MerchantService, + setupDb, +} from "../harness/harness.js"; + +export async function runMerchantAcctselTest(t: GlobalTestState) { + // Set up test environment + + const db = await setupDb(t); + + const { walletClient } = await createWalletDaemonWithClient(t, { + name: "wallet", + }); + + const exchange1 = ExchangeService.create(t, { + name: "testexchange-1", + currency: "TESTKUDOS", + httpPort: 8081, + database: db.connStr, + }); + + exchange1.addCoinConfigList(defaultCoinConfig.map((x) => x("TESTKUDOS"))); + + const paytoXtb = + "payto://x-taler-bank/localhost/exchange?receiver-name=exchange"; + + const paytoIban = + "payto://iban/DE76500202009817493529?receiver-name=exchange"; + + await exchange1.addBankAccount("1", { + accountPaytoUri: paytoXtb, + wireGatewayApiBaseUrl: "http://localhost:8082/", + wireGatewayAuth: { + password: "test", + username: "test", + }, + }); + + const exchange2 = ExchangeService.create(t, { + name: "testexchange-2", + currency: "TESTKUDOS", + httpPort: 8181, + database: db.connStr, + }); + + await exchange2.addBankAccount("1", { + accountPaytoUri: paytoIban, + wireGatewayApiBaseUrl: "http://localhost:8082/", + wireGatewayAuth: { + password: "test", + username: "test", + }, + }); + + exchange2.addCoinConfigList(defaultCoinConfig.map((x) => x("TESTKUDOS"))); + + const merchant = await MerchantService.create(t, { + name: "testmerchant-1", + httpPort: 8083, + database: db.connStr, + }); + + merchant.addExchange(exchange1); + merchant.addExchange(exchange2); + + await exchange1.start(); + await exchange2.start(); + + await merchant.start(); + await merchant.pingUntilAvailable(); + + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [paytoIban, paytoXtb], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + const merchApi = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl(), + ); + + { + const ordResp1 = succeedOrThrow( + await merchApi.createOrder(adminAccessToken, { + payment_target: "iban", + order: { + amount: "TESTKUDOS:5", + summary: "Test!", + }, + }), + ); + + console.log(j2s(ordResp1)); + + const ordDet1 = succeedOrThrow( + await merchApi.getOrderDetails(adminAccessToken, ordResp1.order_id), + ); + + t.assertDeepEqual(ordDet1.order_status, "unpaid"); + + await walletClient.call(WalletApiOperation.PreparePayForUri, { + talerPayUri: ordDet1.taler_pay_uri, + }); + + const ordDet2 = succeedOrThrow( + await merchApi.getOrderDetails(adminAccessToken, ordResp1.order_id), + ); + + console.log(j2s(ordDet2)); + + t.assertDeepEqual(ordDet2.order_status, "claimed"); + + const numExch1 = ordDet2.contract_terms.exchanges.filter( + (x) => x.url === exchange1.baseUrl, + ).length; + const numExch2 = ordDet2.contract_terms.exchanges.filter( + (x) => x.url === exchange2.baseUrl, + ).length; + + t.assertDeepEqual(numExch1, 0); + t.assertDeepEqual(numExch2, 1); + } + + { + const ordResp1 = succeedOrThrow( + await merchApi.createOrder(adminAccessToken, { + payment_target: "x-taler-bank", + order: { + amount: "TESTKUDOS:5", + summary: "Test!", + }, + }), + ); + + console.log(j2s(ordResp1)); + + const ordDet1 = succeedOrThrow( + await merchApi.getOrderDetails(adminAccessToken, ordResp1.order_id), + ); + + t.assertDeepEqual(ordDet1.order_status, "unpaid"); + + await walletClient.call(WalletApiOperation.PreparePayForUri, { + talerPayUri: ordDet1.taler_pay_uri, + }); + + const ordDet2 = succeedOrThrow( + await merchApi.getOrderDetails(adminAccessToken, ordResp1.order_id), + ); + + console.log(j2s(ordDet2)); + + t.assertDeepEqual(ordDet2.order_status, "claimed"); + + const numExch1 = ordDet2.contract_terms.exchanges.filter( + (x) => x.url === exchange1.baseUrl, + ).length; + const numExch2 = ordDet2.contract_terms.exchanges.filter( + (x) => x.url === exchange2.baseUrl, + ).length; + + t.assertDeepEqual(numExch1, 1); + t.assertDeepEqual(numExch2, 0); + } +} + +runMerchantAcctselTest.suites = ["merchant"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -93,6 +93,7 @@ import { runKycTwoFormsTest } from "./test-kyc-two-forms.js"; import { runKycWalletDepositAbortTest } from "./test-kyc-wallet-deposit-abort.js"; import { runKycWithdrawalVerbotenTest } from "./test-kyc-withdrawal-verboten.js"; import { runLibeufinBankTest } from "./test-libeufin-bank.js"; +import { runMerchantAcctselTest } from "./test-merchant-acctsel.js"; import { runMerchantCategoriesTest } from "./test-merchant-categories.js"; import { runMerchantExchangeConfusionTest } from "./test-merchant-exchange-confusion.js"; import { runMerchantInstancesDeleteTest } from "./test-merchant-instances-delete.js"; @@ -371,6 +372,7 @@ const allTests: TestMainFunction[] = [ runKycFormCompressionTest, runDepositLargeTest, runDepositTooLargeTest, + runMerchantAcctselTest, ]; export interface TestRunSpec {