Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020 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_get_reserve.c
21 : * @brief command to test GET /private/reserves/$RESERVE_PUB
22 : * @author Jonathan Buchanan
23 : */
24 : #include "platform.h"
25 : #include <taler/taler_exchange_service.h>
26 : #include <taler/taler_testing_lib.h>
27 : #include "taler_merchant_service.h"
28 : #include "taler_merchant_testing_lib.h"
29 :
30 :
31 : struct GetReserveState
32 : {
33 :
34 : /**
35 : * Handle for a "GET reserve" request.
36 : */
37 : struct TALER_MERCHANT_ReserveGetHandle *rgh;
38 :
39 : /**
40 : * The interpreter state.
41 : */
42 : struct TALER_TESTING_Interpreter *is;
43 :
44 : /**
45 : * Base URL of the merchant serving the request.
46 : */
47 : const char *merchant_url;
48 :
49 : /**
50 : * Label for a command that created a reserve.
51 : */
52 : const char *reserve_reference;
53 :
54 : /**
55 : * Expected HTTP response code.
56 : */
57 : unsigned int http_status;
58 :
59 : /**
60 : * Fetch tips
61 : */
62 : bool fetch_tips;
63 :
64 : /**
65 : * Length of @e tips.
66 : */
67 : unsigned int tips_length;
68 :
69 : /**
70 : * The list of references to tips.
71 : */
72 : const char **tips;
73 : };
74 :
75 :
76 : static void
77 0 : get_reserve_cb (void *cls,
78 : const struct TALER_MERCHANT_HttpResponse *hr,
79 : const struct TALER_MERCHANT_ReserveSummary *rs,
80 : bool active,
81 : const char *exchange_url,
82 : const char *payto_uri,
83 : unsigned int tips_length,
84 : const struct TALER_MERCHANT_TipDetails tips[])
85 : {
86 : /* FIXME, deeper checks should be implemented here. */
87 0 : struct GetReserveState *grs = cls;
88 : const struct TALER_TESTING_Command *reserve_cmd;
89 :
90 0 : reserve_cmd = TALER_TESTING_interpreter_lookup_command (
91 : grs->is,
92 : grs->reserve_reference);
93 :
94 0 : grs->rgh = NULL;
95 0 : if (grs->http_status != hr->http_status)
96 : {
97 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
98 : "Unexpected response code %u (%d) to command %s\n",
99 : hr->http_status,
100 : (int) hr->ec,
101 : TALER_TESTING_interpreter_get_current_label (grs->is));
102 0 : TALER_TESTING_interpreter_fail (grs->is);
103 0 : return;
104 : }
105 0 : switch (hr->http_status)
106 : {
107 0 : case MHD_HTTP_OK:
108 : // FIXME: use grs->reserve_reference here to
109 : // check if the data returned matches that from the POST / PATCH
110 : {
111 : const struct TALER_Amount *initial_amount;
112 0 : if (GNUNET_OK !=
113 0 : TALER_TESTING_get_trait_amount (reserve_cmd,
114 : &initial_amount))
115 0 : TALER_TESTING_interpreter_fail (grs->is);
116 0 : if ((GNUNET_OK !=
117 0 : TALER_amount_cmp_currency (&rs->merchant_initial_amount,
118 0 : initial_amount)) ||
119 0 : (0 != TALER_amount_cmp (&rs->merchant_initial_amount,
120 : initial_amount)))
121 : {
122 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
123 : "Reserve initial amount does not match\n");
124 0 : TALER_TESTING_interpreter_fail (grs->is);
125 0 : return;
126 : }
127 : }
128 0 : if (tips_length != grs->tips_length)
129 : {
130 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
131 : "Number of tips authorized does not match\n");
132 0 : TALER_TESTING_interpreter_fail (grs->is);
133 0 : return;
134 : }
135 0 : for (unsigned int i = 0; i < tips_length; ++i)
136 : {
137 : const struct TALER_TESTING_Command *tip_cmd;
138 :
139 0 : tip_cmd = TALER_TESTING_interpreter_lookup_command (grs->is,
140 0 : grs->tips[i]);
141 : {
142 : const struct TALER_TipIdentifierP *tip_id;
143 :
144 0 : if (GNUNET_OK !=
145 0 : TALER_TESTING_get_trait_tip_id (tip_cmd,
146 : &tip_id))
147 0 : TALER_TESTING_interpreter_fail (grs->is);
148 :
149 0 : if (0 != GNUNET_memcmp (&tips[i].tip_id,
150 : tip_id))
151 : {
152 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
153 : "Reserve tip id does not match\n");
154 0 : TALER_TESTING_interpreter_fail (grs->is);
155 0 : return;
156 : }
157 : }
158 : {
159 : const struct TALER_Amount *total_amount;
160 :
161 0 : if (GNUNET_OK !=
162 0 : TALER_TESTING_get_trait_amount (tip_cmd,
163 : &total_amount))
164 0 : TALER_TESTING_interpreter_fail (grs->is);
165 :
166 0 : if ((GNUNET_OK !=
167 0 : TALER_amount_cmp_currency (&tips[i].amount,
168 0 : total_amount)) ||
169 0 : (0 != TALER_amount_cmp (&tips[i].amount,
170 : total_amount)))
171 : {
172 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
173 : "Reserve tip amount does not match\n");
174 0 : TALER_TESTING_interpreter_fail (grs->is);
175 0 : return;
176 : }
177 : }
178 : {
179 : const char **reason;
180 :
181 0 : if (GNUNET_OK !=
182 0 : TALER_TESTING_get_trait_reason (tip_cmd,
183 : &reason))
184 0 : TALER_TESTING_interpreter_fail (grs->is);
185 :
186 0 : if (0 != strcmp (tips[i].reason,
187 : *reason))
188 : {
189 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
190 : "Reserve tip reason does not match\n");
191 0 : TALER_TESTING_interpreter_fail (grs->is);
192 0 : return;
193 : }
194 : }
195 : }
196 0 : break;
197 0 : default:
198 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
199 : "Unhandled HTTP status.\n");
200 : }
201 0 : TALER_TESTING_interpreter_next (grs->is);
202 : }
203 :
204 :
205 : /**
206 : * Run the "GET /private/reserves/$RESERVE_PUB" CMD.
207 : *
208 : * @param cls closure.
209 : * @param cmd command being run now.
210 : * @param is interpreter state.
211 : */
212 : static void
213 0 : get_reserve_run (void *cls,
214 : const struct TALER_TESTING_Command *cmd,
215 : struct TALER_TESTING_Interpreter *is)
216 : {
217 0 : struct GetReserveState *grs = cls;
218 : const struct TALER_TESTING_Command *reserve_cmd;
219 : const struct TALER_ReservePublicKeyP *reserve_pub;
220 :
221 0 : reserve_cmd = TALER_TESTING_interpreter_lookup_command (
222 : is,
223 : grs->reserve_reference);
224 0 : if (GNUNET_OK !=
225 0 : TALER_TESTING_get_trait_reserve_pub (reserve_cmd,
226 : &reserve_pub))
227 0 : TALER_TESTING_FAIL (is);
228 :
229 0 : grs->is = is;
230 0 : grs->rgh = TALER_MERCHANT_reserve_get (is->ctx,
231 : grs->merchant_url,
232 : reserve_pub,
233 0 : grs->fetch_tips,
234 : &get_reserve_cb,
235 : grs);
236 :
237 0 : GNUNET_assert (NULL != grs->rgh);
238 : }
239 :
240 :
241 : /**
242 : * Free the state of a "GET reserve" CMD, and possibly
243 : * cancel a pending operation thereof.
244 : *
245 : * @param cls closure.
246 : * @param cmd command being run.
247 : */
248 : static void
249 0 : get_reserve_cleanup (void *cls,
250 : const struct TALER_TESTING_Command *cmd)
251 : {
252 0 : struct GetReserveState *grs = cls;
253 :
254 0 : if (NULL != grs->rgh)
255 : {
256 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
257 : "GET /private/reserve/$RESERVE_PUB operation did not complete\n");
258 0 : TALER_MERCHANT_reserve_get_cancel (grs->rgh);
259 : }
260 0 : GNUNET_array_grow (grs->tips,
261 : grs->tips_length,
262 : 0);
263 0 : GNUNET_free (grs);
264 0 : }
265 :
266 :
267 : struct TALER_TESTING_Command
268 0 : TALER_TESTING_cmd_merchant_get_reserve (const char *label,
269 : const char *merchant_url,
270 : unsigned int http_status,
271 : const char *reserve_reference)
272 : {
273 : struct GetReserveState *grs;
274 :
275 0 : grs = GNUNET_new (struct GetReserveState);
276 0 : grs->merchant_url = merchant_url;
277 0 : grs->http_status = http_status;
278 0 : grs->reserve_reference = reserve_reference;
279 0 : grs->fetch_tips = false;
280 : {
281 0 : struct TALER_TESTING_Command cmd = {
282 : .cls = grs,
283 : .label = label,
284 : .run = &get_reserve_run,
285 : .cleanup = &get_reserve_cleanup
286 : };
287 :
288 0 : return cmd;
289 : }
290 : }
291 :
292 :
293 : struct TALER_TESTING_Command
294 0 : TALER_TESTING_cmd_merchant_get_reserve_with_tips (const char *label,
295 : const char *merchant_url,
296 : unsigned int http_status,
297 : const char *reserve_reference,
298 : ...)
299 : {
300 : struct GetReserveState *grs;
301 :
302 0 : grs = GNUNET_new (struct GetReserveState);
303 0 : grs->merchant_url = merchant_url;
304 0 : grs->http_status = http_status;
305 0 : grs->reserve_reference = reserve_reference;
306 0 : grs->fetch_tips = true;
307 : {
308 : const char *clabel;
309 : va_list ap;
310 :
311 0 : va_start (ap, reserve_reference);
312 0 : while (NULL != (clabel = va_arg (ap, const char *)))
313 : {
314 0 : GNUNET_array_append (grs->tips,
315 : grs->tips_length,
316 : clabel);
317 : }
318 0 : va_end (ap);
319 : }
320 : {
321 0 : struct TALER_TESTING_Command cmd = {
322 : .cls = grs,
323 : .label = label,
324 : .run = &get_reserve_run,
325 : .cleanup = &get_reserve_cleanup
326 : };
327 :
328 0 : return cmd;
329 : }
330 : }
331 :
332 :
333 : /* end of testing_api_cmd_get_reserve.c */
|