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


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