LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_deposits_get.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 67 102 65.7 %
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-2021, 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_deposits_get.c
      22             :  * @brief Implement the testing CMDs for the /deposits/ GET operations.
      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 transaction" CMD.
      32             :  */
      33             : struct TrackTransactionState
      34             : {
      35             : 
      36             :   /**
      37             :    * If non NULL, will provide a WTID to be compared against
      38             :    * the one returned by the "track transaction" operation.
      39             :    */
      40             :   const char *bank_transfer_reference;
      41             : 
      42             :   /**
      43             :    * Our command.
      44             :    */
      45             :   const struct TALER_TESTING_Command *cmd;
      46             : 
      47             :   /**
      48             :    * The WTID associated by the transaction being tracked.
      49             :    */
      50             :   struct TALER_WireTransferIdentifierRawP wtid;
      51             : 
      52             :   /**
      53             :    * Expected HTTP response code.
      54             :    */
      55             :   unsigned int expected_response_code;
      56             : 
      57             :   /**
      58             :    * Set to the KYC requirement payto hash *if* the exchange replied with a
      59             :    * request for KYC (#MHD_HTTP_ACCEPTED).
      60             :    * Note: set based on our @e merchant_payto_uri, as
      61             :    * the exchange does not respond with the payto hash.
      62             :    */
      63             :   struct TALER_NormalizedPaytoHashP h_payto;
      64             : 
      65             :   /**
      66             :    * Set to the KYC requirement row *if* the exchange replied with
      67             :    * a request for KYC (#MHD_HTTP_ACCEPTED).
      68             :    */
      69             :   uint64_t requirement_row;
      70             : 
      71             :   /**
      72             :    * Reference to any operation that can provide a transaction.
      73             :    * Will be the transaction to track.
      74             :    */
      75             :   const char *transaction_reference;
      76             : 
      77             :   /**
      78             :    * Payto URI of the merchant receiving the deposit.
      79             :    */
      80             :   struct TALER_FullPayto merchant_payto_uri;
      81             : 
      82             :   /**
      83             :    * Index of the coin involved in the transaction.  Recall:
      84             :    * at the exchange, the tracking is done _per coin_.
      85             :    */
      86             :   unsigned int coin_index;
      87             : 
      88             :   /**
      89             :    * Handle to the "track transaction" pending operation.
      90             :    */
      91             :   struct TALER_EXCHANGE_DepositGetHandle *tth;
      92             : 
      93             :   /**
      94             :    * Interpreter state.
      95             :    */
      96             :   struct TALER_TESTING_Interpreter *is;
      97             : };
      98             : 
      99             : 
     100             : /**
     101             :  * Checks what is returned by the "track transaction" operation.
     102             :  * Checks that the HTTP response code is acceptable, and - if the
     103             :  * right reference is non NULL - that the wire transfer subject
     104             :  * line matches our expectations.
     105             :  *
     106             :  * @param cls closure.
     107             :  * @param dr GET deposit response details
     108             :  */
     109             : static void
     110           8 : deposit_wtid_cb (
     111             :   void *cls,
     112             :   const struct TALER_EXCHANGE_GetDepositResponse *dr)
     113             : {
     114           8 :   struct TrackTransactionState *tts = cls;
     115           8 :   struct TALER_TESTING_Interpreter *is = tts->is;
     116             : 
     117           8 :   tts->tth = NULL;
     118           8 :   if (tts->expected_response_code != dr->hr.http_status)
     119             :   {
     120           0 :     TALER_TESTING_unexpected_status (is,
     121             :                                      dr->hr.http_status,
     122             :                                      tts->expected_response_code);
     123           0 :     return;
     124             :   }
     125           8 :   switch (dr->hr.http_status)
     126             :   {
     127           2 :   case MHD_HTTP_OK:
     128           2 :     tts->wtid = dr->details.ok.wtid;
     129           2 :     if (NULL != tts->bank_transfer_reference)
     130             :     {
     131             :       const struct TALER_TESTING_Command *bank_transfer_cmd;
     132             :       const struct TALER_WireTransferIdentifierRawP *wtid_want;
     133             : 
     134             :       /* _this_ wire transfer subject line.  */
     135             :       bank_transfer_cmd
     136           2 :         = TALER_TESTING_interpreter_lookup_command (is,
     137             :                                                     tts->bank_transfer_reference
     138             :                                                     );
     139           2 :       if (NULL == bank_transfer_cmd)
     140             :       {
     141           0 :         GNUNET_break (0);
     142           0 :         TALER_TESTING_interpreter_fail (is);
     143           0 :         return;
     144             :       }
     145             : 
     146           2 :       if (GNUNET_OK !=
     147           2 :           TALER_TESTING_get_trait_wtid (bank_transfer_cmd,
     148             :                                         &wtid_want))
     149             :       {
     150           0 :         GNUNET_break (0);
     151           0 :         TALER_TESTING_interpreter_fail (is);
     152           0 :         return;
     153             :       }
     154             : 
     155             :       /* Compare that expected and gotten subjects match.  */
     156           2 :       if (0 != GNUNET_memcmp (&dr->details.ok.wtid,
     157             :                               wtid_want))
     158             :       {
     159           0 :         GNUNET_break (0);
     160           0 :         TALER_TESTING_interpreter_fail (tts->is);
     161           0 :         return;
     162             :       }
     163             :     }
     164           2 :     break;
     165           4 :   case MHD_HTTP_ACCEPTED:
     166             :     /* allowed, nothing to check here */
     167           4 :     TALER_full_payto_normalize_and_hash (tts->merchant_payto_uri,
     168             :                                          &tts->h_payto);
     169             :     tts->requirement_row
     170           4 :       = dr->details.accepted.requirement_row;
     171           4 :     break;
     172           2 :   case MHD_HTTP_NOT_FOUND:
     173             :     /* allowed, nothing to check here */
     174           2 :     break;
     175           0 :   default:
     176           0 :     GNUNET_break (0);
     177           0 :     break;
     178             :   }
     179           8 :   TALER_TESTING_interpreter_next (tts->is);
     180             : }
     181             : 
     182             : 
     183             : /**
     184             :  * Run the command.
     185             :  *
     186             :  * @param cls closure.
     187             :  * @param cmd the command to execute.
     188             :  * @param is the interpreter state.
     189             :  */
     190             : static void
     191           8 : deposits_get_run (
     192             :   void *cls,
     193             :   const struct TALER_TESTING_Command *cmd,
     194             :   struct TALER_TESTING_Interpreter *is)
     195             : {
     196           8 :   struct TrackTransactionState *tts = cls;
     197             :   const struct TALER_TESTING_Command *transaction_cmd;
     198             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv;
     199             :   struct TALER_CoinSpendPublicKeyP coin_pub;
     200             :   const json_t *contract_terms;
     201             :   const json_t *wire_details;
     202             :   struct TALER_MerchantWireHashP h_wire_details;
     203             :   struct TALER_PrivateContractHashP h_contract_terms;
     204             :   const struct TALER_MerchantPrivateKeyP *merchant_priv;
     205             : 
     206           8 :   tts->cmd = cmd;
     207           8 :   tts->is = is;
     208             :   transaction_cmd
     209           8 :     = TALER_TESTING_interpreter_lookup_command (tts->is,
     210             :                                                 tts->transaction_reference);
     211           8 :   if (NULL == transaction_cmd)
     212             :   {
     213           0 :     GNUNET_break (0);
     214           0 :     TALER_TESTING_interpreter_fail (tts->is);
     215           0 :     return;
     216             :   }
     217             : 
     218           8 :   if (GNUNET_OK !=
     219           8 :       TALER_TESTING_get_trait_coin_priv (transaction_cmd,
     220             :                                          tts->coin_index,
     221             :                                          &coin_priv))
     222             :   {
     223           0 :     GNUNET_break (0);
     224           0 :     TALER_TESTING_interpreter_fail (tts->is);
     225           0 :     return;
     226             :   }
     227             : 
     228           8 :   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
     229             :                                       &coin_pub.eddsa_pub);
     230             : 
     231             :   /* Get the strings.. */
     232           8 :   if (GNUNET_OK !=
     233           8 :       TALER_TESTING_get_trait_wire_details (transaction_cmd,
     234             :                                             &wire_details))
     235             :   {
     236           0 :     GNUNET_break (0);
     237           0 :     TALER_TESTING_interpreter_fail (tts->is);
     238           0 :     return;
     239             :   }
     240             :   tts->merchant_payto_uri.full_payto
     241           8 :     = GNUNET_strdup (json_string_value (json_object_get (wire_details,
     242             :                                                          "payto_uri")));
     243           8 :   if (GNUNET_OK !=
     244           8 :       TALER_TESTING_get_trait_contract_terms (transaction_cmd,
     245             :                                               &contract_terms))
     246             :   {
     247           0 :     GNUNET_break (0);
     248           0 :     TALER_TESTING_interpreter_fail (tts->is);
     249           0 :     return;
     250             :   }
     251             : 
     252           8 :   if ( (NULL == wire_details) ||
     253           8 :        (NULL == contract_terms) )
     254             :   {
     255           0 :     GNUNET_break (0);
     256           0 :     TALER_TESTING_interpreter_fail (tts->is);
     257           0 :     return;
     258             :   }
     259             : 
     260             :   /* Should not fail here, json has been parsed already */
     261           8 :   GNUNET_assert
     262             :     ( (GNUNET_OK ==
     263             :        TALER_JSON_merchant_wire_signature_hash (wire_details,
     264             :                                                 &h_wire_details)) &&
     265             :     (GNUNET_OK ==
     266             :      TALER_JSON_contract_hash (contract_terms,
     267             :                                &h_contract_terms)) );
     268             : 
     269           8 :   if (GNUNET_OK !=
     270           8 :       TALER_TESTING_get_trait_merchant_priv (transaction_cmd,
     271             :                                              &merchant_priv))
     272             :   {
     273           0 :     GNUNET_break (0);
     274           0 :     TALER_TESTING_interpreter_fail (tts->is);
     275           0 :     return;
     276             :   }
     277             : 
     278           8 :   tts->tth = TALER_EXCHANGE_deposits_get (
     279             :     TALER_TESTING_interpreter_get_context (is),
     280             :     TALER_TESTING_get_exchange_url (is),
     281             :     TALER_TESTING_get_keys (is),
     282             :     merchant_priv,
     283             :     &h_wire_details,
     284             :     &h_contract_terms,
     285             :     &coin_pub,
     286           8 :     GNUNET_TIME_UNIT_ZERO,
     287             :     &deposit_wtid_cb,
     288             :     tts);
     289           8 :   GNUNET_assert (NULL != tts->tth);
     290             : }
     291             : 
     292             : 
     293             : /**
     294             :  * Cleanup the state from a "track transaction" CMD, and possibly
     295             :  * cancel a operation thereof.
     296             :  *
     297             :  * @param cls closure.
     298             :  * @param cmd the command which is being cleaned up.
     299             :  */
     300             : static void
     301           8 : deposits_get_cleanup (
     302             :   void *cls,
     303             :   const struct TALER_TESTING_Command *cmd)
     304             : {
     305           8 :   struct TrackTransactionState *tts = cls;
     306             : 
     307           8 :   if (NULL != tts->tth)
     308             :   {
     309           0 :     TALER_TESTING_command_incomplete (tts->is,
     310             :                                       cmd->label);
     311           0 :     TALER_EXCHANGE_deposits_get_cancel (tts->tth);
     312           0 :     tts->tth = NULL;
     313             :   }
     314           8 :   GNUNET_free (tts->merchant_payto_uri.full_payto);
     315           8 :   GNUNET_free (tts);
     316           8 : }
     317             : 
     318             : 
     319             : /**
     320             :  * Offer internal data from a "track transaction" CMD.
     321             :  *
     322             :  * @param cls closure.
     323             :  * @param[out] ret result (could be anything).
     324             :  * @param trait name of the trait.
     325             :  * @param index index number of the object to offer.
     326             :  * @return #GNUNET_OK on success.
     327             :  */
     328             : static enum GNUNET_GenericReturnValue
     329          25 : deposits_get_traits (void *cls,
     330             :                      const void **ret,
     331             :                      const char *trait,
     332             :                      unsigned int index)
     333             : {
     334          25 :   struct TrackTransactionState *tts = cls;
     335             :   struct TALER_TESTING_Trait traits[] = {
     336          25 :     TALER_TESTING_make_trait_wtid (&tts->wtid),
     337          25 :     TALER_TESTING_make_trait_legi_requirement_row (
     338          25 :       &tts->requirement_row),
     339          25 :     TALER_TESTING_make_trait_h_normalized_payto (&tts->h_payto),
     340          25 :     TALER_TESTING_make_trait_full_payto_uri (&tts->merchant_payto_uri),
     341          25 :     TALER_TESTING_trait_end ()
     342             :   };
     343             : 
     344          25 :   return TALER_TESTING_get_trait (traits,
     345             :                                   ret,
     346             :                                   trait,
     347             :                                   index);
     348             : }
     349             : 
     350             : 
     351             : struct TALER_TESTING_Command
     352           8 : TALER_TESTING_cmd_deposits_get (
     353             :   const char *label,
     354             :   const char *transaction_reference,
     355             :   unsigned int coin_index,
     356             :   unsigned int expected_response_code,
     357             :   const char *bank_transfer_reference)
     358             : {
     359             :   struct TrackTransactionState *tts;
     360             : 
     361           8 :   tts = GNUNET_new (struct TrackTransactionState);
     362           8 :   tts->transaction_reference = transaction_reference;
     363           8 :   tts->expected_response_code = expected_response_code;
     364           8 :   tts->bank_transfer_reference = bank_transfer_reference;
     365           8 :   tts->coin_index = coin_index;
     366             :   {
     367           8 :     struct TALER_TESTING_Command cmd = {
     368             :       .cls = tts,
     369             :       .label = label,
     370             :       .run = &deposits_get_run,
     371             :       .cleanup = &deposits_get_cleanup,
     372             :       .traits = &deposits_get_traits
     373             :     };
     374             : 
     375           8 :     return cmd;
     376             :   }
     377             : }
     378             : 
     379             : 
     380             : /* end of testing_api_cmd_deposits_get.c */

Generated by: LCOV version 1.16