summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-27 14:44:41 -0400
committerJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-05-27 14:44:41 -0400
commit8fdaf760379e3c3edae52ee3552e625482e02ad0 (patch)
tree04ac5c490611ccfb5af5254a18cad06c8a5ddc56
parente2333817a6767933608c6d3bd3216a9fcd3033e7 (diff)
downloadmerchant-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.sql1
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c4
-rw-r--r--src/backenddb/test_merchantdb.c613
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;
}