diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-28 17:16:43 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-28 17:16:43 -0400 |
commit | 7a205972630cc560abb3dd56448b6b0566f0487b (patch) | |
tree | cb033ebcbb7925ab4481a82382a2a9dd49db4f62 /src/backenddb | |
parent | d809c7b29120f2f33e078e402a2b42f624dd20aa (diff) | |
download | merchant-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.sql | 1 | ||||
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 10 | ||||
-rw-r--r-- | src/backenddb/test_merchantdb.c | 686 |
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; } |