diff options
author | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-06-17 21:35:09 -0400 |
---|---|---|
committer | Jonathan Buchanan <jonathan.russ.buchanan@gmail.com> | 2020-06-17 21:35:09 -0400 |
commit | 6624576c0cdd81072256d8abbfe6dd1343f956c6 (patch) | |
tree | a7f19eae242d0ee3e889da9fb4f8a00efdaf4eed | |
parent | 06010ba8681aa588c977410e0ae6f32879435432 (diff) |
implementations, tests, and renames for GET /tips/ & GET /private/tips/
-rw-r--r-- | src/backend/Makefile.am | 2 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 7 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_get-tips-ID.c | 14 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-tips-ID.c | 46 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_private-get-tips-ID.h | 4 | ||||
-rw-r--r-- | src/include/taler_merchant_service.h | 104 | ||||
-rw-r--r-- | src/include/taler_merchant_testing_lib.h | 273 | ||||
-rw-r--r-- | src/lib/Makefile.am | 5 | ||||
-rw-r--r-- | src/lib/merchant_api_merchant_get_tip.c | 339 | ||||
-rw-r--r-- | src/lib/merchant_api_wallet_get_tip.c (renamed from src/lib/merchant_api_tip_query.c) | 83 | ||||
-rw-r--r-- | src/testing/Makefile.am | 3 | ||||
-rw-r--r-- | src/testing/test_merchant_api.c | 8 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_merchant_get_tip.c | 207 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_tip_authorize.c | 2 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_tip_query.c | 292 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_wallet_get_tip.c | 200 |
16 files changed, 1075 insertions, 514 deletions
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 4a7fa382..3682363f 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -28,6 +28,8 @@ taler_merchant_httpd_SOURCES = \ taler-merchant-httpd_get-tips-ID.h \ taler-merchant-httpd_private-get-tips.c \ taler-merchant-httpd_private-get-tips.h \ + taler-merchant-httpd_private-get-tips-ID.c \ + taler-merchant-httpd_private-get-tips-ID.h \ taler-merchant-httpd_mhd.c taler-merchant-httpd_mhd.h \ taler-merchant-httpd_private-delete-instances-ID.c \ taler-merchant-httpd_private-delete-instances-ID.h \ diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index b8791225..34c31647 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -883,6 +883,13 @@ url_handler (void *cls, .method = MHD_HTTP_METHOD_GET, .handler = &TMH_private_get_tips }, + /* GET /tips/$ID: */ + { + .url_prefix = "/tips/", + .method = MHD_HTTP_METHOD_GET, + .have_id_segment = true, + .handler = &TMH_private_get_tips_ID + }, /* GET /reserves: */ { .url_prefix = "/reserves", diff --git a/src/backend/taler-merchant-httpd_get-tips-ID.c b/src/backend/taler-merchant-httpd_get-tips-ID.c index fc77b2f3..52a0a561 100644 --- a/src/backend/taler-merchant-httpd_get-tips-ID.c +++ b/src/backend/taler-merchant-httpd_get-tips-ID.c @@ -95,19 +95,25 @@ TMH_get_tips_ID (const struct TMH_RequestHandler *rh, { MHD_RESULT ret; struct TALER_Amount remaining; + struct GNUNET_TIME_Absolute expiration_round = expiration; - GNUNET_break (0 >= + GNUNET_break (0 <= TALER_amount_subtract (&remaining, &total_authorized, &total_picked_up)); + + GNUNET_TIME_round_abs (&expiration_round); + ret = TALER_MHD_reply_json_pack (connection, MHD_HTTP_OK, - "{s:s, s:o, s:o, s:o}", - "exchange_url", exchange_url, + "{s:s, s:o, s:o}", + "exchange_url", + exchange_url, "tip_amount", TALER_JSON_from_amount (&remaining), "expiration", - GNUNET_JSON_from_time_abs (expiration)); + GNUNET_JSON_from_time_abs ( + expiration_round)); GNUNET_free (exchange_url); return ret; } diff --git a/src/backend/taler-merchant-httpd_private-get-tips-ID.c b/src/backend/taler-merchant-httpd_private-get-tips-ID.c index 59de1b68..7c70a689 100644 --- a/src/backend/taler-merchant-httpd_private-get-tips-ID.c +++ b/src/backend/taler-merchant-httpd_private-get-tips-ID.c @@ -26,7 +26,6 @@ #include "taler-merchant-httpd.h" #include "taler-merchant-httpd_mhd.h" #include "taler-merchant-httpd_exchanges.h" -#include "taler-merchant-httpd_tip-pickup.h" /** @@ -47,12 +46,12 @@ TMH_private_get_tips_ID (const struct TMH_RequestHandler *rh, struct TALER_Amount total_picked_up; char *reason; struct GNUNET_TIME_Absolute expiration; + struct TALER_ReservePublicKeyP reserve_pub; unsigned int pickups_length = 0; struct TALER_MERCHANTDB_PickupDetails *pickups = NULL; - struct GNUNET_TIME_Absolute timestamp_expire; enum GNUNET_DB_QueryStatus qs; bool fpu; - json_t *pickups_json; + json_t *pickups_json = NULL; GNUNET_assert (NULL != hc->infix); if (GNUNET_OK != @@ -76,18 +75,18 @@ TMH_private_get_tips_ID (const struct TMH_RequestHandler *rh, ? 0 == strcasecmp (pstr, "yes") : false; } - db->preflight (db->cls); - qs = db->lookup_tip_details (db->cls, - hc->instance->settings.id, - &tip_id, - fpu, - &total_authorized, - &total_picked_up, - &reason, - &expiration, - &reserve_pub, - &pickups_length, - &pickups); + TMH_db->preflight (TMH_db->cls); + qs = TMH_db->lookup_tip_details (TMH_db->cls, + hc->instance->settings.id, + &tip_id, + fpu, + &total_authorized, + &total_picked_up, + &reason, + &expiration, + &reserve_pub, + &pickups_length, + &pickups); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) { unsigned int response_code; @@ -126,30 +125,33 @@ TMH_private_get_tips_ID (const struct TMH_RequestHandler *rh, { json_array_append_new ( pickups_json, - json_pack ("{s:o,s:o,s:I}", + json_pack ("{s:o,s:I,s:o}", "pickup_id", GNUNET_JSON_from_data_auto (&pickups[i].pickup_id), - "requested_amount", - TALER_JSON_from_amount (&pickups[i].requested_amount), "num_planchets", - (json_int_t) pickups[i].num_planchets)); + (json_int_t) pickups[i].num_planchets, + "requested_amount", + TALER_JSON_from_amount (&pickups[i].requested_amount))); } } GNUNET_array_grow (pickups, pickups_length, 0); { + struct GNUNET_TIME_Absolute expiration_round = expiration; MHD_RESULT ret; + GNUNET_TIME_round_abs (&expiration_round); + ret = TALER_MHD_reply_json_pack ( connection, MHD_HTTP_OK, - "{s:s, s:o, s:o, s:o, s:o, s:o?}", - "reason", reason, + "{s:o, s:o, s:s, s:o, s:o, s:o?}", "total_authorized", TALER_JSON_from_amount (&total_authorized), "total_picked_up", TALER_JSON_from_amount (&total_picked_up), + "reason", reason, + "expiration", GNUNET_JSON_from_time_abs (expiration_round), "reserve_pub", GNUNET_JSON_from_data_auto (&reserve_pub), - "expiration", GNUNET_JSON_from_time_abs (expiration), "pickups", pickups_json); GNUNET_free (reason); return ret; diff --git a/src/backend/taler-merchant-httpd_private-get-tips-ID.h b/src/backend/taler-merchant-httpd_private-get-tips-ID.h index bc594690..5c428c92 100644 --- a/src/backend/taler-merchant-httpd_private-get-tips-ID.h +++ b/src/backend/taler-merchant-httpd_private-get-tips-ID.h @@ -18,8 +18,8 @@ * @brief headers for GET /tips/ID handler * @author Christian Grothoff */ -#ifndef TALER_MERCHANT_HTTPD_GET_TIPS_ID_H -#define TALER_MERCHANT_HTTPD_GET_TIPS_ID_H +#ifndef TALER_MERCHANT_HTTPD_PRIVATE_GET_TIPS_ID_H +#define TALER_MERCHANT_HTTPD_PRIVATE_GET_TIPS_ID_H #include <microhttpd.h> #include "taler-merchant-httpd.h" diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h index 740c213d..4d8c0ef5 100644 --- a/src/include/taler_merchant_service.h +++ b/src/include/taler_merchant_service.h @@ -2793,7 +2793,7 @@ TALER_MERCHANT_reserve_delete_cancel ( /** * Handle for a GET /tips/$TIP_ID (public variant) operation. */ -struct TALER_MERCHANT_TipGetHandle; +struct TALER_MERCHANT_TipWalletGetHandle; /** @@ -2806,12 +2806,12 @@ struct TALER_MERCHANT_TipGetHandle; * @param amount_remaining total amount still available for the tip */ typedef void -(*TALER_MERCHANT_TipGetCallback) ( +(*TALER_MERCHANT_TipWalletGetCallback) ( void *cls, const struct TALER_MERCHANT_HttpResponse *hr, struct GNUNET_TIME_Absolute expiration, const char *exchange_url, - struct TALER_Amount *amount_remaining); + const struct TALER_Amount *amount_remaining); /** @@ -2825,21 +2825,102 @@ typedef void * @param cb_cls closure for @a cb * @return handle for this operation, NULL upon errors */ -struct TALER_MERCHANT_TipGetHandle * -TALER_MERCHANT_tip_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct GNUNET_HashCode *tip_id, - TALER_MERCHANT_TipGetCallback cb, - void *cb_cls); +struct TALER_MERCHANT_TipWalletGetHandle * +TALER_MERCHANT_wallet_tip_get (struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct GNUNET_HashCode *tip_id, + TALER_MERCHANT_TipWalletGetCallback cb, + void *cb_cls); /** - * Cancel a GET /tip-get request. + * Cancel a GET /tips/$TIP_ID request. * * @param tqo handle to the request to be canceled */ void -TALER_MERCHANT_tip_get_cancel (struct TALER_MERCHANT_TipGetHandle *tqh); +TALER_MERCHANT_wallet_tip_get_cancel (struct + TALER_MERCHANT_TipWalletGetHandle *tgh); + + +/** + * Handle for a GET /private/tips/$TIP_ID (private variant) operation. + */ +struct TALER_MERCHANT_TipMerchantGetHandle; + + +/** + * Summary information for a tip pickup. + */ +struct TALER_MERCHANT_PickupDetail +{ + /** + * Identifier of the pickup. + */ + struct GNUNET_HashCode pickup_id; + + /** + * Number of planchets involved. + */ + uint64_t num_planchets; + + /** + * Total amount requested for this pickup. + */ + struct TALER_Amount requested_amount; +}; + +/** + * Callback to process a GET /private/tips/$TIP_ID request + * + * @param cls closure + * @param hr HTTP response details + * @param expiration when the tip will expire + * @param exchange_url exchange from which the coins should be withdrawn + * @param amount_remaining total amount still available for the tip + */ +typedef void +(*TALER_MERCHANT_TipMerchantGetCallback) ( + void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + const struct TALER_Amount *total_authorized, + const struct TALER_Amount *total_picked_up, + const char *reason, + struct GNUNET_TIME_Absolute expiration, + const struct TALER_ReservePublicKeyP *reserve_pub, + unsigned int pickups_length, + const struct TALER_MERCHANT_PickupDetail pickups[]); + + +/** + * Issue a GET /private/tips/$TIP_ID (private variant) request to the backend. + * Returns information needed to pick up a tip. + * + * @param ctx execution context + * @param backend_url base URL of the merchant backend + * @param tip_id which tip should we query + * @param pickups whether to fetch associated pickups + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return handle for this operation, NULL upon errors + */ +struct TALER_MERCHANT_TipMerchantGetHandle * +TALER_MERCHANT_merchant_tip_get (struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct GNUNET_HashCode *tip_id, + bool pickups, + TALER_MERCHANT_TipMerchantGetCallback cb, + void *cb_cls); + + +/** + * Cancel a GET /private/tips/$TIP_ID request. + * + * @param tqo handle to the request to be canceled + */ +void +TALER_MERCHANT_merchant_tip_get_cancel (struct + TALER_MERCHANT_TipMerchantGetHandle *tgh); /** @@ -2858,7 +2939,6 @@ struct TALER_MERCHANT_TipEntry */ uint64_t row_id; - /** * Identifier for the tip. */ diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h index 60846a9e..c7813176 100644 --- a/src/include/taler_merchant_testing_lib.h +++ b/src/include/taler_merchant_testing_lib.h @@ -661,6 +661,142 @@ TALER_TESTING_cmd_get_tips (const char *label, unsigned int http_status); +/** + * 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 http_status expected HTTP response code for the request. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_tip (const char *label, + const char *merchant_url, + const char *tip_reference, + unsigned int http_status); + + +/** + * 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 http_status expected HTTP response code for the request. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_wallet_get_tip (const char *label, + const char *merchant_url, + const char *tip_reference, + unsigned int http_status); + + +/** + * 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 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_with_ec (const char *label, + const char *merchant_url, + const char *exchange_url, + 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); + + +/** + * 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); + + +/** + * Define a /tip-pickup CMD, equipped with the expected error + * code. + * + * @param label the command label + * @param merchant_url base URL of the backend which will serve + * the /tip-pickup request. + * @param http_status expected HTTP response code. + * @param authorize_reference reference to a /tip-autorize CMD + * that offers a tip id to pick up. + * @param amounts array of string-defined amounts that specifies + * which denominations will be accepted for tipping. + * @param ec expected Taler error code. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_tip_pickup_with_ec (const char *label, + const char *merchant_url, + unsigned int http_status, + const char *authorize_reference, + const char **amounts, + enum TALER_ErrorCode ec); + +/** + * Define a /tip-pickup CMD. + * + * @param label the command label + * @param merchant_url base URL of the backend which will serve + * the /tip-pickup request. + * @param http_status expected HTTP response code. + * @param authorize_reference reference to a /tip-autorize CMD + * that offers a tip id to pick up. + * @param amounts array of string-defined amounts that specifies + * which denominations will be accepted for tipping. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_tip_pickup (const char *label, + const char *merchant_url, + unsigned int http_status, + const char *authorize_reference, + const char **amounts); + + /* ******************** OLD ******************* */ @@ -1096,143 +1232,6 @@ TALER_TESTING_get_trait_refund_entry ( // FIXME: rename: entry->detail unsigned int index, const struct TALER_MERCHANT_RefundDetail **refund_entry); -/** - * 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 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_with_ec (const char *label, - const char *merchant_url, - const char *exchange_url, - 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); - - -/** - * 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); - -/** - * Define a /tip-query CMD. - * - * @param label the command label - * @param merchant_url base URL of the merchant which will - * server the /tip-query request. - * @param http_status expected HTTP response code for the - * /tip-query request. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_query (const char *label, - const char *merchant_url, - unsigned int http_status); - -/** - * Define a /tip-query CMD equipped with a expected amount. - * - * @param label the command label - * @param merchant_url base URL of the merchant which will - * server the /tip-query request. - * @param http_status expected HTTP response code for the - * /tip-query request. - * @param expected_amount_picked_up expected amount already - * picked up. - * @param expected_amount_authorized expected amount that was - * authorized in the first place. - * @param expected_amount_available FIXME what is this? - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_query_with_amounts (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *expected_amount_picked_up, - const char *expected_amount_authorized, - const char *expected_amount_available); - -/** - * Define a /tip-pickup CMD, equipped with the expected error - * code. - * - * @param label the command label - * @param merchant_url base URL of the backend which will serve - * the /tip-pickup request. - * @param http_status expected HTTP response code. - * @param authorize_reference reference to a /tip-autorize CMD - * that offers a tip id to pick up. - * @param amounts array of string-defined amounts that specifies - * which denominations will be accepted for tipping. - * @param ec expected Taler error code. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_pickup_with_ec (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *authorize_reference, - const char **amounts, - enum TALER_ErrorCode ec); - -/** - * Define a /tip-pickup CMD. - * - * @param label the command label - * @param merchant_url base URL of the backend which will serve - * the /tip-pickup request. - * @param http_status expected HTTP response code. - * @param authorize_reference reference to a /tip-autorize CMD - * that offers a tip id to pick up. - * @param amounts array of string-defined amounts that specifies - * which denominations will be accepted for tipping. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_pickup (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *authorize_reference, - const char **amounts); /** * Make the instruction pointer point to @a new_ip diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 9c02f332..d0bfaeb4 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -29,6 +29,7 @@ libtalermerchant_la_SOURCES = \ merchant_api_get_transfers.c \ merchant_api_lock_product.c \ merchant_api_merchant_get_order.c \ + merchant_api_merchant_get_tip.c \ merchant_api_patch_instance.c \ merchant_api_patch_product.c \ merchant_api_post_instances.c \ @@ -45,9 +46,9 @@ libtalermerchant_la_SOURCES = \ merchant_api_tip_authorize.c \ merchant_api_tip_pickup.c \ merchant_api_tip_pickup2.c \ - merchant_api_tip_query.c \ merchant_api_track_transaction.c \ - merchant_api_wallet_get_order.c + merchant_api_wallet_get_order.c \ + merchant_api_wallet_get_tip.c # merchant_api_get_transfers.c # merchant_api_get_order.c \ diff --git a/src/lib/merchant_api_merchant_get_tip.c b/src/lib/merchant_api_merchant_get_tip.c new file mode 100644 index 00000000..5ecd65ee --- /dev/null +++ b/src/lib/merchant_api_merchant_get_tip.c @@ -0,0 +1,339 @@ +/* + This file is part of TALER + Copyright (C) 2020 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING.LGPL. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/merchant_api_merchant_get_tip.c + * @brief Implementation of the GET /private/tips/$TIP_ID request of the merchant's HTTP API + * @author Jonathan Buchanan + */ +#include "platform.h" +#include <curl/curl.h> +#include <jansson.h> +#include <microhttpd.h> /* just for HTTP status codes */ +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_curl_lib.h> +#include "taler_merchant_service.h" +#include <taler/taler_json_lib.h> +#include <taler/taler_signatures.h> + + +struct TALER_MERCHANT_TipMerchantGetHandle +{ + /** + * The url for this request. + */ + char *url; + + /** + * Handle for the request. + */ + struct GNUNET_CURL_Job *job; + + /** + * Function to call with the result. + */ + TALER_MERCHANT_TipMerchantGetCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Reference to the execution context. + */ + struct GNUNET_CURL_Context *ctx; +}; + + +static int +parse_pickups (const json_t *pa, + const struct TALER_Amount *total_authorized, + const struct TALER_Amount *total_picked_up, + const char *reason, + struct GNUNET_TIME_Absolute expiration, + const struct TALER_ReservePublicKeyP *reserve_pub, + struct TALER_MERCHANT_TipMerchantGetHandle *tgh) +{ + unsigned int pa_len = json_array_size (pa); + struct TALER_MERCHANT_PickupDetail pickups[pa_len]; + size_t index; + json_t *value; + int ret = GNUNET_OK; + + json_array_foreach (pa, index, value) + { + struct TALER_MERCHANT_PickupDetail *pickup = &pickups[index]; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("pickup_id", + &pickup->pickup_id), + GNUNET_JSON_spec_uint64 ("num_planchets", + &pickup->num_planchets), + TALER_JSON_spec_amount ("requested_amount", + &pickup->requested_amount), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, + NULL)) + { + GNUNET_break_op (0); + ret = GNUNET_SYSERR; + break; + } + } + if (GNUNET_OK == ret) + { + struct TALER_MERCHANT_HttpResponse hr = { + .http_status = MHD_HTTP_OK + }; + + tgh->cb (tgh->cb_cls, + &hr, + total_authorized, + total_picked_up, + reason, + expiration, + reserve_pub, + pa_len, + pickups); + } + return ret; +} + + +/** + * Function called when we're done processing the + * GET /private/tips/$TIP_ID request. + * + * @param cls the `struct TALER_MERCHANT_TipMerchantGetHandle` + * @param response_code HTTP response code, 0 on error + * @param json response body, NULL if not in JSON + */ +static void +handle_merchant_tip_get_finished (void *cls, + long response_code, + const void *response) +{ + struct TALER_MERCHANT_TipMerchantGetHandle *tgh = cls; + const json_t *json = response; + struct TALER_MERCHANT_HttpResponse hr = { + .http_status = (unsigned int) response_code, + .reply = json + }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Got /private/tips/$TIP_ID response with status code %u\n", + (unsigned int) response_code); + tgh->job = NULL; + switch (response_code) + { + case MHD_HTTP_OK: + { + struct TALER_Amount total_authorized; + struct TALER_Amount total_picked_up; + const char *reason; + struct GNUNET_TIME_Absolute expiration; + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_JSON_Specification spec[] = { + TALER_JSON_spec_amount ("total_authorized", + &total_authorized), + TALER_JSON_spec_amount ("total_picked_up", + &total_picked_up), + GNUNET_JSON_spec_string ("reason", + &reason), + GNUNET_JSON_spec_absolute_time ("expiration", + &expiration), + GNUNET_JSON_spec_fixed_auto ("reserve_pub", + &reserve_pub), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (json, + spec, + NULL, NULL)) + { + hr.http_status = 0; + hr.ec = TALER_EC_INVALID_RESPONSE; + } + else + { + json_t *pickups = json_object_get (json, + "pickups"); + if (! json_is_array (pickups)) + { + tgh->cb (tgh->cb_cls, + &hr, + &total_authorized, + &total_picked_up, + reason, + expiration, + &reserve_pub, + 0, + NULL); + TALER_MERCHANT_merchant_tip_get_cancel (tgh); + return; + } + else if (GNUNET_OK == parse_pickups (pickups, + &total_authorized, + &total_picked_up, + reason, + expiration, + &reserve_pub, + tgh)) + { + GNUNET_JSON_parse_free (spec); + TALER_MERCHANT_merchant_tip_get_cancel (tgh); + return; + } + else + { + hr.http_status = 0; + hr.ec = TALER_EC_INVALID_RESPONSE; + } + } + GNUNET_JSON_parse_free (spec); + break; + } + case MHD_HTTP_INTERNAL_SERVER_ERROR: + /* Server had an internal issue; we should retry, but this API + leaves this to the application */ + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + break; + case MHD_HTTP_NOT_FOUND: + /* legal, can happen if instance or tip reserve is unknown */ + hr.ec = TALER_JSON_get_error_code (json); + hr.hint = TALER_JSON_get_error_hint (json); + break; + default: + /* unexpected response code */ + GNUNET_break_op (0); + TALER_MERCHANT_parse_error_details_ (json, + response_code, + &hr); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d\n", + (unsigned int) response_code, + (int) hr.ec); + break; + } + tgh->cb (tgh->cb_cls, + &hr, + NULL, + NULL, + NULL, + GNUNET_TIME_UNIT_ZERO_ABS, + NULL, + 0, + NULL); + TALER_MERCHANT_merchant_tip_get_cancel (tgh); +} + + +/** + * Issue a GET /private/tips/$TIP_ID (private variant) request to the backend. + * Returns information needed to pick up a tip. + * + * @param ctx execution context + * @param backend_url base URL of the merchant backend + * @param tip_id which tip should we query + * @param cb function to call with the result + * @param cb_cls closure for @a cb + * @return handle for this operation, NULL upon errors + */ +struct TALER_MERCHANT_TipMerchantGetHandle * +TALER_MERCHANT_merchant_tip_get (struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct GNUNET_HashCode *tip_id, + bool pickups, + TALER_MERCHANT_TipMerchantGetCallback cb, + void *cb_cls) +{ + struct TALER_MERCHANT_TipMerchantGetHandle *tgh; + CURL *eh; + + GNUNET_assert (NULL != backend_url); + tgh = GNUNET_new (struct TALER_MERCHANT_TipMerchantGetHandle); + tgh->ctx = ctx; + tgh->cb = cb; + tgh->cb_cls = cb_cls; + + { + char res_str[sizeof (*tip_id) * 2]; + char arg_str[sizeof (res_str) + 48]; + char *end; + + end = GNUNET_STRINGS_data_to_string (tip_id, + sizeof (*tip_id), + res_str, + sizeof (res_str)); + *end = '\0'; + GNUNET_snprintf (arg_str, + sizeof (arg_str), + "private/tips/%s", + res_str); + tgh->url = TALER_url_join (backend_url, + arg_str, + "pickups", pickups ? "yes" : NULL, + NULL); + } + if (NULL == tgh->url) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not construct request URL.\n"); + GNUNET_free (tgh); + return NULL; + } + + eh = curl_easy_init (); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_URL, + tgh->url)); + tgh->job = GNUNET_CURL_job_add (ctx, + eh, + GNUNET_YES, + &handle_merchant_tip_get_finished, + tgh); + return tgh; +} + + +/** + * Cancel a GET /private/tips/$TIP_ID request. + * + * @param tgh handle to the request to be canceled + */ +void +TALER_MERCHANT_merchant_tip_get_cancel (struct + TALER_MERCHANT_TipMerchantGetHandle *tgh) +{ + if (NULL != tgh->job) + { + GNUNET_CURL_job_cancel (tgh->job); + tgh->job = NULL; + } + GNUNET_free (tgh->url); + GNUNET_free (tgh); +} + + +/* end of merchant_api_merchant_get_tip.c */ diff --git a/src/lib/merchant_api_tip_query.c b/src/lib/merchant_api_wallet_get_tip.c index cf2f8042..64a76f18 100644 --- a/src/lib/merchant_api_tip_query.c +++ b/src/lib/merchant_api_wallet_get_tip.c @@ -15,7 +15,7 @@ <http://www.gnu.org/licenses/> */ /** - * @file lib/merchant_api_tip_query.c => FIXME: rename! + * @file lib/merchant_api_wallet_get_tip.c * @brief Implementation of the GET /tips/$TIP_ID request of the merchant's HTTP API * @author Florian Dold */ @@ -33,7 +33,7 @@ /** * @brief A handle for tracking /tip-get operations */ -struct TALER_MERCHANT_TipGetHandle +struct TALER_MERCHANT_TipWalletGetHandle { /** * The url for this request. @@ -48,7 +48,7 @@ struct TALER_MERCHANT_TipGetHandle /** * Function to call with the result. */ - TALER_MERCHANT_TipGetCallback cb; + TALER_MERCHANT_TipWalletGetCallback cb; /** * Closure for @a cb. @@ -72,11 +72,11 @@ struct TALER_MERCHANT_TipGetHandle * @param json response body, NULL if not in JSON */ static void -handle_tip_get_finished (void *cls, - long response_code, - const void *response) +handle_wallet_tip_get_finished (void *cls, + long response_code, + const void *response) { - struct TALER_MERCHANT_TipGetHandle *tqo = cls; + struct TALER_MERCHANT_TipWalletGetHandle *tgh = cls; const json_t *json = response; struct TALER_MERCHANT_HttpResponse hr = { .http_status = (unsigned int) response_code, @@ -84,10 +84,10 @@ handle_tip_get_finished (void *cls, }; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Got /tip-get response with status code %u\n", + "Got /tip/$TIP_ID response with status code %u\n", (unsigned int) response_code); - tqo->job = NULL; + tgh->job = NULL; switch (response_code) { case MHD_HTTP_OK: @@ -115,12 +115,12 @@ handle_tip_get_finished (void *cls, hr.ec = TALER_EC_INVALID_RESPONSE; break; } - tqo->cb (tqo->cb_cls, + tgh->cb (tgh->cb_cls, &hr, expiration, exchange_url, &amount_remaining); - TALER_MERCHANT_tip_get_cancel (tqo); + TALER_MERCHANT_wallet_tip_get_cancel (tgh); return; } case MHD_HTTP_INTERNAL_SERVER_ERROR: @@ -146,12 +146,12 @@ handle_tip_get_finished (void *cls, (int) hr.ec); break; } - tqo->cb (tqo->cb_cls, + tgh->cb (tgh->cb_cls, &hr, GNUNET_TIME_UNIT_ZERO_ABS, NULL, NULL); - TALER_MERCHANT_tip_get_cancel (tqo); + TALER_MERCHANT_wallet_tip_get_cancel (tgh); } @@ -166,20 +166,20 @@ handle_tip_get_finished (void *cls, * @param cb_cls closure for @a cb * @return handle for this operation, NULL upon errors */ -struct TALER_MERCHANT_TipGetHandle * -TALER_MERCHANT_tip_get (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const struct GNUNET_HashCode *tip_id, - TALER_MERCHANT_TipGetCallback cb, - void *cb_cls) +struct TALER_MERCHANT_TipWalletGetHandle * +TALER_MERCHANT_wallet_tip_get (struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const struct GNUNET_HashCode *tip_id, + TALER_MERCHANT_TipWalletGetCallback cb, + void *cb_cls) { - struct TALER_MERCHANT_TipGetHandle *tqo; + struct TALER_MERCHANT_TipWalletGetHandle *tgh; CURL *eh; - tqo = GNUNET_new (struct TALER_MERCHANT_TipGetHandle); - tqo->ctx = ctx; - tqo->cb = cb; - tqo->cb_cls = cb_cls; + tgh = GNUNET_new (struct TALER_MERCHANT_TipWalletGetHandle); + tgh->ctx = ctx; + tgh->cb = cb; + tgh->cb_cls = cb_cls; { char res_str[sizeof (*tip_id) * 2]; char arg_str[sizeof (res_str) + 48]; @@ -192,37 +192,37 @@ TALER_MERCHANT_tip_get (struct GNUNET_CURL_Context *ctx, *end = '\0'; GNUNET_snprintf (arg_str, sizeof (arg_str), - "/tips/%s", + "tips/%s", res_str); - tqo->url = TALER_url_join (backend_url, + tgh->url = TALER_url_join (backend_url, arg_str, NULL); } - if (NULL == tqo->url) + if (NULL == tgh->url) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not construct request URL.\n"); - GNUNET_free (tqo); + GNUNET_free (tgh); return NULL; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Requesting URL '%s'\n", - tqo->url); + tgh->url); eh = curl_easy_init (); GNUNET_assert (CURLE_OK == curl_easy_setopt (eh, CURLOPT_URL, - tqo->url)); + tgh->url)); - tqo->job = GNUNET_CURL_job_add (ctx, + tgh->job = GNUNET_CURL_job_add (ctx, eh, GNUNET_YES, - &handle_tip_get_finished, - tqo); - return tqo; + &handle_wallet_tip_get_finished, + tgh); + return tgh; } @@ -233,16 +233,17 @@ TALER_MERCHANT_tip_get (struct GNUNET_CURL_Context *ctx, * @param tqo handle to the operation being cancelled */ void -TALER_MERCHANT_tip_get_cancel (struct TALER_MERCHANT_TipGetHandle *tqo) +TALER_MERCHANT_wallet_tip_get_cancel (struct + TALER_MERCHANT_TipWalletGetHandle *tgh) { - if (NULL != tqo->job) + if (NULL != tgh->job) { - GNUNET_CURL_job_cancel (tqo->job); - tqo->job = NULL; + GNUNET_CURL_job_cancel (tgh->job); + tgh->job = NULL; } - GNUNET_free (tqo->url); - GNUNET_free (tqo); + GNUNET_free (tgh->url); + GNUNET_free (tgh); } -/* end of merchant_api_tip_get.c */ +/* end of merchant_api_wallet_get_tip.c */ diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 6a3aedaa..d8025bf0 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -29,6 +29,7 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_delete_product.c \ testing_api_cmd_delete_reserve.c \ testing_api_cmd_lock_product.c \ + testing_api_cmd_merchant_get_tip.c \ testing_api_cmd_pay_order.c \ testing_api_cmd_post_instances.c \ testing_api_cmd_post_orders.c \ @@ -42,8 +43,8 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_rewind.c \ testing_api_cmd_tip_authorize.c \ testing_api_cmd_tip_pickup.c \ - testing_api_cmd_tip_query.c \ testing_api_cmd_track_transaction.c \ + testing_api_cmd_wallet_get_tip.c \ testing_api_helpers.c \ testing_api_trait_merchant_sig.c \ testing_api_trait_string.c \ diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index fb230f04..ff705a36 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -660,6 +660,14 @@ run (void *cls, MHD_HTTP_OK, "tip 2", "EUR:5.01"), + TALER_TESTING_cmd_wallet_get_tip ("get-tip-1", + merchant_url, + "authorize-tip-1", + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_tip ("merchant-get-tip-1", + merchant_url, + "authorize-tip-1", + MHD_HTTP_OK), TALER_TESTING_cmd_get_tips ("get-tips-1", merchant_url, MHD_HTTP_OK), diff --git a/src/testing/testing_api_cmd_merchant_get_tip.c b/src/testing/testing_api_cmd_merchant_get_tip.c new file mode 100644 index 00000000..f70356c7 --- /dev/null +++ b/src/testing/testing_api_cmd_merchant_get_tip.c @@ -0,0 +1,207 @@ +/* + This file is part of TALER + Copyright (C) 2020 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or + (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/testing_api_cmd_merchant_get_tip.c + * @brief command to test GET /private/tips/$TIP_ID. + * @author Jonathan Buchanan + */ +#include "platform.h" +#include <taler/taler_exchange_service.h> +#include <taler/taler_testing_lib.h> +#include "taler_merchant_service.h" +#include "taler_merchant_testing_lib.h" + +/** + * State for a GET /private/tips/$TIP_ID CMD. + */ +struct MerchantTipGetState +{ + + /** + * The merchant base URL. + */ + const char *merchant_url; + + /** + * Expected HTTP response code for this CMD. + */ + unsigned int http_status; + + /** + * The handle to the current GET /tips/$TIP_ID request. + */ + struct TALER_MERCHANT_TipMerchantGetHandle *tgh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Reference to a command that created a tip. + */ + const char *tip_reference; +}; + + +/** + * Callback for a GET /private/tips/$TIP_ID operation. + * + * @param cls closure for this function + * @param hr http response + * @param total_authorized the total amount authorized for the tip + * @param total_picked_up the total amount of the tip that has been picked up + * @param reason why the tip was authorized + * @param expiration when the tip will expire + * @param reserve_pub public key of the reserve the tip is drawing from + * @param pickups_length number of pickups associated with the tip + * @param pickups the array of pickups associated with the tip + */ +static void +merchant_get_tip_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + const struct TALER_Amount *total_authorized, + const struct TALER_Amount *total_picked_up, + const char *reason, + struct GNUNET_TIME_Absolute expiration, + const struct TALER_ReservePublicKeyP *reserve_pub, + unsigned int pickups_length, + const struct TALER_MERCHANT_PickupDetail pickups[]) +{ + /* FIXME, deeper checks should be implemented here. */ + struct MerchantTipGetState *gts = cls; + + gts->tgh = NULL; + if (gts->http_status != hr->http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + hr->http_status, + (int) hr->ec, + TALER_TESTING_interpreter_get_current_label (gts->is)); + TALER_TESTING_interpreter_fail (gts->is); + return; + } + switch (hr->http_status) + { + case MHD_HTTP_OK: + // FIXME: use gts->tip_reference here to + // check if the data returned matches that from the POST / PATCH + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status.\n"); + } + TALER_TESTING_interpreter_next (gts->is); +} + + +/** + * Run the "GET tip" CMD. + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +merchant_get_tip_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct MerchantTipGetState *tgs = cls; + const struct TALER_TESTING_Command *tip_cmd; + const struct GNUNET_HashCode *tip_id; + + tip_cmd = TALER_TESTING_interpreter_lookup_command (is, + tgs->tip_reference); + + if (GNUNET_OK != + TALER_TESTING_get_trait_tip_id (tip_cmd, + 0, + &tip_id)) + TALER_TESTING_FAIL (is); + + tgs->is = is; + tgs->tgh = TALER_MERCHANT_merchant_tip_get (is->ctx, + tgs->merchant_url, + tip_id, + false, + &merchant_get_tip_cb, + tgs); + GNUNET_assert (NULL != tgs->tgh); +} + + +/** +* Free the state of a "GET tip" CMD, and possibly +* cancel a pending operation thereof. +* +* @param cls closure. +* @param cmd command being run. +*/ +static void +merchant_get_tip_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct MerchantTipGetState *tgs = cls; + + if (NULL != tgs->tgh) + { + TALER_LOG_WARNING ("Get tip operation did not complete\n"); + TALER_MERCHANT_merchant_tip_get_cancel (tgs->tgh); + } + GNUNET_free (tgs); +} + + +/** + * Define a GET /private/tips/$TIP_IDE 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 http_status expected HTTP response code for the request. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_tip (const char *label, + const char *merchant_url, + const char *tip_reference, + unsigned int http_status) +{ + struct MerchantTipGetState *tgs; + + tgs = GNUNET_new (struct MerchantTipGetState); + tgs->merchant_url = merchant_url; + tgs->tip_reference = tip_reference; + 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_tip_authorize.c b/src/testing/testing_api_cmd_tip_authorize.c index ff7f9c0a..e51b70f4 100644 --- a/src/testing/testing_api_cmd_tip_authorize.c +++ b/src/testing/testing_api_cmd_tip_authorize.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA + Copyright (C) 2014-2020 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/src/testing/testing_api_cmd_tip_query.c b/src/testing/testing_api_cmd_tip_query.c deleted file mode 100644 index 27a82a99..00000000 --- a/src/testing/testing_api_cmd_tip_query.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3, or - (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, see - <http://www.gnu.org/licenses/> -*/ - -/** - * @file lib/testing_api_cmd_tip_query.c - * @brief command to test the tipping. - * @author Marcello Stanisci - */ - -#include "platform.h" -#include <taler/taler_exchange_service.h> -#include <taler/taler_testing_lib.h> -#include "taler_merchant_service.h" -#include "taler_merchant_testing_lib.h" - - -/** - * State for a /tip-query CMD. - */ -struct TipQueryState -{ - - /** - * The merchant base URL. - */ - const char *merchant_url; - - /** - * Expected HTTP response code for this CMD. - */ - unsigned int http_status; - - /** - * The handle to the current /tip-query request. - */ - struct TALER_MERCHANT_TipGetHandle *tqo; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Expected amount to be picked up. - */ - const char *expected_amount_picked_up; - - /** - * Expected amount to be tip-authorized. - */ - const char *expected_amount_authorized; - - /** - * Amount that is expected to be still available - * from the tip reserve. - */ - const char *expected_amount_available; -}; - - -/** - * Callback to process a GET /tip-query request, it mainly - * checks that what the backend returned matches the command's - * expectations. - * - * @param cls closure - * @param hr HTTP response - * @param reserve_expiration when the tip reserve will expire - * @param exchange_url from where to pick up the tip - * @param amount_remaining how much is remaining - */ -static void -tip_query_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - struct GNUNET_TIME_Absolute reserve_expiration, - const char *exchange_url, - struct TALER_Amount *amount_remaining) -{ - struct TipQueryState *tqs = cls; - - tqs->tqo = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Tip query callback at command `%s'\n", - TALER_TESTING_interpreter_get_current_label (tqs->is)); -#if FIXME_LATER - if (tqs->expected_amount_available) - { - struct TALER_Amount a; - - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (tqs->expected_amount_available, - &a)); - { - char *str; - - str = TALER_amount_to_string (amount_available); - TALER_LOG_INFO ("expected available %s, actual %s\n", - TALER_amount2s (&a), - str); - GNUNET_free (str); - } - if (0 != - TALER_amount_cmp (amount_available, - &a)) - TALER_TESTING_FAIL (tqs->is); - } - - if (tqs->expected_amount_authorized) - { - struct TALER_Amount a; - char *str; - - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (tqs->expected_amount_authorized, - &a)); - str = TALER_amount_to_string (amount_authorized); - TALER_LOG_INFO ("expected authorized %s, actual %s\n", - TALER_amount2s (&a), - str); - GNUNET_free (str); - if (0 != - TALER_amount_cmp (amount_authorized, - &a)) - TALER_TESTING_FAIL (tqs->is); - } - - if (tqs->expected_amount_picked_up) - { - struct TALER_Amount a; - char *str; - - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (tqs->expected_amount_picked_up, - &a)); - str = TALER_amount_to_string (amount_picked_up); - TALER_LOG_INFO ("expected picked_up %s, actual %s\n", - TALER_amount2s (&a), - str); - GNUNET_free (str); - if (0 != - TALER_amount_cmp (amount_picked_up, - &a)) - TALER_TESTING_FAIL (tqs->is); - } -#endif - if (tqs->http_status != hr->http_status) - TALER_TESTING_FAIL (tqs->is); - TALER_TESTING_interpreter_next (tqs->is); -} - - -/** - * Free the state from a /tip-query CMD, and possibly cancel - * a pending /tip-query request. - * - * @param cls closure. - * @param cmd the /tip-query CMD to free. - */ -static void -tip_query_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct TipQueryState *tqs = cls; - - if (NULL != tqs->tqo) - { - TALER_LOG_WARNING ("Tip-query operation did not complete\n"); - TALER_MERCHANT_tip_get_cancel (tqs->tqo); - } - GNUNET_free (tqs); -} - - -/** - * Run a /tip-query CMD. - * - * @param cls closure. - * @param cmd the current /tip-query CMD. - * @param is the interpreter state. - */ -static void -tip_query_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct TipQueryState *tqs = cls; - struct GNUNET_HashCode tip_id; // FIXME: big bad bug, need to pass this in. Done like this just to quickly fix FTBFS! - - tqs->is = is; - tqs->tqo = TALER_MERCHANT_tip_get (is->ctx, - tqs->merchant_url, - &tip_id, - &tip_query_cb, - tqs); - GNUNET_assert (NULL != tqs->tqo); -} - - -/** - * Define a /tip-query CMD equipped with a expected amount. - * - * @param label the command label - * @param merchant_url base URL of the merchant which will - * server the /tip-query request. - * @param http_status expected HTTP response code for the - * /tip-query request. - * @param expected_amount_picked_up expected amount already - * picked up. - * @param expected_amount_authorized expected amount that was - * authorized in the first place. - * @param expected_amount_available expected amount which is - * still available from the tip reserve - * @return the command - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_query_with_amounts (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *expected_amount_picked_up, - const char *expected_amount_authorized, - const char *expected_amount_available) -{ - struct TipQueryState *tqs; - - tqs = GNUNET_new (struct TipQueryState); - tqs->merchant_url = merchant_url; - tqs->http_status = http_status; - tqs->expected_amount_picked_up = expected_amount_picked_up; - tqs->expected_amount_authorized = expected_amount_authorized; - tqs->expected_amount_available = expected_amount_available; - { - struct TALER_TESTING_Command cmd = { - .cls = tqs, - .label = label, - .run = &tip_query_run, - .cleanup = &tip_query_cleanup - }; - - return cmd; - } -} - - -/** - * Define a /tip-query CMD. - * - * @param label the command label - * @param merchant_url base URL of the merchant which will - * server the /tip-query request. - * @param http_status expected HTTP response code for the - * /tip-query request. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_query (const char *label, - const char *merchant_url, - unsigned int http_status) -{ - struct TipQueryState *tqs; - - tqs = GNUNET_new (struct TipQueryState); - tqs->merchant_url = merchant_url; - tqs->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = tqs, - .label = label, - .run = &tip_query_run, - .cleanup = &tip_query_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_tip_query.c */ diff --git a/src/testing/testing_api_cmd_wallet_get_tip.c b/src/testing/testing_api_cmd_wallet_get_tip.c new file mode 100644 index 00000000..f76c3b69 --- /dev/null +++ b/src/testing/testing_api_cmd_wallet_get_tip.c @@ -0,0 +1,200 @@ +/* + This file is part of TALER + Copyright (C) 2014-2020 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or + (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/testing_api_cmd_wallet_get_tip.c + * @brief command to test the tipping. + * @author Marcello Stanisci + */ +#include "platform.h" +#include <taler/taler_exchange_service.h> +#include <taler/taler_testing_lib.h> +#include "taler_merchant_service.h" +#include "taler_merchant_testing_lib.h" + + +/** + * State for a GET /tips/$TIP_ID CMD. + */ +struct WalletTipGetState +{ + + /** + * The merchant base URL. + */ + const char *merchant_url; + + /** + * Expected HTTP response code for this CMD. + */ + unsigned int http_status; + + /** + * The handle to the current GET /tips/$TIP_ID request. + */ + struct TALER_MERCHANT_TipWalletGetHandle *tgh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Reference to a command that created a tip. + */ + const char *tip_reference; +}; + + +/** + * Callback to process a GET /tips/$TIP_ID request, it mainly + * checks that what the backend returned matches the command's + * expectations. + * + * @param cls closure + * @param hr HTTP response + * @param reserve_expiration when the tip reserve will expire + * @param exchange_url from where to pick up the tip + * @param amount_remaining how much is remaining + */ +static void +wallet_tip_get_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + struct GNUNET_TIME_Absolute reserve_expiration, + const char *exchange_url, + const struct TALER_Amount *amount_remaining) +{ + /* FIXME, deeper checks should be implemented here. */ + struct WalletTipGetState *gts = cls; + + gts->tgh = NULL; + if (gts->http_status != hr->http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + hr->http_status, + (int) hr->ec, + TALER_TESTING_interpreter_get_current_label (gts->is)); + TALER_TESTING_interpreter_fail (gts->is); + return; + } + switch (hr->http_status) + { + case MHD_HTTP_OK: + // FIXME: use gts->tip_reference here to + // check if the data returned matches that from the POST / PATCH + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status.\n"); + } + TALER_TESTING_interpreter_next (gts->is); +} + + +/** + * Run the "GET tip" CMD. + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +wallet_get_tip_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct WalletTipGetState *tgs = cls; + const struct TALER_TESTING_Command *tip_cmd; + const struct GNUNET_HashCode *tip_id; + + tip_cmd = TALER_TESTING_interpreter_lookup_command (is, + tgs->tip_reference); + + if (GNUNET_OK != + TALER_TESTING_get_trait_tip_id (tip_cmd, + 0, + &tip_id)) + TALER_TESTING_FAIL (is); + + tgs->is = is; + tgs->tgh = TALER_MERCHANT_wallet_tip_get (is->ctx, + tgs->merchant_url, + tip_id, + &wallet_tip_get_cb, + tgs); +} + + +/** + * Free the state of a "GET tip" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +wallet_get_tip_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct WalletTipGetState *tgs = cls; + + if (NULL != tgs->tgh) + { + TALER_LOG_WARNING ("Get tip operation did not complete\n"); + TALER_MERCHANT_wallet_tip_get_cancel (tgs->tgh); + } + GNUNET_free (tgs); +} + + +/** + * 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 http_status expected HTTP response code for the request. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_wallet_get_tip (const char *label, + const char *merchant_url, + const char *tip_reference, + unsigned int http_status) +{ + struct WalletTipGetState *tgs; + + tgs = GNUNET_new (struct WalletTipGetState); + tgs->merchant_url = merchant_url; + tgs->tip_reference = tip_reference; + 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 */ |