diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-05-13 19:15:14 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-05-13 19:15:14 +0200 |
commit | 9bac37cbe6a2774782a515458098883bbf98b4b6 (patch) | |
tree | c1be0b61cea40afdee565527fa76fb72cb560c8f /src/testing | |
parent | a48af85c36a3340ee9303b57428f2929b08995e4 (diff) | |
download | merchant-9bac37cbe6a2774782a515458098883bbf98b4b6.tar.gz merchant-9bac37cbe6a2774782a515458098883bbf98b4b6.tar.bz2 merchant-9bac37cbe6a2774782a515458098883bbf98b4b6.zip |
sketch for GET /transfers cmd
Diffstat (limited to 'src/testing')
-rw-r--r-- | src/testing/Makefile.am | 5 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_get_transfers.c | 232 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_post_transfers.c | 473 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_track_transfer.c | 322 |
4 files changed, 708 insertions, 324 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 2b3386ef..c0165e9c 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -21,13 +21,15 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_get_instances.c \ testing_api_cmd_get_product.c \ testing_api_cmd_get_products.c \ + testing_api_cmd_get_transfers.c \ testing_api_cmd_delete_instance.c \ testing_api_cmd_delete_product.c \ testing_api_cmd_lock_product.c \ testing_api_cmd_pay_order.c \ testing_api_cmd_post_instances.c \ - testing_api_cmd_post_products.c \ testing_api_cmd_post_orders.c \ + testing_api_cmd_post_products.c \ + testing_api_cmd_post_transfers.c \ testing_api_cmd_patch_instance.c \ testing_api_cmd_patch_product.c \ testing_api_cmd_refund_order.c \ @@ -37,7 +39,6 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_tip_pickup.c \ testing_api_cmd_tip_query.c \ testing_api_cmd_track_transaction.c \ - testing_api_cmd_track_transfer.c \ testing_api_helpers.c \ testing_api_trait_merchant_sig.c \ testing_api_trait_string.c \ diff --git a/src/testing/testing_api_cmd_get_transfers.c b/src/testing/testing_api_cmd_get_transfers.c new file mode 100644 index 00000000..2f8e01d8 --- /dev/null +++ b/src/testing/testing_api_cmd_get_transfers.c @@ -0,0 +1,232 @@ +/* + This file is part of TALER + Copyright (C) 2014-2018, 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_get_transfers.c + * @brief command to test GET /transfers. + * @author Marcello Stanisci + * @author Christian Grothoff + */ +#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 of a "get transfer" CMD. + */ +struct GetTransfersState +{ + + /** + * Handle for a "get transfer" request. + */ + struct TALER_MERCHANT_GetTransfersHandle *gth; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * payto URI of the merchant to filter by. + */ + const char *payto_uri; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + + /** + * Reference for a "check bank" CMD. It offers the + * WTID to get. + */ + const char *check_bank_reference; + + /** + * Array of POST /transfer command labels we expect to see listed. + */ + const char **transfers; + + /** + * Length of @e transfers. + */ + unsigned int transfers_length; + +}; + + +/** + * Check the result of our GET /transfers request to a merchant + * + * @param cls closure + * @param hr HTTP response details + * @param transfers_length length of the @a transfers array + * @param transfers array with details about the transfers we received + */ +static void +get_transfers_cb ( + void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + unsigned int transfers_length, + const struct TALER_MERCHANT_TransferData transfers[]) +{ + struct GetTransfersState *gts = cls; + + gts->gth = 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: check that list of returned transactions matches our expectations! + } + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status.\n"); + } + TALER_TESTING_interpreter_next (gts->is); +} + + +/** + * Run the "get transfer" CMD. + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +get_transfers_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct GetTransfersState *gts = cls; + + gts->is = is; + gts->gth = TALER_MERCHANT_transfers_get (is->ctx, + gts->merchant_url, + gts->payto_uri, + GNUNET_TIME_UNIT_FOREVER_ABS, + GNUNET_TIME_UNIT_ZERO_ABS, + INT64_MAX, + 0, + TALER_MERCHANT_YNA_ALL, + &get_transfers_cb, + gts); + GNUNET_assert (NULL != gts->gth); +} + + +/** + * Free the state of a "get transfer" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +get_transfers_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct GetTransfersState *gts = cls; + + if (NULL != gts->gth) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "GET /transfer operation did not complete\n"); + TALER_MERCHANT_transfers_get_cancel (gts->gth); + } + GNUNET_array_grow (gts->transfers, + gts->transfers_length, + 0); + GNUNET_free (gts); +} + + +/** + * Define a GET /transfers CMD. + * + * @param label command label. + * @param merchant_url base URL of the backend serving the + * "refund increase" request. + * @param payto_uri payto URI to filter by, NULL for no filter + * @param http_code expected HTTP response code + * @param ... NULL-terminated list of labels (const char *) of + * transfer (commands) we expect to be returned in the list + * (assuming @a http_code is #MHD_HTTP_OK) + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_transfers (const char *label, + const char *merchant_url, + const char *payto_uri, + unsigned int http_code, + ...) +{ + struct GetTransfersState *gts; + + gts = GNUNET_new (struct GetTransfersState); + gts->merchant_url = merchant_url; + gts->payto_uri = payto_uri; + gts->http_status = http_code; + { + const char *clabel; + va_list ap; + + va_start (ap, http_code); + while (NULL != (clabel = va_arg (ap, const char *))) + { + GNUNET_array_append (gts->transfers, + gts->transfers_length, + clabel); + } + va_end (ap); + } + { + struct TALER_TESTING_Command cmd = { + .cls = gts, + .label = label, + .run = &get_transfers_run, + .cleanup = &get_transfers_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_get_transfers.c */ diff --git a/src/testing/testing_api_cmd_post_transfers.c b/src/testing/testing_api_cmd_post_transfers.c new file mode 100644 index 00000000..f5087c2d --- /dev/null +++ b/src/testing/testing_api_cmd_post_transfers.c @@ -0,0 +1,473 @@ +/* + 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_post_transfers.c + * @brief command to test POST /transfers + * @author Christian Grothoff + */ +#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 of a "POST /transfers" CMD. + */ +struct PostTransfersState +{ + + /** + * Handle for a "POST /transfers" request. + */ + struct TALER_MERCHANT_PostTransfersHandle *pth; + + /** + * Handle for a "GET" bank account history request. + */ + struct TALER_BANK_DebitHistoryHandle *dhh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * URL of the bank to run history on. + */ + const char *bank_url; + + /** + * URL of the bank to run history on (set once @e found is set). + */ + char *exchange_url; + + /** + * Payto URI to filter on. + */ + const char *payto_uri; + + /** + * Authentication details to authenticate to the bank. + */ + struct TALER_BANK_AuthenticationData auth; + + /** + * Set once we discovered the WTID and thus @e found is true. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * the credit amount to look for at @e bank_url. + */ + struct TALER_Amount credit_amount; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + + /** + * Array of deposit command labels we expect to see aggregated. + */ + const char **deposits; + + /** + * Length of @e deposits. + */ + unsigned int deposits_length; + + /** + * Set to true once @e wtid and @e exchange_url are initialized. + */ + bool found; +}; + + +/** + * Callback for a POST /transfers operation. + * + * @param cls closure for this function + * @param hr HTTP response details + * @param execution_time when did the transfer happen (according to the exchange), + * #GNUNET_TIME_UNIT_FOREVER_ABS if the transfer did not yet happen or if + * we have no data from the exchange about it + * @param total_amount total amount of the wire transfer, or NULL if the exchange did + * not provide any details + * @param wire_fee how much did the exchange charge in terms of wire fees, or NULL + * if the exchange did not provide any details + * @param details_length length of the @a details array + * @param details array with details about the combined transactions + */ +static void +transfers_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + struct GNUNET_TIME_Absolute execution_time, + const struct TALER_Amount *total_amount, + const struct TALER_Amount *wire_fee, + unsigned int details_length, + const struct TALER_MERCHANT_TrackTransferDetail details[]) +{ + struct PostTransfersState *pts = cls; + + pts->pth = NULL; + if (pts->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 (pts->is)); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + switch (hr->http_status) + { + case MHD_HTTP_OK: + { + struct TALER_Amount total; + + if (0 > + TALER_amount_subtract (&total, + total_amount, + wire_fee)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + if (0 != + TALER_amount_cmp (&total, + &pts->credit_amount)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + TALER_amount_get_zero (total.currency, + &total); + for (unsigned int i = 0; i<details_length; i++) + { + const struct TALER_MERCHANT_TrackTransferDetail *tdd = &details[i]; + struct TALER_Amount sum; + struct TALER_Amount fees; + + TALER_amount_get_zero (tdd->deposit_value.currency, + &sum); + TALER_amount_get_zero (tdd->deposit_fee.currency, + &fees); + for (unsigned int j = 0; j<pts->deposits_length; j++) + { + const char *label = pts->deposits[j]; + const struct TALER_TESTING_Command *cmd; + const json_t *contract_terms; + const struct TALER_Amount *deposit_value; + const char *order_id; + + cmd = TALER_TESTING_interpreter_lookup_command (pts->is, + label); + if (NULL == cmd) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + if ( (GNUNET_OK != + TALER_TESTING_get_trait_contract_terms (cmd, + 0, + &contract_terms)) || + (GNUNET_OK != + TALER_TESTING_get_trait_amount_obj (cmd, + 0, + &deposit_value)) ) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + order_id = json_string_value (json_object_get (contract_terms, + "order_id")); + if (NULL == order_id) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + if (0 != strcmp (tdd->order_id, + order_id)) + continue; + if (0 > + TALER_amount_add (&sum, + &sum, + deposit_value)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + // FIXME #6236: also would want to add deposit_fees, but unavailable as traits right now! + } + if (0 != + TALER_amount_cmp (&sum, + &tdd->deposit_value)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } +#if FIXME6236 + if (0 != + TALER_amount_cmp (&fees, + tdd->deposit_fee)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } + GNUNET_assert (0 <= + TALER_amount_add (&total, + &total, + &tdd->deposit_value)); + GNUNET_assert (0 <= + TALER_amount_subtract (&total, + &total, + &tdd->deposit_fee)); +#endif + } +#if FIXME6236 + if (0 != + TALER_amount_cmp (&total, + pts->credit_amount)) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } +#endif + break; + } + default: + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status.\n"); + } + TALER_TESTING_interpreter_next (pts->is); +} + + +/** + * Callbacks of this type are used to serve the result of asking + * the bank for the debit transaction history. + * + * @param cls closure with a `struct PostTransfersState *` + * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request + * 0 if the bank's reply is bogus (fails to follow the protocol), + * #MHD_HTTP_NO_CONTENT if there are no more results; on success the + * last callback is always of this status (even if `abs(num_results)` were + * already returned). + * @param ec detailed error code + * @param serial_id monotonically increasing counter corresponding to the transaction + * @param details details about the wire transfer + * @param json detailed response from the HTTPD, or NULL if reply was not in JSON + * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration + */ +static int +debit_cb ( + void *cls, + unsigned int http_status, + enum TALER_ErrorCode ec, + uint64_t serial_id, + const struct TALER_BANK_DebitDetails *details, + const json_t *json) +{ + struct PostTransfersState *pts = cls; + + if (MHD_HTTP_NO_CONTENT == http_status) + { + pts->dhh = NULL; + if (! pts->found) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return GNUNET_OK; + } + GNUNET_assert (NULL != pts->exchange_url); + pts->pth = TALER_MERCHANT_transfers_post (pts->is->ctx, + pts->merchant_url, + &pts->credit_amount, + &pts->wtid, + pts->payto_uri, + pts->exchange_url, + &transfers_cb, + pts); + return GNUNET_OK; + } + if (MHD_HTTP_OK != http_status) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + pts->dhh = NULL; + return GNUNET_SYSERR; + } + if (pts->found) + return GNUNET_OK; + if (0 != TALER_amount_cmp (&pts->credit_amount, + &details->amount)) + return GNUNET_OK; + if ( (NULL != pts->payto_uri) && + (0 != strcasecmp (pts->payto_uri, + details->credit_account_url)) ) + return GNUNET_OK; + pts->found = true; + pts->wtid = details->wtid; + pts->exchange_url = GNUNET_strdup (details->exchange_base_url); + return GNUNET_OK; +} + + +/** + * Run the "POST /transfers" CMD. First, get the bank history to find + * the wtid. + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +post_transfers_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PostTransfersState *pts = cls; + + pts->is = is; + pts->dhh = TALER_BANK_debit_history (is->ctx, + NULL, + UINT64_MAX, + -INT64_MAX, + &debit_cb, + pts); + GNUNET_assert (NULL != pts->dhh); +} + + +/** + * Free the state of a "POST product" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +post_transfers_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PostTransfersState *pts = cls; + + if (NULL != pts->pth) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "POST /transfers operation did not complete\n"); + TALER_MERCHANT_transfers_post_cancel (pts->pth); + } + if (NULL != pts->dhh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "GET debit history operation did not complete\n"); + TALER_BANK_debit_history_cancel (pts->dhh); + } + GNUNET_array_grow (pts->deposits, + pts->deposits_length, + 0); + GNUNET_free_non_null (pts->exchange_url); + GNUNET_free (pts); +} + + +/** + * Define a POST /transfers CMD. Details like the WTID and + * other required parameters will be extracted from the bank + * history, using the latest transfer of the specified + * @a credit_amount to the @a merchant_url. + * + * @param label command label. + * @param merchant_url base URL of the backend serving the + * "refund increase" request. + * @param auth credentials to access the exchange's bank account + * @param bank_url URL of the exchange's bank account + * @param credit_amount amount credited + * @param http_code expected HTTP response code + * @param ... NULL-terminated list of labels (const char *) of + * deposit (commands) we expect to be aggregated in the transfer + * (assuming @a http_code is #MHD_HTTP_OK) + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_transfer ( + const char *label, + const struct TALER_BANK_AuthenticationData *auth, + const char *bank_url, + const char *merchant_url, + const char *credit_amount, + unsigned int http_code, + ...) +{ + struct PostTransfersState *pts; + + pts = GNUNET_new (struct PostTransfersState); + pts->bank_url = bank_url; + pts->merchant_url = merchant_url; + pts->auth = *auth; + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (credit_amount, + &pts->credit_amount)); + pts->http_status = http_code; + { + const char *clabel; + va_list ap; + + va_start (ap, http_code); + while (NULL != (clabel = va_arg (ap, const char *))) + { + GNUNET_array_append (pts->deposits, + pts->deposits_length, + clabel); + } + va_end (ap); + } + { + struct TALER_TESTING_Command cmd = { + .cls = pts, + .label = label, + .run = &post_transfers_run, + .cleanup = &post_transfers_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_post_transfers.c */ diff --git a/src/testing/testing_api_cmd_track_transfer.c b/src/testing/testing_api_cmd_track_transfer.c deleted file mode 100644 index b0dfc478..00000000 --- a/src/testing/testing_api_cmd_track_transfer.c +++ /dev/null @@ -1,322 +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_track_transfer.c - * @brief command to test /track/transfer. - * @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 of a "track transfer" CMD. - */ -struct TrackTransferState -{ - - /** - * Handle for a "track transfer" request. - */ - struct TALER_MERCHANT_TrackTransferHandle *tth; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Reference for a "check bank" CMD. It offers the - * WTID to track. - */ - const char *check_bank_reference; - -}; - - -/** - * Callback for a /track/transfer operation, only checks if - * response code is the expected one. - * - * @param cls closure for this function - * @param http_status HTTP response code returned by the server - * @param ec taler-specific error code - * @param sign_key exchange key used to sign @a json, or NULL - * @param json original json reply (may include signatures, - * those have then been validated already) - * @param h_wire hash of the wire transfer address the transfer - * went to, or NULL on error - * @param total_amount total amount of the wire transfer, or NULL - * if the exchange could not provide any @a wtid (set only - * if @a http_status is #MHD_HTTP_OK) - * @param details_length length of the @a details array - * @param details array with details about the combined - * transactions - */ -static void -track_transfer_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, - const struct GNUNET_HashCode *h_wire, - const struct TALER_Amount *total_amount, - unsigned int details_length, - const struct TALER_MERCHANT_TrackTransferDetails *details) -{ - /* FIXME, deeper checks should be implemented here. */ - struct TrackTransferState *tts = cls; - - tts->tth = NULL; - if (tts->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 (tts->is)); - TALER_TESTING_interpreter_fail (tts->is); - return; - } - switch (hr->http_status) - { - /** - * Check that all the deposits sum up to the total - * transferred amount. */ - case MHD_HTTP_OK: - { - json_t *deposits; - const char *amount_str; - struct TALER_Amount total; - struct TALER_Amount wire_fee; - struct TALER_Amount amount_iter; - struct TALER_Amount deposit_fee_iter; - struct TALER_Amount sum; - size_t index; - json_t *value; - - amount_str = json_string_value (json_object_get (hr->reply, - "total")); - if (GNUNET_OK != - TALER_string_to_amount (amount_str, - &total)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s'\n", - amount_str); - TALER_TESTING_FAIL (tts->is); - return; - } - amount_str = json_string_value (json_object_get (hr->reply, - "wire_fee")); - if (GNUNET_OK != - TALER_string_to_amount (amount_str, - &wire_fee)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s'\n", - amount_str); - TALER_TESTING_FAIL (tts->is); - return; - } - GNUNET_assert (GNUNET_OK == - TALER_amount_get_zero (total.currency, - &sum)); - deposits = json_object_get (hr->reply, - "deposits_sums"); - json_array_foreach (deposits, index, value) - { - amount_str = json_string_value (json_object_get (value, - "deposit_value")); - if (GNUNET_OK != - TALER_string_to_amount (amount_str, - &amount_iter)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s'\n", - amount_str); - TALER_TESTING_FAIL (tts->is); - return; - } - amount_str = json_string_value (json_object_get (value, - "deposit_fee")); - if (GNUNET_OK != - TALER_string_to_amount (amount_str, - &deposit_fee_iter)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse amount `%s'\n", - amount_str); - TALER_TESTING_FAIL (tts->is); - return; - } - GNUNET_assert (0 <= - TALER_amount_add (&sum, - &sum, - &amount_iter)); - GNUNET_assert (0 <= - TALER_amount_subtract (&sum, - &sum, - &deposit_fee_iter)); - } - - GNUNET_assert (0 <= - TALER_amount_subtract (&sum, - &sum, - &wire_fee)); - if (0 != TALER_amount_cmp (&sum, - &total)) - { - GNUNET_break (0); - TALER_LOG_ERROR ( - "Inconsistent amount transferred: Sum %s, claimed %s\n", - TALER_amount_to_string (&sum), - TALER_amount_to_string (&total)); - TALER_TESTING_interpreter_fail (tts->is); - } - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (tts->is); -} - - -/** - * Run the "track transfer" CMD. - * - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -track_transfer_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct TrackTransferState *tts = cls; - const struct TALER_WireTransferIdentifierRawP *wtid; - const struct TALER_TESTING_Command *check_bank_cmd; - const char *exchange_url; - - tts->is = is; - check_bank_cmd - = TALER_TESTING_interpreter_lookup_command (is, - tts->check_bank_reference); - if (NULL == check_bank_cmd) - TALER_TESTING_FAIL (is); - if (GNUNET_OK != - TALER_TESTING_get_trait_wtid (check_bank_cmd, - 0, - &wtid)) - TALER_TESTING_FAIL (is); - if (GNUNET_OK != - TALER_TESTING_get_trait_url (check_bank_cmd, - TALER_TESTING_UT_EXCHANGE_BASE_URL, - &exchange_url)) - TALER_TESTING_FAIL (is); - tts->tth = TALER_MERCHANT_track_transfer (is->ctx, - tts->merchant_url, - "x-taler-bank", - wtid, - exchange_url, - &track_transfer_cb, - tts); - GNUNET_assert (NULL != tts->tth); -} - - -/** - * Free the state of a "track transfer" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -track_transfer_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct TrackTransferState *tts = cls; - - if (NULL != tts->tth) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "/track/transfer (test) operation" - " did not complete\n"); - TALER_MERCHANT_track_transfer_cancel (tts->tth); - } - GNUNET_free (tts); -} - - -/** - * Define a "track transfer" CMD. - * - * @param label command label. - * @param merchant_url base URL of the merchant serving the - * /track/transfer request. - * @param http_status expected HTTP response code. - * @param check_bank_reference reference to a "check bank" CMD - * that will provide the WTID and exchange URL to issue - * the track against. - * @return the command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_track_transfer (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *check_bank_reference) -{ - struct TrackTransferState *tts; - - tts = GNUNET_new (struct TrackTransferState); - tts->merchant_url = merchant_url; - tts->http_status = http_status; - tts->check_bank_reference = check_bank_reference; - { - struct TALER_TESTING_Command cmd = { - .cls = tts, - .label = label, - .run = &track_transfer_run, - .cleanup = &track_transfer_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_track_transfer.c */ |