gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 150/277: backenddb tests for refunds


From: gnunet
Subject: [taler-merchant] 150/277: backenddb tests for refunds
Date: Sun, 05 Jul 2020 20:51:03 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 7a205972630cc560abb3dd56448b6b0566f0487b
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
AuthorDate: Thu May 28 17:16:43 2020 -0400

    backenddb tests for refunds
---
 src/backenddb/drop0001.sql                 |   1 +
 src/backenddb/plugin_merchantdb_postgres.c |  10 +-
 src/backenddb/test_merchantdb.c            | 686 +++++++++++++++++++++++++++--
 src/include/taler_merchantdb_plugin.h      |   2 +
 4 files changed, 650 insertions(+), 49 deletions(-)

diff --git a/src/backenddb/drop0001.sql b/src/backenddb/drop0001.sql
index 0720569..5295feb 100644
--- a/src/backenddb/drop0001.sql
+++ b/src/backenddb/drop0001.sql
@@ -38,6 +38,7 @@ DROP TABLE IF EXISTS merchant_order_locks CASCADE;
 DROP TABLE IF EXISTS merchant_contract_terms CASCADE;
 DROP TABLE IF EXISTS merchant_deposits CASCADE;
 DROP TABLE IF EXISTS merchant_refunds CASCADE;
+DROP TABLE IF EXISTS merchant_refund_proofs CASCADE;
 DROP TABLE IF EXISTS merchant_credits CASCADE;
 DROP TABLE IF EXISTS merchant_transfers CASCADE;
 DROP TABLE IF EXISTS merchant_transfer_signatures CASCADE;
diff --git a/src/backenddb/plugin_merchantdb_postgres.c 
b/src/backenddb/plugin_merchantdb_postgres.c
index 30567ed..ae4fc35 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -1933,6 +1933,7 @@ static enum GNUNET_DB_QueryStatus
 postgres_refund_coin (void *cls,
                       const char *instance_id,
                       const struct GNUNET_HashCode *h_contract_terms,
+                      struct GNUNET_TIME_Absolute refund_timestamp,
                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
                       const char *reason)
 {
@@ -1940,6 +1941,7 @@ postgres_refund_coin (void *cls,
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_string (instance_id),
     GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+    GNUNET_PQ_query_param_absolute_time (&refund_timestamp),
     GNUNET_PQ_query_param_auto_from_type (coin_pub),
     GNUNET_PQ_query_param_string (reason),
     GNUNET_PQ_query_param_end
@@ -6859,6 +6861,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "INSERT INTO merchant_refunds"
                             "(order_serial"
                             ",rtransaction_id"
+                            ",refund_timestamp"
                             ",coin_pub"
                             ",reason"
                             ",refund_amount_val"
@@ -6867,12 +6870,13 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "SELECT "
                             " order_serial"
                             ",0" /* rtransaction_id always 0 for /abort */
+                            ",$3"
                             ",coin_pub"
-                            ",$4"
+                            ",$5"
                             ",amount_with_fee_val"
                             ",amount_with_fee_frac"
                             " FROM merchant_deposits"
-                            " WHERE coin_pub=$3"
+                            " WHERE coin_pub=$4"
                             "   AND order_serial="
                             "  (SELECT order_serial"
                             "     FROM merchant_contract_terms"
@@ -6881,7 +6885,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
                             "        (SELECT merchant_serial"
                             "           FROM merchant_instances"
                             "          WHERE merchant_id=$1))",
-                            4),
+                            5),
 
     /* for postgres_lookup_order_status() */
     GNUNET_PQ_make_prepare ("lookup_order_status",
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 2e8416b..5012e95 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -1578,6 +1578,31 @@ lookup_deposits_contract_coin_cb (void *cls,
 }
 
 
+static int
+test_insert_exchange_signkey (const struct TALER_MasterPublicKeyP *master_pub,
+                              const struct
+                              TALER_ExchangePublicKeyP *exchange_pub,
+                              struct GNUNET_TIME_Absolute start_date,
+                              struct GNUNET_TIME_Absolute expire_date,
+                              struct GNUNET_TIME_Absolute end_date,
+                              const struct TALER_MasterSignatureP *master_sig)
+{
+  if (1 != plugin->insert_exchange_signkey (plugin->cls,
+                                            master_pub,
+                                            exchange_pub,
+                                            start_date,
+                                            expire_date,
+                                            end_date,
+                                            master_sig))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Insert exchange signing key failed\n");
+    return 1;
+  }
+  return 0;
+}
+
+
 static int
 test_insert_deposit (const char *is,
                      const struct TALER_ExchangePublicKeyP *exchange_pub,
@@ -1927,18 +1952,12 @@ run_test_deposits (struct TestDeposits_Closure *cls)
                                          &cls->account));
 
   /* Insert a signing key */
