taler-typescript-core

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

commit f56bb45bf9e85586c121a8c020166d6340b51eae
parent 990479c9818c9650a869f0e8123b220df40bc43d
Author: Florian Dold <florian@dold.me>
Date:   Thu, 25 Sep 2025 17:47:09 +0200

harness: add donau-multi test

Diffstat:
Apackages/taler-harness/src/integrationtests/test-donau-multi.ts | 277+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
2 files changed, 279 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-donau-multi.ts b/packages/taler-harness/src/integrationtests/test-donau-multi.ts @@ -0,0 +1,277 @@ +/* + This file is part of GNU Taler + (C) 2020-2025 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 { + AccessToken, + ConfirmPayResultType, + DonauHttpClient, + Duration, + j2s, + MerchantContractOutputType, + MerchantContractVersion, + OrderOutputType, + OrderVersion, + PreparePayResultType, + succeedOrThrow, + TalerMerchantInstanceHttpClient, +} from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; +import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { + createSimpleTestkudosEnvironmentV3, + withdrawViaBankV3, +} from "../harness/environments.js"; +import { DonauService } from "../harness/harness-donau.js"; +import { + delayMs, + getTestHarnessPaytoForLabel, + GlobalTestState, +} from "../harness/harness.js"; + +export async function runDonauMultiTest(t: GlobalTestState) { + // Set up test environment + + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + commonDb, + } = await createSimpleTestkudosEnvironmentV3(t, undefined, { + merchantUseDonau: true, + walletConfig: { + features: { + enableV1Contracts: true, + }, + }, + }); + + const wres = await withdrawViaBankV3(t, { + walletClient, + bankClient, + amount: "TESTKUDOS:100", + exchange, + }); + await wres.withdrawalFinishedCond; + + const donau = DonauService.create(t, { + currency: "TESTKUDOS", + database: commonDb.connStr, + httpPort: 8084, + name: "donau", + domain: "Bern", + }); + + donau.addCoinConfigList(defaultCoinConfig.map((x) => x("TESTKUDOS"))); + + await donau.start(); + + const merchantClient1 = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl(), + ); + + const inst1 = succeedOrThrow( + await merchantClient1.getCurrentInstanceDetails(merchantAdminAccessToken), + ); + const merchantPub1 = inst1.merchant_pub; + + const donauClient = new DonauHttpClient(donau.baseUrl); + + const currentYear = new Date().getFullYear(); + + const charityResp1 = succeedOrThrow( + await donauClient.createCharity("" as AccessToken, { + charity_pub: merchantPub1, + current_year: currentYear, + max_per_year: "TESTKUDOS:1000", + charity_name: "42", + receipts_to_date: "TESTKUDOS:0", + charity_url: merchant.makeInstanceBaseUrl(), + }), + ); + + const charityId1 = charityResp1["charity_id"]; + + succeedOrThrow( + await merchantClient1.postDonau({ + body: { + charity_id: charityId1, + donau_url: donau.baseUrl, + }, + token: merchantAdminAccessToken, + }), + ); + + // Second merchant instance with donau + + const { accessToken: tok2 } = await merchant.addInstanceWithWireAccount( + { + id: "minst2", + name: "minst2", + paytoUris: [getTestHarnessPaytoForLabel("minst2")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }, + { adminAccessToken: merchantAdminAccessToken }, + ); + + const merchantClient2 = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl("minst2"), + ); + + const inst2 = succeedOrThrow( + await merchantClient2.getCurrentInstanceDetails(tok2), + ); + const merchantPub2 = inst2.merchant_pub; + + console.log(`pub1: ${merchantPub1}`); + console.log(`pub2: ${merchantPub2}`); + + const charityResp2 = succeedOrThrow( + await donauClient.createCharity("" as AccessToken, { + charity_pub: merchantPub2, + current_year: currentYear, + max_per_year: "TESTKUDOS:1000", + charity_name: "43", + receipts_to_date: "TESTKUDOS:0", + charity_url: merchant.makeInstanceBaseUrl("minst2"), + }), + ); + + const charityId2 = charityResp2["charity_id"]; + + succeedOrThrow( + await merchantClient2.postDonau({ + body: { + charity_id: charityId2, + donau_url: donau.baseUrl, + }, + token: tok2, + }), + ); + + // Wait for donaukeysupdate + // We don't use -t since it doesn't seem to work at the moment. + await delayMs(2000); + + { + // Just test the GetDonau request (initial) + const getRes = await walletClient.call(WalletApiOperation.GetDonau, {}); + t.assertDeepEqual(getRes.currentDonauInfo, undefined); + } + + await walletClient.call(WalletApiOperation.SetDonau, { + donauBaseUrl: donau.baseUrl, + taxPayerId: "test-tax-payer", + }); + + { + // Just test the GetDonau request (after setting) + const getRes = await walletClient.call(WalletApiOperation.GetDonau, {}); + t.assertTrue(getRes.currentDonauInfo != null); + t.assertDeepEqual(getRes.currentDonauInfo.donauBaseUrl, donau.baseUrl); + } + + for (let i = 0; i < 3; i++) { + const orderResp = succeedOrThrow( + await merchantClient1.createOrder(merchantAdminAccessToken, { + order: { + version: OrderVersion.V1, + summary: "Test Donation", + choices: [ + { + amount: "TESTKUDOS:9", + outputs: [ + { + type: OrderOutputType.TaxReceipt, + amount: "TESTKUDOS:9", + donau_urls: [donau.baseUrl], + }, + ], + }, + ], + }, + }), + ); + + console.log(`order resp: ${j2s(orderResp)}`); + + let orderStatus = succeedOrThrow( + await merchantClient1.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), + ); + + t.assertTrue(orderStatus.order_status === "unpaid"); + + const preparePayResult = await walletClient.call( + WalletApiOperation.PreparePayForUri, + { + talerPayUri: orderStatus.taler_pay_uri, + }, + ); + + console.log(`preparePayResult: ${j2s(preparePayResult)}`); + + t.assertTrue( + preparePayResult.status === PreparePayResultType.ChoiceSelection, + ); + + t.assertDeepEqual( + preparePayResult.contractTerms.version, + MerchantContractVersion.V1, + ); + const outTok = preparePayResult.contractTerms.choices[0].outputs[0]; + t.assertDeepEqual(outTok.type, MerchantContractOutputType.TaxReceipt); + + // t.assertTrue(!!outTok.amount); + + // t.assertAmountEquals(outTok.amount, "TESTKUDOS:5"); + + const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, { + transactionId: preparePayResult.transactionId, + choiceIndex: 0, + useDonau: true, + }); + + t.assertDeepEqual(r2.type, ConfirmPayResultType.Done); + + // Check if payment was successful. + + orderStatus = succeedOrThrow( + await merchantClient1.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), + ); + + t.assertDeepEqual(orderStatus.order_status, "paid"); + } + + const statements = await walletClient.call( + WalletApiOperation.GetDonauStatements, + {}, + ); + console.log(j2s(statements)); +} + +runDonauMultiTest.suites = ["donau"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -54,6 +54,7 @@ import { runDepositTest } from "./test-deposit.js"; import { runDonauCharityManagementTest } from "./test-donau-charity-management.js"; import { runDonauCompatTest } from "./test-donau-compat.js"; import { runDonauMinusTTest } from "./test-donau-minus-t.js"; +import { runDonauMultiTest } from "./test-donau-multi.js"; import { runDonauTest } from "./test-donau.js"; import { runExchangeDepositTest } from "./test-exchange-deposit.js"; import { runExchangeKycAuthTest } from "./test-exchange-kyc-auth.js"; @@ -385,6 +386,7 @@ const allTests: TestMainFunction[] = [ runDonauTest, runDonauMinusTTest, runDonauCharityManagementTest, + runDonauMultiTest, ]; export interface TestRunSpec {