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 (11438B)


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