Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-2019 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 hr HTTP response
80 : * @param taler_refund_uri the refund uri offered to the wallet
81 : * @param h_contract hash of the contract a Browser may need to authorize
82 : * obtaining the HTTP response.
83 : */
84 : static void
85 0 : refund_cb (void *cls,
86 : const struct TALER_MERCHANT_HttpResponse *hr,
87 : const char *taler_refund_uri,
88 : const struct TALER_PrivateContractHashP *h_contract)
89 : {
90 0 : struct RefundState *ris = cls;
91 :
92 : (void) h_contract;
93 0 : ris->orh = NULL;
94 0 : if (ris->http_code != hr->http_status)
95 : {
96 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
97 : "Expected status %u, got %u(%d) for refund increase\n",
98 : ris->http_code,
99 : hr->http_status,
100 : (int) hr->ec);
101 0 : TALER_TESTING_FAIL (ris->is);
102 : }
103 0 : switch (hr->http_status)
104 : {
105 0 : case MHD_HTTP_OK:
106 : {
107 : struct TALER_MERCHANT_RefundUriData rud;
108 :
109 0 : if (GNUNET_OK !=
110 0 : TALER_MERCHANT_parse_refund_uri (taler_refund_uri,
111 : &rud))
112 : {
113 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
114 : "Taler refund uri is malformed\n");
115 0 : TALER_TESTING_interpreter_fail (ris->is);
116 0 : return;
117 : }
118 : {
119 : char *port;
120 : char *host;
121 :
122 0 : if (GNUNET_OK !=
123 0 : GNUNET_CONFIGURATION_get_value_string (ris->is->cfg,
124 : "merchant",
125 : "PORT",
126 : &port))
127 : {
128 : /* How did we get here without a configured port? */
129 0 : GNUNET_break (0);
130 0 : TALER_TESTING_interpreter_fail (ris->is);
131 0 : TALER_MERCHANT_parse_refund_uri_free (&rud);
132 0 : return;
133 : }
134 0 : GNUNET_asprintf (&host,
135 : "localhost:%s",
136 : port);
137 0 : GNUNET_free (port);
138 0 : if ((0 != strcmp (host,
139 0 : rud.merchant_host)) ||
140 0 : (NULL != rud.merchant_prefix_path) ||
141 0 : (0 != strcmp (ris->order_id,
142 0 : rud.order_id)) ||
143 0 : (NULL != rud.ssid))
144 : {
145 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
146 : "Taler refund uri does not match\n");
147 0 : TALER_TESTING_interpreter_fail (ris->is);
148 0 : TALER_MERCHANT_parse_refund_uri_free (&rud);
149 0 : GNUNET_free (host);
150 0 : return;
151 : }
152 0 : GNUNET_free (host);
153 : }
154 0 : TALER_MERCHANT_parse_refund_uri_free (&rud);
155 : }
156 0 : break;
157 0 : case MHD_HTTP_UNAUTHORIZED:
158 0 : break;
159 0 : case MHD_HTTP_FORBIDDEN:
160 0 : break;
161 0 : case MHD_HTTP_NOT_FOUND:
162 0 : break;
163 0 : case MHD_HTTP_CONFLICT:
164 0 : break;
165 0 : default:
166 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
167 : "Unhandled HTTP status %u for refund order.\n",
168 : hr->http_status);
169 : }
170 0 : TALER_TESTING_interpreter_next (ris->is);
171 : }
172 :
173 :
174 : /**
175 : * Run the "refund increase" CMD.
176 : *
177 : * @param cls closure.
178 : * @param cmd command currently being run.
179 : * @param is the interpreter state.
180 : */
181 : static void
182 0 : refund_increase_run (void *cls,
183 : const struct TALER_TESTING_Command *cmd,
184 : struct TALER_TESTING_Interpreter *is)
185 : {
186 0 : struct RefundState *ris = cls;
187 :
188 0 : ris->is = is;
189 0 : ris->orh = TALER_MERCHANT_post_order_refund (is->ctx,
190 : ris->merchant_url,
191 : ris->order_id,
192 0 : &ris->refund_amount,
193 : ris->reason,
194 : &refund_cb,
195 : ris);
196 0 : if (NULL == ris->orh)
197 0 : TALER_TESTING_FAIL (is);
198 : }
199 :
200 :
201 : /**
202 : * Offer internal data from the "refund increase" CMD
203 : * state to other commands.
204 : *
205 : * @param cls closure
206 : * @param[out] ret result (could be anything)
207 : * @param trait name of the trait
208 : * @param index index number of the object to extract.
209 : * @return #GNUNET_OK on success
210 : */
211 : static int
212 0 : refund_increase_traits (void *cls,
213 : const void **ret,
214 : const char *trait,
215 : unsigned int index)
216 : {
217 0 : struct RefundState *ris = cls;
218 : struct TALER_TESTING_Trait traits[] = {
219 0 : TALER_TESTING_make_trait_amount (&ris->refund_amount),
220 0 : TALER_TESTING_make_trait_reason (&ris->reason),
221 0 : TALER_TESTING_trait_end ()
222 : };
223 :
224 0 : return TALER_TESTING_get_trait (traits,
225 : ret,
226 : trait,
227 : index);
228 : }
229 :
230 :
231 : /**
232 : * Free the state of a "refund increase" CMD, and
233 : * possibly cancel a pending "refund increase" operation.
234 : *
235 : * @param cls closure
236 : * @param cmd command currently being freed.
237 : */
238 : static void
239 0 : refund_increase_cleanup (void *cls,
240 : const struct TALER_TESTING_Command *cmd)
241 : {
242 0 : struct RefundState *ris = cls;
243 :
244 0 : if (NULL != ris->orh)
245 : {
246 0 : TALER_LOG_WARNING ("Refund operation did not complete\n");
247 0 : TALER_MERCHANT_post_order_refund_cancel (ris->orh);
248 : }
249 0 : GNUNET_free (ris);
250 0 : }
251 :
252 :
253 : struct TALER_TESTING_Command
254 0 : TALER_TESTING_cmd_merchant_order_refund (const char *label,
255 : const char *merchant_url,
256 : const char *reason,
257 : const char *order_id,
258 : const char *refund_amount,
259 : unsigned int http_code)
260 : {
261 : struct RefundState *ris;
262 :
263 0 : ris = GNUNET_new (struct RefundState);
264 0 : ris->merchant_url = merchant_url;
265 0 : ris->order_id = order_id;
266 0 : GNUNET_assert (GNUNET_OK ==
267 : TALER_string_to_amount (refund_amount,
268 : &ris->refund_amount));
269 0 : ris->reason = reason;
270 0 : ris->http_code = http_code;
271 : {
272 0 : struct TALER_TESTING_Command cmd = {
273 : .cls = ris,
274 : .label = label,
275 : .run = &refund_increase_run,
276 : .cleanup = &refund_increase_cleanup,
277 : .traits = &refund_increase_traits
278 : };
279 :
280 0 : return cmd;
281 : }
282 : }
283 :
284 :
285 : /* end of testing_api_cmd_refund_order.c */
|