gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: merchant test cases


From: gnunet
Subject: [taler-wallet-core] branch master updated: merchant test cases
Date: Thu, 12 Aug 2021 21:01:43 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 2f945b2a merchant test cases
2f945b2a is described below

commit 2f945b2aebf3378496c8be3ef48a16253dde3358
Author: Florian Dold <florian@dold.me>
AuthorDate: Thu Aug 12 21:01:40 2021 +0200

    merchant test cases
---
 .../test-merchant-spec-public-orders.ts            | 332 +++++++++++++++++++++
 .../src/integrationtests/test-paywall-flow.ts      |   4 +-
 .../src/integrationtests/testrunner.ts             |   2 +
 .../taler-wallet-core/src/headless/NodeHttpLib.ts  |   3 +
 .../src/operations/transactions.ts                 |   7 +
 5 files changed, 346 insertions(+), 2 deletions(-)

diff --git 
a/packages/taler-wallet-cli/src/integrationtests/test-merchant-spec-public-orders.ts
 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-spec-public-orders.ts
new file mode 100644
index 00000000..98528ada
--- /dev/null
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-spec-public-orders.ts
@@ -0,0 +1,332 @@
+/*
+ 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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * Imports.
+ */
+import {
+  ConfirmPayResultType,
+  PreparePayResultType,
+  URL,
+} from "@gnu-taler/taler-util";
+import {
+  encodeCrock,
+  getRandomBytes,
+  NodeHttpLib,
+  WalletApiOperation,
+} from "@gnu-taler/taler-wallet-core";
+import { GlobalTestState, MerchantPrivateApi, WalletCli } from "./harness";
+import {
+  createSimpleTestkudosEnvironment,
+  withdrawViaBank,
+} from "./helpers.js";
+
+const httpLib = new NodeHttpLib();
+
+/**
+ * Checks for the /orders/{id} endpoint of the merchant.
+ *
+ * The tests here should exercise all code paths in the executable
+ * specification of the endpoint.
+ */
+export async function runMerchantSpecPublicOrdersTest(t: GlobalTestState) {
+  const {
+    wallet,
+    bank,
+    exchange,
+    merchant,
+  } = await createSimpleTestkudosEnvironment(t);
+  const wallet2 = new WalletCli(t);
+
+  // Withdraw digital cash into the wallet.
+
+  await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
+  await withdrawViaBank(t, {
+    wallet: wallet2,
+    bank,
+    exchange,
+    amount: "TESTKUDOS:20",
+  });
+  // Base URL for the default instance.
+  const merchantBaseUrl = merchant.makeInstanceBaseUrl();
+
+  {
+    const httpResp = await httpLib.get(new URL("config", 
merchantBaseUrl).href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(r.currency, "TESTKUDOS");
+  }
+
+  {
+    const httpResp = await httpLib.get(
+      new URL("orders/foo", merchantBaseUrl).href,
+    );
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 404);
+    // FIXME: also check Taler error code
+  }
+
+  {
+    const httpResp = await httpLib.get(
+      new URL("orders/foo", merchantBaseUrl).href,
+      {
+        headers: {
+          Accept: "text/html",
+        },
+      },
+    );
+    const r = await httpResp.text();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 404);
+    // FIXME: also check Taler error code
+  }
+
+  const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
+    order: {
+      summary: "Buy me!",
+      amount: "TESTKUDOS:5",
+      fulfillment_url: "https://example.com/article42";,
+      public_reorder_url: "https://example.com/article42-share";,
+    },
+  });
+
+  const claimToken = orderResp.token;
+  const orderId = orderResp.order_id;
+  t.assertTrue(!!claimToken);
+  let talerPayUri: string;
+
+  {
+    const httpResp = await httpLib.get(
+      new URL(`orders/${orderId}`, merchantBaseUrl).href,
+    );
+    const r = await httpResp.json();
+    t.assertDeepEqual(httpResp.status, 202);
+    console.log(r);
+  }
+
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("token", claimToken);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    t.assertDeepEqual(httpResp.status, 402);
+    console.log(r);
+    talerPayUri = r.taler_pay_uri;
+    t.assertTrue(!!talerPayUri);
+  }
+
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("token", claimToken);
+    const httpResp = await httpLib.get(url.href, {
+      headers: {
+        Accept: "text/html",
+      },
+    });
+    const r = await httpResp.text();
+    t.assertDeepEqual(httpResp.status, 402);
+    console.log(r);
+  }
+
+  const preparePayResp = await wallet.client.call(
+    WalletApiOperation.PreparePayForUri,
+    {
+      talerPayUri,
+    },
+  );
+
+  t.assertTrue(preparePayResp.status === PreparePayResultType.PaymentPossible);
+  const contractTermsHash = preparePayResp.contractTermsHash;
+  const proposalId = preparePayResp.proposalId;
+
+  // claimed, unpaid, access with wrong h_contract
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const hcWrong = encodeCrock(getRandomBytes(64));
+    url.searchParams.set("h_contract", hcWrong);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 403);
+  }
+
+  // claimed, unpaid, access with wrong claim token
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const ctWrong = encodeCrock(getRandomBytes(16));
+    url.searchParams.set("token", ctWrong);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 403);
+  }
+
+  // claimed, unpaid, access with correct claim token
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("token", claimToken);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 402);
+  }
+
+  // claimed, unpaid, access with correct contract terms hash
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("h_contract", contractTermsHash);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 402);
+  }
+
+  // claimed, unpaid, access without credentials
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 202);
+  }
+
+  const confirmPayRes = await wallet.client.call(
+    WalletApiOperation.ConfirmPay,
+    {
+      proposalId: proposalId,
+    },
+  );
+
+  t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
+
+  // paid, access without credentials
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 202);
+  }
+
+  // paid, access with wrong h_contract
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const hcWrong = encodeCrock(getRandomBytes(64));
+    url.searchParams.set("h_contract", hcWrong);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 403);
+  }
+
+  // paid, access with wrong claim token
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    const ctWrong = encodeCrock(getRandomBytes(16));
+    url.searchParams.set("token", ctWrong);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 403);
+  }
+
+  // paid, access with correct h_contract
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("h_contract", contractTermsHash);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 200);
+  }
+
+  // paid, access with correct claim token
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("token", claimToken);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 200);
+  }
+
+  const confirmPayRes2 = await wallet.client.call(
+    WalletApiOperation.ConfirmPay,
+    {
+      proposalId: proposalId,
+      sessionId: "mysession",
+    },
+  );
+
+  t.assertTrue(confirmPayRes2.type === ConfirmPayResultType.Done);
+
+  // Create another order with identical fulfillment URL to test the "already 
paid" flow
+  const alreadyPaidOrderResp = await MerchantPrivateApi.createOrder(
+    merchant,
+    "default",
+    {
+      order: {
+        summary: "Buy me!",
+        amount: "TESTKUDOS:5",
+        fulfillment_url: "https://example.com/article42";,
+        public_reorder_url: "https://example.com/article42-share";,
+      },
+    },
+  );
+
+  const apOrderId = alreadyPaidOrderResp.order_id;
+  const apToken = alreadyPaidOrderResp.token;
+  t.assertTrue(!!apToken);
+
+  {
+    const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
+    url.searchParams.set("token", apToken);
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 402);
+  }
+
+  // Check for already paid session ID, JSON
+  {
+    const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
+    url.searchParams.set("token", apToken);
+    url.searchParams.set("session_id", "mysession");
+    const httpResp = await httpLib.get(url.href);
+    const r = await httpResp.json();
+    console.log(r);
+    t.assertDeepEqual(httpResp.status, 402);
+    const alreadyPaidOrderId = r.already_paid_order_id;
+    t.assertDeepEqual(alreadyPaidOrderId, orderId);
+  }
+
+  // Check for already paid session ID, HTML
+  {
+    const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
+    url.searchParams.set("token", apToken);
+    url.searchParams.set("session_id", "mysession");
+    const httpResp = await httpLib.get(url.href, {
+      headers: { Accept: "text/html" },
+    });
+    t.assertDeepEqual(httpResp.status, 302);
+    const location = httpResp.headers.get("Location");
+    console.log("location header:", location);
+    t.assertDeepEqual(location, "https://example.com/article42";);
+  }
+}
+
+runMerchantSpecPublicOrdersTest.suites = ["merchant"];
diff --git 
a/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
index 25c8862c..04eee79e 100644
--- a/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
@@ -134,10 +134,10 @@ export async function runPaywallFlowTest(t: 
GlobalTestState) {
 
   console.log(publicOrderStatusResp.data);
 
-  if (publicOrderStatusResp.status != 202) {
+  if (publicOrderStatusResp.status != 200) {
     console.log(publicOrderStatusResp.data);
     throw Error(
-      `expected status 202 (after paying), but got 
${publicOrderStatusResp.status}`,
+      `expected status 200 (after paying), but got 
${publicOrderStatusResp.status}`,
     );
   }
 
diff --git a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts 
b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
index 5e0cb9f5..c2e62643 100644
--- a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
@@ -76,6 +76,7 @@ import { runMerchantInstancesDeleteTest } from 
"./test-merchant-instances-delete
 import { runWalletBackupDoublespendTest } from 
"./test-wallet-backup-doublespend";
 import { runPaymentForgettableTest } from "./test-payment-forgettable.js";
 import { runPaymentZeroTest } from "./test-payment-zero.js";
+import { runMerchantSpecPublicOrdersTest } from 
"./test-merchant-spec-public-orders.js";
 
 /**
  * Test runner.
@@ -113,6 +114,7 @@ const allTests: TestMainFunction[] = [
   runMerchantInstancesDeleteTest,
   runMerchantInstancesUrlsTest,
   runMerchantLongpollingTest,
+  runMerchantSpecPublicOrdersTest,
   runMerchantRefundApiTest,
   runPayAbortTest,
   runPaymentClaimTest,
diff --git a/packages/taler-wallet-core/src/headless/NodeHttpLib.ts 
b/packages/taler-wallet-core/src/headless/NodeHttpLib.ts
index 1186ea4d..9655d363 100644
--- a/packages/taler-wallet-core/src/headless/NodeHttpLib.ts
+++ b/packages/taler-wallet-core/src/headless/NodeHttpLib.ts
@@ -52,6 +52,8 @@ export class NodeHttpLib implements HttpRequestLibrary {
     const method = opt?.method ?? "GET";
     let body = opt?.body;
 
+    logger.trace(`Requesting ${method} ${url}`);
+
     const parsedUrl = new URL(url);
     if (this.throttlingEnabled && this.throttle.applyThrottle(url)) {
       throw OperationFailedError.fromCode(
@@ -79,6 +81,7 @@ export class NodeHttpLib implements HttpRequestLibrary {
         transformResponse: (x) => x,
         data: body,
         timeout,
+        maxRedirects: 0,
       });
     } catch (e) {
       throw OperationFailedError.fromCode(
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts 
b/packages/taler-wallet-core/src/operations/transactions.ts
index 52b9819d..a07551e8 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -403,6 +403,13 @@ export enum TombstoneTag {
   DeleteRefund = "delete-refund",
 }
 
+export async function retryTransactionNow(
+  ws: InternalWalletState,
+  transactionId: string,
+): Promise<void> {
+  const [type, ...rest] = transactionId.split(":");
+}
+
 /**
  * Immediately retry the underlying operation
  * of a transaction.

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]