From 07d8498abc6aa21ab7c8e7146a04b4b731504c3d Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 4 Apr 2023 15:25:29 +0200 Subject: wallet-core: implement runIntegrationTestV2 --- packages/taler-util/src/wallet-types.ts | 15 ++ .../taler-wallet-core/src/operations/pay-peer.ts | 4 +- .../taler-wallet-core/src/operations/testing.ts | 152 +++++++++++++++++++++ packages/taler-wallet-core/src/wallet-api-types.ts | 12 ++ packages/taler-wallet-core/src/wallet.ts | 15 +- 5 files changed, 192 insertions(+), 6 deletions(-) diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts index 940251366..a761c5cff 100644 --- a/packages/taler-util/src/wallet-types.ts +++ b/packages/taler-util/src/wallet-types.ts @@ -1247,6 +1247,21 @@ export const codecForIntegrationTestArgs = (): Codec => .property("bankAccessApiBaseUrl", codecOptional(codecForAmountString())) .build("IntegrationTestArgs"); +export interface IntegrationTestV2Args { + exchangeBaseUrl: string; + bankAccessApiBaseUrl: string; + merchantBaseUrl: string; + merchantAuthToken?: string; +} + +export const codecForIntegrationTestV2Args = (): Codec => + buildCodecForObject() + .property("exchangeBaseUrl", codecForString()) + .property("merchantBaseUrl", codecForString()) + .property("merchantAuthToken", codecOptional(codecForString())) + .property("bankAccessApiBaseUrl", codecForAmountString()) + .build("IntegrationTestV2Args"); + export interface AddExchangeRequest { exchangeBaseUrl: string; forceUpdate?: boolean; diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts index ff0e15c00..92ec549dd 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer.ts @@ -1000,7 +1000,7 @@ export async function processPeerPushCredit( }; } -export async function confirmPeerPushPayment( +export async function confirmPeerPushCredit( ws: InternalWalletState, req: ConfirmPeerPushCreditRequest, ): Promise { @@ -1119,7 +1119,7 @@ export async function processPeerPullDebit( }; } -export async function acceptIncomingPeerPullPayment( +export async function confirmPeerPullDebit( ws: InternalWalletState, req: ConfirmPeerPullDebitRequest, ): Promise { diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index 873fac021..c1f129fcd 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -18,8 +18,11 @@ * Imports. */ import { + AbsoluteTime, base64FromArrayBuffer, ConfirmPayResultType, + Duration, + IntegrationTestV2Args, Logger, stringToBytes, TestPayResult, @@ -46,6 +49,15 @@ import { applyRefund, confirmPay, preparePayForUri } from "./pay-merchant.js"; import { getBalances } from "./balance.js"; import { checkLogicInvariant } from "../util/invariants.js"; import { acceptWithdrawalFromUri } from "./withdraw.js"; +import { updateExchangeFromUrl } from "./exchanges.js"; +import { + confirmPeerPullDebit, + confirmPeerPushCredit, + initiatePeerPullPayment, + initiatePeerPushPayment, + preparePeerPullDebit, + preparePeerPushCredit, +} from "./pay-peer.js"; const logger = new Logger("operations/testing.ts"); @@ -429,6 +441,146 @@ export async function runIntegrationTest( logger.trace("integration test: all done!"); } +export async function runIntegrationTest2( + ws: InternalWalletState, + args: IntegrationTestV2Args, +): Promise { + logger.info("running test with arguments", args); + + const exchangeInfo = await updateExchangeFromUrl(ws, args.exchangeBaseUrl); + + const currency = exchangeInfo.exchangeDetails.currency; + + const amountToWithdraw = Amounts.parseOrThrow(`${currency}:10`); + const amountToSpend = Amounts.parseOrThrow(`${currency}:2`); + + logger.info("withdrawing test balance"); + await withdrawTestBalance(ws, { + amount: Amounts.stringify(amountToWithdraw), + bankBaseUrl: args.bankAccessApiBaseUrl /* FIXME: not necessary */, + bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + exchangeBaseUrl: args.exchangeBaseUrl, + }); + await ws.runUntilDone(); + logger.info("done withdrawing test balance"); + + const balance = await getBalances(ws); + + logger.trace(JSON.stringify(balance, null, 2)); + + const myMerchant: MerchantBackendInfo = { + baseUrl: args.merchantBaseUrl, + authToken: args.merchantAuthToken, + }; + + await makePayment( + ws, + myMerchant, + Amounts.stringify(amountToSpend), + "hello world", + ); + + // Wait until the refresh is done + await ws.runUntilDone(); + + logger.trace("withdrawing test balance for refund"); + const withdrawAmountTwo = Amounts.parseOrThrow(`${currency}:18`); + const spendAmountTwo = Amounts.parseOrThrow(`${currency}:7`); + const refundAmount = Amounts.parseOrThrow(`${currency}:6`); + const spendAmountThree = Amounts.parseOrThrow(`${currency}:3`); + + await withdrawTestBalance(ws, { + amount: Amounts.stringify(withdrawAmountTwo), + bankBaseUrl: args.bankAccessApiBaseUrl /* FIXME: not necessary */, + bankAccessApiBaseUrl: args.bankAccessApiBaseUrl, + exchangeBaseUrl: args.exchangeBaseUrl, + }); + + // Wait until the withdraw is done + await ws.runUntilDone(); + + const { orderId: refundOrderId } = await makePayment( + ws, + myMerchant, + Amounts.stringify(spendAmountTwo), + "order that will be refunded", + ); + + const refundUri = await refund( + ws.http, + myMerchant, + refundOrderId, + "test refund", + Amounts.stringify(refundAmount), + ); + + logger.trace("refund URI", refundUri); + + await applyRefund(ws, refundUri); + + logger.trace("integration test: applied refund"); + + // Wait until the refund is done + await ws.runUntilDone(); + + logger.trace("integration test: making payment after refund"); + + await makePayment( + ws, + myMerchant, + Amounts.stringify(spendAmountThree), + "payment after refund", + ); + + logger.trace("integration test: make payment done"); + + await ws.runUntilDone(); + + const peerPushInit = await initiatePeerPushPayment(ws, { + partialContractTerms: { + amount: `${currency}:1`, + summary: "Payment Peer Push Test", + purse_expiration: AbsoluteTime.toTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ hours: 1 }), + ), + ), + }, + }); + + const peerPushCredit = await preparePeerPushCredit(ws, { + talerUri: peerPushInit.talerUri, + }); + + await confirmPeerPushCredit(ws, { + peerPushPaymentIncomingId: peerPushCredit.peerPushPaymentIncomingId, + }); + + const peerPullInit = await initiatePeerPullPayment(ws, { + partialContractTerms: { + amount: `${currency}:1`, + summary: "Payment Peer Pull Test", + purse_expiration: AbsoluteTime.toTimestamp( + AbsoluteTime.addDuration( + AbsoluteTime.now(), + Duration.fromSpec({ hours: 1 }), + ), + ), + }, + }); + + const peerPullInc = await preparePeerPullDebit(ws, { + talerUri: peerPullInit.talerUri, + }); + + await confirmPeerPullDebit(ws, { + peerPullPaymentIncomingId: peerPullInc.peerPullPaymentIncomingId, + }); + + logger.trace("integration test: all done!"); +} + export async function testPay( ws: InternalWalletState, args: TestPayArgs, diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts index 0b1968857..6f46fe8f2 100644 --- a/packages/taler-wallet-core/src/wallet-api-types.ts +++ b/packages/taler-wallet-core/src/wallet-api-types.ts @@ -132,6 +132,7 @@ export enum WalletApiOperation { PreparePayForTemplate = "preparePayForTemplate", GetContractTermsDetails = "getContractTermsDetails", RunIntegrationTest = "runIntegrationTest", + RunIntegrationTestV2 = "runIntegrationTestV2", TestCrypto = "testCrypto", TestPay = "testPay", AddExchange = "addExchange", @@ -759,6 +760,16 @@ export type RunIntegrationTestOp = { response: EmptyObject; }; +/** + * Run a simple integration test on a test deployment + * of the exchange and merchant. + */ +export type RunIntegrationTestV2Op = { + op: WalletApiOperation.RunIntegrationTest; + request: IntegrationTestArgs; + response: EmptyObject; +}; + /** * Test crypto worker. */ @@ -931,6 +942,7 @@ export type WalletOperations = { [WalletApiOperation.RemoveBackupProvider]: RemoveBackupProviderOp; [WalletApiOperation.GetBackupInfo]: GetBackupInfoOp; [WalletApiOperation.RunIntegrationTest]: RunIntegrationTestOp; + [WalletApiOperation.RunIntegrationTestV2]: RunIntegrationTestV2Op; [WalletApiOperation.TestCrypto]: TestCryptoOp; [WalletApiOperation.WithdrawTestBalance]: WithdrawTestBalanceOp; [WalletApiOperation.TestPay]: TestPayOp; diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 363214e7b..348d2a834 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -112,6 +112,7 @@ import { validateIban, codecForValidateIbanRequest, ValidateIbanResponse, + codecForIntegrationTestV2Args, } from "@gnu-taler/taler-util"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { @@ -200,8 +201,8 @@ import { processPurchase, } from "./operations/pay-merchant.js"; import { - acceptIncomingPeerPullPayment, - confirmPeerPushPayment, + confirmPeerPullDebit, + confirmPeerPushCredit, preparePeerPullDebit, preparePeerPushCredit, initiatePeerPullPayment, @@ -226,6 +227,7 @@ import { } from "./operations/refresh.js"; import { runIntegrationTest, + runIntegrationTest2, testPay, withdrawTestBalance, } from "./operations/testing.js"; @@ -1046,6 +1048,11 @@ async function dispatchRequestInternal( await runIntegrationTest(ws, req); return {}; } + case WalletApiOperation.RunIntegrationTestV2: { + const req = codecForIntegrationTestV2Args().decode(payload); + await runIntegrationTest2(ws, req); + return {}; + } case WalletApiOperation.ValidateIban: { const req = codecForValidateIbanRequest().decode(payload); const valRes = validateIban(req.iban); @@ -1461,7 +1468,7 @@ async function dispatchRequestInternal( } case WalletApiOperation.ConfirmPeerPushCredit: { const req = codecForConfirmPeerPushPaymentRequest().decode(payload); - return await confirmPeerPushPayment(ws, req); + return await confirmPeerPushCredit(ws, req); } case WalletApiOperation.CheckPeerPullCredit: { const req = codecForPreparePeerPullPaymentRequest().decode(payload); @@ -1477,7 +1484,7 @@ async function dispatchRequestInternal( } case WalletApiOperation.ConfirmPeerPullDebit: { const req = codecForAcceptPeerPullPaymentRequest().decode(payload); - return await acceptIncomingPeerPullPayment(ws, req); + return await confirmPeerPullDebit(ws, req); } case WalletApiOperation.ApplyDevExperiment: { const req = codecForApplyDevExperiment().decode(payload); -- cgit v1.2.3