test for manual withdrawal

This commit is contained in:
Florian Dold 2020-08-08 22:27:26 +05:30
parent e8c0a43dd3
commit 5fb9dae13c
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
6 changed files with 188 additions and 21 deletions

View File

@ -69,8 +69,7 @@ export async function sh(
logName: string,
command: string,
): Promise<string> {
console.log("runing command");
console.log(command);
console.log("runing command", command);
return new Promise((resolve, reject) => {
const stdoutChunks: Buffer[] = [];
const proc = spawn(command, {
@ -89,8 +88,8 @@ export async function sh(
flags: "a",
});
proc.stderr.pipe(stderrLog);
proc.on("exit", (code) => {
console.log("child process exited");
proc.on("exit", (code, signal) => {
console.log(`child process exited (${code} / ${signal})`);
if (code != 0) {
reject(Error(`Unexpected exit code ${code} for '${command}'`));
return;
@ -419,6 +418,13 @@ async function pingProc(
}
}
export interface ExchangeBankAccount {
accountName: string;
accountPassword: string;
accountPaytoUri: string;
wireGatewayApiBaseUrl: string;
}
export class BankService {
proc: ProcessWrapper | undefined;
@ -454,6 +460,18 @@ export class BankService {
);
const cfgFilename = gc.testDir + "/bank.conf";
config.write(cfgFilename);
await sh(
gc,
"taler-bank-manage_django",
`taler-bank-manage -c '${cfgFilename}' django migrate`,
);
await sh(
gc,
"taler-bank-manage_django",
`taler-bank-manage -c '${cfgFilename}' django provide_accounts`,
);
return new BankService(gc, bc, cfgFilename);
}
@ -463,6 +481,33 @@ export class BankService {
config.setString("bank", "suggested_exchange_payto", exchangePayto);
}
async createExchangeAccount(
accountName: string,
password: string,
): Promise<ExchangeBankAccount> {
await sh(
this.globalTestState,
"taler-bank-manage_django",
`taler-bank-manage -c '${this.configFile}' django add_bank_account ${accountName}`,
);
await sh(
this.globalTestState,
"taler-bank-manage_django",
`taler-bank-manage -c '${this.configFile}' django changepassword_unsafe ${accountName} ${password}`,
);
await sh(
this.globalTestState,
"taler-bank-manage_django",
`taler-bank-manage -c '${this.configFile}' django top_up ${accountName} ${this.bankConfig.currency}:100000`,
);
return {
accountName: accountName,
accountPassword: password,
accountPaytoUri: `payto://x-taler-bank/${accountName}`,
wireGatewayApiBaseUrl: `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${accountName}/`,
};
}
get port() {
return this.bankConfig.httpPort;
}
@ -495,10 +540,12 @@ export class BankService {
}
async createRandomBankUser(): Promise<BankUser> {
const username =
"user-" + talerCrypto.encodeCrock(talerCrypto.getRandomBytes(10));
const bankUser: BankUser = {
username:
"user-" + talerCrypto.encodeCrock(talerCrypto.getRandomBytes(10)),
username,
password: "pw-" + talerCrypto.encodeCrock(talerCrypto.getRandomBytes(10)),
accountPaytoUri: `payto://x-taler-bank/localhost/${username}`,
};
await this.createAccount(bankUser.username, bankUser.password);
return bankUser;
@ -521,6 +568,29 @@ export class BankService {
return codecForWithdrawalOperationInfo().decode(resp.data);
}
async adminAddIncoming(params: {
exchangeBankAccount: ExchangeBankAccount;
amount: string;
reservePub: string;
debitAccountPayto: string;
}) {
const url = `http://localhost:${this.bankConfig.httpPort}/taler-wire-gateway/${params.exchangeBankAccount.accountName}/admin/add-incoming`;
await axios.post(
url,
{
amount: params.amount,
reserve_pub: params.reservePub,
debit_account: params.debitAccountPayto,
},
{
auth: {
username: params.exchangeBankAccount.accountName,
password: params.exchangeBankAccount.accountPassword,
},
},
);
}
async confirmWithdrawalOperation(
bankUser: BankUser,
wopi: WithdrawalOperationInfo,
@ -539,6 +609,7 @@ export class BankService {
export interface BankUser {
username: string;
password: string;
accountPaytoUri: string;
}
export interface WithdrawalOperationInfo {
@ -600,6 +671,14 @@ export class ExchangeService implements ExchangeServiceInterface {
return new ExchangeService(gc, ec, cfgFilename, keyPair);
}
async runWirewatchOnce() {
await sh(
this.globalState,
"wirewatch-test",
`taler-exchange-wirewatch -c '${this.configFilename}' -t`,
);
}
static create(gc: GlobalTestState, e: ExchangeConfig) {
const config = new Configuration();
config.setString("taler", "currency", e.currency);
@ -686,13 +765,10 @@ export class ExchangeService implements ExchangeServiceInterface {
return this.exchangeConfig.httpPort;
}
async setupTestBankAccount(
bc: BankService,
async addBankAccount(
localName: string,
accountName: string,
password: string,
exchangeBankAccount: ExchangeBankAccount,
): Promise<void> {
await bc.createAccount(accountName, password);
const config = Configuration.load(this.configFilename);
config.setString(
`exchange-account-${localName}`,
@ -702,22 +778,30 @@ export class ExchangeService implements ExchangeServiceInterface {
config.setString(
`exchange-account-${localName}`,
"payto_uri",
`payto://x-taler-bank/localhost/${accountName}`,
exchangeBankAccount.accountPaytoUri,
);
config.setString(`exchange-account-${localName}`, "enable_credit", "yes");
config.setString(`exchange-account-${localName}`, "enable_debit", "yes");
config.setString(
`exchange-account-${localName}`,
"wire_gateway_url",
`http://localhost:${bc.port}/taler-wire-gateway/${accountName}/`,
exchangeBankAccount.wireGatewayApiBaseUrl,
);
config.setString(
`exchange-account-${localName}`,
"wire_gateway_auth_method",
"basic",
);
config.setString(`exchange-account-${localName}`, "username", accountName);
config.setString(`exchange-account-${localName}`, "password", password);
config.setString(
`exchange-account-${localName}`,
"username",
exchangeBankAccount.accountName,
);
config.setString(
`exchange-account-${localName}`,
"password",
exchangeBankAccount.accountPassword,
);
config.write(this.configFilename);
}

View File

@ -32,6 +32,7 @@ import {
setupDb,
BankService,
defaultCoinConfig,
ExchangeBankAccount,
} from "./harness";
import { AmountString } from "taler-wallet-core/lib/types/talerTypes";
@ -39,6 +40,7 @@ export interface SimpleTestEnvironment {
commonDb: DbInfo;
bank: BankService;
exchange: ExchangeService;
exchangeBankAccount: ExchangeBankAccount;
merchant: MerchantService;
wallet: WalletCli;
}
@ -73,13 +75,15 @@ export async function createSimpleTestkudosEnvironment(
database: db.connStr,
});
bank.setSuggestedExchange(exchange, "payto://x-taler-bank/MyExchange");
const exchangeBankAccount = await bank.createExchangeAccount("MyExchange", "x");
exchange.addBankAccount("1", exchangeBankAccount);
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
await bank.start();
await bank.pingUntilAvailable();
await exchange.setupTestBankAccount(bank, "1", "MyExchange", "x");
exchange.addOfferedCoins(defaultCoinConfig);
await exchange.start();
@ -112,6 +116,7 @@ export async function createSimpleTestkudosEnvironment(
merchant,
wallet,
bank,
exchangeBankAccount,
};
}

View File

@ -56,13 +56,15 @@ runTest(async (t: GlobalTestState) => {
database: db.connStr,
});
bank.setSuggestedExchange(exchange, "payto://x-taler-bank/MyExchange");
const exchangeBankAccount = await bank.createExchangeAccount("MyExchange", "x");
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
await bank.start();
await bank.pingUntilAvailable();
await exchange.setupTestBankAccount(bank, "1", "MyExchange", "x");
await exchange.addBankAccount("1", exchangeBankAccount);
exchange.addOfferedCoins(defaultCoinConfig);
await exchange.start();

View File

@ -51,15 +51,17 @@ async function setupTest(t: GlobalTestState): Promise<{
database: db.connStr,
});
const exchangeBankAccount = await bank.createExchangeAccount("MyExchange", "x");
exchange.addOfferedCoins([coin_ct10, coin_u1]);
bank.setSuggestedExchange(exchange, "payto://x-taler-bank/MyExchange");
bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri);
await bank.start();
await bank.pingUntilAvailable();
await exchange.setupTestBankAccount(bank, "1", "MyExchange", "x");
await exchange.addBankAccount("1", exchangeBankAccount);
await exchange.start();
await exchange.pingUntilAvailable();

View File

@ -0,0 +1,74 @@
/*
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 { runTest, GlobalTestState } from "./harness";
import { createSimpleTestkudosEnvironment } from "./helpers";
import { walletTypes } from "taler-wallet-core";
import { CoreApiResponse } from "taler-wallet-core/lib/walletCoreApiHandler";
/**
* Run test for basic, bank-integrated withdrawal.
*/
runTest(async (t: GlobalTestState) => {
// Set up test environment
const { wallet, bank, exchange, exchangeBankAccount } = await createSimpleTestkudosEnvironment(t);
// Create a withdrawal operation
const user = await bank.createRandomBankUser();
let wresp: CoreApiResponse;
wresp = await wallet.apiRequest("addExchange", {
exchangeBaseUrl: exchange.baseUrl,
});
t.assertTrue(wresp.type === "response");
wresp = await wallet.apiRequest("acceptManualWithdrawal", {
exchangeBaseUrl: exchange.baseUrl,
amount: "TESTKUDOS:10",
});
t.assertTrue(wresp.type === "response");
const reservePub: string = (wresp.result as any).reservePub;
await bank.adminAddIncoming({
exchangeBankAccount,
amount: "TESTKUDOS:10",
debitAccountPayto: user.accountPaytoUri,
reservePub: reservePub,
});
await exchange.runWirewatchOnce();
await wallet.runUntilDone();
// Check balance
const balApiResp = await wallet.apiRequest("getBalances", {});
t.assertTrue(balApiResp.type === "response");
const balResp = walletTypes.codecForBalancesResponse().decode(balApiResp.result);
t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available)
await t.shutdown();
});