diff options
Diffstat (limited to 'packages/taler-harness')
| -rw-r--r-- | packages/taler-harness/src/harness/harness.ts | 54 | ||||
| -rw-r--r-- | packages/taler-harness/src/harness/libeufin-apis.ts | 7 | ||||
| -rw-r--r-- | packages/taler-harness/src/index.ts | 125 | 
3 files changed, 180 insertions, 6 deletions
| diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 6168ea0b7..5733e776b 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -1436,12 +1436,20 @@ export interface MerchantServiceInterface {    readonly name: string;  } +export interface DeleteTippingReserveArgs { +  reservePub: string; +  purge?: boolean; +} +  export class MerchantApiClient {    constructor(      private baseUrl: string,      public readonly auth: MerchantAuthConfiguration,    ) {} +  // FIXME: Migrate everything to this in favor of axios +  http = createPlatformHttpLib(); +    async changeAuth(auth: MerchantAuthConfiguration): Promise<void> {      const url = new URL("private/auth", this.baseUrl);      await axios.post(url.href, auth, { @@ -1449,6 +1457,51 @@ export class MerchantApiClient {      });    } +  async deleteTippingReserve(req: DeleteTippingReserveArgs): Promise<void> { +    const url = new URL(`private/reserves/${req.reservePub}`, this.baseUrl); +    if (req.purge) { +      url.searchParams.set("purge", "YES"); +    } +    const resp = await axios.delete(url.href, { +      headers: this.makeAuthHeader(), +    }); +    logger.info(`delete status: ${resp.status}`); +    return; +  } + +  async createTippingReserve( +    req: CreateMerchantTippingReserveRequest, +  ): Promise<CreateMerchantTippingReserveConfirmation> { +    const url = new URL("private/reserves", this.baseUrl); +    const resp = await axios.post(url.href, req, { +      headers: this.makeAuthHeader(), +    }); +    // FIXME: validate +    return resp.data; +  } + +  async getPrivateInstanceInfo(): Promise<any> { +    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, { +      method: "GET", +      headers: this.makeAuthHeader(), +    }); +    return await resp.json(); +  } + +  async getPrivateTipReserves(): Promise<TippingReserveStatus> { +    console.log(this.makeAuthHeader()); +    const url = new URL("private/reserves", this.baseUrl); +    const resp = await this.http.fetch(url.href, { +      method: "GET", +      headers: this.makeAuthHeader(), +    }); +    // FIXME: Validate! +    return await resp.json(); +  } +    async deleteInstance(instanceId: string) {      const url = new URL(`management/instances/${instanceId}`, this.baseUrl);      await axios.delete(url.href, { @@ -1578,6 +1631,7 @@ export namespace MerchantPrivateApi {        `private/reserves`,        merchantService.makeInstanceBaseUrl(instance),      ); +    // FIXME: Don't use axios!      const resp = await axios.post(reqUrl.href, req);      // FIXME: validate      return resp.data; diff --git a/packages/taler-harness/src/harness/libeufin-apis.ts b/packages/taler-harness/src/harness/libeufin-apis.ts index a6abe3466..4ef588fb5 100644 --- a/packages/taler-harness/src/harness/libeufin-apis.ts +++ b/packages/taler-harness/src/harness/libeufin-apis.ts @@ -7,7 +7,8 @@  import axiosImp from "axios";  const axios = axiosImp.default; -import { Logger, URL } from "@gnu-taler/taler-util"; +import { AmountString, Logger, URL } from "@gnu-taler/taler-util"; +import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";  export interface LibeufinSandboxServiceInterface {    baseUrl: string; @@ -163,10 +164,6 @@ export interface LibeufinSandboxAddIncomingRequest {    direction: string;  } -function getRandomString(): string { -  return Math.random().toString(36).substring(2); -} -  /**   * APIs spread across Legacy and Access, it is therefore   * the "base URL" relative to which API every call addresses. diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 14b8a4302..370550420 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -22,10 +22,13 @@ import fs from "fs";  import os from "os";  import path from "path";  import { +  addPaytoQueryParams,    Amounts,    Configuration,    decodeCrock, +  j2s,    Logger, +  parsePaytoUri,    rsaBlind,    setGlobalLogLevelFromString,  } from "@gnu-taler/taler-util"; @@ -33,11 +36,18 @@ import { runBench1 } from "./bench1.js";  import { runBench2 } from "./bench2.js";  import { runBench3 } from "./bench3.js";  import { runEnv1 } from "./env1.js"; -import { GlobalTestState, runTestWithState } from "./harness/harness.js"; +import { +  GlobalTestState, +  MerchantApiClient, +  MerchantPrivateApi, +  runTestWithState, +} from "./harness/harness.js";  import { getTestInfo, runTests } from "./integrationtests/testrunner.js";  import { lintExchangeDeployment } from "./lint.js";  import { runEnvFull } from "./env-full.js";  import { clk } from "@gnu-taler/taler-util/clk"; +import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; +import { BankAccessApiClient } from "@gnu-taler/taler-wallet-core";  const logger = new Logger("taler-harness:index.ts"); @@ -152,11 +162,124 @@ advancedCli      await runTestWithState(testState, runEnv1, "env1", true);    }); +const sandcastleCli = testingCli.subcommand("sandcastleArgs", "sandcastle", { +  help: "Subcommands for handling GNU Taler sandcastle deployments.", +}); +  const deploymentCli = testingCli.subcommand("deploymentArgs", "deployment", {    help: "Subcommands for handling GNU Taler deployments.",  });  deploymentCli +  .subcommand("tipTopup", "tip-topup") +  .requiredOption("merchantBaseUrl", ["--merchant-url"], clk.STRING) +  .requiredOption("exchangeBaseUrl", ["--exchange-url"], clk.STRING) +  .requiredOption("merchantApikey", ["--merchant-apikey"], clk.STRING) +  .requiredOption("bankAccessUrl", ["--bank-access-url"], clk.STRING) +  .requiredOption("bankAccount", ["--bank-account"], clk.STRING) +  .requiredOption("bankPassword", ["--bank-password"], clk.STRING) +  .requiredOption("wireMethod", ["--wire-method"], clk.STRING) +  .requiredOption("amount", ["--amount"], clk.STRING) +  .action(async (args) => { +    const amount = args.tipTopup.amount; + +    const merchantClient = new MerchantApiClient( +      args.tipTopup.merchantBaseUrl, +      { +        method: "token", +        token: args.tipTopup.merchantApikey, +      }, +    ); + +    const res = await merchantClient.getPrivateInstanceInfo(); +    console.log(res); + +    const tipReserveResp = await merchantClient.createTippingReserve({ +      exchange_url: args.tipTopup.exchangeBaseUrl, +      initial_balance: amount, +      wire_method: args.tipTopup.wireMethod, +    }); + +    console.log(tipReserveResp); + +    const bankAccessApiClient = new BankAccessApiClient({ +      baseUrl: args.tipTopup.bankAccessUrl, +      username: args.tipTopup.bankAccount, +      password: args.tipTopup.bankPassword, +    }); + +    const paytoUri = addPaytoQueryParams(tipReserveResp.payto_uri, { +      message: `tip-reserve ${tipReserveResp.reserve_pub}`, +    }); + +    console.log("payto URI:", paytoUri); + +    const transactions = await bankAccessApiClient.getTransactions(); +    console.log("transactions:", j2s(transactions)); + +    await bankAccessApiClient.createTransaction({ +      amount, +      paytoUri, +    }); +  }); + +deploymentCli +  .subcommand("tipCleanup", "tip-cleanup") +  .requiredOption("merchantBaseUrl", ["--merchant-url"], clk.STRING) +  .requiredOption("merchantApikey", ["--merchant-apikey"], clk.STRING) +  .flag("dryRun", ["--dry-run"]) +  .action(async (args) => { +    const merchantClient = new MerchantApiClient( +      args.tipCleanup.merchantBaseUrl, +      { +        method: "token", +        token: args.tipCleanup.merchantApikey, +      }, +    ); + +    const res = await merchantClient.getPrivateInstanceInfo(); +    console.log(res); + +    const tipRes = await merchantClient.getPrivateTipReserves(); +    console.log(tipRes); + +    for (const reserve of tipRes.reserves) { +      if (Amounts.isZero(reserve.exchange_initial_amount)) { +        if (args.tipCleanup.dryRun) { +          logger.info(`dry run, would purge reserve ${reserve}`); +        } else { +          await merchantClient.deleteTippingReserve({ +            reservePub: reserve.reserve_pub, +            purge: true, +          }); +        } +      } +    } + +    // FIXME: Now delete reserves that are not filled yet +  }); + +deploymentCli +  .subcommand("tipStatus", "tip-status") +  .requiredOption("merchantBaseUrl", ["--merchant-url"], clk.STRING) +  .requiredOption("merchantApikey", ["--merchant-apikey"], clk.STRING) +  .action(async (args) => { +    const merchantClient = new MerchantApiClient( +      args.tipStatus.merchantBaseUrl, +      { +        method: "token", +        token: args.tipStatus.merchantApikey, +      }, +    ); + +    const res = await merchantClient.getPrivateInstanceInfo(); +    console.log(res); + +    const tipRes = await merchantClient.getPrivateTipReserves(); +    console.log(j2s(tipRes)); +  }); + +deploymentCli    .subcommand("lintExchange", "lint-exchange", {      help: "Run checks on the exchange deployment.",    }) | 
