gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated (62406304 -> 044b7236)


From: gnunet
Subject: [taler-wallet-core] branch master updated (62406304 -> 044b7236)
Date: Tue, 01 Sep 2020 17:07:55 +0200

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

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

    from 62406304 include error details in transactions list
     new 7f4ebca0 validation
     new 044b7236 correct refund amounts and better testing

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 packages/taler-integrationtests/src/harness.ts     | 38 ++++++++++-
 .../taler-integrationtests/src/merchantApiTypes.ts |  4 +-
 .../src/test-refund-incremental.ts                 | 76 ++++++++++++++++++----
 .../taler-wallet-core/src/operations/refund.ts     | 15 +----
 .../src/operations/transactions.ts                 | 17 +++--
 packages/taler-wallet-core/src/types/talerTypes.ts | 12 ++--
 .../taler-wallet-core/src/types/walletTypes.ts     | 30 ++++++++-
 packages/taler-wallet-core/src/util/amounts.ts     | 14 +++-
 packages/taler-wallet-core/src/util/codec.ts       | 20 +++---
 9 files changed, 172 insertions(+), 54 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/refund.ts 
b/packages/taler-wallet-core/src/operations/refund.ts
index 787d2bb4..373e17a1 100644
--- a/packages/taler-wallet-core/src/operations/refund.ts
+++ b/packages/taler-wallet-core/src/operations/refund.ts
@@ -28,6 +28,7 @@ import {
   TalerErrorDetails,
   RefreshReason,
   CoinPublicKey,
+  ApplyRefundResponse,
 } from "../types/walletTypes";
 import {
   Stores,
@@ -323,20 +324,6 @@ export interface RefundSummary {
   amountRefundGone: AmountJson;
 }
 
-export interface ApplyRefundResponse {
-  contractTermsHash: string;
-
-  proposalId: string;
-
-  amountEffectivePaid: AmountString;
-
-  amountRefundGranted: AmountString;
-
-  amountRefundGone: AmountString;
-
-  pendingAtExchange: boolean;
-}
-
 /**
  * Accept a refund, return the contract hash for the contract
  * that was involved in the refund.
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/types/talerTypes.ts 
b/packages/taler-wallet-core/src/types/talerTypes.ts
index b9e7fae4..b1061a1a 100644
--- a/packages/taler-wallet-core/src/types/talerTypes.ts
+++ b/packages/taler-wallet-core/src/types/talerTypes.ts
@@ -985,7 +985,7 @@ export const codecForBankWithdrawalOperationPostResponse = 
(): Codec<
   BankWithdrawalOperationPostResponse
 > =>
   buildCodecForObject<BankWithdrawalOperationPostResponse>()
-    .property("transfer_done", codecForBoolean)
+    .property("transfer_done", codecForBoolean())
     .build("BankWithdrawalOperationPostResponse");
 
 export type AmountString = string;
@@ -1189,7 +1189,7 @@ export const codecForProposal = (): Codec<Proposal> =>
 export const codecForCheckPaymentResponse = (): Codec<CheckPaymentResponse> =>
   buildCodecForObject<CheckPaymentResponse>()
     .property("order_status", codecForString())
-    .property("refunded", codecOptional(codecForBoolean))
+    .property("refunded", codecOptional(codecForBoolean()))
     .property("refunded_amount", codecOptional(codecForString()))
     .property("contract_terms", codecOptional(codecForAny()))
     .property("taler_pay_uri", codecOptional(codecForString()))
@@ -1200,9 +1200,9 @@ export const codecForWithdrawOperationStatusResponse = 
(): Codec<
   WithdrawOperationStatusResponse
 > =>
   buildCodecForObject<WithdrawOperationStatusResponse>()
-    .property("selection_done", codecForBoolean)
-    .property("transfer_done", codecForBoolean)
-    .property("aborted", codecForBoolean)
+    .property("selection_done", codecForBoolean())
+    .property("transfer_done", codecForBoolean())
+    .property("aborted", codecForBoolean())
     .property("amount", codecForString())
     .property("sender_wire", codecOptional(codecForString()))
     .property("suggested_exchange", codecOptional(codecForString()))
@@ -1298,7 +1298,7 @@ export const codecForMerchantOrderStatusPaid = (): Codec<
 > =>
   buildCodecForObject<MerchantOrderStatusPaid>()
     .property("refund_amount", codecForString())
-    .property("refunded", codecForBoolean)
+    .property("refunded", codecForBoolean())
     .build("MerchantOrderStatusPaid");
 
 export const codecForMerchantOrderRefundPickupResponse = (): Codec<
diff --git a/packages/taler-wallet-core/src/types/walletTypes.ts 
b/packages/taler-wallet-core/src/types/walletTypes.ts
index 89c8b4a8..dbaefae3 100644
--- a/packages/taler-wallet-core/src/types/walletTypes.ts
+++ b/packages/taler-wallet-core/src/types/walletTypes.ts
@@ -180,10 +180,10 @@ export interface BalancesResponse {
 export const codecForBalance = (): Codec<Balance> =>
   buildCodecForObject<Balance>()
     .property("available", codecForString())
-    .property("hasPendingTransactions", codecForBoolean)
+    .property("hasPendingTransactions", codecForBoolean())
     .property("pendingIncoming", codecForString())
     .property("pendingOutgoing", codecForString())
-    .property("requiresUserInput", codecForBoolean)
+    .property("requiresUserInput", codecForBoolean())
     .build("Balance");
 
 export const codecForBalancesResponse = (): Codec<BalancesResponse> =>
@@ -413,7 +413,7 @@ export const codecForPreparePayResultAlreadyConfirmed = (): 
Codec<
     )
     .property("amountEffective", codecForAmountString())
     .property("amountRaw", codecForAmountString())
-    .property("paid", codecForBoolean)
+    .property("paid", codecForBoolean())
     .property("contractTerms", codecForAny())
     .property("contractTermsHash", codecForString())
     .build("PreparePayResultAlreadyConfirmed");
@@ -843,3 +843,27 @@ export const codecForWithdrawTestBalance = (): Codec<
     .property("bankBaseUrl", codecForString())
     .property("exchangeBaseUrl", codecForString())
     .build("WithdrawTestBalanceRequest");
+
+export interface ApplyRefundResponse {
+  contractTermsHash: string;
+
+  proposalId: string;
+
+  amountEffectivePaid: AmountString;
+
+  amountRefundGranted: AmountString;
+
+  amountRefundGone: AmountString;
+
+  pendingAtExchange: boolean;
+}
+
+export const codecForApplyRefundResponse = (): Codec<ApplyRefundResponse> =>
+  buildCodecForObject<ApplyRefundResponse>()
+    .property("amountEffectivePaid", codecForAmountString())
+    .property("amountRefundGone", codecForAmountString())
+    .property("amountRefundGranted", codecForAmountString())
+    .property("contractTermsHash", codecForString())
+    .property("pendingAtExchange", codecForBoolean())
+    .property("proposalId", codecForString())
+    .build("ApplyRefundResponse");
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));
 }
 
 /**
diff --git a/packages/taler-wallet-core/src/util/codec.ts 
b/packages/taler-wallet-core/src/util/codec.ts
index 111abc38..741a5b17 100644
--- a/packages/taler-wallet-core/src/util/codec.ts
+++ b/packages/taler-wallet-core/src/util/codec.ts
@@ -292,15 +292,17 @@ export function codecForNumber(): Codec<number> {
 /**
  * Return a codec for a value that must be a number.
  */
-export const codecForBoolean: Codec<boolean> = {
-  decode(x: any, c?: Context): boolean {
-    if (typeof x === "boolean") {
-      return x;
-    }
-    throw new DecodingError(
-      `expected boolean at ${renderContext(c)} but got ${typeof x}`,
-    );
-  },
+export function codecForBoolean(): Codec<boolean> {
+  return {
+    decode(x: any, c?: Context): boolean {
+      if (typeof x === "boolean") {
+        return x;
+      }
+      throw new DecodingError(
+        `expected boolean at ${renderContext(c)} but got ${typeof x}`,
+      );
+    },
+  }
 };
 
 /**

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