integration tests: various fixes
This commit is contained in:
parent
499e003ff8
commit
70d0199572
@ -22,8 +22,8 @@ import { CoinConfig, defaultCoinConfig } from "./harness/denomStructures.js";
|
||||
import {
|
||||
GlobalTestState,
|
||||
setupDb,
|
||||
FakeBankService,
|
||||
ExchangeService,
|
||||
FakebankService,
|
||||
} from "./harness/harness.js";
|
||||
|
||||
/**
|
||||
@ -35,9 +35,11 @@ import {
|
||||
export async function runEnv1(t: GlobalTestState): Promise<void> {
|
||||
const db = await setupDb(t);
|
||||
|
||||
const bank = await FakeBankService.create(t, {
|
||||
const bank = await FakebankService.create(t, {
|
||||
currency: "TESTKUDOS",
|
||||
httpPort: 8082,
|
||||
allowRegistrations: true,
|
||||
database: db.connStr,
|
||||
});
|
||||
|
||||
const exchange = ExchangeService.create(t, {
|
||||
|
@ -775,11 +775,21 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {
|
||||
/**
|
||||
* Implementation of the bank service using the "taler-fakebank-run" tool.
|
||||
*/
|
||||
class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
export class FakebankService
|
||||
extends BankServiceBase
|
||||
implements BankServiceHandle
|
||||
{
|
||||
proc: ProcessWrapper | undefined;
|
||||
|
||||
http = new NodeHttpLib();
|
||||
|
||||
// We store "created" accounts during setup and
|
||||
// register them after startup.
|
||||
private accounts: {
|
||||
accountName: string;
|
||||
accountPassword: string;
|
||||
}[] = [];
|
||||
|
||||
static async create(
|
||||
gc: GlobalTestState,
|
||||
bc: BankConfig,
|
||||
@ -791,6 +801,7 @@ class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
config.setString("bank", "serve", "http");
|
||||
config.setString("bank", "max_debt_bank", `${bc.currency}:999999`);
|
||||
config.setString("bank", "max_debt", bc.maxDebt ?? `${bc.currency}:100`);
|
||||
config.setString("bank", "ram_limit", `${1024}`);
|
||||
const cfgFilename = gc.testDir + "/bank.conf";
|
||||
config.write(cfgFilename);
|
||||
|
||||
@ -798,6 +809,9 @@ class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
}
|
||||
|
||||
setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) {
|
||||
if (!!this.proc) {
|
||||
throw Error("Can't set suggested exchange while bank is running.");
|
||||
}
|
||||
const config = Configuration.load(this.configFile);
|
||||
config.setString("bank", "suggested_exchange", e.baseUrl);
|
||||
config.write(this.configFile);
|
||||
@ -816,10 +830,10 @@ class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
accountName: string,
|
||||
password: string,
|
||||
): Promise<HarnessExchangeBankAccount> {
|
||||
// FIXME: Is there a better place to do this initialization?
|
||||
await this.start();
|
||||
await this.pingUntilAvailable();
|
||||
await BankApi.registerAccount(this, accountName, password);
|
||||
this.accounts.push({
|
||||
accountName,
|
||||
accountPassword: password,
|
||||
});
|
||||
return {
|
||||
accountName: accountName,
|
||||
accountPassword: password,
|
||||
@ -833,15 +847,25 @@ class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
logger.info("starting fakebank");
|
||||
if (this.proc) {
|
||||
logger.info("fakebank already running, not starting again");
|
||||
return;
|
||||
}
|
||||
this.proc = this.globalTestState.spawnService(
|
||||
"taler-fakebank-run",
|
||||
["-c", this.configFile],
|
||||
[
|
||||
"-c",
|
||||
this.configFile,
|
||||
"--signup-bonus",
|
||||
`${this.bankConfig.currency}:100`,
|
||||
],
|
||||
"bank",
|
||||
);
|
||||
await this.pingUntilAvailable();
|
||||
for (const acc of this.accounts) {
|
||||
await BankApi.registerAccount(this, acc.accountName, acc.accountPassword);
|
||||
}
|
||||
}
|
||||
|
||||
async pingUntilAvailable(): Promise<void> {
|
||||
@ -853,86 +877,8 @@ class FakebankService extends BankServiceBase implements BankServiceHandle {
|
||||
// Use libeufin bank instead of pybank.
|
||||
const useLibeufinBank = false;
|
||||
|
||||
/**
|
||||
* Return a euFin or a pyBank implementation of
|
||||
* the exported BankService class. This allows
|
||||
* to "dynamically export" such class depending
|
||||
* on a particular env variable.
|
||||
*/
|
||||
function getBankServiceImpl(): {
|
||||
prototype: typeof FakebankService.prototype;
|
||||
create: typeof FakebankService.create;
|
||||
} {
|
||||
if (useLibeufinBank)
|
||||
return {
|
||||
prototype: LibEuFinBankService.prototype,
|
||||
create: LibEuFinBankService.create,
|
||||
};
|
||||
return {
|
||||
prototype: FakebankService.prototype,
|
||||
create: FakebankService.create,
|
||||
};
|
||||
}
|
||||
|
||||
export type BankService = FakebankService;
|
||||
export const BankService = getBankServiceImpl();
|
||||
|
||||
export class FakeBankService {
|
||||
proc: ProcessWrapper | undefined;
|
||||
|
||||
static fromExistingConfig(gc: GlobalTestState): FakeBankService {
|
||||
const cfgFilename = gc.testDir + "/bank.conf";
|
||||
logger.info("reading fakebank config from", cfgFilename);
|
||||
const config = Configuration.load(cfgFilename);
|
||||
const bc: FakeBankConfig = {
|
||||
currency: config.getString("taler", "currency").required(),
|
||||
httpPort: config.getNumber("bank", "http_port").required(),
|
||||
};
|
||||
return new FakeBankService(gc, bc, cfgFilename);
|
||||
}
|
||||
|
||||
static async create(
|
||||
gc: GlobalTestState,
|
||||
bc: FakeBankConfig,
|
||||
): Promise<FakeBankService> {
|
||||
const config = new Configuration();
|
||||
setTalerPaths(config, gc.testDir + "/talerhome");
|
||||
config.setString("taler", "currency", bc.currency);
|
||||
config.setString("bank", "http_port", `${bc.httpPort}`);
|
||||
config.setString("bank", "ram_limit", `${1024}`);
|
||||
const cfgFilename = gc.testDir + "/bank.conf";
|
||||
config.write(cfgFilename);
|
||||
return new FakeBankService(gc, bc, cfgFilename);
|
||||
}
|
||||
|
||||
get baseUrl(): string {
|
||||
return `http://localhost:${this.bankConfig.httpPort}/`;
|
||||
}
|
||||
|
||||
get port() {
|
||||
return this.bankConfig.httpPort;
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private globalTestState: GlobalTestState,
|
||||
private bankConfig: FakeBankConfig,
|
||||
private configFile: string,
|
||||
) {}
|
||||
|
||||
async start(): Promise<void> {
|
||||
this.proc = this.globalTestState.spawnService(
|
||||
"taler-fakebank-run",
|
||||
["-c", this.configFile],
|
||||
"fakebank",
|
||||
);
|
||||
}
|
||||
|
||||
async pingUntilAvailable(): Promise<void> {
|
||||
// Fakebank doesn't have "/config", so we ping just "/".
|
||||
const url = `http://localhost:${this.bankConfig.httpPort}/`;
|
||||
await pingProc(this.proc, url, "bank");
|
||||
}
|
||||
}
|
||||
export type BankService = BankServiceHandle;
|
||||
export const BankService = FakebankService;
|
||||
|
||||
export interface ExchangeConfig {
|
||||
name: string;
|
||||
|
@ -691,8 +691,8 @@ export class LibeufinCli {
|
||||
): Promise<void> {
|
||||
const stdout = await sh(
|
||||
this.globalTestState,
|
||||
"libeufin-cli-submitpayment",
|
||||
`libeufin-cli accounts submit-payment` +
|
||||
"libeufin-cli-submitpayments",
|
||||
`libeufin-cli accounts submit-payments` +
|
||||
` --payment-uuid=${paymentUuid}` +
|
||||
` ${details.nexusBankAccountName}`,
|
||||
{
|
||||
|
@ -43,10 +43,10 @@ export async function runBankApiTest(t: GlobalTestState) {
|
||||
const db = await setupDb(t);
|
||||
|
||||
const bank = await BankService.create(t, {
|
||||
allowRegistrations: true,
|
||||
currency: "TESTKUDOS",
|
||||
database: db.connStr,
|
||||
httpPort: 8082,
|
||||
database: db.connStr,
|
||||
allowRegistrations: true,
|
||||
});
|
||||
|
||||
const exchange = ExchangeService.create(t, {
|
||||
|
@ -17,17 +17,9 @@
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import {
|
||||
ConfirmPayResultType,
|
||||
j2s,
|
||||
PreparePayResultType,
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { Wallet, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import {
|
||||
GlobalTestState,
|
||||
MerchantPrivateApi,
|
||||
WithAuthorization,
|
||||
} from "../harness/harness.js";
|
||||
import { j2s } from "@gnu-taler/taler-util";
|
||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import { GlobalTestState } from "../harness/harness.js";
|
||||
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||
|
||||
/**
|
||||
|
@ -54,6 +54,7 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
|
||||
// Abort it
|
||||
|
||||
await BankApi.abortWithdrawalOperation(bank, user, wop);
|
||||
//await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||
|
||||
// Withdraw
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
WalletCli,
|
||||
setupDb,
|
||||
ExchangeService,
|
||||
FakeBankService,
|
||||
FakebankService,
|
||||
} from "../harness/harness.js";
|
||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||
import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js";
|
||||
@ -36,9 +36,12 @@ export async function runWithdrawalFakebankTest(t: GlobalTestState) {
|
||||
|
||||
const db = await setupDb(t);
|
||||
|
||||
const bank = await FakeBankService.create(t, {
|
||||
const bank = await FakebankService.create(t, {
|
||||
currency: "TESTKUDOS",
|
||||
httpPort: 8082,
|
||||
allowRegistrations: true,
|
||||
// Not used by fakebank
|
||||
database: db.connStr,
|
||||
});
|
||||
|
||||
const exchange = ExchangeService.create(t, {
|
||||
|
@ -106,7 +106,7 @@ export namespace BankApi {
|
||||
const url = new URL("testing/register", bank.bankAccessApiBaseUrl);
|
||||
const resp = await bank.http.postJson(url.href, { username, password });
|
||||
let paytoUri = `payto://x-taler-bank/localhost/${username}`;
|
||||
if (resp.status !== 200 && resp.status !== 202) {
|
||||
if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) {
|
||||
logger.error(`${j2s(await resp.json())}`);
|
||||
throw TalerError.fromDetail(
|
||||
TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR,
|
||||
@ -209,7 +209,7 @@ export namespace BankApi {
|
||||
): Promise<void> {
|
||||
const url = new URL(
|
||||
`accounts/${bankUser.username}/withdrawals/${wopi.withdrawal_id}/abort`,
|
||||
bank.baseUrl,
|
||||
bank.bankAccessApiBaseUrl,
|
||||
);
|
||||
const resp = await bank.http.postJson(
|
||||
url.href,
|
||||
|
@ -90,16 +90,21 @@ export async function withdrawTestBalance(
|
||||
ws: InternalWalletState,
|
||||
req: WithdrawTestBalanceRequest,
|
||||
): Promise<void> {
|
||||
const bankBaseUrl = req.bankBaseUrl;
|
||||
const amount = req.amount;
|
||||
const exchangeBaseUrl = req.exchangeBaseUrl;
|
||||
|
||||
const bankUser = await registerRandomBankUser(ws.http, bankBaseUrl);
|
||||
logger.trace(
|
||||
`Registered bank user, bank access base url ${req.bankAccessApiBaseUrl}`,
|
||||
);
|
||||
const bankUser = await registerRandomBankUser(
|
||||
ws.http,
|
||||
req.bankAccessApiBaseUrl,
|
||||
);
|
||||
logger.trace(`Registered bank user ${JSON.stringify(bankUser)}`);
|
||||
|
||||
const wresp = await createDemoBankWithdrawalUri(
|
||||
ws.http,
|
||||
bankBaseUrl,
|
||||
req.bankAccessApiBaseUrl,
|
||||
bankUser,
|
||||
amount,
|
||||
);
|
||||
@ -112,7 +117,7 @@ export async function withdrawTestBalance(
|
||||
|
||||
await confirmBankWithdrawalUri(
|
||||
ws.http,
|
||||
bankBaseUrl,
|
||||
req.bankAccessApiBaseUrl,
|
||||
bankUser,
|
||||
wresp.withdrawal_id,
|
||||
);
|
||||
@ -133,13 +138,13 @@ function getMerchantAuthHeader(m: MerchantBackendInfo): Record<string, string> {
|
||||
*/
|
||||
export async function createDemoBankWithdrawalUri(
|
||||
http: HttpRequestLibrary,
|
||||
bankBaseUrl: string,
|
||||
bankAccessApiBaseUrl: string,
|
||||
bankUser: BankUser,
|
||||
amount: AmountString,
|
||||
): Promise<BankWithdrawalResponse> {
|
||||
const reqUrl = new URL(
|
||||
`accounts/${bankUser.username}/withdrawals`,
|
||||
bankBaseUrl,
|
||||
bankAccessApiBaseUrl,
|
||||
).href;
|
||||
const resp = await http.postJson(
|
||||
reqUrl,
|
||||
@ -161,13 +166,13 @@ export async function createDemoBankWithdrawalUri(
|
||||
|
||||
async function confirmBankWithdrawalUri(
|
||||
http: HttpRequestLibrary,
|
||||
bankBaseUrl: string,
|
||||
bankAccessApiBaseUrl: string,
|
||||
bankUser: BankUser,
|
||||
withdrawalId: string,
|
||||
): Promise<void> {
|
||||
const reqUrl = new URL(
|
||||
`accounts/${bankUser.username}/withdrawals/${withdrawalId}/confirm`,
|
||||
bankBaseUrl,
|
||||
bankAccessApiBaseUrl,
|
||||
).href;
|
||||
const resp = await http.postJson(
|
||||
reqUrl,
|
||||
@ -187,9 +192,9 @@ async function confirmBankWithdrawalUri(
|
||||
|
||||
async function registerRandomBankUser(
|
||||
http: HttpRequestLibrary,
|
||||
bankBaseUrl: string,
|
||||
bankAccessApiBaseUrl: string,
|
||||
): Promise<BankUser> {
|
||||
const reqUrl = new URL("testing/register", bankBaseUrl).href;
|
||||
const reqUrl = new URL("testing/register", bankAccessApiBaseUrl).href;
|
||||
const randId = makeId(8);
|
||||
const bankUser: BankUser = {
|
||||
// euFin doesn't allow resource names to have upper case letters.
|
||||
@ -377,7 +382,7 @@ export async function runIntegrationTest(
|
||||
await withdrawTestBalance(ws, {
|
||||
amount: Amounts.stringify(withdrawAmountTwo),
|
||||
bankBaseUrl: args.bankBaseUrl,
|
||||
bankAccessApiBaseUrl: args.bankBaseUrl,
|
||||
bankAccessApiBaseUrl: args.bankAccessApiBaseUrl,
|
||||
exchangeBaseUrl: args.exchangeBaseUrl,
|
||||
});
|
||||
|
||||
|
@ -376,6 +376,9 @@ export async function getBankWithdrawalInfo(
|
||||
`withdrawal-operation/${uriResult.withdrawalOperationId}`,
|
||||
uriResult.bankIntegrationApiBaseUrl,
|
||||
);
|
||||
|
||||
logger.info(`bank withdrawal status URL: ${reqUrl.href}}`);
|
||||
|
||||
const resp = await http.get(reqUrl.href);
|
||||
const status = await readSuccessResponseJsonOrThrow(
|
||||
resp,
|
||||
|
Loading…
Reference in New Issue
Block a user