-  if (1 != plugin->insert_exchange_signkey (plugin->cls,
-                                            &cls->master_pub,
-                                            &cls->exchange_pub,
-                                            cls->signkey_start,
-                                            cls->signkey_expire,
-                                            cls->signkey_end,
-                                            &cls->master_sig))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Insert signing key failed\n");
-    return 1;
-  }
+  TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->master_pub,
+                                                  &cls->exchange_pub,
+                                                  cls->signkey_start,
+                                                  cls->signkey_expire,
+                                                  cls->signkey_end,
+                                                  &cls->master_sig));
 
   /* Insert an order */
   TEST_RET_ON_FAIL (test_insert_order (cls->is.id,
@@ -2390,18 +2409,12 @@ run_test_transfers (struct TestTransfers_Closure *cls)
   }
 
   /* Insert a signing key */
-  if (1 != plugin->insert_exchange_signkey (plugin->cls,
-                                            &cls->master_pub,
-                                            &cls->exchange_pub,
-                                            cls->signkey_start,
-                                            cls->signkey_expire,
-                                            cls->signkey_end,
-                                            &cls->master_sig))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Insert signing key failed\n");
-    return 1;
-  }
+  TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->master_pub,
+                                                  &cls->exchange_pub,
+                                                  cls->signkey_start,
+                                                  cls->signkey_expire,
+                                                  cls->signkey_end,
+                                                  &cls->master_sig));
 
   /* Test transfer details */
   GNUNET_assert (GNUNET_OK ==
@@ -2545,7 +2558,7 @@ lookup_reserve_cb (void *cls,
   }
   for (unsigned int i = 0; tips_length > i; ++i)
   {
-
+    /* TODO: compare tips */
   }
   cmp->result_matches = 0;
 }
@@ -2595,6 +2608,35 @@ test_lookup_reserve (const char *instance_id,
 }
 
 
+struct ReserveData
+{
+  /**
+   * The reserve public key
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  /**
+   * The reserve private key
+   */
+  struct TALER_ReservePrivateKeyP reserve_priv;
+
+  /**
+   * The reserve initial amount
+   */
+  struct TALER_Amount initial_amount;
+
+  /**
+   * The exchange url
+   */
+  const char *exchange_url;
+
+  /**
+   * The expiration date
+   */
+  struct GNUNET_TIME_Absolute expiration;
+};
+
+
 struct TestTips_Closure
 {
   /**
@@ -2613,14 +2655,10 @@ struct TestTips_Closure
   struct TALER_MerchantPrivateKeyP merchant_priv;
 
   /**
-   * The reserve public key
+   * The tip reserve data
    */
-  struct TALER_ReservePublicKeyP reserve_pub;
+  struct ReserveData reserve;
 
-  /**
-   * The reserve private key
-   */
-  struct TALER_ReservePrivateKeyP reserve_priv;
 };
 
 
@@ -2652,9 +2690,16 @@ pre_test_tips (struct TestTips_Closure *cls)
   cls->is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
 
   /* Reserve */
-  GNUNET_CRYPTO_eddsa_key_create (&cls->reserve_priv.eddsa_priv);
-  GNUNET_CRYPTO_eddsa_key_get_public (&cls->reserve_priv.eddsa_priv,
-                                      &cls->reserve_pub.eddsa_pub);
+  GNUNET_CRYPTO_eddsa_key_create (&cls->reserve.reserve_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->reserve.reserve_priv.eddsa_priv,
+                                      &cls->reserve.reserve_pub.eddsa_pub);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:99.99",
+                                         &cls->reserve.initial_amount));
+  cls->reserve.exchange_url = "exch-url";
+  cls->reserve.expiration =
+    GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+                              GNUNET_TIME_UNIT_WEEKS);
 }
 
 
