taler-typescript-core

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

commit 679681c5ebd0317f77c1c03fcd0e8bed69d793d8
parent 0c154d644dc2c809e56e50bf48b90663a0b17088
Author: Florian Dold <florian@dold.me>
Date:   Wed, 27 May 2026 15:02:30 +0200

harness: reproducer for missing token families in merchant

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

diff --git a/packages/taler-harness/src/integrationtests/test-merchant-tokenfamilies.ts b/packages/taler-harness/src/integrationtests/test-merchant-tokenfamilies.ts @@ -0,0 +1,159 @@ +/* + This file is part of GNU Taler + (C) 2020 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. + +NU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { + AbsoluteTime, + Duration, + Order, + OrderInputType, + OrderOutputType, + succeedOrThrow, + TalerMerchantInstanceHttpClient, + TalerProtocolTimestamp, + TokenFamilyKind, +} from "@gnu-taler/taler-util"; +import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { + applyTimeTravelV2, + createSimpleTestkudosEnvironmentV3, +} from "../harness/environments.js"; +import { GlobalTestState } from "../harness/harness.js"; + +export async function runMerchantTokenfamiliesTest(t: GlobalTestState) { + let { merchant, walletClient, merchantAdminAccessToken } = + await createSimpleTestkudosEnvironmentV3( + t, + defaultCoinConfig.map((x) => x("TESTKUDOS")), + { + walletConfig: { + features: { + enableV1Contracts: true, + }, + }, + }, + ); + + const merchantApi = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl(), + ); + + const tokenFamilyJson = { + kind: TokenFamilyKind.Discount, + slug: "test_discount", + name: "Test discount", + description: "This is a test discount", + description_i18n: {}, + valid_after: TalerProtocolTimestamp.now(), + valid_before: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ years: 1 }), + ), + ), + duration: Duration.toTalerProtocolDuration(Duration.fromSpec({ days: 90 })), + validity_granularity: Duration.toTalerProtocolDuration( + Duration.fromSpec({ days: 1 }), + ), + }; + + // setup discount token family + succeedOrThrow( + await merchantApi.createTokenFamily( + merchantAdminAccessToken, + tokenFamilyJson, + ), + ); + + const orderJsonDiscount: Order = { + version: 1, + summary: "Test order", + timestamp: TalerProtocolTimestamp.now(), + pay_deadline: AbsoluteTime.toProtocolTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ days: 365 }), + ), + ), + choices: [ + { + amount: "TESTKUDOS:2", + inputs: [], + outputs: [ + { + type: OrderOutputType.Token, + token_family_slug: "test_discount", + }, + ], + }, + { + amount: "TESTKUDOS:1", + inputs: [ + { + type: OrderInputType.Token, + token_family_slug: "test_discount", + }, + ], + outputs: [], + }, + ], + }; + + { + const orderResp = succeedOrThrow( + await merchantApi.createOrder(merchantAdminAccessToken, { + order: orderJsonDiscount, + }), + ); + + let orderStatus = succeedOrThrow( + await merchantApi.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), + ); + + t.assertTrue(orderStatus.order_status === "unpaid"); + } + + await applyTimeTravelV2( + Duration.toMilliseconds(Duration.fromSpec({ days: 120 })), + { + merchant, + }, + ); + + { + const orderResp = succeedOrThrow( + await merchantApi.createOrder(merchantAdminAccessToken, { + order: orderJsonDiscount, + }), + ); + + let orderStatus = succeedOrThrow( + await merchantApi.getOrderDetails( + merchantAdminAccessToken, + orderResp.order_id, + ), + ); + + t.assertTrue(orderStatus.order_status === "unpaid"); + } +} + +runMerchantTokenfamiliesTest.suites = ["merchant"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -125,6 +125,7 @@ import { runMerchantSelfProvisionActivationTest } from "./test-merchant-self-pro import { runMerchantSelfProvisionForgotPasswordTest } from "./test-merchant-self-provision-forgot-password.js"; import { runMerchantSelfProvisionInactiveAccountPermissionsTest } from "./test-merchant-self-provision-inactive-account-permissions.js"; import { runMerchantSpecPublicOrdersTest } from "./test-merchant-spec-public-orders.js"; +import { runMerchantTokenfamiliesTest } from "./test-merchant-tokenfamilies.js"; import { runMerchantWireTest } from "./test-merchant-wire.js"; import { runMultiExchangeTest } from "./test-multiexchange.js"; import { runOtpTest } from "./test-otp.js"; @@ -442,6 +443,7 @@ const allTests: TestMainFunction[] = [ runKycMerchantWalletReuseTest, runWithdrawalShortenTest, runMerchantRefundFeesTest, + runMerchantTokenfamiliesTest, ]; export interface TestRunSpec {