diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-06-04 16:01:27 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-06-04 16:01:27 -0400 |
commit | 03146baf2929365c2b8ac88a96300525de80a104 (patch) | |
tree | 6d9eb255c11cea4ddb6d8711282129bb899b3341 /src/backenddb | |
parent | ea5d4f680dd1394889e61adbb805d6d8decfe9e1 (diff) | |
download | merchant-03146baf2929365c2b8ac88a96300525de80a104.tar.gz merchant-03146baf2929365c2b8ac88a96300525de80a104.tar.bz2 merchant-03146baf2929365c2b8ac88a96300525de80a104.zip |
more test cleanup and some lookup_orders filter tests
Diffstat (limited to 'src/backenddb')
-rw-r--r-- | src/backenddb/plugin_merchantdb_postgres.c | 20 | ||||
-rw-r--r-- | src/backenddb/test_merchantdb.c | 1360 |
2 files changed, 685 insertions, 695 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 81b4432f..8c484ff4 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -1225,8 +1225,8 @@ postgres_lookup_orders (void *cls, char stmt[128]; paid = (TALER_MERCHANTDB_YNA_YES == of->paid); - refunded = (TALER_MERCHANTDB_YNA_YES == of->paid); - wired = (TALER_MERCHANTDB_YNA_YES == of->paid); + refunded = (TALER_MERCHANTDB_YNA_YES == of->refunded); + wired = (TALER_MERCHANTDB_YNA_YES == of->wired); /* painfully many cases..., note that "_xxx" being present in 'stmt' merely means that we filter by that variable, the value we filter for is computed above */ @@ -5551,6 +5551,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 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 " @@ -5570,6 +5571,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 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 " @@ -5580,7 +5582,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " AND" " creation_time > $4" " AND" - " BOOL($6) = (order_serial IN" + " CAST($6 as BOOL) = (order_serial IN" " (SELECT order_serial " " FROM merchant_refunds))" " ORDER BY order_serial ASC" @@ -5822,6 +5824,9 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " order_id" ",order_serial" ",creation_time" + ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ + ",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 " @@ -5838,6 +5843,9 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " order_id" ",order_serial" ",creation_time" + ",CAST($5 as BOOL)" /* otherwise $5 is unused and Postgres unhappy */ + ",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 " @@ -5857,6 +5865,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 " @@ -5875,6 +5885,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 " @@ -5897,6 +5909,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 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 " @@ -5916,6 +5929,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) ",order_serial" ",creation_time" ",CAST($5 as BOOL)" /* otherwise $5 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 fbf0ff01..97545662 100644 --- a/src/backenddb/test_merchantdb.c +++ b/src/backenddb/test_merchantdb.c @@ -64,7 +64,7 @@ struct InstanceData }; -/* Convenience functions */ +/* Instances */ static void make_instance (char *instance_id, struct InstanceData *instance) @@ -117,8 +117,6 @@ make_account (struct TALER_MERCHANTDB_AccountDetails *account) } -/* Instance tests */ - /** * Instance settings along with corresponding accounts */ @@ -534,6 +532,9 @@ test_instances (void *cls) } +/* Products */ + + static void free_product (struct TALER_MERCHANTDB_ProductDetails *pd) { @@ -935,6 +936,67 @@ test_products (void *cls) } +/* Orders */ + + +/** + * Container for order data + */ +struct OrderData +{ + /** + * The id of the order + */ + const char *id; + + /** + * The pay deadline for the order + */ + struct GNUNET_TIME_Absolute pay_deadline; + + /** + * The contract of the order + */ + json_t *contract; +}; + + +static void +make_order (const char *order_id, + struct OrderData *order) +{ + struct GNUNET_TIME_Absolute pay_deadline; + struct GNUNET_TIME_Absolute refund_deadline; + + order->id = order_id; + order->pay_deadline = GNUNET_TIME_absolute_get_zero_ (); + order->contract = json_object (); + GNUNET_assert (NULL != order->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 (order->contract, + "fulfillment_url", + json_string ("a")); + json_object_set (order->contract, + "pay_deadline", + GNUNET_JSON_from_time_abs (pay_deadline)); + json_object_set (order->contract, + "refund_deadline", + GNUNET_JSON_from_time_abs (refund_deadline)); +} + + +static void +free_order_data (struct OrderData *order) +{ + json_decref (order->contract); +} + + /** * Closure for testing order lookup */ @@ -948,7 +1010,7 @@ struct TestLookupOrders_Closure /** * Pointer to (ordered) array of order ids */ - const char **order_ids_to_cmp; + const struct OrderData *orders_to_cmp; /** * Pointer to array of bools indicating matches in the correct index @@ -976,7 +1038,7 @@ lookup_orders_cb (void *cls, if (cmp->orders_to_cmp_length > i) { /* Compare the orders */ - if (0 == strcmp (cmp->order_ids_to_cmp[i], + if (0 == strcmp (cmp->orders_to_cmp[i].id, order_id)) cmp->results_match[i] = true; else @@ -986,35 +1048,31 @@ lookup_orders_cb (void *cls, static int -test_insert_order (const char *instance_id, - const char *order_id, - struct GNUNET_TIME_Absolute pay_deadline, - const json_t *contract_terms) +test_insert_order (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) { - if (1 != plugin->insert_order (plugin->cls, - instance_id, - order_id, - pay_deadline, - contract_terms)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Insert order failed\n"); - return 1; - } + TEST_COND_RET_ON_FAIL (expected_result == + plugin->insert_order (plugin->cls, + instance->instance.id, + order->id, + order->pay_deadline, + order->contract), + "Insert order failed\n"); return 0; } static int -test_lookup_order (const char *is, - const char *od, - const json_t *contract_to_cmp) +test_lookup_order (const struct InstanceData *instance, + const struct OrderData *order) { json_t *lookup_terms = NULL; - if (0 > plugin->lookup_order (plugin->cls, - is, - od, - &lookup_terms)) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->lookup_order (plugin->cls, + instance->instance.id, + order->id, + &lookup_terms)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup order failed\n"); @@ -1022,7 +1080,7 @@ test_lookup_order (const char *is, json_decref (lookup_terms); return 1; } - if (1 != json_equal (contract_to_cmp, + if (1 != json_equal (order->contract, lookup_terms)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1037,22 +1095,24 @@ test_lookup_order (const char *is, static int -test_lookup_orders (const char *is, - const struct TALER_MERCHANTDB_OrderFilter *of, +test_lookup_orders (const struct InstanceData *instance, + const struct TALER_MERCHANTDB_OrderFilter *filter, unsigned int orders_length, - const char **order_ids_to_cmp) + const struct OrderData *orders) { bool results_match[orders_length]; struct TestLookupOrders_Closure cls = { .orders_to_cmp_length = orders_length, - .order_ids_to_cmp = order_ids_to_cmp, + .orders_to_cmp = orders, .results_match = results_match, .results_length = 0 }; - memset (results_match, 0, sizeof (bool) * orders_length); + memset (results_match, + 0, + sizeof (bool) * orders_length); if (0 > plugin->lookup_orders (plugin->cls, - is, - of, + instance->instance.id, + filter, &lookup_orders_cb, &cls)) { @@ -1081,59 +1141,54 @@ test_lookup_orders (const char *is, static int -test_delete_order (const char *is, - const char *od) +test_delete_order (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) { - if (0 > plugin->delete_order (plugin->cls, - is, - od)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Delete order failed\n"); - return 1; - } + TEST_COND_RET_ON_FAIL (expected_result == + plugin->delete_order (plugin->cls, + instance->instance.id, + order->id), + "Delete order failed\n"); return 0; } static int -test_insert_contract_terms (const char *is, - const char *order_id, - json_t *contract) +test_insert_contract_terms (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) { - 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; - } + TEST_COND_RET_ON_FAIL (expected_result == + plugin->insert_contract_terms (plugin->cls, + instance->instance.id, + order->id, + order->contract), + "Insert contract terms failed\n"); return 0; } static int -test_lookup_contract_terms (const char *instance_id, - const char *order_id, - const json_t *expected_contract) +test_lookup_contract_terms (const struct InstanceData *instance, + const struct OrderData *order) { json_t *contract = NULL; uint64_t order_serial; - if (1 != plugin->lookup_contract_terms (plugin->cls, - instance_id, - order_id, - &contract, - &order_serial)) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->lookup_contract_terms (plugin->cls, + instance->instance.id, + order->id, + &contract, + &order_serial)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup contract terms failed\n"); GNUNET_assert (NULL == contract); return 1; } - if (1 != json_equal (expected_contract, + if (1 != json_equal (order->contract, contract)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1147,26 +1202,64 @@ test_lookup_contract_terms (const char *instance_id, static int -test_lookup_order_status (const char *instance_id, - const char *order_id, - const struct GNUNET_HashCode *expected_contract_terms, +test_delete_contract_terms (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) +{ + TEST_COND_RET_ON_FAIL (expected_result == + plugin->delete_contract_terms (plugin->cls, + instance->instance.id, + order->id, + GNUNET_TIME_UNIT_MONTHS), + "Delete contract terms failed\n"); + return 0; +} + + +static int +test_mark_contract_paid (const struct InstanceData *instance, + const struct OrderData *order, + enum GNUNET_DB_QueryStatus expected_result) +{ + struct GNUNET_HashCode h_contract_terms; + GNUNET_assert (GNUNET_OK == + TALER_JSON_hash (order->contract, + &h_contract_terms)); + TEST_COND_RET_ON_FAIL (expected_result == + plugin->mark_contract_paid (plugin->cls, + instance->instance.id, + &h_contract_terms, + "test_orders_session"), + "Mark contract paid failed\n"); + return 0; +} + + +static int +test_lookup_order_status (const struct InstanceData *instance, + const struct OrderData *order, bool expected_paid) { + struct GNUNET_HashCode h_contract_terms_expected; 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)) + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->lookup_order_status (plugin->cls, + instance->instance.id, + order->id, + &h_contract_terms, + &order_paid)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup order status failed\n"); return 1; } + GNUNET_assert (GNUNET_OK == + TALER_JSON_hash (order->contract, + &h_contract_terms_expected)); if ((expected_paid != order_paid) || (0 != GNUNET_memcmp (&h_contract_terms, - expected_contract_terms))) + &h_contract_terms_expected))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Lookup order status/deposit failed: mismatched data\n"); @@ -1177,28 +1270,6 @@ test_lookup_order_status (const char *instance_id, /** - * Container for order data - */ -struct OrderData -{ - /** - * The id of the order - */ - const char *id; - - /** - * The pay deadline for the order - */ - struct GNUNET_TIME_Absolute pay_deadline; - - /** - * The contract of the order - */ - json_t *contract; -}; - - -/** * Closure for order tests. */ struct TestOrders_Closure @@ -1210,20 +1281,12 @@ struct TestOrders_Closure * The array of orders */ struct OrderData orders[2]; - }; 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 */ make_instance ("test_inst_orders", &cls->instance); @@ -1233,32 +1296,13 @@ pre_test_orders (struct TestOrders_Closure *cls) &cls->product); /* Orders */ - cls->orders[0].id = "test_orders_od_0"; - cls->orders[0].pay_deadline = GNUNET_TIME_absolute_get_zero_ (); - cls->orders[0].contract = json_object (); - GNUNET_assert (NULL != cls->orders[0].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_ (); - cls->orders[1].contract = json_array (); - GNUNET_assert (NULL != cls->orders[1].contract); - GNUNET_assert (0 == json_array_append (cls->orders[1].contract, - json_string ("Second contract"))); + make_order ("test_orders_od_0", + &cls->orders[0]); + make_order ("test_orders_od_1", + &cls->orders[1]); + GNUNET_assert (0 == json_object_set (cls->orders[1].contract, + "other_field", + json_string ("Second contract"))); } @@ -1267,9 +1311,8 @@ post_test_orders (struct TestOrders_Closure *cls) { free_instance_data (&cls->instance); free_product_data (&cls->product); - - json_decref (cls->orders[0].contract); - json_decref (cls->orders[1].contract); + free_order_data (&cls->orders[0]); + free_order_data (&cls->orders[1]); } @@ -1284,54 +1327,52 @@ run_test_orders (struct TestOrders_Closure *cls) .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->instance, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - /* Test inserting an order */ - TEST_RET_ON_FAIL (test_insert_order (cls->instance.instance.id, - cls->orders[0].id, - cls->orders[0].pay_deadline, - cls->orders[0].contract)); - + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Test double insert fails */ + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); /* Test lookup order */ - TEST_RET_ON_FAIL (test_lookup_order (cls->instance.instance.id, - cls->orders[0].id, - cls->orders[0].contract)); - + TEST_RET_ON_FAIL (test_lookup_order (&cls->instance, + &cls->orders[0])); /* Make sure it fails correctly for nonexistent orders */ - + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->lookup_order (plugin->cls, + cls->instance.instance.id, + cls->orders[1].id, + NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup order failed\n"); + return 1; + } /* Test lookups on multiple orders */ - TEST_RET_ON_FAIL (test_insert_order (cls->instance.instance.id, - cls->orders[1].id, - cls->orders[1].pay_deadline, - cls->orders[1].contract)); - - TEST_RET_ON_FAIL (test_lookup_orders (cls->instance.instance.id, + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->orders[1], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, &filter, 2, - order_id_list)); - + cls->orders)); /* Test inserting contract terms */ - TEST_RET_ON_FAIL (test_insert_contract_terms (cls->instance.instance.id, - cls->orders[0].id, - cls->orders[0].contract)); - + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Test double insert fails */ + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); /* Test order lock */ TEST_RET_ON_FAIL (test_insert_product (&cls->instance, &cls->product, GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); - // TEST_RET_ON_FAIL (test) if (1 != plugin->insert_order_lock (plugin->cls, cls->instance.instance.id, cls->orders[0].id, @@ -1342,56 +1383,82 @@ run_test_orders (struct TestOrders_Closure *cls) "Insert order lock failed\n"); return 1; } - /* Test lookup contract terms */ - TEST_RET_ON_FAIL (test_lookup_contract_terms (cls->instance.instance.id, - cls->orders[0].id, - cls->orders[0].contract)); - + TEST_RET_ON_FAIL (test_lookup_contract_terms (&cls->instance, + &cls->orders[0])); + /* Test lookup fails for nonexistent contract terms */ + { + json_t *lookup_contract = NULL; + uint64_t lookup_order_serial; + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->lookup_contract_terms (plugin->cls, + cls->instance.instance.id, + cls->orders[1].id, + &lookup_contract, + &lookup_order_serial)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup contract terms failed\n"); + GNUNET_assert (NULL == lookup_contract); + return 1; + } + } /* Test lookup order status */ - TEST_RET_ON_FAIL (test_lookup_order_status (cls->instance.instance.id, - cls->orders[0].id, - &h_contract_terms, + TEST_RET_ON_FAIL (test_lookup_order_status (&cls->instance, + &cls->orders[0], false)); - - /* Test marking contracts as paid */ - if (1 != plugin->mark_contract_paid (plugin->cls, - cls->instance.instance.id, - &h_contract_terms, - "test_orders_session")) + /* Test lookup order status fails for nonexistent order */ { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Mark contract as paid failed\n"); - return 1; + struct GNUNET_HashCode h_contract_terms; + bool order_paid; + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != + plugin->lookup_order_status (plugin->cls, + cls->instance.instance.id, + cls->orders[1].id, + &h_contract_terms, + &order_paid)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup order status failed\n"); + return 1; + } } - TEST_RET_ON_FAIL (test_lookup_order_status (cls->instance.instance.id, - cls->orders[0].id, - &h_contract_terms, + /* Test marking contracts as paid */ + TEST_RET_ON_FAIL (test_mark_contract_paid (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Test mark as paid fails for nonexistent order */ + TEST_RET_ON_FAIL (test_mark_contract_paid (&cls->instance, + &cls->orders[1], + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); + TEST_RET_ON_FAIL (test_lookup_order_status (&cls->instance, + &cls->orders[0], true)); filter.paid = TALER_MERCHANTDB_YNA_YES; - TEST_RET_ON_FAIL (test_lookup_orders (cls->instance.instance.id, + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, &filter, 1, - order_id_list)); - + cls->orders)); /* Test deleting contract terms */ - if (1 != plugin->delete_contract_terms (plugin->cls, - cls->instance.instance.id, - cls->orders[0].id, - expiration)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Delete contract terms failed\n"); - return 1; - } - + TEST_RET_ON_FAIL (test_delete_contract_terms (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Test we can't delete something that doesn't exist */ + TEST_RET_ON_FAIL (test_delete_contract_terms (&cls->instance, + &cls->orders[0], + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); /* Test delete order */ - TEST_RET_ON_FAIL (test_delete_order (cls->instance.instance.id, - cls->orders[1].id)); - TEST_RET_ON_FAIL (test_lookup_orders (cls->instance.instance.id, + TEST_RET_ON_FAIL (test_delete_order (&cls->instance, + &cls->orders[1], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, &filter, 0, NULL)); + /* Test we can't delete something that doesn't exist */ + TEST_RET_ON_FAIL (test_delete_order (&cls->instance, + &cls->orders[1], + GNUNET_DB_STATUS_SUCCESS_NO_RESULTS)); return 0; } @@ -1408,6 +1475,51 @@ test_orders (void *cls) } +/* Deposits */ + + +struct ExchangeSignkeyData +{ + struct TALER_MasterPrivateKeyP master_priv; + struct TALER_MasterPublicKeyP master_pub; + struct TALER_MasterSignatureP master_sig; + + struct TALER_ExchangePrivateKeyP exchange_priv; + struct TALER_ExchangePublicKeyP exchange_pub; + + struct GNUNET_TIME_Absolute start_date; + struct GNUNET_TIME_Absolute expire_date; + struct GNUNET_TIME_Absolute end_date; +}; + + +static void +make_exchange_signkey (struct ExchangeSignkeyData *signkey) +{ + struct TALER_ExchangeSigningKeyValidityPS exch_sign = { + .purpose = { + .size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS)), + .purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY) + } + + + }; + + GNUNET_CRYPTO_eddsa_key_create (&signkey->exchange_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public (&signkey->exchange_priv.eddsa_priv, + &signkey->exchange_pub.eddsa_pub); + GNUNET_CRYPTO_eddsa_key_create (&signkey->master_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public (&signkey->master_priv.eddsa_priv, + &signkey->master_pub.eddsa_pub); + GNUNET_CRYPTO_eddsa_sign (&signkey->master_priv.eddsa_priv, + &exch_sign, + &signkey->master_sig.eddsa_signature); + signkey->start_date = GNUNET_TIME_absolute_get (); + signkey->expire_date = GNUNET_TIME_absolute_get (); + signkey->end_date = GNUNET_TIME_absolute_get (); +} + + /** * A container for deposit data. */ @@ -1436,6 +1548,62 @@ struct DepositData }; +static void +make_deposit (const struct InstanceData *instance, + const struct TALER_MERCHANTDB_AccountDetails *account, + const struct OrderData *order, + const struct ExchangeSignkeyData *signkey, + struct DepositData *deposit) +{ + struct TALER_CoinSpendPrivateKeyP coin_priv; + struct TALER_DepositRequestPS deposit_sign = { + .purpose = { + .size = htonl (sizeof (struct TALER_DepositRequestPS)), + .purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT) + } + + + }; + + deposit->timestamp = GNUNET_TIME_absolute_get (); + GNUNET_assert (GNUNET_OK == + TALER_JSON_hash (order->contract, + &deposit->h_contract_terms)); + GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv); + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv, + &deposit->coin_pub.eddsa_pub); + deposit->exchange_url = "test-exchange"; + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:50.00", + &deposit->amount_with_fee)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:1.00", + &deposit->deposit_fee)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:1.50", + &deposit->refund_fee)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("EUR:2.00", + &deposit->wire_fee)); + deposit->h_wire = account->h_wire; + deposit_sign.h_contract_terms = deposit->h_contract_terms; + deposit_sign.h_wire = 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, + &deposit->amount_with_fee); + TALER_amount_hton (&deposit_sign.deposit_fee, + &deposit->deposit_fee); + deposit_sign.merchant = instance->merchant_pub; + deposit_sign.coin_pub = deposit->coin_pub; + GNUNET_CRYPTO_eddsa_sign (&signkey->exchange_priv.eddsa_priv, + &deposit_sign, + &deposit->exchange_sig.eddsa_signature); +} + + /** * Closure for testing deposit lookup */ @@ -1563,26 +1731,18 @@ 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; - } +test_insert_exchange_signkey (const struct ExchangeSignkeyData *signkey, + enum GNUNET_DB_QueryStatus expected_result) +{ + TEST_COND_RET_ON_FAIL (expected_result == + plugin->insert_exchange_signkey (plugin->cls, + &signkey->master_pub, + &signkey->exchange_pub, + signkey->start_date, + signkey->expire_date, + signkey->end_date, + &signkey->master_sig), + "Insert exchange signkey failed\n"); return 0; } @@ -1721,44 +1881,9 @@ struct TestDeposits_Closure struct TALER_MERCHANTDB_AccountDetails account; /** - * The exchange public key + * The exchange signing 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; + struct ExchangeSignkeyData signkey; /** * The order data @@ -1775,26 +1900,6 @@ 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 */ make_instance ("test_inst_deposits", &cls->instance); @@ -1803,76 +1908,18 @@ pre_test_deposits (struct TestDeposits_Closure *cls) make_account (&cls->account); /* 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 (); + make_exchange_signkey (&cls->signkey); /* 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)); + make_order ("test_deposits_od_1", + &cls->order); /* Deposit */ - cls->deposits[0].timestamp = GNUNET_TIME_absolute_get (); - GNUNET_assert (GNUNET_OK == - TALER_JSON_hash (cls->order.contract, - &cls->deposits[0].h_contract_terms)); - 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); - cls->deposits[0].exchange_url = "test-exchange"; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:50.00", - &cls->deposits[0].amount_with_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.00", - &cls->deposits[0].deposit_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.50", - &cls->deposits[0].refund_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:2.00", - &cls->deposits[0].wire_fee)); - cls->deposits[0].h_wire = cls->account.h_wire; - 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 ( - 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->deposits[0].amount_with_fee); - TALER_amount_hton (&deposit_sign.deposit_fee, - &cls->deposits[0].deposit_fee); - deposit_sign.merchant = cls->instance.merchant_pub; - deposit_sign.coin_pub = cls->deposits[0].coin_pub; - GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv, - &deposit_sign, - &cls->deposits[0].exchange_sig.eddsa_signature); + make_deposit (&cls->instance, + &cls->account, + &cls->order, + &cls->signkey, + &cls->deposits[0]); } @@ -1899,27 +1946,22 @@ run_test_deposits (struct TestDeposits_Closure *cls) GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* 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)); + TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->signkey, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert an order */ - TEST_RET_ON_FAIL (test_insert_order (cls->instance.instance.id, - cls->order.id, - cls->order.pay_deadline, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert contract terms */ - TEST_RET_ON_FAIL (test_insert_contract_terms (cls->instance.instance.id, - cls->order.id, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Test inserting a deposit */ TEST_RET_ON_FAIL (test_insert_deposit (cls->instance.instance.id, - &cls->exchange_pub, + &cls->signkey.exchange_pub, &cls->deposits[0])); /* Test lookup deposits */ @@ -2316,49 +2358,9 @@ struct TestTransfers_Closure struct TALER_MERCHANTDB_AccountDetails account; /** - * The exchange public key - */ - struct TALER_ExchangePublicKeyP exchange_pub; - - /** - * The exchange private key - */ - struct TALER_ExchangePrivateKeyP exchange_priv; - - /** - * The exchange signature - */ - struct TALER_ExchangeSignatureP exchange_sig; - - /** - * The master public key - */ - struct TALER_MasterPublicKeyP master_pub; - - /** - * The master private key + * The exchange signing 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; + struct ExchangeSignkeyData signkey; /** * The order data @@ -2386,25 +2388,6 @@ struct TestTransfers_Closure static void pre_test_transfers (struct TestTransfers_Closure *cls) { - struct TALER_ExchangeSigningKeyValidityPS exch_sign = { - .purpose = { - .size = htonl (sizeof (struct TALER_ExchangeSigningKeyValidityPS)), - .purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY) - } - - - }; - struct GNUNET_TIME_Absolute pay_deadline; - struct GNUNET_TIME_Absolute refund_deadline; - 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_MasterWireFeePS fee_sign = { .purpose = { .size = htonl (sizeof (struct TALER_MasterWireFeePS)), @@ -2422,76 +2405,18 @@ pre_test_transfers (struct TestTransfers_Closure *cls) make_account (&cls->account); /* 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->instance.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); + make_order ("test_transfers_od_1", + &cls->order); /* 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 (); + make_exchange_signkey (&cls->signkey); + + /* Deposit */ + make_deposit (&cls->instance, + &cls->account, + &cls->order, + &cls->signkey, + &cls->deposit); /* Wire fee */ cls->exch_wire_method = "wire-method"; @@ -2514,7 +2439,7 @@ pre_test_transfers (struct TestTransfers_Closure *cls) &cls->exch_closing_fee); fee_sign.start_date = GNUNET_TIME_absolute_hton (cls->exch_wire_fee_start); fee_sign.end_date = GNUNET_TIME_absolute_hton (cls->exch_wire_fee_end); - GNUNET_CRYPTO_eddsa_sign (&cls->master_priv.eddsa_priv, + GNUNET_CRYPTO_eddsa_sign (&cls->signkey.master_priv.eddsa_priv, &fee_sign, &cls->exch_fee_sig.eddsa_signature); } @@ -2539,7 +2464,7 @@ run_test_transfers (struct TestTransfers_Closure *cls) struct TALER_Amount amount; struct TALER_Amount total_with_fee; struct TALER_EXCHANGE_TransferData transfer_data = { - .exchange_pub = cls->exchange_pub, + .exchange_pub = cls->signkey.exchange_pub, .execution_time = GNUNET_TIME_absolute_get (), }; struct TALER_TrackTransferDetails transfer_detail = { @@ -2554,7 +2479,7 @@ run_test_transfers (struct TestTransfers_Closure *cls) /* Test store wire fee by exchange */ if (1 != plugin->store_wire_fee_by_exchange (plugin->cls, - &cls->master_pub, + &cls->signkey.master_pub, &cls->exch_h_wire_method, &cls->exch_wire_fee, &cls->exch_closing_fee, @@ -2568,7 +2493,7 @@ run_test_transfers (struct TestTransfers_Closure *cls) } /* Test lookup wire fee by exchange */ - TEST_RET_ON_FAIL (test_lookup_wire_fee (&cls->master_pub, + TEST_RET_ON_FAIL (test_lookup_wire_fee (&cls->signkey.master_pub, cls->exch_wire_method, GNUNET_TIME_absolute_add ( cls->exch_wire_fee_start, @@ -2589,27 +2514,22 @@ run_test_transfers (struct TestTransfers_Closure *cls) GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* 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)); + TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->signkey, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert an order */ - TEST_RET_ON_FAIL (test_insert_order (cls->instance.instance.id, - cls->order.id, - cls->order.pay_deadline, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert contract terms */ - TEST_RET_ON_FAIL (test_insert_contract_terms (cls->instance.instance.id, - cls->order.id, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert the deposit */ TEST_RET_ON_FAIL (test_insert_deposit (cls->instance.instance.id, - &cls->exchange_pub, + &cls->signkey.exchange_pub, &cls->deposit)); transfer_data.details_length = 1; transfer_data.details = &transfer_detail; @@ -3480,10 +3400,23 @@ struct RefundData struct GNUNET_TIME_Absolute timestamp; const char *reason; struct TALER_Amount refund_amount; - struct TALER_CoinSpendPublicKeyP *coin_pub; + const struct TALER_CoinSpendPublicKeyP *coin_pub; const char *exchange_url; }; + +static void +make_refund (const struct DepositData *deposit, + struct RefundData *refund) +{ + refund->timestamp = GNUNET_TIME_absolute_get (); + refund->reason = "some reason"; + refund->refund_amount = deposit->amount_with_fee; + refund->coin_pub = &deposit->coin_pub; + refund->exchange_url = deposit->exchange_url; +} + + struct RefundProofData { struct TALER_Amount refund_fee; @@ -3623,44 +3556,9 @@ struct TestRefunds_Closure 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 + * The exchange signing key */ - struct GNUNET_TIME_Absolute signkey_expire; - - /** - * The exchange signkey end date - */ - struct GNUNET_TIME_Absolute signkey_end; + struct ExchangeSignkeyData signkey; /** * The order data @@ -3687,25 +3585,6 @@ struct TestRefunds_Closure 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)), @@ -3723,126 +3602,33 @@ pre_test_refunds (struct TestRefunds_Closure *cls) make_account (&cls->account); /* 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 (); + make_exchange_signkey (&cls->signkey); /* 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)); + make_order ("test_refunds_od_0", + &cls->order); /* Deposit */ - cls->deposits[0].timestamp = GNUNET_TIME_absolute_get (); - GNUNET_assert (GNUNET_OK == - TALER_JSON_hash (cls->order.contract, - &cls->deposits[0].h_contract_terms)); - 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); - cls->deposits[0].exchange_url = "test-exchange"; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:50.00", - &cls->deposits[0].amount_with_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.00", - &cls->deposits[0].deposit_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.50", - &cls->deposits[0].refund_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:2.00", - &cls->deposits[0].wire_fee)); - cls->deposits[0].h_wire = cls->account.h_wire; - 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 ( - 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->deposits[0].amount_with_fee); - TALER_amount_hton (&deposit_sign.deposit_fee, - &cls->deposits[0].deposit_fee); - deposit_sign.merchant = cls->instance.merchant_pub; - deposit_sign.coin_pub = cls->deposits[0].coin_pub; - GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv, - &deposit_sign, - &cls->deposits[0].exchange_sig.eddsa_signature); - - cls->deposits[1].timestamp = GNUNET_TIME_absolute_get (); - GNUNET_assert (GNUNET_OK == - TALER_JSON_hash (cls->order.contract, - &cls->deposits[1].h_contract_terms)); - GNUNET_CRYPTO_eddsa_key_create (&coin_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv.eddsa_priv, - &cls->deposits[1].coin_pub.eddsa_pub); - cls->deposits[1].exchange_url = "test-exchange"; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:21.00", - &cls->deposits[1].amount_with_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.00", - &cls->deposits[1].deposit_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:1.50", - &cls->deposits[1].refund_fee)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount ("EUR:2.00", - &cls->deposits[1].wire_fee)); - cls->deposits[1].h_wire = cls->account.h_wire; - deposit_sign.h_contract_terms = cls->deposits[1].h_contract_terms; - deposit_sign.h_wire = cls->deposits[1].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->deposits[1].amount_with_fee); - TALER_amount_hton (&deposit_sign.deposit_fee, - &cls->deposits[1].deposit_fee); - deposit_sign.merchant = cls->instance.merchant_pub; - deposit_sign.coin_pub = cls->deposits[1].coin_pub; - GNUNET_CRYPTO_eddsa_sign (&cls->exchange_priv.eddsa_priv, - &deposit_sign, - &cls->deposits[1].exchange_sig.eddsa_signature); + make_deposit (&cls->instance, + &cls->account, + &cls->order, + &cls->signkey, + &cls->deposits[0]); + make_deposit (&cls->instance, + &cls->account, + &cls->order, + &cls->signkey, + &cls->deposits[1]); /* Refund */ - cls->refund.timestamp = GNUNET_TIME_absolute_get (); - cls->refund.reason = "some reason"; - cls->refund.refund_amount = cls->deposits[0].amount_with_fee; - cls->refund.coin_pub = &cls->deposits[0].coin_pub; - cls->refund.exchange_url = cls->deposits[0].exchange_url; + make_refund (&cls->deposits[0], + &cls->refund); /* 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, + GNUNET_CRYPTO_eddsa_sign (&cls->signkey.exchange_priv.eddsa_priv, &refund_sign, &cls->refund_proof.exchange_sig.eddsa_signature); } @@ -3852,9 +3638,7 @@ static void post_test_refunds (struct TestRefunds_Closure *cls) { free_instance_data (&cls->instance); - - /* Order */ - json_decref (cls->order.contract); + free_order_data (&cls->order); } @@ -3871,30 +3655,25 @@ run_test_refunds (struct TestRefunds_Closure *cls) GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert an order */ - TEST_RET_ON_FAIL (test_insert_order (cls->instance.instance.id, - cls->order.id, - cls->order.pay_deadline, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert contract terms */ - TEST_RET_ON_FAIL (test_insert_contract_terms (cls->instance.instance.id, - cls->order.id, - cls->order.contract)); + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->order, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* 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)); + TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->signkey, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); /* Insert a deposit */ TEST_RET_ON_FAIL (test_insert_deposit (cls->instance.instance.id, - &cls->exchange_pub, + &cls->signkey.exchange_pub, &cls->deposits[0])); TEST_RET_ON_FAIL (test_insert_deposit (cls->instance.instance.id, - &cls->exchange_pub, + &cls->signkey.exchange_pub, &cls->deposits[1])); /* Mark as paid */ @@ -3940,7 +3719,7 @@ run_test_refunds (struct TestRefunds_Closure *cls) 1, // TODO: get this from lookup &cls->refund_proof.refund_fee, &cls->refund_proof.exchange_sig, - &cls->exchange_pub)) + &cls->signkey.exchange_pub)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Insert refund proof failed\n"); @@ -3966,7 +3745,7 @@ run_test_refunds (struct TestRefunds_Closure *cls) /* Test lookup refund proof */ TEST_RET_ON_FAIL (test_lookup_refund_proof (1, &cls->refund_proof.exchange_sig, - &cls->exchange_pub)); + &cls->signkey.exchange_pub)); return 0; } @@ -3984,6 +3763,202 @@ test_refunds (void *cls) /** + * Convenience function for testing lookup orders with filters + */ +static void +reverse_order_data_array (unsigned int orders_length, + struct OrderData *orders) +{ + struct OrderData tmp[orders_length]; + for (unsigned int i = 0; i < orders_length; ++i) + tmp[i] = orders[orders_length - 1 - i]; + for (unsigned int i = 0; i < orders_length; ++i) + orders[i] = tmp[i]; +} + + +struct TestLookupOrdersAllFilters_Closure +{ + struct InstanceData instance; + struct TALER_MERCHANTDB_AccountDetails account; + struct ExchangeSignkeyData signkey; + + char *order_ids[16]; + struct OrderData orders[16]; + struct DepositData deposits[16]; + struct RefundData refunds[16]; +}; + + +static void +pre_test_lookup_orders_all_filters (struct + TestLookupOrdersAllFilters_Closure *cls) +{ + make_instance ("test_inst_lookup_orders_all_filters", + &cls->instance); + make_account (&cls->account); + make_exchange_signkey (&cls->signkey); + for (unsigned int i = 0; i < 16; ++i) + { + (void) GNUNET_asprintf (&cls->order_ids[i], + "test_orders_filter_od_%u", + i); + make_order (cls->order_ids[i], + &cls->orders[i]); + GNUNET_assert (0 == json_object_set (cls->orders[i].contract, + "order_id", + json_string (cls->order_ids[i]))); + make_deposit (&cls->instance, + &cls->account, + &cls->orders[i], + &cls->signkey, + &cls->deposits[i]); + make_refund (&cls->deposits[i], + &cls->refunds[i]); + } +} + + +static void +post_test_lookup_orders_all_filters (struct + TestLookupOrdersAllFilters_Closure *cls) +{ + free_instance_data (&cls->instance); + for (unsigned int i = 0; i < 16; ++i) + { + free_order_data (&cls->orders[i]); + GNUNET_free (cls->order_ids[i]); + } +} + + +static int +run_test_lookup_orders_all_filters (struct + TestLookupOrdersAllFilters_Closure *cls) +{ + /* Order filter extravaganza */ + struct OrderData expected_orders[16]; + struct TALER_MERCHANTDB_OrderFilter filter_inc = { + .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 = 16 + }; + struct TALER_MERCHANTDB_OrderFilter filter_dec = { + .paid = TALER_MERCHANTDB_YNA_ALL, + .refunded = TALER_MERCHANTDB_YNA_ALL, + .wired = TALER_MERCHANTDB_YNA_ALL, + .date = GNUNET_TIME_UNIT_FOREVER_ABS, + .start_row = 23, /* Why does this need to be 20 and not 18? */ + .delta = -16 + }; + + TEST_RET_ON_FAIL (test_insert_instance (&cls->instance, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_insert_account (&cls->instance, + &cls->account, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_insert_exchange_signkey (&cls->signkey, + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + for (unsigned int i = 0; i < 16; ++i) + { + expected_orders[i] = cls->orders[i]; + TEST_RET_ON_FAIL (test_insert_order (&cls->instance, + &cls->orders[i], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + TEST_RET_ON_FAIL (test_insert_contract_terms (&cls->instance, + &cls->orders[i], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Mark every other order as paid for */ + if (0 == i % 2) + TEST_RET_ON_FAIL (test_mark_contract_paid (&cls->instance, + &cls->orders[i], + GNUNET_DB_STATUS_SUCCESS_ONE_RESULT)); + /* Refund every fouth order */ + if (0 == i % 4) + { + TEST_RET_ON_FAIL (test_insert_deposit (cls->instance.instance.id, + &cls->signkey.exchange_pub, + &cls->deposits[i])); + TEST_COND_RET_ON_FAIL (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + plugin->refund_coin (plugin->cls, + cls->instance.instance.id, + &cls->deposits[i]. + h_contract_terms, + cls->refunds[i].timestamp, + cls->refunds[i].coin_pub, + cls->refunds[i].reason), + "Refund coin failed\n"); + } + } + + /* We have 16 different cases to cover */ + /* lookup_orders_inc */ + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_inc, + 16, + expected_orders)); + /* lookup_orders_dec */ + reverse_order_data_array (16, + expected_orders); + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_dec, + 16, + expected_orders)); + /* lookup_orders_inc_paid */ + filter_inc.paid = TALER_MERCHANTDB_YNA_YES; + for (unsigned int i = 0; i < 8; ++i) + expected_orders[i] = cls->orders[2 * i]; + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_inc, + 8, + expected_orders)); + /* lookup_orders_dec_paid */ + filter_dec.paid = TALER_MERCHANTDB_YNA_YES; + reverse_order_data_array (8, + expected_orders); + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_dec, + 8, + expected_orders)); + /* lookup_orders_inc_refunded */ + filter_inc.paid = TALER_MERCHANTDB_YNA_ALL; + filter_inc.refunded = TALER_MERCHANTDB_YNA_YES; + for (unsigned int i = 0; i < 4; ++i) + expected_orders[i] = cls->orders[4 * i]; + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_inc, + 4, + expected_orders)); + /* lookup_orders_dec_refunded */ + filter_dec.paid = TALER_MERCHANTDB_YNA_ALL; + filter_dec.refunded = TALER_MERCHANTDB_YNA_YES; + reverse_order_data_array (4, + expected_orders); + TEST_RET_ON_FAIL (test_lookup_orders (&cls->instance, + &filter_dec, + 4, + expected_orders)); + return 0; +} + + +/* This has to happen after everything else because it + depends on deposits, etc. */ +static int +test_lookup_orders_all_filters (void *cls) +{ + struct TestLookupOrdersAllFilters_Closure test_cls; + pre_test_lookup_orders_all_filters (&test_cls); + int test_result = run_test_lookup_orders_all_filters (&test_cls); + post_test_lookup_orders_all_filters (&test_cls); + return test_result; +} + + +/** * Function that runs all tests and returns 1 upon error, 0 on success. */ static int @@ -3996,6 +3971,7 @@ run_tests (void *cls) TEST_RET_ON_FAIL (test_transfers (cls)); TEST_RET_ON_FAIL (test_tips (cls)); TEST_RET_ON_FAIL (test_refunds (cls)); + TEST_RET_ON_FAIL (test_lookup_orders_all_filters (cls)); return 0; } |