taler-typescript-core

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

commit f7e6f2085c7783049950f217844d3ba93cde6406
parent 4234ba5cbd9ab0ddc7cc5690c6e74a73465a9d91
Author: Florian Dold <florian@dold.me>
Date:   Thu, 27 Nov 2025 10:29:18 +0100

harness: wip test for AML PDF generation

Diffstat:
Mpackages/taler-harness/src/harness/tops.ts | 47+++++++++++++++++++++++++++++++++--------------
Apackages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
Mpackages/taler-util/src/http-client/exchange-client.ts | 39+++++++++++++++++++++++++++++++++++++++
4 files changed, 139 insertions(+), 14 deletions(-)

diff --git a/packages/taler-harness/src/harness/tops.ts b/packages/taler-harness/src/harness/tops.ts @@ -692,12 +692,13 @@ export async function createTopsEnvironment( const merchantAdminPayto = getTestHarnessPaytoForLabel("merchant-default"); - const { accessToken: adminAccessToken } = await merchant.addInstanceWithWireAccount({ - id: "admin", - name: "Default Instance", - paytoUris: [merchantAdminPayto], - defaultWireTransferDelay: TalerProtocolDuration.fromSpec({ minutes: 1 }), - }); + const { accessToken: adminAccessToken } = + await merchant.addInstanceWithWireAccount({ + id: "admin", + name: "Default Instance", + paytoUris: [merchantAdminPayto], + defaultWireTransferDelay: TalerProtocolDuration.fromSpec({ minutes: 1 }), + }); await bankClient.registerAccountExtended({ name: "merchant-default", @@ -709,12 +710,15 @@ export async function createTopsEnvironment( const merchantInstId = "minst1"; const merchantInstPaytoUri = getTestHarnessPaytoForLabel(merchantInstId); - await merchant.addInstanceWithWireAccount({ - id: merchantInstId, - name: merchantInstId, - paytoUris: [merchantInstPaytoUri], - defaultWireTransferDelay: TalerProtocolDuration.fromSpec({ minutes: 1 }), - }, { adminAccessToken }); + await merchant.addInstanceWithWireAccount( + { + id: merchantInstId, + name: merchantInstId, + paytoUris: [merchantInstPaytoUri], + defaultWireTransferDelay: TalerProtocolDuration.fromSpec({ minutes: 1 }), + }, + { adminAccessToken }, + ); await bankClient.registerAccountExtended({ name: merchantInstId, @@ -834,7 +838,12 @@ export async function doTopsKycAuth( bank: BankServiceHandle; }, ): Promise<{ accessToken: AccessToken; merchantPaytoHash: string }> { - const { merchantClient, wireGatewayApi, exchangeBankAccount, merchantAdminAccessToken } = args; + const { + merchantClient, + wireGatewayApi, + exchangeBankAccount, + merchantAdminAccessToken, + } = args; { const kycStatus = await merchantClient.getCurrentInstanceKycStatus( merchantAdminAccessToken, @@ -904,7 +913,13 @@ export async function doTopsAcceptTos( merchant: MerchantService; }, ): Promise<void> { - const { exchangeClient, merchant, merchantClient, accessToken, merchantAdminAccessToken } = args; + const { + exchangeClient, + merchant, + merchantClient, + accessToken, + merchantAdminAccessToken, + } = args; { const kycInfo = await exchangeClient.checkKycInfo( accessToken, @@ -959,6 +974,7 @@ export async function doTopsAcceptTos( * Helpers for the test. */ export interface MeasuresTestEnvironment { + exchange: ExchangeService; expectInfo: () => Promise<void>; expectFrozen: () => Promise<void>; expectNotFrozen: () => Promise<void>; @@ -975,6 +991,7 @@ export interface MeasuresTestEnvironment { decideReset: () => Promise<void>; challengerPostal: TestfakeChallengerService; challengerSms: TestfakeChallengerService; + accountPaytoHash: string; officerAcc: OfficerAccount; exchangeClient: TalerExchangeHttpClient; } @@ -1118,8 +1135,10 @@ export async function setupMeasuresTestEnvironment( }; return { + exchange, challengerPostal, challengerSms, + accountPaytoHash: merchantPaytoHash, expectInfo, fakeChallenger, decideMeasure: myTriggerMeasure, diff --git a/packages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts b/packages/taler-harness/src/integrationtests/test-tops-aml-pdf.ts @@ -0,0 +1,65 @@ +/* + 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 { Logger, succeedOrThrow } from "@gnu-taler/taler-util"; +import { GlobalTestState } from "../harness/harness.js"; +import { setupMeasuresTestEnvironment } from "../harness/tops.js"; + +export const logger = new Logger("test-tops-aml-measures.ts"); + +/** + * Test that invokes all measures defined for the TOPS deployment. + */ +export async function runTopsAmlPdfTest(t: GlobalTestState) { + // Setup is done, now the real testing can start! + + const { + decideMeasure, + submitForm, + expectInvestigate, + expectNoInvestigate, + officerAcc, + exchangeClient, + accountPaytoHash, + } = await setupMeasuresTestEnvironment(t); + + { + await decideMeasure("kyx"); + await expectNoInvestigate(); + await submitForm("vqf_902_1_customer", { + FORM_ID: "vqf_902_1_customer", + FORM_VERSION: 1, + CUSTOMER_TYPE: "LEGAL_ENTITY", + CUSTOMER_TYPE_VQF: "OTHER", + FULL_NAME: "Alice A", + DOMICILE_ADDRESS: "Castle St. 1\nWondertown", + }); + await expectInvestigate(); + + const res = succeedOrThrow( + await exchangeClient.getAmlAttributesForAccountAsPdf( + officerAcc, + accountPaytoHash, + ), + ); + console.log(`got ${res.byteLength} bytes`); + } +} + +runTopsAmlPdfTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -154,6 +154,7 @@ import { runTopsAmlCustomAddrSmsTest } from "./test-tops-aml-custom-addr-sms.js" import { runTopsAmlKyxNaturalTest } from "./test-tops-aml-kyx-natural.js"; 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 { runTopsPeerTest } from "./test-tops-peer.js"; import { runTermOfServiceFormatTest } from "./test-tos-format.js"; @@ -399,6 +400,7 @@ const allTests: TestMainFunction[] = [ runDonauMultiTest, runDonauIdempotencyTest, runDonauKeychangeTest, + runTopsAmlPdfTest, ]; export interface TestRunSpec { diff --git a/packages/taler-util/src/http-client/exchange-client.ts b/packages/taler-util/src/http-client/exchange-client.ts @@ -1132,6 +1132,45 @@ export class TalerExchangeHttpClient { } } + async getAmlAttributesForAccountAsPdf( + auth: OfficerAccount, + account: string, + params: PaginationParams = {}, + ): Promise< + | OperationOk<ArrayBuffer> + | OperationFail< + | HttpStatusCode.Forbidden + | HttpStatusCode.NotFound + | HttpStatusCode.Conflict + | HttpStatusCode.NoContent + > + > { + const url = new URL(`aml/${auth.id}/attributes/${account}`, this.baseUrl); + + addPaginationParams(url, params); + const resp = await this.fetch(url, { + headers: { + Accept: "application/pdf", + "Taler-AML-Officer-Signature": encodeCrock( + signAmlQuery(auth.signingKey), + ), + }, + }); + + switch (resp.status) { + case HttpStatusCode.Ok: { + return opFixedSuccess(await resp.bytes()); + } + case HttpStatusCode.NoContent: + case HttpStatusCode.Forbidden: + case HttpStatusCode.NotFound: + case HttpStatusCode.Conflict: + return opKnownHttpFailure(resp.status, resp); + default: + return opUnknownHttpFailure(resp); + } + } + /** * https://docs.taler.net/core/api-exchange.html#post--aml-$OFFICER_PUB-decision *