LCOV - code coverage report
Current view: top level - lib - testing_api_cmd_track.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 72 101 71.3 %
Date: 2018-07-14 06:17:23 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2018 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 lib/testing_api_cmd_track.c
      22             :  * @brief command to test /track/transaction and /track/transfer.
      23             :  * @author Marcello Stanisci
      24             :  */
      25             : 
      26             : #include "platform.h"
      27             : #include <taler/taler_exchange_service.h>
      28             : #include <taler/taler_testing_lib.h>
      29             : #include "taler_merchant_service.h"
      30             : #include "taler_merchant_testing_lib.h"
      31             : 
      32             : 
      33             : /**
      34             :  * State for a "track transaction" CMD.
      35             :  */
      36             : struct TrackTransactionState
      37             : {
      38             :   /**
      39             :    * Handle for a pending /track/transaction request.
      40             :    */
      41             :   struct TALER_MERCHANT_TrackTransactionHandle *tth;
      42             : 
      43             :   /**
      44             :    * The interpreter state.
      45             :    */
      46             :   struct TALER_TESTING_Interpreter *is;
      47             : 
      48             :   /**
      49             :    * Base URL of the merchant serving the request.
      50             :    */
      51             :   const char *merchant_url;
      52             : 
      53             :   /**
      54             :    * CURL context.
      55             :    */
      56             :   struct GNUNET_CURL_Context *ctx;
      57             : 
      58             :   /**
      59             :    * Expected HTTP response code.
      60             :    */
      61             :   unsigned int http_status;
      62             : 
      63             :   /**
      64             :    * Reference to a "pay" CMD, used to get the order
      65             :    * id to issue the track against.
      66             :    */
      67             :   const char *pay_reference;
      68             : 
      69             :   /**
      70             :    * Subject line of the wire transfer that payed
      71             :    * the tracked contract back.  WARNING: impredictible
      72             :    * behaviour if _multiple_ wire transfers were
      73             :    * issued to pay this contract back.
      74             :    */
      75             :   const char *wtid_str; 
      76             : 
      77             :   /**
      78             :    * Binary form of @a wtid_str, expected by other commands
      79             :    * in this form.
      80             :    */
      81             :   struct TALER_WireTransferIdentifierRawP wtid;
      82             : 
      83             :   /**
      84             :    * base URL of the exchange that issued (or was supposed to,
      85             :    * in case 202 Accepted was returned) the wire transfer to
      86             :    * pay the tracked contract back.
      87             :    */
      88             :   const char *exchange_url;
      89             : 
      90             : };
      91             : 
      92             : 
      93             : /**
      94             :  * State of a "track transfer" CMD.
      95             :  */
      96             : struct TrackTransferState
      97             : {
      98             : 
      99             :   /**
     100             :    * Handle for a "track transfer" request.
     101             :    */
     102             :   struct TALER_MERCHANT_TrackTransferHandle *tth;
     103             : 
     104             :   /**
     105             :    * The interpreter state.
     106             :    */
     107             :   struct TALER_TESTING_Interpreter *is;
     108             : 
     109             :   /** 
     110             :    * Base URL of the merchant serving the request.
     111             :    */
     112             :   const char *merchant_url;
     113             : 
     114             :   /**
     115             :    * CURL context.
     116             :    */
     117             :   struct GNUNET_CURL_Context *ctx;
     118             : 
     119             :   /**
     120             :    * Expected HTTP response code.
     121             :    */
     122             :   unsigned int http_status;
     123             : 
     124             : 
     125             :   /**
     126             :    * Reference for a "check bank" CMD.  It offers the
     127             :    * WTID to track.
     128             :    */
     129             :   const char *check_bank_reference;
     130             : 
     131             : };
     132             : 
     133             : /**
     134             :  * Function called with detailed wire transfer data; checks
     135             :  * if HTTP response code matches the expectation, and stores
     136             :  * in the state what came from the backend.
     137             :  *
     138             :  * @param cls closure
     139             :  * @param http_status HTTP status code we got,
     140             :  *        0 on exchange protocol violation
     141             :  * @param ec taler-specific error code
     142             :  * @param json original json reply
     143             :  */
     144             : static void
     145           2 : track_transaction_cb (void *cls,
     146             :                       unsigned int http_status,
     147             :                       enum TALER_ErrorCode ec,
     148             :                       const json_t *json)
     149             : {
     150           2 :   struct TrackTransactionState *tts = cls;
     151             :   json_t *wtid_str;
     152             :   json_t *exchange_url;
     153             : 
     154           2 :   tts->tth = NULL;
     155           2 :   if (tts->http_status != http_status)
     156             :   {
     157           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     158             :                 "Unexpected response code %u (%d) to command %s\n",
     159             :                 http_status,
     160             :                 ec,
     161             :                 TALER_TESTING_interpreter_get_current_label
     162             :                   (tts->is));
     163           0 :     TALER_TESTING_interpreter_fail (tts->is);
     164           0 :     return;
     165             :   }
     166           2 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     167             :               "/track/transaction, response code: %u\n",
     168             :               http_status);
     169           2 :   if (MHD_HTTP_OK == http_status)
     170             :   {
     171             :     /* Only storing first element's wtid, as this works around
     172             :      * the disability of the real bank to provide a "bank check"
     173             :      * CMD as the fakebank does.  */
     174             :   
     175           2 :     if (NULL == (wtid_str = json_object_get
     176           2 :       (json_array_get (json, 0), "wtid")))
     177             :     {
     178           0 :       TALER_TESTING_interpreter_fail (tts->is);
     179           0 :       return; 
     180             :     }
     181             :   
     182           2 :     if (NULL == (exchange_url = json_object_get
     183           2 :       (json_array_get (json, 0), "exchange")))
     184             :     {
     185             :     
     186           0 :       TALER_TESTING_interpreter_fail (tts->is);
     187           0 :       return;
     188             :     }
     189             :   
     190           2 :     tts->exchange_url = GNUNET_strdup
     191             :       (json_string_value (exchange_url));
     192           2 :     tts->wtid_str = GNUNET_strdup
     193             :       (json_string_value (wtid_str));
     194             :   }
     195           2 :   TALER_TESTING_interpreter_next (tts->is);
     196             : }
     197             : 
     198             : /**
     199             :  * Callback for a /track/transfer operation, only checks if
     200             :  * response code is the expected one.
     201             :  *
     202             :  * @param cls closure for this function
     203             :  * @param http_status HTTP response code returned by the server
     204             :  * @param ec taler-specific error code
     205             :  * @param sign_key exchange key used to sign @a json, or NULL
     206             :  * @param json original json reply (may include signatures,
     207             :  *        those have then been validated already)
     208             :  * @param h_wire hash of the wire transfer address the transfer
     209             :  *        went to, or NULL on error
     210             :  * @param total_amount total amount of the wire transfer, or NULL
     211             :  *        if the exchange could not provide any @a wtid (set only
     212             :  *        if @a http_status is #MHD_HTTP_OK)
     213             :  * @param details_length length of the @a details array
     214             :  * @param details array with details about the combined
     215             :  *        transactions
     216             :  */
     217             : static void
     218           4 : track_transfer_cb
     219             :   (void *cls,
     220             :    unsigned int http_status,
     221             :    enum TALER_ErrorCode ec,
     222             :    const struct TALER_ExchangePublicKeyP *sign_key,
     223             :    const json_t *json,
     224             :    const struct GNUNET_HashCode *h_wire,
     225             :    const struct TALER_Amount *total_amount,
     226             :    unsigned int details_length,
     227             :    const struct TALER_MERCHANT_TrackTransferDetails *details)
     228             : {
     229             :   /* FIXME, deeper checks should be implemented here. */
     230           4 :   struct TrackTransferState *tts = cls;
     231             : 
     232           4 :   tts->tth = NULL;
     233           4 :   if (tts->http_status != http_status)
     234             :   {
     235           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     236             :                 "Unexpected response code %u (%d) to command %s\n",
     237             :                 http_status,
     238             :                 ec,
     239             :                 TALER_TESTING_interpreter_get_current_label
     240             :                   (tts->is));
     241           0 :     TALER_TESTING_interpreter_fail (tts->is);
     242           0 :     return;
     243             :   }
     244           4 :   switch (http_status)
     245             :   {
     246             :     case MHD_HTTP_OK:
     247           4 :       break;
     248             :     default:
     249           0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     250             :                   "Unhandled HTTP status.\n");
     251             :   }
     252           4 :   TALER_TESTING_interpreter_next (tts->is);
     253             : }
     254             : 
     255             : 
     256             : 
     257             : /**
     258             :  * Run the "track transfer" CMD.
     259             :  *
     260             :  *
     261             :  * @param cls closure.
     262             :  * @param cmd command being run now.
     263             :  * @param is interpreter state.
     264             :  */
     265             : static void
     266           4 : track_transfer_run (void *cls,
     267             :                     const struct TALER_TESTING_Command *cmd,
     268             :                     struct TALER_TESTING_Interpreter *is)
     269             : {
     270           4 :   struct TrackTransferState *tts = cls;
     271             :   struct TALER_WireTransferIdentifierRawP *wtid;
     272             :   const struct TALER_TESTING_Command *check_bank_cmd;
     273             :   const char *exchange_url;
     274             : 
     275           4 :   tts->is = is;
     276           4 :   check_bank_cmd = TALER_TESTING_interpreter_lookup_command
     277             :     (is, tts->check_bank_reference);
     278           4 :   if (NULL == check_bank_cmd)
     279           0 :     TALER_TESTING_FAIL (is);
     280           4 :   if (GNUNET_OK != TALER_TESTING_get_trait_wtid
     281             :       (check_bank_cmd, 0, &wtid))
     282           0 :     TALER_TESTING_FAIL (is);
     283           4 :   if (GNUNET_OK != TALER_TESTING_get_trait_url
     284             :       (check_bank_cmd, 0, &exchange_url))
     285           0 :     TALER_TESTING_FAIL (is);
     286           4 :   tts->tth = TALER_MERCHANT_track_transfer (tts->ctx,
     287             :                                             tts->merchant_url,
     288             :                                             "default",
     289             :                                             "x-taler-bank",
     290             :                                             wtid,
     291             :                                             exchange_url,
     292             :                                             &track_transfer_cb,
     293             :                                             tts);
     294           4 :   GNUNET_assert (NULL != tts->tth);
     295             : }
     296             : 
     297             : /**
     298             :  * Run the "track transaction" CMD.
     299             :  *
     300             :  *
     301             :  * @param cls closure.
     302             :  * @param cmd command being run now.
     303             :  * @param is interpreter state.
     304             :  */
     305             : static void
     306           2 : track_transaction_run (void *cls,
     307             :                        const struct TALER_TESTING_Command *cmd,
     308             :                        struct TALER_TESTING_Interpreter *is)
     309             : {
     310           2 :   struct TrackTransactionState *tts = cls;
     311             :   const char *order_id;
     312             :   const struct TALER_TESTING_Command *pay_cmd;
     313             : 
     314           2 :   tts->is = is;
     315             : 
     316           2 :   if ( NULL ==
     317           2 :      ( pay_cmd = TALER_TESTING_interpreter_lookup_command
     318             :       (is, tts->pay_reference)))
     319           0 :     TALER_TESTING_FAIL (is);
     320             : 
     321           2 :   if (GNUNET_OK != TALER_TESTING_get_trait_order_id
     322             :       (pay_cmd, 0, &order_id))
     323           0 :     TALER_TESTING_FAIL (is);
     324             : 
     325           2 :   tts->tth = TALER_MERCHANT_track_transaction
     326             :     (tts->ctx,
     327             :      tts->merchant_url,
     328             :      "default",
     329             :      order_id,
     330             :      &track_transaction_cb,
     331             :      tts);
     332             : 
     333           2 :   GNUNET_assert (NULL != tts->tth);
     334             : }
     335             : 
     336             : 
     337             : /**
     338             :  * Free the state of a "track transfer" CMD, and possibly
     339             :  * cancel a pending operation thereof.
     340             :  *
     341             :  * @param cls closure.
     342             :  * @param cmd command being run.
     343             :  */
     344             : static void
     345           4 : track_transfer_cleanup (void *cls,
     346             :                         const struct TALER_TESTING_Command *cmd)
     347             : {
     348           4 :   struct TrackTransferState *tts = cls;
     349             : 
     350           4 :   if (NULL != tts->tth)
     351             :   {
     352           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     353             :                 "/track/transfer (test) operation"
     354             :                 " did not complete\n");
     355           0 :     TALER_MERCHANT_track_transfer_cancel (tts->tth);
     356             :   }
     357           4 :   GNUNET_free (tts);
     358           4 : }
     359             : 
     360             : /**
     361             :  * Free the state of a "track transaction" CMD, and possibly
     362             :  * cancel a pending operation thereof.
     363             :  *
     364             :  * @param cls closure.
     365             :  * @param cmd command being run.
     366             :  */
     367             : static void
     368           2 : track_transaction_cleanup (void *cls,
     369             :                            const struct TALER_TESTING_Command *cmd)
     370             : {
     371           2 :   struct TrackTransactionState *tts = cls;
     372             : 
     373           2 :   if (NULL != tts->tth)
     374             :   {
     375           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     376             :                 "/track/transaction (test) operation"
     377             :                 " did not complete\n");
     378           0 :     TALER_MERCHANT_track_transaction_cancel (tts->tth);
     379             :   }
     380             : 
     381             :   /* Need to discard 'const' before freeing.  */
     382           2 :   GNUNET_free_non_null ((char *) tts->exchange_url);
     383           2 :   GNUNET_free_non_null ((char *) tts->wtid_str);
     384             : 
     385           2 :   GNUNET_free (tts);
     386           2 : }
     387             : 
     388             : 
     389             : /**
     390             :  * Offer internal data of a "track transaction" CMD, for
     391             :  * other CMDs to use.
     392             :  *
     393             :  * @param cls closure.
     394             :  * @param ret[out] return value.
     395             :  * @param trait name of the trait.
     396             :  * @param index index of the trait.
     397             :  *
     398             :  * @return GNUNET_OK if it is successful.
     399             :  */
     400             : static int
     401           0 : track_transaction_traits (void *cls,
     402             :                           void **ret,
     403             :                           const char *trait,
     404             :                           unsigned int index)
     405             : {
     406           0 :   struct TrackTransactionState *tts = cls;
     407             :   struct TALER_WireTransferIdentifierRawP *wtid_ptr;
     408             : 
     409           0 :   if (GNUNET_OK != GNUNET_STRINGS_string_to_data
     410             :       (tts->wtid_str,
     411             :        strlen (tts->wtid_str),
     412           0 :        &tts->wtid,
     413             :        sizeof (struct TALER_WireTransferIdentifierRawP)))
     414           0 :     wtid_ptr = NULL;
     415             :   else
     416           0 :     wtid_ptr = &tts->wtid;
     417             : 
     418           0 :   struct TALER_TESTING_Trait traits[] = {
     419             :     TALER_TESTING_make_trait_wtid (0, wtid_ptr),
     420           0 :     TALER_TESTING_make_trait_url (0, tts->exchange_url),
     421             :     TALER_TESTING_trait_end ()
     422             :   };
     423             : 
     424           0 :   return TALER_TESTING_get_trait (traits,
     425             :                                   ret,
     426             :                                   trait,
     427             :                                   index);
     428             :   return GNUNET_SYSERR;
     429             : }
     430             : 
     431             : /**
     432             :  * Define a "track transaction" CMD.
     433             :  *
     434             :  * @param label command label.
     435             :  * @param merchant_url base URL of the merchant serving the
     436             :  *        /track/transaction request.
     437             :  * @param ctx CURL context.
     438             :  * @param http_status expected HTTP response code.
     439             :  * @param pay_reference used to retrieve the order id to track.
     440             :  * @return the command.
     441             :  */
     442             : struct TALER_TESTING_Command
     443           2 : TALER_TESTING_cmd_merchant_track_transaction
     444             :   (const char *label,
     445             :    const char *merchant_url,
     446             :    struct GNUNET_CURL_Context *ctx,
     447             :    unsigned int http_status,
     448             :    const char *pay_reference)
     449             : {
     450             :   struct TrackTransactionState *tts;
     451             :   struct TALER_TESTING_Command cmd;
     452             : 
     453           2 :   tts = GNUNET_new (struct TrackTransactionState);
     454           2 :   tts->merchant_url = merchant_url;
     455           2 :   tts->ctx = ctx;
     456           2 :   tts->http_status = http_status;
     457           2 :   tts->pay_reference = pay_reference;
     458             : 
     459           2 :   cmd.cls = tts;
     460           2 :   cmd.label = label;
     461           2 :   cmd.run = &track_transaction_run;
     462           2 :   cmd.cleanup = &track_transaction_cleanup;
     463           2 :   cmd.traits = &track_transaction_traits;
     464             : 
     465           2 :   return cmd;
     466             : }
     467             : 
     468             : 
     469             : /**
     470             :  * Define a "track transfer" CMD.
     471             :  *
     472             :  * @param label command label.
     473             :  * @param merchant_url base URL of the merchant serving the
     474             :  *        /track/transfer request.
     475             :  * @param ctx CURL context.
     476             :  * @param http_status expected HTTP response code.
     477             :  * @param check_bank_reference reference to a "check bank" CMD
     478             :  *        that will provide the WTID and exchange URL to issue
     479             :  *        the track against.
     480             :  * @return the command.
     481             :  */
     482             : struct TALER_TESTING_Command
     483           4 : TALER_TESTING_cmd_merchant_track_transfer
     484             :   (const char *label,
     485             :    const char *merchant_url,
     486             :    struct GNUNET_CURL_Context *ctx,
     487             :    unsigned int http_status,
     488             :    const char *check_bank_reference)
     489             : {
     490             :   struct TrackTransferState *tts;
     491             :   struct TALER_TESTING_Command cmd;
     492             : 
     493           4 :   tts = GNUNET_new (struct TrackTransferState);
     494           4 :   tts->merchant_url = merchant_url;
     495           4 :   tts->ctx = ctx;
     496           4 :   tts->http_status = http_status;
     497           4 :   tts->check_bank_reference = check_bank_reference;
     498             : 
     499           4 :   cmd.cls = tts;
     500           4 :   cmd.label = label;
     501           4 :   cmd.run = &track_transfer_run;
     502           4 :   cmd.cleanup = &track_transfer_cleanup;
     503             : 
     504           4 :   return cmd;
     505             : }
     506             : 
     507             : /* end of testing_api_cmd_track.c */

Generated by: LCOV version 1.13