exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_wire.c (6308B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2018, 2023 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it
      6   under the terms of the GNU General Public License as published by
      7   the Free Software Foundation; either version 3, or (at your
      8   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 GNU
     13   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  * @file testing/testing_api_cmd_wire.c
     21  * @brief command for testing /wire.
     22  * @author Marcello Stanisci
     23  */
     24 #include "taler/taler_json_lib.h"
     25 #include <gnunet/gnunet_curl_lib.h>
     26 #include "taler/taler_testing_lib.h"
     27 
     28 
     29 /**
     30  * State for a "wire" CMD.
     31  */
     32 struct WireState
     33 {
     34 
     35   /**
     36    * Handle to the /wire operation.
     37    */
     38   struct TALER_EXCHANGE_WireHandle *wh;
     39 
     40   /**
     41    * Our command.
     42    */
     43   const struct TALER_TESTING_Command *cmd;
     44 
     45   /**
     46    * Which wire-method we expect is offered by the exchange.
     47    */
     48   const char *expected_method;
     49 
     50   /**
     51    * Flag indicating if the expected method is actually
     52    * offered.
     53    */
     54   unsigned int method_found;
     55 
     56   /**
     57    * Fee we expect is charged for this wire-transfer method.
     58    */
     59   const char *expected_fee;
     60 
     61   /**
     62    * Expected HTTP response code.
     63    */
     64   unsigned int expected_response_code;
     65 
     66   /**
     67    * Interpreter state.
     68    */
     69   struct TALER_TESTING_Interpreter *is;
     70 };
     71 
     72 
     73 /**
     74  * Check whether the HTTP response code is acceptable, that
     75  * the expected wire method is offered by the exchange, and
     76  * that the wire fee is acceptable too.
     77  *
     78  * @param cls closure.
     79  * @param wr response details
     80  */
     81 static void
     82 wire_cb (void *cls,
     83          const struct TALER_EXCHANGE_WireResponse *wr)
     84 {
     85   struct WireState *ws = cls;
     86   const struct TALER_EXCHANGE_HttpResponse *hr = &wr->hr;
     87   struct TALER_Amount expected_fee;
     88 
     89   TALER_LOG_DEBUG ("Checking parsed /wire response\n");
     90   ws->wh = NULL;
     91   if (ws->expected_response_code != hr->http_status)
     92   {
     93     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     94                 "Received unexpected status code %u\n",
     95                 hr->http_status);
     96     TALER_TESTING_interpreter_fail (ws->is);
     97     return;
     98   }
     99 
    100   if (MHD_HTTP_OK == hr->http_status)
    101   {
    102     unsigned int accounts_len
    103       = wr->details.ok.accounts_len;
    104     unsigned int fees_len
    105       = wr->details.ok.fees_len;
    106     const struct TALER_EXCHANGE_WireAccount *accounts
    107       = wr->details.ok.accounts;
    108     const struct TALER_EXCHANGE_WireFeesByMethod *fees
    109       = wr->details.ok.fees;
    110 
    111     for (unsigned int i = 0; i<accounts_len; i++)
    112     {
    113       char *method;
    114 
    115       method = TALER_payto_get_method (accounts[i].payto_uri);
    116       if (NULL == method)
    117       {
    118         GNUNET_break (0);
    119         TALER_TESTING_interpreter_fail (ws->is);
    120         return;
    121       }
    122       if (0 == strcmp (ws->expected_method,
    123                        method))
    124       {
    125         ws->method_found = GNUNET_OK;
    126       }
    127       GNUNET_free (method);
    128     }
    129     if (NULL != ws->expected_fee)
    130     {
    131       bool fee_found = false;
    132 
    133       GNUNET_assert (GNUNET_OK ==
    134                      TALER_string_to_amount (ws->expected_fee,
    135                                              &expected_fee));
    136       for (unsigned int i = 0; i<fees_len; i++)
    137       {
    138         if (0 != strcmp (fees[i].method,
    139                          ws->expected_method))
    140           continue;
    141         for (const struct TALER_EXCHANGE_WireAggregateFees *waf
    142                = fees[i].fees_head;
    143              NULL != waf;
    144              waf = waf->next)
    145         {
    146           if (0 != TALER_amount_cmp (&waf->fees.wire,
    147                                      &expected_fee))
    148           {
    149             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    150                         "Wire fee mismatch to command %s\n",
    151                         ws->cmd->label);
    152             TALER_TESTING_interpreter_fail (ws->is);
    153             return;
    154           }
    155           fee_found = true;
    156         }
    157       }
    158       if (! fee_found)
    159       {
    160         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    161                     "/wire does not contain expected fee '%s'\n",
    162                     ws->expected_fee);
    163         TALER_TESTING_interpreter_fail (ws->is);
    164         return;
    165       }
    166     }
    167     if (GNUNET_OK != ws->method_found)
    168     {
    169       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    170                   "/wire does not offer method '%s'\n",
    171                   ws->expected_method);
    172       TALER_TESTING_interpreter_fail (ws->is);
    173       return;
    174     }
    175   }
    176   TALER_TESTING_interpreter_next (ws->is);
    177 }
    178 
    179 
    180 /**
    181  * Run the command.
    182  *
    183  * @param cls closure.
    184  * @param cmd the command to execute.
    185  * @param is the interpreter state.
    186  */
    187 static void
    188 wire_run (void *cls,
    189           const struct TALER_TESTING_Command *cmd,
    190           struct TALER_TESTING_Interpreter *is)
    191 {
    192   struct WireState *ws = cls;
    193 
    194   ws->cmd = cmd;
    195   ws->is = is;
    196   ws->wh = TALER_EXCHANGE_wire (
    197     TALER_TESTING_interpreter_get_context (is),
    198     TALER_TESTING_get_exchange_url (is),
    199     TALER_TESTING_get_keys (is),
    200     &wire_cb,
    201     ws);
    202 }
    203 
    204 
    205 /**
    206  * Cleanup the state of a "wire" CMD, and possibly cancel a
    207  * pending operation thereof.
    208  *
    209  * @param cls closure.
    210  * @param cmd the command which is being cleaned up.
    211  */
    212 static void
    213 wire_cleanup (void *cls,
    214               const struct TALER_TESTING_Command *cmd)
    215 {
    216   struct WireState *ws = cls;
    217 
    218   if (NULL != ws->wh)
    219   {
    220     TALER_TESTING_command_incomplete (ws->is,
    221                                       cmd->label);
    222     TALER_EXCHANGE_wire_cancel (ws->wh);
    223     ws->wh = NULL;
    224   }
    225   GNUNET_free (ws);
    226 }
    227 
    228 
    229 struct TALER_TESTING_Command
    230 TALER_TESTING_cmd_wire (const char *label,
    231                         const char *expected_method,
    232                         const char *expected_fee,
    233                         unsigned int expected_response_code)
    234 {
    235   struct WireState *ws;
    236 
    237   ws = GNUNET_new (struct WireState);
    238   ws->expected_method = expected_method;
    239   ws->expected_fee = expected_fee;
    240   ws->expected_response_code = expected_response_code;
    241   {
    242     struct TALER_TESTING_Command cmd = {
    243       .cls = ws,
    244       .label = label,
    245       .run = &wire_run,
    246       .cleanup = &wire_cleanup
    247     };
    248 
    249     return cmd;
    250   }
    251 }