taler-typescript-core

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

commit 8a7ef910bfb3438cf8ab5ed130c7327faea2e869
parent f775b5cd8da7fb4cdcf03de9df77b0f894059f30
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Mon,  9 Mar 2026 17:09:04 -0300

#11215 add integration test

Diffstat:
Apackages/taler-harness/src/integrationtests/test-merchant-self-provision-activation-two-bank-account.ts | 226+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/taler-harness/src/integrationtests/testrunner.ts | 2++
2 files changed, 228 insertions(+), 0 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-merchant-self-provision-activation-two-bank-account.ts b/packages/taler-harness/src/integrationtests/test-merchant-self-provision-activation-two-bank-account.ts @@ -0,0 +1,226 @@ +/* + This file is part of GNU Taler + (C) 2021 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 { + alternativeOrThrow, + Duration, + HttpStatusCode, + LoginTokenScope, + MerchantAuthMethod, + succeedOrThrow, + TalerMerchantInstanceHttpClient, + TalerMerchantManagementHttpClient, + TanChannel, +} from "@gnu-taler/taler-util"; +import { createSimpleTestkudosEnvironmentV3 } from "harness/environments.js"; +import { startTanHelper } from "harness/tan-helper.js"; +import { randomBytes } from "node:crypto"; +import { chmodSync, writeFileSync } from "node:fs"; +import { getTestHarnessPaytoForLabel, GlobalTestState } from "../harness/harness.js"; +import { solveMFA } from "./test-merchant-self-provision-inactive-account-permissions.js"; + +/** + * Do basic checks on instance management and authentication. + */ +export async function runMerchantSelfProvisionActivationTwoBankAccountsTest( + t: GlobalTestState, +) { + // Set up test environment + + // FIXME: maybe merchant can use commands? + const RND = randomBytes(10).toString("hex"); + const socketFile = `${t.testDir}/tan-helper-${RND}.socket`; + const helperScript = `${t.testDir}/harness-helper-${RND}.sh`; + writeFileSync( + helperScript, + `#!/bin/bash +taler-harness run-helper --socket ${socketFile} -- $@ +`, + ); + chmodSync(helperScript, "777"); + + const { + merchant, + merchantAdminAccessToken, + } = await createSimpleTestkudosEnvironmentV3(t, undefined, { + additionalMerchantConfig(m) { + m.modifyConfig(async (cfg) => { + cfg.setString("merchant", "ENABLE_SELF_PROVISIONING", "yes"); + cfg.setString("merchant", "HELPER_SMS", helperScript); + cfg.setString("merchant", "HELPER_EMAIL", helperScript); + cfg.setString("merchant", "MANDATORY_TAN_CHANNELS", "email sms"); + }); + }, + }); + const helper = await startTanHelper({ socketFile }); + + const merchantClient = new TalerMerchantManagementHttpClient( + merchant.makeInstanceBaseUrl(), + ); + + { + const r = succeedOrThrow( + await merchantClient.listInstances(merchantAdminAccessToken), + ); + t.assertDeepEqual(r.instances.length, 2); + } + + const instanceInfo = { + id: "self-instance", + name: "My instance", + auth: { + method: MerchantAuthMethod.TOKEN, + password: "123", + }, + default_pay_delay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ days: 14 }), + ), + default_wire_transfer_delay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ days: 14 }), + ), + jurisdiction: {}, + address: {}, + email: "some@taler.net", + phone_number: "+1111", + use_stefan: false, + }; + const signupStart = alternativeOrThrow( + await merchantClient.createInstanceSelfProvision(instanceInfo), + HttpStatusCode.Accepted, + ); + + // creation requires 2fa + t.assertDeepEqual(signupStart.challenges.length, 2); + t.assertDeepEqual(signupStart.combi_and, true); + + const firstChallenge = signupStart.challenges[0]; + const secondChallenge = signupStart.challenges[1]; + + { + // new instance is pending, then is not listed + const r = succeedOrThrow( + await merchantClient.listInstances(merchantAdminAccessToken), + ); + t.assertDeepEqual(r.instances.length, 2); + } + + { + succeedOrThrow( + await merchantClient.sendChallenge(firstChallenge.challenge_id), + ); + + const message = helper.getLastCodeForAddress(instanceInfo.phone_number); + const [tanCode] = message.split("\n"); + succeedOrThrow( + await merchantClient.confirmChallenge(firstChallenge.challenge_id, { + tan: tanCode, + }), + ); + } + + { + succeedOrThrow( + await merchantClient.sendChallenge(secondChallenge.challenge_id), + ); + + const message = helper.getLastCodeForAddress(instanceInfo.email); + const [tanCode] = message.split("\n"); + succeedOrThrow( + await merchantClient.confirmChallenge(secondChallenge.challenge_id, { + tan: tanCode, + }), + ); + } + + const completeSignup = await merchantClient.createInstanceSelfProvision( + instanceInfo, + { + challengeIds: [firstChallenge.challenge_id, secondChallenge.challenge_id], + }, + ); + + t.assertDeepEqual(completeSignup.type, "ok"); + + const instanceApi = new TalerMerchantInstanceHttpClient( + merchantClient.getSubInstanceAPI(instanceInfo.id), + merchantClient.httpLib, + ); + + { + // new instance is completed, now it should be visible + const r = succeedOrThrow( + await merchantClient.listInstances(merchantAdminAccessToken), + ); + t.assertDeepEqual(r.instances.length, 3); + } + + const loginChallenge = alternativeOrThrow( + await instanceApi.createAccessToken( + instanceInfo.id, + instanceInfo.auth.password, + { + scope: LoginTokenScope.All, + }, + ), + HttpStatusCode.Accepted, + ); + + await solveMFA(merchantClient, helper, loginChallenge, { + [TanChannel.EMAIL]: instanceInfo.email, + [TanChannel.SMS]: instanceInfo.phone_number, + }); + + const { access_token: token } = succeedOrThrow( + await instanceApi.createAccessToken( + instanceInfo.id, + instanceInfo.auth.password, + { + scope: LoginTokenScope.All, + }, + { + challengeIds: loginChallenge.challenges.map((c) => c.challenge_id), + }, + ), + ); + + const bankAccount = succeedOrThrow(await instanceApi.addBankAccount(token, { + payto_uri: getTestHarnessPaytoForLabel("account1") + })) + + const secondBankAccountChallenge = alternativeOrThrow(await instanceApi.addBankAccount(token, { + payto_uri: getTestHarnessPaytoForLabel("account2") + }), HttpStatusCode.Accepted) + + await solveMFA(instanceApi, helper, secondBankAccountChallenge, { + [TanChannel.EMAIL]: instanceInfo.email, + [TanChannel.SMS]: instanceInfo.phone_number, + }); + + const secondBankAccount = succeedOrThrow(await instanceApi.addBankAccount(token, { + payto_uri: getTestHarnessPaytoForLabel("account2") + }, { + challengeIds: secondBankAccountChallenge.challenges.map((c) => c.challenge_id) + })) + + + + helper.stop(); +} + +runMerchantSelfProvisionActivationTwoBankAccountsTest.suites = ["merchant", "self-provision"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -223,6 +223,7 @@ import { runWithdrawalHugeTest } from "./test-withdrawal-huge.js"; import { runWithdrawalIdempotentTest } from "./test-withdrawal-idempotent.js"; import { runWithdrawalManualTest } from "./test-withdrawal-manual.js"; import { runWithdrawalPrepareTest } from "./test-withdrawal-prepare.js"; +import { runMerchantSelfProvisionActivationTwoBankAccountsTest } from "./test-merchant-self-provision-activation-two-bank-account.js"; /** * Test runner. @@ -341,6 +342,7 @@ const allTests: TestMainFunction[] = [ runExchangeMasterPubChangeTest, runMerchantCategoriesTest, runMerchantSelfProvisionActivationTest, + runMerchantSelfProvisionActivationTwoBankAccountsTest, runWebMerchantLoginTest, runMerchantSelfProvisionActivationAndLoginTest, runMerchantSelfProvisionForgotPasswordTest,