testing_api_cmd_refund_order.c (7178B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as 7 published by the Free Software Foundation; either version 3, or 8 (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with TALER; see the file COPYING. If not, see 17 <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file src/testing/testing_api_cmd_refund_order.c 21 * @brief command to test refunds. 22 * @author Marcello Stanisci 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 struct RefundState; 27 #define TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE struct RefundState 28 #include <taler/taler_exchange_service.h> 29 #include <taler/taler_testing_lib.h> 30 #include "taler/taler_merchant_service.h" 31 #include "taler/taler_merchant_testing_lib.h" 32 #include <taler/merchant/post-private-orders-ORDER_ID-refund.h> 33 34 35 /** 36 * State for a "refund increase" CMD. 37 */ 38 struct RefundState 39 { 40 /** 41 * Operation handle for a POST /orders/$ID/refund request. 42 */ 43 struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *orh; 44 45 /** 46 * Base URL of the merchant serving the request. 47 */ 48 const char *merchant_url; 49 50 /** 51 * Order id of the contract to refund. 52 */ 53 const char *order_id; 54 55 /** 56 * The amount to refund. 57 */ 58 struct TALER_Amount refund_amount; 59 60 /** 61 * Human-readable justification for the refund. 62 */ 63 const char *reason; 64 65 /** 66 * Interpreter state. 67 */ 68 struct TALER_TESTING_Interpreter *is; 69 70 /** 71 * Expected HTTP response code. 72 */ 73 unsigned int http_code; 74 }; 75 76 77 /** 78 * Process POST /refund (increase) response; just checking 79 * if the HTTP response code is the one expected. 80 * 81 * @param cls closure 82 * @param rr response 83 */ 84 static void 85 refund_cb (struct RefundState *ris, 86 const struct TALER_MERCHANT_PostPrivateOrdersRefundResponse *rr) 87 { 88 89 ris->orh = NULL; 90 if (ris->http_code != rr->hr.http_status) 91 { 92 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 93 "Expected status %u, got %u(%d) for refund increase\n", 94 ris->http_code, 95 rr->hr.http_status, 96 (int) rr->hr.ec); 97 TALER_TESTING_FAIL (ris->is); 98 } 99 switch (rr->hr.http_status) 100 { 101 case MHD_HTTP_OK: 102 { 103 struct TALER_MERCHANT_RefundUriData rud; 104 105 if (GNUNET_OK != 106 TALER_MERCHANT_parse_refund_uri ( 107 rr->details.ok.taler_refund_uri, 108 &rud)) 109 { 110 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 111 "Taler refund uri is malformed\n"); 112 TALER_TESTING_interpreter_fail (ris->is); 113 return; 114 } 115 { 116 char *host; 117 118 host = TALER_MERCHANT_TESTING_extract_host (ris->merchant_url); 119 if ((0 != strcmp (host, 120 rud.merchant_host)) || 121 (NULL != rud.merchant_prefix_path) || 122 (0 != strcmp (ris->order_id, 123 rud.order_id)) || 124 (NULL != rud.ssid)) 125 { 126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 127 "Taler refund uri does not match\n"); 128 TALER_TESTING_interpreter_fail (ris->is); 129 TALER_MERCHANT_parse_refund_uri_free (&rud); 130 GNUNET_free (host); 131 return; 132 } 133 GNUNET_free (host); 134 } 135 TALER_MERCHANT_parse_refund_uri_free (&rud); 136 } 137 break; 138 case MHD_HTTP_UNAUTHORIZED: 139 break; 140 case MHD_HTTP_FORBIDDEN: 141 break; 142 case MHD_HTTP_NOT_FOUND: 143 break; 144 case MHD_HTTP_CONFLICT: 145 break; 146 default: 147 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 148 "Unhandled HTTP status %u for refund order.\n", 149 rr->hr.http_status); 150 } 151 TALER_TESTING_interpreter_next (ris->is); 152 } 153 154 155 /** 156 * Run the "refund increase" CMD. 157 * 158 * @param cls closure. 159 * @param cmd command currently being run. 160 * @param is the interpreter state. 161 */ 162 static void 163 refund_increase_run (void *cls, 164 const struct TALER_TESTING_Command *cmd, 165 struct TALER_TESTING_Interpreter *is) 166 { 167 struct RefundState *ris = cls; 168 169 ris->is = is; 170 ris->orh = TALER_MERCHANT_post_private_orders_refund_create ( 171 TALER_TESTING_interpreter_get_context (is), 172 ris->merchant_url, 173 ris->order_id, 174 &ris->refund_amount, 175 ris->reason); 176 { 177 enum TALER_ErrorCode ec; 178 179 ec = TALER_MERCHANT_post_private_orders_refund_start ( 180 ris->orh, 181 &refund_cb, 182 ris); 183 GNUNET_assert (TALER_EC_NONE == ec); 184 } 185 } 186 187 188 /** 189 * Offer internal data from the "refund increase" CMD 190 * state to other commands. 191 * 192 * @param cls closure 193 * @param[out] ret result (could be anything) 194 * @param trait name of the trait 195 * @param index index number of the object to extract. 196 * @return #GNUNET_OK on success 197 */ 198 static int 199 refund_increase_traits (void *cls, 200 const void **ret, 201 const char *trait, 202 unsigned int index) 203 { 204 struct RefundState *ris = cls; 205 struct TALER_TESTING_Trait traits[] = { 206 TALER_TESTING_make_trait_amount (&ris->refund_amount), 207 TALER_TESTING_make_trait_reason (ris->reason), 208 TALER_TESTING_trait_end () 209 }; 210 211 return TALER_TESTING_get_trait (traits, 212 ret, 213 trait, 214 index); 215 } 216 217 218 /** 219 * Free the state of a "refund increase" CMD, and 220 * possibly cancel a pending "refund increase" operation. 221 * 222 * @param cls closure 223 * @param cmd command currently being freed. 224 */ 225 static void 226 refund_increase_cleanup (void *cls, 227 const struct TALER_TESTING_Command *cmd) 228 { 229 struct RefundState *ris = cls; 230 231 if (NULL != ris->orh) 232 { 233 TALER_LOG_WARNING ("Refund operation did not complete\n"); 234 TALER_MERCHANT_post_private_orders_refund_cancel (ris->orh); 235 } 236 GNUNET_free (ris); 237 } 238 239 240 struct TALER_TESTING_Command 241 TALER_TESTING_cmd_merchant_order_refund (const char *label, 242 const char *merchant_url, 243 const char *reason, 244 const char *order_id, 245 const char *refund_amount, 246 unsigned int http_code) 247 { 248 struct RefundState *ris; 249 250 ris = GNUNET_new (struct RefundState); 251 ris->merchant_url = merchant_url; 252 ris->order_id = order_id; 253 GNUNET_assert (GNUNET_OK == 254 TALER_string_to_amount (refund_amount, 255 &ris->refund_amount)); 256 ris->reason = reason; 257 ris->http_code = http_code; 258 { 259 struct TALER_TESTING_Command cmd = { 260 .cls = ris, 261 .label = label, 262 .run = &refund_increase_run, 263 .cleanup = &refund_increase_cleanup, 264 .traits = &refund_increase_traits 265 }; 266 267 return cmd; 268 } 269 } 270 271 272 /* end of testing_api_cmd_refund_order.c */