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:
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"];