taler-typescript-core

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

commit 574d6ece737fc0722e0960f133f98c2dd294baa6
parent b7b77db25f33bd675f3ee721376052dd1710b509
Author: Florian Dold <florian@dold.me>
Date:   Fri, 20 Mar 2026 00:00:20 +0100

harness: test for expired pay transactions in dialog state

Diffstat:
Mpackages/taler-harness/src/integrationtests/test-payment-expired.ts | 198++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 136 insertions(+), 62 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-payment-expired.ts b/packages/taler-harness/src/integrationtests/test-payment-expired.ts @@ -23,6 +23,7 @@ import { PreparePayResultType, TalerMerchantApi, TalerMerchantInstanceHttpClient, + TransactionMajorState, j2s, succeedOrThrow, } from "@gnu-taler/taler-util"; @@ -49,8 +50,13 @@ import { GlobalTestState } from "../harness/harness.js"; export async function runPaymentExpiredTest(t: GlobalTestState) { // Set up test environment - const { walletClient, bankClient, exchange, merchant, merchantAdminAccessToken } = - await createSimpleTestkudosEnvironmentV3(t); + const { + walletClient, + bankClient, + exchange, + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t); // Withdraw digital cash into the wallet. @@ -63,70 +69,138 @@ export async function runPaymentExpiredTest(t: GlobalTestState) { await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - // Order that can only be paid within five minutes. - const order: TalerMerchantApi.Order = { - summary: "Buy me!", - amount: "TESTKUDOS:5", - fulfillment_url: "taler://fulfillment-success/thx", - pay_deadline: AbsoluteTime.toProtocolTimestamp( - AbsoluteTime.addDuration( - AbsoluteTime.now(), - Duration.fromSpec({ minutes: 5 }), - ), - ), - }; - const merchantClient = new TalerMerchantInstanceHttpClient( merchant.makeInstanceBaseUrl(), ); - const orderResp = succeedOrThrow( - await merchantClient.createOrder(merchantAdminAccessToken, { - order, - }), - ); - - 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.assertDeepEqual( - preparePayResult.status, - PreparePayResultType.PaymentPossible, - ); - - await applyTimeTravelV2( - Duration.toMilliseconds(Duration.fromSpec({ hours: 1 })), - { walletClient, exchange, merchant }, - ); - - const confirmPayResult = await walletClient.call( - WalletApiOperation.ConfirmPay, - { transactionId: preparePayResult.transactionId }, - ); - console.log("confirm pay result:"); - console.log(j2s(confirmPayResult)); - await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {}); - - const txns = await walletClient.call(WalletApiOperation.GetTransactions, { - sort: "stable-ascending", - includeRefreshes: true, - }); - console.log(j2s(txns)); - - const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); - console.log(j2s(bal)); - - t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:19.05"); + { + // Order that can only be paid within five minutes. + const order: TalerMerchantApi.Order = { + summary: "Buy me!", + amount: "TESTKUDOS:5", + fulfillment_url: "taler://fulfillment-success/thx", + pay_deadline: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ minutes: 5 }), + ), + ), + }; + + const orderResp = succeedOrThrow( + await merchantClient.createOrder(merchantAdminAccessToken, { + order, + }), + ); + + 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.assertDeepEqual( + preparePayResult.status, + PreparePayResultType.PaymentPossible, + ); + + // Do *not* time-travel the wallet + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ hours: 1 })), + { exchange, merchant }, + ); + + const confirmPayResult = await walletClient.call( + WalletApiOperation.ConfirmPay, + { transactionId: preparePayResult.transactionId }, + ); + console.log("confirm pay result:"); + console.log(j2s(confirmPayResult)); + await walletClient.call( + WalletApiOperation.TestingWaitTransactionsFinal, + {}, + ); + + const txns = await walletClient.call(WalletApiOperation.GetTransactions, { + sort: "stable-ascending", + includeRefreshes: true, + }); + console.log(j2s(txns)); + + const bal = await walletClient.call(WalletApiOperation.GetBalances, {}); + console.log(j2s(bal)); + + t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:19.05"); + } + + { + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ hours: 0 })), + { walletClient, exchange, merchant }, + ); + + // Order that can only be paid within five minutes. + const order: TalerMerchantApi.Order = { + summary: "Buy me!", + amount: "TESTKUDOS:5", + fulfillment_url: "taler://fulfillment-success/thx", + pay_deadline: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ minutes: 5 }), + ), + ), + }; + + const orderResp = succeedOrThrow( + await merchantClient.createOrder(merchantAdminAccessToken, { + order, + }), + ); + + 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.assertDeepEqual( + preparePayResult.status, + PreparePayResultType.PaymentPossible, + ); + + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ hours: 1 })), + { exchange, merchant, walletClient }, + ); + + await walletClient.call(WalletApiOperation.TestingWaitTransactionState, { + transactionId: preparePayResult.transactionId, + txState: { + major: TransactionMajorState.Expired, + }, + }); + } } runPaymentExpiredTest.suites = ["wallet"];