Bring euFin-based tests to pass.
Note: timetravel-withdraw is now failing for both pybank and eufin. That is likely due to the wallet not refreshing expired denominations.
This commit is contained in:
parent
50b9f2167c
commit
9692f589c6
@ -57,6 +57,13 @@ export function parseWithdrawUri(s: string): WithdrawUriResult | undefined {
|
|||||||
|
|
||||||
const host = parts[0].toLowerCase();
|
const host = parts[0].toLowerCase();
|
||||||
const pathSegments = parts.slice(1, parts.length - 1);
|
const pathSegments = parts.slice(1, parts.length - 1);
|
||||||
|
/**
|
||||||
|
* The statement below does not tolerate a slash-ended URI.
|
||||||
|
* This results in (1) the withdrawalId being passed as the
|
||||||
|
* empty string, and (2) the bankIntegrationApi ending with the
|
||||||
|
* actual withdrawal operation ID. That can be fixed by
|
||||||
|
* trimming the parts-list. FIXME
|
||||||
|
*/
|
||||||
const withdrawId = parts[parts.length - 1];
|
const withdrawId = parts[parts.length - 1];
|
||||||
const p = [host, ...pathSegments].join("/");
|
const p = [host, ...pathSegments].join("/");
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ import {
|
|||||||
EddsaKeyPair,
|
EddsaKeyPair,
|
||||||
encodeCrock,
|
encodeCrock,
|
||||||
getRandomBytes,
|
getRandomBytes,
|
||||||
|
hash,
|
||||||
|
stringToBytes
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { CoinConfig } from "./denomStructures.js";
|
import { CoinConfig } from "./denomStructures.js";
|
||||||
import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js";
|
import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js";
|
||||||
@ -431,8 +433,7 @@ function setCoin(config: Configuration, c: CoinConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an HTTP request until it succeeds or the
|
* Send an HTTP request until it suceeds or the process dies.
|
||||||
* process dies.
|
|
||||||
*/
|
*/
|
||||||
export async function pingProc(
|
export async function pingProc(
|
||||||
proc: ProcessWrapper | undefined,
|
proc: ProcessWrapper | undefined,
|
||||||
@ -523,22 +524,26 @@ export namespace BankApi {
|
|||||||
password: string,
|
password: string,
|
||||||
): Promise<BankUser> {
|
): Promise<BankUser> {
|
||||||
const url = new URL("testing/register", bank.baseUrl);
|
const url = new URL("testing/register", bank.baseUrl);
|
||||||
await axios.post(url.href, {
|
let resp = await axios.post(url.href, {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
|
let paytoUri = `payto://x-taler-bank/localhost/${username}`;
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN) {
|
||||||
|
paytoUri = resp.data.paytoUri;
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
password,
|
password,
|
||||||
username,
|
username,
|
||||||
accountPaytoUri: `payto://x-taler-bank/localhost/${username}`,
|
accountPaytoUri: paytoUri,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createRandomBankUser(
|
export async function createRandomBankUser(
|
||||||
bank: BankServiceInterface,
|
bank: BankServiceInterface,
|
||||||
): Promise<BankUser> {
|
): Promise<BankUser> {
|
||||||
const username = "user-" + encodeCrock(getRandomBytes(10));
|
const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase();
|
||||||
const password = "pw-" + encodeCrock(getRandomBytes(10));
|
const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase();
|
||||||
return await registerAccount(bank, username, password);
|
return await registerAccount(bank, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,9 +556,14 @@ export namespace BankApi {
|
|||||||
debitAccountPayto: string;
|
debitAccountPayto: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const url = new URL(
|
|
||||||
|
let maybeBaseUrl = bank.baseUrl;
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN) {
|
||||||
|
maybeBaseUrl = (bank as EufinBankService).baseUrlDemobank;
|
||||||
|
}
|
||||||
|
let url = new URL(
|
||||||
`taler-wire-gateway/${params.exchangeBankAccount.accountName}/admin/add-incoming`,
|
`taler-wire-gateway/${params.exchangeBankAccount.accountName}/admin/add-incoming`,
|
||||||
bank.baseUrl,
|
maybeBaseUrl,
|
||||||
);
|
);
|
||||||
await axios.post(
|
await axios.post(
|
||||||
url.href,
|
url.href,
|
||||||
@ -623,28 +633,55 @@ class BankServiceBase {
|
|||||||
* Work in progress. The key point is that both Sandbox and Nexus
|
* Work in progress. The key point is that both Sandbox and Nexus
|
||||||
* will be configured and started by this class.
|
* will be configured and started by this class.
|
||||||
*/
|
*/
|
||||||
class LibeufinBankService extends BankServiceBase implements BankService {
|
class EufinBankService extends BankServiceBase implements BankServiceInterface {
|
||||||
sandboxProc: ProcessWrapper | undefined;
|
sandboxProc: ProcessWrapper | undefined;
|
||||||
nexusProc: ProcessWrapper | undefined;
|
nexusProc: ProcessWrapper | undefined;
|
||||||
|
|
||||||
static async create(
|
static async create(
|
||||||
gc: GlobalTestState,
|
gc: GlobalTestState,
|
||||||
bc: BankConfig,
|
bc: BankConfig,
|
||||||
): Promise<BankService> {
|
): Promise<EufinBankService> {
|
||||||
|
|
||||||
return new LibeufinBankService(gc, bc, "foo");
|
return new EufinBankService(gc, bc, "foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
get port() {
|
get port() {
|
||||||
return this.bankConfig.httpPort;
|
return this.bankConfig.httpPort;
|
||||||
}
|
}
|
||||||
|
get nexusPort() {
|
||||||
|
return this.bankConfig.httpPort + 1000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get nexusDbConn(): string {
|
||||||
|
return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get sandboxDbConn(): string {
|
||||||
|
return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
get nexusBaseUrl(): string {
|
get nexusBaseUrl(): string {
|
||||||
return `http://localhost:${this.bankConfig.httpPort + 1}`;
|
return `http://localhost:${this.nexusPort}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrlDemobank(): string {
|
||||||
|
let url = new URL("demobanks/default/", this.baseUrlNetloc);
|
||||||
|
return url.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrlAccessApi(): string {
|
||||||
|
let url = new URL("access-api/", this.baseUrlDemobank);
|
||||||
|
return url.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrlNetloc(): string {
|
||||||
|
return `http://localhost:${this.bankConfig.httpPort}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
get baseUrl(): string {
|
get baseUrl(): string {
|
||||||
return `http://localhost:${this.bankConfig.httpPort}/demobanks/default/access-api`;
|
return this.baseUrlAccessApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSuggestedExchange(
|
async setSuggestedExchange(
|
||||||
@ -654,7 +691,11 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
await sh(
|
await sh(
|
||||||
this.globalTestState,
|
this.globalTestState,
|
||||||
"libeufin-sandbox-set-default-exchange",
|
"libeufin-sandbox-set-default-exchange",
|
||||||
`libeufin-sandbox default-exchange ${exchangePayto}`
|
`libeufin-sandbox default-exchange ${e.baseUrl} ${exchangePayto}`,
|
||||||
|
{
|
||||||
|
...process.env,
|
||||||
|
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -663,38 +704,45 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
accountName: string,
|
accountName: string,
|
||||||
password: string,
|
password: string,
|
||||||
): Promise<HarnessExchangeBankAccount> {
|
): Promise<HarnessExchangeBankAccount> {
|
||||||
|
console.log("Create Exchange account(s)!");
|
||||||
|
/**
|
||||||
|
* Many test cases try to create a Exchange account before
|
||||||
|
* starting the bank; that's because the Pybank did it entirely
|
||||||
|
* via the configuration file.
|
||||||
|
*/
|
||||||
|
await this.start();
|
||||||
|
await this.pingUntilAvailable();
|
||||||
await LibeufinSandboxApi.createDemobankAccount(
|
await LibeufinSandboxApi.createDemobankAccount(
|
||||||
accountName,
|
accountName,
|
||||||
password,
|
password,
|
||||||
{ baseUrl: this.baseUrl }
|
{ baseUrl: this.baseUrlAccessApi }
|
||||||
);
|
);
|
||||||
let bankAccountLabel = `${accountName}-acct`
|
let bankAccountLabel = accountName;
|
||||||
await LibeufinSandboxApi.createDemobankEbicsSubscriber(
|
await LibeufinSandboxApi.createDemobankEbicsSubscriber(
|
||||||
{
|
{
|
||||||
hostID: "talertest-ebics-host",
|
hostID: "talertestEbicsHost",
|
||||||
userID: "exchange-ebics-user",
|
userID: "exchangeEbicsUser",
|
||||||
partnerID: "exchange-ebics-partner",
|
partnerID: "exchangeEbicsPartner",
|
||||||
},
|
},
|
||||||
bankAccountLabel,
|
bankAccountLabel,
|
||||||
{ baseUrl: this.baseUrl }
|
{ baseUrl: this.baseUrlDemobank }
|
||||||
);
|
);
|
||||||
|
|
||||||
await LibeufinNexusApi.createUser(
|
await LibeufinNexusApi.createUser(
|
||||||
{ baseUrl: this.nexusBaseUrl },
|
{ baseUrl: this.nexusBaseUrl },
|
||||||
{
|
{
|
||||||
username: `${accountName}-nexus-username`,
|
username: accountName,
|
||||||
password: `${password}-nexus-password`
|
password: password
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await LibeufinNexusApi.createEbicsBankConnection(
|
await LibeufinNexusApi.createEbicsBankConnection(
|
||||||
{ baseUrl: this.nexusBaseUrl },
|
{ baseUrl: this.nexusBaseUrl },
|
||||||
{
|
{
|
||||||
name: "ebics-connection", // connection name.
|
name: "ebics-connection", // connection name.
|
||||||
ebicsURL: `http://localhost:${this.bankConfig.httpPort}/ebicsweb`,
|
ebicsURL: (new URL("ebicsweb", this.baseUrlNetloc)).href,
|
||||||
hostID: "talertest-ebics-host",
|
hostID: "talertestEbicsHost",
|
||||||
userID: "exchange-ebics-user",
|
userID: "exchangeEbicsUser",
|
||||||
partnerID: "exchange-ebics-partner",
|
partnerID: "exchangeEbicsPartner",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await LibeufinNexusApi.connectBankConnection(
|
await LibeufinNexusApi.connectBankConnection(
|
||||||
@ -706,7 +754,7 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
await LibeufinNexusApi.importConnectionAccount(
|
await LibeufinNexusApi.importConnectionAccount(
|
||||||
{ baseUrl: this.nexusBaseUrl },
|
{ baseUrl: this.nexusBaseUrl },
|
||||||
"ebics-connection", // connection name
|
"ebics-connection", // connection name
|
||||||
`${accountName}-acct`, // offered account label
|
accountName, // offered account label
|
||||||
`${accountName}-nexus-label` // bank account label at Nexus
|
`${accountName}-nexus-label` // bank account label at Nexus
|
||||||
);
|
);
|
||||||
await LibeufinNexusApi.createTwgFacade(
|
await LibeufinNexusApi.createTwgFacade(
|
||||||
@ -724,7 +772,7 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
{
|
{
|
||||||
action: "grant",
|
action: "grant",
|
||||||
permission: {
|
permission: {
|
||||||
subjectId: `${accountName}-nexus-username`,
|
subjectId: accountName,
|
||||||
subjectType: "user",
|
subjectType: "user",
|
||||||
resourceType: "facade",
|
resourceType: "facade",
|
||||||
resourceId: "exchange-facade", // facade name
|
resourceId: "exchange-facade", // facade name
|
||||||
@ -737,7 +785,7 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
{
|
{
|
||||||
action: "grant",
|
action: "grant",
|
||||||
permission: {
|
permission: {
|
||||||
subjectId: `${accountName}-nexus-username`,
|
subjectId: accountName,
|
||||||
subjectType: "user",
|
subjectType: "user",
|
||||||
resourceType: "facade",
|
resourceType: "facade",
|
||||||
resourceId: "exchange-facade", // facade name
|
resourceId: "exchange-facade", // facade name
|
||||||
@ -745,12 +793,35 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// Set fetch task.
|
||||||
|
await LibeufinNexusApi.postTask(
|
||||||
|
{ baseUrl: this.nexusBaseUrl },
|
||||||
|
`${accountName}-nexus-label`,
|
||||||
|
{
|
||||||
|
name: "wirewatch-task",
|
||||||
|
cronspec: "* * *",
|
||||||
|
type: "fetch",
|
||||||
|
params: {
|
||||||
|
level: "all",
|
||||||
|
rangeType: "all",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await LibeufinNexusApi.postTask(
|
||||||
|
{ baseUrl: this.nexusBaseUrl },
|
||||||
|
`${accountName}-nexus-label`,
|
||||||
|
{
|
||||||
|
name: "aggregator-task",
|
||||||
|
cronspec: "* * *",
|
||||||
|
type: "submit",
|
||||||
|
params: {},
|
||||||
|
}
|
||||||
|
);
|
||||||
let facadesResp = await LibeufinNexusApi.getAllFacades({ baseUrl: this.nexusBaseUrl });
|
let facadesResp = await LibeufinNexusApi.getAllFacades({ baseUrl: this.nexusBaseUrl });
|
||||||
let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo(
|
let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo(
|
||||||
accountName, // username
|
"admin",
|
||||||
password,
|
"secret",
|
||||||
{ baseUrl: this.nexusBaseUrl },
|
{ baseUrl: this.baseUrlAccessApi },
|
||||||
`${accountName}acct` // bank account label.
|
accountName // bank account label.
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
accountName: accountName,
|
accountName: accountName,
|
||||||
@ -761,15 +832,36 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
async start(): Promise<void> {
|
||||||
let sandboxDb = `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`;
|
/**
|
||||||
let nexusDb = `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`;
|
* Because many test cases try to create a Exchange bank
|
||||||
|
* account _before_ starting the bank (Pybank did it only via
|
||||||
|
* the config), it is possible that at this point Sandbox and
|
||||||
|
* Nexus are already running. Hence, this method only launches
|
||||||
|
* them if they weren't launched earlier.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Only go ahead if BOTH aren't running.
|
||||||
|
if (this.sandboxProc || this.nexusProc) {
|
||||||
|
console.log("Nexus or Sandbox already running, not taking any action.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await sh(
|
||||||
|
this.globalTestState,
|
||||||
|
"libeufin-sandbox-config-demobank",
|
||||||
|
`libeufin-sandbox config --currency=${this.bankConfig.currency} default`,
|
||||||
|
{
|
||||||
|
...process.env,
|
||||||
|
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
|
||||||
|
LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
|
||||||
|
},
|
||||||
|
);
|
||||||
this.sandboxProc = this.globalTestState.spawnService(
|
this.sandboxProc = this.globalTestState.spawnService(
|
||||||
"libeufin-sandbox",
|
"libeufin-sandbox",
|
||||||
["serve", "--port", `${this.port}`],
|
["serve", "--port", `${this.port}`],
|
||||||
"libeufin-sandbox",
|
"libeufin-sandbox",
|
||||||
{
|
{
|
||||||
...process.env,
|
...process.env,
|
||||||
LIBEUFIN_SANDBOX_DB_CONNECTION: sandboxDb,
|
LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
|
||||||
LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
|
LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -780,34 +872,48 @@ class LibeufinBankService extends BankServiceBase implements BankService {
|
|||||||
["superuser", "admin", "--password", "test"],
|
["superuser", "admin", "--password", "test"],
|
||||||
{
|
{
|
||||||
...process.env,
|
...process.env,
|
||||||
LIBEUFIN_NEXUS_DB_CONNECTION: nexusDb,
|
LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
this.nexusProc = this.globalTestState.spawnService(
|
this.nexusProc = this.globalTestState.spawnService(
|
||||||
"libeufin-nexus",
|
"libeufin-nexus",
|
||||||
["serve", "--port", `${this.port + 1}`],
|
["serve", "--port", `${this.nexusPort}`],
|
||||||
"libeufin-nexus",
|
"libeufin-nexus",
|
||||||
{
|
{
|
||||||
...process.env,
|
...process.env,
|
||||||
LIBEUFIN_NEXUS_DB_CONNECTION: nexusDb,
|
LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// need to wait here, because at this point
|
||||||
|
// a Ebics host needs to be created (RESTfully)
|
||||||
|
await this.pingUntilAvailable();
|
||||||
|
LibeufinSandboxApi.createEbicsHost(
|
||||||
|
{ baseUrl: this.baseUrlNetloc },
|
||||||
|
"talertestEbicsHost"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async pingUntilAvailable(): Promise<void> {
|
async pingUntilAvailable(): Promise<void> {
|
||||||
await pingProc(this.sandboxProc, this.baseUrl, "libeufin-sandbox");
|
await pingProc(
|
||||||
await pingProc(this.nexusProc, `${this.baseUrl}config`, "libeufin-nexus");
|
this.sandboxProc,
|
||||||
|
`http://localhost:${this.bankConfig.httpPort}`,
|
||||||
|
"libeufin-sandbox"
|
||||||
|
);
|
||||||
|
await pingProc(
|
||||||
|
this.nexusProc,
|
||||||
|
`${this.nexusBaseUrl}/config`,
|
||||||
|
"libeufin-nexus"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BankService extends BankServiceBase implements BankServiceInterface {
|
class PybankService extends BankServiceBase implements BankServiceInterface {
|
||||||
proc: ProcessWrapper | undefined;
|
proc: ProcessWrapper | undefined;
|
||||||
|
|
||||||
static async create(
|
static async create(
|
||||||
gc: GlobalTestState,
|
gc: GlobalTestState,
|
||||||
bc: BankConfig,
|
bc: BankConfig,
|
||||||
): Promise<BankService> {
|
): Promise<PybankService> {
|
||||||
const config = new Configuration();
|
const config = new Configuration();
|
||||||
setTalerPaths(config, gc.testDir + "/talerhome");
|
setTalerPaths(config, gc.testDir + "/talerhome");
|
||||||
config.setString("taler", "currency", bc.currency);
|
config.setString("taler", "currency", bc.currency);
|
||||||
@ -835,7 +941,7 @@ export class BankService extends BankServiceBase implements BankServiceInterface
|
|||||||
`taler-bank-manage -c '${cfgFilename}' django provide_accounts`,
|
`taler-bank-manage -c '${cfgFilename}' django provide_accounts`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return new BankService(gc, bc, cfgFilename);
|
return new PybankService(gc, bc, cfgFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) {
|
setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) {
|
||||||
@ -870,7 +976,7 @@ export class BankService extends BankServiceBase implements BankServiceInterface
|
|||||||
return {
|
return {
|
||||||
accountName: accountName,
|
accountName: accountName,
|
||||||
accountPassword: password,
|
accountPassword: password,
|
||||||
accountPaytoUri: `payto://x-taler-bank/${accountName}`,
|
accountPaytoUri: getPayto(accountName),
|
||||||
wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`,
|
wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -893,11 +999,31 @@ export class BankService extends BankServiceBase implements BankServiceInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still work in progress..
|
|
||||||
if (false && process.env.WALLET_HARNESS_WITH_EUFIN) {
|
/**
|
||||||
BankService.create = LibeufinBankService.create;
|
* Return a euFin or a pyBank implementation of
|
||||||
BankService.prototype = Object.create(LibeufinBankService.prototype);
|
* the exported BankService class. This allows
|
||||||
}
|
* to "dynamically export" such class depending
|
||||||
|
* on a particular env variable.
|
||||||
|
*/
|
||||||
|
function getBankServiceImpl(): {
|
||||||
|
prototype: typeof PybankService.prototype,
|
||||||
|
create: typeof PybankService.create
|
||||||
|
} {
|
||||||
|
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN)
|
||||||
|
return {
|
||||||
|
prototype: EufinBankService.prototype,
|
||||||
|
create: EufinBankService.create
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
prototype: PybankService.prototype,
|
||||||
|
create: PybankService.create
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BankService = PybankService;
|
||||||
|
export const BankService = getBankServiceImpl();
|
||||||
|
|
||||||
export class FakeBankService {
|
export class FakeBankService {
|
||||||
proc: ProcessWrapper | undefined;
|
proc: ProcessWrapper | undefined;
|
||||||
@ -1038,6 +1164,10 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async runWirewatchOnce() {
|
async runWirewatchOnce() {
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN) {
|
||||||
|
// Not even 2 secods showed to be enough!
|
||||||
|
await waitMs(4000);
|
||||||
|
}
|
||||||
await runCommand(
|
await runCommand(
|
||||||
this.globalState,
|
this.globalState,
|
||||||
`exchange-${this.name}-wirewatch-once`,
|
`exchange-${this.name}-wirewatch-once`,
|
||||||
@ -1699,7 +1829,7 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
return await this.addInstance({
|
return await this.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "external",
|
method: "external",
|
||||||
},
|
},
|
||||||
@ -1956,3 +2086,46 @@ export class WalletCli {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getRandomIban(salt: string | null = null): string {
|
||||||
|
|
||||||
|
function getBban(salt: string | null): string {
|
||||||
|
if (!salt)
|
||||||
|
return Math.random().toString().substring(2, 6);
|
||||||
|
let hashed = hash(stringToBytes(salt));
|
||||||
|
let ret = "";
|
||||||
|
for (let i = 0; i < hashed.length; i++) {
|
||||||
|
ret += hashed[i].toString();
|
||||||
|
}
|
||||||
|
return ret.substring(0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cc_no_check = "131400"; // == DE00
|
||||||
|
let bban = getBban(salt)
|
||||||
|
let check_digits = (98 - (Number.parseInt(`${bban}${cc_no_check}`) % 97)).toString();
|
||||||
|
if (check_digits.length == 1) {
|
||||||
|
check_digits = `0${check_digits}`;
|
||||||
|
}
|
||||||
|
return `DE${check_digits}${bban}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only used in one tipping test.
|
||||||
|
export function getWireMethod(): string {
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN)
|
||||||
|
return "iban"
|
||||||
|
return "x-taler-bank"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a payto address, whose authority depends
|
||||||
|
* on whether the banking is served by euFin or Pybank.
|
||||||
|
*/
|
||||||
|
export function getPayto(label: string): string {
|
||||||
|
if (process.env.WALLET_HARNESS_WITH_EUFIN)
|
||||||
|
return `payto://iban/SANDBOXX/${getRandomIban(label)}?receiver-name=${label}`
|
||||||
|
return `payto://x-taler-bank/${label}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitMs(ms: number): Promise<void> {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
@ -50,6 +50,7 @@ import {
|
|||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
HarnessExchangeBankAccount,
|
HarnessExchangeBankAccount,
|
||||||
WithAuthorization,
|
WithAuthorization,
|
||||||
|
getPayto
|
||||||
} from "./harness.js";
|
} from "./harness.js";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ export async function createSimpleTestkudosEnvironment(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -118,13 +119,13 @@ export async function createSimpleTestkudosEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
@ -186,7 +187,7 @@ export async function createFaultInjectedMerchantTestkudosEnvironment(
|
|||||||
const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081);
|
const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081);
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -213,13 +214,13 @@ export async function createFaultInjectedMerchantTestkudosEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
@ -263,16 +264,19 @@ export async function startWithdrawViaBank(
|
|||||||
|
|
||||||
await wallet.runPending();
|
await wallet.runPending();
|
||||||
|
|
||||||
// Confirm it
|
// Withdraw (AKA select)
|
||||||
|
|
||||||
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
|
||||||
|
|
||||||
// Withdraw
|
|
||||||
|
|
||||||
await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Confirm it
|
||||||
|
|
||||||
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
|
await wallet.runPending();
|
||||||
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -184,7 +184,7 @@ export namespace LibeufinSandboxApi {
|
|||||||
libeufinSandboxService: LibeufinSandboxServiceInterface,
|
libeufinSandboxService: LibeufinSandboxServiceInterface,
|
||||||
accountLabel: string
|
accountLabel: string
|
||||||
) {
|
) {
|
||||||
let url = new URL(`${libeufinSandboxService.baseUrl}/accounts/${accountLabel}`);
|
let url = new URL(`accounts/${accountLabel}`,libeufinSandboxService.baseUrl);
|
||||||
return await axios.get(url.href, {
|
return await axios.get(url.href, {
|
||||||
auth: {
|
auth: {
|
||||||
username: username,
|
username: username,
|
||||||
@ -199,7 +199,7 @@ export namespace LibeufinSandboxApi {
|
|||||||
password: string,
|
password: string,
|
||||||
libeufinSandboxService: LibeufinSandboxServiceInterface,
|
libeufinSandboxService: LibeufinSandboxServiceInterface,
|
||||||
) {
|
) {
|
||||||
let url = new URL(`${libeufinSandboxService.baseUrl}/testing/register`);
|
let url = new URL("testing/register", libeufinSandboxService.baseUrl);
|
||||||
await axios.post(url.href, {
|
await axios.post(url.href, {
|
||||||
username: username,
|
username: username,
|
||||||
password: password
|
password: password
|
||||||
@ -214,11 +214,11 @@ export namespace LibeufinSandboxApi {
|
|||||||
password: string = "secret",
|
password: string = "secret",
|
||||||
) {
|
) {
|
||||||
// baseUrl should already be pointed to one demobank.
|
// baseUrl should already be pointed to one demobank.
|
||||||
let url = new URL(libeufinSandboxService.baseUrl);
|
let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl);
|
||||||
await axios.post(url.href, {
|
await axios.post(url.href, {
|
||||||
userID: req.userID,
|
userID: req.userID,
|
||||||
hostID: req.hostID,
|
hostID: req.hostID,
|
||||||
partnerID: req.userID,
|
partnerID: req.partnerID,
|
||||||
demobankAccountLabel: demobankAccountLabel,
|
demobankAccountLabel: demobankAccountLabel,
|
||||||
}, {
|
}, {
|
||||||
auth: {
|
auth: {
|
||||||
|
@ -36,8 +36,8 @@ import {
|
|||||||
runCommand,
|
runCommand,
|
||||||
setupDb,
|
setupDb,
|
||||||
sh,
|
sh,
|
||||||
|
getRandomIban
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
LibeufinSandboxApi,
|
LibeufinSandboxApi,
|
||||||
LibeufinNexusApi,
|
LibeufinNexusApi,
|
||||||
@ -183,10 +183,6 @@ export interface LibeufinPreparedPaymentDetails {
|
|||||||
nexusBankAccountName: string;
|
nexusBankAccountName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomIban(countryCode: string): string {
|
|
||||||
return `${countryCode}715001051796${(Math.random().toString().substring(2, 8))}`
|
|
||||||
}
|
|
||||||
|
|
||||||
export class LibeufinSandboxService implements LibeufinSandboxServiceInterface {
|
export class LibeufinSandboxService implements LibeufinSandboxServiceInterface {
|
||||||
static async create(
|
static async create(
|
||||||
gc: GlobalTestState,
|
gc: GlobalTestState,
|
||||||
@ -405,7 +401,7 @@ export class SandboxUserBundle {
|
|||||||
constructor(salt: string) {
|
constructor(salt: string) {
|
||||||
this.ebicsBankAccount = {
|
this.ebicsBankAccount = {
|
||||||
bic: "BELADEBEXXX",
|
bic: "BELADEBEXXX",
|
||||||
iban: getRandomIban("DE"),
|
iban: getRandomIban(),
|
||||||
label: `remote-account-${salt}`,
|
label: `remote-account-${salt}`,
|
||||||
name: `Taler Exchange: ${salt}`,
|
name: `Taler Exchange: ${salt}`,
|
||||||
subscriber: {
|
subscriber: {
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
BankApi,
|
BankApi,
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
CreditDebitIndicator,
|
CreditDebitIndicator,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util";
|
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util";
|
||||||
import { defaultCoinConfig } from "../harness/denomStructures";
|
import { defaultCoinConfig } from "../harness/denomStructures";
|
||||||
@ -61,7 +62,7 @@ export async function runBankApiTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -85,13 +86,13 @@ export async function runBankApiTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState, getPayto } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironment, withdrawViaBank } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment, withdrawViaBank } from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +44,7 @@ export async function runDepositTest(t: GlobalTestState) {
|
|||||||
WalletApiOperation.CreateDepositGroup,
|
WalletApiOperation.CreateDepositGroup,
|
||||||
{
|
{
|
||||||
amount: "TESTKUDOS:10",
|
amount: "TESTKUDOS:10",
|
||||||
depositPaytoUri: "payto://x-taler-bank/localhost/foo",
|
depositPaytoUri: getPayto("foo"),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
BankApi,
|
BankApi,
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
import {
|
||||||
@ -69,7 +70,7 @@ export async function runExchangeManagementTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -98,13 +99,13 @@ export async function runExchangeManagementTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -40,6 +40,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js";
|
import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js";
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -127,13 +128,13 @@ export async function runExchangeTimetravelTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
@ -63,7 +64,7 @@ export async function createMyTestkudosEnvironment(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -140,7 +141,7 @@ export async function createMyTestkudosEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
@ -80,7 +81,7 @@ export async function createConfusedMerchantTestkudosEnvironment(
|
|||||||
const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081);
|
const faultyExchange = new FaultInjectedExchangeService(t, exchange, 9081);
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -108,13 +109,13 @@ export async function createConfusedMerchantTestkudosEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")]
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
MerchantApiClient,
|
MerchantApiClient,
|
||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +75,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "external",
|
method: "external",
|
||||||
},
|
},
|
||||||
@ -84,7 +85,7 @@ export async function runMerchantInstancesDeleteTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "myinst",
|
id: "myinst",
|
||||||
name: "Second Instance",
|
name: "Second Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "external",
|
method: "external",
|
||||||
},
|
},
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
MerchantApiClient,
|
MerchantApiClient,
|
||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,7 +72,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
|
|||||||
default_wire_transfer_delay: { d_ms: 60000 },
|
default_wire_transfer_delay: { d_ms: 60000 },
|
||||||
jurisdiction: {},
|
jurisdiction: {},
|
||||||
name: "My Default Instance",
|
name: "My Default Instance",
|
||||||
payto_uris: ["payto://x-taler-bank/foo/bar"],
|
payto_uris: [getPayto("bar")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "token",
|
method: "token",
|
||||||
token: "secret-token:i-am-default",
|
token: "secret-token:i-am-default",
|
||||||
@ -88,7 +89,7 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
|
|||||||
default_wire_transfer_delay: { d_ms: 60000 },
|
default_wire_transfer_delay: { d_ms: 60000 },
|
||||||
jurisdiction: {},
|
jurisdiction: {},
|
||||||
name: "My Second Instance",
|
name: "My Second Instance",
|
||||||
payto_uris: ["payto://x-taler-bank/foo/bar"],
|
payto_uris: [getPayto("bar")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "token",
|
method: "token",
|
||||||
token: "secret-token:i-am-myinst",
|
token: "secret-token:i-am-myinst",
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
MerchantApiClient,
|
MerchantApiClient,
|
||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,7 +75,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "external",
|
method: "external",
|
||||||
},
|
},
|
||||||
@ -84,7 +85,7 @@ export async function runMerchantInstancesTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "myinst",
|
id: "myinst",
|
||||||
name: "Second Instance",
|
name: "Second Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
auth: {
|
auth: {
|
||||||
method: "external",
|
method: "external",
|
||||||
},
|
},
|
||||||
|
@ -31,6 +31,7 @@ import {
|
|||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
BankApi,
|
BankApi,
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
FaultInjectedExchangeService,
|
FaultInjectedExchangeService,
|
||||||
@ -64,7 +65,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -107,7 +108,7 @@ export async function runPaymentFaultTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
@ -131,18 +132,21 @@ export async function runPaymentFaultTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
await wallet.runPending();
|
await wallet.runPending();
|
||||||
|
|
||||||
// Confirm it
|
|
||||||
|
|
||||||
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
|
||||||
|
|
||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
||||||
exchangeBaseUrl: faultyExchange.baseUrl,
|
exchangeBaseUrl: faultyExchange.baseUrl,
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
});
|
});
|
||||||
|
await wallet.runPending();
|
||||||
|
|
||||||
|
// Confirm it
|
||||||
|
|
||||||
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
await wallet.runUntilDone();
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
|
|
||||||
// Check balance
|
// Check balance
|
||||||
|
|
||||||
await wallet.client.call(WalletApiOperation.GetBalances, {});
|
await wallet.client.call(WalletApiOperation.GetBalances, {});
|
||||||
|
@ -25,6 +25,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { withdrawViaBank } from "../harness/helpers.js";
|
import { withdrawViaBank } from "../harness/helpers.js";
|
||||||
import { coin_ct10, coin_u1 } from "../harness/denomStructures";
|
import { coin_ct10, coin_u1 } from "../harness/denomStructures";
|
||||||
@ -54,7 +55,7 @@ async function setupTest(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -86,13 +87,13 @@ async function setupTest(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
setupDb,
|
setupDb,
|
||||||
BankService,
|
BankService,
|
||||||
delayMs,
|
delayMs,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
@ -84,7 +85,7 @@ async function createTestEnvironment(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -121,13 +122,13 @@ async function createTestEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -36,6 +36,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js";
|
import { startWithdrawViaBank, withdrawViaBank } from "../harness/helpers.js";
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -121,13 +122,13 @@ export async function runTimetravelAutorefreshTest(t: GlobalTestState) {
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "minst1",
|
id: "minst1",
|
||||||
name: "minst1",
|
name: "minst1",
|
||||||
paytoUris: ["payto://x-taler-bank/minst1"],
|
paytoUris: [getPayto("minst1")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState, MerchantPrivateApi, BankApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi, BankApi, getWireMethod } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +43,7 @@ export async function runTippingTest(t: GlobalTestState) {
|
|||||||
{
|
{
|
||||||
exchange_url: exchange.baseUrl,
|
exchange_url: exchange.baseUrl,
|
||||||
initial_balance: "TESTKUDOS:10",
|
initial_balance: "TESTKUDOS:10",
|
||||||
wire_method: "x-taler-bank",
|
wire_method: getWireMethod(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import {
|
|||||||
MerchantService,
|
MerchantService,
|
||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
getPayto
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { SimpleTestEnvironment } from "../harness/helpers.js";
|
import { SimpleTestEnvironment } from "../harness/helpers.js";
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ export async function createMyEnvironment(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
"MyExchange",
|
"myexchange",
|
||||||
"x",
|
"x",
|
||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
@ -93,7 +94,7 @@ export async function createMyEnvironment(
|
|||||||
await merchant.addInstance({
|
await merchant.addInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
name: "Default Instance",
|
name: "Default Instance",
|
||||||
paytoUris: [`payto://x-taler-bank/merchant-default`],
|
paytoUris: [getPayto("merchant-default")],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
@ -47,12 +47,18 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
await wallet.runPending();
|
await wallet.runPending();
|
||||||
|
|
||||||
// Confirm it
|
// Abort it
|
||||||
|
|
||||||
await BankApi.abortWithdrawalOperation(bank, user, wop);
|
await BankApi.abortWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
|
// Difference:
|
||||||
|
// -> with euFin, the wallet selects
|
||||||
|
// -> with PyBank, the wallet stops _before_
|
||||||
|
//
|
||||||
|
// WHY ?!
|
||||||
|
//
|
||||||
const e = await t.assertThrowsOperationErrorAsync(async () => {
|
const e = await t.assertThrowsOperationErrorAsync(async () => {
|
||||||
await wallet.client.call(
|
await wallet.client.call(
|
||||||
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
WalletApiOperation.AcceptBankIntegratedWithdrawal,
|
||||||
|
@ -47,16 +47,18 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
await wallet.runPending();
|
await wallet.runPending();
|
||||||
|
|
||||||
// Confirm it
|
|
||||||
|
|
||||||
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
|
||||||
|
|
||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
const r2 = await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
const r2 = await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, {
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
talerWithdrawUri: wop.taler_withdraw_uri,
|
talerWithdrawUri: wop.taler_withdraw_uri,
|
||||||
});
|
});
|
||||||
|
await wallet.runPending();
|
||||||
|
|
||||||
|
// Confirm it
|
||||||
|
|
||||||
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
await wallet.runUntilDone();
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
// Check balance
|
// Check balance
|
||||||
|
@ -50,6 +50,7 @@ export async function runTestWithdrawalManualTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
const reservePub: string = wres.reservePub;
|
const reservePub: string = wres.reservePub;
|
||||||
|
|
||||||
|
// Bug.
|
||||||
await BankApi.adminAddIncoming(bank, {
|
await BankApi.adminAddIncoming(bank, {
|
||||||
exchangeBankAccount,
|
exchangeBankAccount,
|
||||||
amount: "TESTKUDOS:10",
|
amount: "TESTKUDOS:10",
|
||||||
|
@ -175,7 +175,7 @@ export async function getEffectiveDepositAmount(
|
|||||||
for (let i = 0; i < pcs.coinPubs.length; i++) {
|
for (let i = 0; i < pcs.coinPubs.length; i++) {
|
||||||
const coin = await tx.coins.get(pcs.coinPubs[i]);
|
const coin = await tx.coins.get(pcs.coinPubs[i]);
|
||||||
if (!coin) {
|
if (!coin) {
|
||||||
throw Error("can't calculate deposit amountt, coin not found");
|
throw Error("can't calculate deposit amount, coin not found");
|
||||||
}
|
}
|
||||||
const denom = await tx.denominations.get([
|
const denom = await tx.denominations.get([
|
||||||
coin.exchangeBaseUrl,
|
coin.exchangeBaseUrl,
|
||||||
@ -193,6 +193,9 @@ export async function getEffectiveDepositAmount(
|
|||||||
if (!exchangeDetails) {
|
if (!exchangeDetails) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// FIXME/NOTE: the line below _likely_ throws exception
|
||||||
|
// about "find method not found on undefined" when the wireType
|
||||||
|
// is not supported by the Exchange.
|
||||||
const fee = exchangeDetails.wireInfo.feesForType[wireType].find((x) => {
|
const fee = exchangeDetails.wireInfo.feesForType[wireType].find((x) => {
|
||||||
return timestampIsBetween(
|
return timestampIsBetween(
|
||||||
getTimestampNow(),
|
getTimestampNow(),
|
||||||
|
@ -174,7 +174,8 @@ async function registerRandomBankUser(
|
|||||||
const reqUrl = new URL("testing/register", bankBaseUrl).href;
|
const reqUrl = new URL("testing/register", bankBaseUrl).href;
|
||||||
const randId = makeId(8);
|
const randId = makeId(8);
|
||||||
const bankUser: BankUser = {
|
const bankUser: BankUser = {
|
||||||
username: `testuser-${randId}`,
|
// euFin doesn't allow resource names to have upper case letters.
|
||||||
|
username: `testuser-${randId.toLowerCase()}`,
|
||||||
password: `testpw-${randId}`,
|
password: `testpw-${randId}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user