summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-28 17:16:43 -0400
committerJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-28 17:16:43 -0400
commit7a205972630cc560abb3dd56448b6b0566f0487b (patch)
treecb033ebcbb7925ab4481a82382a2a9dd49db4f62 /src/backenddb
parentd809c7b29120f2f33e078e402a2b42f624dd20aa (diff)
downloadmerchant-7a205972630cc560abb3dd56448b6b0566f0487b.tar.gz
merchant-7a205972630cc560abb3dd56448b6b0566f0487b.tar.bz2
merchant-7a205972630cc560abb3dd56448b6b0566f0487b.zip
backenddb tests for refunds
Diffstat (limited to 'src/backenddb')
-rw-r--r--src/backenddb/drop0001.sql1
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c10
-rw-r--r--src/backenddb/test_merchantdb.c686
3 files changed, 648 insertions, 49 deletions
diff --git a/src/backenddb/drop0001.sql b/src/backenddb/drop0001.sql
index 07205697..5295febf 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 30567ed7..ae4fc359 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 2e8416b2..5012e95f 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -1579,6 +1579,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,
const struct DepositData *deposit)
@@ -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;
}