gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: better coverage for merchant


From: gnunet
Subject: [taler-wallet-core] branch master updated: better coverage for merchant spec test
Date: Mon, 16 Aug 2021 13:33:35 +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 ec713f04 better coverage for merchant spec test
ec713f04 is described below

commit ec713f04b83126139087d908cb4b9d012da6c982
Author: Florian Dold <florian@dold.me>
AuthorDate: Mon Aug 16 13:33:21 2021 +0200

    better coverage for merchant spec test
---
 .../test-merchant-spec-public-orders.ts            | 393 ++++++++++++++++++---
 1 file changed, 337 insertions(+), 56 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
index 523f760d..ab7bf1ac 100644
--- 
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
@@ -28,7 +28,14 @@ import {
   NodeHttpLib,
   WalletApiOperation,
 } from "@gnu-taler/taler-wallet-core";
-import { GlobalTestState, MerchantPrivateApi, WalletCli } from "./harness";
+import {
+  BankService,
+  ExchangeService,
+  GlobalTestState,
+  MerchantPrivateApi,
+  MerchantService,
+  WalletCli,
+} from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -36,65 +43,277 @@ import {
 
 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.
+interface Context {
+  merchant: MerchantService;
+  merchantBaseUrl: string;
+  bank: BankService;
+  exchange: ExchangeService;
+}
 
+async function testWithClaimToken(
+  t: GlobalTestState,
+  c: Context,
+): Promise<void> {
+  const wallet = new WalletCli(t, "withclaimtoken");
+  const { bank, exchange } = c;
+  const { merchant, merchantBaseUrl } = c;
   await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
-  await withdrawViaBank(t, {
-    wallet: wallet2,
-    bank,
-    exchange,
-    amount: "TESTKUDOS:20",
+  const sessionId = "mysession";
+  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";,
+    },
   });
-  // Base URL for the default instance.
-  const merchantBaseUrl = merchant.makeInstanceBaseUrl();
+
+  const claimToken = orderResp.token;
+  const orderId = orderResp.order_id;
+  t.assertTrue(!!claimToken);
+  let talerPayUri: string;
 
   {
-    const httpResp = await httpLib.get(new URL("config", 
merchantBaseUrl).href);
+    const httpResp = await httpLib.get(
+      new URL(`orders/${orderId}`, merchantBaseUrl).href,
+    );
     const r = await httpResp.json();
+    t.assertDeepEqual(httpResp.status, 202);
     console.log(r);
-    t.assertDeepEqual(r.currency, "TESTKUDOS");
   }
 
   {
-    const httpResp = await httpLib.get(
-      new URL("orders/foo", merchantBaseUrl).href,
-    );
+    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);
-    t.assertDeepEqual(httpResp.status, 404);
-    // FIXME: also check Taler error code
+    talerPayUri = r.taler_pay_uri;
+    t.assertTrue(!!talerPayUri);
   }
 
   {
-    const httpResp = await httpLib.get(
-      new URL("orders/foo", merchantBaseUrl).href,
-      {
-        headers: {
-          Accept: "text/html",
-        },
+    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);
-    t.assertDeepEqual(httpResp.status, 404);
-    // FIXME: also check Taler error code
   }
 
+  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, JSON
+  {
+    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 respFulfillmentUrl = r.fulfillment_url;
+    t.assertDeepEqual(respFulfillmentUrl, "https://example.com/article42";);
+  }
+
+  // paid, access with correct claim token, HTML
+  {
+    const url = new URL(`orders/${orderId}`, merchantBaseUrl);
+    url.searchParams.set("token", claimToken);
+    const httpResp = await httpLib.get(url.href, {
+      headers: { Accept: "text/html" },
+    });
+    t.assertDeepEqual(httpResp.status, 200);
+  }
+
+  const confirmPayRes2 = await wallet.client.call(
+    WalletApiOperation.ConfirmPay,
+    {
+      proposalId: proposalId,
+      sessionId: sessionId,
+    },
+  );
+
+  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", sessionId);
+    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", sessionId);
+    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";);
+  }
+}
+
+async function testWithoutClaimToken(
+  t: GlobalTestState,
+  c: Context,
+): Promise<void> {
+  const wallet = new WalletCli(t, "withoutct");
+  const sessionId = "mysession2";
+  const { bank, exchange } = c;
+  const { merchant, merchantBaseUrl } = c;
+  await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
   const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
     order: {
       summary: "Buy me!",
@@ -102,11 +321,10 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
       fulfillment_url: "https://example.com/article42";,
       public_reorder_url: "https://example.com/article42-share";,
     },
+    create_token: false,
   });
 
