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