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 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 10 : refund_cb (void *cls,
83 : const struct TALER_MERCHANT_RefundResponse *rr)
84 : {
85 10 : struct RefundState *ris = cls;
86 :
87 10 : ris->orh = NULL;
88 10 : if (ris->http_code != rr->hr.http_status)
89 : {
90 0 : 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 0 : TALER_TESTING_FAIL (ris->is);
96 : }
97 10 : switch (rr->hr.http_status)
98 : {
99 6 : case MHD_HTTP_OK:
100 : {
101 : struct TALER_MERCHANT_RefundUriData rud;
102 :
103 6 : if (GNUNET_OK !=
104 6 : TALER_MERCHANT_parse_refund_uri (
105 6 : rr->details.ok.taler_refund_uri,
106 : &rud))
107 : {
108 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
109 : "Taler refund uri is malformed\n");
110 0 : TALER_TESTING_interpreter_fail (ris->is);
111 0 : return;
112 : }
113 : {
114 : char *host;
115 :
116 6 : host = TALER_MERCHANT_TESTING_extract_host (ris->merchant_url);
117 6 : if ((0 != strcmp (host,
118 6 : rud.merchant_host)) ||
119 6 : (NULL != rud.merchant_prefix_path) ||
120 6 : (0 != strcmp (ris->order_id,
121 6 : rud.order_id)) ||
122 6 : (NULL != rud.ssid))
123 : {
124 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125 : "Taler refund uri does not match\n");
126 0 : TALER_TESTING_interpreter_fail (ris->is);
127 0 : TALER_MERCHANT_parse_refund_uri_free (&rud);
128 0 : GNUNET_free (host);
129 0 : return;
130 : }
131 6 : GNUNET_free (host);
132 : }
133 6 : TALER_MERCHANT_parse_refund_uri_free (&rud);
134 : }
135 6 : break;
136 0 : case MHD_HTTP_UNAUTHORIZED:
137 0 : break;
138 0 : case MHD_HTTP_FORBIDDEN:
139 0 : break;
140 2 : case MHD_HTTP_NOT_FOUND:
141 2 : break;
142 2 : case MHD_HTTP_CONFLICT:
143 2 : break;
144 0 : default:
145 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
146 : "Unhandled HTTP status %u for refund order.\n",
147 : rr->hr.http_status);
148 : }
149 10 : 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 10 : refund_increase_run (void *cls,
162 : const struct TALER_TESTING_Command *cmd,
163 : struct TALER_TESTING_Interpreter *is)
164 : {
165 10 : struct RefundState *ris = cls;
166 :
167 10 : ris->is = is;
168 10 : ris->orh = TALER_MERCHANT_post_order_refund (
169 : TALER_TESTING_interpreter_get_context (is),
170 : ris->merchant_url,
171 : ris->order_id,
172 10 : &ris->refund_amount,
173 : ris->reason,
174 : &refund_cb,
175 : ris);
176 10 : if (NULL == ris->orh)
177 0 : 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 20 : refund_increase_traits (void *cls,
193 : const void **ret,
194 : const char *trait,
195 : unsigned int index)
196 : {
197 20 : struct RefundState *ris = cls;
198 : struct TALER_TESTING_Trait traits[] = {
199 20 : TALER_TESTING_make_trait_amount (&ris->refund_amount),
200 20 : TALER_TESTING_make_trait_reason (ris->reason),
201 20 : TALER_TESTING_trait_end ()
202 : };
203 :
204 20 : 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 10 : refund_increase_cleanup (void *cls,
220 : const struct TALER_TESTING_Command *cmd)
221 : {
222 10 : struct RefundState *ris = cls;
223 :
224 10 : if (NULL != ris->orh)
225 : {
226 0 : TALER_LOG_WARNING ("Refund operation did not complete\n");
227 0 : TALER_MERCHANT_post_order_refund_cancel (ris->orh);
228 : }
229 10 : GNUNET_free (ris);
230 10 : }
231 :
232 :
233 : struct TALER_TESTING_Command
234 10 : 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 10 : ris = GNUNET_new (struct RefundState);
244 10 : ris->merchant_url = merchant_url;
245 10 : ris->order_id = order_id;
246 10 : GNUNET_assert (GNUNET_OK ==
247 : TALER_string_to_amount (refund_amount,
248 : &ris->refund_amount));
249 10 : ris->reason = reason;
250 10 : ris->http_code = http_code;
251 : {
252 10 : 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 10 : return cmd;
261 : }
262 : }
263 :
264 :
265 : /* end of testing_api_cmd_refund_order.c */
|