taler-typescript-core

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

commit b8edc1581b56a9ed5a1895cb386f39fb9c6ae904
parent 501e518906e8b9b6fe200684654eae4a7d86ea39
Author: Florian Dold <florian@dold.me>
Date:   Mon,  6 Jul 2026 12:40:24 +0200

harness: migrate test cases to preparePay...V2

The donau-compat test has been removed, since wallet clients must now
support contracts v1.

Diffstat:
Dpackages/taler-harness/src/integrationtests/test-donau-compat.ts | 168-------------------------------------------------------------------------------
Mpackages/taler-harness/src/integrationtests/test-paivana-repurchase.ts | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Mpackages/taler-harness/src/integrationtests/test-paivana.ts | 27+++++++++++----------------
Mpackages/taler-harness/src/integrationtests/test-repurchase-v1.ts | 13+++++++++----
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2--
5 files changed, 92 insertions(+), 226 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-donau-compat.ts b/packages/taler-harness/src/integrationtests/test-donau-compat.ts @@ -1,168 +0,0 @@ -/* - 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 { - ConfirmPayResultType, - DonauHttpClient, - HttpStatusCode, - j2s, - OrderOutputType, - OrderVersion, - PreparePayResultType, - succeedOrThrow, - TalerErrorCode, - 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 { GlobalTestState } from "../harness/harness.js"; - -/** - * Test that sets up DONAU but pays without enabling - * DONAU on the client side. - */ -export async function runDonauCompatTest(t: GlobalTestState) { - // Set up test environment - - const { - walletClient, - bankClient, - exchange, - merchant, - merchantAdminAccessToken, - commonDb, - } = await createSimpleTestkudosEnvironmentV3(t); - - const wres = await withdrawViaBankV3(t, { - walletClient, - bankClient, - amount: "TESTKUDOS:20", - exchange, - }); - await wres.withdrawalFinishedCond; - - const donau = DonauService.create(t, { - currency: "KUDOS", - database: commonDb.connStr, - httpPort: 8084, - name: "donau", - domain: "Bern", - }); - - donau.addCoinConfigList(defaultCoinConfig.map((x) => x("TESTKUDOS"))); - - await donau.start(); - - const donauClient = new DonauHttpClient(donau.baseUrl); - - const config = await donauClient.getConfig(); - console.log(`config: ${j2s(config)}`); - - const keys = await donauClient.getKeys(); - console.log(`keys: ${j2s(keys)}`); - - const merchantClient = new TalerMerchantInstanceHttpClient( - merchant.makeInstanceBaseUrl(), - ); - - { - // Check what happens if we try to add a donau service - // where the charity_id does not exist. - const postDonauResp = await merchantClient.postDonau({ - body: { - charity_id: 42, - donau_url: donau.baseUrl, - }, - token: merchantAdminAccessToken, - }); - t.assertDeepEqual(postDonauResp.case, HttpStatusCode.BadGateway); - t.assertDeepEqual( - postDonauResp.detail?.code, - TalerErrorCode.DONAU_CHARITY_NOT_FOUND, - ); - console.log(j2s(postDonauResp)); - } - - const orderResp = succeedOrThrow( - await merchantClient.createOrder(merchantAdminAccessToken, { - order: { - version: OrderVersion.V1, - summary: "Test Donation", - choices: [ - { - amount: "TESTKUDOS:10", - outputs: [ - { - type: OrderOutputType.TaxReceipt, - amount: "TESTKUDOS:5", - donau_urls: [donau.baseUrl], - }, - ], - }, - ], - }, - }), - ); - - console.log(`order resp: ${j2s(orderResp)}`); - - let orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails( - merchantAdminAccessToken, - orderResp.order_id, - ), - ); - - t.assertTrue(orderStatus.order_status === "unpaid"); - - const preparePayResult = await walletClient.call( - WalletApiOperation.PreparePayForUri, - { - talerPayUri: orderStatus.taler_pay_uri, - }, - ); - - t.assertTrue( - preparePayResult.status === PreparePayResultType.PaymentPossible, - ); - - const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, { - transactionId: preparePayResult.transactionId, - }); - - t.assertDeepEqual(r2.type, ConfirmPayResultType.Done); - - // Check if payment was successful. - - orderStatus = succeedOrThrow( - await merchantClient.getOrderDetails( - merchantAdminAccessToken, - orderResp.order_id, - ), - ); - - t.assertDeepEqual(orderStatus.order_status, "paid"); -} - -runDonauCompatTest.suites = ["donau"]; diff --git a/packages/taler-harness/src/integrationtests/test-paivana-repurchase.ts b/packages/taler-harness/src/integrationtests/test-paivana-repurchase.ts @@ -18,20 +18,21 @@ * Imports. */ import { - ConfirmPayResultType, encodeCrock, getRandomBytes, Logger, - TalerPayTemplateUri, Result, stringToBytes, succeedOrThrow, TalerMerchantInstanceHttpClient, + TalerPayTemplateUri, TalerProtocolTimestamp, TalerUriAction, TalerUris, timestampRoundedToBuffer, - WalletNotification, + TransactionMajorState, + TransactionMinorState, + TransactionType, } from "@gnu-taler/taler-util"; import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -47,7 +48,11 @@ const harnessHttpLib = createPlatformHttpLib({ }); export const logger = new Logger("test-paivana.ts"); -export function createPaivanaSessionFor(website: string) { +export function createPaivanaSessionFor(website: string): { + paivanaId: string; + nonce: string; + time: TalerProtocolTimestamp; +} { const now = new Date().getTime(); const cur_time = Math.floor(now / 1000); // + 60*60*24; const time = TalerProtocolTimestamp.fromSeconds(cur_time); @@ -84,12 +89,6 @@ export async function runPaivanaRepurchaseTest(t: GlobalTestState) { paivanaWebsite: ".*.html", // block all html pages }); - const notifs: WalletNotification[] = []; - - walletClient.addNotificationListener((x) => { - notifs.push(x); - }); - const withdrawalRes = await withdrawViaBankV3(t, { walletClient, bankClient, @@ -136,43 +135,80 @@ export async function runPaivanaRepurchaseTest(t: GlobalTestState) { logger.info("3) pay template", newTemplate, talerPayTemplateUri); const templateStatus = await walletClient.call( - WalletApiOperation.PreparePayForTemplate, + WalletApiOperation.PreparePayForTemplateV2, { talerPayTemplateUri }, ); - // t.assertTrue( - // templateStatus.status === PreparePayResultType.PaymentPossible, - // ); - const talerPayUri = templateStatus.talerUri; - logger.info("4) pay order", talerPayUri); - - const payStatus = await walletClient.call( - WalletApiOperation.PreparePayForUri, - { talerPayUri }, - ); - // t.assertTrue(payStatus.status === PreparePayResultType.PaymentPossible); + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: templateStatus.transactionId, + txState: [ + { + major: TransactionMajorState.Failed, + minor: TransactionMinorState.Repurchase, + }, + { + major: TransactionMajorState.Dialog, + minor: TransactionMinorState.Proposed, + }, + ], + }); - const startPayment = await walletClient.call( - WalletApiOperation.ConfirmPay, + const txDet = await walletClient.call( + WalletApiOperation.GetTransactionById, { - transactionId: payStatus.transactionId, + transactionId: templateStatus.transactionId, }, ); + t.assertDeepEqual(txDet.type, TransactionType.Payment); - // t.assertTrue(startPayment.type === ConfirmPayResultType.Pending); - await walletClient.call( - WalletApiOperation.TestingWaitTransactionsFinal, - {}, - ); - const payment = await walletClient.call(WalletApiOperation.ConfirmPay, { - transactionId: payStatus.transactionId, - }); - t.assertTrue(payment.type === ConfirmPayResultType.Done); - logger.info("5) order paid", payment.contractTerms.fulfillment_url); + let orderId: string; + + if (txDet.txState.major === TransactionMajorState.Failed) { + const repurchaseTxId = txDet.repurchaseTransactionId; + + t.assertTrue(repurchaseTxId != null); + + await walletClient.call( + WalletApiOperation.TestingWaitTransactionState, + { + transactionId: repurchaseTxId, + txState: { + major: TransactionMajorState.Done, + }, + }, + ); + + const repurchaseTxDet = await walletClient.call( + WalletApiOperation.GetTransactionById, + { + transactionId: repurchaseTxId, + }, + ); + t.assertDeepEqual(repurchaseTxDet.type, TransactionType.Payment); + t.assertTrue(!!repurchaseTxDet.info); + orderId = repurchaseTxDet.info.orderId; + } else { + await walletClient.call(WalletApiOperation.ConfirmPay, { + transactionId: txDet.transactionId, + choiceIndex: 0, + }); + t.assertTrue(!!txDet.info); + orderId = txDet.info.orderId; + + await walletClient.call( + WalletApiOperation.TestingWaitTransactionState, + { + transactionId: txDet.transactionId, + txState: { + major: TransactionMajorState.Done, + }, + }, + ); + } const orderStatus = succeedOrThrow( await merchantClient.getOrderDetails( merchantAdminAccessToken, - payment.contractTerms.order_id, + orderId, { sessionId: session.paivanaId, }, diff --git a/packages/taler-harness/src/integrationtests/test-paivana.ts b/packages/taler-harness/src/integrationtests/test-paivana.ts @@ -19,7 +19,6 @@ */ import { Logger, - PreparePayResultType, Result, succeedOrThrow, TalerMerchantInstanceHttpClient, @@ -110,23 +109,19 @@ export async function runPaivanaTest(t: GlobalTestState) { logger.info("3) pay template", newTemplate, talerPayTemplateUri); const templateStatus = await walletClient.call( - WalletApiOperation.PreparePayForTemplate, + WalletApiOperation.PreparePayForTemplateV2, { talerPayTemplateUri }, ); - t.assertTrue( - templateStatus.status === PreparePayResultType.PaymentPossible, - ); - const talerPayUri = templateStatus.talerUri; - logger.info("4) pay order", talerPayUri); - - const payStatus = await walletClient.call( - WalletApiOperation.PreparePayForUri, - { talerPayUri }, - ); - t.assertTrue(payStatus.status === PreparePayResultType.PaymentPossible); - + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: templateStatus.transactionId, + txState: { + major: TransactionMajorState.Dialog, + minor: "*", + }, + }); await walletClient.call(WalletApiOperation.ConfirmPay, { - transactionId: payStatus.transactionId, + transactionId: templateStatus.transactionId, + choiceIndex: 0, }); await walletClient.call( @@ -136,7 +131,7 @@ export async function runPaivanaTest(t: GlobalTestState) { const paymentTx = await walletClient.call( WalletApiOperation.GetTransactionById, { - transactionId: payStatus.transactionId, + transactionId: templateStatus.transactionId, includeContractTerms: true, }, ); diff --git a/packages/taler-harness/src/integrationtests/test-repurchase-v1.ts b/packages/taler-harness/src/integrationtests/test-repurchase-v1.ts @@ -24,6 +24,7 @@ import { succeedOrThrow, TalerCorebankApiClient, TalerMerchantInstanceHttpClient, + TransactionMajorState, TransactionType, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; @@ -92,15 +93,19 @@ export async function runRepurchaseV1Test(t: GlobalTestState) { t.assertTrue(orderOneStatus.order_status === "unpaid"); const preparePayOneResult = await walletClient.call( - WalletApiOperation.PreparePayForUri, + WalletApiOperation.PreparePayForUriV2, { talerPayUri: orderOneStatus.taler_pay_uri, }, ); - t.assertTrue( - preparePayOneResult.status === PreparePayResultType.PaymentPossible, - ); + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: preparePayOneResult.transactionId, + txState: { + major: TransactionMajorState.Dialog, + minor: "*", + }, + }); const confirmPayResp = await walletClient.call( WalletApiOperation.ConfirmPay, diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -54,7 +54,6 @@ import { runDepositTooLargeTest } from "./test-deposit-too-large.js"; import { runDepositTwiceTest } from "./test-deposit-twice.js"; import { runDepositTest } from "./test-deposit.js"; import { runDonauCharityManagementTest } from "./test-donau-charity-management.js"; -import { runDonauCompatTest } from "./test-donau-compat.js"; import { runDonauIdempotencyTest } from "./test-donau-idempotency.js"; import { runDonauKeychangeTest } from "./test-donau-keychange.js"; import { runDonauMinusTTest } from "./test-donau-minus-t.js"; @@ -408,7 +407,6 @@ const allTests: TestMainFunction[] = [ runMerchantAcctselTest, runLibeufinConversionTest, runDenomLostComplexTest, - runDonauCompatTest, runDonauTest, runDonauMinusTTest, runDonauCharityManagementTest,