@@ -2674,20 +2719,13 @@ run_test_tips (struct TestTips_Closure *cls)
                                           &cls->is));
 
   /* Test insert reserve */
-  struct TALER_Amount initial_amount;
-  GNUNET_assert (GNUNET_OK ==
-                 TALER_string_to_amount ("EUR:99.99",
-                                         &initial_amount));
-  struct GNUNET_TIME_Absolute expiration =
-    GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
-                              GNUNET_TIME_UNIT_WEEKS);
   if (TALER_EC_NONE != plugin->insert_reserve (plugin->cls,
                                                cls->is.id,
-                                               &cls->reserve_priv,
-                                               &cls->reserve_pub,
-                                               "exch-url",
-                                               &initial_amount,
-                                               expiration))
+                                               &cls->reserve.reserve_priv,
+                                               &cls->reserve.reserve_pub,
+                                               cls->reserve.exchange_url,
+                                               &cls->reserve.initial_amount,
+                                               cls->reserve.expiration))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Insert reserve failed\n");
@@ -2752,6 +2790,561 @@ test_tips (void *cls)
 }
 
 
+struct TestLookupRefunds_Closure
+{
+  unsigned int refunds_to_cmp_length;
+
+  const struct TALER_CoinSpendPublicKeyP *coin_pub_to_cmp;
+
+  const struct TALER_Amount *refund_amount_to_cmp;
+
+  unsigned int *results_matching;
+
+  unsigned int results_length;
+};
+
+
+static void
+lookup_refunds_cb (void *cls,
+                   const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                   const struct TALER_Amount *refund_amount)
+{
+  struct TestLookupRefunds_Closure *cmp = cls;
+  if (NULL == cmp)
+    return;
+  cmp->results_length += 1;
+  for (unsigned int i = 0; cmp->refunds_to_cmp_length > i; ++i)
+  {
+    if ((0 == GNUNET_memcmp (&cmp->coin_pub_to_cmp[i],
+                             coin_pub)) &&
+        (GNUNET_OK == TALER_amount_cmp_currency (&cmp->refund_amount_to_cmp[i],
+                                                 refund_amount)) &&
+        (0 == TALER_amount_cmp (&cmp->refund_amount_to_cmp[i],
+                                refund_amount)))
+    {
+      cmp->results_matching[i] += 1;
+    }
+  }
+}
+
+
+static int
+test_lookup_refunds (const char *instance_id,
+                     const struct GNUNET_HashCode *h_contract_terms,
+                     unsigned int refunds_length,
+                     const struct TALER_CoinSpendPublicKeyP *coin_pubs,
+                     const struct TALER_Amount *refund_amounts)
+{
+  unsigned int results_matching[refunds_length];
+  struct TestLookupRefunds_Closure cmp = {
+    .refunds_to_cmp_length = refunds_length,
+    .coin_pub_to_cmp = coin_pubs,
+    .refund_amount_to_cmp = refund_amounts,
+    .results_matching = results_matching,
+    .results_length = 0
+  };
+  memset (results_matching, 0, sizeof (unsigned int) * refunds_length);
+  if (1 != plugin->lookup_refunds (plugin->cls,
+                                   instance_id,
+                                   h_contract_terms,
+                                   &lookup_refunds_cb,
+                                   &cmp))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refunds failed\n");
+    return 1;
+  }
+  if (refunds_length != cmp.results_length)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refunds failed: incorrect number of results 
returned\n");
+    return 1;
+  }
+  for (unsigned int i = 0; refunds_length > i; ++i)
+  {
+    if (1 != cmp.results_matching[i])
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Lookup refunds failed: mismatched data\n");
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+struct RefundData
+{
+  struct GNUNET_TIME_Absolute timestamp;
+  const char *reason;
+  struct TALER_Amount refund_amount;
+  struct TALER_CoinSpendPublicKeyP *coin_pub;
+  const char *exchange_url;
+};
+
+struct RefundProofData
+{
+  struct TALER_Amount refund_fee;
+  struct TALER_ExchangeSignatureP exchange_sig;
+};
+
+
+struct TestLookupRefundsDetailed_Closure
+{
+  unsigned int refunds_to_cmp_length;
+
+  const struct RefundData *refunds_to_cmp;
+
+  unsigned int *results_matching;
+
+  unsigned int results_length;
+};
+
+
+static void
+lookup_refunds_detailed_cb (void *cls,
+                            uint64_t refund_serial,
+                            struct GNUNET_TIME_Absolute timestamp,
+                            const struct TALER_CoinSpendPublicKeyP *coin_pub,
+                            const char *exchange_url,
+                            uint64_t rtransaction_id,
+                            const char *reason,
+                            const struct TALER_Amount *refund_amount)
+{
+  struct TestLookupRefundsDetailed_Closure *cmp = cls;
+  if (NULL == cmp)
+    return;
+  cmp->results_length += 1;
+  for (unsigned int i = 0; cmp->refunds_to_cmp_length > i; ++i)
+  {
+    if ((cmp->refunds_to_cmp[i].timestamp.abs_value_us ==
+         timestamp.abs_value_us) &&
+        (0 == GNUNET_memcmp (cmp->refunds_to_cmp[i].coin_pub,
+                             coin_pub)) &&
+        (0 == strcmp (cmp->refunds_to_cmp[i].exchange_url,
+                      exchange_url)) &&
+        (0 == strcmp (cmp->refunds_to_cmp[i].reason,
+                      reason)) &&
+        (GNUNET_OK == TALER_amount_cmp_currency (
+           &cmp->refunds_to_cmp[i].refund_amount,
+           refund_amount)) &&
+        (0 == TALER_amount_cmp (&cmp->refunds_to_cmp[i].refund_amount,
+                                refund_amount)))
+    {
+      cmp->results_matching[i] += 1;
+    }
+  }
+}
+
+
+static int
+test_lookup_refunds_detailed (const char *instance_id,
+                              const struct GNUNET_HashCode *h_contract_terms,
+                              unsigned int refunds_length,
+                              const struct RefundData *refunds)
+{
+  unsigned int results_matching[refunds_length];
+  struct TestLookupRefundsDetailed_Closure cmp = {
+    .refunds_to_cmp_length = refunds_length,
+    .refunds_to_cmp = refunds,
+    .results_matching = results_matching,
+    .results_length = 0
+  };
+  memset (results_matching, 0, sizeof (unsigned int) * refunds_length);
+  if (1 != plugin->lookup_refunds_detailed (plugin->cls,
+                                            instance_id,
+                                            h_contract_terms,
+                                            &lookup_refunds_detailed_cb,
+                                            &cmp))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refunds detailed failed\n");
+    return 1;
+  }
+  if (refunds_length != cmp.results_length)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refunds detailed failed: incorrect number of 
results\n");
+    return 1;
+  }
+  for (unsigned int i = 0; refunds_length > i; ++i)
+  {
+    if (1 != cmp.results_matching[i])
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Lookup refunds detailed failed: mismatched data\n");
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
+static int
+test_lookup_refund_proof (uint64_t refund_serial,
+                          const struct
+                          TALER_ExchangeSignatureP *expected_exchange_sig,
+                          const struct
+                          TALER_ExchangePublicKeyP *expected_exchange_pub)
+{
+  struct TALER_ExchangeSignatureP exchange_sig;
+  struct TALER_ExchangePublicKeyP exchange_pub;
+  if (1 != plugin->lookup_refund_proof (plugin->cls,
+                                        refund_serial,
+                                        &exchange_sig,
+                                        &exchange_pub))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refund proof failed\n");
+    return 1;
+  }
+  if ((0 != GNUNET_memcmp (expected_exchange_sig,
+                           &exchange_sig)) ||
+      (0 != GNUNET_memcmp (expected_exchange_pub,
+                           &exchange_pub)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Lookup refund proof failed: mismatched data\n");
+    return 1;
+  }
+  return 0;
+}
+
+
+struct TestRefunds_Closure
+{
+  /**
+   * The instance settings
+   */
+  struct TALER_MERCHANTDB_InstanceSettings is;
+
+  /**
+   * The instance public key
+   */
+  struct TALER_MerchantPublicKeyP merchant_pub;
+
+  /**
+   * The instance private key
+   */
+  struct TALER_MerchantPrivateKeyP merchant_priv;
+
+  /**
+   * The merchant account
+   */
+  struct TALER_MERCHANTDB_AccountDetails account;
+
+  /**
+   * The exchange public key
+   */
+  struct TALER_ExchangePublicKeyP exchange_pub;
+
+  /**
+   * The exchange private key
+   */
+  struct TALER_ExchangePrivateKeyP exchange_priv;
+
+  /**
+   * The master public key
+   */
+  struct TALER_MasterPublicKeyP master_pub;
+
+  /**
+   * The master private key
+   */
+  struct TALER_MasterPrivateKeyP master_priv;
+
+  /**
+   * The master signature
+   */
+  struct TALER_MasterSignatureP master_sig;
+
+  /**
+   * The exchange signkey start date
+   */
+  struct GNUNET_TIME_Absolute signkey_start;
+
+  /**
+   * The exchange signkey expire date
+   */
+  struct GNUNET_TIME_Absolute signkey_expire;
+
+  /**
+   * The exchange signkey end date
+   */
+  struct GNUNET_TIME_Absolute signkey_end;
+
+  /**
+   * The order data
+   */
+  struct OrderData order;
+
+  /**
+   * The deposit data
+   */
+  struct DepositData deposit;
+
+  /**
+   * The refund data
+   */
+  struct RefundData refund;
+
+  /**
+   * The refund proof data
+   */
+  struct RefundProofData refund_proof;
+};
+
+
+static void
+pre_test_refunds (struct TestRefunds_Closure *cls)
+{
+  struct GNUNET_TIME_Absolute pay_deadline;
+  struct GNUNET_TIME_Absolute refund_deadline;
+  struct TALER_ExchangeSigningKeyValidityPS exch_sign = {
+    .purpose = {
+      .size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS)),
+      .purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY)
+    }
+
+
+  };
+  struct TALER_CoinSpendPrivateKeyP coin_priv;
+  struct TALER_DepositRequestPS deposit_sign = {
+    .purpose = {
+      .size = htonl (sizeof (struct TALER_DepositRequestPS)),
+      .purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT)
+    }
+
+
+  };
+  struct TALER_RefundRequestPS refund_sign = {
+    .purpose = {
+      .size = htonl (sizeof (struct TALER_RefundRequestPS)),
+      .purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND)
+    }
+
+
+  };
+
+  /* Instance */
+  GNUNET_CRYPTO_eddsa_key_create (&cls->merchant_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->merchant_priv.eddsa_priv,
+                                      &cls->merchant_pub.eddsa_pub);
+  cls->is.id = "test_inst_refunds";
+  cls->is.name = "Test";
+  cls->is.address = json_array ();
+  GNUNET_assert (NULL != cls->is.address);
+  GNUNET_assert (0 == json_array_append (cls->is.address,
+                                         json_string ("123 Example St")));
+  cls->is.jurisdiction = json_array ();
+  GNUNET_assert (NULL != cls->is.jurisdiction);
+  GNUNET_assert (0 == json_array_append (cls->is.jurisdiction,
+                                         json_string ("Ohio")));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1200.40",
+                                         &cls->is.default_max_deposit_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1200.40",
+                                         &cls->is.default_max_wire_fee));
+  cls->is.default_wire_fee_amortization = 1;
+  cls->is.default_wire_transfer_delay = GNUNET_TIME_relative_get_minute_ ();
+  cls->is.default_pay_delay = GNUNET_TIME_relative_get_second_ ();
+
+  /* Signing key */
+  GNUNET_CRYPTO_eddsa_key_create (&cls->exchange_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->exchange_priv.eddsa_priv,
+                                      &cls->exchange_pub.eddsa_pub);
+  GNUNET_CRYPTO_eddsa_key_create (&cls->master_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&cls->master_priv.eddsa_priv,
+                                      &cls->master_pub.eddsa_pub);
+  GNUNET_CRYPTO_eddsa_sign (&cls->master_priv.eddsa_priv,
+                            &exch_sign,
+                            &cls->master_sig.eddsa_signature);
+  cls->signkey_start = GNUNET_TIME_absolute_get ();
+  cls->signkey_expire = GNUNET_TIME_absolute_get ();
+  cls->signkey_end = GNUNET_TIME_absolute_get ();
+
+  /* Order */
+  pay_deadline = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+                                           GNUNET_TIME_UNIT_DAYS);
+  refund_deadline = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
+                                              GNUNET_TIME_UNIT_WEEKS);
+  GNUNET_TIME_round_abs (&pay_deadline);
+  GNUNET_TIME_round_abs (&refund_deadline);
+  cls->order.id = "test_orders_od_1";
+  cls->order.pay_deadline = pay_deadline;
+  cls->order.contract = json_object ();
+  json_object_set (cls->order.contract,
+                   "fulfillment_url",
+                   json_string ("a"));
+  json_object_set (cls->order.contract,
+                   "pay_deadline",
+                   GNUNET_JSON_from_time_abs (pay_deadline));
+  json_object_set (cls->order.contract,
+                   "refund_deadline",
+                   GNUNET_JSON_from_time_abs (refund_deadline));
+
+  /* Deposit */
+  cls->deposit.timestamp = GNUNET_TIME_absolute_get ();
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_hash (cls->order.contract,
+                                  &cls->deposit.h_contract_terms));
+  GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv);
+  GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv,
+                                      &cls->deposit.coin_pub.eddsa_pub);
+  cls->deposit.exchange_url = "test-exchange";
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:50.00",
+                                         &cls->deposit.amount_with_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1.00",
+                                         &cls->deposit.deposit_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:1.50",
+                                         &cls->deposit.refund_fee));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:2.00",
+                                         &cls->deposit.wire_fee));
+  cls->deposit.h_wire = cls->account.h_wire;
+  deposit_sign.h_contract_terms = cls->deposit.h_contract_terms;
+  deposit_sign.h_wire = cls->deposit.h_wire;
+  deposit_sign.wallet_timestamp = GNUNET_TIME_absolute_hton (
+    GNUNET_TIME_absolute_get ());
+  deposit_sign.refund_deadline = GNUNET_TIME_absolute_hton (
+    GNUNET_TIME_absolute_get ());
+  TALER_amount_hton (&deposit_sign.amount_with_fee,
+                     &cls->deposit.amount_with_fee);
+  TALER_amount_hton (&deposit_sign.deposit_fee,
+                     &cls->deposit.deposit_fee);
+  deposit_sign.merchant = cls->merchant_pub;
+  deposit_sign.coin_pub = cls->deposit.coin_pub;
+  GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv,
+                            &deposit_sign,
+                            &cls->deposit.exchange_sig.eddsa_signature);
+
+  /* Refund */
+  cls->refund.timestamp = GNUNET_TIME_absolute_get ();
+  cls->refund.reason = "some reason";
+  cls->refund.refund_amount = cls->deposit.amount_with_fee;
+  cls->refund.coin_pub = &cls->deposit.coin_pub;
+  cls->refund.exchange_url = cls->deposit.exchange_url;
+
+  /* Refund proof */
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_string_to_amount ("EUR:0.02",
+                                         &cls->refund_proof.refund_fee));
+  GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv,
+                            &refund_sign,
+                            &cls->refund_proof.exchange_sig.eddsa_signature);
+}
+
+
+static void
+post_test_refunds (struct TestRefunds_Closure *cls)
+{
+  /* Instance */
+  json_decref (cls->is.address);
+  json_decref (cls->is.jurisdiction);
+
+  /* Order */
+  json_decref (cls->order.contract);
+}
+
+
+static int
+run_test_refunds (struct TestRefunds_Closure *cls)
+{
+  /* Insert an instance */
+  TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub,
+                                          &cls->merchant_priv,
+                                          &cls->is));
+
+  /* Insert an account */
+  TEST_RET_ON_FAIL (test_insert_account (cls->is.id,
+                                         &cls->account));
+
+  /* Insert an order */
+  TEST_RET_ON_FAIL (test_insert_order (cls->is.id,
+                                       cls->order.id,
+                                       cls->order.pay_deadline,
+                                       cls->order.contract));
+
+  /* Insert contract terms */
+  TEST_RET_ON_FAIL (test_insert_contract_terms (cls->is.id,
+                                                cls->order.id,
+                                                cls->order.contract));
+
+  /* Insert a signing key */
+  TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->master_pub,
+                                                  &cls->exchange_pub,
+                                                  cls->signkey_start,
+                                                  cls->signkey_expire,
+                                                  cls->signkey_end,
+                                                  &cls->master_sig));
+
+  /* Insert a deposit */
+  TEST_RET_ON_FAIL (test_insert_deposit (cls->is.id,
+                                         &cls->exchange_pub,
+                                         &cls->deposit));
+
+  /* Test refund coin */
+  if (1 != plugin->refund_coin (plugin->cls,
+                                cls->is.id,
+                                &cls->deposit.h_contract_terms,
+                                cls->refund.timestamp,
+                                cls->refund.coin_pub,
+                                cls->refund.reason))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Refund coin failed\n");
+    return 1;
+  }
+
+  /* Test lookup refunds */
+  TEST_RET_ON_FAIL (test_lookup_refunds (cls->is.id,
+                                         &cls->deposit.h_contract_terms,
+                                         1,
+                                         cls->refund.coin_pub,
+                                         &cls->deposit.amount_with_fee));
+
+  /* Test lookup refunds detailed */
+  TEST_RET_ON_FAIL (test_lookup_refunds_detailed (cls->is.id,
+                                                  
&cls->deposit.h_contract_terms,
+                                                  1,
+                                                  &cls->refund));
+
+  /* Test insert refund proof */
+  if (1 != plugin->insert_refund_proof (plugin->cls,
+                                        1, // TODO: get this from lookup
+                                        &cls->refund_proof.refund_fee,
+                                        &cls->refund_proof.exchange_sig,
+                                        &cls->exchange_pub))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Insert refund proof failed\n");
+    return 1;
+  }
+
+  /* Test lookup refund proof */
+  TEST_RET_ON_FAIL (test_lookup_refund_proof (1,
+                                              &cls->refund_proof.exchange_sig,
+                                              &cls->exchange_pub));
+
+  return 0;
+}
+
+
+static int
+test_refunds (void *cls)
+{
+  struct TestRefunds_Closure test_cls;
+  pre_test_refunds (&test_cls);
+  int test_result = run_test_refunds (&test_cls);
+  post_test_refunds (&test_cls);
+  return test_result;
+}
+
+
 /**
  * Function that runs all tests and returns 1 upon error, 0 on success.
  */
