summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-05-13 19:15:14 +0200
committerChristian Grothoff <christian@grothoff.org>2020-05-13 19:15:14 +0200
commit9bac37cbe6a2774782a515458098883bbf98b4b6 (patch)
treec1be0b61cea40afdee565527fa76fb72cb560c8f /src
parenta48af85c36a3340ee9303b57428f2929b08995e4 (diff)
downloadmerchant-9bac37cbe6a2774782a515458098883bbf98b4b6.tar.gz
merchant-9bac37cbe6a2774782a515458098883bbf98b4b6.tar.bz2
merchant-9bac37cbe6a2774782a515458098883bbf98b4b6.zip
sketch for GET /transfers cmd
Diffstat (limited to 'src')
-rw-r--r--src/include/taler_merchant_service.h3
-rw-r--r--src/include/taler_merchant_testing_lib.h58
-rw-r--r--src/lib/merchant_api_post_transfers.c2
-rw-r--r--src/testing/Makefile.am5
-rw-r--r--src/testing/testing_api_cmd_get_transfers.c232
-rw-r--r--src/testing/testing_api_cmd_post_transfers.c473
-rw-r--r--src/testing/testing_api_cmd_track_transfer.c322
7 files changed, 770 insertions, 325 deletions
diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h
index 850bf150..ce0d22c2 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -2369,6 +2369,9 @@ TALER_MERCHANT_transfers_get_cancel (
struct TALER_MERCHANT_GetTransfersHandle *gth);
+/* ******************* /reserves *************** */
+
+
/* ********************* OLD ************************** */
diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h
index 77c6b57d..87c10a5d 100644
--- a/src/include/taler_merchant_testing_lib.h
+++ b/src/include/taler_merchant_testing_lib.h
@@ -407,6 +407,8 @@ TALER_TESTING_cmd_merchant_delete_product (const char *label,
unsigned int http_status);
+/* ******************* /orders **************** */
+
/**
* Make the "proposal" command.
*
@@ -505,6 +507,62 @@ TALER_TESTING_cmd_merchant_order_refund (const char *label,
unsigned int http_code);
+/* ******************* /transfers *************** */
+
+
+/**
+ * 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,
+ ...);
+
+
+/**
+ * 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,
+ ...);
+
+
+/* ******************* /reserves *************** */
+
+
/* ******************** OLD ******************* */
diff --git a/src/lib/merchant_api_post_transfers.c b/src/lib/merchant_api_post_transfers.c
index 2583dbe7..0dd67ce9 100644
--- a/src/lib/merchant_api_post_transfers.c
+++ b/src/lib/merchant_api_post_transfers.c
@@ -156,7 +156,7 @@ handle_post_transfers_finished (void *cls,
};
if (GNUNET_OK !=
- GNUNET_JSON_parse (json,
+ GNUNET_JSON_parse (deposit_sum,
ispec,
NULL, NULL))
{
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 */