gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 02/02: correct refund amounts and better testing


From: gnunet
Subject: [taler-wallet-core] 02/02: correct refund amounts and better testing
Date: Tue, 01 Sep 2020 17:07:57 +0200

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

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

commit 044b7236572089b98a9f230499bb4cd9ad0342a3
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Tue Sep 1 20:37:50 2020 +0530

    correct refund amounts and better testing
---
 packages/taler-integrationtests/src/harness.ts     | 38 ++++++++++-
 .../taler-integrationtests/src/merchantApiTypes.ts |  4 +-
 .../src/test-refund-incremental.ts                 | 76 ++++++++++++++++++----
 .../src/operations/transactions.ts                 | 17 +++--
 packages/taler-wallet-core/src/util/amounts.ts     | 14 +++-
 5 files changed, 127 insertions(+), 22 deletions(-)

diff --git a/packages/taler-integrationtests/src/harness.ts 
b/packages/taler-integrationtests/src/harness.ts
index 93999c87..0b41923a 100644
--- a/packages/taler-integrationtests/src/harness.ts
+++ b/packages/taler-integrationtests/src/harness.ts
@@ -42,7 +42,6 @@ import {
   CoreApiResponse,
   PreparePayResult,
   PreparePayRequest,
-  codecForPreparePayResultPaymentPossible,
   codecForPreparePayResult,
   OperationFailedError,
   AddExchangeRequest,
@@ -67,6 +66,8 @@ import {
   codecForTransactionsResponse,
   WithdrawTestBalanceRequest,
   AmountString,
+  ApplyRefundRequest,
+  codecForApplyRefundResponse,
 } from "taler-wallet-core";
 import { URL } from "url";
 import axios, { AxiosError } from "axios";
@@ -77,6 +78,7 @@ import {
   PostOrderResponse,
   MerchantOrderPrivateStatusResponse,
 } from "./merchantApiTypes";
+import { ApplyRefundResponse } from "taler-wallet-core";
 
 const exec = util.promisify(require("child_process").exec);
 
@@ -384,6 +386,32 @@ export class GlobalTestState {
     }
   }
 