@@ -2764,6 +3357,7 @@ run_tests (void *cls)
   TEST_RET_ON_FAIL (test_deposits (cls));
   TEST_RET_ON_FAIL (test_transfers (cls));
   TEST_RET_ON_FAIL (test_tips (cls));
+  TEST_RET_ON_FAIL (test_refunds (cls));
 
   return 0;
 }
diff --git a/src/include/taler_merchantdb_plugin.h 
b/src/include/taler_merchantdb_plugin.h
index 34aba15..3262c35 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1209,6 +1209,7 @@ struct TALER_MERCHANTDB_Plugin
    * @param cls closure
    * @param instance_id instance to refund payment for
    * @param h_contract_terms hash of the contract to refund coin for
+   * @param refund_timestamp timestamp of when the coin was refunded
    * @param coin_pub public key of the coin to refund (fully)
    * @param reason text justifying the refund
    * @return transaction status
@@ -1220,6 +1221,7 @@ struct TALER_MERCHANTDB_Plugin
   (*refund_coin)(void *cls,
                  const char *instance_id,
                  const struct GNUNET_HashCode *h_contract_terms,
+                 struct GNUNET_TIME_Absolute refund_timestamp,
                  const struct TALER_CoinSpendPublicKeyP *coin_pub,
                  const char *reason);
 

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