LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_get_orders.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.3 % 165 116
Test Date: 2026-09-11 17:45:24 Functions: 100.0 % 12 12

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2020-2023 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 src/testing/testing_api_cmd_get_orders.c
      21              :  * @brief command to test GET /orders
      22              :  * @author Jonathan Buchanan
      23              :  */
      24              : #include "platform.h"
      25              : #include <taler/taler_exchange_service.h>
      26              : #include <taler/taler_testing_lib.h>
      27              : #include "taler/taler_merchant_service.h"
      28              : #include "taler/taler_merchant_testing_lib.h"
      29              : #include <taler/merchant/get-private-orders.h>
      30              : 
      31              : 
      32              : /**
      33              :  * State of a "GET orders" CMD.
      34              :  */
      35              : struct GetOrdersState
      36              : {
      37              : 
      38              :   /**
      39              :    * Handle for a "GET orders" request.
      40              :    */
      41              :   struct TALER_MERCHANT_GetPrivateOrdersHandle *ogh;
      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              :    * Expected HTTP response code.
      55              :    */
      56              :   unsigned int http_status;
      57              : 
      58              :   /**
      59              :    * A NULL-terminated array of CMD labels that created orders.
      60              :    */
      61              :   const char **orders;
      62              : 
      63              :   /**
      64              :    * The length of @e orders.
      65              :    */
      66              :   unsigned int orders_length;
      67              : 
      68              : };
      69              : 
      70              : 
      71              : /**
      72              :  * Callback for a GET /orders operation.
      73              :  *
      74              :  * @param cls closure for this function
      75              :  * @param ogr response
      76              :  */
      77              : /* FIXME_POLYMORPHISM: TALER_MERCHANT_GetPrivateOrdersCallback is used in this
      78              :    compilation unit with two different closure types (struct GetOrdersState here,
      79              :    struct MerchantPollOrdersStartState in merchant_poll_orders_cb below), so a single
      80              :    TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE override cannot type both. Left as
      81              :    void *cls; adopting the RESULT_CLOSURE pattern needs a manual refactor (e.g. split
      82              :    the two commands into separate translation units). */
      83              : static void
      84            7 : get_orders_cb (void *cls,
      85              :                const struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr)
      86              : {
      87            7 :   struct GetOrdersState *gos = cls;
      88              : 
      89            7 :   gos->ogh = NULL;
      90            7 :   if (gos->http_status != ogr->hr.http_status)
      91              :   {
      92            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
      93              :                 "Unexpected response code %u (%d) to command %s\n",
      94              :                 ogr->hr.http_status,
      95              :                 (int) ogr->hr.ec,
      96              :                 TALER_TESTING_interpreter_get_current_label (gos->is));
      97            0 :     TALER_TESTING_interpreter_fail (gos->is);
      98            0 :     return;
      99              :   }
     100            7 :   switch (ogr->hr.http_status)
     101              :   {
     102            7 :   case MHD_HTTP_OK:
     103            7 :     if (ogr->details.ok.orders_length != gos->orders_length)
     104              :     {
     105            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     106              :                   "Number of orders found does not match\n");
     107            0 :       TALER_TESTING_interpreter_fail (gos->is);
     108            0 :       return;
     109              :     }
     110           15 :     for (unsigned int i = 0; i < ogr->details.ok.orders_length; ++i)
     111              :     {
     112            8 :       const struct TALER_MERCHANT_GetPrivateOrdersOrderEntry *order =
     113            8 :         &ogr->details.ok.orders[i];
     114              :       const struct TALER_TESTING_Command *order_cmd;
     115              : 
     116            8 :       order_cmd = TALER_TESTING_interpreter_lookup_command (
     117              :         gos->is,
     118            8 :         gos->orders[i]);
     119              : 
     120              :       {
     121              :         const char *order_id;
     122              : 
     123            8 :         if (GNUNET_OK !=
     124            8 :             TALER_TESTING_get_trait_order_id (order_cmd,
     125              :                                               &order_id))
     126              :         {
     127            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     128              :                       "Could not fetch order id\n");
     129            0 :           TALER_TESTING_interpreter_fail (gos->is);
     130            0 :           return;
     131              :         }
     132            8 :         if (0 != strcmp (order->order_id,
     133              :                          order_id))
     134              :         {
     135            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     136              :                       "Order id does not match\n");
     137            0 :           TALER_TESTING_interpreter_fail (gos->is);
     138            0 :           return;
     139              :         }
     140              :       }
     141              :       {
     142              :         const json_t *contract_terms;
     143              :         struct TALER_Amount amount;
     144              :         const char *summary;
     145              :         struct GNUNET_JSON_Specification spec[] = {
     146            8 :           GNUNET_JSON_spec_string ("summary",
     147              :                                    &summary),
     148            8 :           TALER_JSON_spec_amount_any ("amount",
     149              :                                       &amount),
     150            8 :           GNUNET_JSON_spec_end ()
     151              :         };
     152              : 
     153            8 :         if (GNUNET_OK !=
     154            8 :             TALER_TESTING_get_trait_contract_terms (order_cmd,
     155              :                                                     &contract_terms))
     156              :         {
     157            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     158              :                       "Could not fetch order contract terms\n");
     159            0 :           TALER_TESTING_interpreter_fail (gos->is);
     160            0 :           return;
     161              :         }
     162            8 :         if (GNUNET_OK !=
     163            8 :             GNUNET_JSON_parse (contract_terms,
     164              :                                spec,
     165              :                                NULL, NULL))
     166              :         {
     167            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     168              :                       "Could not parse order contract terms\n");
     169            0 :           TALER_TESTING_interpreter_fail (gos->is);
     170            0 :           return;
     171              :         }
     172            8 :         if ((0 != strcmp (summary,
     173           16 :                           order->summary)) ||
     174            8 :             (GNUNET_OK != TALER_amount_cmp_currency (&amount,
     175            8 :                                                      &order->amount)) ||
     176            8 :             (0 != TALER_amount_cmp (&amount,
     177              :                                     &order->amount)))
     178              :         {
     179            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     180              :                       "Order summary and/or amount does not match\n");
     181            0 :           TALER_TESTING_interpreter_fail (gos->is);
     182            0 :           return;
     183              :         }
     184              :       }
     185              :     }
     186            7 :     break;
     187            0 :   case MHD_HTTP_ACCEPTED:
     188              :     /* FIXME: do more checks here (new KYC logic!) */
     189            0 :     break;
     190            0 :   default:
     191            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     192              :                 "Unhandled HTTP status.\n");
     193              :   }
     194            7 :   TALER_TESTING_interpreter_next (gos->is);
     195              : }
     196              : 
     197              : 
     198              : /**
     199              :  * Run the "GET /orders" CMD.
     200              :  *
     201              :  * @param cls closure.
     202              :  * @param cmd command being run now.
     203              :  * @param is interpreter state.
     204              :  */
     205              : static void
     206            7 : get_orders_run (void *cls,
     207              :                 const struct TALER_TESTING_Command *cmd,
     208              :                 struct TALER_TESTING_Interpreter *is)
     209              : {
     210            7 :   struct GetOrdersState *gos = cls;
     211              : 
     212            7 :   gos->is = is;
     213            7 :   gos->ogh = TALER_MERCHANT_get_private_orders_create (
     214              :     TALER_TESTING_interpreter_get_context (is),
     215              :     gos->merchant_url);
     216            7 :   GNUNET_assert (NULL != gos->ogh);
     217              :   {
     218              :     enum TALER_ErrorCode ec;
     219              : 
     220            7 :     ec = TALER_MERCHANT_get_private_orders_start (gos->ogh,
     221              :                                                   &get_orders_cb,
     222              :                                                   gos);
     223            7 :     GNUNET_assert (TALER_EC_NONE == ec);
     224              :   }
     225            7 : }
     226              : 
     227              : 
     228              : /**
     229              :  * Free the state of a "GET orders" CMD, and possibly
     230              :  * cancel a pending operation thereof.
     231              :  *
     232              :  * @param cls closure.
     233              :  * @param cmd command being run.
     234              :  */
     235              : static void
     236            7 : get_orders_cleanup (void *cls,
     237              :                     const struct TALER_TESTING_Command *cmd)
     238              : {
     239            7 :   struct GetOrdersState *gos = cls;
     240              : 
     241            7 :   if (NULL != gos->ogh)
     242              :   {
     243            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     244              :                 "GET /orders operation did not complete\n");
     245            0 :     TALER_MERCHANT_get_private_orders_cancel (gos->ogh);
     246              :   }
     247            7 :   GNUNET_array_grow (gos->orders,
     248              :                      gos->orders_length,
     249              :                      0);
     250            7 :   GNUNET_free (gos);
     251            7 : }
     252              : 
     253              : 
     254              : struct TALER_TESTING_Command
     255            7 : TALER_TESTING_cmd_merchant_get_orders (const char *label,
     256              :                                        const char *merchant_url,
     257              :                                        unsigned int http_status,
     258              :                                        ...)
     259              : {
     260              :   struct GetOrdersState *gos;
     261              : 
     262            7 :   gos = GNUNET_new (struct GetOrdersState);
     263            7 :   gos->merchant_url = merchant_url;
     264            7 :   gos->http_status = http_status;
     265              :   {
     266              :     const char *clabel;
     267              :     va_list ap;
     268              : 
     269            7 :     va_start (ap, http_status);
     270           15 :     while (NULL != (clabel = va_arg (ap, const char *)))
     271              :     {
     272            8 :       GNUNET_array_append (gos->orders,
     273              :                            gos->orders_length,
     274              :                            clabel);
     275              :     }
     276            7 :     va_end (ap);
     277              :   }
     278              :   {
     279            7 :     struct TALER_TESTING_Command cmd = {
     280              :       .cls = gos,
     281              :       .label = label,
     282              :       .run = &get_orders_run,
     283              :       .cleanup = &get_orders_cleanup
     284              :     };
     285              : 
     286            7 :     return cmd;
     287              :   }
     288              : }
     289              : 
     290              : 
     291              : struct MerchantPollOrdersConcludeState
     292              : {
     293              :   /**
     294              :    * The interpreter state.
     295              :    */
     296              :   struct TALER_TESTING_Interpreter *is;
     297              : 
     298              :   /**
     299              :    * Reference to a command that can provide a poll orders start command.
     300              :    */
     301              :   const char *start_reference;
     302              : 
     303              :   /**
     304              :    * Task to wait for the deadline.
     305              :    */
     306              :   struct GNUNET_SCHEDULER_Task *task;
     307              : 
     308              :   /**
     309              :    * Expected HTTP response status code.
     310              :    */
     311              :   unsigned int expected_http_status;
     312              : };
     313              : 
     314              : 
     315              : struct MerchantPollOrdersStartState
     316              : {
     317              :   /**
     318              :    * The merchant base URL.
     319              :    */
     320              :   const char *merchant_url;
     321              : 
     322              :   /**
     323              :    * The handle to the current GET /private/orders request.
     324              :    */
     325              :   struct TALER_MERCHANT_GetPrivateOrdersHandle *ogh;
     326              : 
     327              :   /**
     328              :    * The interpreter state.
     329              :    */
     330              :   struct TALER_TESTING_Interpreter *is;
     331              : 
     332              :   /**
     333              :    * How long to wait for server to return a response.
     334              :    */
     335              :   struct GNUNET_TIME_Relative timeout;
     336              : 
     337              :   /**
     338              :    * Conclude state waiting for completion (if any).
     339              :    */
     340              :   struct MerchantPollOrdersConcludeState *cs;
     341              : 
     342              :   /**
     343              :    * The HTTP status code returned by the backend.
     344              :    */
     345              :   unsigned int http_status;
     346              : 
     347              :   /**
     348              :    * When the request should be completed by.
     349              :    */
     350              :   struct GNUNET_TIME_Absolute deadline;
     351              : };
     352              : 
     353              : 
     354              : /**
     355              :  * Task called when either the timeout for the get orders
     356              :  * command expired or we got a response.  Checks if the
     357              :  * result is what we expected.
     358              :  *
     359              :  * @param cls a `struct MerchantPollOrdersConcludeState`
     360              :  */
     361              : static void
     362            2 : conclude_task (void *cls)
     363              : {
     364            2 :   struct MerchantPollOrdersConcludeState *poc = cls;
     365              :   const struct TALER_TESTING_Command *poll_cmd;
     366              :   struct MerchantPollOrdersStartState *pos;
     367              :   struct GNUNET_TIME_Absolute now;
     368              : 
     369            2 :   poc->task = NULL;
     370              :   poll_cmd =
     371            2 :     TALER_TESTING_interpreter_lookup_command (poc->is,
     372              :                                               poc->start_reference);
     373            2 :   if (NULL == poll_cmd)
     374            0 :     TALER_TESTING_FAIL (poc->is);
     375            2 :   pos = poll_cmd->cls;
     376            2 :   if (NULL != pos->ogh)
     377              :   {
     378            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     379              :                 "Expected poll GET /private/orders to have completed, but it did not!\n");
     380            0 :     TALER_TESTING_FAIL (poc->is);
     381              :   }
     382            2 :   if (pos->http_status != poc->expected_http_status)
     383              :   {
     384            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     385              :                 "Expected HTTP status %u, got %u\n",
     386              :                 poc->expected_http_status,
     387              :                 pos->http_status);
     388            0 :     TALER_TESTING_FAIL (poc->is);
     389              :   }
     390            2 :   now = GNUNET_TIME_absolute_get ();
     391            2 :   if (GNUNET_TIME_absolute_cmp (GNUNET_TIME_absolute_add (
     392              :                                   pos->deadline,
     393              :                                   GNUNET_TIME_UNIT_SECONDS),
     394              :                                 <,
     395              :                                 now))
     396              :   {
     397            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     398              :                 "Expected answer to be delayed until %llu, but got response at %llu\n",
     399              :                 (unsigned long long) pos->deadline.abs_value_us,
     400              :                 (unsigned long long) now.abs_value_us);
     401            0 :     TALER_TESTING_FAIL (poc->is);
     402              :   }
     403            2 :   TALER_TESTING_interpreter_next (poc->is);
     404              : }
     405              : 
     406              : 
     407              : /**
     408              :  * Callback to process a GET /orders request
     409              :  *
     410              :  * @param cls closure
     411              :  * @param ogr response details
     412              :  */
     413              : /* FIXME_POLYMORPHISM: see get_orders_cb above — same GetPrivateOrdersCallback typedef
     414              :    is reused here with a different closure type, so this compilation unit cannot adopt
     415              :    a single TALER_MERCHANT_GET_PRIVATE_ORDERS_RESULT_CLOSURE override. Left as void *cls. */
     416              : static void
     417            2 : merchant_poll_orders_cb (
     418              :   void *cls,
     419              :   const struct TALER_MERCHANT_GetPrivateOrdersResponse *ogr)
     420              : {
     421            2 :   struct MerchantPollOrdersStartState *pos = cls;
     422              : 
     423            2 :   pos->ogh = NULL;
     424            2 :   if (MHD_HTTP_OK != ogr->hr.http_status)
     425              :   {
     426            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     427              :                 "Unexpected response code %u (%d) to command %s\n",
     428              :                 ogr->hr.http_status,
     429              :                 (int) ogr->hr.ec,
     430              :                 TALER_TESTING_interpreter_get_current_label (pos->is));
     431            0 :     TALER_TESTING_interpreter_fail (pos->is);
     432            0 :     return;
     433              :   }
     434            2 :   switch (ogr->hr.http_status)
     435              :   {
     436            2 :   case MHD_HTTP_OK:
     437              :     // FIXME: use order references to check if the data returned matches that from the POST / PATCH
     438            2 :     break;
     439            0 :   default:
     440            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     441              :                 "Unhandled HTTP status.\n");
     442              :   }
     443            2 :   pos->http_status = ogr->hr.http_status;
     444            2 :   if (NULL != pos->cs)
     445              :   {
     446            0 :     GNUNET_SCHEDULER_cancel (pos->cs->task);
     447            0 :     pos->cs->task = GNUNET_SCHEDULER_add_now (&conclude_task,
     448            0 :                                               pos->cs);
     449              :   }
     450              : }
     451              : 
     452              : 
     453              : /**
     454              :  * Run the "GET orders" CMD.
     455              :  *
     456              :  * @param cls closure.
     457              :  * @param cmd command being run now.
     458              :  * @param is interpreter state.
     459              :  */
     460              : static void
     461            2 : merchant_poll_orders_start_run (void *cls,
     462              :                                 const struct TALER_TESTING_Command *cmd,
     463              :                                 struct TALER_TESTING_Interpreter *is)
     464              : {
     465            2 :   struct MerchantPollOrdersStartState *pos = cls;
     466              : 
     467              :   /* add 1s grace time to timeout */
     468              :   pos->deadline
     469            2 :     = GNUNET_TIME_relative_to_absolute (
     470              :         GNUNET_TIME_relative_add (pos->timeout,
     471              :                                   GNUNET_TIME_UNIT_SECONDS));
     472            2 :   pos->is = is;
     473            2 :   pos->ogh = TALER_MERCHANT_get_private_orders_create (
     474              :     TALER_TESTING_interpreter_get_context (is),
     475              :     pos->merchant_url);
     476            2 :   GNUNET_assert (NULL != pos->ogh);
     477            2 :   TALER_MERCHANT_get_private_orders_set_options (
     478              :     pos->ogh,
     479              :     TALER_MERCHANT_get_private_orders_option_paid (
     480              :       TALER_EXCHANGE_YNA_ALL),
     481              :     TALER_MERCHANT_get_private_orders_option_refunded (
     482              :       TALER_EXCHANGE_YNA_ALL),
     483              :     TALER_MERCHANT_get_private_orders_option_wired (
     484              :       TALER_EXCHANGE_YNA_ALL),
     485              :     TALER_MERCHANT_get_private_orders_option_date (
     486              :       GNUNET_TIME_UNIT_ZERO_TS),
     487              :     TALER_MERCHANT_get_private_orders_option_offset (1),
     488              :     TALER_MERCHANT_get_private_orders_option_limit (2),
     489              :     TALER_MERCHANT_get_private_orders_option_timeout (
     490              :       pos->timeout));
     491              :   {
     492              :     enum TALER_ErrorCode ec;
     493              : 
     494            2 :     ec = TALER_MERCHANT_get_private_orders_start (pos->ogh,
     495              :                                                   &merchant_poll_orders_cb,
     496              :                                                   pos);
     497            2 :     GNUNET_assert (TALER_EC_NONE == ec);
     498              :   }
     499              :   /* We CONTINUE to run the interpreter while the long-polled command
     500              :      completes asynchronously! */
     501            2 :   TALER_TESTING_interpreter_next (pos->is);
     502            2 : }
     503              : 
     504              : 
     505              : /**
     506              :  * Free the state of a "GET orders" CMD, and possibly
     507              :  * cancel a pending operation thereof.
     508              :  *
     509              :  * @param cls closure.
     510              :  * @param cmd command being run.
     511              :  */
     512              : static void
     513            2 : merchant_poll_orders_start_cleanup (void *cls,
     514              :                                     const struct TALER_TESTING_Command *cmd)
     515              : {
     516            2 :   struct MerchantPollOrdersStartState *pos = cls;
     517              : 
     518            2 :   if (NULL != pos->ogh)
     519              :   {
     520            0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     521              :                 "Command `%s' was not terminated\n",
     522              :                 TALER_TESTING_interpreter_get_current_label (
     523              :                   pos->is));
     524            0 :     TALER_MERCHANT_get_private_orders_cancel (pos->ogh);
     525              :   }
     526            2 :   GNUNET_free (pos);
     527            2 : }
     528              : 
     529              : 
     530              : struct TALER_TESTING_Command
     531            2 : TALER_TESTING_cmd_poll_orders_start (const char *label,
     532              :                                      const char *merchant_url,
     533              :                                      struct GNUNET_TIME_Relative timeout)
     534              : {
     535              :   struct MerchantPollOrdersStartState *pos;
     536              : 
     537            2 :   pos = GNUNET_new (struct MerchantPollOrdersStartState);
     538            2 :   pos->merchant_url = merchant_url;
     539            2 :   pos->timeout = timeout;
     540              :   {
     541            2 :     struct TALER_TESTING_Command cmd = {
     542              :       .cls = pos,
     543              :       .label = label,
     544              :       .run = &merchant_poll_orders_start_run,
     545              :       .cleanup = &merchant_poll_orders_start_cleanup
     546              :     };
     547              : 
     548            2 :     return cmd;
     549              :   }
     550              : }
     551              : 
     552              : 
     553              : /**
     554              :  * Wait for the "GET orders" CMD to complete.
     555              :  *
     556              :  * @param cls closure.
     557              :  * @param cmd command being run now.
     558              :  * @param is interpreter state.
     559              :  */
     560              : static void
     561            2 : merchant_poll_orders_conclude_run (void *cls,
     562              :                                    const struct TALER_TESTING_Command *cmd,
     563              :                                    struct TALER_TESTING_Interpreter *is)
     564              : {
     565            2 :   struct MerchantPollOrdersConcludeState *poc = cls;
     566              :   const struct TALER_TESTING_Command *poll_cmd;
     567              :   struct MerchantPollOrdersStartState *pos;
     568              : 
     569            2 :   poc->is = is;
     570              :   poll_cmd =
     571            2 :     TALER_TESTING_interpreter_lookup_command (is,
     572              :                                               poc->start_reference);
     573            2 :   if (NULL == poll_cmd)
     574            0 :     TALER_TESTING_FAIL (poc->is);
     575            2 :   GNUNET_assert (poll_cmd->run == &merchant_poll_orders_start_run);
     576            2 :   pos = poll_cmd->cls;
     577            2 :   pos->cs = poc;
     578            2 :   if (NULL == pos->ogh)
     579            2 :     poc->task = GNUNET_SCHEDULER_add_now (&conclude_task,
     580              :                                           poc);
     581              :   else
     582            0 :     poc->task = GNUNET_SCHEDULER_add_at (pos->deadline,
     583              :                                          &conclude_task,
     584              :                                          poc);
     585              : }
     586              : 
     587              : 
     588              : /**
     589              :  * Free the state of a "GET orders" CMD, and possibly
     590              :  * cancel a pending operation thereof.
     591              :  *
     592              :  * @param cls closure.
     593              :  * @param cmd command being run.
     594              :  */
     595              : static void
     596            2 : merchant_poll_orders_conclude_cleanup (void *cls,
     597              :                                        const struct TALER_TESTING_Command *cmd)
     598              : {
     599            2 :   struct MerchantPollOrdersConcludeState *poc = cls;
     600              : 
     601            2 :   if (NULL != poc->task)
     602              :   {
     603            0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     604              :                 "Command `%s' was not terminated\n",
     605              :                 TALER_TESTING_interpreter_get_current_label (
     606              :                   poc->is));
     607            0 :     GNUNET_SCHEDULER_cancel (poc->task);
     608            0 :     poc->task = NULL;
     609              :   }
     610            2 :   GNUNET_free (poc);
     611            2 : }
     612              : 
     613              : 
     614              : struct TALER_TESTING_Command
     615            2 : TALER_TESTING_cmd_poll_orders_conclude (const char *label,
     616              :                                         unsigned int http_status,
     617              :                                         const char *poll_start_reference)
     618              : {
     619              :   struct MerchantPollOrdersConcludeState *poc;
     620              : 
     621            2 :   poc = GNUNET_new (struct MerchantPollOrdersConcludeState);
     622            2 :   poc->start_reference = poll_start_reference;
     623            2 :   poc->expected_http_status = http_status;
     624              :   {
     625            2 :     struct TALER_TESTING_Command cmd = {
     626              :       .cls = poc,
     627              :       .label = label,
     628              :       .run = &merchant_poll_orders_conclude_run,
     629              :       .cleanup = &merchant_poll_orders_conclude_cleanup
     630              :     };
     631              : 
     632            2 :     return cmd;
     633              :   }
     634              : }
     635              : 
     636              : 
     637              : /* end of testing_api_cmd_get_orders.c */
        

Generated by: LCOV version 2.0-1