summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-06-18 20:27:04 -0400
committerJonathan Buchanan <jonathan.russ.buchanan@gmail.com>2020-06-18 20:27:04 -0400
commit566408fa02acf56bbf6063c6d17d739e491e27f2 (patch)
tree35fe5a5be349e908f4fccd1d036d718f15abd221 /src
parent6624576c0cdd81072256d8abbfe6dd1343f956c6 (diff)
downloadmerchant-566408fa02acf56bbf6063c6d17d739e491e27f2.tar.gz
merchant-566408fa02acf56bbf6063c6d17d739e491e27f2.tar.bz2
merchant-566408fa02acf56bbf6063c6d17d739e491e27f2.zip
stricter tests for tips/reserves
Diffstat (limited to 'src')
-rw-r--r--src/backend/taler-merchant-httpd.c2
-rw-r--r--src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c4
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c27
-rw-r--r--src/include/taler_merchant_testing_lib.h144
-rw-r--r--src/lib/merchant_api_tip_authorize.c2
-rw-r--r--src/testing/test_merchant_api.c207
-rw-r--r--src/testing/testing_api_cmd_get_reserve.c2
-rw-r--r--src/testing/testing_api_cmd_merchant_get_tip.c175
-rw-r--r--src/testing/testing_api_cmd_post_reserves.c55
-rw-r--r--src/testing/testing_api_cmd_tip_authorize.c187
-rw-r--r--src/testing/testing_api_cmd_tip_pickup.c24
-rw-r--r--src/testing/testing_api_cmd_wallet_get_tip.c83
12 files changed, 730 insertions, 182 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 34c31647..3968d6b2 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -865,7 +865,7 @@ url_handler (void *cls,
},
/* POST /reserves/$ID/authorize-tip: */
{
- .url_prefix = "/reserves",
+ .url_prefix = "/reserves/",
.url_suffix = "authorize-tip",
.have_id_segment = true,
.method = MHD_HTTP_METHOD_POST,
diff --git a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
index 61e2b38a..1c28173b 100644
--- a/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
+++ b/src/backend/taler-merchant-httpd_private-post-reserves-ID-authorize-tip.c
@@ -97,6 +97,10 @@ authorize_tip (const struct TMH_RequestHandler *rh,
msg = "Failed to approve tip: merchant's tipping reserve does not exist";
rc = MHD_HTTP_SERVICE_UNAVAILABLE;
break;
+ case TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND:
+ msg = "Failed to approve tip: merchant's tipping reserve does not exist";
+ rc = MHD_HTTP_NOT_FOUND;
+ break;
default:
rc = MHD_HTTP_INTERNAL_SERVER_ERROR;
msg = "Failed to approve tip: internal server error";
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index db9e9c51..7188839e 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -4889,6 +4889,12 @@ RETRY:
postgres_rollback (pg);
return TALER_EC_TIP_AUTHORIZE_DB_LOOKUP_RESERVE_FAILURE;
}
+ if (qs == 0)
+ {
+ GNUNET_break (0);
+ postgres_rollback (pg);
+ return TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND;
+ }
}
{
struct TALER_Amount remaining;
@@ -5354,13 +5360,14 @@ lookup_pickup_details_cb (void *cls,
for (unsigned int i = 0; i < num_results; i++)
{
struct TALER_MERCHANTDB_PickupDetails *pd = &((*ltdc->pickups)[i]);
+ uint64_t num_planchets = 0;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("pickup_id",
&pd->pickup_id),
TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
&pd->requested_amount),
- GNUNET_PQ_result_spec_uint32 ("num_planchets",
- &pd->num_planchets),
+ GNUNET_PQ_result_spec_uint64 ("num_planchets",
+ &num_planchets),
GNUNET_PQ_result_spec_end
};
@@ -5376,6 +5383,8 @@ lookup_pickup_details_cb (void *cls,
0);
return;
}
+
+ pd->num_planchets = num_planchets;
}
}
@@ -5457,7 +5466,8 @@ postgres_lookup_tip_details (void *cls,
struct LookupTipDetailsContext ltdc = {
.pickups_length = pickups_length,
.pickups = pickups,
- .pg = pg
+ .pg = pg,
+ .qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
};
qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
@@ -7835,14 +7845,11 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" pickup_id"
",amount_val"
",amount_frac"
- ",(SELECT"
- " COUNT(blind_sig)"
- " FROM merchant_tip_pickups"
- " JOIN merchant_tip_pickup_signatures USING (pickup_serial)"
- " WHERE tip_serial = $1)"
- " AS num_planchets"
+ ",COUNT(blind_sig) AS num_planchets"
" FROM merchant_tip_pickups"
- " WHERE tip_serial = $1",
+ " JOIN merchant_tip_pickup_signatures USING (pickup_serial)"
+ " WHERE tip_serial = $1"
+ " GROUP BY pickup_serial",
1),
/* for postgres_insert_pickup() */
GNUNET_PQ_make_prepare ("insert_pickup",
diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h
index c7813176..85cd73ef 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -582,6 +582,18 @@ TALER_TESTING_cmd_merchant_post_reserves (const char *label,
const char *wire_method,
unsigned int http_status);
+
+/**
+ * This commands does not query the backend at all,
+ * but just makes up a fake reserve.
+ *
+ * @param label command label.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_post_reserves_fake (const char *label);
+
+
/**
* Define a "GET reserve" CMD.
*
@@ -678,6 +690,24 @@ TALER_TESTING_cmd_merchant_get_tip (const char *label,
/**
+ * Define a GET /private/tips/$TIP_ID CMD.
+ *
+ * @param label the command label
+ * @param merchant_url base URL of the merchant which will
+ * serve the request.
+ * @param tip_reference reference to a command that created a tip.
+ * @param pickup_refs a NULL-terminated list of pickup commands
+ * associated with the tip.
+ * @param http_status expected HTTP response code for the request.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_get_tip_with_pickups (const char *label,
+ const char *merchant_url,
+ const char *tip_reference,
+ const char *pickup_refs[],
+ unsigned int http_status);
+
+/**
* Define a GET /tips/$TIP_ID CMD.
*
* @param label the command label
@@ -694,6 +724,73 @@ TALER_TESTING_cmd_wallet_get_tip (const char *label,
/**
+ * Define a GET /tips/$TIP_ID CMD.
+ *
+ * @param label the command label
+ * @param merchant_url base URL of the merchant which will
+ * serve the request.
+ * @param tip_reference reference to a command that created a tip.
+ * @param amount_remaining the balance remaining after pickups.
+ * @param http_status expected HTTP response code for the request.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wallet_get_tip2 (const char *label,
+ const char *merchant_url,
+ const char *tip_reference,
+ const char *amount_remaining,
+ unsigned int http_status);
+
+
+/**
+ * Create a /tip-authorize CMD.
+ *
+ * @param label this command label
+ * @param merchant_url the base URL of the merchant that will
+ * serve the /tip-authorize request.
+ * @param exchange_url the base URL of the exchange that owns
+ * the reserve from which the tip is going to be gotten.
+ * @param http_status the HTTP response code which is expected
+ * for this operation.
+ * @param justification human-readable justification for this
+ * tip authorization.
+ * @param amount the amount to authorize for tipping.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_tip_authorize (const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount);
+
+
+/**
+ * Create a /tip-authorize CMD.
+ *
+ * @param label this command label
+ * @param merchant_url the base URL of the merchant that will
+ * serve the /tip-authorize request.
+ * @param exchange_url the base URL of the exchange that owns
+ * the reserve from which the tip is going to be gotten.
+ * @param reserve_reference reference to a command that created
+ * a reserve.
+ * @param http_status the HTTP response code which is expected
+ * for this operation.
+ * @param justification human-readable justification for this
+ * tip authorization.
+ * @param amount the amount to authorize for tipping.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_tip_authorize_from_reserve (const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ const char *reserve_refernce,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount);
+
+
+/**
* Create a /tip-authorize CMD, specifying the Taler error code
* that is expected to be returned by the backend.
*
@@ -720,39 +817,46 @@ TALER_TESTING_cmd_tip_authorize_with_ec (const char *label,
/**
- * This commands does not query the backend at all,
- * but just makes up a fake authorization id that will
- * be subsequently used by the "pick up" CMD in order
- * to test against such a case.
- *
- * @param label command label.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_tip_authorize_fake (const char *label);
-
-
-/**
- * Create a /tip-authorize CMD.
+ * Create a /tip-authorize CMD, specifying the Taler error code
+ * that is expected to be returned by the backend.
*
* @param label this command label
* @param merchant_url the base URL of the merchant that will
* serve the /tip-authorize request.
* @param exchange_url the base URL of the exchange that owns
* the reserve from which the tip is going to be gotten.
+ * @param reserve_reference reference to a command that created
+ * a reserve.
* @param http_status the HTTP response code which is expected
* for this operation.
* @param justification human-readable justification for this
* tip authorization.
* @param amount the amount to authorize for tipping.
+ * @param ec expected Taler-defined error code.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_tip_authorize (const char *label,
- const char *merchant_url,
- const char *exchange_url,
- unsigned int http_status,
- const char *justification,
- const char *amount);
+TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ const char *
+ reserve_reference,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount,
+ enum TALER_ErrorCode ec);
+
+
+/**
+ * This commands does not query the backend at all,
+ * but just makes up a fake authorization id that will
+ * be subsequently used by the "pick up" CMD in order
+ * to test against such a case.
+ *
+ * @param label command label.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_tip_authorize_fake (const char *label);
/**
diff --git a/src/lib/merchant_api_tip_authorize.c b/src/lib/merchant_api_tip_authorize.c
index 8f8505df..01d369f6 100644
--- a/src/lib/merchant_api_tip_authorize.c
+++ b/src/lib/merchant_api_tip_authorize.c
@@ -250,7 +250,7 @@ TALER_MERCHANT_tip_authorize2 (
*end = '\0';
GNUNET_snprintf (arg_str,
sizeof (arg_str),
- "/private/reserves/%s/tip-authorize",
+ "private/reserves/%s/authorize-tip",
res_str);
tao->url = TALER_url_join (backend_url,
arg_str,
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index ff705a36..8663b2e3 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -51,6 +51,10 @@
static const char *pickup_amounts_1[] = {"EUR:5", NULL};
+static const char *pickup_amounts_2[] = {"EUR:0.01", NULL};
+
+static const char *pickup_refs[] = {"pickup-tip-1", "pickup-tip-4", NULL};
+
/**
* Payto URI of the customer (payer).
*/
@@ -654,12 +658,13 @@ run (void *cls,
MHD_HTTP_OK,
"tip 1",
"EUR:5.01"),
- TALER_TESTING_cmd_tip_authorize ("authorize-tip-2",
- merchant_url,
- EXCHANGE_URL,
- MHD_HTTP_OK,
- "tip 2",
- "EUR:5.01"),
+ TALER_TESTING_cmd_tip_authorize_from_reserve ("authorize-tip-2",
+ merchant_url,
+ EXCHANGE_URL,
+ "create-reserve-tip-1",
+ MHD_HTTP_OK,
+ "tip 2",
+ "EUR:5.01"),
TALER_TESTING_cmd_wallet_get_tip ("get-tip-1",
merchant_url,
"authorize-tip-1",
@@ -683,136 +688,94 @@ run (void *cls,
MHD_HTTP_OK,
"authorize-tip-1",
pickup_amounts_1),
- TALER_TESTING_cmd_merchant_delete_reserve ("delete-reserve-tip-1",
- merchant_url,
- "create-reserve-tip-1",
- MHD_HTTP_NO_CONTENT),
- TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-2",
- merchant_url,
- "create-reserve-tip-1",
- MHD_HTTP_NO_CONTENT),
- TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-3",
- merchant_url,
- "create-reserve-tip-1",
- MHD_HTTP_NOT_FOUND),
-#if 0
- /* Test tipping. */
- TALER_TESTING_cmd_admin_add_incoming_with_instance ("create-reserve-tip-1",
- "EUR:20.04",
- &bc.exchange_auth,
- payer_payto,
- "tip",
- CONFIG_FILE),
- cmd_exec_wirewatch ("wirewatch-3"),
- TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-tip-1",
- "EUR:20.04",
- payer_payto,
- exchange_payto,
- "create-reserve-tip-1"),
- TALER_TESTING_cmd_tip_authorize ("authorize-tip-1",
- merchant_url_internal ("tip"),
- EXCHANGE_URL,
- MHD_HTTP_OK,
- "tip 1",
- "EUR:5.01"),
- TALER_TESTING_cmd_tip_authorize ("authorize-tip-2",
- merchant_url_internal ("tip"),
- EXCHANGE_URL,
- MHD_HTTP_OK,
- "tip 2",
- "EUR:5.01"),
+ TALER_TESTING_cmd_wallet_get_tip2 ("query-tip-2",
+ merchant_url,
+ "authorize-tip-1",
+ "EUR:0.01",
+ MHD_HTTP_OK),
+ TALER_TESTING_cmd_tip_pickup ("pickup-tip-2",
+ merchant_url,
+ MHD_HTTP_OK,
+ "authorize-tip-2",
+ pickup_amounts_1),
+
+ TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-tip-3-too-much",
+ merchant_url,
+ MHD_HTTP_BAD_REQUEST,
+ "authorize-tip-1",
+ pickup_amounts_1,
+ TALER_EC_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING),
+
+ TALER_TESTING_cmd_tip_pickup ("pickup-tip-4",
+ merchant_url,
+ MHD_HTTP_OK,
+ "authorize-tip-1",
+ pickup_amounts_2),
+ TALER_TESTING_cmd_merchant_get_tip_with_pickups ("merchant-get-tip-2",
+ merchant_url,
+ "authorize-tip-1",
+ pickup_refs,
+ MHD_HTTP_OK),
+
/* This command tests the authorization of tip
* against a reserve that does not exist. This is
* implemented by passing a "tip instance" that
* specifies a reserve key that was never used to
* actually create a reserve. *///
- TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-null",
- merchant_url_internal ("nulltip"),
- EXCHANGE_URL,
- MHD_HTTP_SERVICE_UNAVAILABLE,
- "tip 2",
- "EUR:5.01",
- TALER_EC_TIP_QUERY_RESERVE_UNKNOWN_TO_EXCHANGE),
- TALER_TESTING_cmd_tip_query ("query-tip-1",
- merchant_url_internal ("tip"),
- MHD_HTTP_OK),
- TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-2",
- merchant_url_internal ("tip"),
- MHD_HTTP_OK,
- "EUR:0.0", // picked
- "EUR:10.02", // authorized
- "EUR:20.04"),// available
- TALER_TESTING_cmd_tip_pickup ("pickup-tip-1",
- merchant_url_external ("tip"),
- MHD_HTTP_OK,
- "authorize-tip-1",
- pickup_amounts_1),
- TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-3",
- merchant_url_internal ("tip"),
- MHD_HTTP_OK,
- "EUR:5.01", // picked
- NULL, // authorized
- "EUR:15.03"),// available
- TALER_TESTING_cmd_tip_pickup ("pickup-tip-2",
- merchant_url_external ("tip"),
- MHD_HTTP_OK,
- "authorize-tip-2",
- pickup_amounts_1),
- TALER_TESTING_cmd_tip_query_with_amounts ("query-tip-4",
- merchant_url_internal ("tip"),
- MHD_HTTP_OK,
- "EUR:10.02", // pick
- "EUR:10.02", // authorized
- "EUR:10.02"), // available
- TALER_TESTING_cmd_admin_add_incoming_with_instance (
- "create-reserve-insufficient-funds",
- "EUR:1.01",
- &bc.exchange_auth,
- payer_payto,
- "dtip",
- CONFIG_FILE),
- TALER_TESTING_cmd_check_bank_admin_transfer (
- "check_bank_transfer-insufficient-tip-funds",
- "EUR:1.01",
- payer_payto,
- exchange_payto,
- "create-reserve-insufficient-funds"),
- cmd_exec_wirewatch ("wirewatch-insufficient-tip-funds"),
- TALER_TESTING_cmd_tip_authorize_with_ec (
- "authorize-tip-3-insufficient-funds",
- merchant_url_internal ("dtip"),
+ TALER_TESTING_cmd_merchant_post_reserves_fake ("create-reserve-tip-2-fake"),
+ TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec ("authorize-tip-null",
+ merchant_url,
+ EXCHANGE_URL,
+ "create-reserve-tip-2-fake",
+ MHD_HTTP_NOT_FOUND,
+ "tip 3",
+ "EUR:5.01",
+ TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND),
+
+ // Test reserve with insufficient funds
+ TALER_TESTING_cmd_merchant_post_reserves ("create-reserve-tip-2",
+ merchant_url,
+ "EUR:1.04",
+ EXCHANGE_URL,
+ "x-taler-bank",
+ MHD_HTTP_OK),
+ TALER_TESTING_cmd_admin_add_incoming_with_ref ("create-reserve-tip-2-exch",
+ "EUR:1.04",
+ &bc.exchange_auth,
+ payer_payto,
+ "create-reserve-tip-2"),
+ cmd_exec_wirewatch ("wirewatch-4"),
+ TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (
+ "authorize-tip-insufficient-funds",
+ merchant_url,
EXCHANGE_URL,
+ "create-reserve-tip-2",
MHD_HTTP_PRECONDITION_FAILED,
- "tip 3",
- "EUR:2.02",
+ "tip 4",
+ "EUR:5.01",
TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS),
- TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-4-unknown-instance",
- merchant_url_internal ("unknown"),
- EXCHANGE_URL,
- MHD_HTTP_NOT_FOUND,
- "tip 4",
- "EUR:5.01",
- TALER_EC_INSTANCE_UNKNOWN),
- TALER_TESTING_cmd_tip_authorize_with_ec ("authorize-tip-5-notip-instance",
- merchant_url,
- EXCHANGE_URL,
- MHD_HTTP_PRECONDITION_FAILED,
- "tip 5",
- "EUR:5.01",
- TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP),
- TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-tip-3-too-much",
- merchant_url_external ("tip"),
- MHD_HTTP_CONFLICT,
- "authorize-tip-1",
- pickup_amounts_1,
- TALER_EC_TIP_PICKUP_NO_FUNDS),
+
TALER_TESTING_cmd_tip_authorize_fake ("fake-tip-authorization"),
TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-non-existent-id",
- merchant_url_external ("tip"),
+ merchant_url,
MHD_HTTP_NOT_FOUND,
"fake-tip-authorization",
pickup_amounts_1,
TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN),
+
+ TALER_TESTING_cmd_merchant_delete_reserve ("delete-reserve-tip-1",
+ merchant_url,
+ "create-reserve-tip-1",
+ MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-2",
+ merchant_url,
+ "create-reserve-tip-1",
+ MHD_HTTP_NO_CONTENT),
+ TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-3",
+ merchant_url,
+ "create-reserve-tip-1",
+ MHD_HTTP_NOT_FOUND),
+#if 0
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-tip-1",
merchant_url_internal ("tip"),
MHD_HTTP_OK,
diff --git a/src/testing/testing_api_cmd_get_reserve.c b/src/testing/testing_api_cmd_get_reserve.c
index d617c182..2a685ae4 100644
--- a/src/testing/testing_api_cmd_get_reserve.c
+++ b/src/testing/testing_api_cmd_get_reserve.c
@@ -100,7 +100,7 @@ get_reserve_cb (void *cls,
TALER_TESTING_get_trait_amount_obj (reserve_cmd,
0,
&initial_amount))
- TALER_TESTING_FAIL (grs->is);
+ TALER_TESTING_interpreter_fail (grs->is);
if ((GNUNET_OK != TALER_amount_cmp_currency (&rs->merchant_initial_amount,
initial_amount)) ||
(0 != TALER_amount_cmp (&rs->merchant_initial_amount,
diff --git a/src/testing/testing_api_cmd_merchant_get_tip.c b/src/testing/testing_api_cmd_merchant_get_tip.c
index f70356c7..085f9575 100644
--- a/src/testing/testing_api_cmd_merchant_get_tip.c
+++ b/src/testing/testing_api_cmd_merchant_get_tip.c
@@ -44,6 +44,16 @@ struct MerchantTipGetState
unsigned int http_status;
/**
+ * Whether to fetch and compare pickups.
+ */
+ bool fetch_pickups;
+
+ /**
+ * The NULL-terminated list of pickup commands associated with the tip.
+ */
+ const char **pickup_refs;
+
+ /**
* The handle to the current GET /tips/$TIP_ID request.
*/
struct TALER_MERCHANT_TipMerchantGetHandle *tgh;
@@ -86,8 +96,15 @@ merchant_get_tip_cb (void *cls,
{
/* FIXME, deeper checks should be implemented here. */
struct MerchantTipGetState *gts = cls;
+ const struct TALER_TESTING_Command *authorize_cmd;
+ struct TALER_Amount expected_total_picked_up;
+
+ authorize_cmd = TALER_TESTING_interpreter_lookup_command (gts->is,
+ gts->tip_reference);
gts->tgh = NULL;
+ GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (total_picked_up->currency,
+ &expected_total_picked_up));
if (gts->http_status != hr->http_status)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -103,6 +120,123 @@ merchant_get_tip_cb (void *cls,
case MHD_HTTP_OK:
// FIXME: use gts->tip_reference here to
// check if the data returned matches that from the POST / PATCH
+ {
+ const struct TALER_Amount *initial_amount;
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_amount_obj (authorize_cmd,
+ 0,
+ &initial_amount))
+ TALER_TESTING_FAIL (gts->is);
+ if ((GNUNET_OK != TALER_amount_cmp_currency (total_authorized,
+ initial_amount)) ||
+ (0 != TALER_amount_cmp (total_authorized,
+ initial_amount)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Tip authorized amount does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
+ {
+ const char *justification;
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_string (authorize_cmd,
+ 0,
+ &justification))
+ TALER_TESTING_FAIL (gts->is);
+ if (0 != strcmp (reason,
+ justification))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Tip authorized reason does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
+ {
+ const struct GNUNET_TIME_Absolute *tip_expiration;
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_absolute_time (authorize_cmd,
+ 0,
+ &tip_expiration))
+ TALER_TESTING_FAIL (gts->is);
+ if (tip_expiration->abs_value_us != expiration.abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Tip authorized expiration does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
+ {
+ for (unsigned int i = 0; i < pickups_length; ++i)
+ {
+ const struct TALER_TESTING_Command *pickup_cmd;
+ if (NULL == gts->pickup_refs[i])
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Length of pickup array does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+
+ pickup_cmd = TALER_TESTING_interpreter_lookup_command (gts->is,
+ gts->pickup_refs[
+ i]);
+ {
+ const uint64_t *num_planchets;
+
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_uint64 (pickup_cmd,
+ 0,
+ &num_planchets))
+ TALER_TESTING_FAIL (gts->is);
+
+ if (*num_planchets != pickups[i].num_planchets)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Pickup planchet count does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
+ {
+ const struct TALER_Amount *total;
+
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_amount_obj (pickup_cmd,
+ pickups[i].num_planchets,
+ &total))
+ TALER_TESTING_FAIL (gts->is);
+
+ if ((GNUNET_OK != TALER_amount_cmp_currency (total,
+ &pickups[i].
+ requested_amount)) ||
+ (0 != TALER_amount_cmp (total,
+ &pickups[i].requested_amount)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Pickup planchet sum does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ GNUNET_assert (0 < TALER_amount_add (&expected_total_picked_up,
+ &expected_total_picked_up,
+ total));
+ }
+ }
+ if ((GNUNET_OK != TALER_amount_cmp_currency (&expected_total_picked_up,
+ total_picked_up)) ||
+ (0 != TALER_amount_cmp (&expected_total_picked_up,
+ total_picked_up)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Tip picked up amount does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -141,7 +275,7 @@ merchant_get_tip_run (void *cls,
tgs->tgh = TALER_MERCHANT_merchant_tip_get (is->ctx,
tgs->merchant_url,
tip_id,
- false,
+ tgs->fetch_pickups,
&merchant_get_tip_cb,
tgs);
GNUNET_assert (NULL != tgs->tgh);
@@ -204,4 +338,43 @@ TALER_TESTING_cmd_merchant_get_tip (const char *label,
}
+/**
+ * Define a GET /private/tips/$TIP_ID CMD.
+ *
+ * @param label the command label
+ * @param merchant_url base URL of the merchant which will
+ * serve the request.
+ * @param tip_reference reference to a command that created a tip.
+ * @param pickup_refs a NULL-terminated list of pickup commands
+ * associated with the tip.
+ * @param http_status expected HTTP response code for the request.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_get_tip_with_pickups (const char *label,
+ const char *merchant_url,
+ const char *tip_reference,
+ const char *pickup_refs[],
+ unsigned int http_status)
+{
+ struct MerchantTipGetState *tgs;
+
+ tgs = GNUNET_new (struct MerchantTipGetState);
+ tgs->merchant_url = merchant_url;
+ tgs->tip_reference = tip_reference;
+ tgs->fetch_pickups = true;
+ tgs->pickup_refs = pickup_refs;
+ tgs->http_status = http_status;
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = tgs,
+ .label = label,
+ .run = &merchant_get_tip_run,
+ .cleanup = &merchant_get_tip_cleanup
+ };
+
+ return cmd;
+ }
+}
+
+
/* end of testing_api_cmd_merchant_get_tip.c */
diff --git a/src/testing/testing_api_cmd_post_reserves.c b/src/testing/testing_api_cmd_post_reserves.c
index 3d62d2f6..f25005c8 100644
--- a/src/testing/testing_api_cmd_post_reserves.c
+++ b/src/testing/testing_api_cmd_post_reserves.c
@@ -180,6 +180,34 @@ post_reserves_run (void *cls,
/**
+ * Run the fake "POST /reserves" CMD.
+ *
+ * @param cls closure.
+ * @param cmd command being run now.
+ * @param is interpreter state.
+ */
+static void
+post_reserves_fake_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct PostReservesState *prs = cls;
+ struct TALER_ReservePrivateKeyP reserve_priv;
+
+ prs->is = is;
+ prs->reserve_pub = GNUNET_new (struct TALER_ReservePublicKeyP);
+
+ GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv);
+ GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv,
+ &prs->reserve_pub->eddsa_pub);
+
+ GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:100.00",
+ &prs->initial_balance));
+ TALER_TESTING_interpreter_next (prs->is);
+}
+
+
+/**
* Free the state of a "POST /reserves" CMD, and possibly
* cancel a pending operation thereof.
*
@@ -244,3 +272,30 @@ TALER_TESTING_cmd_merchant_post_reserves (const char *label,
return cmd;
}
}
+
+
+/**
+ * This commands does not query the backend at all,
+ * but just makes up a fake reserve.
+ *
+ * @param label command label.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_merchant_post_reserves_fake (const char *label)
+{
+ struct PostReservesState *prs;
+
+ prs = GNUNET_new (struct PostReservesState);
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = prs,
+ .label = label,
+ .run = &post_reserves_fake_run,
+ .cleanup = &post_reserves_cleanup,
+ .traits = &post_reserves_traits
+ };
+
+ return cmd;
+ }
+}
diff --git a/src/testing/testing_api_cmd_tip_authorize.c b/src/testing/testing_api_cmd_tip_authorize.c
index e51b70f4..83b472ab 100644
--- a/src/testing/testing_api_cmd_tip_authorize.c
+++ b/src/testing/testing_api_cmd_tip_authorize.c
@@ -47,6 +47,12 @@ struct TipAuthorizeState
unsigned int http_status;
/**
+ * Reference to the reserv to authorize the tip
+ * from (if NULL, the merchant decides).
+ */
+ const char *reserve_reference;
+
+ /**
* Human-readable justification for the
* tip authorization carried on by this CMD.
*/
@@ -55,7 +61,7 @@ struct TipAuthorizeState
/**
* Amount that should be authorized for tipping.
*/
- const char *amount;
+ struct TALER_Amount amount;
/**
* Expected Taler error code for this CMD.
@@ -135,6 +141,7 @@ tip_authorize_cb (void *cls,
{
tas->tip_uri = strdup (taler_tip_uri);
tas->tip_id = *tip_id;
+ tas->tip_expiration = expiration;
}
TALER_TESTING_interpreter_next (tas->is);
}
@@ -157,15 +164,21 @@ tip_authorize_traits (void *cls,
unsigned int index)
{
struct TipAuthorizeState *tas = cls;
- struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_tip_id (0, &tas->tip_id),
- TALER_TESTING_trait_end (),
- };
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
+
+ {
+ struct TALER_TESTING_Trait traits[] = {
+ TALER_TESTING_make_trait_tip_id (0, &tas->tip_id),
+ TALER_TESTING_make_trait_amount_obj (0, &tas->amount),
+ TALER_TESTING_make_trait_string (0, tas->justification),
+ TALER_TESTING_make_trait_absolute_time (0, &tas->tip_expiration),
+ TALER_TESTING_trait_end (),
+ };
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+ }
}
@@ -182,20 +195,39 @@ tip_authorize_run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
struct TipAuthorizeState *tas = cls;
- struct TALER_Amount amount;
tas->is = is;
- if (GNUNET_OK != TALER_string_to_amount (tas->amount,
- &amount))
- TALER_TESTING_FAIL (is);
-
- tas->tao = TALER_MERCHANT_tip_authorize (is->ctx,
- tas->merchant_url,
- "http://merchant.com/pickup",
- &amount,
- tas->justification,
- &tip_authorize_cb,
- tas);
+ if (NULL == tas->reserve_reference)
+ {
+ tas->tao = TALER_MERCHANT_tip_authorize (is->ctx,
+ tas->merchant_url,
+ "http://merchant.com/pickup",
+ &tas->amount,
+ tas->justification,
+ &tip_authorize_cb,
+ tas);
+ }
+ else
+ {
+ const struct TALER_TESTING_Command *reserve_cmd;
+ const struct TALER_ReservePublicKeyP *reserve_pub;
+
+ reserve_cmd = TALER_TESTING_interpreter_lookup_command (
+ tas->is,
+ tas->reserve_reference);
+ GNUNET_assert (GNUNET_OK ==
+ TALER_TESTING_get_trait_reserve_pub (reserve_cmd,
+ 0,
+ &reserve_pub));
+ tas->tao = TALER_MERCHANT_tip_authorize2 (is->ctx,
+ tas->merchant_url,
+ reserve_pub,
+ "http://merchant.com/pickup",
+ &tas->amount,
+ tas->justification,
+ &tip_authorize_cb,
+ tas);
+ }
GNUNET_assert (NULL != tas->tao);
}
@@ -277,9 +309,65 @@ TALER_TESTING_cmd_tip_authorize_with_ec (const char *label,
tas = GNUNET_new (struct TipAuthorizeState);
tas->merchant_url = merchant_url;
tas->justification = justification;
- tas->amount = amount;
tas->http_status = http_status;
tas->expected_ec = ec;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (amount,
+ &tas->amount));
+ {
+ struct TALER_TESTING_Command cmd = {
+ .label = label,
+ .cls = tas,
+ .run = &tip_authorize_run,
+ .cleanup = &tip_authorize_cleanup,
+ .traits = &tip_authorize_traits
+ };
+
+ return cmd;
+ }
+}
+
+
+/**
+ * Create a /tip-authorize CMD, specifying the Taler error code
+ * that is expected to be returned by the backend.
+ *
+ * @param label this command label
+ * @param merchant_url the base URL of the merchant that will
+ * serve the /tip-authorize request.
+ * @param exchange_url the base URL of the exchange that owns
+ * the reserve from which the tip is going to be gotten.
+ * @param reserve_reference reference to a command that created
+ * a reserve.
+ * @param http_status the HTTP response code which is expected
+ * for this operation.
+ * @param justification human-readable justification for this
+ * tip authorization.
+ * @param amount the amount to authorize for tipping.
+ * @param ec expected Taler-defined error code.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ const char *
+ reserve_reference,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount,
+ enum TALER_ErrorCode ec)
+{
+ struct TipAuthorizeState *tas;
+
+ tas = GNUNET_new (struct TipAuthorizeState);
+ tas->merchant_url = merchant_url;
+ tas->justification = justification;
+ tas->http_status = http_status;
+ tas->expected_ec = ec;
+ tas->reserve_reference = reserve_reference;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (amount,
+ &tas->amount));
{
struct TALER_TESTING_Command cmd = {
.label = label,
@@ -321,8 +409,59 @@ TALER_TESTING_cmd_tip_authorize (const char *label,
tas = GNUNET_new (struct TipAuthorizeState);
tas->merchant_url = merchant_url;
tas->justification = justification;
- tas->amount = amount;
tas->http_status = http_status;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (amount,
+ &tas->amount));
+ {
+ struct TALER_TESTING_Command cmd = {
+ .label = label,
+ .cls = tas,
+ .run = &tip_authorize_run,
+ .cleanup = &tip_authorize_cleanup,
+ .traits = &tip_authorize_traits
+ };
+
+ return cmd;
+ }
+}
+
+
+/**
+ * Create a /tip-authorize CMD.
+ *
+ * @param label this command label
+ * @param merchant_url the base URL of the merchant that will
+ * serve the /tip-authorize request.
+ * @param exchange_url the base URL of the exchange that owns
+ * the reserve from which the tip is going to be gotten.
+ * @param reserve_reference reference to a command that created
+ * a reserve.
+ * @param http_status the HTTP response code which is expected
+ * for this operation.
+ * @param justification human-readable justification for this
+ * tip authorization.
+ * @param amount the amount to authorize for tipping.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_tip_authorize_from_reserve (const char *label,
+ const char *merchant_url,
+ const char *exchange_url,
+ const char *reserve_refernce,
+ unsigned int http_status,
+ const char *justification,
+ const char *amount)
+{
+ struct TipAuthorizeState *tas;
+
+ tas = GNUNET_new (struct TipAuthorizeState);
+ tas->merchant_url = merchant_url;
+ tas->reserve_reference = reserve_refernce;
+ tas->justification = justification;
+ tas->http_status = http_status;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (amount,
+ &tas->amount));
{
struct TALER_TESTING_Command cmd = {
.label = label,
diff --git a/src/testing/testing_api_cmd_tip_pickup.c b/src/testing/testing_api_cmd_tip_pickup.c
index d05b20d4..833ab6bc 100644
--- a/src/testing/testing_api_cmd_tip_pickup.c
+++ b/src/testing/testing_api_cmd_tip_pickup.c
@@ -85,9 +85,14 @@ struct TipPickupState
struct TALER_Amount *amounts_obj;
/**
+ * The sum of the the amounts above.
+ */
+ struct TALER_Amount total_amount;
+
+ /**
* How many coins are involved in the tipping operation.
*/
- unsigned int num_coins;
+ uint64_t num_coins;
/**
* The array of denomination keys, in the same order of @a
@@ -237,6 +242,15 @@ tip_pickup_run (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_string_to_amount (tps->amounts[i],
&tps->amounts_obj[i]));
+ if (0 == i)
+ GNUNET_assert (GNUNET_OK ==
+ TALER_amount_get_zero (tps->amounts_obj[i].currency,
+ &tps->total_amount));
+
+ GNUNET_assert (0 <
+ TALER_amount_add (&tps->total_amount,
+ &tps->total_amount,
+ &tps->amounts_obj[i]));
tps->dks[i] = TALER_TESTING_find_pk (is->keys,
&tps->amounts_obj[i]);
if (NULL == tps->dks[i])
@@ -329,7 +343,7 @@ tip_pickup_traits (void *cls,
unsigned int index)
{
struct TipPickupState *tps = cls;
- #define NUM_TRAITS (tps->num_coins * 5) + 2
+ #define NUM_TRAITS (tps->num_coins * 5) + 4
struct TALER_TESTING_Trait traits[NUM_TRAITS];
for (unsigned int i = 0; i<tps->num_coins; i++)
@@ -345,6 +359,12 @@ tip_pickup_traits (void *cls,
traits[i + (tps->num_coins * 4)] =
TALER_TESTING_make_trait_amount_obj (i, &tps->amounts_obj[i]);
}
+ traits[NUM_TRAITS - 4]
+ = TALER_TESTING_make_trait_amount_obj (tps->num_coins,
+ &tps->total_amount);
+ traits[NUM_TRAITS - 3]
+ = TALER_TESTING_make_trait_uint64 (0,
+ &tps->num_coins);
traits[NUM_TRAITS - 2]
= TALER_TESTING_make_trait_url (TALER_TESTING_UT_EXCHANGE_BASE_URL,
tps->exchange_url);
diff --git a/src/testing/testing_api_cmd_wallet_get_tip.c b/src/testing/testing_api_cmd_wallet_get_tip.c
index f76c3b69..0374adae 100644
--- a/src/testing/testing_api_cmd_wallet_get_tip.c
+++ b/src/testing/testing_api_cmd_wallet_get_tip.c
@@ -45,6 +45,16 @@ struct WalletTipGetState
unsigned int http_status;
/**
+ * Whether to compare amounts or not.
+ */
+ bool cmp_amounts;
+
+ /**
+ * The expected amount remaining.
+ */
+ struct TALER_Amount amount_remaining;
+
+ /**
* The handle to the current GET /tips/$TIP_ID request.
*/
struct TALER_MERCHANT_TipWalletGetHandle *tgh;
@@ -81,6 +91,11 @@ wallet_tip_get_cb (void *cls,
{
/* FIXME, deeper checks should be implemented here. */
struct WalletTipGetState *gts = cls;
+ const struct TALER_TESTING_Command *tip_cmd;
+
+ tip_cmd = TALER_TESTING_interpreter_lookup_command (
+ gts->is,
+ gts->tip_reference);
gts->tgh = NULL;
if (gts->http_status != hr->http_status)
@@ -98,6 +113,35 @@ wallet_tip_get_cb (void *cls,
case MHD_HTTP_OK:
// FIXME: use gts->tip_reference here to
// check if the data returned matches that from the POST / PATCH
+ if (gts->cmp_amounts)
+ {
+ if ((GNUNET_OK != TALER_amount_cmp_currency (&gts->amount_remaining,
+ amount_remaining)) ||
+ (0 != TALER_amount_cmp (&gts->amount_remaining,
+ amount_remaining)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Amount remaining on tip does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
+ {
+ const struct GNUNET_TIME_Absolute *expiration;
+
+ if (GNUNET_OK !=
+ TALER_TESTING_get_trait_absolute_time (tip_cmd,
+ 0,
+ &expiration))
+ TALER_TESTING_interpreter_fail (gts->is);
+ if (expiration->abs_value_us != reserve_expiration.abs_value_us)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Tip expiration does not match\n");
+ TALER_TESTING_interpreter_fail (gts->is);
+ return;
+ }
+ }
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -197,4 +241,43 @@ TALER_TESTING_cmd_wallet_get_tip (const char *label,
}
+/**
+ * Define a GET /tips/$TIP_ID CMD.
+ *
+ * @param label the command label
+ * @param merchant_url base URL of the merchant which will
+ * serve the request.
+ * @param tip_reference reference to a command that created a tip.
+ * @param amount_remaining the balance remaining after pickups.
+ * @param http_status expected HTTP response code for the request.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wallet_get_tip2 (const char *label,
+ const char *merchant_url,
+ const char *tip_reference,
+ const char *amount_remaining,
+ unsigned int http_status)
+{
+ struct WalletTipGetState *tgs;
+
+ tgs = GNUNET_new (struct WalletTipGetState);
+ tgs->merchant_url = merchant_url;
+ tgs->tip_reference = tip_reference;
+ tgs->cmp_amounts = true;
+ GNUNET_assert (GNUNET_OK == TALER_string_to_amount (amount_remaining,
+ &tgs->amount_remaining));
+ tgs->http_status = http_status;
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = tgs,
+ .label = label,
+ .run = &wallet_get_tip_run,
+ .cleanup = &wallet_get_tip_cleanup
+ };
+
+ return cmd;
+ }
+}
+
+
/* end of testing_api_cmd_get_tip.c */