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