taler-typescript-core

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

commit 30ff397ca1fdae08433279690f69b455ca9e5b3f
parent 5dbaffcac8889de362ebf6f28502ead0ac9efdb8
Author: Florian Dold <florian@dold.me>
Date:   Mon, 26 May 2025 09:54:15 +0200

harness: re-add test

Diffstat:
Apackages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts | 253+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
2 files changed, 255 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts b/packages/taler-harness/src/integrationtests/test-kyc-merchant-deposit-form.ts @@ -0,0 +1,253 @@ +/* + This file is part of GNU Taler + (C) 2024 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 { + codecForAccountKycRedirects, + codecForKycProcessClientInformation, + codecForQueryInstancesResponse, + Configuration, + j2s, + Logger, + MerchantAccountKycRedirectsResponse, + MerchantAccountKycStatus, + succeedOrThrow, + TalerMerchantApi, +} from "@gnu-taler/taler-util"; +import { + readResponseJsonOrThrow, + readSuccessResponseJsonOrThrow, +} from "@gnu-taler/taler-util/http"; +import { + configureCommonKyc, + createKycTestkudosEnvironment, +} from "../harness/environments.js"; +import { + delayMs, + GlobalTestState, + harnessHttpLib, +} from "../harness/harness.js"; + +const logger = new Logger(`test-kyc-merchant-deposit.ts`); + +const myAmlConfig = ` +# Fallback measure on errors. +[kyc-measure-freeze-investigate] +CHECK_NAME = skip +PROGRAM = freeze-investigate +VOLUNTARY = NO +CONTEXT = {} + +[aml-program-freeze-investigate] +DESCRIPTION = "Fallback measure on errors that freezes the account and asks AML staff to investigate the system failure." +COMMAND = taler-exchange-helper-measure-freeze +ENABLED = YES +FALLBACK = freeze-investigate + +[aml-program-inform-investigate] +DESCRIPTION = "Measure that asks AML staff to investigate an account and informs the account owner about it." +COMMAND = taler-exchange-helper-measure-inform-investigate +ENABLED = YES +FALLBACK = freeze-investigate + +[kyc-check-form-gls-merchant-onboarding] +TYPE = FORM +FORM_NAME = gls-merchant-onboarding +DESCRIPTION = "GLS Merchant Onboarding" +DESCRIPTION_I18N = {} +OUTPUTS = +FALLBACK = freeze-investigate + +[kyc-measure-merchant-onboarding] +CHECK_NAME = form-gls-merchant-onboarding +PROGRAM = inform-investigate +CONTEXT = {} +VOLUNTARY = NO + +[kyc-rule-deposit-limit-zero] +OPERATION_TYPE = DEPOSIT +NEXT_MEASURES = merchant-onboarding +EXPOSED = YES +ENABLED = YES +THRESHOLD = TESTKUDOS:0 +TIMEFRAME = "1 days" +`; + +function adjustExchangeConfig(config: Configuration) { + configureCommonKyc(config); + config.loadFromString(myAmlConfig); +} + +export async function runKycMerchantDepositFormTest(t: GlobalTestState) { + // Set up test environment + + const { + merchant, + bankClient, + exchange, + exchangeBankAccount, + amlKeypair, + wireGatewayApi, + } = await createKycTestkudosEnvironment(t, { + adjustExchangeConfig, + }); + + let accountPub: string; + + { + const instanceUrl = new URL("private", merchant.makeInstanceBaseUrl()); + const resp = await harnessHttpLib.fetch(instanceUrl.href); + const parsedResp = await readSuccessResponseJsonOrThrow( + resp, + codecForQueryInstancesResponse(), + ); + accountPub = parsedResp.merchant_pub; + } + + // Withdraw digital cash into the wallet. + + let kycRespOne: MerchantAccountKycRedirectsResponse | undefined = undefined; + + while (1) { + const kycStatusUrl = new URL("private/kyc", merchant.makeInstanceBaseUrl()) + .href; + logger.info(`requesting GET ${kycStatusUrl}`); + const resp = await harnessHttpLib.fetch(kycStatusUrl); + if (resp.status === 200) { + kycRespOne = await readSuccessResponseJsonOrThrow( + resp, + codecForAccountKycRedirects(), + ); + break; + } + // Wait 500ms + await delayMs(500); + } + + t.assertTrue(!!kycRespOne); + + logger.info(`mechant kyc status: ${j2s(kycRespOne)}`); + + t.assertDeepEqual( + kycRespOne.kyc_data[0].status, + MerchantAccountKycStatus.KYC_WIRE_REQUIRED, + ); + + t.assertDeepEqual(kycRespOne.kyc_data[0].exchange_http_status, 404); + + t.assertTrue( + (kycRespOne.kyc_data[0].limits?.length ?? 0) > 0, + "kyc status should contain non-empty limits", + ); + + // Order creation should fail! + await t.runSpanAsync("order creation should be rejected", async () => { + let url = new URL("private/orders", merchant.makeInstanceBaseUrl()); + const order = { + summary: "Test", + amount: "TESTKUDOS:5", + fulfillment_url: "taler://fulfillment-success/thx", + } satisfies TalerMerchantApi.Order; + const resp = await harnessHttpLib.fetch(url.href, { + method: "POST", + body: { + order, + }, + }); + + logger.info(`order creation status: ${resp.status}`); + t.assertTrue(resp.status !== 200); + }); + + await bankClient.registerAccountExtended({ + name: "merchant-default", + password: "merchant-default", + username: "merchant-default", + payto_uri: kycRespOne.kyc_data[0].payto_uri, //this bank user needs to have the same payto that the exchange is asking from + }); + succeedOrThrow( + await wireGatewayApi.addKycAuth({ + auth: exchangeBankAccount.wireGatewayAuth, + body: { + amount: "TESTKUDOS:0.1", + account_pub: accountPub, + debit_account: kycRespOne.kyc_data[0].payto_uri, + }, + }), + ); + + let kycRespTwo: MerchantAccountKycRedirectsResponse | undefined = undefined; + + // We do this in a loop as a work-around. + // Not exactly the correct behavior from the merchant right now. + while (true) { + const kycStatusLongpollUrl = new URL( + "private/kyc", + merchant.makeInstanceBaseUrl(), + ); + kycStatusLongpollUrl.searchParams.set("lpt", "1"); + const resp = await harnessHttpLib.fetch(kycStatusLongpollUrl.href); + t.assertDeepEqual(resp.status, 200); + const parsedResp = await readSuccessResponseJsonOrThrow( + resp, + codecForAccountKycRedirects(), + ); + logger.info(`kyc resp 2: ${j2s(parsedResp)}`); + if (parsedResp.kyc_data[0].payto_kycauths == null) { + kycRespTwo = parsedResp; + break; + } + // Wait 500ms + await delayMs(500); + } + + // FIXME: Use exchange client! + + const infoResp = await harnessHttpLib.fetch( + new URL(`kyc-info/${kycRespTwo.kyc_data[0].access_token}`, exchange.baseUrl) + .href, + ); + + const clientInfo = await readResponseJsonOrThrow( + infoResp, + codecForKycProcessClientInformation(), + ); + + console.log(j2s(clientInfo)); + + const kycId = clientInfo.requirements[0].id; + t.assertTrue(typeof kycId === "string"); + + const uploadResp = await harnessHttpLib.fetch( + new URL(`kyc-upload/${kycId}`, exchange.baseUrl).href, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: { + full_name: "Alice Abc", + birthdate: "2000-01-01", + }, + }, + ); + + console.log("resp status", uploadResp.status); +} + +runKycMerchantDepositFormTest.suites = ["wallet", "merchant", "kyc"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -74,6 +74,7 @@ import { runKycFormBadMeasureTest } from "./test-kyc-form-bad-measure.js"; import { runKycFormWithdrawalTest } from "./test-kyc-form-withdrawal.js"; import { runKycMerchantActivateBankAccountTest } from "./test-kyc-merchant-activate-bank-account.js"; import { runKycMerchantAggregateTest } from "./test-kyc-merchant-aggregate.js"; +import { runKycMerchantDepositFormTest } from "./test-kyc-merchant-deposit-form.js"; import { runKycMerchantDepositRewriteTest } from "./test-kyc-merchant-deposit-rewrite.js"; import { runKycMerchantDepositTest } from "./test-kyc-merchant-deposit.js"; import { runKycNewMeasureTest } from "./test-kyc-new-measure.js"; @@ -345,6 +346,7 @@ const allTests: TestMainFunction[] = [ runKycBalanceWithdrawalChangeManualTest, runUtilMerchantClientTest, runKycWalletDepositAbortTest, + runKycMerchantDepositFormTest, ]; export interface TestRunSpec {