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_transfer_get.c (11571B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2020, 2024 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 testing/testing_api_cmd_transfer_get.c
     22  * @brief Implement the testing CMDs for the /transfer GET operation.
     23  * @author Marcello Stanisci
     24  */
     25 #include "taler/taler_json_lib.h"
     26 #include <gnunet/gnunet_curl_lib.h>
     27 struct TrackTransferState;
     28 #define TALER_EXCHANGE_GET_TRANSFERS_RESULT_CLOSURE struct TrackTransferState
     29 #include "taler/exchange/get-transfers-WTID.h"
     30 #include "taler/taler_testing_lib.h"
     31 
     32 /**
     33  * State for a "track transfer" CMD.
     34  */
     35 struct TrackTransferState
     36 {
     37 
     38   /**
     39    * Expected amount for the WTID being tracked.
     40    */
     41   const char *expected_total_amount;
     42 
     43   /**
     44    * Expected fee for this WTID.
     45    */
     46   const char *expected_wire_fee;
     47 
     48   /**
     49    * Our command.
     50    */
     51   const struct TALER_TESTING_Command *cmd;
     52 
     53   /**
     54    * Reference to any operation that can provide a WTID.
     55    * Will be the WTID to track.
     56    */
     57   const char *wtid_reference;
     58 
     59   /**
     60    * Reference to any operation that can provide wire details.
     61    * Those wire details will then be matched against the credit
     62    * bank account of the tracked WTID.  This way we can test that
     63    * a wire transfer paid back one particular bank account.
     64    */
     65   const char *wire_details_reference;
     66 
     67   /**
     68    * Reference to any operation that can provide an amount.
     69    * This way we can check that the transferred amount matches
     70    * our expectations.
     71    */
     72   const char *total_amount_reference;
     73 
     74   /**
     75    * Handle to a pending "track transfer" operation.
     76    */
     77   struct TALER_EXCHANGE_GetTransfersHandle *tth;
     78 
     79   /**
     80    * Interpreter state.
     81    */
     82   struct TALER_TESTING_Interpreter *is;
     83 
     84   /**
     85    * Expected HTTP response code.
     86    */
     87   unsigned int expected_response_code;
     88 
     89 };
     90 
     91 
     92 /**
     93  * Cleanup the state for a "track transfer" CMD, and possibly
     94  * cancel a pending operation thereof.
     95  *
     96  * @param cls closure.
     97  * @param cmd the command which is being cleaned up.
     98  */
     99 static void
    100 track_transfer_cleanup (
    101   void *cls,
    102   const struct TALER_TESTING_Command *cmd)
    103 {
    104   struct TrackTransferState *tts = cls;
    105 
    106   if (NULL != tts->tth)
    107   {
    108     TALER_TESTING_command_incomplete (tts->is,
    109                                       cmd->label);
    110     TALER_EXCHANGE_get_transfers_cancel (tts->tth);
    111     tts->tth = NULL;
    112   }
    113   GNUNET_free (tts);
    114 }
    115 
    116 
    117 /**
    118  * Check whether the HTTP response code from a "track transfer"
    119  * operation is acceptable, and all other values like total amount,
    120  * wire fees and hashed wire details as well.
    121  *
    122  * @param tts closure.
    123  * @param tgr response details
    124  */
    125 static void
    126 track_transfer_cb (
    127   struct TrackTransferState *tts,
    128   const struct TALER_EXCHANGE_GetTransfersResponse *tgr)
    129 {
    130   const struct TALER_EXCHANGE_HttpResponse *hr = &tgr->hr;
    131   struct TALER_TESTING_Interpreter *is = tts->is;
    132   struct TALER_Amount expected_amount;
    133 
    134   tts->tth = NULL;
    135   if (tts->expected_response_code != hr->http_status)
    136   {
    137     TALER_TESTING_unexpected_status (is,
    138                                      hr->http_status,
    139                                      tts->expected_response_code);
    140     return;
    141   }
    142 
    143   switch (hr->http_status)
    144   {
    145   case MHD_HTTP_OK:
    146     {
    147       const struct TALER_EXCHANGE_TransferData *ta
    148         = &tgr->details.ok.td;
    149 
    150       if (NULL == tts->expected_total_amount)
    151       {
    152         GNUNET_break (0);
    153         TALER_TESTING_interpreter_fail (is);
    154         return;
    155       }
    156       if (NULL == tts->expected_wire_fee)
    157       {
    158         GNUNET_break (0);
    159         TALER_TESTING_interpreter_fail (is);
    160         return;
    161       }
    162 
    163       if (GNUNET_OK !=
    164           TALER_string_to_amount (tts->expected_total_amount,
    165                                   &expected_amount))
    166       {
    167         GNUNET_break (0);
    168         TALER_TESTING_interpreter_fail (is);
    169         return;
    170       }
    171       if (0 != TALER_amount_cmp (&ta->total_amount,
    172                                  &expected_amount))
    173       {
    174         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    175                     "Total amount mismatch to command %s - "
    176                     "%s vs %s\n",
    177                     tts->cmd->label,
    178                     TALER_amount_to_string (&ta->total_amount),
    179                     TALER_amount_to_string (&expected_amount));
    180         json_dumpf (hr->reply,
    181                     stderr,
    182                     0);
    183         fprintf (stderr, "\n");
    184         TALER_TESTING_interpreter_fail (is);
    185         return;
    186       }
    187 
    188       if (GNUNET_OK !=
    189           TALER_string_to_amount (tts->expected_wire_fee,
    190                                   &expected_amount))
    191       {
    192         GNUNET_break (0);
    193         TALER_TESTING_interpreter_fail (is);
    194         return;
    195       }
    196 
    197       if (0 != TALER_amount_cmp (&ta->wire_fee,
    198                                  &expected_amount))
    199       {
    200         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    201                     "Wire fee mismatch to command %s\n",
    202                     tts->cmd->label);
    203         json_dumpf (hr->reply,
    204                     stderr,
    205                     0);
    206         TALER_TESTING_interpreter_fail (is);
    207         return;
    208       }
    209 
    210       /**
    211        * Optionally checking: (1) wire-details for this transfer
    212        * match the ones from a referenced "deposit" operation -
    213        * or any operation that could provide wire-details.  (2)
    214        * Total amount for this transfer matches the one from any
    215        * referenced command that could provide one.
    216        */
    217       if (NULL != tts->wire_details_reference)
    218       {
    219         const struct TALER_TESTING_Command *wire_details_cmd;
    220         const struct TALER_FullPayto *payto_uri;
    221         struct TALER_FullPaytoHashP h_payto;
    222 
    223         wire_details_cmd
    224           = TALER_TESTING_interpreter_lookup_command (
    225               is,
    226               tts->wire_details_reference);
    227         if (NULL == wire_details_cmd)
    228         {
    229           GNUNET_break (0);
    230           TALER_TESTING_interpreter_fail (is);
    231           return;
    232         }
    233         if (GNUNET_OK !=
    234             TALER_TESTING_get_trait_full_payto_uri (wire_details_cmd,
    235                                                     &payto_uri))
    236         {
    237           GNUNET_break (0);
    238           TALER_TESTING_interpreter_fail (is);
    239           return;
    240         }
    241         TALER_full_payto_hash (*payto_uri,
    242                                &h_payto);
    243         if (0 != GNUNET_memcmp (&h_payto,
    244                                 &ta->h_payto))
    245         {
    246           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    247                       "Wire hash missmath to command %s\n",
    248                       tts->cmd->label);
    249           json_dumpf (hr->reply,
    250                       stderr,
    251                       0);
    252           TALER_TESTING_interpreter_fail (is);
    253           return;
    254         }
    255       }
    256       if (NULL != tts->total_amount_reference)
    257       {
    258         const struct TALER_TESTING_Command *total_amount_cmd;
    259         const struct TALER_Amount *total_amount_from_reference;
    260 
    261         total_amount_cmd
    262           = TALER_TESTING_interpreter_lookup_command (is,
    263                                                       tts->
    264                                                       total_amount_reference);
    265         if (NULL == total_amount_cmd)
    266         {
    267           GNUNET_break (0);
    268           TALER_TESTING_interpreter_fail (is);
    269           return;
    270         }
    271         if (GNUNET_OK !=
    272             TALER_TESTING_get_trait_amount (total_amount_cmd,
    273                                             &total_amount_from_reference))
    274         {
    275           GNUNET_break (0);
    276           TALER_TESTING_interpreter_fail (is);
    277           return;
    278         }
    279         if (0 != TALER_amount_cmp (&ta->total_amount,
    280                                    total_amount_from_reference))
    281         {
    282           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    283                       "Amount mismatch in command %s\n",
    284                       tts->cmd->label);
    285           json_dumpf (hr->reply,
    286                       stderr,
    287                       0);
    288           TALER_TESTING_interpreter_fail (is);
    289           return;
    290         }
    291       }
    292       break;
    293     } /* case OK */
    294   } /* switch on status */
    295   TALER_TESTING_interpreter_next (is);
    296 }
    297 
    298 
    299 /**
    300  * Run the command.
    301  *
    302  * @param cls closure.
    303  * @param cmd the command under execution.
    304  * @param is the interpreter state.
    305  */
    306 static void
    307 track_transfer_run (
    308   void *cls,
    309   const struct TALER_TESTING_Command *cmd,
    310   struct TALER_TESTING_Interpreter *is)
    311 {
    312   /* looking for a wtid to track .. */
    313   struct TrackTransferState *tts = cls;
    314   struct TALER_WireTransferIdentifierRawP wtid;
    315   const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
    316 
    317   tts->cmd = cmd;
    318   /* If no reference is given, we'll use a all-zeros
    319    * WTID */
    320   memset (&wtid,
    321           0,
    322           sizeof (wtid));
    323   wtid_ptr = &wtid;
    324   tts->is = is;
    325   if (NULL != tts->wtid_reference)
    326   {
    327     const struct TALER_TESTING_Command *wtid_cmd;
    328 
    329     wtid_cmd = TALER_TESTING_interpreter_lookup_command (tts->is,
    330                                                          tts->wtid_reference);
    331     if (NULL == wtid_cmd)
    332     {
    333       GNUNET_break (0);
    334       TALER_TESTING_interpreter_fail (tts->is);
    335       return;
    336     }
    337 
    338     if (GNUNET_OK !=
    339         TALER_TESTING_get_trait_wtid (wtid_cmd,
    340                                       &wtid_ptr))
    341     {
    342       GNUNET_break (0);
    343       TALER_TESTING_interpreter_fail (tts->is);
    344       return;
    345     }
    346     GNUNET_assert (NULL != wtid_ptr);
    347   }
    348   tts->tth = TALER_EXCHANGE_get_transfers_create (
    349     TALER_TESTING_interpreter_get_context (is),
    350     TALER_TESTING_get_exchange_url (is),
    351     TALER_TESTING_get_keys (is),
    352     wtid_ptr);
    353   GNUNET_assert (NULL != tts->tth);
    354   GNUNET_assert (TALER_EC_NONE ==
    355                  TALER_EXCHANGE_get_transfers_start (tts->tth,
    356                                                      &track_transfer_cb,
    357                                                      tts));
    358 }
    359 
    360 
    361 struct TALER_TESTING_Command
    362 TALER_TESTING_cmd_track_transfer_empty (
    363   const char *label,
    364   const char *wtid_reference,
    365   unsigned int expected_response_code)
    366 {
    367   struct TrackTransferState *tts;
    368 
    369   tts = GNUNET_new (struct TrackTransferState);
    370   tts->wtid_reference = wtid_reference;
    371   tts->expected_response_code = expected_response_code;
    372   {
    373     struct TALER_TESTING_Command cmd = {
    374       .cls = tts,
    375       .label = label,
    376       .run = &track_transfer_run,
    377       .cleanup = &track_transfer_cleanup
    378     };
    379 
    380     return cmd;
    381   }
    382 }
    383 
    384 
    385 struct TALER_TESTING_Command
    386 TALER_TESTING_cmd_track_transfer (
    387   const char *label,
    388   const char *wtid_reference,
    389   unsigned int expected_response_code,
    390   const char *expected_total_amount,
    391   const char *expected_wire_fee)
    392 {
    393   struct TrackTransferState *tts;
    394 
    395   tts = GNUNET_new (struct TrackTransferState);
    396   tts->wtid_reference = wtid_reference;
    397   tts->expected_response_code = expected_response_code;
    398   tts->expected_total_amount = expected_total_amount;
    399   tts->expected_wire_fee = expected_wire_fee;
    400   {
    401     struct TALER_TESTING_Command cmd = {
    402       .cls = tts,
    403       .label = label,
    404       .run = &track_transfer_run,
    405       .cleanup = &track_transfer_cleanup
    406     };
    407 
    408     return cmd;
    409   }
    410 }
    411 
    412 
    413 /* end of testing_api_cmd_gransfer_get.c */