Compare commits
No commits in common. "a58f73ecdb995e02a770338aa8a8aa529ccfdfaa" and "5ab3070b3a63c2e8fed0e413dea06cf03fb48f1e" have entirely different histories.
a58f73ecdb
...
5ab3070b3a
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getGlobalLogLevel,
|
globalLogLevel,
|
||||||
setGlobalLogLevelFromString,
|
setGlobalLogLevelFromString,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { TranslationProvider } from "@gnu-taler/web-util/browser";
|
import { TranslationProvider } from "@gnu-taler/web-util/browser";
|
||||||
@ -62,7 +62,9 @@ const App: FunctionalComponent = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
(window as any).setGlobalLogLevelFromString = setGlobalLogLevelFromString;
|
(window as any).setGlobalLogLevelFromString = setGlobalLogLevelFromString;
|
||||||
(window as any).getGlobalLevel = getGlobalLogLevel;
|
(window as any).getGlobaLevel = () => {
|
||||||
|
return globalLogLevel;
|
||||||
|
};
|
||||||
|
|
||||||
function localStorageProvider(): Map<unknown, unknown> {
|
function localStorageProvider(): Map<unknown, unknown> {
|
||||||
const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
|
const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]"));
|
||||||
|
@ -467,29 +467,12 @@ export async function setupDb(t: GlobalTestState): Promise<DbInfo> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Make sure that the taler-integrationtest-shared database exists.
|
|
||||||
* Don't delete it if it already exists.
|
|
||||||
*/
|
|
||||||
export async function setupSharedDb(t: GlobalTestState): Promise<DbInfo> {
|
|
||||||
const dbname = "taler-integrationtest-shared";
|
|
||||||
const databases = await runCommand(t, "list-dbs", "psql", ["-Aqtl"]);
|
|
||||||
if (databases.indexOf("taler-integrationtest-shared") < 0) {
|
|
||||||
await runCommand(t, "createdb", "createdb", [dbname]);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
connStr: `postgres:///${dbname}`,
|
|
||||||
dbname,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BankConfig {
|
export interface BankConfig {
|
||||||
currency: string;
|
currency: string;
|
||||||
httpPort: number;
|
httpPort: number;
|
||||||
database: string;
|
database: string;
|
||||||
allowRegistrations: boolean;
|
allowRegistrations: boolean;
|
||||||
maxDebt?: string;
|
maxDebt?: string;
|
||||||
overrideTestDir?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FakeBankConfig {
|
export interface FakeBankConfig {
|
||||||
@ -535,14 +518,6 @@ function setCoin(config: Configuration, c: CoinConfig) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function backoffStart(): number {
|
|
||||||
return 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
function backoffIncrement(n: number): number {
|
|
||||||
return Math.min(Math.floor(n * 1.5), 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an HTTP request until it succeeds or the process dies.
|
* Send an HTTP request until it succeeds or the process dies.
|
||||||
*/
|
*/
|
||||||
@ -554,7 +529,6 @@ export async function pingProc(
|
|||||||
if (!proc || proc.proc.exitCode !== null) {
|
if (!proc || proc.proc.exitCode !== null) {
|
||||||
throw Error(`service process ${serviceName} not started, can't ping`);
|
throw Error(`service process ${serviceName} not started, can't ping`);
|
||||||
}
|
}
|
||||||
let nextDelay = backoffStart();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
logger.trace(`pinging ${serviceName} at ${url}`);
|
logger.trace(`pinging ${serviceName} at ${url}`);
|
||||||
@ -563,9 +537,8 @@ export async function pingProc(
|
|||||||
return;
|
return;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
logger.warn(`service ${serviceName} not ready:`, e.toString());
|
logger.warn(`service ${serviceName} not ready:`, e.toString());
|
||||||
logger.info(`waiting ${nextDelay}ms on ${serviceName}`);
|
//console.log(e);
|
||||||
await delayMs(nextDelay);
|
await delayMs(1000);
|
||||||
nextDelay = backoffIncrement(nextDelay);
|
|
||||||
}
|
}
|
||||||
if (!proc || proc.proc.exitCode != null || proc.proc.signalCode != null) {
|
if (!proc || proc.proc.exitCode != null || proc.proc.signalCode != null) {
|
||||||
throw Error(`service process ${serviceName} stopped unexpectedly`);
|
throw Error(`service process ${serviceName} stopped unexpectedly`);
|
||||||
@ -884,57 +857,31 @@ export class FakebankService
|
|||||||
accountPassword: string;
|
accountPassword: string;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new fakebank service handle.
|
|
||||||
*
|
|
||||||
* First generates the configuration for the fakebank and
|
|
||||||
* then creates a fakebank handle, but doesn't start the fakebank
|
|
||||||
* service yet.
|
|
||||||
*/
|
|
||||||
static async create(
|
static async create(
|
||||||
gc: GlobalTestState,
|
gc: GlobalTestState,
|
||||||
bc: BankConfig,
|
bc: BankConfig,
|
||||||
): Promise<FakebankService> {
|
): Promise<FakebankService> {
|
||||||
const config = new Configuration();
|
const config = new Configuration();
|
||||||
const testDir = bc.overrideTestDir ?? gc.testDir;
|
setTalerPaths(config, gc.testDir + "/talerhome");
|
||||||
setTalerPaths(config, testDir + "/talerhome");
|
|
||||||
config.setString("taler", "currency", bc.currency);
|
config.setString("taler", "currency", bc.currency);
|
||||||
config.setString("bank", "http_port", `${bc.httpPort}`);
|
config.setString("bank", "http_port", `${bc.httpPort}`);
|
||||||
config.setString("bank", "serve", "http");
|
config.setString("bank", "serve", "http");
|
||||||
config.setString("bank", "max_debt_bank", `${bc.currency}:999999`);
|
config.setString("bank", "max_debt_bank", `${bc.currency}:999999`);
|
||||||
config.setString("bank", "max_debt", bc.maxDebt ?? `${bc.currency}:100`);
|
config.setString("bank", "max_debt", bc.maxDebt ?? `${bc.currency}:100`);
|
||||||
config.setString("bank", "ram_limit", `${1024}`);
|
config.setString("bank", "ram_limit", `${1024}`);
|
||||||
const cfgFilename = testDir + "/bank.conf";
|
const cfgFilename = gc.testDir + "/bank.conf";
|
||||||
config.write(cfgFilename, { excludeDefaults: true });
|
config.write(cfgFilename);
|
||||||
|
|
||||||
return new FakebankService(gc, bc, cfgFilename);
|
return new FakebankService(gc, bc, cfgFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromExistingConfig(
|
|
||||||
gc: GlobalTestState,
|
|
||||||
opts: { overridePath?: string },
|
|
||||||
): FakebankService {
|
|
||||||
const testDir = opts.overridePath ?? gc.testDir;
|
|
||||||
const cfgFilename = testDir + `/bank.conf`;
|
|
||||||
const config = Configuration.load(cfgFilename);
|
|
||||||
const bc: BankConfig = {
|
|
||||||
allowRegistrations:
|
|
||||||
config.getYesNo("bank", "allow_registrations").orUndefined() ?? true,
|
|
||||||
currency: config.getString("taler", "currency").required(),
|
|
||||||
database: "none",
|
|
||||||
httpPort: config.getNumber("bank", "http_port").required(),
|
|
||||||
maxDebt: config.getString("bank", "max_debt").required(),
|
|
||||||
};
|
|
||||||
return new FakebankService(gc, bc, cfgFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) {
|
setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) {
|
||||||
if (!!this.proc) {
|
if (!!this.proc) {
|
||||||
throw Error("Can't set suggested exchange while bank is running.");
|
throw Error("Can't set suggested exchange while bank is running.");
|
||||||
}
|
}
|
||||||
const config = Configuration.load(this.configFile);
|
const config = Configuration.load(this.configFile);
|
||||||
config.setString("bank", "suggested_exchange", e.baseUrl);
|
config.setString("bank", "suggested_exchange", e.baseUrl);
|
||||||
config.write(this.configFile, { excludeDefaults: true });
|
config.write(this.configFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
get baseUrl(): string {
|
get baseUrl(): string {
|
||||||
@ -1011,7 +958,6 @@ export interface ExchangeConfig {
|
|||||||
roundUnit?: string;
|
roundUnit?: string;
|
||||||
httpPort: number;
|
httpPort: number;
|
||||||
database: string;
|
database: string;
|
||||||
overrideTestDir?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExchangeServiceInterface {
|
export interface ExchangeServiceInterface {
|
||||||
@ -1022,13 +968,8 @@ export interface ExchangeServiceInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ExchangeService implements ExchangeServiceInterface {
|
export class ExchangeService implements ExchangeServiceInterface {
|
||||||
static fromExistingConfig(
|
static fromExistingConfig(gc: GlobalTestState, exchangeName: string) {
|
||||||
gc: GlobalTestState,
|
const cfgFilename = gc.testDir + `/exchange-${exchangeName}.conf`;
|
||||||
exchangeName: string,
|
|
||||||
opts: { overridePath?: string },
|
|
||||||
) {
|
|
||||||
const testDir = opts.overridePath ?? gc.testDir;
|
|
||||||
const cfgFilename = testDir + `/exchange-${exchangeName}.conf`;
|
|
||||||
const config = Configuration.load(cfgFilename);
|
const config = Configuration.load(cfgFilename);
|
||||||
const ec: ExchangeConfig = {
|
const ec: ExchangeConfig = {
|
||||||
currency: config.getString("taler", "currency").required(),
|
currency: config.getString("taler", "currency").required(),
|
||||||
@ -1037,9 +978,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
name: exchangeName,
|
name: exchangeName,
|
||||||
roundUnit: config.getString("taler", "currency_round_unit").required(),
|
roundUnit: config.getString("taler", "currency_round_unit").required(),
|
||||||
};
|
};
|
||||||
const privFile = config
|
const privFile = config.getPath("exchange", "master_priv_file").required();
|
||||||
.getPath("exchange-offline", "master_priv_file")
|
|
||||||
.required();
|
|
||||||
const eddsaPriv = fs.readFileSync(privFile);
|
const eddsaPriv = fs.readFileSync(privFile);
|
||||||
const keyPair: EddsaKeyPair = {
|
const keyPair: EddsaKeyPair = {
|
||||||
eddsaPriv,
|
eddsaPriv,
|
||||||
@ -1137,13 +1076,11 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
changeConfig(f: (config: Configuration) => void) {
|
changeConfig(f: (config: Configuration) => void) {
|
||||||
const config = Configuration.load(this.configFilename);
|
const config = Configuration.load(this.configFilename);
|
||||||
f(config);
|
f(config);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static create(gc: GlobalTestState, e: ExchangeConfig) {
|
static create(gc: GlobalTestState, e: ExchangeConfig) {
|
||||||
const testDir = e.overrideTestDir ?? gc.testDir;
|
|
||||||
const config = new Configuration();
|
const config = new Configuration();
|
||||||
setTalerPaths(config, testDir + "/talerhome");
|
|
||||||
config.setString("taler", "currency", e.currency);
|
config.setString("taler", "currency", e.currency);
|
||||||
// Required by the exchange but not really used yet.
|
// Required by the exchange but not really used yet.
|
||||||
config.setString("exchange", "aml_threshold", `${e.currency}:1000000`);
|
config.setString("exchange", "aml_threshold", `${e.currency}:1000000`);
|
||||||
@ -1152,6 +1089,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
"currency_round_unit",
|
"currency_round_unit",
|
||||||
e.roundUnit ?? `${e.currency}:0.01`,
|
e.roundUnit ?? `${e.currency}:0.01`,
|
||||||
);
|
);
|
||||||
|
setTalerPaths(config, gc.testDir + "/talerhome");
|
||||||
config.setString(
|
config.setString(
|
||||||
"exchange",
|
"exchange",
|
||||||
"revocation_dir",
|
"revocation_dir",
|
||||||
@ -1186,16 +1124,10 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
|
|
||||||
fs.mkdirSync(path.dirname(masterPrivFile), { recursive: true });
|
fs.mkdirSync(path.dirname(masterPrivFile), { recursive: true });
|
||||||
|
|
||||||
if (fs.existsSync(masterPrivFile)) {
|
|
||||||
throw new Error(
|
|
||||||
"master priv file already exists, can't create new exchange config",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(masterPrivFile, Buffer.from(exchangeMasterKey.eddsaPriv));
|
fs.writeFileSync(masterPrivFile, Buffer.from(exchangeMasterKey.eddsaPriv));
|
||||||
|
|
||||||
const cfgFilename = testDir + `/exchange-${e.name}.conf`;
|
const cfgFilename = gc.testDir + `/exchange-${e.name}.conf`;
|
||||||
config.write(cfgFilename, { excludeDefaults: true });
|
config.write(cfgFilename);
|
||||||
return new ExchangeService(gc, e, cfgFilename, exchangeMasterKey);
|
return new ExchangeService(gc, e, cfgFilename, exchangeMasterKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1204,13 +1136,13 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
offeredCoins.forEach((cc) =>
|
offeredCoins.forEach((cc) =>
|
||||||
setCoin(config, cc(this.exchangeConfig.currency)),
|
setCoin(config, cc(this.exchangeConfig.currency)),
|
||||||
);
|
);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
addCoinConfigList(ccs: CoinConfig[]) {
|
addCoinConfigList(ccs: CoinConfig[]) {
|
||||||
const config = Configuration.load(this.configFilename);
|
const config = Configuration.load(this.configFilename);
|
||||||
ccs.forEach((cc) => setCoin(config, cc));
|
ccs.forEach((cc) => setCoin(config, cc));
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
enableAgeRestrictions(maskStr: string) {
|
enableAgeRestrictions(maskStr: string) {
|
||||||
@ -1221,7 +1153,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
"age_groups",
|
"age_groups",
|
||||||
maskStr,
|
maskStr,
|
||||||
);
|
);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
get masterPub() {
|
get masterPub() {
|
||||||
@ -1242,7 +1174,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const config = Configuration.load(this.configFilename);
|
const config = Configuration.load(this.configFilename);
|
||||||
await f(config);
|
await f(config);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addBankAccount(
|
async addBankAccount(
|
||||||
@ -1282,7 +1214,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
"password",
|
"password",
|
||||||
exchangeBankAccount.accountPassword,
|
exchangeBankAccount.accountPassword,
|
||||||
);
|
);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeHttpProc: ProcessWrapper | undefined;
|
exchangeHttpProc: ProcessWrapper | undefined;
|
||||||
@ -1543,26 +1475,15 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async dbinit() {
|
async start(): Promise<void> {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
throw Error("exchange is already running");
|
||||||
|
}
|
||||||
await sh(
|
await sh(
|
||||||
this.globalState,
|
this.globalState,
|
||||||
"exchange-dbinit",
|
"exchange-dbinit",
|
||||||
`taler-exchange-dbinit -c "${this.configFilename}"`,
|
`taler-exchange-dbinit -c "${this.configFilename}"`,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
async start(
|
|
||||||
opts: { skipDbinit?: boolean; skipKeyup?: boolean } = {},
|
|
||||||
): Promise<void> {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
throw Error("exchange is already running");
|
|
||||||
}
|
|
||||||
|
|
||||||
const skipDbinit = opts.skipDbinit ?? false;
|
|
||||||
|
|
||||||
if (!skipDbinit) {
|
|
||||||
await this.dbinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.helperCryptoEddsaProc = this.globalState.spawnService(
|
this.helperCryptoEddsaProc = this.globalState.spawnService(
|
||||||
"taler-exchange-secmod-eddsa",
|
"taler-exchange-secmod-eddsa",
|
||||||
@ -1593,14 +1514,7 @@ export class ExchangeService implements ExchangeServiceInterface {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await this.pingUntilAvailable();
|
await this.pingUntilAvailable();
|
||||||
|
|
||||||
const skipKeyup = opts.skipKeyup ?? false;
|
|
||||||
|
|
||||||
if (!skipKeyup) {
|
|
||||||
await this.keyup();
|
await this.keyup();
|
||||||
} else {
|
|
||||||
logger.info("skipping keyup");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async pingUntilAvailable(): Promise<void> {
|
async pingUntilAvailable(): Promise<void> {
|
||||||
@ -1616,7 +1530,6 @@ export interface MerchantConfig {
|
|||||||
currency: string;
|
currency: string;
|
||||||
httpPort: number;
|
httpPort: number;
|
||||||
database: string;
|
database: string;
|
||||||
overrideTestDir?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrivateOrderStatusQuery {
|
export interface PrivateOrderStatusQuery {
|
||||||
@ -1862,13 +1775,8 @@ export interface CreateMerchantTippingReserveRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class MerchantService implements MerchantServiceInterface {
|
export class MerchantService implements MerchantServiceInterface {
|
||||||
static fromExistingConfig(
|
static fromExistingConfig(gc: GlobalTestState, name: string) {
|
||||||
gc: GlobalTestState,
|
const cfgFilename = gc.testDir + `/merchant-${name}.conf`;
|
||||||
name: string,
|
|
||||||
opts: { overridePath?: string },
|
|
||||||
) {
|
|
||||||
const testDir = opts.overridePath ?? gc.testDir;
|
|
||||||
const cfgFilename = testDir + `/merchant-${name}.conf`;
|
|
||||||
const config = Configuration.load(cfgFilename);
|
const config = Configuration.load(cfgFilename);
|
||||||
const mc: MerchantConfig = {
|
const mc: MerchantConfig = {
|
||||||
currency: config.getString("taler", "currency").required(),
|
currency: config.getString("taler", "currency").required(),
|
||||||
@ -1938,24 +1846,13 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async dbinit() {
|
async start(): Promise<void> {
|
||||||
await runCommand(
|
await runCommand(
|
||||||
this.globalState,
|
this.globalState,
|
||||||
"merchant-dbinit",
|
"merchant-dbinit",
|
||||||
"taler-merchant-dbinit",
|
"taler-merchant-dbinit",
|
||||||
["-c", this.configFilename],
|
["-c", this.configFilename],
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the merchant,
|
|
||||||
*/
|
|
||||||
async start(opts: { skipDbinit?: boolean } = {}): Promise<void> {
|
|
||||||
const skipSetup = opts.skipDbinit ?? false;
|
|
||||||
|
|
||||||
if (!skipSetup) {
|
|
||||||
await this.dbinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.proc = this.globalState.spawnService(
|
this.proc = this.globalState.spawnService(
|
||||||
"taler-merchant-httpd",
|
"taler-merchant-httpd",
|
||||||
@ -1974,12 +1871,11 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
gc: GlobalTestState,
|
gc: GlobalTestState,
|
||||||
mc: MerchantConfig,
|
mc: MerchantConfig,
|
||||||
): Promise<MerchantService> {
|
): Promise<MerchantService> {
|
||||||
const testDir = mc.overrideTestDir ?? gc.testDir;
|
|
||||||
const config = new Configuration();
|
const config = new Configuration();
|
||||||
config.setString("taler", "currency", mc.currency);
|
config.setString("taler", "currency", mc.currency);
|
||||||
|
|
||||||
const cfgFilename = testDir + `/merchant-${mc.name}.conf`;
|
const cfgFilename = gc.testDir + `/merchant-${mc.name}.conf`;
|
||||||
setTalerPaths(config, testDir + "/talerhome");
|
setTalerPaths(config, gc.testDir + "/talerhome");
|
||||||
config.setString("merchant", "serve", "tcp");
|
config.setString("merchant", "serve", "tcp");
|
||||||
config.setString("merchant", "port", `${mc.httpPort}`);
|
config.setString("merchant", "port", `${mc.httpPort}`);
|
||||||
config.setString(
|
config.setString(
|
||||||
@ -1988,7 +1884,7 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
"${TALER_DATA_HOME}/merchant/merchant.priv",
|
"${TALER_DATA_HOME}/merchant/merchant.priv",
|
||||||
);
|
);
|
||||||
config.setString("merchantdb-postgres", "config", mc.database);
|
config.setString("merchantdb-postgres", "config", mc.database);
|
||||||
config.write(cfgFilename, { excludeDefaults: true });
|
config.write(cfgFilename);
|
||||||
|
|
||||||
return new MerchantService(gc, mc, cfgFilename);
|
return new MerchantService(gc, mc, cfgFilename);
|
||||||
}
|
}
|
||||||
@ -2006,7 +1902,7 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
this.merchantConfig.currency,
|
this.merchantConfig.currency,
|
||||||
);
|
);
|
||||||
config.setString(`merchant-exchange-${e.name}`, "master_key", e.masterPub);
|
config.setString(`merchant-exchange-${e.name}`, "master_key", e.masterPub);
|
||||||
config.write(this.configFilename, { excludeDefaults: true });
|
config.write(this.configFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
async addDefaultInstance(): Promise<void> {
|
async addDefaultInstance(): Promise<void> {
|
||||||
@ -2039,8 +1935,14 @@ export class MerchantService implements MerchantServiceInterface {
|
|||||||
name: instanceConfig.name,
|
name: instanceConfig.name,
|
||||||
address: instanceConfig.address ?? {},
|
address: instanceConfig.address ?? {},
|
||||||
jurisdiction: instanceConfig.jurisdiction ?? {},
|
jurisdiction: instanceConfig.jurisdiction ?? {},
|
||||||
// FIXME: In some tests, we might want to make this configurable
|
default_max_wire_fee:
|
||||||
use_stefan: true,
|
instanceConfig.defaultMaxWireFee ??
|
||||||
|
`${this.merchantConfig.currency}:1.0`,
|
||||||
|
default_wire_fee_amortization:
|
||||||
|
instanceConfig.defaultWireFeeAmortization ?? 3,
|
||||||
|
default_max_deposit_fee:
|
||||||
|
instanceConfig.defaultMaxDepositFee ??
|
||||||
|
`${this.merchantConfig.currency}:1.0`,
|
||||||
default_wire_transfer_delay:
|
default_wire_transfer_delay:
|
||||||
instanceConfig.defaultWireTransferDelay ??
|
instanceConfig.defaultWireTransferDelay ??
|
||||||
Duration.toTalerProtocolDuration(
|
Duration.toTalerProtocolDuration(
|
||||||
@ -2082,6 +1984,9 @@ export interface PartialMerchantInstanceConfig {
|
|||||||
paytoUris: string[];
|
paytoUris: string[];
|
||||||
address?: unknown;
|
address?: unknown;
|
||||||
jurisdiction?: unknown;
|
jurisdiction?: unknown;
|
||||||
|
defaultMaxWireFee?: string;
|
||||||
|
defaultMaxDepositFee?: string;
|
||||||
|
defaultWireFeeAmortization?: number;
|
||||||
defaultWireTransferDelay?: TalerProtocolDuration;
|
defaultWireTransferDelay?: TalerProtocolDuration;
|
||||||
defaultPayDelay?: TalerProtocolDuration;
|
defaultPayDelay?: TalerProtocolDuration;
|
||||||
}
|
}
|
||||||
@ -2124,7 +2029,9 @@ export interface MerchantInstanceConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
address: unknown;
|
address: unknown;
|
||||||
jurisdiction: unknown;
|
jurisdiction: unknown;
|
||||||
use_stefan: boolean;
|
default_max_wire_fee: string;
|
||||||
|
default_max_deposit_fee: string;
|
||||||
|
default_wire_fee_amortization: number;
|
||||||
default_wire_transfer_delay: TalerProtocolDuration;
|
default_wire_transfer_delay: TalerProtocolDuration;
|
||||||
default_pay_delay: TalerProtocolDuration;
|
default_pay_delay: TalerProtocolDuration;
|
||||||
}
|
}
|
||||||
@ -2322,15 +2229,12 @@ export class WalletService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async pingUntilAvailable(): Promise<void> {
|
async pingUntilAvailable(): Promise<void> {
|
||||||
let nextDelay = backoffStart();
|
|
||||||
while (1) {
|
while (1) {
|
||||||
try {
|
try {
|
||||||
await tryUnixConnect(this.socketPath);
|
await tryUnixConnect(this.socketPath);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(`wallet connection attempt failed: ${e}`);
|
logger.info(`connection attempt failed: ${e}`);
|
||||||
logger.info(`waiting on wallet for ${nextDelay}ms`);
|
await delayMs(200);
|
||||||
await delayMs(nextDelay);
|
|
||||||
nextDelay = backoffIncrement(nextDelay);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logger.info("connection to wallet-core succeeded");
|
logger.info("connection to wallet-core succeeded");
|
||||||
|
@ -32,7 +32,6 @@ import {
|
|||||||
NotificationType,
|
NotificationType,
|
||||||
WalletNotification,
|
WalletNotification,
|
||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
Logger,
|
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
@ -50,24 +49,18 @@ import {
|
|||||||
DbInfo,
|
DbInfo,
|
||||||
ExchangeService,
|
ExchangeService,
|
||||||
ExchangeServiceInterface,
|
ExchangeServiceInterface,
|
||||||
FakebankService,
|
|
||||||
getPayto,
|
getPayto,
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
MerchantService,
|
MerchantService,
|
||||||
MerchantServiceInterface,
|
MerchantServiceInterface,
|
||||||
setupDb,
|
setupDb,
|
||||||
setupSharedDb,
|
|
||||||
WalletCli,
|
WalletCli,
|
||||||
WalletClient,
|
WalletClient,
|
||||||
WalletService,
|
WalletService,
|
||||||
WithAuthorization,
|
WithAuthorization,
|
||||||
} from "./harness.js";
|
} from "./harness.js";
|
||||||
|
|
||||||
import * as fs from "fs";
|
|
||||||
|
|
||||||
const logger = new Logger("helpers.ts");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
@ -101,10 +94,6 @@ export interface EnvOptions {
|
|||||||
ageMaskSpec?: string;
|
ageMaskSpec?: string;
|
||||||
|
|
||||||
mixedAgeRestriction?: boolean;
|
mixedAgeRestriction?: boolean;
|
||||||
|
|
||||||
additionalExchangeConfig?(e: ExchangeService): void;
|
|
||||||
additionalMerchantConfig?(m: MerchantService): void;
|
|
||||||
additionalBankConfig?(b: BankService): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -215,179 +204,6 @@ export async function createSimpleTestkudosEnvironment(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function useSharedTestkudosEnvironment(t: GlobalTestState) {
|
|
||||||
const coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS"));
|
|
||||||
|
|
||||||
const sharedDir = `/tmp/taler-harness@${process.env.USER}`;
|
|
||||||
|
|
||||||
fs.mkdirSync(sharedDir, { recursive: true });
|
|
||||||
|
|
||||||
const db = await setupSharedDb(t);
|
|
||||||
|
|
||||||
let bank: FakebankService;
|
|
||||||
|
|
||||||
const prevSetupDone = fs.existsSync(sharedDir + "/setup-done");
|
|
||||||
|
|
||||||
logger.info(`previous setup done: ${prevSetupDone}`);
|
|
||||||
|
|
||||||
|
|
||||||
// Wallet has longer startup-time and no dependencies,
|
|
||||||
// so we start it rather early.
|
|
||||||
const walletStartProm = createWalletDaemonWithClient(t, { name: "wallet" })
|
|
||||||
|
|
||||||
if (fs.existsSync(sharedDir + "/bank.conf")) {
|
|
||||||
logger.info("reusing existing bank");
|
|
||||||
bank = BankService.fromExistingConfig(t, {
|
|
||||||
overridePath: sharedDir,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
logger.info("creating new bank config");
|
|
||||||
bank = await BankService.create(t, {
|
|
||||||
allowRegistrations: true,
|
|
||||||
currency: "TESTKUDOS",
|
|
||||||
database: db.connStr,
|
|
||||||
httpPort: 8082,
|
|
||||||
overrideTestDir: sharedDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("setting up exchange");
|
|
||||||
|
|
||||||
const exchangeName = "testexchange-1";
|
|
||||||
const exchangeConfigFilename = sharedDir + `/exchange-${exchangeName}.conf`;
|
|
||||||
|
|
||||||
logger.info(`exchange config filename: ${exchangeConfigFilename}`);
|
|
||||||
|
|
||||||
let exchange: ExchangeService;
|
|
||||||
|
|
||||||
if (fs.existsSync(exchangeConfigFilename)) {
|
|
||||||
logger.info("reusing existing exchange config");
|
|
||||||
exchange = ExchangeService.fromExistingConfig(t, exchangeName, {
|
|
||||||
overridePath: sharedDir,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
logger.info("creating new exchange config");
|
|
||||||
exchange = ExchangeService.create(t, {
|
|
||||||
name: "testexchange-1",
|
|
||||||
currency: "TESTKUDOS",
|
|
||||||
httpPort: 8081,
|
|
||||||
database: db.connStr,
|
|
||||||
overrideTestDir: sharedDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("setting up merchant");
|
|
||||||
|
|
||||||
let merchant: MerchantService;
|
|
||||||
const merchantName = "testmerchant-1";
|
|
||||||
const merchantConfigFilename = sharedDir + `/merchant-${merchantName}}`;
|
|
||||||
|
|
||||||
if (fs.existsSync(merchantConfigFilename)) {
|
|
||||||
merchant = MerchantService.fromExistingConfig(t, merchantName, {
|
|
||||||
overridePath: sharedDir,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
merchant = await MerchantService.create(t, {
|
|
||||||
name: "testmerchant-1",
|
|
||||||
currency: "TESTKUDOS",
|
|
||||||
httpPort: 8083,
|
|
||||||
database: db.connStr,
|
|
||||||
overrideTestDir: sharedDir,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("creating bank account for exchange");
|
|
||||||
|
|
||||||
const exchangeBankAccount = await bank.createExchangeAccount(
|
|
||||||
"myexchange",
|
|
||||||
"x",
|
|
||||||
);
|
|
||||||
|
|
||||||
logger.info("creating exchange bank account");
|
|
||||||
await exchange.addBankAccount("1", exchangeBankAccount);
|
|
||||||
|
|
||||||
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
|
||||||
|
|
||||||
exchange.addCoinConfigList(coinConfig);
|
|
||||||
|
|
||||||
merchant.addExchange(exchange);
|
|
||||||
|
|
||||||
logger.info("basic setup done, starting services");
|
|
||||||
|
|
||||||
if (!prevSetupDone) {
|
|
||||||
// Must be done sequentially, due to a concurrency
|
|
||||||
// issue in the *-dbinit tools.
|
|
||||||
await exchange.dbinit();
|
|
||||||
await merchant.dbinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
const bankStart = async () => {
|
|
||||||
await bank.start();
|
|
||||||
await bank.pingUntilAvailable();
|
|
||||||
};
|
|
||||||
|
|
||||||
const exchangeStart = async () => {
|
|
||||||
await exchange.start({
|
|
||||||
skipDbinit: true,
|
|
||||||
skipKeyup: prevSetupDone,
|
|
||||||
});
|
|
||||||
await exchange.pingUntilAvailable();
|
|
||||||
};
|
|
||||||
|
|
||||||
const merchStart = async () => {
|
|
||||||
await merchant.start({
|
|
||||||
skipDbinit: true,
|
|
||||||
});
|
|
||||||
await merchant.pingUntilAvailable();
|
|
||||||
|
|
||||||
if (!prevSetupDone) {
|
|
||||||
await merchant.addInstance({
|
|
||||||
id: "default",
|
|
||||||
name: "Default Instance",
|
|
||||||
paytoUris: [getPayto("merchant-default")],
|
|
||||||
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
|
||||||
Duration.fromSpec({ minutes: 1 }),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
await merchant.addInstance({
|
|
||||||
id: "minst1",
|
|
||||||
name: "minst1",
|
|
||||||
paytoUris: [getPayto("minst1")],
|
|
||||||
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
|
||||||
Duration.fromSpec({ minutes: 1 }),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
await bankStart()
|
|
||||||
|
|
||||||
const res = await Promise.all([
|
|
||||||
exchangeStart(),
|
|
||||||
merchStart(),
|
|
||||||
undefined,
|
|
||||||
walletStartProm,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const walletClient = res[3].walletClient;
|
|
||||||
const walletService = res[3].walletService;
|
|
||||||
|
|
||||||
fs.writeFileSync(sharedDir + "/setup-done", "OK");
|
|
||||||
|
|
||||||
logger.info("setup done!");
|
|
||||||
|
|
||||||
return {
|
|
||||||
commonDb: db,
|
|
||||||
exchange,
|
|
||||||
merchant,
|
|
||||||
walletClient,
|
|
||||||
walletService,
|
|
||||||
bank,
|
|
||||||
exchangeBankAccount,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run a test case with a simple TESTKUDOS Taler environment, consisting
|
* Run a test case with a simple TESTKUDOS Taler environment, consisting
|
||||||
* of one exchange, one bank and one merchant.
|
* of one exchange, one bank and one merchant.
|
||||||
@ -430,9 +246,6 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
|
|
||||||
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
||||||
|
|
||||||
if (opts.additionalBankConfig) {
|
|
||||||
opts.additionalBankConfig(bank);
|
|
||||||
}
|
|
||||||
await bank.start();
|
await bank.start();
|
||||||
|
|
||||||
await bank.pingUntilAvailable();
|
await bank.pingUntilAvailable();
|
||||||
@ -459,17 +272,11 @@ export async function createSimpleTestkudosEnvironmentV2(
|
|||||||
exchange.addCoinConfigList(coinConfig);
|
exchange.addCoinConfigList(coinConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.additionalExchangeConfig) {
|
|
||||||
opts.additionalExchangeConfig(exchange);
|
|
||||||
}
|
|
||||||
await exchange.start();
|
await exchange.start();
|
||||||
await exchange.pingUntilAvailable();
|
await exchange.pingUntilAvailable();
|
||||||
|
|
||||||
merchant.addExchange(exchange);
|
merchant.addExchange(exchange);
|
||||||
|
|
||||||
if (opts.additionalMerchantConfig) {
|
|
||||||
opts.additionalMerchantConfig(merchant);
|
|
||||||
}
|
|
||||||
await merchant.start();
|
await merchant.start();
|
||||||
await merchant.pingUntilAvailable();
|
await merchant.pingUntilAvailable();
|
||||||
|
|
||||||
@ -529,7 +336,7 @@ export async function createWalletDaemonWithClient(
|
|||||||
const walletClient = new WalletClient({
|
const walletClient = new WalletClient({
|
||||||
unixPath: walletService.socketPath,
|
unixPath: walletService.socketPath,
|
||||||
onNotification(n) {
|
onNotification(n) {
|
||||||
console.log(`got ${args.name} notification`, n);
|
console.log("got notification", n);
|
||||||
if (args.handleNotification) {
|
if (args.handleNotification) {
|
||||||
args.handleNotification(n);
|
args.handleNotification(n);
|
||||||
}
|
}
|
||||||
@ -803,8 +610,6 @@ export async function applyTimeTravel(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a simple payment and check that it succeeded.
|
* Make a simple payment and check that it succeeded.
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
*/
|
||||||
export async function makeTestPayment(
|
export async function makeTestPayment(
|
||||||
t: GlobalTestState,
|
t: GlobalTestState,
|
||||||
|
@ -170,39 +170,6 @@ const sandcastleCli = testingCli.subcommand("sandcastleArgs", "sandcastle", {
|
|||||||
help: "Subcommands for handling GNU Taler sandcastle deployments.",
|
help: "Subcommands for handling GNU Taler sandcastle deployments.",
|
||||||
});
|
});
|
||||||
|
|
||||||
const configCli = testingCli.subcommand("configArgs", "config", {
|
|
||||||
help: "Subcommands for handling the Taler configuration.",
|
|
||||||
});
|
|
||||||
|
|
||||||
configCli.subcommand("show", "show").action(async (args) => {
|
|
||||||
const config = Configuration.load();
|
|
||||||
const cfgStr = config.stringify({
|
|
||||||
diagnostics: true,
|
|
||||||
});
|
|
||||||
console.log(cfgStr);
|
|
||||||
});
|
|
||||||
|
|
||||||
configCli
|
|
||||||
.subcommand("get", "get")
|
|
||||||
.requiredArgument("section", clk.STRING)
|
|
||||||
.requiredArgument("option", clk.STRING)
|
|
||||||
.flag("file", ["-f"])
|
|
||||||
.action(async (args) => {
|
|
||||||
const config = Configuration.load();
|
|
||||||
let res;
|
|
||||||
if (args.get.file) {
|
|
||||||
res = config.getString(args.get.section, args.get.option);
|
|
||||||
} else {
|
|
||||||
res = config.getPath(args.get.section, args.get.option);
|
|
||||||
}
|
|
||||||
if (res.isDefined()) {
|
|
||||||
console.log(res.value);
|
|
||||||
} else {
|
|
||||||
console.warn("not found");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const deploymentCli = testingCli.subcommand("deploymentArgs", "deployment", {
|
const deploymentCli = testingCli.subcommand("deploymentArgs", "deployment", {
|
||||||
help: "Subcommands for handling GNU Taler deployments.",
|
help: "Subcommands for handling GNU Taler deployments.",
|
||||||
});
|
});
|
||||||
@ -241,10 +208,8 @@ deploymentCli
|
|||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const bankAccessApiClient = new BankAccessApiClient({
|
||||||
baseUrl: args.tipTopup.bankAccessUrl,
|
baseUrl: args.tipTopup.bankAccessUrl,
|
||||||
auth: {
|
|
||||||
username: args.tipTopup.bankAccount,
|
username: args.tipTopup.bankAccount,
|
||||||
password: args.tipTopup.bankPassword,
|
password: args.tipTopup.bankPassword,
|
||||||
},
|
|
||||||
allowHttp: true,
|
allowHttp: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -254,12 +219,10 @@ deploymentCli
|
|||||||
|
|
||||||
console.log("payto URI:", paytoUri);
|
console.log("payto URI:", paytoUri);
|
||||||
|
|
||||||
const transactions = await bankAccessApiClient.getTransactions(
|
const transactions = await bankAccessApiClient.getTransactions();
|
||||||
args.tipTopup.bankAccount,
|
|
||||||
);
|
|
||||||
console.log("transactions:", j2s(transactions));
|
console.log("transactions:", j2s(transactions));
|
||||||
|
|
||||||
await bankAccessApiClient.createTransaction(args.tipTopup.bankAccount, {
|
await bankAccessApiClient.createTransaction({
|
||||||
amount,
|
amount,
|
||||||
paytoUri,
|
paytoUri,
|
||||||
});
|
});
|
||||||
|
@ -17,14 +17,12 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { defaultCoinConfig } from "../harness/denomStructures.js";
|
import { defaultCoinConfig } from "../harness/denomStructures.js";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState, WalletCli } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
createWalletDaemonWithClient,
|
withdrawViaBank,
|
||||||
makeTestPaymentV2,
|
makeTestPayment,
|
||||||
withdrawViaBankV2,
|
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,11 +32,11 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) {
|
|||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const {
|
const {
|
||||||
walletClient: walletOne,
|
wallet: walletOne,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
merchant,
|
merchant,
|
||||||
} = await createSimpleTestkudosEnvironmentV2(
|
} = await createSimpleTestkudosEnvironment(
|
||||||
t,
|
t,
|
||||||
defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
||||||
{
|
{
|
||||||
@ -47,27 +45,20 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { walletClient: walletTwo } = await createWalletDaemonWithClient(t, {
|
const walletTwo = new WalletCli(t, "walletTwo");
|
||||||
name: "w2",
|
const walletThree = new WalletCli(t, "walletThree");
|
||||||
});
|
|
||||||
|
|
||||||
const { walletClient: walletThree } = await createWalletDaemonWithClient(t, {
|
|
||||||
name: "w3",
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const walletClient = walletOne;
|
const wallet = walletOne;
|
||||||
|
|
||||||
const wres = await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, {
|
||||||
walletClient,
|
wallet,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
amount: "TESTKUDOS:20",
|
amount: "TESTKUDOS:20",
|
||||||
restrictAge: 13,
|
restrictAge: 13,
|
||||||
});
|
});
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
const order = {
|
const order = {
|
||||||
summary: "Buy me!",
|
summary: "Buy me!",
|
||||||
amount: "TESTKUDOS:5",
|
amount: "TESTKUDOS:5",
|
||||||
@ -75,46 +66,41 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) {
|
|||||||
minimum_age: 9,
|
minimum_age: 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
await walletClient.call(
|
await wallet.runUntilDone();
|
||||||
WalletApiOperation.TestingWaitTransactionsFinal,
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const wres = await withdrawViaBankV2(t, {
|
const wallet = walletTwo;
|
||||||
walletClient: walletTwo,
|
|
||||||
|
await withdrawViaBank(t, {
|
||||||
|
wallet,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
amount: "TESTKUDOS:20",
|
amount: "TESTKUDOS:20",
|
||||||
restrictAge: 13,
|
restrictAge: 13,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
const order = {
|
const order = {
|
||||||
summary: "Buy me!",
|
summary: "Buy me!",
|
||||||
amount: "TESTKUDOS:5",
|
amount: "TESTKUDOS:5",
|
||||||
fulfillment_url: "taler://fulfillment-success/thx",
|
fulfillment_url: "taler://fulfillment-success/thx",
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient: walletTwo, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
await walletTwo.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const wres = await withdrawViaBankV2(t, {
|
const wallet = walletThree;
|
||||||
walletClient: walletThree,
|
|
||||||
|
await withdrawViaBank(t, {
|
||||||
|
wallet,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
amount: "TESTKUDOS:20",
|
amount: "TESTKUDOS:20",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
const order = {
|
const order = {
|
||||||
summary: "Buy me!",
|
summary: "Buy me!",
|
||||||
amount: "TESTKUDOS:5",
|
amount: "TESTKUDOS:5",
|
||||||
@ -122,8 +108,8 @@ export async function runAgeRestrictionsMixedMerchantTest(t: GlobalTestState) {
|
|||||||
minimum_age: 9,
|
minimum_age: 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient: walletThree, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
await walletThree.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,22 +17,23 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util";
|
|
||||||
import {
|
import {
|
||||||
BankAccessApi,
|
GlobalTestState,
|
||||||
|
WalletCli,
|
||||||
|
ExchangeService,
|
||||||
|
setupDb,
|
||||||
|
BankService,
|
||||||
|
MerchantService,
|
||||||
|
getPayto,
|
||||||
|
} from "../harness/harness.js";
|
||||||
|
import { createEddsaKeyPair, encodeCrock } from "@gnu-taler/taler-util";
|
||||||
|
import { defaultCoinConfig } from "../harness/denomStructures.js";
|
||||||
|
import {
|
||||||
BankApi,
|
BankApi,
|
||||||
|
BankAccessApi,
|
||||||
CreditDebitIndicator,
|
CreditDebitIndicator,
|
||||||
WireGatewayApiClient,
|
WireGatewayApiClient,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { defaultCoinConfig } from "../harness/denomStructures.js";
|
|
||||||
import {
|
|
||||||
BankService,
|
|
||||||
ExchangeService,
|
|
||||||
GlobalTestState,
|
|
||||||
MerchantService,
|
|
||||||
getPayto,
|
|
||||||
setupDb,
|
|
||||||
} from "../harness/harness.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { URL } from "url";
|
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import { URL } from "url";
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for the merchant's order lifecycle.
|
* Run test for the merchant's order lifecycle.
|
||||||
@ -34,15 +34,10 @@ import {
|
|||||||
export async function runClaimLoopTest(t: GlobalTestState) {
|
export async function runClaimLoopTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up order.
|
// Set up order.
|
||||||
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
|
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
|
||||||
@ -66,7 +61,7 @@ export async function runClaimLoopTest(t: GlobalTestState) {
|
|||||||
// Make wallet claim the unpaid order.
|
// Make wallet claim the unpaid order.
|
||||||
t.assertTrue(orderStatusBefore.order_status === "unpaid");
|
t.assertTrue(orderStatusBefore.order_status === "unpaid");
|
||||||
const talerPayUri = orderStatusBefore.taler_pay_uri;
|
const talerPayUri = orderStatusBefore.taler_pay_uri;
|
||||||
await walletClient.call(WalletApiOperation.PreparePayForUri, {
|
await wallet.client.call(WalletApiOperation.PreparePayForUri, {
|
||||||
talerPayUri,
|
talerPayUri,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -18,29 +18,22 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { PreparePayResultType, TalerErrorCode } from "@gnu-taler/taler-util";
|
import { PreparePayResultType, TalerErrorCode } from "@gnu-taler/taler-util";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { Wallet, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
|
||||||
export async function runDenomUnofferedTest(t: GlobalTestState) {
|
export async function runDenomUnofferedTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
const wres = await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
// Make the exchange forget the denomination.
|
// Make the exchange forget the denomination.
|
||||||
// Effectively we completely reset the exchange,
|
// Effectively we completely reset the exchange,
|
||||||
@ -74,7 +67,7 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const preparePayResult = await walletClient.call(
|
const preparePayResult = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
@ -85,11 +78,11 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
|
|||||||
preparePayResult.status === PreparePayResultType.PaymentPossible,
|
preparePayResult.status === PreparePayResultType.PaymentPossible,
|
||||||
);
|
);
|
||||||
|
|
||||||
const confirmResp = await walletClient.call(WalletApiOperation.ConfirmPay, {
|
const confirmResp = await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||||
proposalId: preparePayResult.proposalId,
|
proposalId: preparePayResult.proposalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const tx = await walletClient.call(WalletApiOperation.GetTransactionById, {
|
const tx = await wallet.client.call(WalletApiOperation.GetTransactionById, {
|
||||||
transactionId: confirmResp.transactionId,
|
transactionId: confirmResp.transactionId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -103,26 +96,21 @@ export async function runDenomUnofferedTest(t: GlobalTestState) {
|
|||||||
TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND,
|
TalerErrorCode.MERCHANT_POST_ORDERS_ID_PAY_DENOMINATION_KEY_NOT_FOUND,
|
||||||
);
|
);
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddExchange, {
|
await wallet.client.call(WalletApiOperation.AddExchange, {
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
forceUpdate: true,
|
forceUpdate: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.DeleteTransaction, {
|
await wallet.client.call(WalletApiOperation.DeleteTransaction, {
|
||||||
transactionId: confirmResp.transactionId,
|
transactionId: confirmResp.transactionId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Now withdrawal should work again.
|
// Now withdrawal should work again.
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {});
|
const txs = await wallet.client.call(WalletApiOperation.GetTransactions, {});
|
||||||
console.log(JSON.stringify(txs, undefined, 2));
|
console.log(JSON.stringify(txs, undefined, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,15 +30,14 @@ import {
|
|||||||
depositCoin,
|
depositCoin,
|
||||||
downloadExchangeInfo,
|
downloadExchangeInfo,
|
||||||
findDenomOrThrow,
|
findDenomOrThrow,
|
||||||
|
refreshCoin,
|
||||||
SynchronousCryptoWorkerFactoryPlain,
|
SynchronousCryptoWorkerFactoryPlain,
|
||||||
topupReserveWithDemobank,
|
topupReserveWithDemobank,
|
||||||
Wallet,
|
Wallet,
|
||||||
withdrawCoin,
|
withdrawCoin,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import {
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
createSimpleTestkudosEnvironmentV2,
|
|
||||||
} from "../harness/helpers.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal and payment.
|
* Run test for basic, bank-integrated withdrawal and payment.
|
||||||
@ -46,7 +45,7 @@ import {
|
|||||||
export async function runExchangeDepositTest(t: GlobalTestState) {
|
export async function runExchangeDepositTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(t);
|
const { bank, exchange } = await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const http = createPlatformHttpLib({
|
const http = createPlatformHttpLib({
|
||||||
allowHttp: true,
|
allowHttp: true,
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
import {
|
||||||
|
GlobalTestState,
|
||||||
BankService,
|
BankService,
|
||||||
ExchangeService,
|
ExchangeService,
|
||||||
GlobalTestState,
|
|
||||||
MerchantService,
|
MerchantService,
|
||||||
getPayto,
|
|
||||||
setupDb,
|
setupDb,
|
||||||
|
WalletCli,
|
||||||
|
getPayto,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
SimpleTestEnvironmentNg,
|
withdrawViaBank,
|
||||||
createWalletDaemonWithClient,
|
makeTestPayment,
|
||||||
makeTestPaymentV2,
|
SimpleTestEnvironment,
|
||||||
withdrawViaBankV2,
|
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +39,7 @@ import {
|
|||||||
*/
|
*/
|
||||||
export async function createMyTestkudosEnvironment(
|
export async function createMyTestkudosEnvironment(
|
||||||
t: GlobalTestState,
|
t: GlobalTestState,
|
||||||
): Promise<SimpleTestEnvironmentNg> {
|
): Promise<SimpleTestEnvironment> {
|
||||||
const db = await setupDb(t);
|
const db = await setupDb(t);
|
||||||
|
|
||||||
const bank = await BankService.create(t, {
|
const bank = await BankService.create(t, {
|
||||||
@ -147,19 +147,13 @@ export async function createMyTestkudosEnvironment(
|
|||||||
|
|
||||||
console.log("setup done!");
|
console.log("setup done!");
|
||||||
|
|
||||||
const { walletClient, walletService } = await createWalletDaemonWithClient(
|
const wallet = new WalletCli(t);
|
||||||
t,
|
|
||||||
{
|
|
||||||
name: "w1",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
commonDb: db,
|
commonDb: db,
|
||||||
exchange,
|
exchange,
|
||||||
merchant,
|
merchant,
|
||||||
walletClient,
|
wallet,
|
||||||
walletService,
|
|
||||||
bank,
|
bank,
|
||||||
exchangeBankAccount,
|
exchangeBankAccount,
|
||||||
};
|
};
|
||||||
@ -171,21 +165,19 @@ export async function createMyTestkudosEnvironment(
|
|||||||
export async function runFeeRegressionTest(t: GlobalTestState) {
|
export async function runFeeRegressionTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createMyTestkudosEnvironment(t);
|
await createMyTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
const wres = await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, {
|
||||||
walletClient,
|
wallet,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
amount: "TESTKUDOS:1.92",
|
amount: "TESTKUDOS:1.92",
|
||||||
});
|
});
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
const coins = await wallet.client.call(WalletApiOperation.DumpCoins, {});
|
||||||
|
|
||||||
const coins = await walletClient.call(WalletApiOperation.DumpCoins, {});
|
|
||||||
|
|
||||||
// Make sure we really withdraw one 0.64 and one 1.28 coin.
|
// Make sure we really withdraw one 0.64 and one 1.28 coin.
|
||||||
t.assertTrue(coins.coins.length === 2);
|
t.assertTrue(coins.coins.length === 2);
|
||||||
@ -196,11 +188,11 @@ export async function runFeeRegressionTest(t: GlobalTestState) {
|
|||||||
fulfillment_url: "taler://fulfillment-success/thx",
|
fulfillment_url: "taler://fulfillment-success/thx",
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {});
|
const txs = await wallet.client.call(WalletApiOperation.GetTransactions, {});
|
||||||
t.assertAmountEquals(txs.transactions[1].amountEffective, "TESTKUDOS:1.30");
|
t.assertAmountEquals(txs.transactions[1].amountEffective, "TESTKUDOS:1.30");
|
||||||
console.log(txs);
|
console.log(txs);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
import { j2s } from "@gnu-taler/taler-util";
|
import { j2s } from "@gnu-taler/taler-util";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for forced denom/coin selection.
|
* Run test for forced denom/coin selection.
|
||||||
@ -28,14 +28,14 @@ import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
|||||||
export async function runForcedSelectionTest(t: GlobalTestState) {
|
export async function runForcedSelectionTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddExchange, {
|
await wallet.client.call(WalletApiOperation.AddExchange, {
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.WithdrawTestBalance, {
|
await wallet.client.call(WalletApiOperation.WithdrawTestBalance, {
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
amount: "TESTKUDOS:10",
|
amount: "TESTKUDOS:10",
|
||||||
bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl,
|
bankAccessApiBaseUrl: bank.bankAccessApiBaseUrl,
|
||||||
@ -49,13 +49,13 @@ export async function runForcedSelectionTest(t: GlobalTestState) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const coinDump = await walletClient.call(WalletApiOperation.DumpCoins, {});
|
const coinDump = await wallet.client.call(WalletApiOperation.DumpCoins, {});
|
||||||
console.log(coinDump);
|
console.log(coinDump);
|
||||||
t.assertDeepEqual(coinDump.coins.length, 3);
|
t.assertDeepEqual(coinDump.coins.length, 3);
|
||||||
|
|
||||||
const payResp = await walletClient.call(WalletApiOperation.TestPay, {
|
const payResp = await wallet.client.call(WalletApiOperation.TestPay, {
|
||||||
amount: "TESTKUDOS:3",
|
amount: "TESTKUDOS:3",
|
||||||
merchantBaseUrl: merchant.makeInstanceBaseUrl(),
|
merchantBaseUrl: merchant.makeInstanceBaseUrl(),
|
||||||
summary: "bla",
|
summary: "bla",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
|
NexusUserBundle,
|
||||||
LibeufinNexusApi,
|
LibeufinNexusApi,
|
||||||
LibeufinNexusService,
|
LibeufinNexusService,
|
||||||
LibeufinSandboxService,
|
LibeufinSandboxService,
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
NexusUserBundle,
|
NexusUserBundle,
|
||||||
launchLibeufinServices,
|
launchLibeufinServices,
|
||||||
LibeufinNexusApi,
|
LibeufinNexusApi,
|
||||||
|
LibeufinCli,
|
||||||
} from "../harness/libeufin.js";
|
} from "../harness/libeufin.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,10 +67,12 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
|
|||||||
await clientForDefault.createInstance({
|
await clientForDefault.createInstance({
|
||||||
id: "default",
|
id: "default",
|
||||||
address: {},
|
address: {},
|
||||||
use_stefan: true,
|
default_max_deposit_fee: "TESTKUDOS:1",
|
||||||
|
default_max_wire_fee: "TESTKUDOS:1",
|
||||||
default_pay_delay: Duration.toTalerProtocolDuration(
|
default_pay_delay: Duration.toTalerProtocolDuration(
|
||||||
Duration.fromSpec({ seconds: 60 }),
|
Duration.fromSpec({ seconds: 60 }),
|
||||||
),
|
),
|
||||||
|
default_wire_fee_amortization: 1,
|
||||||
default_wire_transfer_delay: Duration.toTalerProtocolDuration(
|
default_wire_transfer_delay: Duration.toTalerProtocolDuration(
|
||||||
Duration.fromSpec({ seconds: 60 }),
|
Duration.fromSpec({ seconds: 60 }),
|
||||||
),
|
),
|
||||||
@ -90,10 +92,12 @@ export async function runMerchantInstancesUrlsTest(t: GlobalTestState) {
|
|||||||
await clientForDefault.createInstance({
|
await clientForDefault.createInstance({
|
||||||
id: "myinst",
|
id: "myinst",
|
||||||
address: {},
|
address: {},
|
||||||
|
default_max_deposit_fee: "TESTKUDOS:1",
|
||||||
|
default_max_wire_fee: "TESTKUDOS:1",
|
||||||
default_pay_delay: Duration.toTalerProtocolDuration(
|
default_pay_delay: Duration.toTalerProtocolDuration(
|
||||||
Duration.fromSpec({ seconds: 60 }),
|
Duration.fromSpec({ seconds: 60 }),
|
||||||
),
|
),
|
||||||
use_stefan: true,
|
default_wire_fee_amortization: 1,
|
||||||
default_wire_transfer_delay: Duration.toTalerProtocolDuration(
|
default_wire_transfer_delay: Duration.toTalerProtocolDuration(
|
||||||
Duration.fromSpec({ seconds: 60 }),
|
Duration.fromSpec({ seconds: 60 }),
|
||||||
),
|
),
|
||||||
|
@ -17,20 +17,20 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
|
||||||
ConfirmPayResultType,
|
|
||||||
PreparePayResultType,
|
|
||||||
URL,
|
|
||||||
codecForMerchantOrderStatusUnpaid,
|
|
||||||
} from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import axiosImp from "axios";
|
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import {
|
||||||
|
PreparePayResultType,
|
||||||
|
codecForMerchantOrderStatusUnpaid,
|
||||||
|
ConfirmPayResultType,
|
||||||
|
URL,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
import axiosImp from "axios";
|
||||||
const axios = axiosImp.default;
|
const axios = axiosImp.default;
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -38,19 +38,12 @@ const axios = axiosImp.default;
|
|||||||
export async function runMerchantLongpollingTest(t: GlobalTestState) {
|
export async function runMerchantLongpollingTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
const wres = await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
@ -120,7 +113,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
|
|||||||
* =========================================================================
|
* =========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let preparePayResp = await walletClient.call(
|
let preparePayResp = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: pubUnpaidStatus.taler_pay_uri,
|
talerPayUri: pubUnpaidStatus.taler_pay_uri,
|
||||||
@ -155,7 +148,7 @@ export async function runMerchantLongpollingTest(t: GlobalTestState) {
|
|||||||
publicOrderStatusResp.data,
|
publicOrderStatusResp.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
const confirmPayRes = await walletClient.call(
|
const confirmPayRes = await wallet.client.call(
|
||||||
WalletApiOperation.ConfirmPay,
|
WalletApiOperation.ConfirmPay,
|
||||||
{
|
{
|
||||||
proposalId: proposalId,
|
proposalId: proposalId,
|
||||||
|
@ -24,6 +24,7 @@ import {
|
|||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
import {
|
import {
|
||||||
FaultInjectionRequestContext,
|
FaultInjectionRequestContext,
|
||||||
|
FaultInjectionResponseContext,
|
||||||
} from "../harness/faultInjection.js";
|
} from "../harness/faultInjection.js";
|
||||||
import {
|
import {
|
||||||
codecForMerchantOrderStatusUnpaid,
|
codecForMerchantOrderStatusUnpaid,
|
||||||
|
@ -17,17 +17,18 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { PreparePayResultType, TalerErrorCode } from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import {
|
import {
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import { PreparePayResultType } from "@gnu-taler/taler-util";
|
||||||
|
import { TalerErrorCode } from "@gnu-taler/taler-util";
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -35,19 +36,14 @@ import {
|
|||||||
export async function runPaymentClaimTest(t: GlobalTestState) {
|
export async function runPaymentClaimTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const walletTwo = new WalletCli(t, "two");
|
const walletTwo = new WalletCli(t, "two");
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up order.
|
// Set up order.
|
||||||
|
|
||||||
@ -69,7 +65,7 @@ export async function runPaymentClaimTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const preparePayResult = await walletClient.call(
|
const preparePayResult = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri,
|
talerPayUri,
|
||||||
@ -86,7 +82,7 @@ export async function runPaymentClaimTest(t: GlobalTestState) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.ConfirmPay, {
|
await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||||
proposalId: preparePayResult.proposalId,
|
proposalId: preparePayResult.proposalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,12 +17,11 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
makeTestPaymentV2,
|
withdrawViaBank,
|
||||||
withdrawViaBankV2,
|
makeTestPayment,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,19 +30,12 @@ import {
|
|||||||
export async function runPaymentForgettableTest(t: GlobalTestState) {
|
export async function runPaymentForgettableTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
const wres = await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
await wres.withdrawalFinishedCond;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const order = {
|
const order = {
|
||||||
@ -58,7 +50,7 @@ export async function runPaymentForgettableTest(t: GlobalTestState) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("testing with forgettable field without hash");
|
console.log("testing with forgettable field without hash");
|
||||||
@ -76,10 +68,10 @@ export async function runPaymentForgettableTest(t: GlobalTestState) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
await makeTestPaymentV2(t, { walletClient, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
}
|
}
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
runPaymentForgettableTest.suites = ["wallet", "merchant"];
|
runPaymentForgettableTest.suites = ["wallet", "merchant"];
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { PreparePayResultType } from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import { PreparePayResultType } from "@gnu-taler/taler-util";
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the wallet-core payment API, especially that repeated operations
|
* Test the wallet-core payment API, especially that repeated operations
|
||||||
@ -32,17 +32,12 @@ import {
|
|||||||
export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up order.
|
// Set up order.
|
||||||
|
|
||||||
@ -64,14 +59,14 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const preparePayResult = await walletClient.call(
|
const preparePayResult = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const preparePayResultRep = await walletClient.call(
|
const preparePayResultRep = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
@ -87,7 +82,7 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
const proposalId = preparePayResult.proposalId;
|
const proposalId = preparePayResult.proposalId;
|
||||||
|
|
||||||
const confirmPayResult = await walletClient.call(
|
const confirmPayResult = await wallet.client.call(
|
||||||
WalletApiOperation.ConfirmPay,
|
WalletApiOperation.ConfirmPay,
|
||||||
{
|
{
|
||||||
proposalId: proposalId,
|
proposalId: proposalId,
|
||||||
@ -96,7 +91,7 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
console.log("confirm pay result", confirmPayResult);
|
console.log("confirm pay result", confirmPayResult);
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
// Check if payment was successful.
|
// Check if payment was successful.
|
||||||
|
|
||||||
@ -106,7 +101,7 @@ export async function runPaymentIdempotencyTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
t.assertTrue(orderStatus.order_status === "paid");
|
t.assertTrue(orderStatus.order_status === "paid");
|
||||||
|
|
||||||
const preparePayResultAfter = await walletClient.call(
|
const preparePayResultAfter = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri,
|
talerPayUri,
|
||||||
|
@ -17,17 +17,21 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
|
||||||
ConfirmPayResultType,
|
|
||||||
PreparePayResultType,
|
|
||||||
} from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironmentV2,
|
||||||
createWalletDaemonWithClient,
|
|
||||||
withdrawViaBankV2,
|
withdrawViaBankV2,
|
||||||
|
makeTestPaymentV2,
|
||||||
|
createWalletDaemonWithClient,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import {
|
||||||
|
ConfirmPayResultType,
|
||||||
|
PreparePayResultType,
|
||||||
|
j2s,
|
||||||
|
parsePayUri,
|
||||||
|
stringifyPayUri,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal and payment.
|
* Run test for basic, bank-integrated withdrawal and payment.
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { ConfirmPayResultType, Duration, PreparePayResultType } from "@gnu-taler/taler-util";
|
import { ConfirmPayResultType, Duration, PreparePayResultType, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2
|
withdrawViaBank,
|
||||||
|
makeTestPayment,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,8 +32,8 @@ import {
|
|||||||
export async function runPaymentTemplateTest(t: GlobalTestState) {
|
export async function runPaymentTemplateTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
await MerchantPrivateApi.createTemplate(merchant, "default", {
|
await MerchantPrivateApi.createTemplate(merchant, "default", {
|
||||||
template_id: "template1",
|
template_id: "template1",
|
||||||
@ -50,11 +51,11 @@ export async function runPaymentTemplateTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:20" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
|
|
||||||
// Request a template payment
|
// Request a template payment
|
||||||
|
|
||||||
const preparePayResult = await walletClient.call(
|
const preparePayResult = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForTemplate,
|
WalletApiOperation.PreparePayForTemplate,
|
||||||
{
|
{
|
||||||
talerPayTemplateUri: `taler+http://pay-template/localhost:${merchant.port}/template1?amount=TESTKUDOS:1`,
|
talerPayTemplateUri: `taler+http://pay-template/localhost:${merchant.port}/template1?amount=TESTKUDOS:1`,
|
||||||
@ -70,7 +71,7 @@ export async function runPaymentTemplateTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Pay for it
|
// Pay for it
|
||||||
|
|
||||||
const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, {
|
const r2 = await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||||
proposalId: preparePayResult.proposalId,
|
proposalId: preparePayResult.proposalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +88,8 @@ export async function runPaymentTemplateTest(t: GlobalTestState) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
t.assertTrue(orderStatus.order_status === "paid");
|
t.assertTrue(orderStatus.order_status === "paid");
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
|
||||||
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
runPaymentTemplateTest.suites = ["wallet"];
|
runPaymentTemplateTest.suites = ["wallet"];
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
makeTestPaymentV2,
|
makeTestPayment,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
import { TransactionMajorState } from "@gnu-taler/taler-util";
|
import { TransactionMajorState } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
@ -33,19 +33,19 @@ import { TransactionMajorState } from "@gnu-taler/taler-util";
|
|||||||
export async function runPaymentZeroTest(t: GlobalTestState) {
|
export async function runPaymentZeroTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// First, make a "free" payment when we don't even have
|
// First, make a "free" payment when we don't even have
|
||||||
// any money in the
|
// any money in the
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:20" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
await makeTestPaymentV2(t, {
|
await makeTestPayment(t, {
|
||||||
walletClient,
|
wallet,
|
||||||
merchant,
|
merchant,
|
||||||
order: {
|
order: {
|
||||||
summary: "I am free!",
|
summary: "I am free!",
|
||||||
@ -54,9 +54,9 @@ export async function runPaymentZeroTest(t: GlobalTestState) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const transactions = await walletClient.call(
|
const transactions = await wallet.client.call(
|
||||||
WalletApiOperation.GetTransactions,
|
WalletApiOperation.GetTransactions,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
@ -18,23 +18,19 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
|
import {
|
||||||
|
createSimpleTestkudosEnvironment,
|
||||||
|
withdrawViaBank,
|
||||||
|
} from "../harness/helpers.js";
|
||||||
import {
|
import {
|
||||||
PreparePayResultType,
|
PreparePayResultType,
|
||||||
codecForMerchantOrderStatusUnpaid,
|
codecForMerchantOrderStatusUnpaid,
|
||||||
ConfirmPayResultType,
|
ConfirmPayResultType,
|
||||||
URL,
|
URL,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
|
import axiosImp from "axios";
|
||||||
|
const axios = axiosImp.default;
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
|
||||||
createSimpleTestkudosEnvironmentV2,
|
|
||||||
withdrawViaBankV2,
|
|
||||||
} from "../harness/helpers.js";
|
|
||||||
import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";
|
|
||||||
|
|
||||||
const httpLib = createPlatformHttpLib({
|
|
||||||
allowHttp: true,
|
|
||||||
enableThrottling: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -42,17 +38,12 @@ const httpLib = createPlatformHttpLib({
|
|||||||
export async function runPaywallFlowTest(t: GlobalTestState) {
|
export async function runPaywallFlowTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* =========================================================================
|
* =========================================================================
|
||||||
@ -86,7 +77,9 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
t.assertTrue(orderStatus.already_paid_order_id === undefined);
|
t.assertTrue(orderStatus.already_paid_order_id === undefined);
|
||||||
let publicOrderStatusUrl = new URL(orderStatus.order_status_url);
|
let publicOrderStatusUrl = new URL(orderStatus.order_status_url);
|
||||||
|
|
||||||
let publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href);
|
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
|
||||||
|
validateStatus: () => true,
|
||||||
|
});
|
||||||
|
|
||||||
if (publicOrderStatusResp.status != 402) {
|
if (publicOrderStatusResp.status != 402) {
|
||||||
throw Error(
|
throw Error(
|
||||||
@ -95,12 +88,12 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
let pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
||||||
publicOrderStatusResp.json(),
|
publicOrderStatusResp.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(pubUnpaidStatus);
|
console.log(pubUnpaidStatus);
|
||||||
|
|
||||||
let preparePayResp = await walletClient.call(
|
let preparePayResp = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: pubUnpaidStatus.taler_pay_uri,
|
talerPayUri: pubUnpaidStatus.taler_pay_uri,
|
||||||
@ -112,8 +105,10 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
const proposalId = preparePayResp.proposalId;
|
const proposalId = preparePayResp.proposalId;
|
||||||
|
|
||||||
console.log("requesting", publicOrderStatusUrl.href);
|
console.log("requesting", publicOrderStatusUrl.href);
|
||||||
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href);
|
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
|
||||||
console.log("response body", publicOrderStatusResp.json());
|
validateStatus: () => true,
|
||||||
|
});
|
||||||
|
console.log("response body", publicOrderStatusResp.data);
|
||||||
if (publicOrderStatusResp.status != 402) {
|
if (publicOrderStatusResp.status != 402) {
|
||||||
throw Error(
|
throw Error(
|
||||||
`expected status 402 (after claiming), but got ${publicOrderStatusResp.status}`,
|
`expected status 402 (after claiming), but got ${publicOrderStatusResp.status}`,
|
||||||
@ -121,20 +116,26 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
||||||
publicOrderStatusResp.json(),
|
publicOrderStatusResp.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
const confirmPayRes = await walletClient.call(WalletApiOperation.ConfirmPay, {
|
const confirmPayRes = await wallet.client.call(
|
||||||
|
WalletApiOperation.ConfirmPay,
|
||||||
|
{
|
||||||
proposalId: proposalId,
|
proposalId: proposalId,
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
|
t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
|
||||||
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href);
|
|
||||||
|
|
||||||
console.log(publicOrderStatusResp.json());
|
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
|
||||||
|
validateStatus: () => true,
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(publicOrderStatusResp.data);
|
||||||
|
|
||||||
if (publicOrderStatusResp.status != 200) {
|
if (publicOrderStatusResp.status != 200) {
|
||||||
console.log(publicOrderStatusResp.json());
|
console.log(publicOrderStatusResp.data);
|
||||||
throw Error(
|
throw Error(
|
||||||
`expected status 200 (after paying), but got ${publicOrderStatusResp.status}`,
|
`expected status 200 (after paying), but got ${publicOrderStatusResp.status}`,
|
||||||
);
|
);
|
||||||
@ -157,7 +158,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
// Pay with new taler://pay URI, which should
|
// Pay with new taler://pay URI, which should
|
||||||
// have the new session ID!
|
// have the new session ID!
|
||||||
// Wallet should now automatically re-play payment.
|
// Wallet should now automatically re-play payment.
|
||||||
preparePayResp = await walletClient.call(
|
preparePayResp = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: talerPayUriOne,
|
talerPayUri: talerPayUriOne,
|
||||||
@ -198,7 +199,7 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
// Here the re-purchase detection should kick in,
|
// Here the re-purchase detection should kick in,
|
||||||
// and the wallet should re-pay for the old order
|
// and the wallet should re-pay for the old order
|
||||||
// under the new session ID (mysession-three).
|
// under the new session ID (mysession-three).
|
||||||
preparePayResp = await walletClient.call(
|
preparePayResp = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
@ -231,17 +232,19 @@ export async function runPaywallFlowTest(t: GlobalTestState) {
|
|||||||
console.log("requesting public status", publicOrderStatusUrl);
|
console.log("requesting public status", publicOrderStatusUrl);
|
||||||
|
|
||||||
// Ask the order status of the claimed-but-unpaid order
|
// Ask the order status of the claimed-but-unpaid order
|
||||||
publicOrderStatusResp = await httpLib.fetch(publicOrderStatusUrl.href);
|
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
|
||||||
|
validateStatus: () => true,
|
||||||
|
});
|
||||||
|
|
||||||
if (publicOrderStatusResp.status != 402) {
|
if (publicOrderStatusResp.status != 402) {
|
||||||
throw Error(`expected status 402, but got ${publicOrderStatusResp.status}`);
|
throw Error(`expected status 402, but got ${publicOrderStatusResp.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
pubUnpaidStatus = codecForMerchantOrderStatusUnpaid().decode(
|
||||||
publicOrderStatusResp.json(),
|
publicOrderStatusResp.data,
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(publicOrderStatusResp.json());
|
console.log(publicOrderStatusResp.data);
|
||||||
|
|
||||||
t.assertTrue(pubUnpaidStatus.already_paid_order_id === firstOrderId);
|
t.assertTrue(pubUnpaidStatus.already_paid_order_id === firstOrderId);
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,13 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { Duration, durationFromSpec } from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
import { GlobalTestState, MerchantPrivateApi } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import { Duration, durationFromSpec } from "@gnu-taler/taler-util";
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -31,17 +31,12 @@ import {
|
|||||||
export async function runRefundAutoTest(t: GlobalTestState) {
|
export async function runRefundAutoTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up order.
|
// Set up order.
|
||||||
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
|
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
|
||||||
@ -66,12 +61,13 @@ export async function runRefundAutoTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const r1 = await walletClient.call(WalletApiOperation.PreparePayForUri, {
|
const r1 = await wallet.client.call(WalletApiOperation.PreparePayForUri, {
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.ConfirmPay, {
|
await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||||
transactionId: r1.transactionId,
|
// FIXME: should be validated, don't cast!
|
||||||
|
proposalId: r1.proposalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if payment was successful.
|
// Check if payment was successful.
|
||||||
@ -92,9 +88,9 @@ export async function runRefundAutoTest(t: GlobalTestState) {
|
|||||||
console.log(ref);
|
console.log(ref);
|
||||||
|
|
||||||
// The wallet should now automatically pick up the refund.
|
// The wallet should now automatically pick up the refund.
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const transactions = await walletClient.call(
|
const transactions = await wallet.client.call(
|
||||||
WalletApiOperation.GetTransactions,
|
WalletApiOperation.GetTransactions,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
@ -17,22 +17,22 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
|
||||||
Amounts,
|
|
||||||
Duration,
|
|
||||||
TransactionType,
|
|
||||||
durationFromSpec,
|
|
||||||
} from "@gnu-taler/taler-util";
|
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import {
|
import {
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
MerchantPrivateApi,
|
|
||||||
delayMs,
|
delayMs,
|
||||||
|
MerchantPrivateApi,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
withdrawViaBankV2,
|
withdrawViaBank,
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import {
|
||||||
|
TransactionType,
|
||||||
|
Amounts,
|
||||||
|
durationFromSpec,
|
||||||
|
Duration,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal.
|
* Run test for basic, bank-integrated withdrawal.
|
||||||
@ -40,17 +40,12 @@ import {
|
|||||||
export async function runRefundIncrementalTest(t: GlobalTestState) {
|
export async function runRefundIncrementalTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { wallet, bank, exchange, merchant } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set up order.
|
// Set up order.
|
||||||
|
|
||||||
@ -73,11 +68,11 @@ export async function runRefundIncrementalTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const r1 = await walletClient.call(WalletApiOperation.PreparePayForUri, {
|
const r1 = await wallet.client.call(WalletApiOperation.PreparePayForUri, {
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.ConfirmPay, {
|
await wallet.client.call(WalletApiOperation.ConfirmPay, {
|
||||||
proposalId: r1.proposalId,
|
proposalId: r1.proposalId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -99,15 +94,15 @@ export async function runRefundIncrementalTest(t: GlobalTestState) {
|
|||||||
console.log("first refund increase response", ref);
|
console.log("first refund increase response", ref);
|
||||||
|
|
||||||
{
|
{
|
||||||
let wr = await walletClient.call(WalletApiOperation.StartRefundQuery, {
|
let wr = await wallet.client.call(WalletApiOperation.StartRefundQuery, {
|
||||||
transactionId: r1.transactionId,
|
transactionId: r1.transactionId,
|
||||||
});
|
});
|
||||||
await walletClient.call(
|
await wallet.runUntilDone();
|
||||||
WalletApiOperation.TestingWaitTransactionsFinal,
|
console.log(wr);
|
||||||
|
const txs = await wallet.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
console.log(wr);
|
|
||||||
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {});
|
|
||||||
console.log(
|
console.log(
|
||||||
"transactions after applying first refund:",
|
"transactions after applying first refund:",
|
||||||
JSON.stringify(txs, undefined, 2),
|
JSON.stringify(txs, undefined, 2),
|
||||||
@ -141,13 +136,10 @@ export async function runRefundIncrementalTest(t: GlobalTestState) {
|
|||||||
console.log("third refund increase response", ref);
|
console.log("third refund increase response", ref);
|
||||||
|
|
||||||
{
|
{
|
||||||
let wr = await walletClient.call(WalletApiOperation.StartRefundQuery, {
|
let wr = await wallet.client.call(WalletApiOperation.StartRefundQuery, {
|
||||||
transactionId: r1.transactionId,
|
transactionId: r1.transactionId,
|
||||||
});
|
});
|
||||||
await walletClient.call(
|
await wallet.runUntilDone();
|
||||||
WalletApiOperation.TestingWaitTransactionsFinal,
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
console.log(wr);
|
console.log(wr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,17 +153,25 @@ export async function runRefundIncrementalTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
console.log(JSON.stringify(orderStatus, undefined, 2));
|
console.log(JSON.stringify(orderStatus, undefined, 2));
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
const bal = await walletClient.call(WalletApiOperation.GetBalances, {});
|
const bal = await wallet.client.call(WalletApiOperation.GetBalances, {});
|
||||||
console.log(JSON.stringify(bal, undefined, 2));
|
console.log(JSON.stringify(bal, undefined, 2));
|
||||||
|
|
||||||
{
|
{
|
||||||
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {});
|
const txs = await wallet.client.call(
|
||||||
|
WalletApiOperation.GetTransactions,
|
||||||
|
{},
|
||||||
|
);
|
||||||
console.log(JSON.stringify(txs, undefined, 2));
|
console.log(JSON.stringify(txs, undefined, 2));
|
||||||
|
|
||||||
const txTypes = txs.transactions.map((x) => x.type);
|
const txTypes = txs.transactions.map((x) => x.type);
|
||||||
t.assertDeepEqual(txTypes, ["withdrawal", "payment", "refund", "refund"]);
|
t.assertDeepEqual(txTypes, [
|
||||||
|
"withdrawal",
|
||||||
|
"payment",
|
||||||
|
"refund",
|
||||||
|
"refund",
|
||||||
|
]);
|
||||||
|
|
||||||
for (const tx of txs.transactions) {
|
for (const tx of txs.transactions) {
|
||||||
if (tx.type !== TransactionType.Refund) {
|
if (tx.type !== TransactionType.Refund) {
|
||||||
|
@ -213,4 +213,3 @@ export async function runRevocationTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
runRevocationTest.timeoutMs = 120000;
|
runRevocationTest.timeoutMs = 120000;
|
||||||
runRevocationTest.suites = ["wallet"];
|
runRevocationTest.suites = ["wallet"];
|
||||||
runRevocationTest.excludeByDefault = true;
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of GNU Taler
|
This file is part of GNU Taler
|
||||||
(C) 2023 Taler Systems S.A.
|
(C) 2020 Taler Systems S.A.
|
||||||
|
|
||||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -20,10 +20,11 @@
|
|||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
|
createSimpleTestkudosEnvironmentV2,
|
||||||
withdrawViaBankV2,
|
withdrawViaBankV2,
|
||||||
makeTestPaymentV2,
|
makeTestPaymentV2,
|
||||||
useSharedTestkudosEnvironment,
|
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
|
import { j2s } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal and payment.
|
* Run test for basic, bank-integrated withdrawal and payment.
|
||||||
@ -32,7 +33,7 @@ export async function runSimplePaymentTest(t: GlobalTestState) {
|
|||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant } =
|
const { walletClient, bank, exchange, merchant } =
|
||||||
await useSharedTestkudosEnvironment(t);
|
await createSimpleTestkudosEnvironmentV2(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
BankAccessApiClient,
|
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
|
BankApi,
|
||||||
WireGatewayApiClient,
|
WireGatewayApiClient,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
import {
|
||||||
@ -28,7 +28,7 @@ import {
|
|||||||
MerchantPrivateApi,
|
MerchantPrivateApi,
|
||||||
getWireMethodForTest,
|
getWireMethodForTest,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
import { TransactionMajorState } from "@gnu-taler/taler-util";
|
import { TransactionMajorState } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,14 +37,10 @@ import { TransactionMajorState } from "@gnu-taler/taler-util";
|
|||||||
export async function runTippingTest(t: GlobalTestState) {
|
export async function runTippingTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, merchant, exchangeBankAccount } =
|
const { wallet, bank, exchange, merchant, exchangeBankAccount } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const mbu = await BankApi.createRandomBankUser(bank);
|
||||||
allowHttp: true,
|
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
|
||||||
});
|
|
||||||
const mbu = await bankAccessApiClient.createRandomBankUser();
|
|
||||||
|
|
||||||
const merchantClient = new MerchantApiClient(
|
const merchantClient = new MerchantApiClient(
|
||||||
merchant.makeInstanceBaseUrl("default"),
|
merchant.makeInstanceBaseUrl("default"),
|
||||||
@ -103,7 +99,7 @@ export async function runTippingTest(t: GlobalTestState) {
|
|||||||
console.log("created tip", tip);
|
console.log("created tip", tip);
|
||||||
|
|
||||||
const doTip = async (): Promise<void> => {
|
const doTip = async (): Promise<void> => {
|
||||||
const ptr = await walletClient.call(WalletApiOperation.PrepareReward, {
|
const ptr = await wallet.client.call(WalletApiOperation.PrepareReward, {
|
||||||
talerRewardUri: tip.taler_reward_uri,
|
talerRewardUri: tip.taler_reward_uri,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -112,22 +108,19 @@ export async function runTippingTest(t: GlobalTestState) {
|
|||||||
t.assertAmountEquals(ptr.rewardAmountRaw, "TESTKUDOS:5");
|
t.assertAmountEquals(ptr.rewardAmountRaw, "TESTKUDOS:5");
|
||||||
t.assertAmountEquals(ptr.rewardAmountEffective, "TESTKUDOS:4.85");
|
t.assertAmountEquals(ptr.rewardAmountEffective, "TESTKUDOS:4.85");
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AcceptReward, {
|
await wallet.client.call(WalletApiOperation.AcceptReward, {
|
||||||
walletRewardId: ptr.walletRewardId,
|
walletRewardId: ptr.walletRewardId,
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(
|
await wallet.runUntilDone();
|
||||||
WalletApiOperation.TestingWaitTransactionsFinal,
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
|
|
||||||
const bal = await walletClient.call(WalletApiOperation.GetBalances, {});
|
const bal = await wallet.client.call(WalletApiOperation.GetBalances, {});
|
||||||
|
|
||||||
console.log(bal);
|
console.log(bal);
|
||||||
|
|
||||||
t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:4.85");
|
t.assertAmountEquals(bal.balances[0].available, "TESTKUDOS:4.85");
|
||||||
|
|
||||||
const txns = await walletClient.call(
|
const txns = await wallet.client.call(
|
||||||
WalletApiOperation.GetTransactions,
|
WalletApiOperation.GetTransactions,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
@ -135,10 +128,7 @@ export async function runTippingTest(t: GlobalTestState) {
|
|||||||
console.log("Transactions:", JSON.stringify(txns, undefined, 2));
|
console.log("Transactions:", JSON.stringify(txns, undefined, 2));
|
||||||
|
|
||||||
t.assertDeepEqual(txns.transactions[0].type, "reward");
|
t.assertDeepEqual(txns.transactions[0].type, "reward");
|
||||||
t.assertDeepEqual(
|
t.assertDeepEqual(txns.transactions[0].txState.major, TransactionMajorState.Done);
|
||||||
txns.transactions[0].txState.major,
|
|
||||||
TransactionMajorState.Done,
|
|
||||||
);
|
|
||||||
t.assertAmountEquals(
|
t.assertAmountEquals(
|
||||||
txns.transactions[0].amountEffective,
|
txns.transactions[0].amountEffective,
|
||||||
"TESTKUDOS:4.85",
|
"TESTKUDOS:4.85",
|
||||||
|
@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
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 } from "../harness/harness.js";
|
|
||||||
import {
|
|
||||||
createSimpleTestkudosEnvironmentV2,
|
|
||||||
} from "../harness/helpers.js";
|
|
||||||
import * as fs from "fs";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run test for basic, bank-integrated withdrawal and payment.
|
|
||||||
*/
|
|
||||||
export async function runTermOfServiceFormatTest(t: GlobalTestState) {
|
|
||||||
// Set up test environment
|
|
||||||
const tosDir = t.testDir + `/tos/`;
|
|
||||||
const langs = ["es", "en", "de"]
|
|
||||||
|
|
||||||
langs.forEach(l => {
|
|
||||||
const langDir = tosDir + l + "/"
|
|
||||||
fs.mkdirSync(langDir, { recursive: true });
|
|
||||||
fs.writeFileSync(langDir + "v1.txt", "text content");
|
|
||||||
fs.writeFileSync(langDir + "v1.md", "markdown content");
|
|
||||||
fs.writeFileSync(langDir + "v1.html", "html content");
|
|
||||||
});
|
|
||||||
|
|
||||||
const { walletClient, exchange, } =
|
|
||||||
await createSimpleTestkudosEnvironmentV2(t, undefined, {
|
|
||||||
additionalExchangeConfig: (ex) => {
|
|
||||||
ex.changeConfig((cfg) => {
|
|
||||||
cfg.setString("exchange", "terms_etag", "v1")
|
|
||||||
cfg.setString("exchange", "terms_dir", tosDir)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
|
||||||
})
|
|
||||||
|
|
||||||
t.assertDeepEqual(tos.content, "text content");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
|
||||||
acceptedFormat: ["text/html"]
|
|
||||||
})
|
|
||||||
|
|
||||||
t.assertDeepEqual(tos.content, "html content");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
|
||||||
acceptedFormat: ["text/markdown"]
|
|
||||||
})
|
|
||||||
|
|
||||||
t.assertDeepEqual(tos.content, "markdown content");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
|
||||||
acceptedFormat: ["text/markdown", "text/html"]
|
|
||||||
})
|
|
||||||
|
|
||||||
// prefer markdown since its the first one in the list
|
|
||||||
t.assertDeepEqual(tos.content, "markdown content");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const tos = await walletClient.client.call(WalletApiOperation.GetExchangeTos, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
|
||||||
acceptedFormat: ["text/pdf", "text/html"]
|
|
||||||
})
|
|
||||||
|
|
||||||
// there is no pdf so fallback in html
|
|
||||||
t.assertDeepEqual(tos.content, "html content");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
runTermOfServiceFormatTest.suites = ["wallet"];
|
|
@ -22,9 +22,7 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
|||||||
import { GlobalTestState, WalletCli } from "../harness/harness.js";
|
import { GlobalTestState, WalletCli } from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironment,
|
createSimpleTestkudosEnvironment,
|
||||||
createSimpleTestkudosEnvironmentV2,
|
|
||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
withdrawViaBankV2,
|
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
import { SyncService } from "../harness/sync.js";
|
import { SyncService } from "../harness/sync.js";
|
||||||
|
|
||||||
@ -34,8 +32,8 @@ import { SyncService } from "../harness/sync.js";
|
|||||||
export async function runWalletBackupBasicTest(t: GlobalTestState) {
|
export async function runWalletBackupBasicTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { commonDb, merchant, walletClient, bank, exchange } =
|
const { commonDb, merchant, wallet, bank, exchange } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const sync = await SyncService.create(t, {
|
const sync = await SyncService.create(t, {
|
||||||
currency: "TESTKUDOS",
|
currency: "TESTKUDOS",
|
||||||
@ -51,32 +49,32 @@ export async function runWalletBackupBasicTest(t: GlobalTestState) {
|
|||||||
await sync.start();
|
await sync.start();
|
||||||
await sync.pingUntilAvailable();
|
await sync.pingUntilAvailable();
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddBackupProvider, {
|
await wallet.client.call(WalletApiOperation.AddBackupProvider, {
|
||||||
backupProviderBaseUrl: sync.baseUrl,
|
backupProviderBaseUrl: sync.baseUrl,
|
||||||
activate: false,
|
activate: false,
|
||||||
name: sync.baseUrl,
|
name: sync.baseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
const bi = await walletClient.call(WalletApiOperation.GetBackupInfo, {});
|
const bi = await wallet.client.call(WalletApiOperation.GetBackupInfo, {});
|
||||||
t.assertDeepEqual(bi.providers[0].active, false);
|
t.assertDeepEqual(bi.providers[0].active, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddBackupProvider, {
|
await wallet.client.call(WalletApiOperation.AddBackupProvider, {
|
||||||
backupProviderBaseUrl: sync.baseUrl,
|
backupProviderBaseUrl: sync.baseUrl,
|
||||||
activate: true,
|
activate: true,
|
||||||
name: sync.baseUrl,
|
name: sync.baseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
const bi = await walletClient.call(WalletApiOperation.GetBackupInfo, {});
|
const bi = await wallet.client.call(WalletApiOperation.GetBackupInfo, {});
|
||||||
t.assertDeepEqual(bi.providers[0].active, true);
|
t.assertDeepEqual(bi.providers[0].active, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.RunBackupCycle, {});
|
await wallet.client.call(WalletApiOperation.RunBackupCycle, {});
|
||||||
|
|
||||||
{
|
{
|
||||||
const bi = await walletClient.call(WalletApiOperation.GetBackupInfo, {});
|
const bi = await wallet.client.call(WalletApiOperation.GetBackupInfo, {});
|
||||||
console.log(bi);
|
console.log(bi);
|
||||||
t.assertDeepEqual(
|
t.assertDeepEqual(
|
||||||
bi.providers[0].paymentStatus.type,
|
bi.providers[0].paymentStatus.type,
|
||||||
@ -84,32 +82,32 @@ export async function runWalletBackupBasicTest(t: GlobalTestState) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:10" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:10" });
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.RunBackupCycle, {});
|
await wallet.client.call(WalletApiOperation.RunBackupCycle, {});
|
||||||
|
|
||||||
{
|
{
|
||||||
const bi = await walletClient.call(WalletApiOperation.GetBackupInfo, {});
|
const bi = await wallet.client.call(WalletApiOperation.GetBackupInfo, {});
|
||||||
console.log(bi);
|
console.log(bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:5" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:5" });
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.RunBackupCycle, {});
|
await wallet.client.call(WalletApiOperation.RunBackupCycle, {});
|
||||||
|
|
||||||
{
|
{
|
||||||
const bi = await walletClient.call(WalletApiOperation.GetBackupInfo, {});
|
const bi = await wallet.client.call(WalletApiOperation.GetBackupInfo, {});
|
||||||
console.log(bi);
|
console.log(bi);
|
||||||
}
|
}
|
||||||
|
|
||||||
const backupRecovery = await walletClient.call(
|
const backupRecovery = await wallet.client.call(
|
||||||
WalletApiOperation.ExportBackupRecovery,
|
WalletApiOperation.ExportBackupRecovery,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
const txs = await walletClient.call(WalletApiOperation.GetTransactions, {});
|
const txs = await wallet.client.call(WalletApiOperation.GetTransactions, {});
|
||||||
console.log(`backed up transactions ${j2s(txs)}`);
|
console.log(`backed up transactions ${j2s(txs)}`);
|
||||||
|
|
||||||
const wallet2 = new WalletCli(t, "wallet2");
|
const wallet2 = new WalletCli(t, "wallet2");
|
||||||
|
@ -21,22 +21,21 @@ import { PreparePayResultType } from "@gnu-taler/taler-util";
|
|||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
import {
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
MerchantPrivateApi,
|
|
||||||
WalletCli,
|
WalletCli,
|
||||||
|
MerchantPrivateApi,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
createSimpleTestkudosEnvironmentV2,
|
createSimpleTestkudosEnvironment,
|
||||||
makeTestPaymentV2,
|
makeTestPayment,
|
||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
withdrawViaBankV2
|
|
||||||
} from "../harness/helpers.js";
|
} from "../harness/helpers.js";
|
||||||
import { SyncService } from "../harness/sync.js";
|
import { SyncService } from "../harness/sync.js";
|
||||||
|
|
||||||
export async function runWalletBackupDoublespendTest(t: GlobalTestState) {
|
export async function runWalletBackupDoublespendTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { commonDb, merchant, walletClient, bank, exchange } =
|
const { commonDb, merchant, wallet, bank, exchange } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const sync = await SyncService.create(t, {
|
const sync = await SyncService.create(t, {
|
||||||
currency: "TESTKUDOS",
|
currency: "TESTKUDOS",
|
||||||
@ -52,21 +51,21 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) {
|
|||||||
await sync.start();
|
await sync.start();
|
||||||
await sync.pingUntilAvailable();
|
await sync.pingUntilAvailable();
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddBackupProvider, {
|
await wallet.client.call(WalletApiOperation.AddBackupProvider, {
|
||||||
backupProviderBaseUrl: sync.baseUrl,
|
backupProviderBaseUrl: sync.baseUrl,
|
||||||
activate: true,
|
activate: true,
|
||||||
name: sync.baseUrl,
|
name: sync.baseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
await withdrawViaBankV2(t, { walletClient, bank, exchange, amount: "TESTKUDOS:10" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:10" });
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.RunBackupCycle, {});
|
await wallet.client.call(WalletApiOperation.RunBackupCycle, {});
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
await walletClient.call(WalletApiOperation.RunBackupCycle, {});
|
await wallet.client.call(WalletApiOperation.RunBackupCycle, {});
|
||||||
|
|
||||||
const backupRecovery = await walletClient.call(
|
const backupRecovery = await wallet.client.call(
|
||||||
WalletApiOperation.ExportBackupRecovery,
|
WalletApiOperation.ExportBackupRecovery,
|
||||||
{},
|
{},
|
||||||
);
|
);
|
||||||
@ -81,23 +80,23 @@ export async function runWalletBackupDoublespendTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"wallet1 balance before spend:",
|
"wallet1 balance before spend:",
|
||||||
await walletClient.call(WalletApiOperation.GetBalances, {}),
|
await wallet.client.call(WalletApiOperation.GetBalances, {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
await makeTestPaymentV2(t, {
|
await makeTestPayment(t, {
|
||||||
merchant,
|
merchant,
|
||||||
walletClient,
|
wallet,
|
||||||
order: {
|
order: {
|
||||||
summary: "foo",
|
summary: "foo",
|
||||||
amount: "TESTKUDOS:7",
|
amount: "TESTKUDOS:7",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"wallet1 balance after spend:",
|
"wallet1 balance after spend:",
|
||||||
await walletClient.call(WalletApiOperation.GetBalances, {}),
|
await wallet.client.call(WalletApiOperation.GetBalances, {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -30,11 +30,7 @@ import {
|
|||||||
setupDb,
|
setupDb,
|
||||||
WalletCli,
|
WalletCli,
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import { withdrawViaBank } from "../harness/helpers.js";
|
||||||
createSimpleTestkudosEnvironmentV2,
|
|
||||||
withdrawViaBank,
|
|
||||||
withdrawViaBankV2,
|
|
||||||
} from "../harness/helpers.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for wallet balance error messages / different types of insufficient balance.
|
* Test for wallet balance error messages / different types of insufficient balance.
|
||||||
@ -45,17 +41,72 @@ import {
|
|||||||
export async function runWalletBalanceTest(t: GlobalTestState) {
|
export async function runWalletBalanceTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { merchant, walletClient, exchange, bank } =
|
const db = await setupDb(t);
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
|
||||||
|
const bank = await FakebankService.create(t, {
|
||||||
|
allowRegistrations: true,
|
||||||
|
currency: "TESTKUDOS",
|
||||||
|
database: db.connStr,
|
||||||
|
httpPort: 8082,
|
||||||
|
});
|
||||||
|
|
||||||
|
const exchange = ExchangeService.create(t, {
|
||||||
|
name: "testexchange-1",
|
||||||
|
currency: "TESTKUDOS",
|
||||||
|
httpPort: 8081,
|
||||||
|
database: db.connStr,
|
||||||
|
});
|
||||||
|
|
||||||
|
const merchant = await MerchantService.create(t, {
|
||||||
|
name: "testmerchant-1",
|
||||||
|
currency: "TESTKUDOS",
|
||||||
|
httpPort: 8083,
|
||||||
|
database: db.connStr,
|
||||||
|
});
|
||||||
|
|
||||||
|
const exchangeBankAccount = await bank.createExchangeAccount(
|
||||||
|
"myexchange",
|
||||||
|
"x",
|
||||||
|
);
|
||||||
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
|
|
||||||
|
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
|
||||||
|
|
||||||
|
await bank.start();
|
||||||
|
|
||||||
|
await bank.pingUntilAvailable();
|
||||||
|
|
||||||
|
const coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS"));
|
||||||
|
exchange.addCoinConfigList(coinConfig);
|
||||||
|
|
||||||
|
await exchange.start();
|
||||||
|
await exchange.pingUntilAvailable();
|
||||||
|
|
||||||
|
merchant.addExchange(exchange);
|
||||||
|
|
||||||
|
await merchant.start();
|
||||||
|
await merchant.pingUntilAvailable();
|
||||||
|
|
||||||
|
// Fakebank uses x-taler-bank, but merchant is configured to only accept sepa!
|
||||||
|
const label = "mymerchant";
|
||||||
|
await merchant.addInstance({
|
||||||
|
id: "default",
|
||||||
|
name: "Default Instance",
|
||||||
|
paytoUris: [
|
||||||
|
`payto://iban/SANDBOXX/${getRandomIban(label)}?receiver-name=${label}`,
|
||||||
|
],
|
||||||
|
defaultWireTransferDelay: Duration.toTalerProtocolDuration(
|
||||||
|
Duration.fromSpec({ minutes: 1 }),
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("setup done!");
|
||||||
|
|
||||||
|
const wallet = new WalletCli(t);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
await withdrawViaBankV2(t, {
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
|
||||||
walletClient,
|
|
||||||
bank,
|
|
||||||
exchange,
|
|
||||||
amount: "TESTKUDOS:20",
|
|
||||||
});
|
|
||||||
|
|
||||||
const order = {
|
const order = {
|
||||||
summary: "Buy me!",
|
summary: "Buy me!",
|
||||||
@ -75,7 +126,7 @@ export async function runWalletBalanceTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Make wallet pay for the order
|
// Make wallet pay for the order
|
||||||
|
|
||||||
const preparePayResult = await walletClient.call(
|
const preparePayResult = await wallet.client.call(
|
||||||
WalletApiOperation.PreparePayForUri,
|
WalletApiOperation.PreparePayForUri,
|
||||||
{
|
{
|
||||||
talerPayUri: orderStatus.taler_pay_uri,
|
talerPayUri: orderStatus.taler_pay_uri,
|
||||||
@ -101,7 +152,7 @@ export async function runWalletBalanceTest(t: GlobalTestState) {
|
|||||||
Amounts.isZero(preparePayResult.balanceDetails.balanceMerchantDepositable),
|
Amounts.isZero(preparePayResult.balanceDetails.balanceMerchantDepositable),
|
||||||
);
|
);
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
runWalletBalanceTest.suites = ["wallet"];
|
runWalletBalanceTest.suites = ["wallet"];
|
||||||
|
@ -37,7 +37,7 @@ import {
|
|||||||
withdrawCoin,
|
withdrawCoin,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run test for basic, bank-integrated withdrawal and payment.
|
* Run test for basic, bank-integrated withdrawal and payment.
|
||||||
@ -45,7 +45,7 @@ import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
|||||||
export async function runWalletDblessTest(t: GlobalTestState) {
|
export async function runWalletDblessTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { bank, exchange } = await createSimpleTestkudosEnvironmentV2(t);
|
const { bank, exchange } = await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
const http = createPlatformHttpLib({
|
const http = createPlatformHttpLib({
|
||||||
allowHttp: true,
|
allowHttp: true,
|
||||||
|
@ -18,24 +18,27 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
|
Amounts,
|
||||||
Duration,
|
Duration,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
|
PreparePayResultType,
|
||||||
TransactionMajorState,
|
TransactionMajorState,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
BankAccessApiClient,
|
BankAccessApi,
|
||||||
|
BankApi,
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js";
|
import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js";
|
||||||
import {
|
import {
|
||||||
ExchangeService,
|
ExchangeService,
|
||||||
FakebankService,
|
FakebankService,
|
||||||
|
getRandomIban,
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
MerchantService,
|
MerchantService,
|
||||||
|
setupDb,
|
||||||
WalletClient,
|
WalletClient,
|
||||||
WalletService,
|
WalletService,
|
||||||
getRandomIban,
|
|
||||||
setupDb,
|
|
||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -123,14 +126,10 @@ export async function runWalletNotificationsTest(t: GlobalTestState) {
|
|||||||
skipDefaults: true,
|
skipDefaults: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const user = await BankApi.createRandomBankUser(bank);
|
||||||
allowHttp: true,
|
const wop = await BankAccessApi.createWithdrawalOperation(
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
bank,
|
||||||
});
|
user,
|
||||||
const user = await bankAccessApiClient.createRandomBankUser();
|
|
||||||
bankAccessApiClient.setAuth(user);
|
|
||||||
const wop = await bankAccessApiClient.createWithdrawalOperation(
|
|
||||||
user.username,
|
|
||||||
"TESTKUDOS:20",
|
"TESTKUDOS:20",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -164,7 +163,7 @@ export async function runWalletNotificationsTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Confirm it
|
// Confirm it
|
||||||
|
|
||||||
await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop);
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
await withdrawalFinishedReceivedPromise;
|
await withdrawalFinishedReceivedPromise;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
import { TalerErrorCode } from "@gnu-taler/taler-util";
|
import { TalerErrorCode } from "@gnu-taler/taler-util";
|
||||||
import {
|
import {
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
BankAccessApiClient,
|
BankApi,
|
||||||
|
BankAccessApi,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
@ -35,14 +36,10 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Create a withdrawal operation
|
// Create a withdrawal operation
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const user = await BankApi.createRandomBankUser(bank);
|
||||||
allowHttp: true,
|
const wop = await BankAccessApi.createWithdrawalOperation(
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
bank,
|
||||||
});
|
user,
|
||||||
const user = await bankAccessApiClient.createRandomBankUser();
|
|
||||||
bankAccessApiClient.setAuth(user);
|
|
||||||
const wop = await bankAccessApiClient.createWithdrawalOperation(
|
|
||||||
user.username,
|
|
||||||
"TESTKUDOS:10",
|
"TESTKUDOS:10",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -56,7 +53,8 @@ export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Abort it
|
// Abort it
|
||||||
|
|
||||||
await bankAccessApiClient.abortWithdrawalOperation(user.username, wop);
|
await BankApi.abortWithdrawalOperation(bank, user, wop);
|
||||||
|
//await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
// Withdraw
|
// Withdraw
|
||||||
|
|
||||||
|
@ -19,7 +19,11 @@
|
|||||||
*/
|
*/
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
||||||
import { BankAccessApiClient, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import {
|
||||||
|
WalletApiOperation,
|
||||||
|
BankApi,
|
||||||
|
BankAccessApi,
|
||||||
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import {
|
import {
|
||||||
j2s,
|
j2s,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
@ -40,14 +44,10 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Create a withdrawal operation
|
// Create a withdrawal operation
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const user = await BankApi.createRandomBankUser(bank);
|
||||||
allowHttp: true,
|
const wop = await BankAccessApi.createWithdrawalOperation(
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
bank,
|
||||||
});
|
user,
|
||||||
const user = await bankAccessApiClient.createRandomBankUser();
|
|
||||||
bankAccessApiClient.setAuth(user);
|
|
||||||
const wop = await bankAccessApiClient.createWithdrawalOperation(
|
|
||||||
user.username,
|
|
||||||
"TESTKUDOS:10",
|
"TESTKUDOS:10",
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Confirm it
|
// Confirm it
|
||||||
|
|
||||||
await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop);
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
await withdrawalBankConfirmedCond;
|
await withdrawalBankConfirmedCond;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import {
|
|||||||
} from "../harness/harness.js";
|
} from "../harness/harness.js";
|
||||||
import {
|
import {
|
||||||
BankAccessApi,
|
BankAccessApi,
|
||||||
BankAccessApiClient,
|
|
||||||
BankApi,
|
BankApi,
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
@ -113,13 +112,8 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
const amount = "TESTKUDOS:7.5";
|
const amount = "TESTKUDOS:7.5";
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const user = await BankApi.createRandomBankUser(bank);
|
||||||
allowHttp: true,
|
const wop = await BankAccessApi.createWithdrawalOperation(bank, user, amount);
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
|
||||||
});
|
|
||||||
const user = await bankAccessApiClient.createRandomBankUser();
|
|
||||||
bankAccessApiClient.setAuth(user);
|
|
||||||
const wop = await bankAccessApiClient.createWithdrawalOperation(user.username, amount);
|
|
||||||
|
|
||||||
// Hand it to the wallet
|
// Hand it to the wallet
|
||||||
|
|
||||||
@ -156,7 +150,10 @@ export async function runWithdrawalFeesTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
// Confirm it
|
// Confirm it
|
||||||
|
|
||||||
await bankAccessApiClient.confirmWithdrawalOperation(user.username, wop);
|
await BankApi.confirmWithdrawalOperation(bank, user, wop);
|
||||||
|
|
||||||
|
await exchange.runWirewatchOnce();
|
||||||
|
|
||||||
await wallet.runUntilDone();
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
// Check balance
|
// Check balance
|
||||||
|
@ -27,11 +27,7 @@ import {
|
|||||||
} 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 { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js";
|
import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js";
|
||||||
import {
|
import { NotificationType, TransactionMajorState, URL } from "@gnu-taler/taler-util";
|
||||||
NotificationType,
|
|
||||||
TransactionMajorState,
|
|
||||||
URL,
|
|
||||||
} from "@gnu-taler/taler-util";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Withdraw a high amount. Mostly intended as a perf test.
|
* Withdraw a high amount. Mostly intended as a perf test.
|
||||||
@ -88,8 +84,7 @@ export async function runWithdrawalHugeTest(t: GlobalTestState) {
|
|||||||
await wallet.connect();
|
await wallet.connect();
|
||||||
|
|
||||||
const withdrawalFinishedCond = wallet.waitForNotificationCond(
|
const withdrawalFinishedCond = wallet.waitForNotificationCond(
|
||||||
(wn) =>
|
(wn) => wn.type === NotificationType.TransactionStateTransition &&
|
||||||
wn.type === NotificationType.TransactionStateTransition &&
|
|
||||||
wn.transactionId.startsWith("txn:withdrawal:") &&
|
wn.transactionId.startsWith("txn:withdrawal:") &&
|
||||||
wn.newTxState.major === TransactionMajorState.Done,
|
wn.newTxState.major === TransactionMajorState.Done,
|
||||||
);
|
);
|
||||||
|
@ -17,14 +17,14 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { AbsoluteTime, Logger, j2s } from "@gnu-taler/taler-util";
|
import { GlobalTestState } from "../harness/harness.js";
|
||||||
|
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
|
||||||
import {
|
import {
|
||||||
BankAccessApiClient,
|
|
||||||
WalletApiOperation,
|
WalletApiOperation,
|
||||||
|
BankApi,
|
||||||
WireGatewayApiClient,
|
WireGatewayApiClient,
|
||||||
} from "@gnu-taler/taler-wallet-core";
|
} from "@gnu-taler/taler-wallet-core";
|
||||||
import { GlobalTestState } from "../harness/harness.js";
|
import { AbsoluteTime, j2s, Logger } from "@gnu-taler/taler-util";
|
||||||
import { createSimpleTestkudosEnvironmentV2 } from "../harness/helpers.js";
|
|
||||||
|
|
||||||
const logger = new Logger("test-withdrawal-manual.ts");
|
const logger = new Logger("test-withdrawal-manual.ts");
|
||||||
|
|
||||||
@ -34,19 +34,14 @@ const logger = new Logger("test-withdrawal-manual.ts");
|
|||||||
export async function runWithdrawalManualTest(t: GlobalTestState) {
|
export async function runWithdrawalManualTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// Set up test environment
|
||||||
|
|
||||||
const { walletClient, bank, exchange, exchangeBankAccount } =
|
const { wallet, bank, exchange, exchangeBankAccount } =
|
||||||
await createSimpleTestkudosEnvironmentV2(t);
|
await createSimpleTestkudosEnvironment(t);
|
||||||
|
|
||||||
// Create a withdrawal operation
|
// Create a withdrawal operation
|
||||||
|
|
||||||
const bankAccessApiClient = new BankAccessApiClient({
|
const user = await BankApi.createRandomBankUser(bank);
|
||||||
baseUrl: bank.bankAccessApiBaseUrl,
|
|
||||||
allowHttp: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
const user = await bankAccessApiClient.createRandomBankUser();
|
await wallet.client.call(WalletApiOperation.AddExchange, {
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.AddExchange, {
|
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -55,7 +50,7 @@ export async function runWithdrawalManualTest(t: GlobalTestState) {
|
|||||||
logger.info("starting AcceptManualWithdrawal request");
|
logger.info("starting AcceptManualWithdrawal request");
|
||||||
// We expect this to return immediately.
|
// We expect this to return immediately.
|
||||||
|
|
||||||
const wres = await walletClient.call(
|
const wres = await wallet.client.call(
|
||||||
WalletApiOperation.AcceptManualWithdrawal,
|
WalletApiOperation.AcceptManualWithdrawal,
|
||||||
{
|
{
|
||||||
exchangeBaseUrl: exchange.baseUrl,
|
exchangeBaseUrl: exchange.baseUrl,
|
||||||
@ -89,11 +84,11 @@ export async function runWithdrawalManualTest(t: GlobalTestState) {
|
|||||||
|
|
||||||
await exchange.runWirewatchOnce();
|
await exchange.runWirewatchOnce();
|
||||||
|
|
||||||
await walletClient.call(WalletApiOperation.TestingWaitTransactionsFinal, {});
|
await wallet.runUntilDone();
|
||||||
|
|
||||||
// Check balance
|
// Check balance
|
||||||
|
|
||||||
const balResp = await walletClient.call(WalletApiOperation.GetBalances, {});
|
const balResp = await wallet.client.call(WalletApiOperation.GetBalances, {});
|
||||||
t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
|
t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
|
||||||
|
|
||||||
await t.shutdown();
|
await t.shutdown();
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CancellationToken, Logger, minimatch, setGlobalLogLevelFromString } from "@gnu-taler/taler-util";
|
import { CancellationToken, Logger, minimatch } from "@gnu-taler/taler-util";
|
||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
@ -104,7 +104,6 @@ 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";
|
import { runPaymentShareTest } from "./test-payment-share.js";
|
||||||
import { runSimplePaymentTest } from "./test-simple-payment.js";
|
import { runSimplePaymentTest } from "./test-simple-payment.js";
|
||||||
import { runTermOfServiceFormatTest } from "./test-tos-format.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test runner.
|
* Test runner.
|
||||||
@ -201,7 +200,6 @@ const allTests: TestMainFunction[] = [
|
|||||||
runWithdrawalFakebankTest,
|
runWithdrawalFakebankTest,
|
||||||
runWithdrawalFeesTest,
|
runWithdrawalFeesTest,
|
||||||
runWithdrawalHugeTest,
|
runWithdrawalHugeTest,
|
||||||
runTermOfServiceFormatTest,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export interface TestRunSpec {
|
export interface TestRunSpec {
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
// Work in progress.
|
|
||||||
// TS-based schema for the sandcastle configuration.
|
|
||||||
|
|
||||||
export interface SandcastleConfig {
|
|
||||||
currency: string;
|
|
||||||
merchant: {
|
|
||||||
apiKey: string;
|
|
||||||
baseUrl: string;
|
|
||||||
};
|
|
||||||
}
|
|
@ -32,17 +32,13 @@ export enum LogLevel {
|
|||||||
None = "none",
|
None = "none",
|
||||||
}
|
}
|
||||||
|
|
||||||
let globalLogLevel = LogLevel.Info;
|
export let globalLogLevel = LogLevel.Info;
|
||||||
const byTagLogLevel: Record<string, LogLevel> = {};
|
|
||||||
|
|
||||||
export function getGlobalLogLevel(): string {
|
|
||||||
return globalLogLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setGlobalLogLevelFromString(logLevelStr: string): void {
|
export function setGlobalLogLevelFromString(logLevelStr: string): void {
|
||||||
globalLogLevel = getLevelForString(logLevelStr);
|
globalLogLevel = getLevelForString(logLevelStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const byTagLogLevel: Record<string, LogLevel> = {};
|
||||||
export function setLogLevelFromString(tag: string, logLevelStr: string): void {
|
export function setLogLevelFromString(tag: string, logLevelStr: string): void {
|
||||||
byTagLogLevel[tag] = getLevelForString(logLevelStr);
|
byTagLogLevel[tag] = getLevelForString(logLevelStr);
|
||||||
}
|
}
|
||||||
@ -102,7 +98,7 @@ function writeNodeLog(
|
|||||||
* and uses the corresponding console.* method to log in the browser.
|
* and uses the corresponding console.* method to log in the browser.
|
||||||
*/
|
*/
|
||||||
export class Logger {
|
export class Logger {
|
||||||
constructor(private tag: string) { }
|
constructor(private tag: string) {}
|
||||||
|
|
||||||
shouldLogTrace(): boolean {
|
shouldLogTrace(): boolean {
|
||||||
const level = byTagLogLevel[this.tag] ?? globalLogLevel;
|
const level = byTagLogLevel[this.tag] ?? globalLogLevel;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of GNU Taler
|
This file is part of GNU Taler
|
||||||
(C) 2020-2023 Taler Systems S.A.
|
(C) 2020 Taler Systems S.A.
|
||||||
|
|
||||||
GNU Taler is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -39,30 +39,10 @@ export class ConfigError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EntryOrigin {
|
|
||||||
/**
|
|
||||||
* From a default file.
|
|
||||||
*/
|
|
||||||
DefaultFile = 1,
|
|
||||||
/**
|
|
||||||
* From a system/installation specific default value.
|
|
||||||
*/
|
|
||||||
DefaultSystem = 2,
|
|
||||||
/**
|
|
||||||
* Loaded from file or string
|
|
||||||
*/
|
|
||||||
Loaded = 3,
|
|
||||||
/**
|
|
||||||
* Changed after loading
|
|
||||||
*/
|
|
||||||
Changed = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Entry {
|
interface Entry {
|
||||||
value: string;
|
value: string;
|
||||||
sourceLine: number;
|
sourceLine: number;
|
||||||
sourceFile: string;
|
sourceFile: string;
|
||||||
origin: EntryOrigin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Section {
|
interface Section {
|
||||||
@ -179,12 +159,12 @@ export function pathsub(
|
|||||||
|
|
||||||
const r = lookup(inner, depth + 1);
|
const r = lookup(inner, depth + 1);
|
||||||
if (r !== undefined) {
|
if (r !== undefined) {
|
||||||
s = s.substring(0, start) + r + s.substring(p + 1);
|
s = s.substr(0, start) + r + s.substr(p + 1);
|
||||||
l = start + r.length;
|
l = start + r.length;
|
||||||
continue;
|
continue;
|
||||||
} else if (defaultValue !== undefined) {
|
} else if (defaultValue !== undefined) {
|
||||||
const resolvedDefault = pathsub(defaultValue, lookup, depth + 1);
|
const resolvedDefault = pathsub(defaultValue, lookup, depth + 1);
|
||||||
s = s.substring(0, start) + resolvedDefault + s.substring(p + 1);
|
s = s.substr(0, start) + resolvedDefault + s.substr(p + 1);
|
||||||
l = start + resolvedDefault.length;
|
l = start + resolvedDefault.length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -196,7 +176,7 @@ export function pathsub(
|
|||||||
if (m && m[0]) {
|
if (m && m[0]) {
|
||||||
const r = lookup(m[0], depth + 1);
|
const r = lookup(m[0], depth + 1);
|
||||||
if (r !== undefined) {
|
if (r !== undefined) {
|
||||||
s = s.substring(0, l) + r + s.substring(l + 1 + m[0].length);
|
s = s.substr(0, l) + r + s.substr(l + 1 + m[0].length);
|
||||||
l = l + r.length;
|
l = l + r.length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -215,7 +195,6 @@ export interface LoadOptions {
|
|||||||
|
|
||||||
export interface StringifyOptions {
|
export interface StringifyOptions {
|
||||||
diagnostics?: boolean;
|
diagnostics?: boolean;
|
||||||
excludeDefaults?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LoadedFile {
|
export interface LoadedFile {
|
||||||
@ -303,11 +282,7 @@ export class Configuration {
|
|||||||
|
|
||||||
private nestLevel = 0;
|
private nestLevel = 0;
|
||||||
|
|
||||||
private loadFromFilename(
|
private loadFromFilename(filename: string, opts: LoadOptions = {}): void {
|
||||||
filename: string,
|
|
||||||
isDefaultSource: boolean,
|
|
||||||
opts: LoadOptions = {},
|
|
||||||
): void {
|
|
||||||
filename = expandPath(filename);
|
filename = expandPath(filename);
|
||||||
|
|
||||||
const checkCycle = () => {
|
const checkCycle = () => {
|
||||||
@ -334,7 +309,7 @@ export class Configuration {
|
|||||||
const oldNestLevel = this.nestLevel;
|
const oldNestLevel = this.nestLevel;
|
||||||
this.nestLevel += 1;
|
this.nestLevel += 1;
|
||||||
try {
|
try {
|
||||||
this.internalLoadFromString(s, isDefaultSource, {
|
this.loadFromString(s, {
|
||||||
...opts,
|
...opts,
|
||||||
filename: filename,
|
filename: filename,
|
||||||
});
|
});
|
||||||
@ -343,11 +318,7 @@ export class Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadGlob(
|
private loadGlob(parentFilename: string, fileglob: string): void {
|
||||||
parentFilename: string,
|
|
||||||
isDefaultSource: boolean,
|
|
||||||
fileglob: string,
|
|
||||||
): void {
|
|
||||||
const resolvedParent = nodejs_fs.realpathSync(parentFilename);
|
const resolvedParent = nodejs_fs.realpathSync(parentFilename);
|
||||||
const parentDir = nodejs_path.dirname(resolvedParent);
|
const parentDir = nodejs_path.dirname(resolvedParent);
|
||||||
|
|
||||||
@ -368,16 +339,12 @@ export class Configuration {
|
|||||||
for (const f of files) {
|
for (const f of files) {
|
||||||
if (globMatch(tail, f)) {
|
if (globMatch(tail, f)) {
|
||||||
const fullPath = nodejs_path.join(head, f);
|
const fullPath = nodejs_path.join(head, f);
|
||||||
this.loadFromFilename(fullPath, isDefaultSource);
|
this.loadFromFilename(fullPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadSecret(
|
private loadSecret(sectionName: string, filename: string): void {
|
||||||
sectionName: string,
|
|
||||||
filename: string,
|
|
||||||
isDefaultSource: boolean,
|
|
||||||
): void {
|
|
||||||
const sec = this.provideSection(sectionName);
|
const sec = this.provideSection(sectionName);
|
||||||
sec.secretFilename = filename;
|
sec.secretFilename = filename;
|
||||||
const otherCfg = new Configuration();
|
const otherCfg = new Configuration();
|
||||||
@ -387,7 +354,7 @@ export class Configuration {
|
|||||||
sec.inaccessible = true;
|
sec.inaccessible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
otherCfg.loadFromFilename(filename, isDefaultSource, {
|
otherCfg.loadFromFilename(filename, {
|
||||||
banDirectives: true,
|
banDirectives: true,
|
||||||
});
|
});
|
||||||
const otherSec = otherCfg.provideSection(sectionName);
|
const otherSec = otherCfg.provideSection(sectionName);
|
||||||
@ -396,11 +363,7 @@ export class Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private internalLoadFromString(
|
loadFromString(s: string, opts: LoadOptions = {}): void {
|
||||||
s: string,
|
|
||||||
isDefaultSource: boolean,
|
|
||||||
opts: LoadOptions = {},
|
|
||||||
): void {
|
|
||||||
let lineNo = 0;
|
let lineNo = 0;
|
||||||
const fn = opts.filename ?? "<input>";
|
const fn = opts.filename ?? "<input>";
|
||||||
const reComment = /^\s*#.*$/;
|
const reComment = /^\s*#.*$/;
|
||||||
@ -436,10 +399,7 @@ export class Configuration {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const arg = directiveMatch[2].trim();
|
const arg = directiveMatch[2].trim();
|
||||||
this.loadFromFilename(
|
this.loadFromFilename(normalizeInlineFilename(opts.filename, arg));
|
||||||
normalizeInlineFilename(opts.filename, arg),
|
|
||||||
isDefaultSource,
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "inline-secret": {
|
case "inline-secret": {
|
||||||
@ -459,7 +419,7 @@ export class Configuration {
|
|||||||
opts.filename,
|
opts.filename,
|
||||||
sp[1],
|
sp[1],
|
||||||
);
|
);
|
||||||
this.loadSecret(sp[0], secretFilename, isDefaultSource);
|
this.loadSecret(sp[0], secretFilename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "inline-matching": {
|
case "inline-matching": {
|
||||||
@ -469,7 +429,7 @@ export class Configuration {
|
|||||||
`invalid configuration, @inline-matching@ directive in ${fn}:${lineNo} can only be used from a file`,
|
`invalid configuration, @inline-matching@ directive in ${fn}:${lineNo} can only be used from a file`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.loadGlob(opts.filename, isDefaultSource, arg);
|
this.loadGlob(opts.filename, arg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -502,9 +462,6 @@ export class Configuration {
|
|||||||
value: val,
|
value: val,
|
||||||
sourceFile: opts.filename ?? "<unknown>",
|
sourceFile: opts.filename ?? "<unknown>",
|
||||||
sourceLine: lineNo,
|
sourceLine: lineNo,
|
||||||
origin: isDefaultSource
|
|
||||||
? EntryOrigin.DefaultFile
|
|
||||||
: EntryOrigin.Loaded,
|
|
||||||
};
|
};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -514,10 +471,6 @@ export class Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFromString(s: string, opts: LoadOptions = {}): void {
|
|
||||||
return this.internalLoadFromString(s, false, opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
private provideSection(section: string): Section {
|
private provideSection(section: string): Section {
|
||||||
const secNorm = section.toUpperCase();
|
const secNorm = section.toUpperCase();
|
||||||
if (this.sectionMap[secNorm]) {
|
if (this.sectionMap[secNorm]) {
|
||||||
@ -543,24 +496,6 @@ export class Configuration {
|
|||||||
value,
|
value,
|
||||||
sourceLine: 0,
|
sourceLine: 0,
|
||||||
sourceFile: "<unknown>",
|
sourceFile: "<unknown>",
|
||||||
origin: EntryOrigin.Changed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a string value to a value from default locations.
|
|
||||||
*/
|
|
||||||
private setStringSystemDefault(
|
|
||||||
section: string,
|
|
||||||
option: string,
|
|
||||||
value: string,
|
|
||||||
): void {
|
|
||||||
const sec = this.provideSection(section);
|
|
||||||
sec.entries[option.toUpperCase()] = {
|
|
||||||
value,
|
|
||||||
sourceLine: 0,
|
|
||||||
sourceFile: "<unknown>",
|
|
||||||
origin: EntryOrigin.DefaultSystem,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,7 +559,7 @@ export class Configuration {
|
|||||||
lookupVariable(x: string, depth: number = 0): string | undefined {
|
lookupVariable(x: string, depth: number = 0): string | undefined {
|
||||||
// We loop up options in PATHS in upper case, as option names
|
// We loop up options in PATHS in upper case, as option names
|
||||||
// are case insensitive
|
// are case insensitive
|
||||||
let val = this.findEntry("PATHS", x)?.value;
|
const val = this.findEntry("PATHS", x)?.value;
|
||||||
if (val !== undefined) {
|
if (val !== undefined) {
|
||||||
return pathsub(val, (v, d) => this.lookupVariable(v, d), depth);
|
return pathsub(val, (v, d) => this.lookupVariable(v, d), depth);
|
||||||
}
|
}
|
||||||
@ -643,63 +578,30 @@ export class Configuration {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDefaultsFromDir(dirname: string): void {
|
loadFrom(dirname: string): void {
|
||||||
const files = nodejs_fs.readdirSync(dirname);
|
const files = nodejs_fs.readdirSync(dirname);
|
||||||
for (const f of files) {
|
for (const f of files) {
|
||||||
const fn = nodejs_path.join(dirname, f);
|
const fn = nodejs_path.join(dirname, f);
|
||||||
this.loadFromFilename(fn, true);
|
this.loadFromFilename(fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadDefaults(): void {
|
private loadDefaults(): void {
|
||||||
let baseConfigDir = process.env["TALER_BASE_CONFIG"];
|
let bc = process.env["TALER_BASE_CONFIG"];
|
||||||
if (!baseConfigDir) {
|
if (!bc) {
|
||||||
/* Try to locate the configuration based on the location
|
/* Try to locate the configuration based on the location
|
||||||
* of the taler-config binary. */
|
* of the taler-config binary. */
|
||||||
const path = which("taler-config");
|
const path = which("taler-config");
|
||||||
if (path) {
|
if (path) {
|
||||||
baseConfigDir = nodejs_fs.realpathSync(
|
bc = nodejs_fs.realpathSync(
|
||||||
nodejs_path.dirname(path) + "/../share/taler/config.d",
|
nodejs_path.dirname(path) + "/../share/taler/config.d",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!baseConfigDir) {
|
if (!bc) {
|
||||||
baseConfigDir = "/usr/share/taler/config.d";
|
bc = "/usr/share/taler/config.d";
|
||||||
}
|
}
|
||||||
|
this.loadFrom(bc);
|
||||||
let installPrefix = process.env["TALER_PREFIX"];
|
|
||||||
if (!installPrefix) {
|
|
||||||
/* Try to locate install path based on the location
|
|
||||||
* of the taler-config binary. */
|
|
||||||
const path = which("taler-config");
|
|
||||||
if (path) {
|
|
||||||
installPrefix = nodejs_fs.realpathSync(
|
|
||||||
nodejs_path.dirname(path) + "/..",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!installPrefix) {
|
|
||||||
installPrefix = "/usr";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setStringSystemDefault(
|
|
||||||
"PATHS",
|
|
||||||
"LIBEXECDIR",
|
|
||||||
`${installPrefix}/taler/libexec/`,
|
|
||||||
);
|
|
||||||
this.setStringSystemDefault(
|
|
||||||
"PATHS",
|
|
||||||
"DOCDIR",
|
|
||||||
`${installPrefix}/share/doc/taler/`,
|
|
||||||
);
|
|
||||||
this.setStringSystemDefault("PATHS", "ICONDIR", `${installPrefix}/share/icons/`);
|
|
||||||
this.setStringSystemDefault("PATHS", "LOCALEDIR", `${installPrefix}/share/locale/`);
|
|
||||||
this.setStringSystemDefault("PATHS", "PREFIX", `${installPrefix}/`);
|
|
||||||
this.setStringSystemDefault("PATHS", "BINDIR", `${installPrefix}/bin`);
|
|
||||||
this.setStringSystemDefault("PATHS", "LIBDIR", `${installPrefix}/lib/taler/`);
|
|
||||||
this.setStringSystemDefault("PATHS", "DATADIR", `${installPrefix}/share/taler/`);
|
|
||||||
|
|
||||||
this.loadDefaultsFromDir(baseConfigDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultConfigFilename(): string | undefined {
|
getDefaultConfigFilename(): string | undefined {
|
||||||
@ -729,13 +631,11 @@ export class Configuration {
|
|||||||
const cfg = new Configuration();
|
const cfg = new Configuration();
|
||||||
cfg.loadDefaults();
|
cfg.loadDefaults();
|
||||||
if (filename) {
|
if (filename) {
|
||||||
cfg.loadFromFilename(filename, false);
|
cfg.loadFromFilename(filename);
|
||||||
} else {
|
} else {
|
||||||
const fn = cfg.getDefaultConfigFilename();
|
const fn = cfg.getDefaultConfigFilename();
|
||||||
if (fn) {
|
if (fn) {
|
||||||
// It's the default filename for the main config file,
|
cfg.loadFromFilename(fn);
|
||||||
// but we don't consider the values default values.
|
|
||||||
cfg.loadFromFilename(fn, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cfg.hintEntrypoint = filename;
|
cfg.hintEntrypoint = filename;
|
||||||
@ -757,51 +657,26 @@ export class Configuration {
|
|||||||
}
|
}
|
||||||
for (const sectionName of Object.keys(this.sectionMap)) {
|
for (const sectionName of Object.keys(this.sectionMap)) {
|
||||||
const sec = this.sectionMap[sectionName];
|
const sec = this.sectionMap[sectionName];
|
||||||
let headerWritten = false;
|
|
||||||
for (const optionName of Object.keys(sec.entries)) {
|
|
||||||
const entry = this.sectionMap[sectionName].entries[optionName];
|
|
||||||
if (
|
|
||||||
opts.excludeDefaults &&
|
|
||||||
(entry.origin === EntryOrigin.DefaultSystem ||
|
|
||||||
entry.origin === EntryOrigin.DefaultFile)
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!headerWritten) {
|
|
||||||
if (opts.diagnostics && sec.secretFilename) {
|
if (opts.diagnostics && sec.secretFilename) {
|
||||||
s += `# Secret section from ${sec.secretFilename}\n`;
|
s += `# Secret section from ${sec.secretFilename}\n`;
|
||||||
s += `# Secret accessible: ${!sec.inaccessible}\n`;
|
s += `# Secret accessible: ${!sec.inaccessible}\n`;
|
||||||
}
|
}
|
||||||
s += `[${sectionName}]\n`;
|
s += `[${sectionName}]\n`;
|
||||||
headerWritten = true;
|
for (const optionName of Object.keys(sec.entries)) {
|
||||||
}
|
const entry = this.sectionMap[sectionName].entries[optionName];
|
||||||
if (entry !== undefined) {
|
if (entry !== undefined) {
|
||||||
if (opts.diagnostics) {
|
if (opts.diagnostics) {
|
||||||
switch (entry.origin) {
|
|
||||||
case EntryOrigin.DefaultFile:
|
|
||||||
case EntryOrigin.Changed:
|
|
||||||
case EntryOrigin.Loaded:
|
|
||||||
s += `# ${entry.sourceFile}:${entry.sourceLine}\n`;
|
s += `# ${entry.sourceFile}:${entry.sourceLine}\n`;
|
||||||
break;
|
|
||||||
case EntryOrigin.DefaultSystem:
|
|
||||||
s += `# (system/installation default)\n`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s += `${optionName} = ${entry.value}\n`;
|
s += `${optionName} = ${entry.value}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (headerWritten) {
|
|
||||||
s += "\n";
|
s += "\n";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(filename: string, opts: { excludeDefaults?: boolean } = {}): void {
|
write(filename: string): void {
|
||||||
nodejs_fs.writeFileSync(
|
nodejs_fs.writeFileSync(filename, this.stringify());
|
||||||
filename,
|
|
||||||
this.stringify({ excludeDefaults: opts.excludeDefaults }),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,8 @@ export namespace BankAccessApi {
|
|||||||
|
|
||||||
export interface BankAccessApiClientArgs {
|
export interface BankAccessApiClientArgs {
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
auth?: { username: string; password: string };
|
username: string;
|
||||||
|
password: string;
|
||||||
enableThrottling?: boolean;
|
enableThrottling?: boolean;
|
||||||
allowHttp?: boolean;
|
allowHttp?: boolean;
|
||||||
}
|
}
|
||||||
@ -329,7 +330,7 @@ export class WireGatewayApiClient {
|
|||||||
* but it will be nice to have in utils to be used by others
|
* but it will be nice to have in utils to be used by others
|
||||||
*/
|
*/
|
||||||
export class BankAccessApiClient {
|
export class BankAccessApiClient {
|
||||||
httpLib: HttpRequestLibrary;
|
httpLib;
|
||||||
|
|
||||||
constructor(private args: BankAccessApiClientArgs) {
|
constructor(private args: BankAccessApiClientArgs) {
|
||||||
this.httpLib = createPlatformHttpLib({
|
this.httpLib = createPlatformHttpLib({
|
||||||
@ -338,33 +339,19 @@ export class BankAccessApiClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setAuth(auth: { username: string; password: string }) {
|
async getTransactions(): Promise<void> {
|
||||||
this.args.auth = auth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private makeAuthHeader(): Record<string, string> {
|
|
||||||
if (!this.args.auth) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const authHeaderValue = makeBasicAuthHeader(
|
|
||||||
this.args.auth.username,
|
|
||||||
this.args.auth.password,
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
Authorization: authHeaderValue,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTransactions(username: string): Promise<void> {
|
|
||||||
const auth = this.args.auth;
|
|
||||||
const reqUrl = new URL(
|
const reqUrl = new URL(
|
||||||
`accounts/${username}/transactions`,
|
`accounts/${this.args.username}/transactions`,
|
||||||
this.args.baseUrl,
|
this.args.baseUrl,
|
||||||
);
|
);
|
||||||
|
const authHeaderValue = makeBasicAuthHeader(
|
||||||
|
this.args.username,
|
||||||
|
this.args.password,
|
||||||
|
);
|
||||||
const resp = await this.httpLib.fetch(reqUrl.href, {
|
const resp = await this.httpLib.fetch(reqUrl.href, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
...this.makeAuthHeader(),
|
Authorization: authHeaderValue,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -373,128 +360,24 @@ export class BankAccessApiClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createTransaction(
|
async createTransaction(
|
||||||
username: string,
|
|
||||||
req: BankAccessApiCreateTransactionRequest,
|
req: BankAccessApiCreateTransactionRequest,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const reqUrl = new URL(
|
const reqUrl = new URL(
|
||||||
`accounts/${username}/transactions`,
|
`accounts/${this.args.username}/transactions`,
|
||||||
this.args.baseUrl,
|
this.args.baseUrl,
|
||||||
);
|
);
|
||||||
|
const authHeaderValue = makeBasicAuthHeader(
|
||||||
|
this.args.username,
|
||||||
|
this.args.password,
|
||||||
|
);
|
||||||
const resp = await this.httpLib.fetch(reqUrl.href, {
|
const resp = await this.httpLib.fetch(reqUrl.href, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: req,
|
body: req,
|
||||||
headers: this.makeAuthHeader(),
|
headers: {
|
||||||
|
Authorization: authHeaderValue,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return await readSuccessResponseJsonOrThrow(resp, codecForAny());
|
return await readSuccessResponseJsonOrThrow(resp, codecForAny());
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerAccount(
|
|
||||||
username: string,
|
|
||||||
password: string,
|
|
||||||
options: {
|
|
||||||
iban?: string;
|
|
||||||
},
|
|
||||||
): Promise<BankUser> {
|
|
||||||
const url = new URL("testing/register", this.args.baseUrl);
|
|
||||||
const resp = await this.httpLib.fetch(url.href, {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
iban: options?.iban,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
let paytoUri = `payto://x-taler-bank/localhost/${username}`;
|
|
||||||
if (resp.status !== 200 && resp.status !== 202 && resp.status !== 204) {
|
|
||||||
logger.error(`${j2s(await resp.json())}`);
|
|
||||||
throw TalerError.fromDetail(
|
|
||||||
TalerErrorCode.GENERIC_UNEXPECTED_REQUEST_ERROR,
|
|
||||||
{
|
|
||||||
httpStatusCode: resp.status,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Pybank has no body, thus this might throw.
|
|
||||||
const respJson = await resp.json();
|
|
||||||
// LibEuFin demobank returns payto URI in response
|
|
||||||
if (respJson.paytoUri) {
|
|
||||||
paytoUri = respJson.paytoUri;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
password,
|
|
||||||
username,
|
|
||||||
accountPaytoUri: paytoUri,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async createRandomBankUser(): Promise<BankUser> {
|
|
||||||
const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase();
|
|
||||||
const password = "pw-" + encodeCrock(getRandomBytes(10)).toLowerCase();
|
|
||||||
// FIXME: This is just a temporary workaround, because demobank is running out of short IBANs
|
|
||||||
const iban = generateIban("DE", 15);
|
|
||||||
return await this.registerAccount(username, password, {
|
|
||||||
iban,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async createWithdrawalOperation(
|
|
||||||
user: string,
|
|
||||||
amount: string,
|
|
||||||
): Promise<WithdrawalOperationInfo> {
|
|
||||||
const url = new URL(`accounts/${user}/withdrawals`, this.args.baseUrl);
|
|
||||||
const resp = await this.httpLib.fetch(url.href, {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
amount,
|
|
||||||
},
|
|
||||||
headers: this.makeAuthHeader(),
|
|
||||||
});
|
|
||||||
return readSuccessResponseJsonOrThrow(
|
|
||||||
resp,
|
|
||||||
codecForWithdrawalOperationInfo(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async confirmWithdrawalOperation(
|
|
||||||
username: string,
|
|
||||||
wopi: WithdrawalOperationInfo,
|
|
||||||
): Promise<void> {
|
|
||||||
const url = new URL(
|
|
||||||
`accounts/${username}/withdrawals/${wopi.withdrawal_id}/confirm`,
|
|
||||||
this.args.baseUrl,
|
|
||||||
);
|
|
||||||
logger.info(`confirming withdrawal operation via ${url.href}`);
|
|
||||||
const resp = await this.httpLib.fetch(url.href, {
|
|
||||||
method: "POST",
|
|
||||||
body: {},
|
|
||||||
headers: this.makeAuthHeader(),
|
|
||||||
});
|
|
||||||
|
|
||||||
logger.info(`response status ${resp.status}`);
|
|
||||||
const respJson = await readSuccessResponseJsonOrThrow(resp, codecForAny());
|
|
||||||
|
|
||||||
// FIXME: We don't check the status here!
|
|
||||||
}
|
|
||||||
|
|
||||||
async abortWithdrawalOperation(
|
|
||||||
accountName: string,
|
|
||||||
wopi: WithdrawalOperationInfo,
|
|
||||||
): Promise<void> {
|
|
||||||
const url = new URL(
|
|
||||||
`accounts/${accountName}/withdrawals/${wopi.withdrawal_id}/abort`,
|
|
||||||
this.args.baseUrl,
|
|
||||||
);
|
|
||||||
const resp = await this.httpLib.fetch(url.href, {
|
|
||||||
method: "POST",
|
|
||||||
body: {},
|
|
||||||
headers: this.makeAuthHeader(),
|
|
||||||
});
|
|
||||||
await readSuccessResponseJsonOrThrow(resp, codecForAny());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user