LCOV - code coverage report
Current view: top level - lib - testing_api_cmd_tip.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 257 303 84.8 %
Date: 2018-07-14 06:17:23 Functions: 20 20 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2018 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify
       6             :   it under the terms of the GNU General Public License as
       7             :   published by the Free Software Foundation; either version 3, or
       8             :   (at your option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful, but
      11             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public
      16             :   License along with TALER; see the file COPYING.  If not, see
      17             :   <http://www.gnu.org/licenses/>
      18             : */
      19             : 
      20             : /**
      21             :  * @file lib/testing_api_cmd_tip.c
      22             :  * @brief command to test the tipping.
      23             :  * @author Marcello Stanisci
      24             :  */
      25             : 
      26             : #include "platform.h"
      27             : #include <taler/taler_exchange_service.h>
      28             : #include <taler/taler_testing_lib.h>
      29             : #include "taler_merchant_service.h"
      30             : #include "taler_merchant_testing_lib.h"
      31             : 
      32             : /**
      33             :  * Obtain the URL to use for an API request.
      34             :  *
      35             :  * @param h the exchange handle to query
      36             :  * @param path Taler API path (i.e. "/reserve/withdraw")
      37             :  * @return the full URL to use with cURL
      38             :  */
      39             : char *
      40             : MAH_path_to_url (struct TALER_EXCHANGE_Handle *h,
      41             :                  const char *path);
      42             : 
      43             : /**
      44             :  * State for a /tip-pickup CMD.
      45             :  */
      46             : struct TipPickupState
      47             : {
      48             :   /**
      49             :    * Merchant base URL.
      50             :    */
      51             :   const char *merchant_url;
      52             : 
      53             :   /**
      54             :    * Exchange base URL.
      55             :    */
      56             :   const char *exchange_url;
      57             : 
      58             :   /**
      59             :    * CURL context.
      60             :    */
      61             :   struct GNUNET_CURL_Context *ctx;
      62             : 
      63             :   /**
      64             :    * Expected HTTP response code.
      65             :    */
      66             :   unsigned int http_status;
      67             : 
      68             :   /**
      69             :    * Reference to a /tip/authorize CMD.  This will be used to
      70             :    * get the tip id to make the request with.
      71             :    */
      72             :   const char *authorize_reference;
      73             : 
      74             :   /**
      75             :    * If set to non NULL, it references another pickup CMD
      76             :    * that will provide all the data which is needed to issue
      77             :    * the request (like planchet secrets, denomination keys..).
      78             :    */
      79             :   const char *replay_reference;
      80             : 
      81             :   /**
      82             :    * Handle to a on-going /tip/pickup request.
      83             :    */
      84             :   struct TALER_MERCHANT_TipPickupOperation *tpo;
      85             : 
      86             :   /**
      87             :    * The interpreter state.
      88             :    */
      89             :   struct TALER_TESTING_Interpreter *is;
      90             : 
      91             :   /**
      92             :    * An array of string-defined amounts that indicates
      93             :    * which denominations are going to be used to receive
      94             :    * tips.
      95             :    */
      96             :   const char **amounts;
      97             : 
      98             :   /**
      99             :    * The object version of the above @a amounts.
     100             :    */
     101             :   struct TALER_Amount *amounts_obj;
     102             : 
     103             :   /**
     104             :    * How many coins are involved in the tipping operation.
     105             :    */
     106             :   unsigned int num_coins;
     107             :   
     108             :   /**
     109             :    * The array of denomination keys, in the same order of @a
     110             :    * amounts.
     111             :    */
     112             :   const struct TALER_EXCHANGE_DenomPublicKey **dks;
     113             : 
     114             : 
     115             :   /**
     116             :    * The array of planchet secrets, in the same order of @a
     117             :    * amounts.
     118             :    */
     119             :   struct TALER_PlanchetSecretsP *psa;
     120             : 
     121             :   /**
     122             :    * Temporary data structure of @e num_coins entries for the
     123             :    * withdraw operations.
     124             :    */
     125             :   struct WithdrawHandle *withdraws;
     126             : 
     127             :   /**
     128             :    * Set (by the interpreter) to an array of @a num_coins
     129             :    * signatures created from the (successful) tip operation.
     130             :    */
     131             :   struct TALER_DenominationSignature *sigs;
     132             : 
     133             :   /**
     134             :    * Expected Taler error code (NOTE: this is NOT the HTTP
     135             :    * response code).
     136             :    */
     137             :   enum TALER_ErrorCode expected_ec;
     138             : 
     139             :   /**
     140             :    * The connection to the exchange.
     141             :    */
     142             :   struct TALER_EXCHANGE_Handle *exchange;
     143             : };
     144             : 
     145             : 
     146             : /**
     147             :  * State for a /tip-query CMD.
     148             :  */
     149             : struct TipQueryState
     150             : {
     151             : 
     152             :   /**
     153             :    * The merchant base URL.
     154             :    */
     155             :   const char *merchant_url;
     156             : 
     157             :   /**
     158             :    * The CURL context.
     159             :    */
     160             :   struct GNUNET_CURL_Context *ctx;
     161             : 
     162             :   /**
     163             :    * Expected HTTP response code for this CMD.
     164             :    */
     165             :   unsigned int http_status;
     166             : 
     167             :   /**
     168             :    * Which merchant instance is running this CMD.
     169             :    */
     170             :   const char *instance;
     171             : 
     172             :   /**
     173             :    * The handle to the current /tip-query request.
     174             :    */
     175             :   struct TALER_MERCHANT_TipQueryOperation *tqo;
     176             : 
     177             :   /**
     178             :    * The interpreter state.
     179             :    */
     180             :   struct TALER_TESTING_Interpreter *is;
     181             : 
     182             :   /**
     183             :    * Expected amount to be picked up.
     184             :    */
     185             :   const char *expected_amount_picked_up;
     186             : 
     187             :   /**
     188             :    * Expected amount to be tip-authorized.
     189             :    */
     190             :   const char *expected_amount_authorized;
     191             : 
     192             :   /**
     193             :    * Amount that is expected to be still available
     194             :    * from the tip reserve.
     195             :    */
     196             :   const char *expected_amount_available;
     197             : };
     198             : 
     199             : 
     200             : /**
     201             :  * State for a /tip-authorize CMD.
     202             :  */
     203             : struct TipAuthorizeState
     204             : {
     205             :   
     206             :   /**
     207             :    * Merchant base URL.
     208             :    */
     209             :   const char *merchant_url;
     210             : 
     211             :   /**
     212             :    * CURL context.
     213             :    */
     214             :   struct GNUNET_CURL_Context *ctx;
     215             : 
     216             :   /**
     217             :    * Expected HTTP response code.
     218             :    */
     219             :   unsigned int http_status;
     220             : 
     221             :   /**
     222             :    * Merchant instance running this CMD.
     223             :    */
     224             :   const char *instance;
     225             : 
     226             :   /**
     227             :    * Human-readable justification for the
     228             :    * tip authorization carried on by this CMD.
     229             :    */
     230             :   const char *justification;
     231             : 
     232             :   /**
     233             :    * Amount that should be authorized for tipping.
     234             :    */
     235             :   const char *amount;
     236             : 
     237             :   /**
     238             :    * Expected Taler error code for this CMD.
     239             :    */
     240             :   enum TALER_ErrorCode expected_ec;
     241             : 
     242             :   /**
     243             :    * Base URL of the involved exchange.
     244             :    */
     245             :   const char *exchange_url;
     246             : 
     247             :   /**
     248             :    * The tip id; set when the CMD succeeds.
     249             :    */
     250             :   struct GNUNET_HashCode tip_id;
     251             : 
     252             :   /**
     253             :    * Expiration date for this tip.
     254             :    */
     255             :   struct GNUNET_TIME_Absolute tip_expiration;
     256             : 
     257             :   /**
     258             :    * Handle to the on-going /tip-authorize request.
     259             :    */
     260             :   struct TALER_MERCHANT_TipAuthorizeOperation *tao;
     261             : 
     262             :   /**
     263             :    * The interpreter state.
     264             :    */
     265             :   struct TALER_TESTING_Interpreter *is;
     266             : };
     267             : 
     268             : /**
     269             :  * Callback for a /tip-authorize request.  Set into the state
     270             :  * what was returned from the backend (@a tip_id and @a
     271             :  * tip_expiration).
     272             :  *
     273             :  * @param cls closure
     274             :  * @param http_status HTTP status returned by the merchant backend
     275             :  * @param ec taler-specific error code
     276             :  * @param tip_id which tip ID should be used to pickup the tip
     277             :  * @param tip_expiration when does the tip expire (needs to be
     278             :  *        picked up before this time)
     279             :  * @param exchange_url at what exchange can the tip be picked up
     280             :  */
     281             : static void
     282           6 : tip_authorize_cb (void *cls,
     283             :                   unsigned int http_status,
     284             :                   enum TALER_ErrorCode ec,
     285             :                   const struct GNUNET_HashCode *tip_id,
     286             :                   struct GNUNET_TIME_Absolute tip_expiration,
     287             :                   const char *exchange_url)
     288             : {
     289           6 :   struct TipAuthorizeState *tas = cls; 
     290             : 
     291           6 :   tas->tao = NULL;
     292           6 :   if (tas->http_status != http_status)
     293             :   {
     294           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     295             :                 "Unexpected response code %u (%d)"
     296             :                 " to command %s\n",
     297             :                 http_status,
     298             :                 ec,
     299             :                 TALER_TESTING_interpreter_get_current_label
     300             :                   (tas->is));
     301             : 
     302           0 :     TALER_TESTING_interpreter_fail (tas->is);
     303           0 :     return;
     304             :   }
     305             : 
     306           6 :   if (tas->expected_ec != ec)
     307             :   {
     308           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     309             :                 "Unexpected error code %d (%u) to command %s\n",
     310             :                 ec,
     311             :                 http_status,
     312             :                 TALER_TESTING_interpreter_get_current_label
     313             :                   (tas->is));
     314           0 :     TALER_TESTING_interpreter_fail (tas->is);
     315           0 :     return;
     316             :   }
     317           6 :   if ( (MHD_HTTP_OK == http_status) &&
     318             :        (TALER_EC_NONE == ec) )
     319             :   {
     320           2 :     if (0 != strcmp (exchange_url,
     321             :                      tas->exchange_url))
     322             :     {
     323           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     324             :                   "Unexpected exchange URL %s to command %s\n",
     325             :                   exchange_url,
     326             :                   TALER_TESTING_interpreter_get_current_label
     327             :                     (tas->is));
     328           0 :       TALER_TESTING_interpreter_fail (tas->is);
     329           0 :       return;
     330             :     }
     331           2 :     tas->tip_id = *tip_id;
     332           2 :     tas->tip_expiration = tip_expiration;
     333             :   }
     334             : 
     335           6 :   TALER_TESTING_interpreter_next (tas->is);
     336             : }
     337             : 
     338             : /**
     339             :  * Offers information from the /tip-authorize CMD state to other
     340             :  * commands.
     341             :  *
     342             :  * @param cls closure
     343             :  * @param ret[out] result (could be anything)
     344             :  * @param trait name of the trait
     345             :  * @param index index number of the object to extract.
     346             :  * @return #GNUNET_OK on success
     347             :  */
     348             : static int
     349           4 : tip_authorize_traits (void *cls,
     350             :                       void **ret,
     351             :                       const char *trait,
     352             :                       unsigned int index)
     353             : {
     354           4 :   struct TipAuthorizeState *tas = cls;
     355             : 
     356           4 :   struct TALER_TESTING_Trait traits[] = {
     357           4 :     TALER_TESTING_make_trait_tip_id (0, &tas->tip_id),
     358             :     TALER_TESTING_trait_end (),
     359             :   };
     360             : 
     361           4 :   return TALER_TESTING_get_trait (traits,
     362             :                                   ret,
     363             :                                   trait,
     364             :                                   index);
     365             :   return GNUNET_SYSERR;
     366             : }
     367             : 
     368             : /**
     369             :  * Runs the /tip-authorize CMD
     370             :  *
     371             :  * @param cls closure
     372             :  * @param cmd the CMD representing _this_ command
     373             :  * @param is interpreter state
     374             :  */
     375             : static void
     376           6 : tip_authorize_run (void *cls,
     377             :                    const struct TALER_TESTING_Command *cmd,
     378             :                    struct TALER_TESTING_Interpreter *is)
     379             : {
     380           6 :   struct TipAuthorizeState *tas = cls;
     381             :   struct TALER_Amount amount; 
     382             : 
     383           6 :   tas->is = is;
     384           6 :   if (GNUNET_OK != TALER_string_to_amount (tas->amount,
     385             :                                            &amount))
     386           0 :     TALER_TESTING_FAIL (is);
     387             : 
     388           6 :   tas->tao = TALER_MERCHANT_tip_authorize
     389             :     (tas->ctx,
     390             :      tas->merchant_url,
     391             :      "http://merchant.com/pickup",
     392             :      "http://merchant.com/continue",
     393             :      &amount,
     394             :      tas->instance,
     395             :      tas->justification,
     396             :      tip_authorize_cb,
     397             :      tas);
     398             : 
     399           6 :   GNUNET_assert (NULL != tas->tao);
     400             : }
     401             : 
     402             : 
     403             : /**
     404             :  * Run the /tip-authorize CMD, the "fake" version of it.
     405             :  *
     406             :  * @param cls closure
     407             :  * @param cmd the CMD representing _this_ command
     408             :  * @param is interpreter state *
     409             :  */
     410             : static void
     411           1 : tip_authorize_fake_run (void *cls,
     412             :                         const struct TALER_TESTING_Command *cmd,
     413             :                         struct TALER_TESTING_Interpreter *is)
     414             : {
     415           1 :   struct TipAuthorizeState *tas = cls;
     416             : 
     417             :   /* Make up a tip id.  */
     418           1 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     419           1 :                               &tas->tip_id,
     420             :                               sizeof (struct GNUNET_HashCode));
     421             : 
     422           1 :   TALER_TESTING_interpreter_next (is);
     423           1 : }
     424             : 
     425             : 
     426             : /**
     427             :  * Free the state from a /tip-authorize CMD, and possibly
     428             :  * cancel any pending operation.
     429             :  *
     430             :  * @param cls closure
     431             :  * @param cmd the /tip-authorize CMD that is about to be freed.
     432             :  */
     433             : static void
     434           7 : tip_authorize_cleanup (void *cls,
     435             :                        const struct TALER_TESTING_Command *cmd)
     436             : {
     437           7 :   struct TipAuthorizeState *tas = cls;
     438             : 
     439           7 :   if (NULL != tas->tao)
     440             :   {
     441           0 :     TALER_LOG_WARNING ("Tip-autorize operation"
     442             :                        " did not complete\n");
     443           0 :     TALER_MERCHANT_tip_authorize_cancel (tas->tao);
     444             :   }
     445           7 :   GNUNET_free (tas);
     446           7 : }
     447             : 
     448             : 
     449             : /**
     450             :  * Create a /tip-authorize CMD, specifying the Taler error code
     451             :  * that is expected to be returned by the backend.
     452             :  *
     453             :  * @param label this command label
     454             :  * @param merchant_url the base URL of the merchant that will
     455             :  *        serve the /tip-authorize request.
     456             :  * @param exchange_url the base URL of the exchange that owns
     457             :  *        the reserve from which the tip is going to be gotten.
     458             :  * @param ctx the CURL context to carry on the HTTP work.
     459             :  * @param http_status the HTTP response code which is expected
     460             :  *        for this operation.
     461             :  * @param instance which merchant instance is running this CMD.
     462             :  * @param justification human-readable justification for this
     463             :  *        tip authorization.
     464             :  * @param amount the amount to authorize for tipping.
     465             :  * @param ec expected Taler-defined error code.
     466             :  */
     467             : struct TALER_TESTING_Command
     468           4 : TALER_TESTING_cmd_tip_authorize_with_ec
     469             :   (const char *label,
     470             :    const char *merchant_url,
     471             :    const char *exchange_url,
     472             :    struct GNUNET_CURL_Context *ctx,
     473             :    unsigned int http_status,
     474             :    const char *instance,
     475             :    const char *justification,
     476             :    const char *amount,
     477             :    enum TALER_ErrorCode ec)
     478             : {
     479             :   struct TipAuthorizeState *tas;
     480             :   struct TALER_TESTING_Command cmd;
     481             : 
     482           4 :   tas = GNUNET_new (struct TipAuthorizeState);
     483           4 :   tas->merchant_url = merchant_url;
     484           4 :   tas->exchange_url = exchange_url;
     485           4 :   tas->ctx = ctx;
     486           4 :   tas->instance = instance;
     487           4 :   tas->justification = justification;
     488           4 :   tas->amount = amount;
     489           4 :   tas->http_status = http_status;
     490           4 :   tas->expected_ec = ec;
     491             : 
     492           4 :   cmd.label = label;
     493           4 :   cmd.cls = tas;
     494           4 :   cmd.run = &tip_authorize_run;
     495           4 :   cmd.cleanup = &tip_authorize_cleanup;
     496           4 :   cmd.traits = &tip_authorize_traits;
     497             :   
     498           4 :   return cmd;
     499             : }
     500             : 
     501             : 
     502             : 
     503             : /**
     504             :  * Create a /tip-authorize CMD.
     505             :  *
     506             :  * @param label this command label
     507             :  * @param merchant_url the base URL of the merchant that will
     508             :  *        serve the /tip-authorize request.
     509             :  * @param exchange_url the base URL of the exchange that owns
     510             :  *        the reserve from which the tip is going to be gotten.
     511             :  * @param ctx the CURL context to carry on the HTTP work.
     512             :  * @param http_status the HTTP response code which is expected
     513             :  *        for this operation.
     514             :  * @param instance which merchant instance is running this CMD.
     515             :  * @param justification human-readable justification for this
     516             :  *        tip authorization.
     517             :  * @param amount the amount to authorize for tipping.
     518             :  */
     519             : struct TALER_TESTING_Command
     520           2 : TALER_TESTING_cmd_tip_authorize (const char *label,
     521             :                                  const char *merchant_url,
     522             :                                  const char *exchange_url,
     523             :                                  struct GNUNET_CURL_Context *ctx,
     524             :                                  unsigned int http_status,
     525             :                                  const char *instance,
     526             :                                  const char *justification,
     527             :                                  const char *amount)
     528             : {
     529             :   struct TipAuthorizeState *tas;
     530             :   struct TALER_TESTING_Command cmd;
     531             : 
     532           2 :   tas = GNUNET_new (struct TipAuthorizeState);
     533           2 :   tas->merchant_url = merchant_url;
     534           2 :   tas->exchange_url = exchange_url;
     535           2 :   tas->ctx = ctx;
     536           2 :   tas->instance = instance;
     537           2 :   tas->justification = justification;
     538           2 :   tas->amount = amount;
     539           2 :   tas->http_status = http_status;
     540             : 
     541           2 :   cmd.label = label;
     542           2 :   cmd.cls = tas;
     543           2 :   cmd.run = &tip_authorize_run;
     544           2 :   cmd.cleanup = &tip_authorize_cleanup;
     545           2 :   cmd.traits = &tip_authorize_traits;
     546             :   
     547           2 :   return cmd;
     548             : }
     549             : 
     550             : /**
     551             :  * Callback to process a GET /tip-query request, it mainly
     552             :  * checks that what the backend returned matches the command's
     553             :  * expectations.
     554             :  *
     555             :  * @param cls closure
     556             :  * @param http_status HTTP status code for this request
     557             :  * @param ec Taler-specific error code
     558             :  * @param raw raw response body
     559             :  * @param reserve_expiration when the tip reserve will expire
     560             :  * @param reserve_pub tip reserve public key
     561             :  * @param amount_authorized total amount authorized on tip reserve
     562             :  * @param amount_available total amount still available on
     563             :  *        tip reserve
     564             :  * @param amount_picked_up total amount picked up from tip reserve
     565             :  */
     566             : static void
     567           4 : tip_query_cb (void *cls,
     568             :               unsigned int http_status,
     569             :               enum TALER_ErrorCode ec,
     570             :               const json_t *raw,
     571             :               struct GNUNET_TIME_Absolute reserve_expiration,
     572             :               struct TALER_ReservePublicKeyP *reserve_pub,
     573             :               struct TALER_Amount *amount_authorized,
     574             :               struct TALER_Amount *amount_available,
     575             :               struct TALER_Amount *amount_picked_up)
     576             : {
     577           4 :   struct TipQueryState *tqs = cls;
     578             :   struct TALER_Amount a;
     579             : 
     580           4 :   tqs->tqo = NULL;
     581           4 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     582             :               "Tip query callback at command `%s'\n",
     583             :               TALER_TESTING_interpreter_get_current_label
     584             :                 (tqs->is));
     585             : 
     586           4 :   GNUNET_assert (NULL != reserve_pub);
     587           4 :   GNUNET_assert (NULL != amount_authorized);
     588           4 :   GNUNET_assert (NULL != amount_available);
     589           4 :   GNUNET_assert (NULL != amount_picked_up);
     590             : 
     591           4 :   if (tqs->expected_amount_available)
     592             :   {
     593           3 :     GNUNET_assert (GNUNET_OK == TALER_string_to_amount
     594             :       (tqs->expected_amount_available, &a));
     595           3 :     TALER_LOG_INFO ("expected available %s, actual %s\n",
     596             :                     TALER_amount_to_string (&a),
     597             :                     TALER_amount_to_string (amount_available));
     598           3 :     if (0 != TALER_amount_cmp (amount_available, &a))
     599           0 :       TALER_TESTING_FAIL (tqs->is);
     600             :   }
     601             : 
     602           4 :   if (tqs->expected_amount_authorized)
     603             :   {
     604           2 :     GNUNET_assert (GNUNET_OK == TALER_string_to_amount
     605             :       (tqs->expected_amount_authorized, &a));
     606           2 :     TALER_LOG_INFO ("expected authorized %s, actual %s\n",
     607             :                     TALER_amount_to_string (&a),
     608             :                     TALER_amount_to_string (amount_authorized));
     609           2 :     if (0 != TALER_amount_cmp (amount_authorized, &a))
     610           0 :       TALER_TESTING_FAIL (tqs->is);
     611             :   }
     612             : 
     613           4 :   if (tqs->expected_amount_picked_up)
     614             :   {
     615           3 :     GNUNET_assert (GNUNET_OK == TALER_string_to_amount
     616             :       (tqs->expected_amount_picked_up, &a));
     617           3 :     TALER_LOG_INFO ("expected picked_up %s, actual %s\n",
     618             :                     TALER_amount_to_string (&a),
     619             :                     TALER_amount_to_string (amount_picked_up));
     620           3 :     if (0 != TALER_amount_cmp (amount_picked_up, &a))
     621           0 :       TALER_TESTING_FAIL (tqs->is);
     622             :   }
     623             : 
     624           4 :   if (tqs->http_status != http_status)
     625           0 :     TALER_TESTING_FAIL (tqs->is);
     626             : 
     627           4 :   TALER_TESTING_interpreter_next (tqs->is);
     628             : }
     629             : 
     630             : /**
     631             :  * Free the state from a /tip-query CMD, and possibly cancel
     632             :  * a pending /tip-query request.
     633             :  *
     634             :  * @param cls closure.
     635             :  * @param cmd the /tip-query CMD to free.
     636             :  */
     637             : static void
     638           4 : tip_query_cleanup (void *cls,
     639             :                    const struct TALER_TESTING_Command *cmd)
     640             : {
     641           4 :   struct TipQueryState *tqs = cls;
     642             : 
     643           4 :   if (NULL != tqs->tqo)
     644             :   {
     645           0 :     TALER_LOG_WARNING ("Tip-query operation"
     646             :                        " did not complete\n");
     647           0 :     TALER_MERCHANT_tip_query_cancel (tqs->tqo);
     648             :   }
     649           4 :   GNUNET_free (tqs);
     650           4 : }
     651             : 
     652             : /**
     653             :  * Run a /tip-query CMD.
     654             :  *
     655             :  * @param cls closure.
     656             :  * @param cmd the current /tip-query CMD.
     657             :  * @param is the interpreter state.
     658             :  */
     659             : static void
     660           4 : tip_query_run (void *cls,
     661             :                const struct TALER_TESTING_Command *cmd,
     662             :                struct TALER_TESTING_Interpreter *is)
     663             : {
     664           4 :   struct TipQueryState *tqs = cls;
     665             :   
     666           4 :   tqs->is = is;
     667           4 :   tqs->tqo = TALER_MERCHANT_tip_query (tqs->ctx,
     668             :                                        tqs->merchant_url,
     669             :                                        tqs->instance,
     670             :                                        &tip_query_cb,
     671             :                                        tqs);
     672           4 :   GNUNET_assert (NULL != tqs->tqo);
     673           4 : }
     674             : 
     675             : 
     676             : /**
     677             :  * Define a /tip-query CMD equipped with a expected amount.
     678             :  *
     679             :  * @param label the command label
     680             :  * @param merchant_url base URL of the merchant which will
     681             :  *        server the /tip-query request.
     682             :  * @param ctx CURL context to carry on the HTTP work.
     683             :  * @param http_status expected HTTP response code for the
     684             :  *        /tip-query request.
     685             :  * @param instance the merchant instance running this CMD.
     686             :  * @param expected_amount_picked_up expected amount already
     687             :  *        picked up.
     688             :  * @param expected_amount_authorized expected amount that was
     689             :  *        authorized in the first place.
     690             :  * @param expected_amount_available expected amount which is
     691             :  *        still available from the tip reserve
     692             :  * @return the command
     693             :  */
     694             : struct TALER_TESTING_Command
     695           3 : TALER_TESTING_cmd_tip_query_with_amounts
     696             :   (const char *label,
     697             :    const char *merchant_url,
     698             :    struct GNUNET_CURL_Context *ctx,
     699             :    unsigned int http_status,
     700             :    const char *instance,
     701             :    const char *expected_amount_picked_up,
     702             :    const char *expected_amount_authorized,
     703             :    const char *expected_amount_available)
     704             : {
     705             :   struct TipQueryState *tqs;
     706             :   struct TALER_TESTING_Command cmd;
     707             : 
     708           3 :   tqs = GNUNET_new (struct TipQueryState);
     709           3 :   tqs->merchant_url = merchant_url;
     710           3 :   tqs->ctx = ctx;
     711           3 :   tqs->instance = instance;
     712           3 :   tqs->http_status = http_status;
     713           3 :   tqs->expected_amount_picked_up = expected_amount_picked_up;
     714           3 :   tqs->expected_amount_authorized = expected_amount_authorized;
     715           3 :   tqs->expected_amount_available = expected_amount_available;
     716             : 
     717           3 :   cmd.cls = tqs;
     718           3 :   cmd.label = label;
     719           3 :   cmd.run = &tip_query_run;
     720           3 :   cmd.cleanup = &tip_query_cleanup;
     721             :   
     722           3 :   return cmd;
     723             : }
     724             : 
     725             : 
     726             : /**
     727             :  * Define a /tip-query CMD.
     728             :  *
     729             :  * @param label the command label
     730             :  * @param merchant_url base URL of the merchant which will
     731             :  *        server the /tip-query request.
     732             :  * @param ctx CURL context to carry on the HTTP work.
     733             :  * @param http_status expected HTTP response code for the
     734             :  *        /tip-query request.
     735             :  * @param instance the merchant instance running this CMD.
     736             :  */
     737             : struct TALER_TESTING_Command
     738           1 : TALER_TESTING_cmd_tip_query (const char *label,
     739             :                              const char *merchant_url,
     740             :                              struct GNUNET_CURL_Context *ctx,
     741             :                              unsigned int http_status,
     742             :                              const char *instance)
     743             : {
     744             :   struct TipQueryState *tqs;
     745             :   struct TALER_TESTING_Command cmd;
     746             : 
     747           1 :   tqs = GNUNET_new (struct TipQueryState);
     748           1 :   tqs->merchant_url = merchant_url;
     749           1 :   tqs->ctx = ctx;
     750           1 :   tqs->instance = instance;
     751           1 :   tqs->http_status = http_status;
     752             : 
     753           1 :   cmd.cls = tqs;
     754           1 :   cmd.label = label;
     755           1 :   cmd.run = &tip_query_run;
     756           1 :   cmd.cleanup = &tip_query_cleanup;
     757             :   
     758           1 :   return cmd;
     759             : }
     760             : 
     761             : /**
     762             :  * Internal withdraw handle used when withdrawing tips.
     763             :  */
     764             : struct WithdrawHandle
     765             : {
     766             :   /**
     767             :    * Withdraw operation this handle represents.
     768             :    */
     769             :   struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh;
     770             : 
     771             :   /**
     772             :    * Interpreter state.
     773             :    */
     774             :   struct TALER_TESTING_Interpreter *is;
     775             : 
     776             :   /**
     777             :    * Offset of this withdraw operation in the current
     778             :    * @e is command.
     779             :    */
     780             :   unsigned int off;
     781             : 
     782             :   
     783             :   /**
     784             :    * Internal state of the "pickup" CMD.
     785             :    */
     786             :   struct TipPickupState *tps;
     787             : };
     788             : 
     789             : /**
     790             :  * This callback handles the response of a withdraw operation 
     791             :  * from the exchange, that is the final step in getting the tip.
     792             :  *
     793             :  * @param cls closure, a `struct WithdrawHandle *`
     794             :  * @param http_status HTTP response code, #MHD_HTTP_OK (200)
     795             :  *        for successful status request, 0 if the exchange's
     796             :  *        reply is bogus (fails to follow the protocol)
     797             :  * @param ec taler-specific error code, #TALER_EC_NONE on success
     798             :  * @param sig signature over the coin, NULL on error
     799             :  * @param full_response full response from the exchange
     800             :  *        (for logging, in case of errors)
     801             :  */
     802             : static void
     803           2 : pickup_withdraw_cb (void *cls,
     804             :                     unsigned int http_status,
     805             :                     enum TALER_ErrorCode ec,
     806             :                     const struct TALER_DenominationSignature *sig,
     807             :                     const json_t *full_response)
     808             : {
     809           2 :   struct WithdrawHandle *wh = cls;
     810           2 :   struct TALER_TESTING_Interpreter *is = wh->is;
     811             : 
     812           2 :   struct TipPickupState *tps = wh->tps;
     813             : 
     814           2 :   wh->wsh = NULL;
     815           2 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     816             :               "Withdraw operation %u completed with %u (%d)\n",
     817             :               wh->off,
     818             :               http_status,
     819             :               ec);
     820           2 :   GNUNET_assert (wh->off < tps->num_coins);
     821           2 :   if ( (MHD_HTTP_OK != http_status) ||
     822             :        (TALER_EC_NONE != ec) )
     823             :   {
     824           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     825             :                 "Unexpected response code %u (%d)"
     826             :                 " to command %s when withdrawing\n",
     827             :                 http_status,
     828             :                 ec,
     829             :                 TALER_TESTING_interpreter_get_current_label (is));
     830           0 :     TALER_TESTING_interpreter_fail (is);
     831           0 :     return;
     832             :   }
     833           2 :   if (NULL == tps->sigs)
     834           2 :     tps->sigs = GNUNET_new_array
     835             :       (tps->num_coins, struct TALER_DenominationSignature);
     836             : 
     837           2 :   GNUNET_assert (NULL == tps->sigs[wh->off].rsa_signature);
     838           2 :   tps->sigs[wh->off].rsa_signature
     839           2 :     = GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
     840             : 
     841           4 :   for (unsigned int i=0; i<tps->num_coins; i++)
     842           2 :     if (NULL != tps->withdraws[wh->off].wsh)
     843           0 :       return; /* still some ops ongoing */
     844             : 
     845           2 :   GNUNET_free (tps->withdraws);
     846           2 :   tps->withdraws = NULL;
     847           2 :   TALER_TESTING_interpreter_next (is);
     848             : }
     849             : 
     850             : 
     851             : /**
     852             :  * Callback for a /tip-pickup request, it mainly checks if
     853             :  * values returned from the backend are as expected, and if so
     854             :  * (and if the status was 200 OK) proceede with the withdrawal.
     855             :  *
     856             :  * @param cls closure
     857             :  * @param http_status HTTP status returned by the merchant
     858             :  *        backend, "200 OK" on success
     859             :  * @param ec taler-specific error code
     860             :  * @param reserve_pub public key of the reserve that made the
     861             :  *        @a reserve_sigs, NULL on error
     862             :  * @param num_reserve_sigs length of the @a reserve_sigs array,
     863             :  *        0 on error
     864             :  * @param reserve_sigs array of signatures authorizing withdrawals,
     865             :  *        NULL on error
     866             :  * @param json original json response
     867             :  */
     868             : static void
     869           4 : pickup_cb (void *cls,
     870             :            unsigned int http_status,
     871             :            enum TALER_ErrorCode ec,
     872             :            const struct TALER_ReservePublicKeyP *reserve_pub,
     873             :            unsigned int num_reserve_sigs,
     874             :            const struct TALER_ReserveSignatureP *reserve_sigs,
     875             :            const json_t *json)
     876             : {
     877           4 :   struct TipPickupState *tps = cls;
     878             : 
     879           4 :   tps->tpo = NULL;
     880           4 :   if (http_status != tps->http_status)
     881             :   {
     882           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     883             :                 "Unexpected response code %u (%d) to command %s\n",
     884             :                 http_status,
     885             :                 ec,
     886             :                 TALER_TESTING_interpreter_get_current_label
     887             :                   (tps->is));
     888           0 :     TALER_TESTING_FAIL (tps->is);
     889             :   }
     890             : 
     891           4 :   if (ec != tps->expected_ec)
     892           0 :     TALER_TESTING_FAIL (tps->is);
     893             : 
     894             :   /* Safe to go ahead: http status was expected.  */
     895           4 :   if ( (MHD_HTTP_OK != http_status) ||
     896             :        (TALER_EC_NONE != ec) )
     897             :   {
     898           2 :     TALER_TESTING_interpreter_next (tps->is);
     899           2 :     return;
     900             :   }
     901           2 :   if (num_reserve_sigs != tps->num_coins)
     902           0 :     TALER_TESTING_FAIL (tps->is);
     903             : 
     904             :   /* pickup successful, now withdraw! */
     905           2 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     906             :               "Obtained %u signatures for withdrawal"
     907             :               " from picking up a tip\n",
     908             :               num_reserve_sigs);
     909             : 
     910           2 :   GNUNET_assert (NULL == tps->withdraws);
     911           2 :   tps->withdraws = GNUNET_new_array
     912             :     (num_reserve_sigs, struct WithdrawHandle);
     913             : 
     914           4 :   for (unsigned int i=0;i<num_reserve_sigs;i++)
     915             :   {
     916           2 :     struct WithdrawHandle *wh = &tps->withdraws[i];
     917             : 
     918           2 :     wh->off = i;
     919           2 :     wh->is = tps->is;
     920           2 :     wh->tps = tps;
     921           2 :     GNUNET_assert
     922             :       ( (NULL == wh->wsh) &&
     923             :         ( (NULL == tps->sigs) ||
     924             :           (NULL == tps->sigs[wh->off].rsa_signature) ) );
     925           4 :     wh->wsh = TALER_EXCHANGE_reserve_withdraw2
     926             :       (tps->exchange,
     927           2 :        tps->dks[i],
     928           2 :        &reserve_sigs[i],
     929             :        reserve_pub,
     930           2 :        &tps->psa[i],
     931             :        &pickup_withdraw_cb,
     932             :        wh);
     933           2 :   if (NULL == wh->wsh)
     934           0 :     TALER_TESTING_FAIL (tps->is);
     935             :   }
     936           2 :   if (0 == num_reserve_sigs)
     937           0 :     TALER_TESTING_interpreter_next (tps->is);
     938             : }
     939             : 
     940             : 
     941             : /**
     942             :  * Run a /tip-pickup CMD.
     943             :  *
     944             :  * @param cls closure
     945             :  * @param cmd the current /tip-pickup CMD.
     946             :  * @param is interpreter state.
     947             :  */
     948             : static void
     949           4 : tip_pickup_run (void *cls,
     950             :                 const struct TALER_TESTING_Command *cmd,
     951             :                 struct TALER_TESTING_Interpreter *is)
     952             : {
     953             : 
     954           4 :   struct TipPickupState *tps = cls;
     955             :   unsigned int num_planchets;
     956             :   const struct TALER_TESTING_Command *replay_cmd;
     957             :   const struct TALER_TESTING_Command *authorize_cmd;
     958             :   const struct GNUNET_HashCode *tip_id;
     959             : 
     960           4 :   tps->is = is;
     961           4 :   tps->exchange_url = MAH_path_to_url (tps->exchange, "/");
     962           4 :   if (NULL == tps->replay_reference)
     963             :   {
     964           4 :     replay_cmd = NULL;
     965             : 
     966             :     /* Count planchets. */
     967          12 :     for (num_planchets=0;
     968           8 :          NULL != tps->amounts[num_planchets];
     969           4 :          num_planchets++);
     970             :   }
     971             :   else
     972             :   {
     973             :     unsigned int *np;
     974           0 :     if ( NULL == /* looking for "parent" tip-pickup command */
     975           0 :        ( replay_cmd = TALER_TESTING_interpreter_lookup_command
     976             :          (is, tps->replay_reference)) )
     977           0 :     TALER_TESTING_FAIL (is);   
     978             :     
     979           0 :     if (GNUNET_OK != TALER_TESTING_get_trait_uint
     980             :         (replay_cmd, 0, &np))
     981           0 :       TALER_TESTING_FAIL (is);
     982           0 :     num_planchets = *np;
     983             :   }
     984             : 
     985           4 :   if (NULL ==
     986           4 :      ( authorize_cmd = TALER_TESTING_interpreter_lookup_command
     987             :        (is, tps->authorize_reference)) )
     988           0 :     TALER_TESTING_FAIL (is);
     989             : 
     990           4 :   tps->num_coins = num_planchets;
     991           4 :   {
     992           4 :     struct TALER_PlanchetDetail planchets[num_planchets];
     993             : 
     994           4 :     tps->psa = GNUNET_new_array (num_planchets,
     995             :                                  struct TALER_PlanchetSecretsP);
     996           4 :     tps->dks = GNUNET_new_array
     997             :       (num_planchets,
     998             :        const struct TALER_EXCHANGE_DenomPublicKey *);
     999             : 
    1000           4 :     tps->amounts_obj = GNUNET_new_array
    1001             :       (num_planchets, struct TALER_Amount);
    1002             : 
    1003           8 :     for (unsigned int i=0;i<num_planchets;i++)
    1004             :     {
    1005           4 :       if (NULL == replay_cmd)
    1006             :       {
    1007           4 :         GNUNET_assert (GNUNET_OK == TALER_string_to_amount
    1008             :           (tps->amounts[i], &tps->amounts_obj[i]));
    1009             : 
    1010           8 :         tps->dks[i] = TALER_TESTING_find_pk
    1011             :           (is->keys,
    1012           4 :            &tps->amounts_obj[i]);
    1013             : 
    1014           4 :         if (NULL == tps->dks[i])
    1015           0 :           TALER_TESTING_FAIL (is);
    1016             : 
    1017           4 :         TALER_planchet_setup_random (&tps->psa[i]); 
    1018             :       }
    1019             :       else
    1020             :       {
    1021           0 :         if (GNUNET_OK != TALER_TESTING_get_trait_denom_pub
    1022           0 :             (replay_cmd, i, &tps->dks[i]))
    1023           0 :           TALER_TESTING_FAIL (is);
    1024             : 
    1025             :         struct TALER_PlanchetSecretsP *ps;
    1026             : 
    1027           0 :         if (GNUNET_OK != TALER_TESTING_get_trait_planchet_secrets
    1028             :             (replay_cmd, i, &ps))
    1029           0 :           TALER_TESTING_FAIL (is);
    1030           0 :         tps->psa[i] = *ps;
    1031             :       }
    1032             : 
    1033           8 :       if (GNUNET_OK != TALER_planchet_prepare (&tps->dks[i]->key,
    1034           4 :                                                &tps->psa[i],
    1035             :                                                &planchets[i]))
    1036           0 :         TALER_TESTING_FAIL (is); 
    1037             :     }
    1038             :     
    1039           4 :     if (GNUNET_OK != TALER_TESTING_get_trait_tip_id
    1040             :       (authorize_cmd, 0, &tip_id))
    1041           0 :       TALER_TESTING_FAIL (is);
    1042             : 
    1043           4 :     tps->tpo = TALER_MERCHANT_tip_pickup (tps->ctx,
    1044             :                                           tps->merchant_url,
    1045             :                                           tip_id,
    1046             :                                           num_planchets,
    1047             :                                           planchets,
    1048             :                                           &pickup_cb,
    1049             :                                           tps);
    1050           4 :     GNUNET_assert (NULL != tps->tpo);
    1051             :   }
    1052             : }
    1053             : 
    1054             : /**
    1055             :  * Free a /tip-pickup CMD state, and possibly cancel a
    1056             :  * pending /tip-pickup request.
    1057             :  *
    1058             :  * @param cls closure.
    1059             :  * @param cmd current CMD to be freed.
    1060             :  */
    1061             : static void
    1062           4 : tip_pickup_cleanup (void *cls,
    1063             :                     const struct TALER_TESTING_Command *cmd)
    1064             : {
    1065           4 :   struct TipPickupState *tps = cls;
    1066             : 
    1067           4 :   GNUNET_free_non_null (tps->amounts_obj);
    1068           4 :   GNUNET_free_non_null (tps->dks);
    1069           4 :   GNUNET_free_non_null (tps->psa);
    1070           4 :   GNUNET_free_non_null (tps->withdraws);
    1071           4 :   GNUNET_free_non_null (tps->sigs);
    1072             : 
    1073           4 :   if (NULL != tps->tpo)
    1074             :   {
    1075           0 :     TALER_LOG_WARNING ("Tip-pickup operation"
    1076             :                        " did not complete\n");
    1077           0 :     TALER_MERCHANT_tip_pickup_cancel (tps->tpo);
    1078             :   }
    1079             : 
    1080           4 :   GNUNET_free (tps);
    1081           4 : }
    1082             : 
    1083             : 
    1084             : /**
    1085             :  * Offers information from the /tip-pickup CMD state to other
    1086             :  * commands.
    1087             :  *
    1088             :  * @param cls closure
    1089             :  * @param ret[out] result (could be anything)
    1090             :  * @param trait name of the trait
    1091             :  * @param index index number of the object to extract.
    1092             :  * @return #GNUNET_OK on success
    1093             :  */
    1094             : static int
    1095           5 : tip_pickup_traits (void *cls,
    1096             :                    void **ret,
    1097             :                    const char *trait,
    1098             :                    unsigned int index)
    1099           5 : {
    1100           5 :   struct TipPickupState *tps = cls;
    1101             :   #define NUM_TRAITS (tps->num_coins * 5) + 2
    1102           5 :   struct TALER_TESTING_Trait traits[NUM_TRAITS];
    1103             :   
    1104          10 :   for (unsigned int i=0; i<tps->num_coins; i++)
    1105             :   {
    1106           5 :     traits[i] = TALER_TESTING_make_trait_planchet_secrets
    1107           5 :       (i, &tps->psa[i]);
    1108             : 
    1109          10 :     traits[i + tps->num_coins] =
    1110             :       TALER_TESTING_make_trait_coin_priv
    1111           5 :         (i, &tps->psa[i].coin_priv);
    1112             : 
    1113          10 :     traits[i + (tps->num_coins * 2)] =
    1114           5 :       TALER_TESTING_make_trait_denom_pub (i, tps->dks[i]);
    1115             : 
    1116          10 :     traits[i + (tps->num_coins *3)] =
    1117           5 :       TALER_TESTING_make_trait_denom_sig (i, &tps->sigs[i]);
    1118             : 
    1119          10 :     traits[i + (tps->num_coins *4)] =
    1120             :       TALER_TESTING_make_trait_amount_obj
    1121           5 :         (i, &tps->amounts_obj[i]);
    1122             : 
    1123             :   }
    1124           5 :   traits[NUM_TRAITS - 2] = TALER_TESTING_make_trait_url
    1125             :     (0, tps->exchange_url);
    1126           5 :   traits[NUM_TRAITS - 1] = TALER_TESTING_trait_end ();
    1127             : 
    1128           5 :   return TALER_TESTING_get_trait (traits,
    1129             :                                   ret,
    1130             :                                   trait,
    1131             :                                   index);
    1132             :   return GNUNET_SYSERR;
    1133             : }
    1134             : 
    1135             : /**
    1136             :  * Define a /tip-pickup CMD, equipped with the expected error
    1137             :  * code.
    1138             :  *
    1139             :  * @param label the command label
    1140             :  * @param merchant_url base URL of the backend which will serve
    1141             :  *        the /tip-pickup request.
    1142             :  * @param ctx CURL context to carry on HTTP work.
    1143             :  * @param http_status expected HTTP response code.
    1144             :  * @param authorize_reference reference to a /tip-autorize CMD
    1145             :  *        that offers a tip id to pick up.
    1146             :  * @param amounts array of string-defined amounts that specifies
    1147             :  *        which denominations will be accepted for tipping.
    1148             :  * @param exchange connection handle to the exchange that will
    1149             :  *        eventually serve the withdraw operation.
    1150             :  * @param ec expected Taler error code.
    1151             :  */
    1152             : struct TALER_TESTING_Command
    1153           2 : TALER_TESTING_cmd_tip_pickup_with_ec
    1154             :   (const char *label,
    1155             :    const char *merchant_url,
    1156             :    struct GNUNET_CURL_Context *ctx,
    1157             :    unsigned int http_status,
    1158             :    const char *authorize_reference,
    1159             :    const char **amounts,
    1160             :    struct TALER_EXCHANGE_Handle *exchange,
    1161             :    enum TALER_ErrorCode ec)
    1162             : {
    1163             :   struct TipPickupState *tps;
    1164             :   struct TALER_TESTING_Command cmd;
    1165             : 
    1166           2 :   tps = GNUNET_new (struct TipPickupState);
    1167           2 :   tps->merchant_url = merchant_url;
    1168           2 :   tps->ctx = ctx;
    1169           2 :   tps->authorize_reference = authorize_reference;
    1170           2 :   tps->amounts = amounts;
    1171           2 :   tps->exchange = exchange;
    1172           2 :   tps->http_status = http_status;
    1173           2 :   tps->expected_ec = ec;
    1174             : 
    1175           2 :   cmd.cls = tps;
    1176           2 :   cmd.label = label;
    1177           2 :   cmd.run = &tip_pickup_run;
    1178           2 :   cmd.cleanup = &tip_pickup_cleanup;
    1179           2 :   cmd.traits = &tip_pickup_traits;
    1180             :   
    1181           2 :   return cmd;
    1182             : }
    1183             : 
    1184             : /**
    1185             :  * Define a /tip-pickup CMD.
    1186             :  *
    1187             :  * @param label the command label
    1188             :  * @param merchant_url base URL of the backend which will serve
    1189             :  *        the /tip-pickup request.
    1190             :  * @param ctx CURL context to carry on HTTP work.
    1191             :  * @param http_status expected HTTP response code.
    1192             :  * @param authorize_reference reference to a /tip-autorize CMD
    1193             :  *        that offers a tip id to pick up.
    1194             :  * @param amounts array of string-defined amounts that specifies
    1195             :  *        which denominations will be accepted for tipping.
    1196             :  * @param exchange connection handle to the exchange that will
    1197             :  *        eventually serve the withdraw operation.
    1198             :  */
    1199             : struct TALER_TESTING_Command
    1200           2 : TALER_TESTING_cmd_tip_pickup
    1201             :   (const char *label,
    1202             :    const char *merchant_url,
    1203             :    struct GNUNET_CURL_Context *ctx,
    1204             :    unsigned int http_status,
    1205             :    const char *authorize_reference,
    1206             :    const char **amounts,
    1207             :    struct TALER_EXCHANGE_Handle *exchange)
    1208             : {
    1209             :   struct TipPickupState *tps;
    1210             :   struct TALER_TESTING_Command cmd;
    1211             : 
    1212           2 :   tps = GNUNET_new (struct TipPickupState);
    1213           2 :   tps->merchant_url = merchant_url;
    1214           2 :   tps->ctx = ctx;
    1215           2 :   tps->authorize_reference = authorize_reference;
    1216           2 :   tps->amounts = amounts;
    1217           2 :   tps->exchange = exchange;
    1218           2 :   tps->http_status = http_status;
    1219             : 
    1220           2 :   cmd.cls = tps;
    1221           2 :   cmd.label = label;
    1222           2 :   cmd.run = &tip_pickup_run;
    1223           2 :   cmd.cleanup = &tip_pickup_cleanup;
    1224           2 :   cmd.traits = &tip_pickup_traits;
    1225             :   
    1226           2 :   return cmd;
    1227             : }
    1228             : 
    1229             : /**
    1230             :  * This commands does not query the backend at all,
    1231             :  * but just makes up a fake authorization id that will
    1232             :  * be subsequently used by the "pick up" CMD in order
    1233             :  * to test against such a case.
    1234             :  *
    1235             :  * @param label command label.
    1236             :  *
    1237             :  * @return the command.
    1238             :  */
    1239             : struct TALER_TESTING_Command
    1240           1 : TALER_TESTING_cmd_tip_authorize_fake (const char *label)
    1241             : {
    1242             :   struct TipAuthorizeState *tas;
    1243             :   struct TALER_TESTING_Command cmd;
    1244             : 
    1245           1 :   tas = GNUNET_new (struct TipAuthorizeState);
    1246             : 
    1247           1 :   cmd.label = label;
    1248           1 :   cmd.cls = tas;
    1249           1 :   cmd.run = &tip_authorize_fake_run;
    1250           1 :   cmd.cleanup = &tip_authorize_cleanup;
    1251           1 :   cmd.traits = &tip_authorize_traits;
    1252             :   
    1253           1 :   return cmd;
    1254             : }
    1255             : 
    1256             : /* end of testing_api_cmd_tip.c */

Generated by: LCOV version 1.13