taler-typescript-core

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

commit 78ac0beae5ca9d1b91aee388ac7de744fe37644d
parent 119c423765650e10263ce8462e9fbbffd6506eb1
Author: Florian Dold <florian@dold.me>
Date:   Mon, 23 Feb 2026 20:10:34 +0100

harness: test for ToS acceptance

Diffstat:
Apackages/taler-harness/src/integrationtests/test-tops-merchant-tos.ts | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
Mpackages/taler-util/src/types-taler-merchant.ts | 3+++
3 files changed, 128 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-tops-merchant-tos.ts b/packages/taler-harness/src/integrationtests/test-tops-merchant-tos.ts @@ -0,0 +1,123 @@ +/* + This file is part of GNU Taler + (C) 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 { + j2s, + Logger, + MerchantAccountKycStatus, + succeedOrThrow, + TalerExchangeHttpClient, + TalerMerchantInstanceHttpClient, +} from "@gnu-taler/taler-util"; +import { GlobalTestState, harnessHttpLib } from "../harness/harness.js"; +import { createTopsEnvironment, doTopsKycAuth } from "../harness/tops.js"; + +export const logger = new Logger("test-tops-aml.ts"); + +/** + * Test for ToS acceptance by the merchant. + * In particular, we test that long-polling works and + * we do not manually have to run taler-merchant-kyccheck with the -t option. + */ +export async function runTopsMerchantTosTest(t: GlobalTestState) { + // Set up test environment + const { + exchange, + officerAcc, + merchant, + exchangeBankAccount, + wireGatewayApi, + merchantAdminAccessToken, + bank, + } = await createTopsEnvironment(t); + + const merchantClient = new TalerMerchantInstanceHttpClient( + merchant.makeInstanceBaseUrl(), + ); + const exchangeClient = new TalerExchangeHttpClient(exchange.baseUrl, { + httpClient: harnessHttpLib, + }); + + // Do KYC auth transfer + const { accessToken } = await doTopsKycAuth(t, { + merchantClient, + exchangeBankAccount, + wireGatewayApi, + merchantAdminAccessToken, + bank, + }); + + { + const kycInfo = await exchangeClient.checkKycInfo( + accessToken, + undefined, + undefined, + ); + console.log(j2s(kycInfo)); + + t.assertDeepEqual(kycInfo.case, "ok"); + t.assertDeepEqual(kycInfo.body.requirements.length, 1); + t.assertDeepEqual(kycInfo.body.requirements[0].form, "accept-tos"); + const requirementId = kycInfo.body.requirements[0].id; + t.assertTrue(typeof requirementId === "string"); + + const uploadRes = await exchangeClient.uploadKycForm(requirementId, { + FORM_ID: "accept-tos", + FORM_VERSION: 1, + ACCEPTED_TERMS_OF_SERVICE: "v1", + DOWNLOADED_TERMS_OF_SERVICE: true, + }); + console.log("upload res", uploadRes); + t.assertDeepEqual(uploadRes.case, "ok"); + } + + { + const kycInfo = await exchangeClient.checkKycInfo( + accessToken, + undefined, + undefined, + ); + console.log(j2s(kycInfo)); + } + + { + const kycStatus = succeedOrThrow( + await merchantClient.getCurrentInstanceKycStatus( + merchantAdminAccessToken, + { + exchangeURL: exchange.baseUrl, + longpoll: { + type: "state-enter", + status: MerchantAccountKycStatus.READY, + timeout: 10000, + }, + }, + ), + ); + logger.info(`kyc status after accept-tos: ${j2s(kycStatus)}`); + t.assertDeepEqual(kycStatus.kycRequired, true); + const myRow = kycStatus.kyc_data.find( + (x) => x.exchange_url === exchange.baseUrl, + ); + t.assertTrue(myRow != null); + t.assertDeepEqual(myRow.status, MerchantAccountKycStatus.READY); + } +} + +runTopsMerchantTosTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -164,6 +164,7 @@ import { runTopsAmlLegiTest } from "./test-tops-aml-legi.js"; import { runTopsAmlMeasuresTest } from "./test-tops-aml-measures.js"; import { runTopsAmlPdfTest } from "./test-tops-aml-pdf.js"; import { runTopsChallengerTwiceTest } from "./test-tops-challenger-twice.js"; +import { runTopsMerchantTosTest } from "./test-tops-merchant-tos.js"; import { runTopsPeerTest } from "./test-tops-peer.js"; import { runTermOfServiceFormatTest } from "./test-tos-format.js"; import { runUtilMerchantClientTest } from "./test-util-merchant-client.js"; @@ -425,6 +426,7 @@ const allTests: TestMainFunction[] = [ runMerchantReportsTest, runExchangeMerchantKycAuthTest, runMerchantKycAuthMultiTest, + runTopsMerchantTosTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/types-taler-merchant.ts b/packages/taler-util/src/types-taler-merchant.ts @@ -1445,16 +1445,19 @@ export type KycEtag = string; export type KycLongPollingReasonWaitForStateEnter = { type: "state-enter"; status: MerchantAccountKycStatus; + // FIXME: Unit! timeout: number; }; export type KycLongPollingReasonWaitForStateExit = { type: "state-exit"; status: MerchantAccountKycStatus; + // FIXME: Unit! timeout: number; }; export type KycLongPollingReasonWaitForStateChange = { type: "state-change"; etag: KycEtag; + // FIXME: Unit! timeout: number; };