Line data Source code
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 14 : refund_cb (struct RefundState *ris,
86 : const struct TALER_MERCHANT_PostPrivateOrdersRefundResponse *rr)
87 : {
88 :
89 14 : ris->orh = NULL;
90 14 : if (ris->http_code != rr->hr.http_status)
91 : {
92 0 : 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 0 : TALER_TESTING_FAIL (ris->is);
98 : }
99 14 : switch (rr->hr.http_status)
100 : {
101 8 : case MHD_HTTP_OK:
102 : {
103 : struct TALER_MERCHANT_RefundUriData rud;
104 :
105 8 : if (GNUNET_OK !=
106 8 : TALER_MERCHANT_parse_refund_uri (
107 8 : rr->details.ok.taler_refund_uri,
108 : &rud))
109 : {
110 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
111 : "Taler refund uri is malformed\n");
112 0 : TALER_TESTING_interpreter_fail (ris->is);
113 0 : return;
114 : }
115 : {
116 : char *host;
117 :
118 8 : host = TALER_MERCHANT_TESTING_extract_host (ris->merchant_url);
119 8 : if ((0 != strcmp (host,
120 8 : rud.merchant_host)) ||
121 8 : (NULL != rud.merchant_prefix_path) ||
122 8 : (0 != strcmp (ris->order_id,
123 8 : rud.order_id)) ||
124 8 : (NULL != rud.ssid))
125 : {
126 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
127 : "Taler refund uri does not match\n");
128 0 : TALER_TESTING_interpreter_fail (ris->is);
129 0 : TALER_MERCHANT_parse_refund_uri_free (&rud);
130 0 : GNUNET_free (host);
131 0 : return;
132 : }
133 8 : GNUNET_free (host);
134 : }
135 8 : TALER_MERCHANT_parse_refund_uri_free (&rud);
136 : }
137 8 : break;
138 0 : case MHD_HTTP_UNAUTHORIZED:
139 0 : break;
140 0 : case MHD_HTTP_FORBIDDEN:
141 0 : break;
142 2 : case MHD_HTTP_NOT_FOUND:
143 2 : break;
144 4 : case MHD_HTTP_CONFLICT:
145 4 : break;
146 0 : default:
147 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
148 : "Unhandled HTTP status %u for refund order.\n",
149 : rr->hr.http_status);
150 : }
151 14 : 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 14 : refund_increase_run (void *cls,
164 : const struct TALER_TESTING_Command *cmd,
165 : struct TALER_TESTING_Interpreter *is)
166 : {
167 14 : struct RefundState *ris = cls;
168 :
169 14 : ris->is = is;
170 14 : 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 14 : &ris->refund_amount,
175 : ris->reason);
176 : {
177 : enum TALER_ErrorCode ec;
178 :
179 14 : ec = TALER_MERCHANT_post_private_orders_refund_start (
180 : ris->orh,
181 : &refund_cb,
182 : ris);
183 14 : GNUNET_assert (TALER_EC_NONE == ec);
184 : }
185 14 : }
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 20 : refund_increase_traits (void *cls,
200 : const void **ret,
201 : const char *trait,
202 : unsigned int index)
203 : {
204 20 : struct RefundState *ris = cls;
205 : struct TALER_TESTING_Trait traits[] = {
206 20 : TALER_TESTING_make_trait_amount (&ris->refund_amount),
207 20 : TALER_TESTING_make_trait_reason (ris->reason),
208 20 : TALER_TESTING_trait_end ()
209 : };
210 :
211 20 : 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 14 : refund_increase_cleanup (void *cls,
227 : const struct TALER_TESTING_Command *cmd)
228 : {
229 14 : struct RefundState *ris = cls;
230 :
231 14 : if (NULL != ris->orh)
232 : {
233 0 : TALER_LOG_WARNING ("Refund operation did not complete\n");
234 0 : TALER_MERCHANT_post_private_orders_refund_cancel (ris->orh);
235 : }
236 14 : GNUNET_free (ris);
237 14 : }
238 :
239 :
240 : struct TALER_TESTING_Command
241 14 : 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 14 : ris = GNUNET_new (struct RefundState);
251 14 : ris->merchant_url = merchant_url;
252 14 : ris->order_id = order_id;
253 14 : GNUNET_assert (GNUNET_OK ==
254 : TALER_string_to_amount (refund_amount,
255 : &ris->refund_amount));
256 14 : ris->reason = reason;
257 14 : ris->http_code = http_code;
258 : {
259 14 : 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 14 : return cmd;
268 : }
269 : }
270 :
271 :
272 : /* end of testing_api_cmd_refund_order.c */
|