add integration test
This commit is contained in:
Sebastian 2023-07-03 12:44:20 -03:00
parent 545bf16cdf
commit f407ab2023
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
4 changed files with 265 additions and 43 deletions

View File

@ -28,6 +28,8 @@ import {
AmountJson, AmountJson,
Amounts, Amounts,
AmountString, AmountString,
codecForMerchantOrderPrivateStatusResponse,
codecForMerchantPostOrderResponse,
codecForMerchantReserveCreateConfirmation, codecForMerchantReserveCreateConfirmation,
Configuration, Configuration,
CoreApiResponse, CoreApiResponse,
@ -39,28 +41,42 @@ import {
hash, hash,
j2s, j2s,
Logger, Logger,
MerchantInstancesResponse,
MerchantOrderPrivateStatusResponse,
MerchantPostOrderRequest,
MerchantPostOrderResponse,
MerchantReserveCreateConfirmation, MerchantReserveCreateConfirmation,
MerchantTemplateAddDetails, MerchantTemplateAddDetails,
NotificationType,
parsePaytoUri, parsePaytoUri,
stringToBytes, stringToBytes,
TalerError, TalerError,
TalerProtocolDuration, TalerProtocolDuration,
TransactionMajorState, TipCreateConfirmation,
TipCreateRequest,
TippingReserveStatus,
WalletNotification, WalletNotification,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import {
createPlatformHttpLib,
readSuccessResponseJsonOrThrow,
} from "@gnu-taler/taler-util/http";
import { import {
BankApi, BankApi,
BankServiceHandle, BankServiceHandle,
HarnessExchangeBankAccount, HarnessExchangeBankAccount,
OpenedPromise,
openPromise, openPromise,
WalletApiOperation,
WalletCoreApiClient, WalletCoreApiClient,
WalletCoreRequestType, WalletCoreRequestType,
WalletCoreResponseType, WalletCoreResponseType,
WalletOperations, WalletOperations,
} from "@gnu-taler/taler-wallet-core"; } from "@gnu-taler/taler-wallet-core";
import {
createRemoteWallet,
getClientFromRemoteWallet,
makeNotificationWaiter,
RemoteWallet,
WalletNotificationWaiter,
} from "@gnu-taler/taler-wallet-core/remote";
import { deepStrictEqual } from "assert"; import { deepStrictEqual } from "assert";
import axiosImp, { AxiosError } from "axios"; import axiosImp, { AxiosError } from "axios";
import { ChildProcess, spawn } from "child_process"; import { ChildProcess, spawn } from "child_process";
@ -72,29 +88,6 @@ import * as readline from "readline";
import { URL } from "url"; import { URL } from "url";
import { CoinConfig } from "./denomStructures.js"; import { CoinConfig } from "./denomStructures.js";
import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js"; import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js";
import {
codecForMerchantOrderPrivateStatusResponse,
codecForMerchantPostOrderResponse,
MerchantInstancesResponse,
MerchantOrderPrivateStatusResponse,
MerchantPostOrderRequest,
MerchantPostOrderResponse,
TipCreateConfirmation,
TipCreateRequest,
TippingReserveStatus,
} from "@gnu-taler/taler-util";
import {
createRemoteWallet,
getClientFromRemoteWallet,
makeNotificationWaiter,
RemoteWallet,
WalletNotificationWaiter,
} from "@gnu-taler/taler-wallet-core/remote";
import {
createPlatformHttpLib,
readSuccessResponseJsonOrErrorCode,
readSuccessResponseJsonOrThrow,
} from "@gnu-taler/taler-util/http";
const logger = new Logger("harness.ts"); const logger = new Logger("harness.ts");

View File

@ -298,22 +298,10 @@ export async function createSimpleTestkudosEnvironmentV2(
), ),
}); });
const walletService = new WalletService(t, { const { walletClient, walletService } = await createWalletDaemonWithClient(
name: "wallet", t,
}); { name: "wallet" },
await walletService.start(); );
await walletService.pingUntilAvailable();
const walletClient = new WalletClient({
unixPath: walletService.socketPath,
onNotification(n) {
console.log("got notification", n);
},
});
await walletClient.connect();
await walletClient.client.call(WalletApiOperation.InitWallet, {
skipDefaults: true,
});
console.log("setup done!"); console.log("setup done!");

View File

