testing_api_cmd_post_orders_paid.c (6834B)
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_post_orders_paid.c 21 * @brief command to test POST /orders/$ID/paid. 22 * @author Jonathan Buchanan 23 */ 24 #include "taler/platform.h" 25 #include <taler/taler_exchange_service.h> 26 #include <taler/taler_testing_lib.h> 27 #include "taler/taler_merchant_service.h" 28 #include "taler/taler_merchant_testing_lib.h" 29 #include <taler/taler-merchant/post-orders-ORDER_ID-paid.h> 30 31 32 /** 33 * State of a "POST /orders/$ID/paid" CMD. 34 */ 35 struct PostOrdersPaidState 36 { 37 38 /** 39 * Handle for a "POST /paid" request. 40 */ 41 struct TALER_MERCHANT_PostOrdersPaidHandle *oph; 42 43 /** 44 * The interpreter state. 45 */ 46 struct TALER_TESTING_Interpreter *is; 47 48 /** 49 * Base URL of the merchant serving the request. 50 */ 51 const char *merchant_url; 52 53 /** 54 * Reference to the "pay" command to verify. 55 */ 56 const char *pay_reference; 57 58 /** 59 * The session to use for the request. 60 */ 61 const char *session_id; 62 63 /** 64 * Expected HTTP response code. 65 */ 66 unsigned int http_status; 67 68 }; 69 70 71 /** 72 * Response from the merchant after POST /paid. 73 * 74 * @param cls pointer to `struct PostOrdersPaidState`. 75 * @param opr the response. 76 */ 77 static void 78 paid_cb (void *cls, 79 const struct TALER_MERCHANT_PostOrdersPaidResponse *opr) 80 { 81 struct PostOrdersPaidState *ops = cls; 82 83 ops->oph = NULL; 84 if (ops->http_status != opr->hr.http_status) 85 { 86 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 87 "Unexpected response code %u (%d) to command %s\n", 88 opr->hr.http_status, 89 (int) opr->hr.ec, 90 TALER_TESTING_interpreter_get_current_label (ops->is)); 91 TALER_TESTING_FAIL (ops->is); 92 } 93 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 94 "Successful order-paid (HTTP status: %u)\n", 95 ops->http_status); 96 TALER_TESTING_interpreter_next (ops->is); 97 } 98 99 100 /** 101 * Run a "paid" CMD. 102 * 103 * @param cls closure 104 * @param cmd command being run. 105 * @param is interpreter state 106 */ 107 static void 108 paid_run (void *cls, 109 const struct TALER_TESTING_Command *cmd, 110 struct TALER_TESTING_Interpreter *is) 111 { 112 struct PostOrdersPaidState *ops = cls; 113 const struct TALER_TESTING_Command *pay_cmd; 114 const char *proposal_reference; 115 const struct TALER_TESTING_Command *proposal_cmd; 116 const char *order_id; 117 const struct TALER_PrivateContractHashP *h_contract_terms; 118 const struct TALER_MerchantSignatureP *merchant_sig; 119 120 ops->is = is; 121 pay_cmd = TALER_TESTING_interpreter_lookup_command (is, 122 ops->pay_reference); 123 if (NULL == pay_cmd) 124 TALER_TESTING_FAIL (is); 125 if (GNUNET_OK != 126 TALER_TESTING_get_trait_merchant_sig (pay_cmd, 127 &merchant_sig)) 128 TALER_TESTING_FAIL (is); 129 if (GNUNET_OK != 130 TALER_TESTING_get_trait_proposal_reference (pay_cmd, 131 &proposal_reference)) 132 TALER_TESTING_FAIL (is); 133 proposal_cmd = TALER_TESTING_interpreter_lookup_command (is, 134 proposal_reference); 135 136 if (NULL == proposal_cmd) 137 TALER_TESTING_FAIL (is); 138 139 { 140 const json_t *contract_terms; 141 const char *error_name; 142 unsigned int error_line; 143 144 if (GNUNET_OK != 145 TALER_TESTING_get_trait_contract_terms (proposal_cmd, 146 &contract_terms)) 147 TALER_TESTING_FAIL (is); 148 { 149 /* Get information that needs to be put verbatim in the 150 * deposit permission */ 151 struct GNUNET_JSON_Specification spec[] = { 152 GNUNET_JSON_spec_string ("order_id", 153 &order_id), 154 GNUNET_JSON_spec_end () 155 }; 156 157 if (GNUNET_OK != 158 GNUNET_JSON_parse (contract_terms, 159 spec, 160 &error_name, 161 &error_line)) 162 { 163 char *js; 164 165 js = json_dumps (contract_terms, 166 JSON_INDENT (1)); 167 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 168 "Parser failed on %s:%u for input `%s'\n", 169 error_name, 170 error_line, 171 js); 172 free (js); 173 TALER_TESTING_FAIL (is); 174 } 175 } 176 } 177 178 if (GNUNET_OK != 179 TALER_TESTING_get_trait_h_contract_terms (proposal_cmd, 180 &h_contract_terms)) 181 TALER_TESTING_FAIL (is); 182 183 ops->oph = TALER_MERCHANT_post_orders_paid_create ( 184 TALER_TESTING_interpreter_get_context (is), 185 ops->merchant_url, 186 order_id, 187 ops->session_id, 188 h_contract_terms, 189 merchant_sig); 190 { 191 enum TALER_ErrorCode ec; 192 193 ec = TALER_MERCHANT_post_orders_paid_start ( 194 ops->oph, 195 &paid_cb, 196 ops); 197 GNUNET_assert (TALER_EC_NONE == ec); 198 } 199 } 200 201 202 /** 203 * Free a "paid" CMD, and cancel it if need be. 204 * 205 * @param cls closure. 206 * @param cmd command currently being freed. 207 */ 208 static void 209 paid_cleanup (void *cls, 210 const struct TALER_TESTING_Command *cmd) 211 { 212 struct PostOrdersPaidState *ops = cls; 213 214 if (NULL != ops->oph) 215 { 216 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 217 "Command `%s' did not complete.\n", 218 TALER_TESTING_interpreter_get_current_label ( 219 ops->is)); 220 TALER_MERCHANT_post_orders_paid_cancel (ops->oph); 221 } 222 GNUNET_free (ops); 223 } 224 225 226 struct TALER_TESTING_Command 227 TALER_TESTING_cmd_merchant_post_orders_paid (const char *label, 228 const char *merchant_url, 229 const char *pay_reference, 230 const char *session_id, 231 unsigned int http_status) 232 { 233 struct PostOrdersPaidState *ops; 234 235 ops = GNUNET_new (struct PostOrdersPaidState); 236 ops->http_status = http_status; 237 ops->pay_reference = pay_reference; 238 ops->merchant_url = merchant_url; 239 ops->session_id = session_id; 240 { 241 struct TALER_TESTING_Command cmd = { 242 .cls = ops, 243 .label = label, 244 .run = &paid_run, 245 .cleanup = &paid_cleanup 246 }; 247 248 return cmd; 249 } 250 }