LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_refund.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 44 66 66.7 %
Date: 2021-08-30 06:43:37 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2020 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             :  * @file testing/testing_api_cmd_refund.c
      21             :  * @brief Implement the /refund test command, plus other
      22             :  *        corollary commands (?).
      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             : /**
      32             :  * State for a "refund" CMD.
      33             :  */
      34             : struct RefundState
      35             : {
      36             :   /**
      37             :    * Expected HTTP response code.
      38             :    */
      39             :   unsigned int expected_response_code;
      40             : 
      41             :   /**
      42             :    * Amount to be refunded.
      43             :    */
      44             :   const char *refund_amount;
      45             : 
      46             :   /**
      47             :    * Reference to any command that can provide a coin to refund.
      48             :    */
      49             :   const char *coin_reference;
      50             : 
      51             :   /**
      52             :    * Refund transaction identifier.
      53             :    */
      54             :   uint64_t refund_transaction_id;
      55             : 
      56             :   /**
      57             :    * Connection to the exchange.
      58             :    */
      59             :   struct TALER_EXCHANGE_Handle *exchange;
      60             : 
      61             :   /**
      62             :    * Handle to the refund operation.
      63             :    */
      64             :   struct TALER_EXCHANGE_RefundHandle *rh;
      65             : 
      66             :   /**
      67             :    * Interpreter state.
      68             :    */
      69             :   struct TALER_TESTING_Interpreter *is;
      70             : };
      71             : 
      72             : 
      73             : /**
      74             :  * Check the result for the refund request, just check if the
      75             :  * response code is acceptable.
      76             :  *
      77             :  * @param cls closure
      78             :  * @param hr HTTP response details
      79             :  * @param exchange_pub public key the exchange
      80             :  *        used for signing @a obj.
      81             :  * @param exchange_sig actual signature confirming the refund
      82             :  */
      83             : static void
      84          11 : refund_cb (void *cls,
      85             :            const struct TALER_EXCHANGE_HttpResponse *hr,
      86             :            const struct TALER_ExchangePublicKeyP *exchange_pub,
      87             :            const struct TALER_ExchangeSignatureP *exchange_sig)
      88             : {
      89             : 
      90          11 :   struct RefundState *rs = cls;
      91             :   struct TALER_TESTING_Command *refund_cmd;
      92             : 
      93          11 :   refund_cmd = &rs->is->commands[rs->is->ip];
      94          11 :   rs->rh = NULL;
      95          11 :   if (rs->expected_response_code != hr->http_status)
      96             :   {
      97           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      98             :                 "Unexpected response code %u/%d to command %s in %s:%u\n",
      99             :                 hr->http_status,
     100             :                 hr->ec,
     101             :                 refund_cmd->label,
     102             :                 __FILE__,
     103             :                 __LINE__);
     104           0 :     json_dumpf (hr->reply,
     105             :                 stderr,
     106             :                 0);
     107           0 :     TALER_TESTING_interpreter_fail (rs->is);
     108           0 :     return;
     109             :   }
     110          11 :   TALER_TESTING_interpreter_next (rs->is);
     111             : }
     112             : 
     113             : 
     114             : /**
     115             :  * Run the command.
     116             :  *
     117             :  * @param cls closure.
     118             :  * @param cmd the command to execute.
     119             :  * @param is the interpreter state.
     120             :  */
     121             : static void
     122          11 : refund_run (void *cls,
     123             :             const struct TALER_TESTING_Command *cmd,
     124             :             struct TALER_TESTING_Interpreter *is)
     125             : {
     126          11 :   struct RefundState *rs = cls;
     127             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv;
     128             :   struct TALER_CoinSpendPublicKeyP coin;
     129             :   const json_t *contract_terms;
     130             :   struct GNUNET_HashCode h_contract_terms;
     131             :   struct TALER_Amount refund_amount;
     132             :   const struct TALER_MerchantPrivateKeyP *merchant_priv;
     133             :   const struct TALER_TESTING_Command *coin_cmd;
     134             : 
     135          11 :   rs->exchange = is->exchange;
     136          11 :   rs->is = is;
     137             : 
     138          11 :   if (GNUNET_OK !=
     139          11 :       TALER_string_to_amount (rs->refund_amount,
     140             :                               &refund_amount))
     141             :   {
     142           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     143             :                 "Failed to parse amount `%s' at %u/%s\n",
     144             :                 rs->refund_amount,
     145             :                 is->ip,
     146             :                 cmd->label);
     147           0 :     TALER_TESTING_interpreter_fail (is);
     148           0 :     return;
     149             :   }
     150          11 :   coin_cmd = TALER_TESTING_interpreter_lookup_command (is,
     151             :                                                        rs->coin_reference);
     152          11 :   if (NULL == coin_cmd)
     153             :   {
     154           0 :     GNUNET_break (0);
     155           0 :     TALER_TESTING_interpreter_fail (is);
     156           0 :     return;
     157             :   }
     158          11 :   if (GNUNET_OK !=
     159          11 :       TALER_TESTING_get_trait_contract_terms (coin_cmd,
     160             :                                               0,
     161             :                                               &contract_terms))
     162             :   {
     163           0 :     GNUNET_break (0);
     164           0 :     TALER_TESTING_interpreter_fail (is);
     165           0 :     return;
     166             :   }
     167          11 :   GNUNET_assert (GNUNET_OK ==
     168             :                  TALER_JSON_contract_hash (contract_terms,
     169             :                                            &h_contract_terms));
     170             : 
     171             :   /* Hunting for a coin .. */
     172          11 :   if (GNUNET_OK !=
     173          11 :       TALER_TESTING_get_trait_coin_priv (coin_cmd,
     174             :                                          0,
     175             :                                          &coin_priv))
     176             :   {
     177           0 :     GNUNET_break (0);
     178           0 :     TALER_TESTING_interpreter_fail (is);
     179           0 :     return;
     180             :   }
     181             : 
     182          11 :   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
     183             :                                       &coin.eddsa_pub);
     184          11 :   if (GNUNET_OK !=
     185          11 :       TALER_TESTING_get_trait_merchant_priv (coin_cmd,
     186             :                                              0,
     187             :                                              &merchant_priv))
     188             :   {
     189           0 :     GNUNET_break (0);
     190           0 :     TALER_TESTING_interpreter_fail (is);
     191           0 :     return;
     192             :   }
     193          11 :   rs->rh = TALER_EXCHANGE_refund (rs->exchange,
     194             :                                   &refund_amount,
     195             :                                   &h_contract_terms,
     196             :                                   &coin,
     197             :                                   rs->refund_transaction_id,
     198             :                                   merchant_priv,
     199             :                                   &refund_cb,
     200             :                                   rs);
     201          11 :   GNUNET_assert (NULL != rs->rh);
     202             : }
     203             : 
     204             : 
     205             : /**
     206             :  * Free the state from a "refund" CMD, and possibly cancel
     207             :  * a pending operation thereof.
     208             :  *
     209             :  * @param cls closure.
     210             :  * @param cmd the command which is being cleaned up.
     211             :  */
     212             : static void
     213          11 : refund_cleanup (void *cls,
     214             :                 const struct TALER_TESTING_Command *cmd)
     215             : {
     216          11 :   struct RefundState *rs = cls;
     217             : 
     218          11 :   if (NULL != rs->rh)
     219             :   {
     220           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     221             :                 "Command %u (%s) did not complete\n",
     222             :                 rs->is->ip,
     223             :                 cmd->label);
     224           0 :     TALER_EXCHANGE_refund_cancel (rs->rh);
     225           0 :     rs->rh = NULL;
     226             :   }
     227          11 :   GNUNET_free (rs);
     228          11 : }
     229             : 
     230             : 
     231             : /**
     232             :  * Create a "refund" command.
     233             :  *
     234             :  * @param label command label.
     235             :  * @param expected_response_code expected HTTP status code.
     236             :  * @param refund_amount the amount to ask a refund for.
     237             :  * @param coin_reference reference to a command that can
     238             :  *        provide a coin to be refunded.
     239             :  *
     240             :  * @return the command.
     241             :  */
     242             : struct TALER_TESTING_Command
     243           7 : TALER_TESTING_cmd_refund (const char *label,
     244             :                           unsigned int expected_response_code,
     245             :                           const char *refund_amount,
     246             :                           const char *coin_reference)
     247             : {
     248             :   struct RefundState *rs;
     249             : 
     250           7 :   rs = GNUNET_new (struct RefundState);
     251             : 
     252           7 :   rs->expected_response_code = expected_response_code;
     253           7 :   rs->refund_amount = refund_amount;
     254           7 :   rs->coin_reference = coin_reference;
     255             :   {
     256           7 :     struct TALER_TESTING_Command cmd = {
     257             :       .cls = rs,
     258             :       .label = label,
     259             :       .run = &refund_run,
     260             :       .cleanup = &refund_cleanup
     261             :     };
     262             : 
     263           7 :     return cmd;
     264             :   }
     265             : }
     266             : 
     267             : 
     268             : /**
     269             :  * Create a "refund" command, allow to specify refund transaction
     270             :  * id.  Mainly used to create conflicting requests.
     271             :  *
     272             :  * @param label command label.
     273             :  * @param expected_response_code expected HTTP status code.
     274             :  * @param refund_amount the amount to ask a refund for.
     275             :  * @param coin_reference reference to a command that can
     276             :  *        provide a coin to be refunded.
     277             :  * @param refund_transaction_id transaction id to use
     278             :  *        in the request.
     279             :  *
     280             :  * @return the command.
     281             :  */
     282             : struct TALER_TESTING_Command
     283           4 : TALER_TESTING_cmd_refund_with_id
     284             :   (const char *label,
     285             :   unsigned int expected_response_code,
     286             :   const char *refund_amount,
     287             :   const char *coin_reference,
     288             :   uint64_t refund_transaction_id)
     289             : {
     290             :   struct RefundState *rs;
     291             : 
     292           4 :   rs = GNUNET_new (struct RefundState);
     293           4 :   rs->expected_response_code = expected_response_code;
     294           4 :   rs->refund_amount = refund_amount;
     295           4 :   rs->coin_reference = coin_reference;
     296           4 :   rs->refund_transaction_id = refund_transaction_id;
     297             :   {
     298           4 :     struct TALER_TESTING_Command cmd = {
     299             :       .cls = rs,
     300             :       .label = label,
     301             :       .run = &refund_run,
     302             :       .cleanup = &refund_cleanup
     303             :     };
     304             : 
     305           4 :     return cmd;
     306             :   }
     307             : }

Generated by: LCOV version 1.14