diff --git a/packages/taler-wallet-cli/src/integrationtests/harness.ts b/packages/taler-wallet-cli/src/integrationtests/harness.ts index cb8b59a5c..118bc35d4 100644 --- a/packages/taler-wallet-cli/src/integrationtests/harness.ts +++ b/packages/taler-wallet-cli/src/integrationtests/harness.ts @@ -1186,6 +1186,14 @@ export class MerchantApiClient { }); } + async createInstance(req: MerchantInstanceConfig): Promise { + const baseUrl = this.baseUrl; + const url = new URL("private/instances", baseUrl); + await axios.post(url.href, req, { + headers: this.makeAuthHeader(), + }); + } + async getInstances(): Promise { const url = new URL("private/instances", this.baseUrl); const resp = await axios.get(url.href, { @@ -1214,6 +1222,9 @@ export class MerchantApiClient { } } +/** + * FIXME: This should be deprecated in favor of MerchantApiClient + */ export namespace MerchantPrivateApi { export async function createOrder( merchantService: MerchantServiceInterface, @@ -1444,7 +1455,7 @@ export class MerchantService implements MerchantServiceInterface { config.write(this.configFilename); } - async addInstance(instanceConfig: MerchantInstanceConfig): Promise { + async addInstance(instanceConfig: PartialMerchantInstanceConfig): Promise { if (!this.proc) { throw Error("merchant must be running to add instance"); } @@ -1492,7 +1503,7 @@ export interface MerchantAuthConfiguration { token?: string; } -export interface MerchantInstanceConfig { +export interface PartialMerchantInstanceConfig { auth?: MerchantAuthConfiguration; id: string; name: string; @@ -1506,6 +1517,20 @@ export interface MerchantInstanceConfig { defaultPayDelay?: Duration; } +export interface MerchantInstanceConfig { + auth: MerchantAuthConfiguration; + id: string; + name: string; + payto_uris: string[]; + address: unknown; + jurisdiction: unknown; + default_max_wire_fee: string; + default_max_deposit_fee: string; + default_wire_fee_amortization: number; + default_wire_transfer_delay: Duration; + default_pay_delay: Duration; +} + type TestStatus = "pass" | "fail" | "skip"; export interface TestRunResult { diff --git a/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts new file mode 100644 index 000000000..9ed1705af --- /dev/null +++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-instances-urls.ts @@ -0,0 +1,152 @@ +/* + This file is part of GNU Taler + (C) 2021 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 + */ + +/** + * Imports. + */ +import { URL } from "@gnu-taler/taler-wallet-core"; +import axios from "axios"; +import { + ExchangeService, + GlobalTestState, + MerchantApiClient, + MerchantService, + setupDb, +} from "./harness"; + +/** + * Do basic checks on instance management and authentication. + */ +export async function runMerchantInstancesUrlsTest(t: GlobalTestState) { + // Set up test environment + + const db = await setupDb(t); + + 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, + }); + + merchant.addExchange(exchange); + + await merchant.start(); + await merchant.pingUntilAvailable(); + + const clientForDefault = new MerchantApiClient( + merchant.makeInstanceBaseUrl(), + { + method: "token", + token: "secret-token:i-am-default", + }, + ); + + const clientForMyinst = new MerchantApiClient( + merchant.makeInstanceBaseUrl("myinst"), + { + method: "token", + token: "secret-token:i-am-myinst", + }, + ); + + await clientForDefault.createInstance({ + id: "default", + address: {}, + default_max_deposit_fee: "TESTKUDOS:1", + default_max_wire_fee: "TESTKUDOS:1", + default_pay_delay: { d_ms: 60000 }, + default_wire_fee_amortization: 1, + default_wire_transfer_delay: { d_ms: 60000 }, + jurisdiction: {}, + name: "My Default Instance", + payto_uris: ["payto://x-taler-bank/foo/bar"], + auth: { + method: "token", + token: "secret-token:i-am-default", + }, + }); + + await clientForDefault.createInstance({ + id: "myinst", + address: {}, + default_max_deposit_fee: "TESTKUDOS:1", + default_max_wire_fee: "TESTKUDOS:1", + default_pay_delay: { d_ms: 60000 }, + default_wire_fee_amortization: 1, + default_wire_transfer_delay: { d_ms: 60000 }, + jurisdiction: {}, + name: "My Second Instance", + payto_uris: ["payto://x-taler-bank/foo/bar"], + auth: { + method: "token", + token: "secret-token:i-am-myinst", + }, + }); + + async function check(url: string, token: string, expectedStatus: number) { + const resp = await axios.get(url, { + headers: { + Authorization: `Bearer ${token}`, + }, + validateStatus: () => true, + }); + console.log("checking", url); + t.assertDeepEqual(resp.status, expectedStatus); + } + + const tokDefault = "secret-token:i-am-default"; + const tokMyinst = "secret-token:i-am-myinst"; + + const defaultBaseUrl = merchant.makeInstanceBaseUrl(); + + await check(`${defaultBaseUrl}config`, "foo", 200); + await check(`${defaultBaseUrl}instances/default/config`, "foo", 200); + await check(`${defaultBaseUrl}instances/myinst/config`, "foo", 200); + await check(`${defaultBaseUrl}instances/foo/config`, "foo", 404); + await check( + `${defaultBaseUrl}instances/default/instances/config`, + "foo", + 404, + ); + + await check( + `${defaultBaseUrl}private/instances/myinst/config`, + tokDefault, + 404, + ); + + await check( + `${defaultBaseUrl}instances/myinst/private/orders`, + tokDefault, + 200, + ); + + await check( + `${defaultBaseUrl}private/instances/myinst/orders`, + tokDefault, + 404, + ); +} + +runMerchantInstancesUrlsTest.suites = ["merchant"]; diff --git a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts index 6568e5667..9aeb7ac73 100644 --- a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts +++ b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts @@ -60,6 +60,7 @@ import { runLibeufinTutorialTest } from "./test-libeufin-tutorial"; import { runDepositTest } from "./test-deposit"; import CancellationToken from "cancellationtoken"; import { runMerchantInstancesTest } from "./test-merchant-instances"; +import { runMerchantInstancesUrlsTest } from "./test-merchant-instances-urls"; /** * Test runner. @@ -85,6 +86,7 @@ const allTests: TestMainFunction[] = [ runLibeufinRefundTest, runMerchantExchangeConfusionTest, runMerchantInstancesTest, + runMerchantInstancesUrlsTest, runMerchantLongpollingTest, runMerchantRefundApiTest, runPayAbortTest,