@ -0,0 +1,239 @@
/*
This file is part of GNU Taler
(C) 2020 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 { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
import {
createSimpleTestkudosEnvironmentV2,
withdrawViaBankV2,
makeTestPaymentV2,
createWalletDaemonWithClient,
} from "../harness/helpers.js";
import {
ConfirmPayResultType,
PreparePayResultType,
j2s,
parsePayUri,
stringifyPayUri,
} from "@gnu-taler/taler-util";
/**
* Run test for basic, bank-integrated withdrawal and payment.
*/
export async function runPaymentShareTest(t: GlobalTestState) {
// Set up test environment
const {
walletClient: firstWallet,
bank,
exchange,
merchant,
} = await createSimpleTestkudosEnvironmentV2(t);
// Withdraw digital cash into the wallet.
await withdrawViaBankV2(t, {
walletClient: firstWallet,
bank,
exchange,
amount: "TESTKUDOS:20",
});
await firstWallet.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
const { walletClient: secondWallet } = await createWalletDaemonWithClient(t, {
name: "wallet2",
});
await withdrawViaBankV2(t, {
walletClient: secondWallet,
bank,
exchange,
amount: "TESTKUDOS:20",
});
await secondWallet.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
//create two orders to pay
async function createOrder(amount: string) {
const order = {
summary: "Buy me!",
amount,
fulfillment_url: "taler://fulfillment-success/thx",
};
const instance = "default";
const args = { order };
const auth = {};
const orderResp = await MerchantPrivateApi.createOrder(
merchant,
instance,
{
order: args.order,
},
auth,
);
const orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(
merchant,
{
orderId: orderResp.order_id,
},
auth,
);
t.assertTrue(orderStatus.order_status === "unpaid");
return { id: orderResp.order_id, uri: orderStatus.taler_pay_uri };
}
/**
* FIRST CASE, create in first wallet and pay in the second wallet
* first wallet should not be able to continue
*/
{
const order = await createOrder("TESTKUDOS:5");
// Claim the order with the first wallet
const claimFirstWallet = await firstWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: order.uri },
);
t.assertTrue(
claimFirstWallet.status === PreparePayResultType.PaymentPossible,
);
//share order from the first wallet
const { privatePayUri } = await firstWallet.call(
WalletApiOperation.SharePayment,
{
merchantBaseUrl: merchant.makeInstanceBaseUrl(),
orderId: order.id,
},
);
//claim from the second wallet
const claimSecondWallet = await secondWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: privatePayUri },
);
t.assertTrue(
claimSecondWallet.status === PreparePayResultType.PaymentPossible,
);
//pay from the second wallet
const r2 = await secondWallet.call(WalletApiOperation.ConfirmPay, {
proposalId: claimSecondWallet.proposalId,
});
t.assertTrue(r2.type === ConfirmPayResultType.Done);
{
const first = await firstWallet.call(WalletApiOperation.GetBalances, {});
const second = await secondWallet.call(
WalletApiOperation.GetBalances,
{},
);
t.assertAmountEquals(first.balances[0].available, "TESTKUDOS:19.53");
t.assertAmountEquals(second.balances[0].available, "TESTKUDOS:14.23");
}
// Claim the order with the first wallet
const claimFirstWalletAgain = await firstWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: order.uri },
);
t.assertTrue(
claimFirstWalletAgain.status === PreparePayResultType.AlreadyConfirmed,
);
const r1 = await firstWallet.call(WalletApiOperation.ConfirmPay, {
proposalId: claimFirstWallet.proposalId,
});
t.assertTrue(r1.type === ConfirmPayResultType.Done);
{
const first = await firstWallet.call(WalletApiOperation.GetBalances, {});
const second = await secondWallet.call(
WalletApiOperation.GetBalances,
{},
);
t.assertAmountEquals(first.balances[0].available, "TESTKUDOS:19.53");
t.assertAmountEquals(second.balances[0].available, "TESTKUDOS:14.23");
}
}
/**
* SECOND CASE, create in first wallet and share to the second wallet
* pay with the first wallet, second wallet should not be able to continue
*/
{
const order = await createOrder("TESTKUDOS:3");
// Claim the order with the first wallet
const claimFirstWallet = await firstWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: order.uri },
);
t.assertTrue(
claimFirstWallet.status === PreparePayResultType.PaymentPossible,
);
//share order from the first wallet
const { privatePayUri } = await firstWallet.call(
WalletApiOperation.SharePayment,
{
merchantBaseUrl: merchant.makeInstanceBaseUrl(),
orderId: order.id,
},
);
//claim from the second wallet
const claimSecondWallet = await secondWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: privatePayUri },
);
t.assertTrue(
claimSecondWallet.status === PreparePayResultType.PaymentPossible,
);
//pay from the second wallet
const r2 = await firstWallet.call(WalletApiOperation.ConfirmPay, {
proposalId: claimFirstWallet.proposalId,
});
t.assertTrue(r2.type === ConfirmPayResultType.Done);
const bal1 = await firstWallet.call(WalletApiOperation.GetBalances, {});
t.assertAmountEquals(bal1.balances[0].available, "TESTKUDOS:16.18");
const bal2 = await secondWallet.call(WalletApiOperation.GetBalances, {});
t.assertAmountEquals(bal2.balances[0].available, "TESTKUDOS:14.23");
// Claim the order with the first wallet
const claimSecondWalletAgain = await secondWallet.call(
WalletApiOperation.PreparePayForUri,
{ talerPayUri: order.uri },
);
t.assertTrue(
claimSecondWalletAgain.status === PreparePayResultType.AlreadyConfirmed,
);
}
}
runPaymentShareTest.suites = ["wallet"];

View File

@ -102,6 +102,7 @@ import { runWalletBalanceTest } from "./test-wallet-balance.js";
import { runPaymentTemplateTest } from "./test-payment-template.js"; import { runPaymentTemplateTest } from "./test-payment-template.js";
import { runExchangeDepositTest } from "./test-exchange-deposit.js"; import { runExchangeDepositTest } from "./test-exchange-deposit.js";
import { runPeerRepairTest } from "./test-peer-repair.js"; import { runPeerRepairTest } from "./test-peer-repair.js";
import { runPaymentShareTest } from "./test-payment-share.js";
/** /**
* Test runner. * Test runner.
@ -166,6 +167,7 @@ const allTests: TestMainFunction[] = [
runPaymentIdempotencyTest, runPaymentIdempotencyTest,
runPaymentMultipleTest, runPaymentMultipleTest,
runPaymentTest, runPaymentTest,
runPaymentShareTest,
runPaymentTemplateTest, runPaymentTemplateTest,
runPaymentAbortTest, runPaymentAbortTest,
runPaymentTransientTest, runPaymentTransientTest,