LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_post_orders.c (source / functions) Hit Total Coverage
Test: GNU Taler coverage report Lines: 0 219 0.0 %
Date: 2020-08-15 06:12:35 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-2018 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify
       6             :   it under the terms of the GNU General Public License as
       7             :   published by the Free Software Foundation; either version 3, or
       8             :   (at your option) any later version.
       9             : 
      10             :   TALER is distributed in the hope that it will be useful, but
      11             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :   GNU General Public License for more details.
      14             : 
      15             :   You should have received a copy of the GNU General Public
      16             :   License along with TALER; see the file COPYING.  If not, see
      17             :   <http://www.gnu.org/licenses/>
      18             : */
      19             : 
      20             : /**
      21             :  * @file 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             :    * The order.
      40             :    */
      41             :   char *order;
      42             : 
      43             :   /**
      44             :    * Expected status code.
      45             :    */
      46             :   unsigned int http_status;
      47             : 
      48             :   /**
      49             :    * Order id.
      50             :    */
      51             :   const char *order_id;
      52             : 
      53             :   /**
      54             :    * The order id we expect the merchant to assign (if not NULL).
      55             :    */
      56             :   const char *expected_order_id;
      57             : 
      58             :   /**
      59             :    * Contract terms obtained from the backend.
      60             :    */
      61             :   json_t *contract_terms;
      62             : 
      63             :   /**
      64             :    * Contract terms hash code.
      65             :    */
      66             :   struct GNUNET_HashCode h_contract_terms;
      67             : 
      68             :   /**
      69             :    * The /orders operation handle.
      70             :    */
      71             :   struct TALER_MERCHANT_PostOrdersOperation *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 ret[out] 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 int
     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             : 
     160             :   struct TALER_TESTING_Trait traits[] = {
     161           0 :     TALER_TESTING_make_trait_order_id (0, ps->order_id),
     162           0 :     TALER_TESTING_make_trait_contract_terms (0, ps->contract_terms),
     163           0 :     TALER_TESTING_make_trait_h_contract_terms (0, &ps->h_contract_terms),
     164           0 :     TALER_TESTING_make_trait_merchant_sig (0, &ps->merchant_sig),
     165           0 :     TALER_TESTING_make_trait_merchant_pub (0, &ps->merchant_pub),
     166           0 :     TALER_TESTING_make_trait_claim_nonce (0, &ps->nonce),
     167           0 :     TALER_TESTING_make_trait_claim_token (0, &ps->claim_token),
     168           0 :     TALER_TESTING_make_trait_string (0, ps->order),
     169           0 :     TALER_TESTING_trait_end ()
     170             :   };
     171             : 
     172           0 :   return TALER_TESTING_get_trait (traits,
     173             :                                   ret,
     174             :                                   trait,
     175             :                                   index);
     176             : }
     177             : 
     178             : 
     179             : /**
     180             :  * Used to fill the "orders" CMD state with backend-provided
     181             :  * values.  Also double-checks that the order was correctly
     182             :  * created.
     183             :  *
     184             :  * @param cls closure
     185             :  * @param hr HTTP response we got
     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 GNUNET_HashCode *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           0 :     TALER_TESTING_FAIL (ps->is);
     209             : 
     210           0 :   ps->contract_terms = json_deep_copy (contract_terms);
     211           0 :   ps->h_contract_terms = *hash;
     212           0 :   ps->merchant_sig = *sig;
     213           0 :   if (GNUNET_OK !=
     214           0 :       GNUNET_JSON_parse (contract_terms,
     215             :                          spec,
     216             :                          &error_name,
     217             :                          &error_line))
     218             :   {
     219             :     char *log;
     220             : 
     221           0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     222             :                 "Parser failed on %s:%u\n",
     223             :                 error_name,
     224             :                 error_line);
     225           0 :     log = json_dumps (ps->contract_terms,
     226             :                       JSON_INDENT (1));
     227           0 :     fprintf (stderr,
     228             :              "%s\n",
     229             :              log);
     230           0 :     free (log);
     231           0 :     TALER_TESTING_FAIL (ps->is);
     232             :   }
     233           0 :   ps->merchant_pub = merchant_pub;
     234           0 :   TALER_TESTING_interpreter_next (ps->is);
     235             : }
     236             : 
     237             : 
     238             : /**
     239             :  * Callback that processes the response following a
     240             :  * POST /orders.  NOTE: no contract terms are included
     241             :  * here; they need to be taken via the "orders lookup"
     242             :  * method.
     243             :  *
     244             :  * @param cls closure.
     245             :  * @param hr HTTP response
     246             :  * @param order_id order id of the orders.
     247             :  */
     248             : static void
     249           0 : order_cb (void *cls,
     250             :           const struct TALER_MERCHANT_HttpResponse *hr,
     251             :           const char *order_id,
     252             :           const struct TALER_ClaimTokenP *claim_token)
     253             : {
     254           0 :   struct OrdersState *ps = cls;
     255             : 
     256           0 :   ps->po = NULL;
     257           0 :   if (NULL != claim_token)
     258           0 :     ps->claim_token = *claim_token;
     259           0 :   if (ps->http_status != hr->http_status)
     260             :   {
     261           0 :     TALER_LOG_ERROR ("Given vs expected: %u(%d) vs %u\n",
     262             :                      hr->http_status,
     263             :                      (int) hr->ec,
     264             :                      ps->http_status);
     265           0 :     TALER_TESTING_FAIL (ps->is);
     266             :   }
     267           0 :   if (0 == ps->http_status)
     268             :   {
     269           0 :     TALER_LOG_DEBUG ("/orders, expected 0 status code\n");
     270           0 :     TALER_TESTING_interpreter_next (ps->is);
     271           0 :     return;
     272             :   }
     273           0 :   switch (hr->http_status)
     274             :   {
     275           0 :   case MHD_HTTP_OK:
     276           0 :     ps->order_id = GNUNET_strdup (order_id);
     277           0 :     if ((NULL != ps->expected_order_id) &&
     278           0 :         (0 != strcmp (order_id,
     279             :                       ps->expected_order_id)))
     280             :     {
     281           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     282             :                   "Order id assigned does not match\n");
     283           0 :       TALER_TESTING_interpreter_fail (ps->is);
     284           0 :       return;
     285             :     }
     286           0 :     if (NULL != ps->duplicate_of)
     287             :     {
     288             :       const struct TALER_TESTING_Command *order_cmd;
     289             :       const struct TALER_ClaimTokenP *prev_token;
     290           0 :       struct TALER_ClaimTokenP zero_token = {0};
     291           0 :       order_cmd = TALER_TESTING_interpreter_lookup_command (
     292             :         ps->is,
     293             :         ps->duplicate_of);
     294           0 :       if (GNUNET_OK !=
     295           0 :           TALER_TESTING_get_trait_claim_token (order_cmd,
     296             :                                                0,
     297             :                                                &prev_token))
     298             :       {
     299           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     300             :                     "Could not fetch previous order claim token\n");
     301           0 :         TALER_TESTING_interpreter_fail (ps->is);
     302           0 :         return;
     303             :       }
     304           0 :       if (NULL == claim_token)
     305           0 :         prev_token = &zero_token;
     306           0 :       if (0 != GNUNET_memcmp (prev_token,
     307             :                               claim_token))
     308             :       {
     309           0 :         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     310             :                     "Claim tokens for identical requests do not match\n");
     311           0 :         TALER_TESTING_interpreter_fail (ps->is);
     312           0 :         return;
     313             :       }
     314             :     }
     315           0 :     break;
     316           0 :   default:
     317             :     {
     318           0 :       char *s = json_dumps (hr->reply,
     319             :                             JSON_COMPACT);
     320           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     321             :                   "Unexpected status code from /orders: %u (%d) at %s; JSON: %s\n",
     322             :                   hr->http_status,
     323             :                   hr->ec,
     324             :                   TALER_TESTING_interpreter_get_current_label (ps->is),
     325             :                   s);
     326           0 :       GNUNET_free (s);
     327             :       /**
     328             :        * Not failing, as test cases are _supposed_
     329             :        * to create non 200 OK situations.
     330             :        */
     331           0 :       TALER_TESTING_interpreter_next (ps->is);
     332             :     }
     333           0 :     return;
     334             :   }
     335             : 
     336           0 :   if (false == ps->with_claim)
     337             :   {
     338           0 :     TALER_TESTING_interpreter_next (ps->is);
     339           0 :     return;
     340             :   }
     341           0 :   if (NULL ==
     342           0 :       (ps->och = TALER_MERCHANT_order_claim (ps->is->ctx,
     343             :                                              ps->merchant_url,
     344             :                                              ps->order_id,
     345           0 :                                              &ps->nonce,
     346           0 :                                              &ps->claim_token,
     347             :                                              &orders_claim_cb,
     348             :                                              ps)))
     349           0 :     TALER_TESTING_FAIL (ps->is);
     350             : }
     351             : 
     352             : 
     353             : /**
     354             :  * Run a "orders" CMD.
     355             :  *
     356             :  * @param cls closure.
     357             :  * @param cmd command currently being run.
     358             :  * @param is interpreter state.
     359             :  */
     360             : static void
     361           0 : orders_run (void *cls,
     362             :             const struct TALER_TESTING_Command *cmd,
     363             :             struct TALER_TESTING_Interpreter *is)
     364             : {
     365           0 :   struct OrdersState *ps = cls;
     366             :   json_t *order;
     367             :   json_error_t error;
     368             : 
     369           0 :   ps->is = is;
     370           0 :   order = json_loads (ps->order,
     371             :                       JSON_REJECT_DUPLICATES,
     372             :                       &error);
     373           0 :   if (NULL == order)
     374             :   {
     375             :     // human error here.
     376           0 :     GNUNET_break (0);
     377           0 :     fprintf (stderr, "%s\n", error.text);
     378           0 :     TALER_TESTING_interpreter_fail (is);
     379           0 :     return;
     380             :   }
     381             : 
     382           0 :   if (NULL == json_object_get (order,
     383             :                                "order_id"))
     384             :   {
     385             :     struct GNUNET_TIME_Absolute now;
     386             :     char *order_id;
     387             : 
     388             :     // FIXME: should probably use get_monotone() to ensure uniqueness!
     389           0 :     now = GNUNET_TIME_absolute_get ();
     390           0 :     order_id = GNUNET_STRINGS_data_to_string_alloc
     391             :                  (&now.abs_value_us,
     392             :                  sizeof (now.abs_value_us));
     393           0 :     json_object_set_new (order,
     394             :                          "order_id",
     395             :                          json_string (order_id));
     396           0 :     GNUNET_free (order_id);
     397             :   }
     398           0 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     399           0 :                               &ps->nonce,
     400             :                               sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
     401           0 :   ps->po = TALER_MERCHANT_orders_post (is->ctx,
     402             :                                        ps->merchant_url,
     403             :                                        order,
     404             :                                        GNUNET_TIME_UNIT_ZERO,
     405             :                                        &order_cb,
     406             :                                        ps);
     407           0 :   json_decref (order);
     408           0 :   GNUNET_assert (NULL != ps->po);
     409             : }
     410             : 
     411             : 
     412             : /**
     413             :  * Run a "orders" CMD.
     414             :  *
     415             :  * @param cls closure.
     416             :  * @param cmd command currently being run.
     417             :  * @param is interpreter state.
     418             :  */
     419             : static void
     420           0 : orders_run2 (void *cls,
     421             :              const struct TALER_TESTING_Command *cmd,
     422             :              struct TALER_TESTING_Interpreter *is)
     423             : {
     424           0 :   struct OrdersState *ps = cls;
     425           0 :   const char *order_str = ps->order;
     426             :   json_t *order;
     427             :   json_error_t error;
     428             : 
     429           0 :   char *products_string = GNUNET_strdup (ps->products);
     430           0 :   char *locks_string = GNUNET_strdup (ps->locks);
     431             :   char *token;
     432             : 
     433           0 :   struct TALER_MERCHANT_InventoryProduct *products = NULL;
     434           0 :   unsigned int products_length = 0;
     435           0 :   struct GNUNET_Uuid *locks = NULL;
     436           0 :   unsigned int locks_length = 0;
     437             : 
     438           0 :   ps->is = is;
     439           0 :   if (NULL != ps->duplicate_of)
     440             :   {
     441             :     const struct TALER_TESTING_Command *order_cmd;
     442           0 :     order_cmd = TALER_TESTING_interpreter_lookup_command (
     443             :       is,
     444             :       ps->duplicate_of);
     445           0 :     if (GNUNET_OK !=
     446           0 :         TALER_TESTING_get_trait_string (order_cmd,
     447             :                                         0,
     448             :                                         &order_str))
     449             :     {
     450           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     451             :                   "Could not fetch previous order string\n");
     452           0 :       TALER_TESTING_interpreter_fail (is);
     453           0 :       return;
     454             :     }
     455             :   }
     456           0 :   order = json_loads (order_str,
     457             :                       JSON_REJECT_DUPLICATES,
     458             :                       &error);
     459           0 :   if (NULL == order)
     460             :   {
     461             :     // human error here.
     462           0 :     GNUNET_break (0);
     463           0 :     fprintf (stderr, "%s\n", error.text);
     464           0 :     TALER_TESTING_interpreter_fail (is);
     465           0 :     return;
     466             :   }
     467             : 
     468           0 :   if (NULL == json_object_get (order,
     469             :                                "order_id"))
     470             :   {
     471             :     struct GNUNET_TIME_Absolute now;
     472             :     char *order_id;
     473             : 
     474             :     // FIXME: should probably use get_monotone() to ensure uniqueness!
     475           0 :     now = GNUNET_TIME_absolute_get ();
     476           0 :     order_id = GNUNET_STRINGS_data_to_string_alloc
     477             :                  (&now.abs_value_us,
     478             :                  sizeof (now.abs_value_us));
     479           0 :     json_object_set_new (order,
     480             :                          "order_id",
     481             :                          json_string (order_id));
     482           0 :     GNUNET_free (order_id);
     483             :   }
     484           0 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     485           0 :                               &ps->nonce,
     486             :                               sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
     487           0 :   for (token = strtok (products_string, ";");
     488             :        NULL != token;
     489           0 :        token = strtok (NULL, ";"))
     490             :   {
     491             :     char *ctok;
     492             :     struct TALER_MERCHANT_InventoryProduct pd;
     493             : 
     494             :     /* Token syntax is "[product_id]/[quantity]" */
     495           0 :     ctok = strchr (token, '/');
     496           0 :     if (NULL != ctok)
     497             :     {
     498           0 :       *ctok = '\0';
     499           0 :       ctok++;
     500           0 :       if (1 != sscanf (ctok,
     501             :                        "%u",
     502             :                        &pd.quantity))
     503             :       {
     504           0 :         GNUNET_break (0);
     505           0 :         break;
     506             :       }
     507             :     }
     508             :     else
     509             :     {
     510           0 :       pd.quantity = 1;
     511             :     }
     512           0 :     pd.product_id = token;
     513             : 
     514           0 :     GNUNET_array_append (products,
     515             :                          products_length,
     516             :                          pd);
     517             :   }
     518           0 :   for (token = strtok (locks_string, ";");
     519             :        NULL != token;
     520           0 :        token = strtok (NULL, ";"))
     521             :   {
     522             :     const struct TALER_TESTING_Command *lock_cmd;
     523             :     struct GNUNET_Uuid *uuid;
     524             : 
     525           0 :     lock_cmd = TALER_TESTING_interpreter_lookup_command (
     526             :       is,
     527             :       token);
     528             : 
     529           0 :     if (GNUNET_OK !=
     530           0 :         TALER_TESTING_get_trait_uuid (lock_cmd,
     531             :                                       0,
     532             :                                       &uuid))
     533             :     {
     534           0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     535             :                   "Could not fetch lock uuid\n");
     536           0 :       TALER_TESTING_interpreter_fail (is);
     537           0 :       return;
     538             :     }
     539             : 
     540           0 :     GNUNET_array_append (locks,
     541             :                          locks_length,
     542             :                          *uuid);
     543             :   }
     544           0 :   ps->po = TALER_MERCHANT_orders_post2 (is->ctx,
     545             :                                         ps->merchant_url,
     546             :                                         order,
     547             :                                         GNUNET_TIME_UNIT_ZERO,
     548             :                                         ps->payment_target,
     549             :                                         products_length,
     550             :                                         products,
     551             :                                         locks_length,
     552             :                                         locks,
     553           0 :                                         ps->make_claim_token,
     554             :                                         &order_cb,
     555             :                                         ps);
     556           0 :   json_decref (order);
     557           0 :   GNUNET_free (products_string);
     558           0 :   GNUNET_free (locks_string);
     559           0 :   GNUNET_array_grow (products,
     560             :                      products_length,
     561             :                      0);
     562           0 :   GNUNET_array_grow (locks,
     563             :                      locks_length,
     564             :                      0);
     565           0 :   GNUNET_assert (NULL != ps->po);
     566             : }
     567             : 
     568             : 
     569             : /**
     570             :  * Free the state of a "orders" CMD, and possibly
     571             :  * cancel it if it did not complete.
     572             :  *
     573             :  * @param cls closure.
     574             :  * @param cmd command being freed.
     575             :  */
     576             : static void
     577           0 : orders_cleanup (void *cls,
     578             :                 const struct TALER_TESTING_Command *cmd)
     579             : {
     580           0 :   struct OrdersState *ps = cls;
     581             : 
     582           0 :   if (NULL != ps->po)
     583             :   {
     584           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     585             :                 "Command '%s' did not complete (orders put)\n",
     586             :                 cmd->label);
     587           0 :     TALER_MERCHANT_orders_post_cancel (ps->po);
     588           0 :     ps->po = NULL;
     589             :   }
     590             : 
     591           0 :   if (NULL != ps->och)
     592             :   {
     593           0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     594             :                 "Command '%s' did not complete"
     595             :                 " (orders lookup)\n",
     596             :                 cmd->label);
     597           0 :     TALER_MERCHANT_order_claim_cancel (ps->och);
     598           0 :     ps->och = NULL;
     599             :   }
     600             : 
     601           0 :   json_decref (ps->contract_terms);
     602           0 :   GNUNET_free (ps->order);
     603           0 :   GNUNET_free_nz ((void *) ps->order_id);
     604           0 :   GNUNET_free (ps);
     605           0 : }
     606             : 
     607             : 
     608             : /**
     609             :  * Mark part of the contract terms as possible to forget.
     610             :  *
     611             :  * @param cls pointer to the result of the forget operation.
     612             :  * @param object_id name of the object to forget.
     613             :  * @param parent parent of the object at @e object_id.
     614             :  */
     615             : static void
     616           0 : mark_forgettable (void *cls,
     617             :                   const char *object_id,
     618             :                   json_t *parent)
     619             : {
     620           0 :   GNUNET_assert (GNUNET_OK ==
     621             :                  TALER_JSON_contract_mark_forgettable (parent,
     622             :                                                        object_id));
     623           0 : }
     624             : 
     625             : 
     626             : /**
     627             :  * Constructs the json for a POST order request.
     628             :  *
     629             :  * @param order_id the name of the order to add.
     630             :  * @param refund_deadline the deadline for refunds on this order.
     631             :  * @param pay_deadline the deadline for payment on this order.
     632             :  * @param amount the amount this order is for.
     633             :  * @param order[out] where to write the json string.
     634             :  */
     635             : static void
     636           0 : make_order_json (const char *order_id,
     637             :                  struct GNUNET_TIME_Absolute refund_deadline,
     638             :                  struct GNUNET_TIME_Absolute pay_deadline,
     639             :                  const char *amount,
     640             :                  char **order)
     641             : {
     642           0 :   struct GNUNET_TIME_Absolute refund = refund_deadline;
     643           0 :   struct GNUNET_TIME_Absolute pay = pay_deadline;
     644             : 
     645             :   json_t *contract_terms;
     646             : 
     647           0 :   GNUNET_TIME_round_abs (&refund);
     648           0 :   GNUNET_TIME_round_abs (&pay);
     649             : 
     650             :   /* Include required fields and some dummy objects to test forgetting. */
     651           0 :   contract_terms = json_pack (
     652             :     "{s:s, s:s?, s:s, s:s, s:o, s:o, s:s, s:[{s:s}, {s:s}, {s:s}]}",
     653             :     "summary", "merchant-lib testcase",
     654             :     "order_id", order_id,
     655             :     "amount", amount,
     656             :     "fulfillment_url", "https://example.com",
     657             :     "refund_deadline", GNUNET_JSON_from_time_abs (refund),
     658             :     "pay_deadline", GNUNET_JSON_from_time_abs (pay),
     659             :     "dummy_obj", "EUR:1.0",
     660             :     "dummy_array", /* For testing forgetting parts of arrays */
     661             :     "item", "speakers",
     662             :     "item", "headphones",
     663             :     "item", "earbuds"
     664             :     );
     665             : 
     666           0 :   GNUNET_assert (GNUNET_OK ==
     667             :                  TALER_JSON_expand_path (contract_terms,
     668             :                                          "$.dummy_obj",
     669             :                                          &mark_forgettable,
     670             :                                          NULL));
     671           0 :   GNUNET_assert (GNUNET_OK ==
     672             :                  TALER_JSON_expand_path (contract_terms,
     673             :                                          "$.dummy_array[*].item",
     674             :                                          &mark_forgettable,
     675             :                                          NULL));
     676             : 
     677           0 :   *order = json_dumps (contract_terms, 0);
     678           0 :   json_decref (contract_terms);
     679           0 : }
     680             : 
     681             : 
     682             : /**
     683             :  * Make the "proposal" command AVOIDING claiming the order.
     684             :  *
     685             :  * @param label command label
     686             :  * @param merchant_url base URL of the merchant serving
     687             :  *        the proposal request.
     688             :  * @param http_status expected HTTP status.
     689             :  * @param order_id the name of the order to add.
     690             :  * @param refund_deadline the deadline for refunds on this order.
     691             :  * @param pay_deadline the deadline for payment on this order.
     692             :  * @param amount the amount this order is for.
     693             :  * @return the command
     694             :  */
     695             : struct TALER_TESTING_Command
     696           0 : TALER_TESTING_cmd_merchant_post_orders_no_claim (const char *label,
     697             :                                                  const char *merchant_url,
     698             :                                                  unsigned int http_status,
     699             :                                                  const char *order_id,
     700             :                                                  struct GNUNET_TIME_Absolute
     701             :                                                  refund_deadline,
     702             :                                                  struct GNUNET_TIME_Absolute
     703             :                                                  pay_deadline,
     704             :                                                  const char *amount)
     705             : {
     706             :   struct OrdersState *ps;
     707             : 
     708           0 :   ps = GNUNET_new (struct OrdersState);
     709           0 :   make_order_json (order_id,
     710             :                    refund_deadline,
     711             :                    pay_deadline,
     712             :                    amount,
     713             :                    &ps->order);
     714           0 :   ps->http_status = http_status;
     715           0 :   ps->expected_order_id = order_id;
     716           0 :   ps->merchant_url = merchant_url;
     717           0 :   ps->with_claim = false;
     718             :   {
     719           0 :     struct TALER_TESTING_Command cmd = {
     720             :       .cls = ps,
     721             :       .label = label,
     722             :       .run = &orders_run,
     723             :       .cleanup = &orders_cleanup,
     724             :       .traits = &orders_traits
     725             :     };
     726             : 
     727           0 :     return cmd;
     728             :   }
     729             : }
     730             : 
     731             : 
     732             : /**
     733             :  * Make the "proposal" command.
     734             :  *
     735             :  * @param label command label
     736             :  * @param merchant_url base URL of the merchant serving
     737             :  *        the proposal request.
     738             :  * @param http_status expected HTTP status.
     739             :  * @param order_id the name of the order to add.
     740             :  * @param refund_deadline the deadline for refunds on this order.
     741             :  * @param pay_deadline the deadline for payment on this order.
     742             :  * @param amount the amount this order is for.
     743             :  * @return the command
     744             :  */
     745             : struct TALER_TESTING_Command
     746           0 : TALER_TESTING_cmd_merchant_post_orders (const char *label,
     747             :                                         const char *merchant_url,
     748             :                                         unsigned int http_status,
     749             :                                         const char *order_id,
     750             :                                         struct GNUNET_TIME_Absolute
     751             :                                         refund_deadline,
     752             :                                         struct GNUNET_TIME_Absolute
     753             :                                         pay_deadline,
     754             :                                         const char *amount)
     755             : {
     756             :   struct OrdersState *ps;
     757             : 
     758           0 :   ps = GNUNET_new (struct OrdersState);
     759           0 :   make_order_json (order_id,
     760             :                    refund_deadline,
     761             :                    pay_deadline,
     762             :                    amount,
     763             :                    &ps->order);
     764           0 :   ps->http_status = http_status;
     765           0 :   ps->expected_order_id = order_id;
     766           0 :   ps->merchant_url = merchant_url;
     767           0 :   ps->with_claim = true;
     768             :   {
     769           0 :     struct TALER_TESTING_Command cmd = {
     770             :       .cls = ps,
     771             :       .label = label,
     772             :       .run = &orders_run,
     773             :       .cleanup = &orders_cleanup,
     774             :       .traits = &orders_traits
     775             :     };
     776             : 
     777           0 :     return cmd;
     778             :   }
     779             : }
     780             : 
     781             : 
     782             : /**
     783             :  * Make the "proposal" command.
     784             :  *
     785             :  * @param label command label
     786             :  * @param merchant_url base URL of the merchant serving
     787             :  *        the proposal request.
     788             :  * @param http_status expected HTTP status.
     789             :  * @param order_id the name of the order to add.
     790             :  * @param refund_deadline the deadline for refunds on this order.
     791             :  * @param pay_deadline the deadline for payment on this order.
     792             :  * @param claim_token whether to generate a claim token.
     793             :  * @param amount the amount this order is for.
     794             :  * @param payment_target payment target for the order.
     795             :  * @param products a string indicating the products this order will be
     796             :  *        purchasing. Should be formatted as
     797             :  *        "[product_id]/[quantity];...".
     798             :  * @param locks a string of references to lock product commands that should
     799             :  *        be formatted as "[lock_1];[lock_2];...".
     800             :  * @param duplicate_of if not NULL, a reference to a previous order command
     801             :  *        that should be duplicated and checked for an identical response.
     802             :  * @return the command
     803             :  */
     804             : struct TALER_TESTING_Command
     805           0 : TALER_TESTING_cmd_merchant_post_orders2 (const char *label,
     806             :                                          const char *merchant_url,
     807             :                                          unsigned int http_status,
     808             :                                          const char *order_id,
     809             :                                          struct GNUNET_TIME_Absolute
     810             :                                          refund_deadline,
     811             :                                          struct GNUNET_TIME_Absolute
     812             :                                          pay_deadline,
     813             :                                          bool claim_token,
     814             :                                          const char *amount,
     815             :                                          const char *payment_target,
     816             :                                          const char *products,
     817             :                                          const char *locks,
     818             :                                          const char *duplicate_of)
     819             : {
     820             :   struct OrdersState *ps;
     821             : 
     822           0 :   ps = GNUNET_new (struct OrdersState);
     823           0 :   make_order_json (order_id,
     824             :                    refund_deadline,
     825             :                    pay_deadline,
     826             :                    amount,
     827             :                    &ps->order);
     828             : 
     829           0 :   ps->http_status = http_status;
     830           0 :   ps->expected_order_id = order_id;
     831           0 :   ps->merchant_url = merchant_url;
     832           0 :   ps->payment_target = payment_target;
     833           0 :   ps->products = products;
     834           0 :   ps->locks = locks;
     835           0 :   ps->with_claim = (NULL == duplicate_of);
     836           0 :   ps->make_claim_token = claim_token;
     837           0 :   ps->duplicate_of = duplicate_of;
     838             :   {
     839           0 :     struct TALER_TESTING_Command cmd = {
     840             :       .cls = ps,
     841             :       .label = label,
     842             :       .run = &orders_run2,
     843             :       .cleanup = &orders_cleanup,
     844             :       .traits = &orders_traits
     845             :     };
     846             : 
     847           0 :     return cmd;
     848             :   }
     849             : }

Generated by: LCOV version 1.14