aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-harness/src/harness
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-08-29 09:02:16 +0200
committerFlorian Dold <florian@dold.me>2023-08-29 09:03:19 +0200
commitb13bd85215ad64e7a2764ac7e7fee5945ffa1c07 (patch)
tree70643c7e76baeb9f61857add603dc381b6f03766 /packages/taler-harness/src/harness
parent8941f29cb457f86235b73f125e77a88cb762f353 (diff)
downloadwallet-core-b13bd85215ad64e7a2764ac7e7fee5945ffa1c07.tar.xz
taler-harness: remove axios usage, renovate some tests
Diffstat (limited to 'packages/taler-harness/src/harness')
-rw-r--r--packages/taler-harness/src/harness/harness.ts396
-rw-r--r--packages/taler-harness/src/harness/libeufin-apis.ts519
-rw-r--r--packages/taler-harness/src/harness/libeufin.ts177
3 files changed, 446 insertions, 646 deletions
diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts
index 926a0c93b..7db9d82bd 100644
--- a/packages/taler-harness/src/harness/harness.ts
+++ b/packages/taler-harness/src/harness/harness.ts
@@ -55,9 +55,11 @@ import {
RewardCreateRequest,
TippingReserveStatus,
WalletNotification,
+ codecForAny,
} from "@gnu-taler/taler-util";
import {
createPlatformHttpLib,
+ expectSuccessResponseOrThrow,
readSuccessResponseJsonOrThrow,
} from "@gnu-taler/taler-util/http";
import {
@@ -78,7 +80,6 @@ import {
WalletNotificationWaiter,
} from "@gnu-taler/taler-wallet-core/remote";
import { deepStrictEqual } from "assert";
-import axiosImp, { AxiosError } from "axios";
import { ChildProcess, spawn } from "child_process";
import * as fs from "fs";
import * as http from "http";
@@ -87,12 +88,9 @@ import * as path from "path";
import * as readline from "readline";
import { URL } from "url";
import { CoinConfig } from "./denomStructures.js";
-import { LibeufinNexusApi, LibeufinSandboxApi } from "./libeufin-apis.js";
const logger = new Logger("harness.ts");
-const axios = axiosImp.default;
-
export async function delayMs(ms: number): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(), ms);
@@ -322,12 +320,6 @@ export class GlobalTestState {
);
}
- assertAxiosError(e: any): asserts e is AxiosError {
- if (!e.isAxiosError) {
- throw Error("expected axios error");
- }
- }
-
assertTrue(b: boolean): asserts b {
if (!b) {
throw Error("test assertion failed");
@@ -558,7 +550,10 @@ export async function pingProc(
while (true) {
try {
logger.trace(`pinging ${serviceName} at ${url}`);
- const resp = await axios.get(url);
+ const resp = await harnessHttpLib.fetch(url);
+ if (resp.status !== 200) {
+ throw Error("non-200 status code");
+ }
logger.trace(`service ${serviceName} available`);
return;
} catch (e: any) {
@@ -584,289 +579,6 @@ class BankServiceBase {
}
/**
- * Work in progress. The key point is that both Sandbox and Nexus
- * will be configured and started by this class.
- */
-class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {
- sandboxProc: ProcessWrapper | undefined;
- nexusProc: ProcessWrapper | undefined;
-
- http = createPlatformHttpLib({
- allowHttp: true,
- enableThrottling: false,
- });
-
- static async create(
- gc: GlobalTestState,
- bc: BankConfig,
- ): Promise<LibEuFinBankService> {
- return new LibEuFinBankService(gc, bc, "foo");
- }
-
- get port() {
- return this.bankConfig.httpPort;
- }
- get nexusPort() {
- return this.bankConfig.httpPort + 1000;
- }
-
- get nexusDbConn(): string {
- return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-nexus.sqlite3`;
- }
-
- get sandboxDbConn(): string {
- return `jdbc:sqlite:${this.globalTestState.testDir}/libeufin-sandbox.sqlite3`;
- }
-
- get nexusBaseUrl(): string {
- return `http://localhost:${this.nexusPort}`;
- }
-
- get baseUrlDemobank(): string {
- let url = new URL("demobanks/default/", this.baseUrlNetloc);
- return url.href;
- }
-
- get bankAccessApiBaseUrl(): string {
- let url = new URL("access-api/", this.baseUrlDemobank);
- return url.href;
- }
-
- get baseUrlNetloc(): string {
- return `http://localhost:${this.bankConfig.httpPort}/`;
- }
-
- get baseUrl(): string {
- return this.bankAccessApiBaseUrl;
- }
-
- async setSuggestedExchange(
- e: ExchangeServiceInterface,
- exchangePayto: string,
- ) {
- await sh(
- this.globalTestState,
- "libeufin-sandbox-set-default-exchange",
- `libeufin-sandbox default-exchange ${e.baseUrl} ${exchangePayto}`,
- {
- ...process.env,
- LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
- },
- );
- }
-
- // Create one at both sides: Sandbox and Nexus.
- async createExchangeAccount(
- accountName: string,
- password: string,
- ): Promise<HarnessExchangeBankAccount> {
- logger.info("Create Exchange account(s)!");
- /**
- * Many test cases try to create a Exchange account before
- * starting the bank; that's because the Pybank did it entirely
- * via the configuration file.
- */
- await this.start();
- await this.pingUntilAvailable();
- await LibeufinSandboxApi.createDemobankAccount(accountName, password, {
- baseUrl: this.bankAccessApiBaseUrl,
- });
- let bankAccountLabel = accountName;
- await LibeufinSandboxApi.createDemobankEbicsSubscriber(
- {
- hostID: "talertestEbicsHost",
- userID: "exchangeEbicsUser",
- partnerID: "exchangeEbicsPartner",
- },
- bankAccountLabel,
- { baseUrl: this.baseUrlDemobank },
- );
-
- await LibeufinNexusApi.createUser(
- { baseUrl: this.nexusBaseUrl },
- {
- username: accountName,
- password: password,
- },
- );
- await LibeufinNexusApi.createEbicsBankConnection(
- { baseUrl: this.nexusBaseUrl },
- {
- name: "ebics-connection", // connection name.
- ebicsURL: new URL("ebicsweb", this.baseUrlNetloc).href,
- hostID: "talertestEbicsHost",
- userID: "exchangeEbicsUser",
- partnerID: "exchangeEbicsPartner",
- },
- );
- await LibeufinNexusApi.connectBankConnection(
- { baseUrl: this.nexusBaseUrl },
- "ebics-connection",
- );
- await LibeufinNexusApi.fetchAccounts(
- { baseUrl: this.nexusBaseUrl },
- "ebics-connection",
- );
- await LibeufinNexusApi.importConnectionAccount(
- { baseUrl: this.nexusBaseUrl },
- "ebics-connection", // connection name
- accountName, // offered account label
- `${accountName}-nexus-label`, // bank account label at Nexus
- );
- await LibeufinNexusApi.createTwgFacade(
- { baseUrl: this.nexusBaseUrl },
- {
- name: "exchange-facade",
- connectionName: "ebics-connection",
- accountName: `${accountName}-nexus-label`,
- currency: "EUR",
- reserveTransferLevel: "report",
- },
- );
- await LibeufinNexusApi.postPermission(
- { baseUrl: this.nexusBaseUrl },
- {
- action: "grant",
- permission: {
- subjectId: accountName,
- subjectType: "user",
- resourceType: "facade",
- resourceId: "exchange-facade", // facade name
- permissionName: "facade.talerWireGateway.transfer",
- },
- },
- );
- await LibeufinNexusApi.postPermission(
- { baseUrl: this.nexusBaseUrl },
- {
- action: "grant",
- permission: {
- subjectId: accountName,
- subjectType: "user",
- resourceType: "facade",
- resourceId: "exchange-facade", // facade name
- permissionName: "facade.talerWireGateway.history",
- },
- },
- );
- // Set fetch task.
- await LibeufinNexusApi.postTask(
- { baseUrl: this.nexusBaseUrl },
- `${accountName}-nexus-label`,
- {
- name: "wirewatch-task",
- cronspec: "* * *",
- type: "fetch",
- params: {
- level: "all",
- rangeType: "all",
- },
- },
- );
- await LibeufinNexusApi.postTask(
- { baseUrl: this.nexusBaseUrl },
- `${accountName}-nexus-label`,
- {
- name: "aggregator-task",
- cronspec: "* * *",
- type: "submit",
- params: {},
- },
- );
- let facadesResp = await LibeufinNexusApi.getAllFacades({
- baseUrl: this.nexusBaseUrl,
- });
- let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo(
- "admin",
- "secret",
- { baseUrl: this.bankAccessApiBaseUrl },
- accountName, // bank account label.
- );
- return {
- accountName: accountName,
- accountPassword: password,
- accountPaytoUri: accountInfoResp.data.paytoUri,
- wireGatewayApiBaseUrl: facadesResp.data.facades[0].baseUrl,
- };
- }
-
- async start(): Promise<void> {
- /**
- * Because many test cases try to create a Exchange bank
- * account _before_ starting the bank (Pybank did it only via
- * the config), it is possible that at this point Sandbox and
- * Nexus are already running. Hence, this method only launches
- * them if they weren't launched earlier.
- */
-
- // Only go ahead if BOTH aren't running.
- if (this.sandboxProc || this.nexusProc) {
- logger.info("Nexus or Sandbox already running, not taking any action.");
- return;
- }
- await sh(
- this.globalTestState,
- "libeufin-sandbox-config-demobank",
- `libeufin-sandbox config --currency=${this.bankConfig.currency} default`,
- {
- ...process.env,
- LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
- LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
- },
- );
- this.sandboxProc = this.globalTestState.spawnService(
- "libeufin-sandbox",
- ["serve", "--port", `${this.port}`],
- "libeufin-sandbox",
- {
- ...process.env,
- LIBEUFIN_SANDBOX_DB_CONNECTION: this.sandboxDbConn,
- LIBEUFIN_SANDBOX_ADMIN_PASSWORD: "secret",
- },
- );
- await runCommand(
- this.globalTestState,
- "libeufin-nexus-superuser",
- "libeufin-nexus",
- ["superuser", "admin", "--password", "test"],
- {
- ...process.env,
- LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
- },
- );
- this.nexusProc = this.globalTestState.spawnService(
- "libeufin-nexus",
- ["serve", "--port", `${this.nexusPort}`],
- "libeufin-nexus",
- {
- ...process.env,
- LIBEUFIN_NEXUS_DB_CONNECTION: this.nexusDbConn,
- },
- );
- // need to wait here, because at this point
- // a Ebics host needs to be created (RESTfully)
- await this.pingUntilAvailable();
- LibeufinSandboxApi.createEbicsHost(
- { baseUrl: this.baseUrlNetloc },
- "talertestEbicsHost",
- );
- }
-
- async pingUntilAvailable(): Promise<void> {
- await pingProc(
- this.sandboxProc,
- `http://localhost:${this.bankConfig.httpPort}`,
- "libeufin-sandbox",
- );
- await pingProc(
- this.nexusProc,
- `${this.nexusBaseUrl}/config`,
- "libeufin-nexus",
- );
- }
-}
-
-/**
* Implementation of the bank service using the "taler-fakebank-run" tool.
*/
export class FakebankService
@@ -1152,6 +864,9 @@ export class ExchangeService implements ExchangeServiceInterface {
"currency_round_unit",
e.roundUnit ?? `${e.currency}:0.01`,
);
+ // Set to a high value to not break existing test cases where the merchant
+ // would cover all fees.
+ config.setString("exchange", "STEFAN_ABS", `${e.currency}:1`);
config.setString(
"exchange",
"revocation_dir",
@@ -1636,20 +1351,30 @@ export interface DeleteTippingReserveArgs {
purge?: boolean;
}
+/**
+ * Default HTTP client handle for the integration test harness.
+ */
+export const harnessHttpLib = createPlatformHttpLib({
+ allowHttp: true,
+ enableThrottling: false,
+});
+
export class MerchantApiClient {
constructor(
private baseUrl: string,
public readonly auth: MerchantAuthConfiguration,
) {}
- // FIXME: Migrate everything to this in favor of axios
- http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });
+ httpClient = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });
async changeAuth(auth: MerchantAuthConfiguration): Promise<void> {
const url = new URL("private/auth", this.baseUrl);
- await axios.post(url.href, auth, {
+ const res = await this.httpClient.fetch(url.href, {
+ method: "POST",
+ body: auth,
headers: this.makeAuthHeader(),
});
+ await expectSuccessResponseOrThrow(res);
}
async deleteTippingReserve(req: DeleteTippingReserveArgs): Promise<void> {
@@ -1657,7 +1382,8 @@ export class MerchantApiClient {
if (req.purge) {
url.searchParams.set("purge", "YES");
}
- const resp = await axios.delete(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
+ method: "DELETE",
headers: this.makeAuthHeader(),
});
logger.info(`delete status: ${resp.status}`);
@@ -1668,7 +1394,7 @@ export class MerchantApiClient {
req: CreateMerchantTippingReserveRequest,
): Promise<MerchantReserveCreateConfirmation> {
const url = new URL("private/reserves", this.baseUrl);
- const resp = await this.http.fetch(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
method: "POST",
body: req,
headers: this.makeAuthHeader(),
@@ -1684,7 +1410,7 @@ export class MerchantApiClient {
console.log(this.makeAuthHeader());
const url = new URL("private", this.baseUrl);
logger.info(`request url ${url.href}`);
- const resp = await this.http.fetch(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
method: "GET",
headers: this.makeAuthHeader(),
});
@@ -1694,7 +1420,7 @@ export class MerchantApiClient {
async getPrivateTipReserves(): Promise<TippingReserveStatus> {
console.log(this.makeAuthHeader());
const url = new URL("private/reserves", this.baseUrl);
- const resp = await this.http.fetch(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
method: "GET",
headers: this.makeAuthHeader(),
});
@@ -1704,33 +1430,37 @@ export class MerchantApiClient {
async deleteInstance(instanceId: string) {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
- await axios.delete(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
+ method: "DELETE",
headers: this.makeAuthHeader(),
});
+ await expectSuccessResponseOrThrow(resp);
}
async createInstance(req: MerchantInstanceConfig): Promise<void> {
const url = new URL("management/instances", this.baseUrl);
- await axios.post(url.href, req, {
+ await this.httpClient.fetch(url.href, {
+ method: "POST",
+ body: req,
headers: this.makeAuthHeader(),
});
}
async getInstances(): Promise<MerchantInstancesResponse> {
const url = new URL("management/instances", this.baseUrl);
- const resp = await axios.get(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
headers: this.makeAuthHeader(),
});
- return resp.data;
+ return resp.json();
}
async getInstanceFullDetails(instanceId: string): Promise<any> {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
try {
- const resp = await axios.get(url.href, {
+ const resp = await this.httpClient.fetch(url.href, {
headers: this.makeAuthHeader(),
});
- return resp.data;
+ return resp.json();
} catch (e) {
throw e;
}
@@ -1750,6 +1480,8 @@ export class MerchantApiClient {
/**
* FIXME: This should be deprecated in favor of MerchantApiClient
+ *
+ * @deprecated use MerchantApiClient instead
*/
export namespace MerchantPrivateApi {
export async function createOrder(
@@ -1760,10 +1492,15 @@ export namespace MerchantPrivateApi {
): Promise<MerchantPostOrderResponse> {
const baseUrl = merchantService.makeInstanceBaseUrl(instanceName);
let url = new URL("private/orders", baseUrl);
- const resp = await axios.post(url.href, req, {
+ const resp = await harnessHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
headers: withAuthorization as Record<string, string>,
});
- return codecForMerchantPostOrderResponse().decode(resp.data);
+ return readSuccessResponseJsonOrThrow(
+ resp,
+ codecForMerchantPostOrderResponse(),
+ );
}
export async function createTemplate(
@@ -1774,7 +1511,9 @@ export namespace MerchantPrivateApi {
) {
const baseUrl = merchantService.makeInstanceBaseUrl(instanceName);
let url = new URL("private/templates", baseUrl);
- const resp = await axios.post(url.href, req, {
+ const resp = await harnessHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
headers: withAuthorization as Record<string, string>,
});
if (resp.status !== 204) {
@@ -1794,10 +1533,13 @@ export namespace MerchantPrivateApi {
if (query.sessionId) {
reqUrl.searchParams.set("session_id", query.sessionId);
}
- const resp = await axios.get(reqUrl.href, {
+ const resp = await harnessHttpLib.fetch(reqUrl.href, {
headers: withAuthorization as Record<string, string>,
});
- return codecForMerchantOrderPrivateStatusResponse().decode(resp.data);
+ return readSuccessResponseJsonOrThrow(
+ resp,
+ codecForMerchantOrderPrivateStatusResponse(),
+ );
}
export async function giveRefund(
@@ -1813,12 +1555,16 @@ export namespace MerchantPrivateApi {
`private/orders/${r.orderId}/refund`,
merchantService.makeInstanceBaseUrl(r.instance),
);
- const resp = await axios.post(reqUrl.href, {
- refund: r.amount,
- reason: r.justification,
+ const resp = await harnessHttpLib.fetch(reqUrl.href, {
+ method: "POST",
+ body: {
+ refund: r.amount,
+ reason: r.justification,
+ },
});
+ const respBody = await resp.json();
return {
- talerRefundUri: resp.data.taler_refund_uri,
+ talerRefundUri: respBody.taler_refund_uri,
};
}
@@ -1830,9 +1576,9 @@ export namespace MerchantPrivateApi {
`private/reserves`,
merchantService.makeInstanceBaseUrl(instance),
);
- const resp = await axios.get(reqUrl.href);
+ const resp = await harnessHttpLib.fetch(reqUrl.href);
// FIXME: validate
- return resp.data;
+ return resp.json();
}
export async function giveTip(
@@ -1844,9 +1590,12 @@ export namespace MerchantPrivateApi {
`private/tips`,
merchantService.makeInstanceBaseUrl(instance),
);
- const resp = await axios.post(reqUrl.href, req);
+ const resp = await harnessHttpLib.fetch(reqUrl.href, {
+ method: "POST",
+ body: req,
+ });
// FIXME: validate
- return resp.data;
+ return resp.json();
}
}
@@ -2052,7 +1801,12 @@ export class MerchantService implements MerchantServiceInterface {
instanceConfig.defaultPayDelay ??
Duration.toTalerProtocolDuration(Duration.getForever()),
};
- await axios.post(url, body);
+ const httpLib = createPlatformHttpLib({
+ allowHttp: true,
+ enableThrottling: false,
+ });
+ const resp = await httpLib.fetch(url, { method: "POST", body });
+ await expectSuccessResponseOrThrow(resp);
}
makeInstanceBaseUrl(instanceName?: string): string {
diff --git a/packages/taler-harness/src/harness/libeufin-apis.ts b/packages/taler-harness/src/harness/libeufin-apis.ts
index cb9acdaa4..3c57eee07 100644
--- a/packages/taler-harness/src/harness/libeufin-apis.ts
+++ b/packages/taler-harness/src/harness/libeufin-apis.ts
@@ -6,8 +6,21 @@
*/
import { URL } from "@gnu-taler/taler-util";
-import axiosImp from "axios";
-const axios = axiosImp.default;
+import {
+ createPlatformHttpLib,
+ makeBasicAuthHeader,
+} from "@gnu-taler/taler-util/http";
+import {
+ LibeufinNexusTransactions,
+ LibeufinSandboxAdminBankAccountBalance,
+ NexusBankConnections,
+ NexusFacadeListResponse,
+ NexusGetPermissionsResponse,
+ NexusNewTransactionsInfo,
+ NexusTask,
+ NexusTaskCollection,
+ NexusUserResponse,
+} from "./libeufin.js";
export interface LibeufinSandboxServiceInterface {
baseUrl: string;
@@ -163,30 +176,13 @@ export interface LibeufinSandboxAddIncomingRequest {
direction: string;
}
+const libeufinHttpLib = createPlatformHttpLib();
+
/**
* APIs spread across Legacy and Access, it is therefore
* the "base URL" relative to which API every call addresses.
*/
export namespace LibeufinSandboxApi {
- // Need Access API base URL.
- export async function demobankAccountInfo(
- username: string,
- password: string,
- libeufinSandboxService: LibeufinSandboxServiceInterface,
- accountLabel: string,
- ) {
- let url = new URL(
- `accounts/${accountLabel}`,
- libeufinSandboxService.baseUrl,
- );
- return await axios.get(url.href, {
- auth: {
- username: username,
- password: password,
- },
- });
- }
-
// Creates one bank account via the Access API.
// Need the /demobanks/$id/access-api as the base URL
export async function createDemobankAccount(
@@ -194,12 +190,15 @@ export namespace LibeufinSandboxApi {
password: string,
libeufinSandboxService: LibeufinSandboxServiceInterface,
iban: string | null = null,
- ) {
+ ): Promise<void> {
let url = new URL("testing/register", libeufinSandboxService.baseUrl);
- await axios.post(url.href, {
- username: username,
- password: password,
- iban: iban,
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: {
+ username: username,
+ password: password,
+ iban: iban,
+ },
});
}
// Need /demobanks/$id as the base URL
@@ -209,75 +208,57 @@ export namespace LibeufinSandboxApi {
libeufinSandboxService: LibeufinSandboxServiceInterface,
username: string = "admin",
password: string = "secret",
- ) {
+ ): Promise<void> {
// baseUrl should already be pointed to one demobank.
let url = new URL("ebics/subscribers", libeufinSandboxService.baseUrl);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: {
userID: req.userID,
hostID: req.hostID,
partnerID: req.partnerID,
demobankAccountLabel: demobankAccountLabel,
},
- {
- auth: {
- username: "admin",
- password: "secret",
- },
- },
- );
+ });
}
export async function rotateKeys(
libeufinSandboxService: LibeufinSandboxServiceInterface,
hostID: string,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/ebics/hosts/${hostID}/rotate-keys`, baseUrl);
- await axios.post(
- url.href,
- {},
- {
- auth: {
- username: "admin",
- password: "secret",
- },
- },
- );
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: {},
+ });
}
export async function createEbicsHost(
libeufinSandboxService: LibeufinSandboxServiceInterface,
hostID: string,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/hosts", baseUrl);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: {
hostID,
ebicsVersion: "2.5",
},
- {
- auth: {
- username: "admin",
- password: "secret",
- },
- },
- );
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ });
}
export async function createBankAccount(
libeufinSandboxService: LibeufinSandboxServiceInterface,
req: BankAccountInfo,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/bank-accounts/${req.label}`, baseUrl);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
@@ -288,14 +269,13 @@ export namespace LibeufinSandboxApi {
export async function createEbicsSubscriber(
libeufinSandboxService: LibeufinSandboxServiceInterface,
req: CreateEbicsSubscriberRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/subscribers", baseUrl);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
@@ -306,14 +286,13 @@ export namespace LibeufinSandboxApi {
export async function createEbicsBankAccount(
libeufinSandboxService: LibeufinSandboxServiceInterface,
req: CreateEbicsBankAccountRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/ebics/bank-accounts", baseUrl);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
@@ -321,17 +300,16 @@ export namespace LibeufinSandboxApi {
libeufinSandboxService: LibeufinSandboxServiceInterface,
accountLabel: string,
req: SimulateIncomingTransactionRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(
`admin/bank-accounts/${accountLabel}/simulate-incoming-transaction`,
baseUrl,
);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ body: req,
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
@@ -344,13 +322,10 @@ export namespace LibeufinSandboxApi {
`admin/bank-accounts/${accountLabel}/transactions`,
baseUrl,
);
- const res = await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ const res = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
- return res.data as SandboxAccountTransactions;
+ return (await res.json()) as SandboxAccountTransactions;
}
export async function getCamt053(
@@ -359,61 +334,50 @@ export namespace LibeufinSandboxApi {
): Promise<any> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL("admin/payments/camt", baseUrl);
- return await axios.post(
- url.href,
- {
+ return await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
bankaccount: accountLabel,
type: 53,
},
- {
- auth: {
- username: "admin",
- password: "secret",
- },
- },
- );
+ });
}
export async function getAccountInfoWithBalance(
libeufinSandboxService: LibeufinSandboxServiceInterface,
accountLabel: string,
- ): Promise<any> {
+ ): Promise<LibeufinSandboxAdminBankAccountBalance> {
const baseUrl = libeufinSandboxService.baseUrl;
let url = new URL(`admin/bank-accounts/${accountLabel}`, baseUrl);
- return await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "secret",
- },
+ const res = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ return res.json();
}
}
export namespace LibeufinNexusApi {
export async function getAllConnections(
nexus: LibeufinNexusServiceInterface,
- ): Promise<any> {
+ ): Promise<NexusBankConnections> {
let url = new URL("bank-connections", nexus.baseUrl);
- const res = await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ const res = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
- return res;
+ return res.json();
}
export async function deleteBankConnection(
libeufinNexusService: LibeufinNexusServiceInterface,
req: DeleteBankConnectionRequest,
- ): Promise<any> {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("bank-connections/delete-connection", baseUrl);
- return await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: req,
});
}
@@ -423,9 +387,10 @@ export namespace LibeufinNexusApi {
): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("bank-connections", baseUrl);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
source: "new",
type: "ebics",
name: req.name,
@@ -437,13 +402,7 @@ export namespace LibeufinNexusApi {
systemID: req.systemID,
},
},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ });
}
export async function getBankAccount(
@@ -452,12 +411,10 @@ export namespace LibeufinNexusApi {
): Promise<any> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`bank-accounts/${accountName}`, baseUrl);
- return await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ return resp.json();
}
export async function submitInitiatedPayment(
@@ -470,16 +427,11 @@ export namespace LibeufinNexusApi {
`bank-accounts/${accountName}/payment-initiations/${paymentId}/submit`,
baseUrl,
);
- await axios.post(
- url.href,
- {},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {},
+ });
}
export async function fetchAccounts(
@@ -491,16 +443,11 @@ export namespace LibeufinNexusApi {
`bank-connections/${connectionName}/fetch-accounts`,
baseUrl,
);
- await axios.post(
- url.href,
- {},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {},
+ });
}
export async function importConnectionAccount(
@@ -514,37 +461,27 @@ export namespace LibeufinNexusApi {
`bank-connections/${connectionName}/import-account`,
baseUrl,
);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
offeredAccountId,
nexusBankAccountId,
},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ });
}
export async function connectBankConnection(
libeufinNexusService: LibeufinNexusServiceInterface,
connectionName: string,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`bank-connections/${connectionName}/connect`, baseUrl);
- await axios.post(
- url.href,
- {},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {},
+ });
}
export async function getPaymentInitiations(
@@ -558,43 +495,33 @@ export namespace LibeufinNexusApi {
`/bank-accounts/${accountName}/payment-initiations`,
baseUrl,
);
- let response = await axios.get(url.href, {
- auth: {
- username: username,
- password: password,
- },
+ let response = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ const respJson = await response.json();
console.log(
`Payment initiations of: ${accountName}`,
- JSON.stringify(response.data, null, 2),
+ JSON.stringify(respJson, null, 2),
);
}
- export async function getConfig(
- libeufinNexusService: LibeufinNexusServiceInterface,
- ): Promise<void> {
- const baseUrl = libeufinNexusService.baseUrl;
- let url = new URL(`/config`, baseUrl);
- let response = await axios.get(url.href);
- }
-
// Uses the Anastasis API to get a list of transactions.
export async function getAnastasisTransactions(
libeufinNexusService: LibeufinNexusServiceInterface,
anastasisBaseUrl: string,
+ // FIXME: Nail down type!
params: {}, // of the request: {delta: 5, ..}
username: string = "admin",
password: string = "test",
): Promise<any> {
let url = new URL("history/incoming", anastasisBaseUrl);
- let response = await axios.get(url.href, {
- params: params,
- auth: {
- username: username,
- password: password,
- },
+ for (const [k, v] of Object.entries(params)) {
+ url.searchParams.set(k, String(v));
+ }
+ let response = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
- return response;
+ return response.json();
}
// FIXME: this function should return some structured
@@ -604,16 +531,13 @@ export namespace LibeufinNexusApi {
accountName: string,
username: string = "admin",
password: string = "test",
- ): Promise<any> {
+ ): Promise<LibeufinNexusTransactions> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${accountName}/transactions`, baseUrl);
- let response = await axios.get(url.href, {
- auth: {
- username: username,
- password: password,
- },
+ let response = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
- return response;
+ return response.json();
}
export async function fetchTransactions(
@@ -623,25 +547,21 @@ export namespace LibeufinNexusApi {
level: string = "report",
username: string = "admin",
password: string = "test",
- ): Promise<any> {
+ ): Promise<NexusNewTransactionsInfo> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(
`/bank-accounts/${accountName}/fetch-transactions`,
baseUrl,
);
- return await axios.post(
- url.href,
- {
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
rangeType: rangeType,
level: level,
},
- {
- auth: {
- username: username,
- password: password,
- },
- },
- );
+ });
+ return resp.json();
}
export async function changePassword(
@@ -649,97 +569,109 @@ export namespace LibeufinNexusApi {
username: string,
req: UpdateNexusUserRequest,
auth: NexusAuth,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/users/${username}/password`, baseUrl);
- await axios.post(url.href, req, auth);
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: req,
+ });
}
export async function getUser(
libeufinNexusService: LibeufinNexusServiceInterface,
auth: NexusAuth,
- ): Promise<any> {
+ ): Promise<NexusUserResponse> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/user`, baseUrl);
- return await axios.get(url.href, auth);
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ });
+ return resp.json();
}
export async function createUser(
libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateNexusUserRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/users`, baseUrl);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: req,
});
}
export async function getAllPermissions(
libeufinNexusService: LibeufinNexusServiceInterface,
- ): Promise<any> {
+ ): Promise<NexusGetPermissionsResponse> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/permissions`, baseUrl);
- return await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ return resp.json();
}
export async function postPermission(
libeufinNexusService: LibeufinNexusServiceInterface,
req: PostNexusPermissionRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/permissions`, baseUrl);
- await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: req,
+ });
+ }
+
+ export async function getAllTasks(
+ libeufinNexusService: LibeufinNexusServiceInterface,
+ bankAccountName: string,
+ ): Promise<NexusTaskCollection> {
+ const baseUrl = libeufinNexusService.baseUrl;
+ let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl);
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ return resp.json();
}
- export async function getTasks(
+ export async function getTask(
libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string,
// When void, the request returns the list of all the
// tasks under this bank account.
- taskName: string | void,
- ): Promise<any> {
+ taskName: string,
+ ): Promise<NexusTask> {
const baseUrl = libeufinNexusService.baseUrl;
- let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl);
+ let url = new URL(
+ `/bank-accounts/${bankAccountName}/schedule/${taskName}`,
+ baseUrl,
+ );
if (taskName) url = new URL(taskName, `${url.href}/`);
-
- // It's caller's responsibility to interpret the response.
- return await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ return resp.json();
}
export async function deleteTask(
libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string,
taskName: string,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(
`/bank-accounts/${bankAccountName}/schedule/${taskName}`,
baseUrl,
);
- await axios.delete(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "DELETE",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
@@ -747,53 +679,50 @@ export namespace LibeufinNexusApi {
libeufinNexusService: LibeufinNexusServiceInterface,
bankAccountName: string,
req: PostNexusTaskRequest,
- ): Promise<any> {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`/bank-accounts/${bankAccountName}/schedule`, baseUrl);
- return await axios.post(url.href, req, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: req,
});
}
export async function deleteFacade(
libeufinNexusService: LibeufinNexusServiceInterface,
facadeName: string,
- ): Promise<any> {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(`facades/${facadeName}`, baseUrl);
- return await axios.delete(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ await libeufinHttpLib.fetch(url.href, {
+ method: "DELETE",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
}
export async function getAllFacades(
libeufinNexusService: LibeufinNexusServiceInterface,
- ): Promise<any> {
+ ): Promise<NexusFacadeListResponse> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl);
- return await axios.get(url.href, {
- auth: {
- username: "admin",
- password: "test",
- },
+ const resp = await libeufinHttpLib.fetch(url.href, {
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
});
+ // FIXME: Just return validated, typed response here!
+ return resp.json();
}
export async function createAnastasisFacade(
libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateAnastasisFacadeRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
name: req.name,
type: "anastasis",
config: {
@@ -803,24 +732,19 @@ export namespace LibeufinNexusApi {
reserveTransferLevel: req.reserveTransferLevel,
},
},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ });
}
export async function createTwgFacade(
libeufinNexusService: LibeufinNexusServiceInterface,
req: CreateTalerWireGatewayFacadeRequest,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL("facades", baseUrl);
- await axios.post(
- url.href,
- {
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {
name: req.name,
type: "taler-wire-gateway",
config: {
@@ -830,33 +754,22 @@ export namespace LibeufinNexusApi {
reserveTransferLevel: req.reserveTransferLevel,
},
},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ });
}
export async function submitAllPaymentInitiations(
libeufinNexusService: LibeufinNexusServiceInterface,
accountId: string,
- ) {
+ ): Promise<void> {
const baseUrl = libeufinNexusService.baseUrl;
let url = new URL(
`/bank-accounts/${accountId}/submit-all-payment-initiations`,
baseUrl,
);
- await axios.post(
- url.href,
- {},
- {
- auth: {
- username: "admin",
- password: "test",
- },
- },
- );
+ await libeufinHttpLib.fetch(url.href, {
+ method: "POST",
+ headers: { Authorization: makeBasicAuthHeader("admin", "secret") },
+ body: {},
+ });
}
}
diff --git a/packages/taler-harness/src/harness/libeufin.ts b/packages/taler-harness/src/harness/libeufin.ts
index 8fd276fad..9f3e7a5a0 100644
--- a/packages/taler-harness/src/harness/libeufin.ts
+++ b/packages/taler-harness/src/harness/libeufin.ts
@@ -26,39 +26,32 @@
/**
* Imports.
*/
-import axios from "axios";
-import { URL, Logger } from "@gnu-taler/taler-util";
+import { AmountString, Logger } from "@gnu-taler/taler-util";
import {
- GlobalTestState,
DbInfo,
- pingProc,
+ GlobalTestState,
ProcessWrapper,
+ getRandomIban,
+ pingProc,
runCommand,
setupDb,
sh,
- getRandomIban,
} from "../harness/harness.js";
import {
- LibeufinSandboxApi,
- LibeufinNexusApi,
+ CreateAnastasisFacadeRequest,
CreateEbicsBankAccountRequest,
- LibeufinSandboxServiceInterface,
- CreateTalerWireGatewayFacadeRequest,
- SimulateIncomingTransactionRequest,
- SandboxAccountTransactions,
- DeleteBankConnectionRequest,
CreateEbicsBankConnectionRequest,
- UpdateNexusUserRequest,
- NexusAuth,
- CreateAnastasisFacadeRequest,
- PostNexusTaskRequest,
- PostNexusPermissionRequest,
CreateNexusUserRequest,
+ CreateTalerWireGatewayFacadeRequest,
+ LibeufinNexusApi,
+ LibeufinSandboxApi,
+ LibeufinSandboxServiceInterface,
+ PostNexusPermissionRequest,
} from "../harness/libeufin-apis.js";
const logger = new Logger("libeufin.ts");
-export { LibeufinSandboxApi, LibeufinNexusApi };
+export { LibeufinNexusApi, LibeufinSandboxApi };
export interface LibeufinServices {
libeufinSandbox: LibeufinSandboxService;
@@ -76,7 +69,7 @@ export interface LibeufinNexusConfig {
databaseJdbcUri: string;
}
-interface LibeufinNexusMoneyMovement {
+export interface LibeufinNexusMoneyMovement {
amount: string;
creditDebitIndicator: string;
details: {
@@ -103,11 +96,11 @@ interface LibeufinNexusMoneyMovement {
};
}
-interface LibeufinNexusBatches {
+export interface LibeufinNexusBatches {
batchTransactions: Array<LibeufinNexusMoneyMovement>;
}
-interface LibeufinNexusTransaction {
+export interface LibeufinNexusTransaction {
amount: string;
creditDebitIndicator: string;
status: string;
@@ -118,7 +111,7 @@ interface LibeufinNexusTransaction {
batches: Array<LibeufinNexusBatches>;
}
-interface LibeufinNexusTransactions {
+export interface LibeufinNexusTransactions {
transactions: Array<LibeufinNexusTransaction>;
}
@@ -182,6 +175,146 @@ export interface LibeufinPreparedPaymentDetails {
nexusBankAccountName: string;
}
+export interface NexusBankConnection {
+ // connection type. For example "ebics".
+ type: string;
+
+ // connection name as given by the user at
+ // the moment of creation.
+ name: string;
+}
+
+export interface NexusBankConnections {
+ bankConnections: NexusBankConnection[];
+}
+
+export interface FacadeShowInfo {
+ // Name of the facade, same as the "fcid" parameter.
+ name: string;
+
+ // Type of the facade.
+ // For example, "taler-wire-gateway".
+ type: string;
+
+ // Bas URL of the facade.
+ baseUrl: string;
+
+ // details depending on the facade type.
+ config: any;
+}
+
+export interface FetchParams {
+ // Because transactions are delivered by banks in "batches",
+ // then every batch can have different qualities. This value
+ // lets the request specify which type of batch ought to be
+ // returned. Currently, the following two type are supported:
+ //
+ // 'report': typically includes only non booked transactions.
+ // 'statement': typically includes only booked transactions.
+ level: "report" | "statement" | "all";
+
+ // This type indicates the time range of the query.
+ // It allows the following values:
+ //
+ // 'latest': retrieves the last transactions from the bank.
+ // If there are older unread transactions, those will *not*
+ // be downloaded.
+ //
+ // 'all': retrieves all the transactions from the bank,
+ // until the oldest.
+ //
+ // 'previous-days': currently *not* implemented, it will allow
+ // the request to download transactions from
+ // today until N days before.
+ //
+ // 'since-last': retrieves all the transactions since the last
+ // time one was downloaded.
+ //
+ rangeType: "latest" | "all" | "previous-days" | "since-last";
+}
+
+export interface NexusTask {
+ // The resource being impacted by this operation.
+ // Typically a (Nexus) bank account being fetched
+ // or whose payments are submitted. In this cases,
+ // this value is the "bank-account" constant.
+ resourceType: string;
+ // Name of the resource. In case of "bank-account", that
+ // is the name under which the bank account was imported
+ // from the bank.
+ resourceId: string;
+ // Task name, equals 'taskId'
+ taskName: string;
+ // Values allowed are "fetch" or "submit".
+ taskType: string;
+ // FIXME: describe.
+ taskCronSpec: string;
+ // Only meaningful for "fetch" types.
+ taskParams: FetchParams;
+ // Timestamp in secons when the next iteration will run.
+ nextScheduledExecutionSec: number;
+ // Timestamp in seconds when the previous iteration ran.
+ prevScheduledExecutionSec: number;
+}
+
+export interface NexusNewTransactionsInfo {
+ // How many transactions are new to Nexus.
+ newTransactions: number;
+ // How many transactions got downloaded by the request.
+ // Note that a transaction can be downloaded multiple
+ // times but only counts as new once.
+ downloadedTransactions: number;
+}
+
+
+export interface NexusUserResponse {
+ // User name
+ username: string;
+
+ // Is this a super user?
+ superuser: boolean;
+}
+
+export interface NexusTaskShortInfo {
+ cronspec: string;
+ type: "fetch" | "submit";
+ params: FetchParams;
+}
+
+export interface NexusTaskCollection {
+ // This field can contain *multiple* objects of the type sampled below.
+ schedule: {
+ [taskName: string]: NexusTaskShortInfo;
+ };
+}
+
+export interface NexusFacadeListResponse {
+ facades: FacadeShowInfo[];
+}
+
+export interface LibeufinSandboxAdminBankAccountBalance {
+ // Balance in the $currency:$amount format.
+ balance: AmountString;
+ // IBAN of the bank account identified by $accountLabel
+ iban: string;
+ // BIC of the bank account identified by $accountLabel
+ bic: string;
+ // Mentions $accountLabel
+ label: string;
+}
+
+export interface LibeufinPermission {
+ subjectType: string;
+ subjectId: string;
+ resourceType: string;
+ resourceId: string;
+ permissionName: string;
+}
+
+export interface NexusGetPermissionsResponse {
+ permissions: LibeufinPermission[];
+}
+
export class LibeufinSandboxService implements LibeufinSandboxServiceInterface {
static async create(
gc: GlobalTestState,