LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_wallet_get_order.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.3 % 247 186
Test Date: 2025-10-31 14:20:14 Functions: 100.0 % 15 15

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 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_api_cmd_wallet_get_order.c
      21              :  * @brief command to test GET /order/$ORDER_ID
      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_merchant_service.h"
      28              : #include "taler_merchant_testing_lib.h"
      29              : 
      30              : 
      31              : /**
      32              :  * State for a GET /orders/$ORDER_ID CMD.
      33              :  */
      34              : struct WalletGetOrderState
      35              : {
      36              :   /**
      37              :    * The merchant base URL.
      38              :    */
      39              :   const char *merchant_url;
      40              : 
      41              :   /**
      42              :    * Expected HTTP response code for this CMD.
      43              :    */
      44              :   unsigned int http_status;
      45              : 
      46              :   /**
      47              :    * The handle to the current GET /orders/$ORDER_ID request.
      48              :    */
      49              :   struct TALER_MERCHANT_OrderWalletGetHandle *ogh;
      50              : 
      51              :   /**
      52              :    * The interpreter state.
      53              :    */
      54              :   struct TALER_TESTING_Interpreter *is;
      55              : 
      56              :   /**
      57              :    * Reference to a command that created an order.
      58              :    */
      59              :   const char *order_reference;
      60              : 
      61              :   /**
      62              :    * Reference to a command that created a paid
      63              :    * equivalent order that we expect to be referred
      64              :    * to during repurchase detection, or NULL.
      65              :    */
      66              :   const char *repurchase_order_ref;
      67              : 
      68              :   /**
      69              :    * Session Id the order needs to be bound to.
      70              :    */
      71              :   const char *session_id;
      72              : 
      73              :   /**
      74              :    * Whether the order was paid or not.
      75              :    */
      76              :   bool paid;
      77              : 
      78              :   /**
      79              :    * Whether the order was refunded or not.
      80              :    */
      81              :   bool refunded;
      82              : 
      83              :   /**
      84              :    * Whether the order has refunds pending.
      85              :    */
      86              :   bool refund_pending;
      87              : };
      88              : 
      89              : 
      90              : /**
      91              :  * Callback to process a GET /orders/$ID request
      92              :  *
      93              :  * @param cls closure
      94              :  * @param owgr response details
      95              :  */
      96              : static void
      97           21 : wallet_get_order_cb (
      98              :   void *cls,
      99              :   const struct TALER_MERCHANT_OrderWalletGetResponse *owgr)
     100              : {
     101           21 :   struct WalletGetOrderState *gos = cls;
     102           21 :   const struct TALER_MERCHANT_HttpResponse *hr = &owgr->hr;
     103              : 
     104           21 :   gos->ogh = NULL;
     105           21 :   if (gos->http_status != hr->http_status)
     106              :   {
     107            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     108              :                 "Unexpected response code %u (%d) to command %s\n",
     109              :                 hr->http_status,
     110              :                 (int) hr->ec,
     111              :                 TALER_TESTING_interpreter_get_current_label (gos->is));
     112            0 :     TALER_TESTING_interpreter_fail (gos->is);
     113            0 :     return;
     114              :   }
     115           21 :   switch (hr->http_status)
     116              :   {
     117           14 :   case MHD_HTTP_OK:
     118           14 :     if (gos->refunded != owgr->details.ok.refunded)
     119              :     {
     120            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     121              :                   "Order refunded does not match\n");
     122            0 :       TALER_TESTING_interpreter_fail (gos->is);
     123            0 :       return;
     124              :     }
     125           14 :     if (gos->refund_pending != owgr->details.ok.refund_pending)
     126              :     {
     127            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     128              :                   "Order refund pending does not match\n");
     129            0 :       TALER_TESTING_interpreter_fail (gos->is);
     130            0 :       return;
     131              :     }
     132           14 :     break;
     133            7 :   case MHD_HTTP_PAYMENT_REQUIRED:
     134              :     {
     135              :       struct TALER_MERCHANT_PayUriData pud;
     136              :       const struct TALER_TESTING_Command *order_cmd;
     137              :       const char *order_id;
     138              :       const struct TALER_ClaimTokenP *claim_token;
     139              : 
     140            7 :       if (NULL != gos->repurchase_order_ref)
     141              :       {
     142              :         const struct TALER_TESTING_Command *rep_cmd;
     143              :         const char *rep_id;
     144              :         const char *ri;
     145              : 
     146            2 :         rep_cmd = TALER_TESTING_interpreter_lookup_command (
     147              :           gos->is,
     148              :           gos->repurchase_order_ref);
     149            2 :         if (GNUNET_OK !=
     150            2 :             TALER_TESTING_get_trait_order_id (rep_cmd,
     151              :                                               &rep_id))
     152              :         {
     153            0 :           TALER_TESTING_FAIL (gos->is);
     154              :         }
     155            2 :         ri = owgr->details.payment_required.already_paid_order_id;
     156            2 :         if ( (NULL == ri) ||
     157              :              (0 !=
     158            2 :               strcmp (ri,
     159              :                       rep_id)) )
     160              :         {
     161            0 :           TALER_TESTING_FAIL (gos->is);
     162              :         }
     163              :       }
     164              : 
     165            7 :       if (GNUNET_OK !=
     166            7 :           TALER_MERCHANT_parse_pay_uri (
     167            7 :             owgr->details.payment_required.taler_pay_uri,
     168              :             &pud))
     169              :       {
     170            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     171              :                     "Taler pay uri `%s' is malformed\n",
     172              :                     owgr->details.payment_required.taler_pay_uri);
     173            0 :         TALER_TESTING_interpreter_fail (gos->is);
     174            0 :         return;
     175              :       }
     176              : 
     177            7 :       order_cmd = TALER_TESTING_interpreter_lookup_command (
     178              :         gos->is,
     179              :         gos->order_reference);
     180              : 
     181            7 :       if (GNUNET_OK !=
     182            7 :           TALER_TESTING_get_trait_order_id (order_cmd,
     183              :                                             &order_id))
     184              :       {
     185            0 :         TALER_MERCHANT_parse_pay_uri_free (&pud);
     186            0 :         TALER_TESTING_FAIL (gos->is);
     187              :       }
     188              : 
     189            7 :       if (GNUNET_OK !=
     190            7 :           TALER_TESTING_get_trait_claim_token (order_cmd,
     191              :                                                &claim_token))
     192              :       {
     193            0 :         TALER_MERCHANT_parse_pay_uri_free (&pud);
     194            0 :         TALER_TESTING_FAIL (gos->is);
     195              :       }
     196              : 
     197              :       {
     198              :         char *host;
     199              : 
     200            7 :         host = TALER_MERCHANT_TESTING_extract_host (gos->merchant_url);
     201            7 :         if ((0 != strcmp (host,
     202            7 :                           pud.merchant_host)) ||
     203            7 :             (NULL != pud.merchant_prefix_path) ||
     204            7 :             (0 != strcmp (order_id,
     205            7 :                           pud.order_id)) ||
     206            7 :             (NULL != pud.ssid))
     207              :         {
     208            0 :           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     209              :                       "Order pay uri `%s' does not match `%s'\n",
     210              :                       owgr->details.payment_required.taler_pay_uri,
     211              :                       pud.order_id);
     212            0 :           TALER_TESTING_interpreter_fail (gos->is);
     213            0 :           TALER_MERCHANT_parse_pay_uri_free (&pud);
     214            0 :           GNUNET_free (host);
     215            0 :           return;
     216              :         }
     217            7 :         GNUNET_free (host);
     218              :       }
     219              :       /* The claim token is not given in the pay uri if the order
     220              :          has been claimed already. */
     221            7 :       if ((NULL != pud.claim_token) &&
     222            0 :           ((NULL == claim_token) ||
     223            0 :            (0 != GNUNET_memcmp (claim_token,
     224              :                                 pud.claim_token))))
     225              :       {
     226            0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     227              :                     "Order pay uri claim token does not match (%d/%d)\n",
     228              :                     NULL == pud.claim_token,
     229              :                     NULL == claim_token);
     230            0 :         TALER_TESTING_interpreter_fail (gos->is);
     231            0 :         TALER_MERCHANT_parse_pay_uri_free (&pud);
     232            0 :         return;
     233              :       }
     234            7 :       TALER_MERCHANT_parse_pay_uri_free (&pud);
     235              :     }
     236            7 :     break;
     237            0 :   default:
     238            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     239              :                 "Unhandled HTTP status.\n");
     240              :   }
     241           21 :   TALER_TESTING_interpreter_next (gos->is);
     242              : }
     243              : 
     244              : 
     245              : /**
     246              :  * Run the "GET order" CMD.
     247              :  *
     248              :  * @param cls closure.
     249              :  * @param cmd command being run now.
     250              :  * @param is interpreter state.
     251              :  */
     252              : static void
     253           21 : wallet_get_order_run (void *cls,
     254              :                       const struct TALER_TESTING_Command *cmd,
     255              :                       struct TALER_TESTING_Interpreter *is)
     256              : {
     257           21 :   struct WalletGetOrderState *gos = cls;
     258              :   const struct TALER_TESTING_Command *order_cmd;
     259              :   const char *order_id;
     260              :   const struct TALER_PrivateContractHashP *h_contract;
     261              : 
     262           21 :   order_cmd = TALER_TESTING_interpreter_lookup_command (
     263              :     is,
     264              :     gos->order_reference);
     265              : 
     266           21 :   if (GNUNET_OK !=
     267           21 :       TALER_TESTING_get_trait_order_id (order_cmd,
     268              :                                         &order_id))
     269            0 :     TALER_TESTING_FAIL (is);
     270              : 
     271           21 :   if (GNUNET_OK !=
     272           21 :       TALER_TESTING_get_trait_h_contract_terms (order_cmd,
     273              :                                                 &h_contract))
     274            0 :     TALER_TESTING_FAIL (is);
     275              : 
     276           21 :   gos->is = is;
     277           21 :   gos->ogh = TALER_MERCHANT_wallet_order_get (
     278              :     TALER_TESTING_interpreter_get_context (is),
     279              :     gos->merchant_url,
     280              :     order_id,
     281              :     h_contract,
     282           21 :     GNUNET_TIME_UNIT_ZERO,
     283              :     gos->session_id,
     284              :     NULL,
     285              :     false,
     286              :     &wallet_get_order_cb,
     287              :     gos);
     288              : }
     289              : 
     290              : 
     291              : /**
     292              :  * Free the state of a "GET order" CMD, and possibly
     293              :  * cancel a pending operation thereof.
     294              :  *
     295              :  * @param cls closure.
     296              :  * @param cmd command being run.
     297              :  */
     298              : static void
     299           21 : wallet_get_order_cleanup (void *cls,
     300              :                           const struct TALER_TESTING_Command *cmd)
     301              : {
     302           21 :   struct WalletGetOrderState *gos = cls;
     303              : 
     304           21 :   if (NULL != gos->ogh)
     305              :   {
     306            0 :     TALER_LOG_WARNING ("Get order operation did not complete\n");
     307            0 :     TALER_MERCHANT_wallet_order_get_cancel (gos->ogh);
     308              :   }
     309           21 :   GNUNET_free (gos);
     310           21 : }
     311              : 
     312              : 
     313              : struct TALER_TESTING_Command
     314           13 : TALER_TESTING_cmd_wallet_get_order (
     315              :   const char *label,
     316              :   const char *merchant_url,
     317              :   const char *order_reference,
     318              :   bool paid,
     319              :   bool refunded,
     320              :   bool refund_pending,
     321              :   unsigned int http_status)
     322              : {
     323              :   struct WalletGetOrderState *gos;
     324              : 
     325           13 :   gos = GNUNET_new (struct WalletGetOrderState);
     326           13 :   gos->merchant_url = merchant_url;
     327           13 :   gos->order_reference = order_reference;
     328           13 :   gos->http_status = http_status;
     329           13 :   gos->paid = paid;
     330           13 :   gos->refunded = refunded;
     331           13 :   gos->refund_pending = refund_pending;
     332              :   {
     333           13 :     struct TALER_TESTING_Command cmd = {
     334              :       .cls = gos,
     335              :       .label = label,
     336              :       .run = &wallet_get_order_run,
     337              :       .cleanup = &wallet_get_order_cleanup
     338              :     };
     339              : 
     340           13 :     return cmd;
     341              :   }
     342              : }
     343              : 
     344              : 
     345              : struct TALER_TESTING_Command
     346            8 : TALER_TESTING_cmd_wallet_get_order2 (
     347              :   const char *label,
     348              :   const char *merchant_url,
     349              :   const char *order_reference,
     350              :   const char *session_id,
     351              :   bool paid,
     352              :   bool refunded,
     353              :   bool refund_pending,
     354              :   const char *repurchase_order_ref,
     355              :   unsigned int http_status)
     356              : {
     357              :   struct WalletGetOrderState *gos;
     358              : 
     359            8 :   gos = GNUNET_new (struct WalletGetOrderState);
     360            8 :   gos->merchant_url = merchant_url;
     361            8 :   gos->order_reference = order_reference;
     362            8 :   gos->http_status = http_status;
     363            8 :   gos->paid = paid;
     364            8 :   gos->session_id = session_id;
     365            8 :   gos->refunded = refunded;
     366            8 :   gos->refund_pending = refund_pending;
     367            8 :   gos->repurchase_order_ref = repurchase_order_ref;
     368              :   {
     369            8 :     struct TALER_TESTING_Command cmd = {
     370              :       .cls = gos,
     371              :       .label = label,
     372              :       .run = &wallet_get_order_run,
     373              :       .cleanup = &wallet_get_order_cleanup
     374              :     };
     375              : 
     376            8 :     return cmd;
     377              :   }
     378              : }
     379              : 
     380              : 
     381              : struct WalletPollOrderConcludeState
     382              : {
     383              :   /**
     384              :    * The interpreter state.
     385              :    */
     386              :   struct TALER_TESTING_Interpreter *is;
     387              : 
     388              :   /**
     389              :    * Reference to a command that can provide a poll order start command.
     390              :    */
     391              :   const char *start_reference;
     392              : 
     393              :   /**
     394              :    * Already paid order ID expected, or NULL for none.
     395              :    */
     396              :   const char *already_paid_order_id;
     397              : 
     398              :   /**
     399              :    * Task to wait for the deadline.
     400              :    */
     401              :   struct GNUNET_SCHEDULER_Task *task;
     402              : 
     403              :   /**
     404              :    * Amount of a refund expected.
     405              :    */
     406              :   struct TALER_Amount expected_refund_amount;
     407              : 
     408              :   /**
     409              :    * Expected HTTP response status code.
     410              :    */
     411              :   unsigned int expected_http_status;
     412              : 
     413              :   /**
     414              :    * Are we expecting a refund?
     415              :    */
     416              :   bool expected_refund;
     417              : };
     418              : 
     419              : 
     420              : struct WalletPollOrderStartState
     421              : {
     422              :   /**
     423              :    * The merchant base URL.
     424              :    */
     425              :   const char *merchant_url;
     426              : 
     427              :   /**
     428              :    * The handle to the current GET /orders/$ORDER_ID request.
     429              :    */
     430              :   struct TALER_MERCHANT_OrderWalletGetHandle *ogh;
     431              : 
     432              :   /**
     433              :    * The interpreter state.
     434              :    */
     435              :   struct TALER_TESTING_Interpreter *is;
     436              : 
     437              :   /**
     438              :    * Reference to a command that created an order.
     439              :    */
     440              :   const char *order_ref;
     441              : 
     442              :   /**
     443              :    * Which session ID to poll for.
     444              :    */
     445              :   const char *session_id;
     446              : 
     447              :   /**
     448              :    * How long to wait for server to return a response.
     449              :    */
     450              :   struct GNUNET_TIME_Relative timeout;
     451              : 
     452              :   /**
     453              :    * Conclude state waiting for completion (if any).
     454              :    */
     455              :   struct WalletPollOrderConcludeState *cs;
     456              : 
     457              :   /**
     458              :    * The HTTP status code returned by the backend.
     459              :    */
     460              :   unsigned int http_status;
     461              : 
     462              :   /**
     463              :    * When the request should be completed by.
     464              :    */
     465              :   struct GNUNET_TIME_Absolute deadline;
     466              : 
     467              :   /**
     468              :    * Minimum refund to wait for.
     469              :    */
     470              :   struct TALER_Amount refund_threshold;
     471              : 
     472              :   /**
     473              :    * Available refund as returned by the merchant.
     474              :    */
     475              :   struct TALER_Amount refund_available;
     476              : 
     477              :   /**
     478              :    * Already paid order ID returned, or NULL for none.
     479              :    */
     480              :   char *already_paid_order_id;
     481              : 
     482              :   /**
     483              :    * Should we poll for a refund?
     484              :    */
     485              :   bool wait_for_refund;
     486              : 
     487              :   /**
     488              :    * Did we receive a refund according to response from the merchant?
     489              :    */
     490              :   bool refunded;
     491              : 
     492              :   /**
     493              :    * Was the order paid according to response from the merchant?
     494              :    */
     495              :   bool paid;
     496              : 
     497              :   /**
     498              :    * Has the order a pending refund according to response from the merchant?
     499              :    */
     500              :   bool refund_pending;
     501              : };
     502              : 
     503              : 
     504              : /**
     505              :  * Task called when either the timeout for the GET /private/order/$ID command
     506              :  * expired or we got a response.  Checks if the result is what we expected.
     507              :  *
     508              :  * @param cls a `struct WalletPollOrderConcludeState`
     509              :  */
     510              : static void
     511            8 : conclude_task (void *cls)
     512              : {
     513            8 :   struct WalletPollOrderConcludeState *ppc = cls;
     514              :   const struct TALER_TESTING_Command *poll_cmd;
     515              :   struct WalletPollOrderStartState *cps;
     516              :   struct GNUNET_TIME_Absolute now;
     517              : 
     518            8 :   ppc->task = NULL;
     519              :   poll_cmd =
     520            8 :     TALER_TESTING_interpreter_lookup_command (ppc->is,
     521              :                                               ppc->start_reference);
     522            8 :   if (NULL == poll_cmd)
     523            0 :     TALER_TESTING_FAIL (ppc->is);
     524            8 :   cps = poll_cmd->cls;
     525            8 :   if (NULL != cps->ogh)
     526              :   {
     527            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     528              :                 "Expected poll GET /orders/$ORDER_ID to have completed, but it did not!\n");
     529            0 :     TALER_TESTING_FAIL (ppc->is);
     530              :   }
     531            8 :   if (cps->http_status != ppc->expected_http_status)
     532              :   {
     533            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     534              :                 "Expected HTTP status %u, got %u\n",
     535              :                 ppc->expected_http_status,
     536              :                 cps->http_status);
     537            0 :     TALER_TESTING_FAIL (ppc->is);
     538              :   }
     539            8 :   if (ppc->expected_refund != cps->refunded)
     540              :   {
     541            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     542              :                 "Order was %srefunded, contrary to our expectations\n",
     543              :                 cps->refunded ? "" : "NOT ");
     544            0 :     TALER_TESTING_FAIL (ppc->is);
     545              :   }
     546            8 :   if ( (NULL == ppc->already_paid_order_id)
     547            8 :        ^ (NULL == cps->already_paid_order_id) )
     548              :   {
     549            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     550              :                 "Mismatch in already paid order IDs: %s vs %s\n",
     551              :                 ppc->already_paid_order_id,
     552              :                 cps->already_paid_order_id);
     553            0 :     TALER_TESTING_FAIL (ppc->is);
     554              :   }
     555            8 :   if ( (NULL != ppc->already_paid_order_id) &&
     556            2 :        (0 != strcmp (ppc->already_paid_order_id,
     557            2 :                      cps->already_paid_order_id) ) )
     558              :   {
     559            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     560              :                 "Mismatch in already paid order IDs: %s vs %s\n",
     561              :                 ppc->already_paid_order_id,
     562              :                 cps->already_paid_order_id);
     563            0 :     TALER_TESTING_FAIL (ppc->is);
     564              :   }
     565              : 
     566            8 :   if (cps->refunded)
     567              :   {
     568            4 :     if (0 != TALER_amount_cmp (&ppc->expected_refund_amount,
     569            4 :                                &cps->refund_available))
     570              :     {
     571            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     572              :                   "Refund amount %s does not match our expectation!\n",
     573              :                   TALER_amount2s (&cps->refund_available));
     574            0 :       TALER_TESTING_FAIL (ppc->is);
     575              :     }
     576              :   }
     577              :   // FIXME: add checks for cps->paid/refund_available status flags?
     578            8 :   now = GNUNET_TIME_absolute_get ();
     579            8 :   if ((GNUNET_TIME_absolute_add (cps->deadline,
     580            8 :                                  GNUNET_TIME_UNIT_SECONDS).abs_value_us <
     581            8 :        now.abs_value_us) )
     582              :   {
     583            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     584              :                 "Expected answer to be delayed until %llu, but got response at %llu\n",
     585              :                 (unsigned long long) cps->deadline.abs_value_us,
     586              :                 (unsigned long long) now.abs_value_us);
     587            0 :     TALER_TESTING_FAIL (ppc->is);
     588              :   }
     589            8 :   TALER_TESTING_interpreter_next (ppc->is);
     590              : }
     591              : 
     592              : 
     593              : /**
     594              :  * Process response from a GET /orders/$ID request
     595              :  *
     596              :  * @param cls a `struct WalletPollOrderStartState *`
     597              :  * @param owgr response details
     598              :  */
     599              : static void
     600            8 : wallet_poll_order_cb (
     601              :   void *cls,
     602              :   const struct TALER_MERCHANT_OrderWalletGetResponse *owgr)
     603              : {
     604            8 :   struct WalletPollOrderStartState *pos = cls;
     605            8 :   const struct TALER_MERCHANT_HttpResponse *hr = &owgr->hr;
     606              : 
     607            8 :   pos->ogh = NULL;
     608            8 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     609              :               "GET /orders/$ID finished with status %u.\n",
     610              :               hr->http_status);
     611            8 :   pos->http_status = hr->http_status;
     612            8 :   switch (hr->http_status)
     613              :   {
     614            6 :   case MHD_HTTP_OK:
     615            6 :     pos->paid = true;
     616            6 :     pos->refunded = owgr->details.ok.refunded;
     617            6 :     pos->refund_pending = owgr->details.ok.refund_pending;
     618            6 :     if (owgr->details.ok.refunded)
     619            4 :       pos->refund_available = owgr->details.ok.refund_amount;
     620            6 :     break;
     621            2 :   case MHD_HTTP_PAYMENT_REQUIRED:
     622            2 :     if (NULL != owgr->details.payment_required.already_paid_order_id)
     623            2 :       pos->already_paid_order_id = GNUNET_strdup (
     624              :         owgr->details.payment_required.already_paid_order_id);
     625            2 :     break;
     626            0 :   default:
     627            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     628              :                 "Unhandled HTTP status.\n");
     629            0 :     break;
     630              :   }
     631            8 :   if ( (NULL != pos->cs) &&
     632            4 :        (NULL != pos->cs->task) )
     633              :   {
     634            4 :     GNUNET_SCHEDULER_cancel (pos->cs->task);
     635            4 :     pos->cs->task = GNUNET_SCHEDULER_add_now (&conclude_task,
     636            4 :                                               pos->cs);
     637              :   }
     638            8 : }
     639              : 
     640              : 
     641              : /**
     642              :  * Run the "GET order" CMD.
     643              :  *
     644              :  * @param cls closure.
     645              :  * @param cmd command being run now.
     646              :  * @param is interpreter state.
     647              :  */
     648              : static void
     649            8 : wallet_poll_order_start_run (void *cls,
     650              :                              const struct TALER_TESTING_Command *cmd,
     651              :                              struct TALER_TESTING_Interpreter *is)
     652              : {
     653            8 :   struct WalletPollOrderStartState *pos = cls;
     654              :   const struct TALER_TESTING_Command *order_cmd;
     655              :   const char *order_id;
     656              :   const struct TALER_PrivateContractHashP *h_contract;
     657              : 
     658            8 :   order_cmd = TALER_TESTING_interpreter_lookup_command (
     659              :     is,
     660              :     pos->order_ref);
     661              : 
     662            8 :   if (GNUNET_OK !=
     663            8 :       TALER_TESTING_get_trait_order_id (order_cmd,
     664              :                                         &order_id))
     665            0 :     TALER_TESTING_FAIL (is);
     666              : 
     667            8 :   if (GNUNET_OK !=
     668            8 :       TALER_TESTING_get_trait_h_contract_terms (order_cmd,
     669              :                                                 &h_contract))
     670            0 :     TALER_TESTING_FAIL (is);
     671              : 
     672              :   /* add 1s grace time to timeout */
     673              :   pos->deadline
     674            8 :     = GNUNET_TIME_absolute_add (GNUNET_TIME_relative_to_absolute (pos->timeout),
     675              :                                 GNUNET_TIME_UNIT_SECONDS);
     676            8 :   pos->is = is;
     677            8 :   pos->ogh = TALER_MERCHANT_wallet_order_get (
     678              :     TALER_TESTING_interpreter_get_context (is),
     679              :     pos->merchant_url,
     680              :     order_id,
     681              :     h_contract,
     682              :     pos->timeout,
     683              :     pos->session_id,
     684            8 :     pos->wait_for_refund
     685              :     ? &pos->refund_threshold
     686              :     : NULL,
     687              :     false,                                           /* await_refund_obtained */
     688              :     &wallet_poll_order_cb,
     689              :     pos);
     690            8 :   GNUNET_assert (NULL != pos->ogh);
     691              :   /* We CONTINUE to run the interpreter while the long-polled command
     692              :      completes asynchronously! */
     693            8 :   TALER_TESTING_interpreter_next (pos->is);
     694              : }
     695              : 
     696              : 
     697              : /**
     698              :  * Free the state of a "GET order" CMD, and possibly
     699              :  * cancel a pending operation thereof.
     700              :  *
     701              :  * @param cls closure.
     702              :  * @param cmd command being run.
     703              :  */
     704              : static void
     705            8 : wallet_poll_order_start_cleanup (void *cls,
     706              :                                  const struct TALER_TESTING_Command *cmd)
     707              : {
     708            8 :   struct WalletPollOrderStartState *pos = cls;
     709              : 
     710            8 :   if (NULL != pos->ogh)
     711              :   {
     712            0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     713              :                 "Command `%s' was not terminated\n",
     714              :                 TALER_TESTING_interpreter_get_current_label (
     715              :                   pos->is));
     716            0 :     TALER_MERCHANT_wallet_order_get_cancel (pos->ogh);
     717              :   }
     718            8 :   GNUNET_free (pos->already_paid_order_id);
     719            8 :   GNUNET_free (pos);
     720            8 : }
     721              : 
     722              : 
     723              : struct TALER_TESTING_Command
     724            8 : TALER_TESTING_cmd_wallet_poll_order_start (
     725              :   const char *label,
     726              :   const char *merchant_url,
     727              :   const char *order_ref,
     728              :   struct GNUNET_TIME_Relative timeout,
     729              :   const char *await_refund)
     730              : {
     731              :   struct WalletPollOrderStartState *pos;
     732              : 
     733            8 :   pos = GNUNET_new (struct WalletPollOrderStartState);
     734            8 :   pos->order_ref = order_ref;
     735            8 :   pos->merchant_url = merchant_url;
     736            8 :   pos->timeout = timeout;
     737            8 :   if (NULL != await_refund)
     738              :   {
     739            4 :     pos->wait_for_refund = true;
     740            4 :     GNUNET_assert (GNUNET_OK ==
     741              :                    TALER_string_to_amount (await_refund,
     742              :                                            &pos->refund_threshold));
     743              :   }
     744              :   {
     745            8 :     struct TALER_TESTING_Command cmd = {
     746              :       .cls = pos,
     747              :       .label = label,
     748              :       .run = &wallet_poll_order_start_run,
     749              :       .cleanup = &wallet_poll_order_start_cleanup
     750              :     };
     751              : 
     752            8 :     return cmd;
     753              :   }
     754              : }
     755              : 
     756              : 
     757              : struct TALER_TESTING_Command
     758            2 : TALER_TESTING_cmd_wallet_poll_order_start2 (
     759              :   const char *label,
     760              :   const char *merchant_url,
     761              :   const char *order_ref,
     762              :   struct GNUNET_TIME_Relative timeout,
     763              :   const char *await_refund,
     764              :   const char *session_id)
     765              : {
     766              :   struct WalletPollOrderStartState *pos;
     767              :   struct TALER_TESTING_Command cmd;
     768              : 
     769            2 :   cmd = TALER_TESTING_cmd_wallet_poll_order_start (label,
     770              :                                                    merchant_url,
     771              :                                                    order_ref,
     772              :                                                    timeout,
     773              :                                                    await_refund);
     774            2 :   pos = cmd.cls;
     775            2 :   pos->session_id = session_id;
     776            2 :   return cmd;
     777              : }
     778              : 
     779              : 
     780              : /**
     781              :  * Run the "GET order conclude" CMD.
     782              :  *
     783              :  * @param cls closure.
     784              :  * @param cmd command being run now.
     785              :  * @param is interpreter state.
     786              :  */
     787              : static void
     788            8 : wallet_poll_order_conclude_run (void *cls,
     789              :                                 const struct TALER_TESTING_Command *cmd,
     790              :                                 struct TALER_TESTING_Interpreter *is)
     791              : {
     792            8 :   struct WalletPollOrderConcludeState *poc = cls;
     793              :   const struct TALER_TESTING_Command *poll_cmd;
     794              :   struct WalletPollOrderStartState *pos;
     795              : 
     796            8 :   poc->is = is;
     797              :   poll_cmd =
     798            8 :     TALER_TESTING_interpreter_lookup_command (is,
     799              :                                               poc->start_reference);
     800            8 :   if (NULL == poll_cmd)
     801            0 :     TALER_TESTING_FAIL (poc->is);
     802            8 :   GNUNET_assert (poll_cmd->run == &wallet_poll_order_start_run);
     803            8 :   pos = poll_cmd->cls;
     804            8 :   pos->cs = poc;
     805            8 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     806              :               "Waiting on GET /orders/$ID of %s (%s)\n",
     807              :               poc->start_reference,
     808              :               (NULL == pos->ogh)
     809              :               ? "finished"
     810              :               : "active");
     811            8 :   if (NULL == pos->ogh)
     812            4 :     poc->task = GNUNET_SCHEDULER_add_now (&conclude_task,
     813              :                                           poc);
     814              :   else
     815            4 :     poc->task = GNUNET_SCHEDULER_add_at (pos->deadline,
     816              :                                          &conclude_task,
     817              :                                          poc);
     818              : }
     819              : 
     820              : 
     821              : /**
     822              :  * Free the state of a "GET order" CMD, and possibly
     823              :  * cancel a pending operation thereof.
     824              :  *
     825              :  * @param cls closure.
     826              :  * @param cmd command being run.
     827              :  */
     828              : static void
     829            8 : wallet_poll_order_conclude_cleanup (void *cls,
     830              :                                     const struct TALER_TESTING_Command *cmd)
     831              : {
     832            8 :   struct WalletPollOrderConcludeState *poc = cls;
     833              : 
     834            8 :   if (NULL != poc->task)
     835              :   {
     836            0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     837              :                 "Command `%s' was not terminated\n",
     838              :                 TALER_TESTING_interpreter_get_current_label (
     839              :                   poc->is));
     840            0 :     GNUNET_SCHEDULER_cancel (poc->task);
     841            0 :     poc->task = NULL;
     842              :   }
     843            8 :   GNUNET_free (poc);
     844            8 : }
     845              : 
     846              : 
     847              : struct TALER_TESTING_Command
     848            8 : TALER_TESTING_cmd_wallet_poll_order_conclude (
     849              :   const char *label,
     850              :   unsigned int expected_http_status,
     851              :   const char *expected_refund_amount,
     852              :   const char *poll_start_reference)
     853              : {
     854              :   struct WalletPollOrderConcludeState *cps;
     855              : 
     856            8 :   cps = GNUNET_new (struct WalletPollOrderConcludeState);
     857            8 :   cps->start_reference = poll_start_reference;
     858            8 :   cps->expected_http_status = expected_http_status;
     859            8 :   if (NULL != expected_refund_amount)
     860              :   {
     861            4 :     cps->expected_refund = true;
     862            4 :     GNUNET_assert (GNUNET_OK ==
     863              :                    TALER_string_to_amount (expected_refund_amount,
     864              :                                            &cps->expected_refund_amount));
     865              :   }
     866              :   {
     867            8 :     struct TALER_TESTING_Command cmd = {
     868              :       .cls = cps,
     869              :       .label = label,
     870              :       .run = &wallet_poll_order_conclude_run,
     871              :       .cleanup = &wallet_poll_order_conclude_cleanup
     872              :     };
     873              : 
     874            8 :     return cmd;
     875              :   }
     876              : }
     877              : 
     878              : 
     879              : struct TALER_TESTING_Command
     880            2 : TALER_TESTING_cmd_wallet_poll_order_conclude2 (
     881              :   const char *label,
     882              :   unsigned int expected_http_status,
     883              :   const char *expected_refund_amount,
     884              :   const char *poll_start_reference,
     885              :   const char *already_paid_order_id)
     886              : {
     887              :   struct WalletPollOrderConcludeState *cps;
     888              :   struct TALER_TESTING_Command cmd;
     889              : 
     890            2 :   cmd = TALER_TESTING_cmd_wallet_poll_order_conclude (
     891              :     label,
     892              :     expected_http_status,
     893              :     expected_refund_amount,
     894              :     poll_start_reference);
     895            2 :   cps = cmd.cls;
     896            2 :   cps->already_paid_order_id = already_paid_order_id;
     897            2 :   return cmd;
     898              : }
     899              : 
     900              : 
     901              : /* end of testing_api_cmd_wallet_get_order.c */
        

Generated by: LCOV version 2.0-1