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:
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
*