LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_transfer_get.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 54 117 46.2 %
Date: 2025-06-05 21:03:14 Functions: 5 5 100.0 %

          Line data    Source code
       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 "platform.h"
      26             : #include "taler_json_lib.h"
      27             : #include <gnunet/gnunet_curl_lib.h>
      28             : #include "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           6 : track_transfer_cleanup (
      99             :   void *cls,
     100             :   const struct TALER_TESTING_Command *cmd)
     101             : {
     102           6 :   struct TrackTransferState *tts = cls;
     103             : 
     104           6 :   if (NULL != tts->tth)
     105             :   {
     106           0 :     TALER_TESTING_command_incomplete (tts->is,
     107             :                                       cmd->label);
     108           0 :     TALER_EXCHANGE_transfers_get_cancel (tts->tth);
     109           0 :     tts->tth = NULL;
     110             :   }
     111           6 :   GNUNET_free (tts);
     112           6 : }
     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           6 : track_transfer_cb (
     125             :   void *cls,
     126             :   const struct TALER_EXCHANGE_TransfersGetResponse *tgr)
     127             : {
     128           6 :   struct TrackTransferState *tts = cls;
     129           6 :   const struct TALER_EXCHANGE_HttpResponse *hr = &tgr->hr;
     130           6 :   struct TALER_TESTING_Interpreter *is = tts->is;
     131             :   struct TALER_Amount expected_amount;
     132             : 
     133           6 :   tts->tth = NULL;
     134           6 :   if (tts->expected_response_code != hr->http_status)
     135             :   {
     136           0 :     TALER_TESTING_unexpected_status (is,
     137             :                                      hr->http_status,
     138             :                                      tts->expected_response_code);
     139           0 :     return;
     140             :   }
     141             : 
     142           6 :   switch (hr->http_status)
     143             :   {
     144           4 :   case MHD_HTTP_OK:
     145             :     {
     146           4 :       const struct TALER_EXCHANGE_TransferData *ta
     147             :         = &tgr->details.ok.td;
     148             : 
     149           4 :       if (NULL == tts->expected_total_amount)
     150             :       {
     151           0 :         GNUNET_break (0);
     152           0 :         TALER_TESTING_interpreter_fail (is);
     153           0 :         return;
     154             :       }
     155           4 :       if (NULL == tts->expected_wire_fee)
     156             :       {
     157           0 :         GNUNET_break (0);
     158           0 :         TALER_TESTING_interpreter_fail (is);
     159           0 :         return;
     160             :       }
     161             : 
     162           4 :       if (GNUNET_OK !=
     163           4 :           TALER_string_to_amount (tts->expected_total_amount,
     164             :                                   &expected_amount))
     165             :       {
     166           0 :         GNUNET_break (0);
     167           0 :         TALER_TESTING_interpreter_fail (is);
     168           0 :         return;
     169             :       }
     170           4 :       if (0 != TALER_amount_cmp (&ta->total_amount,
     171             :                                  &expected_amount))
     172             :       {
     173           0 :         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           0 :         json_dumpf (hr->reply,
     180             :                     stderr,
     181             :                     0);
     182           0 :         fprintf (stderr, "\n");
     183           0 :         TALER_TESTING_interpreter_fail (is);
     184           0 :         return;
     185             :       }
     186             : 
     187           4 :       if (GNUNET_OK !=
     188           4 :           TALER_string_to_amount (tts->expected_wire_fee,
     189             :                                   &expected_amount))
     190             :       {
     191           0 :         GNUNET_break (0);
     192           0 :         TALER_TESTING_interpreter_fail (is);
     193           0 :         return;
     194             :       }
     195             : 
     196           4 :       if (0 != TALER_amount_cmp (&ta->wire_fee,
     197             :                                  &expected_amount))
     198             :       {
     199           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     200             :                     "Wire fee mismatch to command %s\n",
     201             :                     tts->cmd->label);
     202           0 :         json_dumpf (hr->reply,
     203             :                     stderr,
     204             :                     0);
     205           0 :         TALER_TESTING_interpreter_fail (is);
     206           0 :         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           4 :       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           0 :           = TALER_TESTING_interpreter_lookup_command (
     224             :               is,
     225             :               tts->wire_details_reference);
     226           0 :         if (NULL == wire_details_cmd)
     227             :         {
     228           0 :           GNUNET_break (0);
     229           0 :           TALER_TESTING_interpreter_fail (is);
     230           0 :           return;
     231             :         }
     232           0 :         if (GNUNET_OK !=
     233           0 :             TALER_TESTING_get_trait_full_payto_uri (wire_details_cmd,
     234             :                                                     &payto_uri))
     235             :         {
     236           0 :           GNUNET_break (0);
     237           0 :           TALER_TESTING_interpreter_fail (is);
     238           0 :           return;
     239             :         }
     240           0 :         TALER_full_payto_hash (*payto_uri,
     241             :                                &h_payto);
     242           0 :         if (0 != GNUNET_memcmp (&h_payto,
     243             :                                 &ta->h_payto))
     244             :         {
     245           0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     246             :                       "Wire hash missmath to command %s\n",
     247             :                       tts->cmd->label);
     248           0 :           json_dumpf (hr->reply,
     249             :                       stderr,
     250             :                       0);
     251           0 :           TALER_TESTING_interpreter_fail (is);
     252           0 :           return;
     253             :         }
     254             :       }
     255           4 :       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           0 :           = TALER_TESTING_interpreter_lookup_command (is,
     262             :                                                       tts->
     263             :                                                       total_amount_reference);
     264           0 :         if (NULL == total_amount_cmd)
     265             :         {
     266           0 :           GNUNET_break (0);
     267           0 :           TALER_TESTING_interpreter_fail (is);
     268           0 :           return;
     269             :         }
     270           0 :         if (GNUNET_OK !=
     271           0 :             TALER_TESTING_get_trait_amount (total_amount_cmd,
     272             :                                             &total_amount_from_reference))
     273             :         {
     274           0 :           GNUNET_break (0);
     275           0 :           TALER_TESTING_interpreter_fail (is);
     276           0 :           return;
     277             :         }
     278           0 :         if (0 != TALER_amount_cmp (&ta->total_amount,
     279             :                                    total_amount_from_reference))
     280             :         {
     281           0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     282             :                       "Amount mismatch in command %s\n",
     283             :                       tts->cmd->label);
     284           0 :           json_dumpf (hr->reply,
     285             :                       stderr,
     286             :                       0);
     287           0 :           TALER_TESTING_interpreter_fail (is);
     288           0 :           return;
     289             :         }
     290             :       }
     291           4 :       break;
     292             :     } /* case OK */
     293             :   } /* switch on status */
     294           6 :   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           6 : 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           6 :   struct TrackTransferState *tts = cls;
     313             :   struct TALER_WireTransferIdentifierRawP wtid;
     314             :   const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
     315             : 
     316           6 :   tts->cmd = cmd;
     317             :   /* If no reference is given, we'll use a all-zeros
     318             :    * WTID */
     319           6 :   memset (&wtid,
     320             :           0,
     321             :           sizeof (wtid));
     322           6 :   wtid_ptr = &wtid;
     323           6 :   tts->is = is;
     324           6 :   if (NULL != tts->wtid_reference)
     325             :   {
     326             :     const struct TALER_TESTING_Command *wtid_cmd;
     327             : 
     328           4 :     wtid_cmd = TALER_TESTING_interpreter_lookup_command (tts->is,
     329             :                                                          tts->wtid_reference);
     330           4 :     if (NULL == wtid_cmd)
     331             :     {
     332           0 :       GNUNET_break (0);
     333           0 :       TALER_TESTING_interpreter_fail (tts->is);
     334           0 :       return;
     335             :     }
     336             : 
     337           4 :     if (GNUNET_OK !=
     338           4 :         TALER_TESTING_get_trait_wtid (wtid_cmd,
     339             :                                       &wtid_ptr))
     340             :     {
     341           0 :       GNUNET_break (0);
     342           0 :       TALER_TESTING_interpreter_fail (tts->is);
     343           0 :       return;
     344             :     }
     345           4 :     GNUNET_assert (NULL != wtid_ptr);
     346             :   }
     347           6 :   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           6 :   GNUNET_assert (NULL != tts->tth);
     355             : }
     356             : 
     357             : 
     358             : struct TALER_TESTING_Command
     359           2 : 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           2 :   tts = GNUNET_new (struct TrackTransferState);
     367           2 :   tts->wtid_reference = wtid_reference;
     368           2 :   tts->expected_response_code = expected_response_code;
     369             :   {
     370           2 :     struct TALER_TESTING_Command cmd = {
     371             :       .cls = tts,
     372             :       .label = label,
     373             :       .run = &track_transfer_run,
     374             :       .cleanup = &track_transfer_cleanup
     375             :     };
     376             : 
     377           2 :     return cmd;
     378             :   }
     379             : }
     380             : 
     381             : 
     382             : struct TALER_TESTING_Command
     383           4 : 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           4 :   tts = GNUNET_new (struct TrackTransferState);
     393           4 :   tts->wtid_reference = wtid_reference;
     394           4 :   tts->expected_response_code = expected_response_code;
     395           4 :   tts->expected_total_amount = expected_total_amount;
     396           4 :   tts->expected_wire_fee = expected_wire_fee;
     397             :   {
     398           4 :     struct TALER_TESTING_Command cmd = {
     399             :       .cls = tts,
     400             :       .label = label,
     401             :       .run = &track_transfer_run,
     402             :       .cleanup = &track_transfer_cleanup
     403             :     };
     404             : 
     405           4 :     return cmd;
     406             :   }
     407             : }
     408             : 
     409             : 
     410             : /* end of testing_api_cmd_gransfer_get.c */

Generated by: LCOV version 1.16