LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_post_orders.c (source / functions) Hit Total Coverage
Test: GNU Taler merchant coverage report Lines: 0 221 0.0 %
Date: 2022-08-25 06:17:04 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-2021 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify
       6             :   it under the terms of the GNU General Public License as
       7             :   published by the Free Software Foundation; either version 3, or
       8             :   (at your option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful, but
      11             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public
      16             :   License along with TALER; see the file COPYING.  If not, see
      17             :   <http://www.gnu.org/licenses/>
      18             : */
      19             : 
      20             : /**
      21             :  * @file testing_api_cmd_post_orders.c
      22             :  * @brief command to run POST /orders
      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             :  * State for a "POST /orders" CMD.
      34             :  */
      35             : struct OrdersState
      36             : {
      37             : 
      38             :   /**
      39             :    * Expected status code.
      40             :    */
      41             :   unsigned int http_status;
      42             : 
      43             :   /**
      44             :    * Order id.
      45             :    */
      46             :   const char *order_id;
      47             : 
      48             :   /**
      49             :    * The order id we expect the merchant to assign (if not NULL).
      50             :    */
      51             :   const char *expected_order_id;
      52             : 
      53             :   /**
      54             :    * Contract terms obtained from the backend.
      55             :    */
      56             :   json_t *contract_terms;
      57             : 
      58             :   /**
      59             :    * Order submitted to the backend.
      60             :    */
      61             :   json_t *order_terms;
      62             : 
      63             :   /**
      64             :    * Contract terms hash code.
      65             :    */
      66             :   struct TALER_PrivateContractHashP h_contract_terms;
      67             : 
      68             :   /**
      69             :    * The /orders operation handle.
      70             :    */
      71             :   struct TALER_MERCHANT_PostOrdersHandle *po;
      72             : 
      73             :   /**
      74             :    * The (initial) POST /orders/$ID/claim operation handle.
      75             :    * The logic is such that after an order creation,
      76             :    * we immediately claim the order.
      77             :    */
      78             :   struct TALER_MERCHANT_OrderClaimHandle *och;
      79             : 
      80             :   /**
      81             :    * The nonce.
      82             :    */
      83             :   struct GNUNET_CRYPTO_EddsaPublicKey nonce;
      84             : 
      85             :   /**
      86             :    * Whether to generate a claim token.
      87             :    */
      88             :   bool make_claim_token;
      89             : 
      90             :   /**
      91             :    * The claim token
      92             :    */
      93             :   struct TALER_ClaimTokenP claim_token;
      94             : 
      95             :   /**
      96             :    * URL of the merchant backend.
      97             :    */
      98             :   const char *merchant_url;
      99             : 
     100             :   /**
     101             :    * The interpreter state.
     102             :    */
     103             :   struct TALER_TESTING_Interpreter *is;
     104             : 
     105             :   /**
     106             :    * Merchant signature over the orders.
     107             :    */
     108             :   struct TALER_MerchantSignatureP merchant_sig;
     109             : 
     110             :   /**
     111             :    * Merchant public key.
     112             :    */
     113             :   struct TALER_MerchantPublicKeyP merchant_pub;
     114             : 
     115             :   /**
     116             :    * The payment target for the order
     117             :    */
     118             :   const char *payment_target;
     119             : 
     120             :   /**
     121             :    * The products the order is purchasing.
     122             :    */
     123             :   const char *products;
     124             : 
     125             :   /**
     126             :    * The locks that the order should release.
     127             :    */
     128             :   const char *locks;
     129             : 
     130             :   /**
     131             :    * Should the command also CLAIM the order?
     132             :    */
     133             :   bool with_claim;
     134             : 
     135             :   /**
     136             :    * If not NULL, the command should duplicate the request and verify the
     137             :    * response is the same as in this command.
     138             :    */
     139             :   const char *duplicate_of;
     140             : };
     141             : 
     142             : 
     143             : /**
     144             :  * Offer internal data to other commands.
     145             :  *
     146             :  * @param cls closure
     147             :  * @param[out] ret result (could be anything)
     148             :  * @param trait name of the trait
     149             :  * @param index index number of the object to extract.
     150             :  * @return #GNUNET_OK on success
     151             :  */
     152             : static enum GNUNET_GenericReturnValue
     153           0 : orders_traits (void *cls,
     154             :                const void **ret,
     155             :                const char *trait,
     156             :                unsigned int index)
     157             : {
     158           0 :   struct OrdersState *ps = cls;
     159             :   struct TALER_TESTING_Trait traits[] = {
     160           0 :     TALER_TESTING_make_trait_order_id (&ps->order_id),
     161           0 :     TALER_TESTING_make_trait_contract_terms (ps->contract_terms),
     162           0 :     TALER_TESTING_make_trait_order_terms (ps->order_terms),
     163           0 :     TALER_TESTING_make_trait_h_contract_terms (&ps->h_contract_terms),
     164           0 :     TALER_TESTING_make_trait_merchant_sig (&ps->merchant_sig),
     165           0 :     TALER_TESTING_make_trait_merchant_pub (&ps->merchant_pub),
     166           0 :     TALER_TESTING_make_trait_claim_nonce (&ps->nonce),
     167           0 :     TALER_TESTING_make_trait_claim_token (&ps->claim_token),
     168           0 :     TALER_TESTING_trait_end ()
     169             :   };
     170             : 
     171           0 :   return TALER_TESTING_get_trait (traits,
     172             :                                   ret,
     173             :                                   trait,
     174             :                                   index);
     175             : }
     176             : 
     177             : 
     178             : /**
     179             :  * Used to fill the "orders" CMD state with backend-provided
     180             :  * values.  Also double-checks that the order was correctly
     181             :  * created.
     182             :  *
     183             :  * @param cls closure
     184             :  * @param hr HTTP response we got
     185             :  * @param contract_terms contract terms of this order
     186             :  * @param sig merchant's signature
     187             :  * @param hash hash over the contract
     188             :  */
     189             : static void
     190           0 : orders_claim_cb (void *cls,
     191             :                  const struct TALER_MERCHANT_HttpResponse *hr,
     192             :                  const json_t *contract_terms,
     193             :                  const struct TALER_MerchantSignatureP *sig,
     194             :                  const struct TALER_PrivateContractHashP *hash)
     195             : {
     196           0 :   struct OrdersState *ps = cls;
     197             :   struct TALER_MerchantPublicKeyP merchant_pub;
     198             :   const char *error_name;
     199             :   unsigned int error_line;
     200             :   struct GNUNET_JSON_Specification spec[] = {
     201           0 :     GNUNET_JSON_spec_fixed_auto ("merchant_pub",
     202             :                                  &merchant_pub),
     203           0 :     GNUNET_JSON_spec_end ()
     204             :   };
     205             : 
     206           0 :   ps->och = NULL;
     207           0 :   if (ps->http_status != hr->http_status)
     208             :   {
     209           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     210             :                 "Expected status %u, got %u\n",
     211             :                 ps->http_status,
     212             :                 hr->http_status);
     213           0 :     TALER_TESTING_FAIL (ps->is);
     214             :   }
     215             : 
     216           0 :   ps->contract_terms = json_deep_copy (contract_terms);
     217           0 :   ps->h_contract_terms = *hash;
     218           0 :   ps->merchant_sig = *sig;
     219           0 :   if (GNUNET_OK !=
     220           0 :       GNUNET_JSON_parse (contract_terms,
     221             :                          spec,
     222             :                          &error_name,
     223             :                          &error_line))
     224             :   {
     225             :     char *log;
     226             : 
     227           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     228             :                 "Parser failed on %s:%u\n",
     229             :                 error_name,
     230             :                 error_line);
     231           0 :     log = json_dumps (ps->contract_terms,
     232             :                       JSON_INDENT (1));
     233           0 :     fprintf (stderr,
     234             :              "%s\n",
     235             :              log);
     236           0 :     free (log);
     237           0 :     TALER_TESTING_FAIL (ps->is);
     238             :   }
     239           0 :   ps->merchant_pub = merchant_pub;
     240           0 :   TALER_TESTING_interpreter_next (ps->is);
     241             : }
     242             : 
     243             : 
     244             : /**
     245             :  * Callback that processes the response following a
     246             :  * POST /orders.  NOTE: no contract terms are included
     247             :  * here; they need to be taken via the "orders lookup"
     248             :  * method.
     249             :  *
     250             :  * @param cls closure.
     251             :  * @param por details about the response
     252             :  */
     253             : static void
     254           0 : order_cb (void *cls,
     255             :           const struct TALER_MERCHANT_PostOrdersReply *por)
     256             : {
     257           0 :   struct OrdersState *ps = cls;
     258             : 
     259           0 :   ps->po = NULL;
     260           0 :   if (ps->http_status != por->hr.http_status)
     261             :   {
     262           0 :     TALER_LOG_ERROR ("Given vs expected: %u(%d) vs %u\n",
     263             :                      por->hr.http_status,
     264             :                      (int) por->hr.ec,
     265             :                      ps->http_status);
     266           0 :     TALER_TESTING_FAIL (ps->is);
     267             :   }
     268           0 :   if (0 == ps->http_status)
     269             :   {
     270           0 :     TALER_LOG_DEBUG ("/orders, expected 0 status code\n");
     271           0 :     TALER_TESTING_interpreter_next (ps->is);
     272           0 :     return;
     273             :   }
     274           0 :   switch (por->hr.http_status)
     275             :   {
     276           0 :   case MHD_HTTP_OK:
     277           0 :     if (NULL != por->details.ok.token)
     278           0 :       ps->claim_token = *por->details.ok.token;
     279           0 :     ps->order_id = GNUNET_strdup (por->details.ok.order_id);
     280           0 :     if ((NULL != ps->expected_order_id) &&
     281           0 :         (0 != strcmp (por->details.ok.order_id,
     282             :                       ps->expected_order_id)))
     283             :     {
     284           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     285             :                   "Order id assigned does not match\n");
     286           0 :       TALER_TESTING_interpreter_fail (ps->is);
     287           0 :       return;
     288             :     }
     289           0 :     if (NULL != ps->duplicate_of)
     290             :     {
     291             :       const struct TALER_TESTING_Command *order_cmd;
     292             :       const struct TALER_ClaimTokenP *prev_token;
     293           0 :       struct TALER_ClaimTokenP zero_token = {0};
     294             : 
     295           0 :       order_cmd = TALER_TESTING_interpreter_lookup_command (
     296             :         ps->is,
     297             :         ps->duplicate_of);
     298           0 :       if (GNUNET_OK !=
     299           0 :           TALER_TESTING_get_trait_claim_token (order_cmd,
     300             :                                                &prev_token))
     301             :       {
     302           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     303             :                     "Could not fetch previous order claim token\n");
     304           0 :         TALER_TESTING_interpreter_fail (ps->is);
     305           0 :         return;
     306             :       }
     307           0 :       if (NULL == por->details.ok.token)
     308           0 :         prev_token = &zero_token;
     309           0 :       if (0 != GNUNET_memcmp (prev_token,
     310             :                               por->details.ok.token))
     311             :       {
     312           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     313             :                     "Claim tokens for identical requests do not match\n");
     314           0 :         TALER_TESTING_interpreter_fail (ps->is);
     315           0 :         return;
     316             :       }
     317             :     }
     318           0 :     break;
     319           0 :   case MHD_HTTP_NOT_FOUND:
     320           0 :     TALER_TESTING_interpreter_next (ps->is);
     321           0 :     return;
     322           0 :   case MHD_HTTP_GONE:
     323           0 :     TALER_TESTING_interpreter_next (ps->is);
     324           0 :     return;
     325           0 :   case MHD_HTTP_CONFLICT:
     326           0 :     TALER_TESTING_interpreter_next (ps->is);
     327           0 :     return;
     328           0 :   default:
     329             :     {
     330           0 :       char *s = json_dumps (por->hr.reply,
     331             :                             JSON_COMPACT);
     332           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     333             :                   "Unexpected status code from /orders: %u (%d) at %s; JSON: %s\n",
     334             :                   por->hr.http_status,
     335             :                   (int) por->hr.ec,
     336             :                   TALER_TESTING_interpreter_get_current_label (ps->is),
     337             :                   s);
     338           0 :       GNUNET_free (s);
     339             :       /**
     340             :        * Not failing, as test cases are _supposed_
     341             :        * to create non 200 OK situations.
     342             :        */
     343           0 :       TALER_TESTING_interpreter_next (ps->is);
     344             :     }
     345           0 :     return;
     346             :   }
     347             : 
     348           0 :   if (! ps->with_claim)
     349             :   {
     350           0 :     TALER_TESTING_interpreter_next (ps->is);
     351           0 :     return;
     352             :   }
     353           0 :   if (NULL ==
     354           0 :       (ps->och = TALER_MERCHANT_order_claim (ps->is->ctx,
     355             :                                              ps->merchant_url,
     356             :                                              ps->order_id,
     357           0 :                                              &ps->nonce,
     358           0 :                                              &ps->claim_token,
     359             :                                              &orders_claim_cb,
     360             :                                              ps)))
     361           0 :     TALER_TESTING_FAIL (ps->is);
     362             : }
     363             : 
     364             : 
     365             : /**
     366             :  * Run a "orders" CMD.
     367             :  *
     368             :  * @param cls closure.
     369             :  * @param cmd command currently being run.
     370             :  * @param is interpreter state.
     371             :  */
     372             : static void
     373           0 : orders_run (void *cls,
     374             :             const struct TALER_TESTING_Command *cmd,
     375             :             struct TALER_TESTING_Interpreter *is)
     376             : {
     377           0 :   struct OrdersState *ps = cls;
     378             : 
     379           0 :   ps->is = is;
     380           0 :   if (NULL == json_object_get (ps->order_terms,
     381             :                                "order_id"))
     382             :   {
     383             :     struct GNUNET_TIME_Absolute now;
     384             :     char *order_id;
     385             : 
     386           0 :     now = GNUNET_TIME_absolute_get_monotonic (is->cfg);
     387           0 :     order_id = GNUNET_STRINGS_data_to_string_alloc (
     388             :       &now,
     389             :       sizeof (now));
     390           0 :     GNUNET_assert (0 ==
     391             :                    json_object_set_new (ps->order_terms,
     392             :                                         "order_id",
     393             :                                         json_string (order_id)));
     394           0 :     GNUNET_free (order_id);
     395             :   }
     396           0 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     397           0 :                               &ps->nonce,
     398             :                               sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
     399           0 :   ps->po = TALER_MERCHANT_orders_post (is->ctx,
     400             :                                        ps->merchant_url,
     401           0 :                                        ps->order_terms,
     402           0 :                                        GNUNET_TIME_UNIT_ZERO,
     403             :                                        &order_cb,
     404             :                                        ps);
     405           0 :   GNUNET_assert (NULL != ps->po);
     406           0 : }
     407             : 
     408             : 
     409             : /**
     410             :  * Run a "orders" CMD.
     411             :  *
     412             :  * @param cls closure.
     413             :  * @param cmd command currently being run.
     414             :  * @param is interpreter state.
     415             :  */
     416             : static void
     417           0 : orders_run2 (void *cls,
     418             :              const struct TALER_TESTING_Command *cmd,
     419             :              struct TALER_TESTING_Interpreter *is)
     420             : {
     421           0 :   struct OrdersState *ps = cls;
     422             :   const json_t *order;
     423           0 :   char *products_string = GNUNET_strdup (ps->products);
     424           0 :   char *locks_string = GNUNET_strdup (ps->locks);
     425             :   char *token;
     426           0 :   struct TALER_MERCHANT_InventoryProduct *products = NULL;
     427           0 :   unsigned int products_length = 0;
     428           0 :   const char **locks = NULL;
     429           0 :   unsigned int locks_length = 0;
     430             : 
     431           0 :   ps->is = is;
     432           0 :   if (NULL != ps->duplicate_of)
     433             :   {
     434             :     const struct TALER_TESTING_Command *order_cmd;
     435             :     const json_t *ct;
     436             : 
     437           0 :     order_cmd = TALER_TESTING_interpreter_lookup_command (
     438             :       is,
     439             :       ps->duplicate_of);
     440           0 :     if (GNUNET_OK !=
     441           0 :         TALER_TESTING_get_trait_order_terms (order_cmd,
     442             :                                              &ct))
     443             :     {
     444           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     445             :                   "Could not fetch previous order string\n");
     446           0 :       TALER_TESTING_interpreter_fail (is);
     447           0 :       return;
     448             :     }
     449           0 :     order = (json_t *) ct;
     450             :   }
     451             :   else
     452             :   {
     453           0 :     if (NULL == json_object_get (ps->order_terms,
     454             :                                  "order_id"))
     455             :     {
     456             :       struct GNUNET_TIME_Absolute now;
     457             :       char *order_id;
     458             : 
     459           0 :       now = GNUNET_TIME_absolute_get_monotonic (is->cfg);
     460           0 :       order_id = GNUNET_STRINGS_data_to_string_alloc (
     461             :         &now.abs_value_us,
     462             :         sizeof (now.abs_value_us));
     463           0 :       GNUNET_assert (0 ==
     464             :                      json_object_set_new (ps->order_terms,
     465             :                                           "order_id",
     466             :                                           json_string (order_id)));
     467           0 :       GNUNET_free (order_id);
     468             :     }
     469           0 :     order = ps->order_terms;
     470             :   }
     471           0 :   if (NULL == order)
     472             :   {
     473           0 :     GNUNET_break (0);
     474           0 :     TALER_TESTING_interpreter_fail (is);
     475           0 :     return;
     476             :   }
     477             : 
     478           0 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     479           0 :                               &ps->nonce,
     480             :                               sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
     481           0 :   for (token = strtok (products_string, ";");
     482             :        NULL != token;
     483           0 :        token = strtok (NULL, ";"))
     484             :   {
     485             :     char *ctok;
     486             :     struct TALER_MERCHANT_InventoryProduct pd;
     487             : 
     488             :     /* Token syntax is "[product_id]/[quantity]" */
     489           0 :     ctok = strchr (token, '/');
     490           0 :     if (NULL != ctok)
     491             :     {
     492           0 :       *ctok = '\0';
     493           0 :       ctok++;
     494           0 :       if (1 != sscanf (ctok,
     495             :                        "%u",
     496             :                        &pd.quantity))
     497             :       {
     498           0 :         GNUNET_break (0);
     499           0 :         break;
     500             :       }
     501             :     }
     502             :     else
     503             :     {
     504           0 :       pd.quantity = 1;
     505             :     }
     506           0 :     pd.product_id = token;
     507             : 
     508           0 :     GNUNET_array_append (products,
     509             :                          products_length,
     510             :                          pd);
     511             :   }
     512           0 :   for (token = strtok (locks_string, ";");
     513             :        NULL != token;
     514           0 :        token = strtok (NULL, ";"))
     515             :   {
     516             :     const struct TALER_TESTING_Command *lock_cmd;
     517             :     const char **uuid;
     518             : 
     519           0 :     lock_cmd = TALER_TESTING_interpreter_lookup_command (
     520             :       is,
     521             :       token);
     522             : 
     523           0 :     if (GNUNET_OK !=
     524           0 :         TALER_TESTING_get_trait_lock_uuid (lock_cmd,
     525             :                                            &uuid))
     526             :     {
     527           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     528             :                   "Could not fetch lock uuid\n");
     529           0 :       TALER_TESTING_interpreter_fail (is);
     530           0 :       return;
     531             :     }
     532             : 
     533           0 :     GNUNET_array_append (locks,
     534             :                          locks_length,
     535             :                          *uuid);
     536             :   }
     537           0 :   ps->po = TALER_MERCHANT_orders_post2 (is->ctx,
     538             :                                         ps->merchant_url,
     539             :                                         order,
     540           0 :                                         GNUNET_TIME_UNIT_ZERO,
     541             :                                         ps->payment_target,
     542             :                                         products_length,
     543             :                                         products,
     544             :                                         locks_length,
     545             :                                         locks,
     546           0 :                                         ps->make_claim_token,
     547             :                                         &order_cb,
     548             :                                         ps);
     549           0 :   GNUNET_free (products_string);
     550           0 :   GNUNET_free (locks_string);
     551           0 :   GNUNET_array_grow (products,
     552             :                      products_length,
     553             :                      0);
     554           0 :   GNUNET_array_grow (locks,
     555             :                      locks_length,
     556             :                      0);
     557           0 :   GNUNET_assert (NULL != ps->po);
     558             : }
     559             : 
     560             : 
     561             : /**
     562             :  * Free the state of a "orders" CMD, and possibly
     563             :  * cancel it if it did not complete.
     564             :  *
     565             :  * @param cls closure.
     566             :  * @param cmd command being freed.
     567             :  */
     568             : static void
     569           0 : orders_cleanup (void *cls,
     570             :                 const struct TALER_TESTING_Command *cmd)
     571             : {
     572           0 :   struct OrdersState *ps = cls;
     573             : 
     574           0 :   if (NULL != ps->po)
     575             :   {
     576           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     577             :                 "Command '%s' did not complete (orders put)\n",
     578             :                 cmd->label);
     579           0 :     TALER_MERCHANT_orders_post_cancel (ps->po);
     580           0 :     ps->po = NULL;
     581             :   }
     582             : 
     583           0 :   if (NULL != ps->och)
     584             :   {
     585           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     586             :                 "Command '%s' did not complete (orders lookup)\n",
     587             :                 cmd->label);
     588           0 :     TALER_MERCHANT_order_claim_cancel (ps->och);
     589           0 :     ps->och = NULL;
     590             :   }
     591             : 
     592           0 :   json_decref (ps->contract_terms);
     593           0 :   json_decref (ps->order_terms);
     594           0 :   GNUNET_free_nz ((void *) ps->order_id);
     595           0 :   GNUNET_free (ps);
     596           0 : }
     597             : 
     598             : 
     599             : /**
     600             :  * Mark part of the contract terms as possible to forget.
     601             :  *
     602             :  * @param cls pointer to the result of the forget operation.
     603             :  * @param object_id name of the object to forget.
     604             :  * @param parent parent of the object at @e object_id.
     605             :  */
     606             : static void
     607           0 : mark_forgettable (void *cls,
     608             :                   const char *object_id,
     609             :                   json_t *parent)
     610             : {
     611           0 :   GNUNET_assert (GNUNET_OK ==
     612             :                  TALER_JSON_contract_mark_forgettable (parent,
     613             :                                                        object_id));
     614           0 : }
     615             : 
     616             : 
     617             : /**
     618             :  * Constructs the json for a POST order request.
     619             :  *
     620             :  * @param order_id the name of the order to add, can be NULL.
     621             :  * @param refund_deadline the deadline for refunds on this order.
     622             :  * @param pay_deadline the deadline for payment on this order.
     623             :  * @param amount the amount this order is for.
     624             :  * @param[out] order where to write the json string.
     625             :  */
     626             : static void
     627           0 : make_order_json (const char *order_id,
     628             :                  struct GNUNET_TIME_Timestamp refund_deadline,
     629             :                  struct GNUNET_TIME_Timestamp pay_deadline,
     630             :                  const char *amount,
     631             :                  json_t **order)
     632             : {
     633           0 :   struct GNUNET_TIME_Timestamp refund = refund_deadline;
     634           0 :   struct GNUNET_TIME_Timestamp pay = pay_deadline;
     635             :   json_t *contract_terms;
     636             : 
     637             :   /* Include required fields and some dummy objects to test forgetting. */
     638           0 :   contract_terms = json_pack (
     639             :     "{s:s, s:s?, s:s, s:s, s:o, s:o, s:s, s:[{s:s}, {s:s}, {s:s}]}",
     640             :     "summary", "merchant-lib testcase",
     641             :     "order_id", order_id,
     642             :     "amount", amount,
     643             :     "fulfillment_url", "https://example.com",
     644             :     "refund_deadline", GNUNET_JSON_from_timestamp (refund),
     645             :     "pay_deadline", GNUNET_JSON_from_timestamp (pay),
     646             :     "dummy_obj", "EUR:1.0",
     647             :     "dummy_array", /* For testing forgetting parts of arrays */
     648             :     "item", "speakers",
     649             :     "item", "headphones",
     650             :     "item", "earbuds"
     651             :     );
     652           0 :   GNUNET_assert (GNUNET_OK ==
     653             :                  TALER_JSON_expand_path (contract_terms,
     654             :                                          "$.dummy_obj",
     655             :                                          &mark_forgettable,
     656             :                                          NULL));
     657           0 :   GNUNET_assert (GNUNET_OK ==
     658             :                  TALER_JSON_expand_path (contract_terms,
     659             :                                          "$.dummy_array[*].item",
     660             :                                          &mark_forgettable,
     661             :                                          NULL));
     662           0 :   *order = contract_terms;
     663           0 : }
     664             : 
     665             : 
     666             : struct TALER_TESTING_Command
     667           0 : TALER_TESTING_cmd_merchant_post_orders_no_claim (
     668             :   const char *label,
     669             :   const char *merchant_url,
     670             :   unsigned int http_status,
     671             :   const char *order_id,
     672             :   struct GNUNET_TIME_Timestamp refund_deadline,
     673             :   struct GNUNET_TIME_Timestamp pay_deadline,
     674             :   const char *amount)
     675             : {
     676             :   struct OrdersState *ps;
     677             : 
     678           0 :   ps = GNUNET_new (struct OrdersState);
     679           0 :   make_order_json (order_id,
     680             :                    refund_deadline,
     681             :                    pay_deadline,
     682             :                    amount,
     683             :                    &ps->order_terms);
     684           0 :   ps->http_status = http_status;
     685           0 :   ps->expected_order_id = order_id;
     686           0 :   ps->merchant_url = merchant_url;
     687           0 :   ps->with_claim = false;
     688             :   {
     689           0 :     struct TALER_TESTING_Command cmd = {
     690             :       .cls = ps,
     691             :       .label = label,
     692             :       .run = &orders_run,
     693             :       .cleanup = &orders_cleanup,
     694             :       .traits = &orders_traits
     695             :     };
     696             : 
     697           0 :     return cmd;
     698             :   }
     699             : }
     700             : 
     701             : 
     702             : struct TALER_TESTING_Command
     703           0 : TALER_TESTING_cmd_merchant_post_orders (
     704             :   const char *label,
     705             :   const char *merchant_url,
     706             :   unsigned int http_status,
     707             :   const char *order_id,
     708             :   struct GNUNET_TIME_Timestamp refund_deadline,
     709             :   struct GNUNET_TIME_Timestamp pay_deadline,
     710             :   const char *amount)
     711             : {
     712             :   struct OrdersState *ps;
     713             : 
     714           0 :   ps = GNUNET_new (struct OrdersState);
     715           0 :   make_order_json (order_id,
     716             :                    refund_deadline,
     717             :                    pay_deadline,
     718             :                    amount,
     719             :                    &ps->order_terms);
     720           0 :   ps->http_status = http_status;
     721           0 :   ps->expected_order_id = order_id;
     722           0 :   ps->merchant_url = merchant_url;
     723           0 :   ps->with_claim = true;
     724             :   {
     725           0 :     struct TALER_TESTING_Command cmd = {
     726             :       .cls = ps,
     727             :       .label = label,
     728             :       .run = &orders_run,
     729             :       .cleanup = &orders_cleanup,
     730             :       .traits = &orders_traits
     731             :     };
     732             : 
     733           0 :     return cmd;
     734             :   }
     735             : }
     736             : 
     737             : 
     738             : struct TALER_TESTING_Command
     739           0 : TALER_TESTING_cmd_merchant_post_orders2 (
     740             :   const char *label,
     741             :   const char *merchant_url,
     742             :   unsigned int http_status,
     743             :   const char *order_id,
     744             :   struct GNUNET_TIME_Timestamp refund_deadline,
     745             :   struct GNUNET_TIME_Timestamp pay_deadline,
     746             :   bool claim_token,
     747             :   const char *amount,
     748             :   const char *payment_target,
     749             :   const char *products,
     750             :   const char *locks,
     751             :   const char *duplicate_of)
     752             : {
     753             :   struct OrdersState *ps;
     754             : 
     755           0 :   ps = GNUNET_new (struct OrdersState);
     756           0 :   make_order_json (order_id,
     757             :                    refund_deadline,
     758             :                    pay_deadline,
     759             :                    amount,
     760             :                    &ps->order_terms);
     761           0 :   ps->http_status = http_status;
     762           0 :   ps->expected_order_id = order_id;
     763           0 :   ps->merchant_url = merchant_url;
     764           0 :   ps->payment_target = payment_target;
     765           0 :   ps->products = products;
     766           0 :   ps->locks = locks;
     767           0 :   ps->with_claim = (NULL == duplicate_of);
     768           0 :   ps->make_claim_token = claim_token;
     769           0 :   ps->duplicate_of = duplicate_of;
     770             :   {
     771           0 :     struct TALER_TESTING_Command cmd = {
     772             :       .cls = ps,
     773             :       .label = label,
     774             :       .run = &orders_run2,
     775             :       .cleanup = &orders_cleanup,
     776             :       .traits = &orders_traits
     777             :     };
     778             : 
     779           0 :     return cmd;
     780             :   }
     781             : }

Generated by: LCOV version 1.14