-  const claimToken = orderResp.token;
   const orderId = orderResp.order_id;
-  t.assertTrue(!!claimToken);
   let talerPayUri: string;
 
   {
@@ -114,13 +332,12 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
       new URL(`orders/${orderId}`, merchantBaseUrl).href,
     );
     const r = await httpResp.json();
-    t.assertDeepEqual(httpResp.status, 202);
+    t.assertDeepEqual(httpResp.status, 402);
     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);
@@ -131,7 +348,6 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
 
   {
     const url = new URL(`orders/${orderId}`, merchantBaseUrl);
-    url.searchParams.set("token", claimToken);
     const httpResp = await httpLib.get(url.href, {
       headers: {
         Accept: "text/html",
@@ -149,6 +365,8 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     },
   );
 
+  console.log(preparePayResp);
+
   t.assertTrue(preparePayResp.status === PreparePayResultType.PaymentPossible);
   const contractTermsHash = preparePayResp.contractTermsHash;
   const proposalId = preparePayResp.proposalId;
@@ -175,10 +393,9 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     t.assertDeepEqual(httpResp.status, 403);
   }
 
-  // claimed, unpaid, access with correct claim token
+  // claimed, unpaid, no 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);
@@ -201,7 +418,10 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     const httpResp = await httpLib.get(url.href);
     const r = await httpResp.json();
     console.log(r);
-    t.assertDeepEqual(httpResp.status, 202);
+    // No credentials, but the order doesn't require a claim token.
+    // This effectively means that the order ID is already considered
+    // enough authentication, at least to check for the basic order status
+    t.assertDeepEqual(httpResp.status, 402);
   }
 
   const confirmPayRes = await wallet.client.call(
@@ -219,7 +439,7 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     const httpResp = await httpLib.get(url.href);
     const r = await httpResp.json();
     console.log(r);
-    t.assertDeepEqual(httpResp.status, 202);
+    t.assertDeepEqual(httpResp.status, 200);
   }
 
   // paid, access with wrong h_contract
@@ -254,10 +474,9 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     t.assertDeepEqual(httpResp.status, 200);
   }
 
-  // paid, access with correct claim token, JSON
+  // paid, JSON
   {
     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);
@@ -266,10 +485,9 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     t.assertDeepEqual(respFulfillmentUrl, "https://example.com/article42";);
   }
 
-  // paid, access with correct claim token, HTML
+  // paid, HTML
   {
     const url = new URL(`orders/${orderId}`, merchantBaseUrl);
-    url.searchParams.set("token", claimToken);
     const httpResp = await httpLib.get(url.href, {
       headers: { Accept: "text/html" },
     });
@@ -280,7 +498,7 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
     WalletApiOperation.ConfirmPay,
     {
       proposalId: proposalId,
-      sessionId: "mysession",
+      sessionId: sessionId,
     },
   );
 
@@ -317,7 +535,7 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
   {
     const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
     url.searchParams.set("token", apToken);
-    url.searchParams.set("session_id", "mysession");
+    url.searchParams.set("session_id", sessionId);
     const httpResp = await httpLib.get(url.href);
     const r = await httpResp.json();
     console.log(r);
@@ -330,7 +548,7 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
   {
     const url = new URL(`orders/${apOrderId}`, merchantBaseUrl);
     url.searchParams.set("token", apToken);
-    url.searchParams.set("session_id", "mysession");
+    url.searchParams.set("session_id", sessionId);
     const httpResp = await httpLib.get(url.href, {
       headers: { Accept: "text/html" },
     });
@@ -341,4 +559,67 @@ export async function runMerchantSpecPublicOrdersTest(t: 
GlobalTestState) {
   }
 }
 
+/**
+ * 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 {
+    bank,
+    exchange,
+    merchant,
+  } = await createSimpleTestkudosEnvironment(t);
+
+  // 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
+  }
+
+  await testWithClaimToken(t, {
+    merchant,
+    merchantBaseUrl,
+    exchange,
+    bank,
+  });
+
+  await testWithoutClaimToken(t, {
+    merchant,
+    merchantBaseUrl,
+    exchange,
+    bank,
+  });
+}
+
 runMerchantSpecPublicOrdersTest.suites = ["merchant"];

-- 
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]