diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-27 14:44:41 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-05-27 14:44:41 -0400 |
commit | 8fdaf760379e3c3edae52ee3552e625482e02ad0 (patch) | |
tree | 04ac5c490611ccfb5af5254a18cad06c8a5ddc56 | |
parent | e2333817a6767933608c6d3bd3216a9fcd3033e7 (diff) | |
download | merchant-8fdaf760379e3c3edae52ee3552e625482e02ad0.tar.gz merchant-8fdaf760379e3c3edae52ee3552e625482e02ad0.tar.bz2 merchant-8fdaf760379e3c3edae52ee3552e625482e02ad0.zip |
added more tests for contract terms, deposits, and transfers
-rw-r--r-- | src/backenddb/drop0001.sql | 1 | ||||
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 4 | ||||
-rw-r--r-- | src/backenddb/test_merchantdb.c | 613 |
3 files changed, 528 insertions, 90 deletions
diff --git a/src/backenddb/drop0001.sql b/src/backenddb/drop0001.sql index f0bfeb74..07205697 100644 --- a/src/backenddb/drop0001.sql +++ b/src/backenddb/drop0001.sql @@ -39,6 +39,7 @@ 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_credits CASCADE; +DROP TABLE IF EXISTS merchant_transfers CASCADE; DROP TABLE IF EXISTS merchant_transfer_signatures CASCADE; DROP TABLE IF EXISTS merchant_transfer_by_coin CASCADE; DROP TABLE IF EXISTS merchant_tip_reserves CASCADE; diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index a5105a34..7c4b543a 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -5961,6 +5961,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " order_id" ",order_serial" ",creation_time" + ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ + ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_orders" " WHERE merchant_orders.merchant_serial=" " (SELECT merchant_serial " @@ -5979,6 +5981,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " order_id" ",order_serial" ",creation_time" + ",CAST($6 as BOOL)" /* otherwise $6 is unused and Postgres unhappy */ + ",CAST($7 as BOOL)" /* otherwise $7 is unused and Postgres unhappy */ " FROM merchant_contract_terms" " WHERE merchant_contract_terms.merchant_serial=" " (SELECT merchant_serial " diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c index 6ed0b217..2ee1f0eb 100644 --- a/src/backenddb/test_merchantdb.c +++ b/src/backenddb/test_merchantdb.c @@ -146,20 +146,21 @@ lookup_instances_cb (void *cls, unsigned int accounts_length, const struct TALER_MERCHANTDB_AccountDetails accounts[]) { - if (cls == NULL) - return; struct TestLookupInstances_Closure *cmp = cls; + if (NULL == cmp) + return; cmp->results_length += 1; /* Look through the closure and test each instance for equality */ for (unsigned int i = 0; cmp->instances_to_cmp_length > i; ++i) { + int accounts_matching[accounts_length]; + bool accounts_match = true; if (0 != check_instances_equal (cmp->instances_to_cmp[i].instance, is)) continue; if (accounts_length != cmp->instances_to_cmp[i].accounts_length) continue; /* Count matches between the accounts found and accounts in cls */ - int accounts_matching[accounts_length]; for (unsigned int j = 0; accounts_length > j; ++j) accounts_matching[j] = 0; for (unsigned int j = 0; accounts_length > j; ++j) @@ -172,7 +173,6 @@ lookup_instances_cb (void *cls, } } /* Each account from the lookup should match with one and only one from cls */ - bool accounts_match = true; for (unsigned int j = 0; accounts_length > j; ++j) if (1 != accounts_matching[j]) accounts_match = false; @@ -205,24 +205,24 @@ test_lookup_instances (bool active_only, unsigned int instances_length, struct InstanceWithAccounts instances[]) { - struct TestLookupInstances_Closure cls; - cls.instances_to_cmp_length = instances_length; - cls.instances_to_cmp = instances; unsigned int results_matching[instances_length]; - for (unsigned int i = 0; instances_length > i; ++i) - results_matching[i] = 0; - cls.results_matching = results_matching; - cls.results_length = 0; + struct TestLookupInstances_Closure cmp = { + .instances_to_cmp_length = instances_length, + .instances_to_cmp = instances, + .results_matching = results_matching, + .results_length = 0 + }; + memset (results_matching, 0, sizeof (unsigned int) * instances_length); if (0 > plugin->lookup_instances (plugin->cls, active_only, &lookup_instances_cb, - &cls)) + &cmp)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup instances failed\n"); return 1; } - if (instances_length != cls.results_length) + if (instances_length != cmp.results_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup instances failed: incorrect number of results\n"); @@ -230,7 +230,7 @@ test_lookup_instances (bool active_only, } for (unsigned int i = 0; instances_length > i; ++i) { - if (1 != cls.results_matching[i]) + if (1 != cmp.results_matching[i]) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup instances failed: mismatched data\n"); @@ -348,16 +348,21 @@ post_test_instances (struct TestInstances_Closure *cls) static int run_test_instances (struct TestInstances_Closure *cls) { + struct InstanceWithAccounts instances[1] = { + { + .accounts_length = 0, + .accounts = NULL, + .instance = &cls->is + } + }; + uint64_t account_serial; + /* Test inserting an instance */ TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub, &cls->merchant_priv, &cls->is)); /* Test lookup instances- is our new instance there? */ - struct InstanceWithAccounts instances[1]; - instances[0].accounts_length = 0; - instances[0].accounts = NULL; - instances[0].instance = &cls->is; TEST_RET_ON_FAIL (test_lookup_instances (false, 1, instances)); @@ -402,7 +407,6 @@ run_test_instances (struct TestInstances_Closure *cls) /* Test multiple accounts */ /* Test lookup account */ - uint64_t account_serial; if (1 != plugin->lookup_account (plugin->cls, cls->is.id, cls->accounts[0].payto_uri, @@ -512,9 +516,9 @@ static void lookup_products_cb (void *cls, const char *product_id) { - if (cls == NULL) - return; struct TestLookupProducts_Closure *cmp = cls; + if (NULL == cmp) + return; cmp->results_length += 1; for (unsigned int i = 0; cmp->products_to_cmp_length > i; ++i) { @@ -606,14 +610,14 @@ test_lookup_products (const char *is, unsigned int products_length, const char **product_ids) { - struct TestLookupProducts_Closure cls; - cls.products_to_cmp_length = products_length; - cls.product_ids_to_cmp = product_ids; unsigned int results_matching[products_length]; - for (unsigned int i = 0; products_length > i; ++i) - results_matching[i] = 0; - cls.results_matching = results_matching; - cls.results_length = 0; + struct TestLookupProducts_Closure cls = { + .products_to_cmp_length = products_length, + .product_ids_to_cmp = product_ids, + .results_matching = results_matching, + .results_length = 0 + }; + memset (results_matching, 0, sizeof (unsigned int) * products_length); if (0 > plugin->lookup_products (plugin->cls, is, &lookup_products_cb, @@ -829,6 +833,26 @@ run_test_products (struct TestProducts_Closure *cls) 2, cls->product_ids)); + /* Test locking */ + /* + struct GNUNET_Uuid uuid; + uuid.value[0] = 0x1287346a; + struct GNUNET_TIME_Absolute refund_deadline = + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + GNUNET_TIME_UNIT_WEEKS); + if (1 != plugin->lock_product (plugin->cls, + cls->is.id, + cls->product_ids[0], + &uuid, + 0, + refund_deadline)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lock product failed\n"); + return 1; + } + */ + /* Test product deletion */ TEST_RET_ON_FAIL (test_delete_product (cls->is.id, cls->product_ids[1])); @@ -889,9 +913,9 @@ lookup_orders_cb (void *cls, uint64_t order_serial, struct GNUNET_TIME_Absolute timestamp) { - if (cls == NULL) - return; struct TestLookupOrders_Closure *cmp = cls; + if (NULL == cmp) + return; unsigned int i = cmp->results_length; cmp->results_length += 1; if (cmp->orders_to_cmp_length > i) @@ -963,12 +987,14 @@ test_lookup_orders (const char *is, unsigned int orders_length, const char **order_ids_to_cmp) { - struct TestLookupOrders_Closure cls; - cls.orders_to_cmp_length = orders_length; - cls.order_ids_to_cmp = order_ids_to_cmp; bool results_match[orders_length]; - cls.results_match = results_match; - cls.results_length = 0; + struct TestLookupOrders_Closure cls = { + .orders_to_cmp_length = orders_length, + .order_ids_to_cmp = order_ids_to_cmp, + .results_match = results_match, + .results_length = 0 + }; + memset (results_match, 0, sizeof (bool) * orders_length); if (0 > plugin->lookup_orders (plugin->cls, is, of, @@ -982,7 +1008,8 @@ test_lookup_orders (const char *is, if (orders_length != cls.results_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Lookup orders failed: incorrect number of results\n"); + "Lookup orders failed: incorrect number of results (%d)\n", + cls.results_length); return 1; } for (unsigned int i = 0; orders_length > i; ++i) @@ -1014,6 +1041,86 @@ test_delete_order (const char *is, } +static int +test_insert_contract_terms (const char *is, + const char *order_id, + json_t *contract) +{ + if (1 != plugin->insert_contract_terms (plugin->cls, + is, + order_id, + contract)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Insert contract terms failed\n"); + return 1; + } + return 0; +} + + +static int +test_lookup_contract_terms (const char *instance_id, + const char *order_id, + const json_t *expected_contract) +{ + json_t *contract = NULL; + if (1 != plugin->lookup_contract_terms (plugin->cls, + instance_id, + order_id, + &contract)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup contract terms failed\n"); + if (NULL != contract) + json_decref (contract); + return 1; + } + if (1 != json_equal (expected_contract, + contract)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup contract terms failed: mismatched data\n"); + if (NULL != contract) + json_decref (contract); + return 1; + } + if (NULL != contract) + json_decref (contract); + return 0; +} + + +static int +test_lookup_order_status (const char *instance_id, + const char *order_id, + const struct GNUNET_HashCode *expected_contract_terms, + bool expected_paid) +{ + struct GNUNET_HashCode h_contract_terms; + bool order_paid = false; + if (1 != plugin->lookup_order_status (plugin->cls, + instance_id, + order_id, + &h_contract_terms, + &order_paid)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup order status failed\n"); + return 1; + } + if ((expected_paid != order_paid) || + (0 != GNUNET_memcmp (&h_contract_terms, + expected_contract_terms))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup order status/deposit failed: mismatched data\n"); + return 1; + } + return 0; +} + + /** * Container for order data */ @@ -1067,6 +1174,13 @@ struct TestOrders_Closure static void pre_test_orders (struct TestOrders_Closure *cls) { + struct GNUNET_TIME_Absolute pay_deadline = + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + GNUNET_TIME_UNIT_DAYS); + struct GNUNET_TIME_Absolute refund_deadline = + GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), + GNUNET_TIME_UNIT_WEEKS); + /* Instance */ GNUNET_CRYPTO_eddsa_key_create (&cls->merchant_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_get_public (&cls->merchant_priv.eddsa_priv, @@ -1094,10 +1208,23 @@ pre_test_orders (struct TestOrders_Closure *cls) /* Orders */ cls->orders[0].id = "test_orders_od_0"; cls->orders[0].pay_deadline = GNUNET_TIME_absolute_get_zero_ (); - cls->orders[0].contract = json_array (); + cls->orders[0].contract = json_object (); GNUNET_assert (NULL != cls->orders[0].contract); - GNUNET_assert (0 == json_array_append (cls->orders[0].contract, - json_string ("Dummy contract"))); + 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); + json_object_set (cls->orders[0].contract, + "fulfillment_url", + json_string ("a")); + json_object_set (cls->orders[0].contract, + "pay_deadline", + GNUNET_JSON_from_time_abs (pay_deadline)); + json_object_set (cls->orders[0].contract, + "refund_deadline", + GNUNET_JSON_from_time_abs (refund_deadline)); cls->orders[1].id = "test_orders_od_1"; cls->orders[1].pay_deadline = GNUNET_TIME_absolute_get_zero_ (); @@ -1122,6 +1249,24 @@ post_test_orders (struct TestOrders_Closure *cls) static int run_test_orders (struct TestOrders_Closure *cls) { + struct TALER_MERCHANTDB_OrderFilter filter = { + .paid = TALER_MERCHANTDB_YNA_ALL, + .refunded = TALER_MERCHANTDB_YNA_ALL, + .wired = TALER_MERCHANTDB_YNA_ALL, + .date = GNUNET_TIME_absolute_get_zero_ (), + .start_row = 0, + .delta = 8 + }; + const char *order_id_list[2] = { + cls->orders[0].id, + cls->orders[1].id + }; + struct GNUNET_HashCode h_contract_terms; + GNUNET_assert (GNUNET_OK == + TALER_JSON_hash (cls->orders[0].contract, + &h_contract_terms)); + struct GNUNET_TIME_Relative expiration = GNUNET_TIME_UNIT_MONTHS; + /* Insert the instance */ TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub, &cls->merchant_priv, @@ -1145,31 +1290,62 @@ run_test_orders (struct TestOrders_Closure *cls) cls->orders[1].id, cls->orders[1].pay_deadline, cls->orders[1].contract)); - struct TALER_MERCHANTDB_OrderFilter filter; - filter.paid = TALER_MERCHANTDB_YNA_ALL; - filter.refunded = TALER_MERCHANTDB_YNA_ALL; - filter.wired = TALER_MERCHANTDB_YNA_ALL; - filter.date = GNUNET_TIME_absolute_get_zero_ (); - filter.start_row = 0; - filter.delta = 8; - const char *order_id_list[2] = { - cls->orders[0].id, - cls->orders[1].id - }; + TEST_RET_ON_FAIL (test_lookup_orders (cls->is.id, &filter, 2, order_id_list)); - /* Test delete order */ - TEST_RET_ON_FAIL (test_delete_order (cls->is.id, - cls->orders[1].id)); + /* Test inserting contract terms */ + TEST_RET_ON_FAIL (test_insert_contract_terms (cls->is.id, + cls->orders[0].id, + cls->orders[0].contract)); + + /* Test lookup contract terms */ + TEST_RET_ON_FAIL (test_lookup_contract_terms (cls->is.id, + cls->orders[0].id, + cls->orders[0].contract)); + + /* Test lookup order status */ + TEST_RET_ON_FAIL (test_lookup_order_status (cls->is.id, + cls->orders[0].id, + &h_contract_terms, + false)); + + /* Test marking contracts as paid */ + if (1 != plugin->mark_contract_paid (plugin->cls, + cls->is.id, + &h_contract_terms, + "test_orders_session")) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Mark contract as paid failed\n"); + return 1; + } + TEST_RET_ON_FAIL (test_lookup_order_status (cls->is.id, + cls->orders[0].id, + &h_contract_terms, + true)); + filter.paid = TALER_MERCHANTDB_YNA_YES; TEST_RET_ON_FAIL (test_lookup_orders (cls->is.id, &filter, 1, order_id_list)); + + /* Test deleting contract terms */ + if (1 != plugin->delete_contract_terms (plugin->cls, + cls->is.id, + cls->orders[0].id, + expiration)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Delete contract terms failed\n"); + return 1; + } + + /* Test delete order */ TEST_RET_ON_FAIL (test_delete_order (cls->is.id, - cls->orders[0].id)); + cls->orders[1].id)); TEST_RET_ON_FAIL (test_lookup_orders (cls->is.id, &filter, 0, @@ -1254,9 +1430,9 @@ lookup_deposits_cb (void *cls, const struct TALER_Amount *refund_fee, const struct TALER_Amount *wire_fee) { - if (NULL == cls) - return; struct TestLookupDeposits_Closure *cmp = cls; + if (NULL == cmp) + return; cmp->results_length += 1; for (unsigned int i = 0; cmp->deposits_to_cmp_length > i; ++i) { @@ -1288,6 +1464,62 @@ lookup_deposits_cb (void *cls, } +static void +lookup_deposits_contract_coin_cb (void *cls, + const char *exchange_url, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + const struct TALER_Amount *refund_fee, + const struct TALER_Amount *wire_fee, + const struct GNUNET_HashCode *h_wire, + struct GNUNET_TIME_Absolute deposit_timestamp, + struct GNUNET_TIME_Absolute refund_deadline, + const struct + TALER_ExchangeSignatureP *exchange_sig, + const struct + TALER_ExchangePublicKeyP *exchange_pub) +{ + struct TestLookupDeposits_Closure *cmp = cls; + if (NULL == cmp) + return; + cmp->results_length += 1; + for (unsigned int i = 0; cmp->deposits_to_cmp_length > i; ++i) + { + if ((cmp->deposits_to_cmp[i].timestamp.abs_value_us == + deposit_timestamp.abs_value_us) && + (0 == strcmp (cmp->deposits_to_cmp[i].exchange_url, + exchange_url)) && + (GNUNET_OK == TALER_amount_cmp_currency ( + &cmp->deposits_to_cmp[i].amount_with_fee, + amount_with_fee)) && + (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].amount_with_fee, + amount_with_fee)) && + (GNUNET_OK == TALER_amount_cmp_currency ( + &cmp->deposits_to_cmp[i].deposit_fee, + deposit_fee)) && + (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].deposit_fee, + deposit_fee)) && + (GNUNET_OK == TALER_amount_cmp_currency ( + &cmp->deposits_to_cmp[i].refund_fee, + refund_fee)) && + (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].refund_fee, + refund_fee)) && + (GNUNET_OK == TALER_amount_cmp_currency ( + &cmp->deposits_to_cmp[i].wire_fee, + wire_fee)) && + (0 == TALER_amount_cmp (&cmp->deposits_to_cmp[i].wire_fee, + wire_fee)) && + (0 == GNUNET_memcmp (&cmp->deposits_to_cmp[i].h_wire, + h_wire)) && + (0 == GNUNET_memcmp (&cmp->deposits_to_cmp[i].exchange_sig, + exchange_sig))) + { + cmp->results_matching[i] += 1; + } + } +} + + static int test_insert_deposit (const char *is, const struct TALER_ExchangePublicKeyP *exchange_pub, @@ -1321,25 +1553,73 @@ test_lookup_deposits (const char *is, unsigned int deposits_length, const struct DepositData *deposits) { - struct TestLookupDeposits_Closure cls; - cls.deposits_to_cmp_length = deposits_length; - cls.deposits_to_cmp = deposits; unsigned int results_matching[deposits_length]; - for (unsigned int i = 0; deposits_length > i; ++i) - results_matching[i] = 0; - cls.results_matching = results_matching; - cls.results_length = 0; + struct TestLookupDeposits_Closure cmp = { + .deposits_to_cmp_length = deposits_length, + .deposits_to_cmp = deposits, + .results_matching = results_matching, + .results_length = 0 + }; + memset (results_matching, 0, sizeof (unsigned int) * deposits_length); if (0 > plugin->lookup_deposits (plugin->cls, is, h_contract_terms, &lookup_deposits_cb, - &cls)) + &cmp)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup deposits failed\n"); return 1; } - if (deposits_length != cls.results_length) + if (deposits_length != cmp.results_length) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup deposits failed: incorrect number of results returned\n"); + return 1; + } + for (unsigned int i = 0; deposits_length > i; ++i) + { + if (cmp.results_matching[i] != 1) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup deposits failed: mismatched data\n"); + return 1; + } + } + return 0; +} + + +static int +test_lookup_deposits_contract_and_coin (const char *instance_id, + const struct + GNUNET_HashCode *h_contract, + const struct + TALER_CoinSpendPublicKeyP *coin_pub, + unsigned int deposits_length, + const struct DepositData *deposits) +{ + unsigned int results_matching[deposits_length]; + struct TestLookupDeposits_Closure cmp = { + .deposits_to_cmp_length = deposits_length, + .deposits_to_cmp = deposits, + .results_matching = results_matching, + .results_length = 0 + }; + memset (results_matching, 0, sizeof (unsigned int) * deposits_length); + if (0 > plugin->lookup_deposits_by_contract_and_coin (plugin->cls, + instance_id, + h_contract, + coin_pub, + & + lookup_deposits_contract_coin_cb, + &cmp)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup deposits by contract and coin failed\n"); + return 1; + } + if (deposits_length != cmp.results_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup deposits failed: incorrect number of results returned\n"); @@ -1347,7 +1627,7 @@ test_lookup_deposits (const char *is, } for (unsigned int i = 0; deposits_length > i; ++i) { - if (cls.results_matching[i] != 1) + if (cmp.results_matching[i] != 1) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup deposits failed: mismatched data\n"); @@ -1438,6 +1718,26 @@ struct TestDeposits_Closure static void pre_test_deposits (struct TestDeposits_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) + } + + + }; + /* Instance */ GNUNET_CRYPTO_eddsa_key_create (&cls->merchant_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_get_public (&cls->merchant_priv.eddsa_priv, @@ -1477,11 +1777,6 @@ pre_test_deposits (struct TestDeposits_Closure *cls) 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); - struct TALER_ExchangeSigningKeyValidityPS exch_sign; - exch_sign.purpose.size = htonl (sizeof (struct - TALER_ExchangeSigningKeyValidityPS)); - exch_sign.purpose.purpose = htonl ( - TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY); GNUNET_CRYPTO_eddsa_sign (&cls->master_priv.eddsa_priv, &exch_sign, &cls->master_sig.eddsa_signature); @@ -1490,12 +1785,10 @@ pre_test_deposits (struct TestDeposits_Closure *cls) cls->signkey_end = GNUNET_TIME_absolute_get (); /* Order */ - struct GNUNET_TIME_Absolute pay_deadline = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_UNIT_DAYS); - struct GNUNET_TIME_Absolute refund_deadline = - GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), - GNUNET_TIME_UNIT_WEEKS); + 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"; @@ -1516,7 +1809,6 @@ pre_test_deposits (struct TestDeposits_Closure *cls) GNUNET_assert (GNUNET_OK == TALER_JSON_hash (cls->order.contract, &cls->deposits[0].h_contract_terms)); - struct TALER_CoinSpendPrivateKeyP coin_priv; GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv, &cls->deposits[0].coin_pub.eddsa_pub); @@ -1534,9 +1826,6 @@ pre_test_deposits (struct TestDeposits_Closure *cls) TALER_string_to_amount ("EUR:2.00", &cls->deposits[0].wire_fee)); cls->deposits[0].h_wire = cls->account.h_wire; - struct TALER_DepositRequestPS deposit_sign; - deposit_sign.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS)); - deposit_sign.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT); deposit_sign.h_contract_terms = cls->deposits[0].h_contract_terms; deposit_sign.h_wire = cls->deposits[0].h_wire; deposit_sign.wallet_timestamp = GNUNET_TIME_absolute_hton ( @@ -1600,15 +1889,9 @@ run_test_deposits (struct TestDeposits_Closure *cls) cls->order.contract)); /* Insert contract terms */ - if (1 != plugin->insert_contract_terms (plugin->cls, - cls->is.id, - cls->order.id, - cls->order.contract)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Insert contract terms failed\n"); - return 1; - } + TEST_RET_ON_FAIL (test_insert_contract_terms (cls->is.id, + cls->order.id, + cls->order.contract)); /* Test inserting a deposit */ TEST_RET_ON_FAIL (test_insert_deposit (cls->is.id, @@ -1621,6 +1904,15 @@ run_test_deposits (struct TestDeposits_Closure *cls) 1, cls->deposits)); + /* Test lookup deposits by contract and coins */ + TEST_RET_ON_FAIL (test_lookup_deposits_contract_and_coin (cls->is.id, + &cls->deposits[0]. + h_contract_terms, + &cls->deposits[0]. + coin_pub, + 1, + cls->deposits)); + return 0; } @@ -1636,6 +1928,146 @@ test_deposits (void *cls) } +struct TestTransfers_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 account + */ + struct TALER_MERCHANTDB_AccountDetails account; +}; + + +static void +pre_test_transfers (struct TestTransfers_Closure *cls) +{ + /* 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_transfers"; + 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_ (); + + /* Account */ + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->account.h_wire); + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_STRONG, + &cls->account.salt); + cls->account.payto_uri = "payto://x-taler-bank/bank.demo.taler.net/4"; + cls->account.active = true; +} + + +static void +post_test_transfers (struct TestTransfers_Closure *cls) +{ + json_decref (cls->is.address); + json_decref (cls->is.jurisdiction); +} + + +static int +run_test_transfers (struct TestTransfers_Closure *cls) +{ + struct TALER_WireTransferIdentifierRawP wtid = { + .raw = {0} + }; + struct TALER_Amount amount; + + /* Insert the instance */ + TEST_RET_ON_FAIL (test_insert_instance (&cls->merchant_pub, + &cls->merchant_priv, + &cls->is)); + + /* Insert the account */ + TEST_RET_ON_FAIL (test_insert_account (cls->is.id, + &cls->account)); + + /* Insert the transfer */ + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:13", + &amount)); + if (1 != plugin->insert_transfer (plugin->cls, + cls->is.id, + "exch-url", + &wtid, + &amount, + cls->account.payto_uri, + false)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Insert transfer failed\n"); + return 1; + } + + /* Test transfer details */ + struct TALER_EXCHANGE_TransferData transfer_data = { + .details_length = 0 + }; + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:13", + &transfer_data.total_amount)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:0.49", + &transfer_data.wire_fee)); + if (1 != plugin->insert_transfer_details (plugin->cls, + cls->is.id, + "exch-url", + cls->account.payto_uri, + &wtid, + &transfer_data)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Insert transfer details failed\n"); + return 1; + } + + return 0; +} + + +static int +test_transfers (void *cls) +{ + struct TestTransfers_Closure test_cls; + pre_test_transfers (&test_cls); + int test_result = run_test_transfers (&test_cls); + post_test_transfers (&test_cls); + return test_result; +} + + /** * Function that runs all tests and returns 1 upon error, 0 on success. */ @@ -1646,6 +2078,7 @@ run_tests (void *cls) TEST_RET_ON_FAIL (test_products (cls)); TEST_RET_ON_FAIL (test_orders (cls)); TEST_RET_ON_FAIL (test_deposits (cls)); + TEST_RET_ON_FAIL (test_transfers (cls)); return 0; } |