+  assertAmountLeq(
+    amtExpected: string | AmountJson,
+    amtActual: string | AmountJson,
+  ): void {
+    let ja1: AmountJson;
+    let ja2: AmountJson;
+    if (typeof amtExpected === "string") {
+      ja1 = Amounts.parseOrThrow(amtExpected);
+    } else {
+      ja1 = amtExpected;
+    }
+    if (typeof amtActual === "string") {
+      ja2 = Amounts.parseOrThrow(amtActual);
+    } else {
+      ja2 = amtActual;
+    }
+
+    if (Amounts.cmp(ja1, ja2) > 0) {
+      throw Error(
+        `test assertion failed: expected ${Amounts.stringify(
+          ja1,
+        )} to be less or equal (leq) than ${Amounts.stringify(ja2)}`,
+      );
+    }
+  }
+
   private shutdownSync(): void {
     for (const s of this.servers) {
       s.close();
@@ -1512,6 +1540,14 @@ export class WalletCli {
     );
   }
 
+  async applyRefund(req: ApplyRefundRequest): Promise<ApplyRefundResponse> {
+    const resp = await this.apiRequest("applyRefund", req);
+    if (resp.type === "response") {
+      return codecForApplyRefundResponse().decode(resp.result);
+    }
+    throw new OperationFailedError(resp.error);
+  }
+
   async preparePay(req: PreparePayRequest): Promise<PreparePayResult> {
     const resp = await this.apiRequest("preparePay", req);
     if (resp.type === "response") {
diff --git a/packages/taler-integrationtests/src/merchantApiTypes.ts 
b/packages/taler-integrationtests/src/merchantApiTypes.ts
index d08c354a..550c5e90 100644
--- a/packages/taler-integrationtests/src/merchantApiTypes.ts
+++ b/packages/taler-integrationtests/src/merchantApiTypes.ts
@@ -83,8 +83,8 @@ export const codecForCheckPaymentPaidResponse = (): Codec<
 > =>
   buildCodecForObject<CheckPaymentPaidResponse>()
     .property("order_status", codecForConstString("paid"))
-    .property("refunded", codecForBoolean)
-    .property("wired", codecForBoolean)
+    .property("refunded", codecForBoolean())
+    .property("wired", codecForBoolean())
     .property("deposit_total", codecForAmountString())
     .property("exchange_ec", codecForNumber())
     .property("exchange_hc", codecForNumber())
diff --git a/packages/taler-integrationtests/src/test-refund-incremental.ts 
b/packages/taler-integrationtests/src/test-refund-incremental.ts
index e823b40a..3439f704 100644
--- a/packages/taler-integrationtests/src/test-refund-incremental.ts
+++ b/packages/taler-integrationtests/src/test-refund-incremental.ts
@@ -24,6 +24,7 @@ import {
   MerchantPrivateApi,
 } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
+import { TransactionType, Amounts } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
@@ -47,7 +48,7 @@ runTest(async (t: GlobalTestState) => {
   const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
     order: {
       summary: "Buy me!",
-      amount: "TESTKUDOS:5",
+      amount: "TESTKUDOS:10",
       fulfillment_url: "taler://fulfillment-success/thx",
     },
   });
@@ -88,9 +89,21 @@ runTest(async (t: GlobalTestState) => {
 
   console.log("first refund increase response", ref);
 
+  {
+    let wr = await wallet.applyRefund({
+      talerRefundUri: ref.talerRefundUri,
+    });
+    console.log(wr);
+    const txs = await wallet.getTransactions();
+    console.log(
+      "transactions after applying first refund:",
+      JSON.stringify(txs, undefined, 2),
+    );
+  }
+
   // Wait at least a second, because otherwise the increased
   // refund will be grouped with the previous one.
-  await delayMs(1.2);
+  await delayMs(1200);
 
   ref = await MerchantPrivateApi.giveRefund(merchant, {
     amount: "TESTKUDOS:5",
@@ -101,10 +114,25 @@ runTest(async (t: GlobalTestState) => {
 
   console.log("second refund increase response", ref);
 
-  let r = await wallet.apiRequest("applyRefund", {
-    talerRefundUri: ref.talerRefundUri,
+  // Wait at least a second, because otherwise the increased
+  // refund will be grouped with the previous one.
+  await delayMs(1200);
+
+  ref = await MerchantPrivateApi.giveRefund(merchant, {
+    amount: "TESTKUDOS:10",
+    instance: "default",
+    justification: "bar",
+    orderId: orderResp.order_id,
   });
-  console.log(r);
+
+  console.log("third refund increase response", ref);
+
+  {
+    let wr = await wallet.applyRefund({
+      talerRefundUri: ref.talerRefundUri,
+    });
+    console.log(wr);
+  }
 
   orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
     orderId: orderResp.order_id,
@@ -112,17 +140,43 @@ runTest(async (t: GlobalTestState) => {
 
   t.assertTrue(orderStatus.order_status === "paid");
 
-  t.assertAmountEquals(orderStatus.refund_amount, "TESTKUDOS:5");
+  t.assertAmountEquals(orderStatus.refund_amount, "TESTKUDOS:10");
 
   console.log(JSON.stringify(orderStatus, undefined, 2));
 
   await wallet.runUntilDone();
 
-  r = await wallet.apiRequest("getBalances", {});
-  console.log(JSON.stringify(r, undefined, 2));
-
-  r = await wallet.apiRequest("getTransactions", {});
-  console.log(JSON.stringify(r, undefined, 2));
+  const bal = await wallet.getBalances();
+  console.log(JSON.stringify(bal, undefined, 2));
+
+  {
+    const txs = await wallet.getTransactions();
+    console.log(JSON.stringify(txs, undefined, 2));
+
+    const txTypes = txs.transactions.map((x) => x.type);
+    t.assertDeepEqual(txTypes, [
+      "withdrawal",
+      "payment",
+      "refund",
+      "refund",
+      "refund",
+    ]);
+
+    for (const tx of txs.transactions) {
+      if (tx.type !== TransactionType.Refund) {
+        continue;
+      }
+      t.assertAmountLeq(tx.amountEffective, tx.amountRaw);
+    }
+
+    const raw = Amounts.sum(
+      txs.transactions
+        .filter((x) => x.type === TransactionType.Refund)
+        .map((x) => x.amountRaw),
+    ).amount;
+
+    t.assertAmountEquals(raw, "TESTKUDOS:10");
+  }
 
   await t.shutdown();
 });
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts 
b/packages/taler-wallet-core/src/operations/transactions.ts
index 2515415d..da75f6e5 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -281,22 +281,27 @@ export async function getTransactions(
             groupKey,
           );
           let r0: WalletRefundItem | undefined;
-          let amountEffective = Amounts.getZero(
+          let amountRaw = Amounts.getZero(
             pr.contractData.amount.currency,
           );
-          let amountRaw = Amounts.getZero(pr.contractData.amount.currency);
+          let amountEffective = 
Amounts.getZero(pr.contractData.amount.currency);
           for (const rk of Object.keys(pr.refunds)) {
             const refund = pr.refunds[rk];
+            const myGroupKey = `${refund.executionTime.t_ms}`;
+            if (myGroupKey !== groupKey) {
+              continue;
+            }
             if (!r0) {
               r0 = refund;
             }
+
             if (refund.type === RefundState.Applied) {
-              amountEffective = Amounts.add(
-                amountEffective,
-                refund.refundAmount,
-              ).amount;
               amountRaw = Amounts.add(
                 amountRaw,
+                refund.refundAmount,
+              ).amount;
+              amountEffective = Amounts.add(
+                amountEffective,
                 Amounts.sub(
                   refund.refundAmount,
                   refund.refundFee,
diff --git a/packages/taler-wallet-core/src/util/amounts.ts 
b/packages/taler-wallet-core/src/util/amounts.ts
index 2a8c4790..2f912cff 100644
--- a/packages/taler-wallet-core/src/util/amounts.ts
+++ b/packages/taler-wallet-core/src/util/amounts.ts
@@ -101,11 +101,21 @@ export function getZero(currency: string): AmountJson {
   };
 }
 
-export function sum(amounts: AmountJson[]): Result {
+export type AmountLike = AmountString | AmountJson;
+
+export function jsonifyAmount(amt: AmountLike): AmountJson {
+  if (typeof amt === "string") {
+    return parseOrThrow(amt);
+  }
+  return amt;
+}
+
+export function sum(amounts: AmountLike[]): Result {
   if (amounts.length <= 0) {
     throw Error("can't sum zero amounts");
   }
-  return add(amounts[0], ...amounts.slice(1));
+  const jsonAmounts = amounts.map((x) => jsonifyAmount(x));
+  return add(jsonAmounts[0], ...jsonAmounts.slice(1));
 }
 
 /**

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