commit f6633b5cb3567046f73d6cf4de0ab5b2eb4d217b
parent 5acd586004bd7281e6dcf14217e3fee316716804
Author: Christian Grothoff <christian@grothoff.org>
Date: Sat, 2 Nov 2019 23:09:52 +0100
simplify structure
Diffstat:
7 files changed, 1512 insertions(+), 1846 deletions(-)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
@@ -42,14 +42,17 @@ libtalermerchant_la_LIBADD = \
$(XLIB)
libtalermerchanttesting_la_SOURCES = \
- testing_api_cmd_proposal.c \
+ testing_api_cmd_history.c \
testing_api_cmd_pay.c \
- testing_api_cmd_refund.c \
- testing_api_cmd_tip.c \
+ testing_api_cmd_proposal.c \
+ testing_api_cmd_refund_increase.c \
+ testing_api_cmd_refund_lookup.c \
+ 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_track_transfer.c \
- testing_api_cmd_history.c \
- testing_api_cmd_rewind.c \
testing_api_helpers.c \
testing_api_trait_merchant_sig.c \
testing_api_trait_string.c \
diff --git a/src/lib/testing_api_cmd_refund.c b/src/lib/testing_api_cmd_refund.c
@@ -1,636 +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_refund.c
- * @brief command to test refunds.
- * @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 "refund increase" CMD.
- */
-struct RefundIncreaseState
-{
- /**
- * Operation handle for a POST /refund request.
- */
- struct TALER_MERCHANT_RefundIncreaseOperation *rio;
-
- /**
- * Base URL of the merchant serving the request.
- */
- const char *merchant_url;
-
- /**
- * Order id of the contract to refund.
- */
- const char *order_id;
-
- /**
- * The amount to refund.
- */
- const char *refund_amount;
-
- /**
- * Refund fee.
- */
- const char *refund_fee;
-
- /**
- * Human-readable justification for the refund.
- */
- const char *reason;
-
- /**
- * Interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * Expected HTTP response code.
- */
- unsigned int http_code;
-};
-
-
-/**
- * State for a "refund lookup" CMD.
- */
-struct RefundLookupState
-{
- /**
- * Operation handle for a GET /public/refund request.
- */
- struct TALER_MERCHANT_RefundLookupOperation *rlo;
-
- /**
- * Base URL of the merchant serving the request.
- */
- const char *merchant_url;
-
- /**
- * Order id to look up.
- */
- const char *order_id;
-
- /**
- * Reference to a "pay" CMD, used to double-check if
- * refunded coins were actually spent:
- */
- const char *pay_reference;
-
- /**
- * Reference to a "refund increase" CMD that offer
- * the expected amount to be refunded; can be NULL.
- */
- const char *increase_reference;
-
- /**
- * Expected HTTP response code.
- */
- unsigned int http_code;
-
- /**
- * Interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * Explicit amount to be refunded, must be defined if @a
- * increase_reference is NULL.
- */
- const char *refund_amount;
-};
-
-
-/**
- * Free the state of a "refund increase" CMD, and
- * possibly cancel a pending "refund increase" operation.
- *
- * @param cls closure
- * @param cmd command currently being freed.
- */
-static void
-refund_increase_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct RefundIncreaseState *ris = cls;
-
- if (NULL != ris->rio)
- {
- TALER_LOG_WARNING ("Refund-increase operation"
- " did not complete\n");
- TALER_MERCHANT_refund_increase_cancel (ris->rio);
- }
- GNUNET_free (ris);
-}
-
-
-/**
- * Free the state of a "refund lookup" CMD, and
- * possibly cancel a pending "refund lookup" operation.
- *
- * @param cls closure
- * @param cmd command currently being freed.
- */
-static void
-refund_lookup_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct RefundLookupState *rls = cls;
-
- if (NULL != rls->rlo)
- {
- TALER_LOG_WARNING ("Refund-lookup operation"
- " did not complete\n");
- TALER_MERCHANT_refund_lookup_cancel (rls->rlo);
- }
- GNUNET_free (rls);
-}
-
-
-/**
- * Process POST /refund (increase) response; just checking
- * if the HTTP response code is the one expected.
- *
- * @param cls closure
- * @param http_status HTTP status code
- * @param ec taler-specific error object
- * @param obj response body; is NULL on success.
- */
-static void
-refund_increase_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const json_t *obj)
-{
- struct RefundIncreaseState *ris = cls;
-
- ris->rio = NULL;
- if (ris->http_code != http_status)
- TALER_TESTING_FAIL (ris->is);
-
- TALER_TESTING_interpreter_next (ris->is);
-}
-
-
-/**
- * Run the "refund increase" CMD.
- *
- * @param cls closure.
- * @param cmd command currently being run.
- * @param is the interpreter state.
- */
-static void
-refund_increase_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct RefundIncreaseState *ris = cls;
- struct TALER_Amount refund_amount;
-
- ris->is = is;
- if (GNUNET_OK != TALER_string_to_amount (ris->refund_amount,
- &refund_amount))
- TALER_TESTING_FAIL (is);
- ris->rio = TALER_MERCHANT_refund_increase (is->ctx,
- ris->merchant_url,
- ris->order_id,
- &refund_amount,
- ris->reason,
- &refund_increase_cb,
- ris);
- GNUNET_assert (NULL != ris->rio);
-}
-
-
-/**
- * Callback that frees all the elements in the hashmap
- *
- * @param cls closure, NULL
- * @param key current key
- * @param value a `struct TALER_Amount`
- *
- * @return always #GNUNET_YES (continue to iterate)
- */
-static int
-hashmap_free (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct TALER_Amount *refund_amount = value;
-
- GNUNET_free (refund_amount);
- return GNUNET_YES;
-}
-
-
-/**
- * Process "GET /public/refund" (lookup) response;
- * mainly checking if the refunded amount matches the
- * expectation.
- *
- * @param cls closure
- * @param http_status HTTP status code
- * @param ec taler-specific error object
- * @param obj response body; is NULL on error.
- */
-static void
-refund_lookup_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const json_t *obj)
-{
- struct RefundLookupState *rls = cls;
- struct GNUNET_CONTAINER_MultiHashMap *map;
- size_t index;
- json_t *elem;
- const char *error_name;
- unsigned int error_line;
- struct GNUNET_HashCode h_coin_pub;
- const char *coin_reference;
- char *coin_reference_dup;
- const char *icoin_reference;
- const struct TALER_TESTING_Command *pay_cmd;
- const struct TALER_TESTING_Command *increase_cmd;
- const char *refund_amount;
- struct TALER_Amount acc;
- struct TALER_Amount ra;
- const json_t *arr;
-
- rls->rlo = NULL;
- if (rls->http_code != http_status)
- TALER_TESTING_FAIL (rls->is);
-
- arr = json_object_get (obj, "refund_permissions");
- if (NULL == arr)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Tolerating a refund permission not found\n");
- TALER_TESTING_interpreter_next (rls->is);
- return;
- }
- map = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
-
- /* Put in array every refunded coin. */
- json_array_foreach (arr, index, elem)
- {
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_Amount *irefund_amount = GNUNET_new
- (struct TALER_Amount);
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
- TALER_JSON_spec_amount ("refund_amount", irefund_amount),
- GNUNET_JSON_spec_end ()
- };
-
- GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (elem,
- spec,
- &error_name,
- &error_line));
- GNUNET_CRYPTO_hash (&coin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- &h_coin_pub);
- GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put
- (map,
- &h_coin_pub, // which
- irefund_amount, // how much
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- };
-
- /* Compare spent coins with refunded, and if they match,
- * increase an accumulator. */
- if (NULL ==
- (pay_cmd = TALER_TESTING_interpreter_lookup_command
- (rls->is, rls->pay_reference)))
- TALER_TESTING_FAIL (rls->is);
-
- if (GNUNET_OK != TALER_TESTING_get_trait_coin_reference
- (pay_cmd, 0, &coin_reference))
- TALER_TESTING_FAIL (rls->is);
-
- GNUNET_assert (GNUNET_OK == TALER_amount_get_zero ("EUR",
- &acc));
- coin_reference_dup = GNUNET_strdup (coin_reference);
- for (icoin_reference = strtok (coin_reference_dup, ";");
- NULL != icoin_reference;
- icoin_reference = strtok (NULL, ";"))
- {
- const struct TALER_CoinSpendPrivateKeyP *icoin_priv;
- struct TALER_CoinSpendPublicKeyP icoin_pub;
- struct GNUNET_HashCode h_icoin_pub;
- struct TALER_Amount *iamount;
- const struct TALER_TESTING_Command *icoin_cmd;
-
- if (NULL ==
- (icoin_cmd = TALER_TESTING_interpreter_lookup_command
- (rls->is, icoin_reference)) )
- {
- GNUNET_break (0);
- TALER_LOG_ERROR ("Bad reference `%s'\n",
- icoin_reference);
- TALER_TESTING_interpreter_fail (rls->is);
- GNUNET_CONTAINER_multihashmap_destroy (map);
- return;
- }
-
- if (GNUNET_OK != TALER_TESTING_get_trait_coin_priv
- (icoin_cmd, 0, &icoin_priv))
- {
- GNUNET_break (0);
- TALER_LOG_ERROR ("Command `%s' failed to give coin"
- " priv trait\n",
- icoin_reference);
- TALER_TESTING_interpreter_fail (rls->is);
- GNUNET_CONTAINER_multihashmap_destroy (map);
- return;
- }
-
- GNUNET_CRYPTO_eddsa_key_get_public (&icoin_priv->eddsa_priv,
- &icoin_pub.eddsa_pub);
- GNUNET_CRYPTO_hash (&icoin_pub,
- sizeof (struct TALER_CoinSpendPublicKeyP),
- &h_icoin_pub);
-
- iamount = GNUNET_CONTAINER_multihashmap_get
- (map, &h_icoin_pub);
-
- /* Can be NULL: not all coins are involved in refund */
- if (NULL == iamount)
- continue;
-
- GNUNET_assert (GNUNET_OK == TALER_amount_add (&acc,
- &acc,
- iamount));
- }
-
- GNUNET_free (coin_reference_dup);
-
- if (NULL !=
- (increase_cmd = TALER_TESTING_interpreter_lookup_command
- (rls->is, rls->increase_reference)))
- {
- if (GNUNET_OK != TALER_TESTING_get_trait_amount
- (increase_cmd, 0, &refund_amount))
- TALER_TESTING_FAIL (rls->is);
-
- if (GNUNET_OK != TALER_string_to_amount
- (refund_amount, &ra))
- TALER_TESTING_FAIL (rls->is);
- }
- else
- {
- GNUNET_assert (NULL != rls->refund_amount);
-
- if (GNUNET_OK != TALER_string_to_amount
- (rls->refund_amount, &ra))
- TALER_TESTING_FAIL (rls->is);
- }
-
- GNUNET_CONTAINER_multihashmap_iterate (map,
- &hashmap_free,
- NULL);
- GNUNET_CONTAINER_multihashmap_destroy (map);
-
- /* Check that what the backend claims to have been refunded
- * actually matches _our_ refund expectation. */
- if (0 != TALER_amount_cmp (&acc,
- &ra))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Incomplete refund: expected '%s', got '%s'\n",
- TALER_amount_to_string (&ra),
- TALER_amount_to_string (&acc));
- TALER_TESTING_interpreter_fail (rls->is);
- return;
- }
-
- TALER_TESTING_interpreter_next (rls->is);
-}
-
-
-/**
- * Run the "refund lookup" CMD.
- *
- * @param cls closure.
- * @param cmd command being currently run.
- * @param is interpreter state.
- */
-static void
-refund_lookup_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct RefundLookupState *rls = cls;
-
- rls->is = is;
- rls->rlo = TALER_MERCHANT_refund_lookup (is->ctx,
- rls->merchant_url,
- rls->order_id,
- &refund_lookup_cb,
- rls);
- GNUNET_assert (NULL != rls->rlo);
-}
-
-
-/**
- * Offer internal data from the "refund increase" CMD
- * state to other commands.
- *
- * @param cls closure
- * @param ret[out] result (could be anything)
- * @param trait name of the trait
- * @param index index number of the object to extract.
- * @return #GNUNET_OK on success
- */
-static int
-refund_increase_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- struct RefundIncreaseState *ris = cls;
-
- struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_amount (0, ris->refund_amount),
- TALER_TESTING_trait_end ()
- };
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
-
- return GNUNET_SYSERR;
-}
-
-
-/**
- * Define a "refund increase" CMD.
- *
- * @param label command label.
- * @param merchant_url base URL of the backend serving the
- * "refund increase" request.
- * @param reason refund justification, human-readable.
- * @param order_id order id of the contract to refund.
- * @param refund_amount amount to be refund-increased.
- * @param refund_fee refund fee.
- * @param http_code expected HTTP response code.
- *
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_refund_increase
- (const char *label,
- const char *merchant_url,
- const char *reason,
- const char *order_id,
- const char *refund_amount,
- const char *refund_fee,
- unsigned int http_code)
-{
- struct RefundIncreaseState *ris;
-
- ris = GNUNET_new (struct RefundIncreaseState);
- ris->merchant_url = merchant_url;
- ris->order_id = order_id;
- ris->refund_amount = refund_amount;
- ris->refund_fee = refund_fee;
- ris->reason = reason;
- ris->http_code = http_code;
-
- struct TALER_TESTING_Command cmd = {
- .cls = ris,
- .label = label,
- .run = &refund_increase_run,
- .cleanup = &refund_increase_cleanup,
- .traits = &refund_increase_traits
- };
-
- return cmd;
-}
-
-
-/**
- * Define a "refund lookup" CMD.
- *
- * @param label command label.
- * @param merchant_url base URL of the merchant serving the
- * "refund lookup" request.
- * @param increase_reference reference to a "refund increase" CMD
- * that will offer the amount to check the looked up refund
- * against. Must NOT be NULL.
- * @param pay_reference reference to the "pay" CMD whose coins got
- * refunded. It is used to double-check if the refunded
- * coins were actually spent in the first place.
- * @param order_id order id whose refund status is to be looked up.
- * @param http_code expected HTTP response code.
- *
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_refund_lookup
- (const char *label,
- const char *merchant_url,
- const char *increase_reference,
- const char *pay_reference,
- const char *order_id,
- unsigned int http_code)
-{
- struct RefundLookupState *rls;
-
- rls = GNUNET_new (struct RefundLookupState);
- rls->merchant_url = merchant_url;
- rls->order_id = order_id;
- rls->pay_reference = pay_reference;
- rls->increase_reference = increase_reference;
- rls->http_code = http_code;
-
- struct TALER_TESTING_Command cmd = {
- .cls = rls,
- .label = label,
- .run = &refund_lookup_run,
- .cleanup = &refund_lookup_cleanup
- };
-
- return cmd;
-}
-
-
-/**
- * Define a "refund lookup" CMD, equipped with a expected refund
- * amount.
- *
- * @param label command label.
- * @param merchant_url base URL of the merchant serving the
- * "refund lookup" request.
- * @param increase_reference reference to a "refund increase" CMD
- * that will offer the amount to check the looked up refund
- * against. Can be NULL, takes precedence over @a
- * refund_amount.
- * @param pay_reference reference to the "pay" CMD whose coins got
- * refunded. It is used to double-check if the refunded
- * coins were actually spent in the first place.
- * @param order_id order id whose refund status is to be looked up.
- * @param http_code expected HTTP response code.
- * @param refund_amount expected refund amount. Must be defined
- * if @a increase_reference is NULL.
- *
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_refund_lookup_with_amount
- (const char *label,
- const char *merchant_url,
- const char *increase_reference,
- const char *pay_reference,
- const char *order_id,
- unsigned int http_code,
- const char *refund_amount)
-{
- struct RefundLookupState *rls;
-
- rls = GNUNET_new (struct RefundLookupState);
- rls->merchant_url = merchant_url;
- rls->order_id = order_id;
- rls->pay_reference = pay_reference;
- rls->increase_reference = increase_reference;
- rls->http_code = http_code;
- rls->refund_amount = refund_amount;
-
- struct TALER_TESTING_Command cmd = {
- .cls = rls,
- .label = label,
- .run = &refund_lookup_run,
- .cleanup = &refund_lookup_cleanup
- };
-
- return cmd;
-}
-
-
-/* end of testing_api_cmd_refund.c */
diff --git a/src/lib/testing_api_cmd_refund_increase.c b/src/lib/testing_api_cmd_refund_increase.c
@@ -0,0 +1,234 @@
+/*
+ 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_refund_increase.c
+ * @brief command to test refunds.
+ * @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 "refund increase" CMD.
+ */
+struct RefundIncreaseState
+{
+ /**
+ * Operation handle for a POST /refund request.
+ */
+ struct TALER_MERCHANT_RefundIncreaseOperation *rio;
+
+ /**
+ * Base URL of the merchant serving the request.
+ */
+ const char *merchant_url;
+
+ /**
+ * Order id of the contract to refund.
+ */
+ const char *order_id;
+
+ /**
+ * The amount to refund.
+ */
+ const char *refund_amount;
+
+ /**
+ * Refund fee.
+ */
+ const char *refund_fee;
+
+ /**
+ * Human-readable justification for the refund.
+ */
+ const char *reason;
+
+ /**
+ * Interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Expected HTTP response code.
+ */
+ unsigned int http_code;
+};
+
+
+/**
+ * Free the state of a "refund increase" CMD, and
+ * possibly cancel a pending "refund increase" operation.
+ *
+ * @param cls closure
+ * @param cmd command currently being freed.
+ */
+static void
+refund_increase_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct RefundIncreaseState *ris = cls;
+
+ if (NULL != ris->rio)
+ {
+ TALER_LOG_WARNING ("Refund-increase operation"
+ " did not complete\n");
+ TALER_MERCHANT_refund_increase_cancel (ris->rio);
+ }
+ GNUNET_free (ris);
+}
+
+
+/**
+ * Process POST /refund (increase) response; just checking
+ * if the HTTP response code is the one expected.
+ *
+ * @param cls closure
+ * @param http_status HTTP status code
+ * @param ec taler-specific error object
+ * @param obj response body; is NULL on success.
+ */
+static void
+refund_increase_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *obj)
+{
+ struct RefundIncreaseState *ris = cls;
+
+ ris->rio = NULL;
+ if (ris->http_code != http_status)
+ TALER_TESTING_FAIL (ris->is);
+
+ TALER_TESTING_interpreter_next (ris->is);
+}
+
+
+/**
+ * Run the "refund increase" CMD.
+ *
+ * @param cls closure.
+ * @param cmd command currently being run.
+ * @param is the interpreter state.
+ */
+static void
+refund_increase_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct RefundIncreaseState *ris = cls;
+ struct TALER_Amount refund_amount;
+
+ ris->is = is;
+ if (GNUNET_OK != TALER_string_to_amount (ris->refund_amount,
+ &refund_amount))
+ TALER_TESTING_FAIL (is);
+ ris->rio = TALER_MERCHANT_refund_increase (is->ctx,
+ ris->merchant_url,
+ ris->order_id,
+ &refund_amount,
+ ris->reason,
+ &refund_increase_cb,
+ ris);
+ GNUNET_assert (NULL != ris->rio);
+}
+
+
+/**
+ * Offer internal data from the "refund increase" CMD
+ * state to other commands.
+ *
+ * @param cls closure
+ * @param ret[out] result (could be anything)
+ * @param trait name of the trait
+ * @param index index number of the object to extract.
+ * @return #GNUNET_OK on success
+ */
+static int
+refund_increase_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ struct RefundIncreaseState *ris = cls;
+ struct TALER_TESTING_Trait traits[] = {
+ TALER_TESTING_make_trait_amount (0, ris->refund_amount),
+ TALER_TESTING_trait_end ()
+ };
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+}
+
+
+/**
+ * Define a "refund increase" CMD.
+ *
+ * @param label command label.
+ * @param merchant_url base URL of the backend serving the
+ * "refund increase" request.
+ * @param reason refund justification, human-readable.
+ * @param order_id order id of the contract to refund.
+ * @param refund_amount amount to be refund-increased.
+ * @param refund_fee refund fee.
+ * @param http_code expected HTTP response code.
+ *
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_refund_increase
+ (const char *label,
+ const char *merchant_url,
+ const char *reason,
+ const char *order_id,
+ const char *refund_amount,
+ const char *refund_fee,
+ unsigned int http_code)
+{
+ struct RefundIncreaseState *ris;
+
+ ris = GNUNET_new (struct RefundIncreaseState);
+ ris->merchant_url = merchant_url;
+ ris->order_id = order_id;
+ ris->refund_amount = refund_amount;
+ ris->refund_fee = refund_fee;
+ ris->reason = reason;
+ ris->http_code = http_code;
+ {
+ struct TALER_TESTING_Command cmd = {
+ .cls = ris,
+ .label = label,
+ .run = &refund_increase_run,
+ .cleanup = &refund_increase_cleanup,
+ .traits = &refund_increase_traits
+ };
+
+ return cmd;
+ }
+}
+
+
+/* end of testing_api_cmd_refund_increase.c */
diff --git a/src/lib/testing_api_cmd_tip.c b/src/lib/testing_api_cmd_tip.c
@@ -1,1205 +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.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-pickup CMD.
- */
-struct TipPickupState
-{
- /**
- * Merchant base URL.
- */
- const char *merchant_url;
-
- /**
- * Exchange base URL.
- */
- const char *exchange_url;
-
- /**
- * Expected HTTP response code.
- */
- unsigned int http_status;
-
- /**
- * Reference to a /tip/authorize CMD. This will be used to
- * get the tip id to make the request with.
- */
- const char *authorize_reference;
-
- /**
- * If set to non NULL, it references another pickup CMD
- * that will provide all the data which is needed to issue
- * the request (like planchet secrets, denomination keys..).
- */
- const char *replay_reference;
-
- /**
- * Handle to a on-going /tip/pickup request.
- */
- struct TALER_MERCHANT_TipPickupOperation *tpo;
-
- /**
- * The interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * An array of string-defined amounts that indicates
- * which denominations are going to be used to receive
- * tips.
- */
- const char **amounts;
-
- /**
- * The object version of the above @a amounts.
- */
- struct TALER_Amount *amounts_obj;
-
- /**
- * How many coins are involved in the tipping operation.
- */
- unsigned int num_coins;
-
- /**
- * The array of denomination keys, in the same order of @a
- * amounts.
- */
- const struct TALER_EXCHANGE_DenomPublicKey **dks;
-
-
- /**
- * The array of planchet secrets, in the same order of @a
- * amounts.
- */
- struct TALER_PlanchetSecretsP *psa;
-
- /**
- * Temporary data structure of @e num_coins entries for the
- * withdraw operations.
- */
- struct WithdrawHandle *withdraws;
-
- /**
- * Set (by the interpreter) to an array of @a num_coins
- * signatures created from the (successful) tip operation.
- */
- struct TALER_DenominationSignature *sigs;
-
- /**
- * Expected Taler error code (NOTE: this is NOT the HTTP
- * response code).
- */
- enum TALER_ErrorCode expected_ec;
-};
-
-
-/**
- * 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_TipQueryOperation *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;
-};
-
-
-/**
- * State for a /tip-authorize CMD.
- */
-struct TipAuthorizeState
-{
-
- /**
- * Merchant base URL.
- */
- const char *merchant_url;
-
- /**
- * Expected HTTP response code.
- */
- unsigned int http_status;
-
- /**
- * Human-readable justification for the
- * tip authorization carried on by this CMD.
- */
- const char *justification;
-
- /**
- * Amount that should be authorized for tipping.
- */
- const char *amount;
-
- /**
- * Expected Taler error code for this CMD.
- */
- enum TALER_ErrorCode expected_ec;
-
- /**
- * Tip taler:// URI.
- */
- const char *tip_uri;
-
- /**
- * The tip id; set when the CMD succeeds.
- */
- struct GNUNET_HashCode tip_id;
-
- /**
- * Expiration date for this tip.
- */
- struct GNUNET_TIME_Absolute tip_expiration;
-
- /**
- * Handle to the on-going /tip-authorize request.
- */
- struct TALER_MERCHANT_TipAuthorizeOperation *tao;
-
- /**
- * The interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-};
-
-/**
- * Callback for a /tip-authorize request. Set into the state
- * what was returned from the backend (@a tip_id and @a
- * tip_expiration).
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant backend
- * @param ec taler-specific error code
- * @param taler_tip_uri URI to let the wallet know about the tip
- * @param tip_id unique identifier for the tip
- */
-static void
-tip_authorize_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const char *taler_tip_uri,
- struct GNUNET_HashCode *tip_id)
-{
- struct TipAuthorizeState *tas = cls;
-
- tas->tao = NULL;
- if (tas->http_status != http_status)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u (%d)"
- " to command %s\n",
- http_status,
- ec,
- TALER_TESTING_interpreter_get_current_label
- (tas->is));
-
- TALER_TESTING_interpreter_fail (tas->is);
- return;
- }
-
- if (tas->expected_ec != ec)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected error code %d (%u) to command %s\n",
- ec,
- http_status,
- TALER_TESTING_interpreter_get_current_label
- (tas->is));
- TALER_TESTING_interpreter_fail (tas->is);
- return;
- }
- if ( (MHD_HTTP_OK == http_status) &&
- (TALER_EC_NONE == ec) )
- {
- tas->tip_uri = strdup (taler_tip_uri);
- tas->tip_id = *tip_id;
- }
-
- TALER_TESTING_interpreter_next (tas->is);
-}
-
-
-/**
- * Offers information from the /tip-authorize CMD state to other
- * commands.
- *
- * @param cls closure
- * @param ret[out] result (could be anything)
- * @param trait name of the trait
- * @param index index number of the object to extract.
- * @return #GNUNET_OK on success
- */
-static int
-tip_authorize_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- struct TipAuthorizeState *tas = cls;
- struct TALER_TESTING_Trait traits[] = {
- TALER_TESTING_make_trait_tip_id (0, &tas->tip_id),
- TALER_TESTING_trait_end (),
- };
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
-}
-
-
-/**
- * Runs the /tip-authorize CMD
- *
- * @param cls closure
- * @param cmd the CMD representing _this_ command
- * @param is interpreter state
- */
-static void
-tip_authorize_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct TipAuthorizeState *tas = cls;
- struct TALER_Amount amount;
-
- tas->is = is;
- if (GNUNET_OK != TALER_string_to_amount (tas->amount,
- &amount))
- TALER_TESTING_FAIL (is);
-
- tas->tao = TALER_MERCHANT_tip_authorize
- (is->ctx,
- tas->merchant_url,
- "http://merchant.com/pickup",
- "http://merchant.com/continue",
- &amount,
- tas->justification,
- tip_authorize_cb,
- tas);
-
- GNUNET_assert (NULL != tas->tao);
-}
-
-
-/**
- * Run the /tip-authorize CMD, the "fake" version of it.
- *
- * @param cls closure
- * @param cmd the CMD representing _this_ command
- * @param is interpreter state *
- */
-static void
-tip_authorize_fake_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct TipAuthorizeState *tas = cls;
-
- /* Make up a tip id. */
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
- &tas->tip_id,
- sizeof (struct GNUNET_HashCode));
-
- TALER_TESTING_interpreter_next (is);
-}
-
-
-/**
- * Free the state from a /tip-authorize CMD, and possibly
- * cancel any pending operation.
- *
- * @param cls closure
- * @param cmd the /tip-authorize CMD that is about to be freed.
- */
-static void
-tip_authorize_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct TipAuthorizeState *tas = cls;
-
- if (NULL != tas->tao)
- {
- TALER_LOG_WARNING ("Tip-autorize operation"
- " did not complete\n");
- TALER_MERCHANT_tip_authorize_cancel (tas->tao);
- }
- GNUNET_free (tas);
-}
-
-
-/**
- * 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)
-{
- struct TipAuthorizeState *tas;
-
- tas = GNUNET_new (struct TipAuthorizeState);
- tas->merchant_url = merchant_url;
- tas->justification = justification;
- tas->amount = amount;
- tas->http_status = http_status;
- tas->expected_ec = ec;
-
- struct TALER_TESTING_Command cmd = {
- .label = label,
- .cls = tas,
- .run = &tip_authorize_run,
- .cleanup = &tip_authorize_cleanup,
- .traits = &tip_authorize_traits
- };
-
- return cmd;
-}
-
-
-/**
- * Create a /tip-authorize CMD.
- *
- * @param label this command label
- * @param merchant_url the base URL of the merchant that will
- * serve the /tip-authorize request.
- * @param exchange_url the base URL of the exchange that owns
- * the reserve from which the tip is going to be gotten.
- * @param 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)
-{
- struct TipAuthorizeState *tas;
-
- tas = GNUNET_new (struct TipAuthorizeState);
- tas->merchant_url = merchant_url;
- tas->justification = justification;
- tas->amount = amount;
- tas->http_status = http_status;
-
- struct TALER_TESTING_Command cmd = {
- .label = label,
- .cls = tas,
- .run = &tip_authorize_run,
- .cleanup = &tip_authorize_cleanup,
- .traits = &tip_authorize_traits
- };
-
- return cmd;
-}
-
-
-/**
- * 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 http_status HTTP status code for this request
- * @param ec Taler-specific error code
- * @param raw raw response body
- * @param reserve_expiration when the tip reserve will expire
- * @param reserve_pub tip reserve public key
- * @param amount_authorized total amount authorized on tip reserve
- * @param amount_available total amount still available on
- * tip reserve
- * @param amount_picked_up total amount picked up from tip reserve
- */
-static void
-tip_query_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const json_t *raw,
- struct GNUNET_TIME_Absolute reserve_expiration,
- struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_Amount *amount_authorized,
- struct TALER_Amount *amount_available,
- struct TALER_Amount *amount_picked_up)
-{
- struct TipQueryState *tqs = cls;
- struct TALER_Amount a;
-
- tqs->tqo = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Tip query callback at command `%s'\n",
- TALER_TESTING_interpreter_get_current_label
- (tqs->is));
-
- GNUNET_assert (NULL != reserve_pub);
- GNUNET_assert (NULL != amount_authorized);
- GNUNET_assert (NULL != amount_available);
- GNUNET_assert (NULL != amount_picked_up);
-
- if (tqs->expected_amount_available)
- {
- 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)
- {
- GNUNET_assert (GNUNET_OK == TALER_string_to_amount
- (tqs->expected_amount_authorized, &a));
- {
- char *str;
-
- 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)
- {
- GNUNET_assert (GNUNET_OK == TALER_string_to_amount
- (tqs->expected_amount_picked_up, &a));
- {
- char *str;
- 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);
- }
-
- if (tqs->http_status != 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_query_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;
-
- tqs->is = is;
- tqs->tqo = TALER_MERCHANT_tip_query (is->ctx,
- tqs->merchant_url,
- &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;
-}
-
-
-/**
- * Internal withdraw handle used when withdrawing tips.
- */
-struct WithdrawHandle
-{
- /**
- * Withdraw operation this handle represents.
- */
- struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
-
- /**
- * Interpreter state.
- */
- struct TALER_TESTING_Interpreter *is;
-
- /**
- * Offset of this withdraw operation in the current
- * @e is command.
- */
- unsigned int off;
-
-
- /**
- * Internal state of the "pickup" CMD.
- */
- struct TipPickupState *tps;
-};
-
-/**
- * This callback handles the response of a withdraw operation
- * from the exchange, that is the final step in getting the tip.
- *
- * @param cls closure, a `struct WithdrawHandle *`
- * @param http_status HTTP response code, #MHD_HTTP_OK (200)
- * for successful status request, 0 if the exchange's
- * reply is bogus (fails to follow the protocol)
- * @param ec taler-specific error code, #TALER_EC_NONE on success
- * @param sig signature over the coin, NULL on error
- * @param full_response full response from the exchange
- * (for logging, in case of errors)
- */
-static void
-pickup_withdraw_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct TALER_DenominationSignature *sig,
- const json_t *full_response)
-{
- struct WithdrawHandle *wh = cls;
- struct TALER_TESTING_Interpreter *is = wh->is;
-
- struct TipPickupState *tps = wh->tps;
-
- wh->wsh = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Withdraw operation %u completed with %u (%d)\n",
- wh->off,
- http_status,
- ec);
- GNUNET_assert (wh->off < tps->num_coins);
- if ( (MHD_HTTP_OK != http_status) ||
- (TALER_EC_NONE != ec) )
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u (%d)"
- " to command %s when withdrawing\n",
- http_status,
- ec,
- TALER_TESTING_interpreter_get_current_label (is));
- TALER_TESTING_interpreter_fail (is);
- return;
- }
- if (NULL == tps->sigs)
- tps->sigs = GNUNET_new_array
- (tps->num_coins, struct TALER_DenominationSignature);
-
- GNUNET_assert (NULL == tps->sigs[wh->off].rsa_signature);
- tps->sigs[wh->off].rsa_signature
- = GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
-
- for (unsigned int i = 0; i<tps->num_coins; i++)
- if (NULL != tps->withdraws[wh->off].wsh)
- return;
- /* still some ops ongoing */
-
- GNUNET_free (tps->withdraws);
- tps->withdraws = NULL;
- TALER_TESTING_interpreter_next (is);
-}
-
-
-/**
- * Callback for a /tip-pickup request, it mainly checks if
- * values returned from the backend are as expected, and if so
- * (and if the status was 200 OK) proceede with the withdrawal.
- *
- * @param cls closure
- * @param http_status HTTP status returned by the merchant
- * backend, "200 OK" on success
- * @param ec taler-specific error code
- * @param reserve_pub public key of the reserve that made the
- * @a reserve_sigs, NULL on error
- * @param num_reserve_sigs length of the @a reserve_sigs array,
- * 0 on error
- * @param reserve_sigs array of signatures authorizing withdrawals,
- * NULL on error
- * @param json original json response
- */
-static void
-pickup_cb (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- unsigned int num_reserve_sigs,
- const struct TALER_ReserveSignatureP *reserve_sigs,
- const json_t *json)
-{
- struct TipPickupState *tps = cls;
-
- tps->tpo = NULL;
- if (http_status != tps->http_status)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unexpected response code %u (%d) to command %s\n",
- http_status,
- ec,
- TALER_TESTING_interpreter_get_current_label
- (tps->is));
- TALER_TESTING_FAIL (tps->is);
- }
-
- if (ec != tps->expected_ec)
- TALER_TESTING_FAIL (tps->is);
-
- /* Safe to go ahead: http status was expected. */
- if ( (MHD_HTTP_OK != http_status) ||
- (TALER_EC_NONE != ec) )
- {
- TALER_TESTING_interpreter_next (tps->is);
- return;
- }
- if (num_reserve_sigs != tps->num_coins)
- TALER_TESTING_FAIL (tps->is);
-
- /* pickup successful, now withdraw! */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Obtained %u signatures for withdrawal"
- " from picking up a tip\n",
- num_reserve_sigs);
-
- GNUNET_assert (NULL == tps->withdraws);
- tps->withdraws = GNUNET_new_array
- (num_reserve_sigs, struct WithdrawHandle);
-
- for (unsigned int i = 0; i<num_reserve_sigs; i++)
- {
- struct WithdrawHandle *wh = &tps->withdraws[i];
-
- wh->off = i;
- wh->is = tps->is;
- wh->tps = tps;
- GNUNET_assert
- ( (NULL == wh->wsh) &&
- ( (NULL == tps->sigs) ||
- (NULL == tps->sigs[wh->off].rsa_signature) ) );
- wh->wsh = TALER_EXCHANGE_reserve_withdraw2
- (tps->is->exchange,
- tps->dks[i],
- &reserve_sigs[i],
- reserve_pub,
- &tps->psa[i],
- &pickup_withdraw_cb,
- wh);
- if (NULL == wh->wsh)
- TALER_TESTING_FAIL (tps->is);
- }
- if (0 == num_reserve_sigs)
- TALER_TESTING_interpreter_next (tps->is);
-}
-
-
-/**
- * Run a /tip-pickup CMD.
- *
- * @param cls closure
- * @param cmd the current /tip-pickup CMD.
- * @param is interpreter state.
- */
-static void
-tip_pickup_run (void *cls,
- const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *is)
-{
- struct TipPickupState *tps = cls;
- unsigned int num_planchets;
- const struct TALER_TESTING_Command *replay_cmd;
- const struct TALER_TESTING_Command *authorize_cmd;
- const struct GNUNET_HashCode *tip_id;
-
- tps->is = is;
- tps->exchange_url = TALER_EXCHANGE_get_base_url (is->exchange);
- if (NULL == tps->replay_reference)
- {
- replay_cmd = NULL;
-
- /* Count planchets. */
- for (num_planchets = 0;
- NULL != tps->amounts[num_planchets];
- num_planchets++)
- ;
- }
- else
- {
- const unsigned int *np;
- if (NULL == /* looking for "parent" tip-pickup command */
- (replay_cmd = TALER_TESTING_interpreter_lookup_command
- (is, tps->replay_reference)) )
- TALER_TESTING_FAIL (is);
-
- if (GNUNET_OK != TALER_TESTING_get_trait_uint
- (replay_cmd, 0, &np))
- TALER_TESTING_FAIL (is);
- num_planchets = *np;
- }
-
- if (NULL ==
- (authorize_cmd = TALER_TESTING_interpreter_lookup_command
- (is, tps->authorize_reference)) )
- TALER_TESTING_FAIL (is);
-
- tps->num_coins = num_planchets;
- {
- struct TALER_PlanchetDetail planchets[num_planchets];
-
- tps->psa = GNUNET_new_array (num_planchets,
- struct TALER_PlanchetSecretsP);
- tps->dks = GNUNET_new_array
- (num_planchets,
- const struct TALER_EXCHANGE_DenomPublicKey *);
-
- tps->amounts_obj = GNUNET_new_array
- (num_planchets, struct TALER_Amount);
-
- for (unsigned int i = 0; i<num_planchets; i++)
- {
- if (NULL == replay_cmd)
- {
- GNUNET_assert (GNUNET_OK == TALER_string_to_amount
- (tps->amounts[i], &tps->amounts_obj[i]));
-
- tps->dks[i] = TALER_TESTING_find_pk
- (is->keys,
- &tps->amounts_obj[i]);
-
- if (NULL == tps->dks[i])
- TALER_TESTING_FAIL (is);
-
- TALER_planchet_setup_random (&tps->psa[i]);
- }
- else
- {
- if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub
- (replay_cmd, i, &tps->dks[i]))
- TALER_TESTING_FAIL (is);
-
- struct TALER_PlanchetSecretsP *ps;
-
- if (GNUNET_OK != TALER_TESTING_get_trait_planchet_secrets
- (replay_cmd, i, &ps))
- TALER_TESTING_FAIL (is);
- tps->psa[i] = *ps;
- }
-
- if (GNUNET_OK != TALER_planchet_prepare (&tps->dks[i]->key,
- &tps->psa[i],
- &planchets[i]))
- TALER_TESTING_FAIL (is);
- }
-
- if (GNUNET_OK != TALER_TESTING_get_trait_tip_id
- (authorize_cmd, 0, &tip_id))
- TALER_TESTING_FAIL (is);
-
- tps->tpo = TALER_MERCHANT_tip_pickup (is->ctx,
- tps->merchant_url,
- tip_id,
- num_planchets,
- planchets,
- &pickup_cb,
- tps);
- for (unsigned int i = 0; i<num_planchets; i++)
- {
- GNUNET_free (planchets[i].coin_ev);
- planchets[i].coin_ev = NULL;
- planchets[i].coin_ev_size = 0;
- }
- GNUNET_assert (NULL != tps->tpo);
- }
-}
-
-
-/**
- * Free a /tip-pickup CMD state, and possibly cancel a
- * pending /tip-pickup request.
- *
- * @param cls closure.
- * @param cmd current CMD to be freed.
- */
-static void
-tip_pickup_cleanup (void *cls,
- const struct TALER_TESTING_Command *cmd)
-{
- struct TipPickupState *tps = cls;
-
- GNUNET_free_non_null (tps->amounts_obj);
- GNUNET_free_non_null (tps->dks);
- GNUNET_free_non_null (tps->psa);
- GNUNET_free_non_null (tps->withdraws);
- if (NULL != tps->sigs)
- {
- for (unsigned int i = 0; i<tps->num_coins; i++)
- if (NULL != tps->sigs[i].rsa_signature)
- GNUNET_CRYPTO_rsa_signature_free (tps->sigs[i].rsa_signature);
- GNUNET_free (tps->sigs);
- }
-
- if (NULL != tps->tpo)
- {
- TALER_LOG_WARNING ("Tip-pickup operation"
- " did not complete\n");
- TALER_MERCHANT_tip_pickup_cancel (tps->tpo);
- }
-
- GNUNET_free (tps);
-}
-
-
-/**
- * Offers information from the /tip-pickup CMD state to other
- * commands.
- *
- * @param cls closure
- * @param ret[out] result (could be anything)
- * @param trait name of the trait
- * @param index index number of the object to extract.
- * @return #GNUNET_OK on success
- */
-static int
-tip_pickup_traits (void *cls,
- const void **ret,
- const char *trait,
- unsigned int index)
-{
- struct TipPickupState *tps = cls;
- #define NUM_TRAITS (tps->num_coins * 5) + 2
- struct TALER_TESTING_Trait traits[NUM_TRAITS];
-
- for (unsigned int i = 0; i<tps->num_coins; i++)
- {
- traits[i] = TALER_TESTING_make_trait_planchet_secrets
- (i, &tps->psa[i]);
-
- traits[i + tps->num_coins] =
- TALER_TESTING_make_trait_coin_priv
- (i, &tps->psa[i].coin_priv);
-
- traits[i + (tps->num_coins * 2)] =
- TALER_TESTING_make_trait_denom_pub (i, tps->dks[i]);
-
- traits[i + (tps->num_coins * 3)] =
- TALER_TESTING_make_trait_denom_sig (i, &tps->sigs[i]);
-
- traits[i + (tps->num_coins * 4)] =
- TALER_TESTING_make_trait_amount_obj
- (i, &tps->amounts_obj[i]);
-
- }
- traits[NUM_TRAITS - 2] = TALER_TESTING_make_trait_url
- (0, tps->exchange_url);
- traits[NUM_TRAITS - 1] = TALER_TESTING_trait_end ();
-
- return TALER_TESTING_get_trait (traits,
- ret,
- trait,
- index);
-}
-
-
-/**
- * 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 exchange connection handle to the exchange that will
- * eventually serve the withdraw operation.
- * @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)
-{
- struct TipPickupState *tps;
-
- tps = GNUNET_new (struct TipPickupState);
- tps->merchant_url = merchant_url;
- tps->authorize_reference = authorize_reference;
- tps->amounts = amounts;
- tps->http_status = http_status;
- tps->expected_ec = ec;
-
- struct TALER_TESTING_Command cmd = {
- .cls = tps,
- .label = label,
- .run = &tip_pickup_run,
- .cleanup = &tip_pickup_cleanup,
- .traits = &tip_pickup_traits
- };
-
- return cmd;
-}
-
-
-/**
- * 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)
-{
- struct TipPickupState *tps;
-
- tps = GNUNET_new (struct TipPickupState);
- tps->merchant_url = merchant_url;
- tps->authorize_reference = authorize_reference;
- tps->amounts = amounts;
- tps->http_status = http_status;
-
- struct TALER_TESTING_Command cmd = {
- .cls = tps,
- .label = label,
- .run = &tip_pickup_run,
- .cleanup = &tip_pickup_cleanup,
- .traits = &tip_pickup_traits
- };
-
- return cmd;
-}
-
-
-/**
- * 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)
-{
- struct TipAuthorizeState *tas;
-
- tas = GNUNET_new (struct TipAuthorizeState);
-
- struct TALER_TESTING_Command cmd = {
- .label = label,
- .cls = tas,
- .run = &tip_authorize_fake_run,
- .cleanup = &tip_authorize_cleanup,
- .traits = &tip_authorize_traits
- };
-
- return cmd;
-}
-
-
-/* end of testing_api_cmd_tip.c */
diff --git a/src/lib/testing_api_cmd_tip_authorize.c b/src/lib/testing_api_cmd_tip_authorize.c
@@ -0,0 +1,375 @@
+/*
+ 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_authorize.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-authorize CMD.
+ */
+struct TipAuthorizeState
+{
+
+ /**
+ * Merchant base URL.
+ */
+ const char *merchant_url;
+
+ /**
+ * Expected HTTP response code.
+ */
+ unsigned int http_status;
+
+ /**
+ * Human-readable justification for the
+ * tip authorization carried on by this CMD.
+ */
+ const char *justification;
+
+ /**
+ * Amount that should be authorized for tipping.
+ */
+ const char *amount;
+
+ /**
+ * Expected Taler error code for this CMD.
+ */
+ enum TALER_ErrorCode expected_ec;
+
+ /**
+ * Tip taler:// URI.
+ */
+ const char *tip_uri;
+
+ /**
+ * The tip id; set when the CMD succeeds.
+ */
+ struct GNUNET_HashCode tip_id;
+
+ /**
+ * Expiration date for this tip.
+ */
+ struct GNUNET_TIME_Absolute tip_expiration;
+
+ /**
+ * Handle to the on-going /tip-authorize request.
+ */
+ struct TALER_MERCHANT_TipAuthorizeOperation *tao;
+
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+};
+
+
+/**
+ * Callback for a /tip-authorize request. Set into the state
+ * what was returned from the backend (@a tip_id and @a
+ * tip_expiration).
+ *
+ * @param cls closure
+ * @param http_status HTTP status returned by the merchant backend
+ * @param ec taler-specific error code
+ * @param taler_tip_uri URI to let the wallet know about the tip
+ * @param tip_id unique identifier for the tip
+ */
+static void
+tip_authorize_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const char *taler_tip_uri,
+ struct GNUNET_HashCode *tip_id)
+{
+ struct TipAuthorizeState *tas = cls;
+
+ tas->tao = NULL;
+ if (tas->http_status != http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u (%d)"
+ " to command %s\n",
+ http_status,
+ ec,
+ TALER_TESTING_interpreter_get_current_label
+ (tas->is));
+
+ TALER_TESTING_interpreter_fail (tas->is);
+ return;
+ }
+
+ if (tas->expected_ec != ec)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected error code %d (%u) to command %s\n",
+ ec,
+ http_status,
+ TALER_TESTING_interpreter_get_current_label
+ (tas->is));
+ TALER_TESTING_interpreter_fail (tas->is);
+ return;
+ }
+ if ( (MHD_HTTP_OK == http_status) &&
+ (TALER_EC_NONE == ec) )
+ {
+ tas->tip_uri = strdup (taler_tip_uri);
+ tas->tip_id = *tip_id;
+ }
+
+ TALER_TESTING_interpreter_next (tas->is);
+}
+
+
+/**
+ * Offers information from the /tip-authorize CMD state to other
+ * commands.
+ *
+ * @param cls closure
+ * @param ret[out] result (could be anything)
+ * @param trait name of the trait
+ * @param index index number of the object to extract.
+ * @return #GNUNET_OK on success
+ */
+static int
+tip_authorize_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ struct TipAuthorizeState *tas = cls;
+ struct TALER_TESTING_Trait traits[] = {
+ TALER_TESTING_make_trait_tip_id (0, &tas->tip_id),
+ TALER_TESTING_trait_end (),
+ };
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+}
+
+
+/**
+ * Runs the /tip-authorize CMD
+ *
+ * @param cls closure
+ * @param cmd the CMD representing _this_ command
+ * @param is interpreter state
+ */
+static void
+tip_authorize_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct TipAuthorizeState *tas = cls;
+ struct TALER_Amount amount;
+
+ tas->is = is;
+ if (GNUNET_OK != TALER_string_to_amount (tas->amount,
+ &amount))
+ TALER_TESTING_FAIL (is);
+
+ tas->tao = TALER_MERCHANT_tip_authorize
+ (is->ctx,
+ tas->merchant_url,
+ "http://merchant.com/pickup",
+ "http://merchant.com/continue",
+ &amount,
+ tas->justification,
+ tip_authorize_cb,
+ tas);
+
+ GNUNET_assert (NULL != tas->tao);
+}
+
+
+/**
+ * Run the /tip-authorize CMD, the "fake" version of it.
+ *
+ * @param cls closure
+ * @param cmd the CMD representing _this_ command
+ * @param is interpreter state *
+ */
+static void
+tip_authorize_fake_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct TipAuthorizeState *tas = cls;
+
+ /* Make up a tip id. */
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &tas->tip_id,
+ sizeof (struct GNUNET_HashCode));
+
+ TALER_TESTING_interpreter_next (is);
+}
+
+
+/**
+ * Free the state from a /tip-authorize CMD, and possibly
+ * cancel any pending operation.
+ *
+ * @param cls closure
+ * @param cmd the /tip-authorize CMD that is about to be freed.
+ */
+static void
+tip_authorize_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct TipAuthorizeState *tas = cls;
+
+ if (NULL != tas->tao)
+ {
+ TALER_LOG_WARNING ("Tip-autorize operation"
+ " did not complete\n");
+ TALER_MERCHANT_tip_authorize_cancel (tas->tao);
+ }
+ GNUNET_free (tas);
+}
+
+
+/**
+ * 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)
+{
+ struct TipAuthorizeState *tas;
+
+ tas = GNUNET_new (struct TipAuthorizeState);
+ tas->merchant_url = merchant_url;
+ tas->justification = justification;
+ tas->amount = amount;
+ tas->http_status = http_status;
+ tas->expected_ec = ec;
+
+ struct TALER_TESTING_Command cmd = {
+ .label = label,
+ .cls = tas,
+ .run = &tip_authorize_run,
+ .cleanup = &tip_authorize_cleanup,
+ .traits = &tip_authorize_traits
+ };
+
+ return cmd;
+}
+
+
+/**
+ * Create a /tip-authorize CMD.
+ *
+ * @param label this command label
+ * @param merchant_url the base URL of the merchant that will
+ * serve the /tip-authorize request.
+ * @param exchange_url the base URL of the exchange that owns
+ * the reserve from which the tip is going to be gotten.
+ * @param 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)
+{
+ struct TipAuthorizeState *tas;
+
+ tas = GNUNET_new (struct TipAuthorizeState);
+ tas->merchant_url = merchant_url;
+ tas->justification = justification;
+ tas->amount = amount;
+ tas->http_status = http_status;
+
+ struct TALER_TESTING_Command cmd = {
+ .label = label,
+ .cls = tas,
+ .run = &tip_authorize_run,
+ .cleanup = &tip_authorize_cleanup,
+ .traits = &tip_authorize_traits
+ };
+
+ return cmd;
+}
+
+
+/**
+ * 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)
+{
+ struct TipAuthorizeState *tas;
+
+ tas = GNUNET_new (struct TipAuthorizeState);
+
+ struct TALER_TESTING_Command cmd = {
+ .label = label,
+ .cls = tas,
+ .run = &tip_authorize_fake_run,
+ .cleanup = &tip_authorize_cleanup,
+ .traits = &tip_authorize_traits
+ };
+
+ return cmd;
+}
+
+
+/* end of testing_api_cmd_tip_authorize.c */
diff --git a/src/lib/testing_api_cmd_tip_pickup.c b/src/lib/testing_api_cmd_tip_pickup.c
@@ -0,0 +1,598 @@
+/*
+ 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.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-pickup CMD.
+ */
+struct TipPickupState
+{
+ /**
+ * Merchant base URL.
+ */
+ const char *merchant_url;
+
+ /**
+ * Exchange base URL.
+ */
+ const char *exchange_url;
+
+ /**
+ * Expected HTTP response code.
+ */
+ unsigned int http_status;
+
+ /**
+ * Reference to a /tip/authorize CMD. This will be used to
+ * get the tip id to make the request with.
+ */
+ const char *authorize_reference;
+
+ /**
+ * If set to non NULL, it references another pickup CMD
+ * that will provide all the data which is needed to issue
+ * the request (like planchet secrets, denomination keys..).
+ */
+ const char *replay_reference;
+
+ /**
+ * Handle to a on-going /tip/pickup request.
+ */
+ struct TALER_MERCHANT_TipPickupOperation *tpo;
+
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * An array of string-defined amounts that indicates
+ * which denominations are going to be used to receive
+ * tips.
+ */
+ const char **amounts;
+
+ /**
+ * The object version of the above @a amounts.
+ */
+ struct TALER_Amount *amounts_obj;
+
+ /**
+ * How many coins are involved in the tipping operation.
+ */
+ unsigned int num_coins;
+
+ /**
+ * The array of denomination keys, in the same order of @a
+ * amounts.
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey **dks;
+
+ /**
+ * The array of planchet secrets, in the same order of @a
+ * amounts.
+ */
+ struct TALER_PlanchetSecretsP *psa;
+
+ /**
+ * Temporary data structure of @e num_coins entries for the
+ * withdraw operations.
+ */
+ struct WithdrawHandle *withdraws;
+
+ /**
+ * Set (by the interpreter) to an array of @a num_coins
+ * signatures created from the (successful) tip operation.
+ */
+ struct TALER_DenominationSignature *sigs;
+
+ /**
+ * Expected Taler error code (NOTE: this is NOT the HTTP
+ * response code).
+ */
+ enum TALER_ErrorCode expected_ec;
+};
+
+
+/**
+ * Internal withdraw handle used when withdrawing tips.
+ */
+struct WithdrawHandle
+{
+ /**
+ * Withdraw operation this handle represents.
+ */
+ struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
+
+ /**
+ * Interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Offset of this withdraw operation in the current
+ * @e is command.
+ */
+ unsigned int off;
+
+ /**
+ * Internal state of the "pickup" CMD.
+ */
+ struct TipPickupState *tps;
+};
+
+
+/**
+ * This callback handles the response of a withdraw operation
+ * from the exchange, that is the final step in getting the tip.
+ *
+ * @param cls closure, a `struct WithdrawHandle *`
+ * @param http_status HTTP response code, #MHD_HTTP_OK (200)
+ * for successful status request, 0 if the exchange's
+ * reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
+ * @param sig signature over the coin, NULL on error
+ * @param full_response full response from the exchange
+ * (for logging, in case of errors)
+ */
+static void
+pickup_withdraw_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct TALER_DenominationSignature *sig,
+ const json_t *full_response)
+{
+ struct WithdrawHandle *wh = cls;
+ struct TALER_TESTING_Interpreter *is = wh->is;
+
+ struct TipPickupState *tps = wh->tps;
+
+ wh->wsh = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Withdraw operation %u completed with %u (%d)\n",
+ wh->off,
+ http_status,
+ ec);
+ GNUNET_assert (wh->off < tps->num_coins);
+ if ( (MHD_HTTP_OK != http_status) ||
+ (TALER_EC_NONE != ec) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u (%d)"
+ " to command %s when withdrawing\n",
+ http_status,
+ ec,
+ TALER_TESTING_interpreter_get_current_label (is));
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
+ if (NULL == tps->sigs)
+ tps->sigs = GNUNET_new_array
+ (tps->num_coins, struct TALER_DenominationSignature);
+
+ GNUNET_assert (NULL == tps->sigs[wh->off].rsa_signature);
+ tps->sigs[wh->off].rsa_signature
+ = GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
+
+ for (unsigned int i = 0; i<tps->num_coins; i++)
+ if (NULL != tps->withdraws[wh->off].wsh)
+ return;
+ /* still some ops ongoing */
+
+ GNUNET_free (tps->withdraws);
+ tps->withdraws = NULL;
+ TALER_TESTING_interpreter_next (is);
+}
+
+
+/**
+ * Callback for a /tip-pickup request, it mainly checks if
+ * values returned from the backend are as expected, and if so
+ * (and if the status was 200 OK) proceede with the withdrawal.
+ *
+ * @param cls closure
+ * @param http_status HTTP status returned by the merchant
+ * backend, "200 OK" on success
+ * @param ec taler-specific error code
+ * @param reserve_pub public key of the reserve that made the
+ * @a reserve_sigs, NULL on error
+ * @param num_reserve_sigs length of the @a reserve_sigs array,
+ * 0 on error
+ * @param reserve_sigs array of signatures authorizing withdrawals,
+ * NULL on error
+ * @param json original json response
+ */
+static void
+pickup_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ unsigned int num_reserve_sigs,
+ const struct TALER_ReserveSignatureP *reserve_sigs,
+ const json_t *json)
+{
+ struct TipPickupState *tps = cls;
+
+ tps->tpo = NULL;
+ if (http_status != tps->http_status)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u (%d) to command %s\n",
+ http_status,
+ ec,
+ TALER_TESTING_interpreter_get_current_label
+ (tps->is));
+ TALER_TESTING_FAIL (tps->is);
+ }
+
+ if (ec != tps->expected_ec)
+ TALER_TESTING_FAIL (tps->is);
+
+ /* Safe to go ahead: http status was expected. */
+ if ( (MHD_HTTP_OK != http_status) ||
+ (TALER_EC_NONE != ec) )
+ {
+ TALER_TESTING_interpreter_next (tps->is);
+ return;
+ }
+ if (num_reserve_sigs != tps->num_coins)
+ TALER_TESTING_FAIL (tps->is);
+
+ /* pickup successful, now withdraw! */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Obtained %u signatures for withdrawal"
+ " from picking up a tip\n",
+ num_reserve_sigs);
+
+ GNUNET_assert (NULL == tps->withdraws);
+ tps->withdraws = GNUNET_new_array
+ (num_reserve_sigs, struct WithdrawHandle);
+
+ for (unsigned int i = 0; i<num_reserve_sigs; i++)
+ {
+ struct WithdrawHandle *wh = &tps->withdraws[i];
+
+ wh->off = i;
+ wh->is = tps->is;
+ wh->tps = tps;
+ GNUNET_assert
+ ( (NULL == wh->wsh) &&
+ ( (NULL == tps->sigs) ||
+ (NULL == tps->sigs[wh->off].rsa_signature) ) );
+ wh->wsh = TALER_EXCHANGE_reserve_withdraw2
+ (tps->is->exchange,
+ tps->dks[i],
+ &reserve_sigs[i],
+ reserve_pub,
+ &tps->psa[i],
+ &pickup_withdraw_cb,
+ wh);
+ if (NULL == wh->wsh)
+ TALER_TESTING_FAIL (tps->is);
+ }
+ if (0 == num_reserve_sigs)
+ TALER_TESTING_interpreter_next (tps->is);
+}
+
+
+/**
+ * Run a /tip-pickup CMD.
+ *
+ * @param cls closure
+ * @param cmd the current /tip-pickup CMD.
+ * @param is interpreter state.
+ */
+static void
+tip_pickup_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct TipPickupState *tps = cls;
+ unsigned int num_planchets;
+ const struct TALER_TESTING_Command *replay_cmd;
+ const struct TALER_TESTING_Command *authorize_cmd;
+ const struct GNUNET_HashCode *tip_id;
+
+ tps->is = is;
+ tps->exchange_url = TALER_EXCHANGE_get_base_url (is->exchange);
+ if (NULL == tps->replay_reference)
+ {
+ replay_cmd = NULL;
+
+ /* Count planchets. */
+ for (num_planchets = 0;
+ NULL != tps->amounts[num_planchets];
+ num_planchets++)
+ ;
+ }
+ else
+ {
+ const unsigned int *np;
+ if (NULL == /* looking for "parent" tip-pickup command */
+ (replay_cmd = TALER_TESTING_interpreter_lookup_command
+ (is, tps->replay_reference)) )
+ TALER_TESTING_FAIL (is);
+
+ if (GNUNET_OK != TALER_TESTING_get_trait_uint
+ (replay_cmd, 0, &np))
+ TALER_TESTING_FAIL (is);
+ num_planchets = *np;
+ }
+
+ if (NULL ==
+ (authorize_cmd = TALER_TESTING_interpreter_lookup_command
+ (is, tps->authorize_reference)) )
+ TALER_TESTING_FAIL (is);
+
+ tps->num_coins = num_planchets;
+ {
+ struct TALER_PlanchetDetail planchets[num_planchets];
+
+ tps->psa = GNUNET_new_array (num_planchets,
+ struct TALER_PlanchetSecretsP);
+ tps->dks = GNUNET_new_array
+ (num_planchets,
+ const struct TALER_EXCHANGE_DenomPublicKey *);
+
+ tps->amounts_obj = GNUNET_new_array
+ (num_planchets, struct TALER_Amount);
+
+ for (unsigned int i = 0; i<num_planchets; i++)
+ {
+ if (NULL == replay_cmd)
+ {
+ GNUNET_assert (GNUNET_OK == TALER_string_to_amount
+ (tps->amounts[i], &tps->amounts_obj[i]));
+
+ tps->dks[i] = TALER_TESTING_find_pk
+ (is->keys,
+ &tps->amounts_obj[i]);
+
+ if (NULL == tps->dks[i])
+ TALER_TESTING_FAIL (is);
+
+ TALER_planchet_setup_random (&tps->psa[i]);
+ }
+ else
+ {
+ if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub
+ (replay_cmd, i, &tps->dks[i]))
+ TALER_TESTING_FAIL (is);
+
+ struct TALER_PlanchetSecretsP *ps;
+
+ if (GNUNET_OK != TALER_TESTING_get_trait_planchet_secrets
+ (replay_cmd, i, &ps))
+ TALER_TESTING_FAIL (is);
+ tps->psa[i] = *ps;
+ }
+
+ if (GNUNET_OK != TALER_planchet_prepare (&tps->dks[i]->key,
+ &tps->psa[i],
+ &planchets[i]))
+ TALER_TESTING_FAIL (is);
+ }
+
+ if (GNUNET_OK != TALER_TESTING_get_trait_tip_id
+ (authorize_cmd, 0, &tip_id))
+ TALER_TESTING_FAIL (is);
+
+ tps->tpo = TALER_MERCHANT_tip_pickup (is->ctx,
+ tps->merchant_url,
+ tip_id,
+ num_planchets,
+ planchets,
+ &pickup_cb,
+ tps);
+ for (unsigned int i = 0; i<num_planchets; i++)
+ {
+ GNUNET_free (planchets[i].coin_ev);
+ planchets[i].coin_ev = NULL;
+ planchets[i].coin_ev_size = 0;
+ }
+ GNUNET_assert (NULL != tps->tpo);
+ }
+}
+
+
+/**
+ * Free a /tip-pickup CMD state, and possibly cancel a
+ * pending /tip-pickup request.
+ *
+ * @param cls closure.
+ * @param cmd current CMD to be freed.
+ */
+static void
+tip_pickup_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct TipPickupState *tps = cls;
+
+ GNUNET_free_non_null (tps->amounts_obj);
+ GNUNET_free_non_null (tps->dks);
+ GNUNET_free_non_null (tps->psa);
+ GNUNET_free_non_null (tps->withdraws);
+ if (NULL != tps->sigs)
+ {
+ for (unsigned int i = 0; i<tps->num_coins; i++)
+ if (NULL != tps->sigs[i].rsa_signature)
+ GNUNET_CRYPTO_rsa_signature_free (tps->sigs[i].rsa_signature);
+ GNUNET_free (tps->sigs);
+ }
+
+ if (NULL != tps->tpo)
+ {
+ TALER_LOG_WARNING ("Tip-pickup operation"
+ " did not complete\n");
+ TALER_MERCHANT_tip_pickup_cancel (tps->tpo);
+ }
+
+ GNUNET_free (tps);
+}
+
+
+/**
+ * Offers information from the /tip-pickup CMD state to other
+ * commands.
+ *
+ * @param cls closure
+ * @param ret[out] result (could be anything)
+ * @param trait name of the trait
+ * @param index index number of the object to extract.
+ * @return #GNUNET_OK on success
+ */
+static int
+tip_pickup_traits (void *cls,
+ const void **ret,
+ const char *trait,
+ unsigned int index)
+{
+ struct TipPickupState *tps = cls;
+ #define NUM_TRAITS (tps->num_coins * 5) + 2
+ struct TALER_TESTING_Trait traits[NUM_TRAITS];
+
+ for (unsigned int i = 0; i<tps->num_coins; i++)
+ {
+ traits[i] = TALER_TESTING_make_trait_planchet_secrets
+ (i, &tps->psa[i]);
+
+ traits[i + tps->num_coins] =
+ TALER_TESTING_make_trait_coin_priv
+ (i, &tps->psa[i].coin_priv);
+
+ traits[i + (tps->num_coins * 2)] =
+ TALER_TESTING_make_trait_denom_pub (i, tps->dks[i]);
+
+ traits[i + (tps->num_coins * 3)] =
+ TALER_TESTING_make_trait_denom_sig (i, &tps->sigs[i]);
+
+ traits[i + (tps->num_coins * 4)] =
+ TALER_TESTING_make_trait_amount_obj
+ (i, &tps->amounts_obj[i]);
+
+ }
+ traits[NUM_TRAITS - 2] = TALER_TESTING_make_trait_url
+ (0, tps->exchange_url);
+ traits[NUM_TRAITS - 1] = TALER_TESTING_trait_end ();
+
+ return TALER_TESTING_get_trait (traits,
+ ret,
+ trait,
+ index);
+}
+
+
+/**
+ * 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 exchange connection handle to the exchange that will
+ * eventually serve the withdraw operation.
+ * @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)
+{
+ struct TipPickupState *tps;
+
+ tps = GNUNET_new (struct TipPickupState);
+ tps->merchant_url = merchant_url;
+ tps->authorize_reference = authorize_reference;
+ tps->amounts = amounts;
+ tps->http_status = http_status;
+ tps->expected_ec = ec;
+
+ struct TALER_TESTING_Command cmd = {
+ .cls = tps,
+ .label = label,
+ .run = &tip_pickup_run,
+ .cleanup = &tip_pickup_cleanup,
+ .traits = &tip_pickup_traits
+ };
+
+ return cmd;
+}
+
+
+/**
+ * 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)
+{
+ struct TipPickupState *tps;
+
+ tps = GNUNET_new (struct TipPickupState);
+ tps->merchant_url = merchant_url;
+ tps->authorize_reference = authorize_reference;
+ tps->amounts = amounts;
+ tps->http_status = http_status;
+
+ struct TALER_TESTING_Command cmd = {
+ .cls = tps,
+ .label = label,
+ .run = &tip_pickup_run,
+ .cleanup = &tip_pickup_cleanup,
+ .traits = &tip_pickup_traits
+ };
+
+ return cmd;
+}
+
+
+/* end of testing_api_cmd_tip_pickup.c */
diff --git a/src/lib/testing_api_cmd_tip_query.c b/src/lib/testing_api_cmd_tip_query.c
@@ -0,0 +1,297 @@
+/*
+ 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_TipQueryOperation *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 http_status HTTP status code for this request
+ * @param ec Taler-specific error code
+ * @param raw raw response body
+ * @param reserve_expiration when the tip reserve will expire
+ * @param reserve_pub tip reserve public key
+ * @param amount_authorized total amount authorized on tip reserve
+ * @param amount_available total amount still available on
+ * tip reserve
+ * @param amount_picked_up total amount picked up from tip reserve
+ */
+static void
+tip_query_cb (void *cls,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const json_t *raw,
+ struct GNUNET_TIME_Absolute reserve_expiration,
+ struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_Amount *amount_authorized,
+ struct TALER_Amount *amount_available,
+ struct TALER_Amount *amount_picked_up)
+{
+ struct TipQueryState *tqs = cls;
+ struct TALER_Amount a;
+
+ tqs->tqo = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Tip query callback at command `%s'\n",
+ TALER_TESTING_interpreter_get_current_label
+ (tqs->is));
+
+ GNUNET_assert (NULL != reserve_pub);
+ GNUNET_assert (NULL != amount_authorized);
+ GNUNET_assert (NULL != amount_available);
+ GNUNET_assert (NULL != amount_picked_up);
+
+ if (tqs->expected_amount_available)
+ {
+ 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)
+ {
+ GNUNET_assert (GNUNET_OK == TALER_string_to_amount
+ (tqs->expected_amount_authorized, &a));
+ {
+ char *str;
+
+ 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)
+ {
+ GNUNET_assert (GNUNET_OK == TALER_string_to_amount
+ (tqs->expected_amount_picked_up, &a));
+ {
+ char *str;
+ 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);
+ }
+
+ if (tqs->http_status != 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_query_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;
+
+ tqs->is = is;
+ tqs->tqo = TALER_MERCHANT_tip_query (is->ctx,
+ tqs->merchant_url,
+ &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 */