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 0 : struct GetReserveState *grs = cls;
87 : const struct TALER_TESTING_Command *reserve_cmd;
88 :
89 0 : reserve_cmd = TALER_TESTING_interpreter_lookup_command (
90 : grs->is,
91 : grs->reserve_reference);
92 :
93 0 : grs->rgh = NULL;
94 0 : if (grs->http_status != hr->http_status)
95 : {
96 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
97 : "Unexpected response code %u (%d) to command %s\n",
98 : hr->http_status,
99 : (int) hr->ec,
100 : TALER_TESTING_interpreter_get_current_label (grs->is));
101 0 : TALER_TESTING_interpreter_fail (grs->is);
102 0 : return;
103 : }
104 0 : switch (hr->http_status)
105 : {
106 0 : case MHD_HTTP_OK:
107 : {
108 : const struct TALER_Amount *initial_amount;
109 0 : if (GNUNET_OK !=
110 0 : TALER_TESTING_get_trait_amount (reserve_cmd,
111 : &initial_amount))
112 0 : TALER_TESTING_interpreter_fail (grs->is);
113 0 : if ((GNUNET_OK !=
114 0 : TALER_amount_cmp_currency (&rs->merchant_initial_amount,
115 0 : initial_amount)) ||
116 0 : (0 != TALER_amount_cmp (&rs->merchant_initial_amount,
117 : initial_amount)))
118 : {
119 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
120 : "Reserve initial amount does not match\n");
121 0 : TALER_TESTING_interpreter_fail (grs->is);
122 0 : return;
123 : }
124 : }
125 0 : if (tips_length != grs->tips_length)
126 : {
127 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
128 : "Number of tips authorized does not match\n");
129 0 : TALER_TESTING_interpreter_fail (grs->is);
130 0 : return;
131 : }
132 0 : for (unsigned int i = 0; i < tips_length; ++i)
133 : {
134 : const struct TALER_TESTING_Command *tip_cmd;
135 :
136 0 : tip_cmd = TALER_TESTING_interpreter_lookup_command (grs->is,
137 0 : grs->tips[i]);
138 : {
139 : const struct TALER_TipIdentifierP *tip_id;
140 :
141 0 : if (GNUNET_OK !=
142 0 : TALER_TESTING_get_trait_tip_id (tip_cmd,
143 : &tip_id))
144 0 : TALER_TESTING_interpreter_fail (grs->is);
145 :
146 0 : if (0 != GNUNET_memcmp (&tips[i].tip_id,
147 : tip_id))
148 : {
149 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
150 : "Reserve tip id does not match\n");
151 0 : TALER_TESTING_interpreter_fail (grs->is);
152 0 : return;
153 : }
154 : }
155 : {
156 : const struct TALER_Amount *total_amount;
157 :
158 0 : if (GNUNET_OK !=
159 0 : TALER_TESTING_get_trait_amount (tip_cmd,
160 : &total_amount))
161 0 : TALER_TESTING_interpreter_fail (grs->is);
162 :
163 0 : if ((GNUNET_OK !=
164 0 : TALER_amount_cmp_currency (&tips[i].amount,
165 0 : total_amount)) ||
166 0 : (0 != TALER_amount_cmp (&tips[i].amount,
167 : total_amount)))
168 : {
169 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
170 : "Reserve tip amount does not match\n");
171 0 : TALER_TESTING_interpreter_fail (grs->is);
172 0 : return;
173 : }
174 : }
175 : {
176 : const char **reason;
177 :
178 0 : if (GNUNET_OK !=
179 0 : TALER_TESTING_get_trait_reason (tip_cmd,
180 : &reason))
181 0 : TALER_TESTING_interpreter_fail (grs->is);
182 :
183 0 : if (0 != strcmp (tips[i].reason,
184 : *reason))
185 : {
186 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
187 : "Reserve tip reason does not match\n");
188 0 : TALER_TESTING_interpreter_fail (grs->is);
189 0 : return;
190 : }
191 : }
192 : }
193 0 : break;
194 0 : default:
195 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
196 : "Unhandled HTTP status.\n");
197 : }
198 0 : TALER_TESTING_interpreter_next (grs->is);
199 : }
200 :
201 :
202 : /**
203 : * Run the "GET /private/reserves/$RESERVE_PUB" CMD.
204 : *
205 : * @param cls closure.
206 : * @param cmd command being run now.
207 : * @param is interpreter state.
208 : */
209 : static void
210 0 : get_reserve_run (void *cls,
211 : const struct TALER_TESTING_Command *cmd,
212 : struct TALER_TESTING_Interpreter *is)
213 : {
214 0 : struct GetReserveState *grs = cls;
215 : const struct TALER_TESTING_Command *reserve_cmd;
216 : const struct TALER_ReservePublicKeyP *reserve_pub;
217 :
218 0 : reserve_cmd = TALER_TESTING_interpreter_lookup_command (
219 : is,
220 : grs->reserve_reference);
221 0 : if (GNUNET_OK !=
222 0 : TALER_TESTING_get_trait_reserve_pub (reserve_cmd,
223 : &reserve_pub))
224 0 : TALER_TESTING_FAIL (is);
225 :
226 0 : grs->is = is;
227 0 : grs->rgh = TALER_MERCHANT_reserve_get (is->ctx,
228 : grs->merchant_url,
229 : reserve_pub,
230 0 : grs->fetch_tips,
231 : &get_reserve_cb,
232 : grs);
233 :
234 0 : GNUNET_assert (NULL != grs->rgh);
235 : }
236 :
237 :
238 : /**
239 : * Free the state of a "GET reserve" CMD, and possibly
240 : * cancel a pending operation thereof.
241 : *
242 : * @param cls closure.
243 : * @param cmd command being run.
244 : */
245 : static void
246 0 : get_reserve_cleanup (void *cls,
247 : const struct TALER_TESTING_Command *cmd)
248 : {
249 0 : struct GetReserveState *grs = cls;
250 :
251 0 : if (NULL != grs->rgh)
252 : {
253 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
254 : "GET /private/reserve/$RESERVE_PUB operation did not complete\n");
255 0 : TALER_MERCHANT_reserve_get_cancel (grs->rgh);
256 : }
257 0 : GNUNET_array_grow (grs->tips,
258 : grs->tips_length,
259 : 0);
260 0 : GNUNET_free (grs);
261 0 : }
262 :
263 :
264 : struct TALER_TESTING_Command
265 0 : TALER_TESTING_cmd_merchant_get_reserve (const char *label,
266 : const char *merchant_url,
267 : unsigned int http_status,
268 : const char *reserve_reference)
269 : {
270 : struct GetReserveState *grs;
271 :
272 0 : grs = GNUNET_new (struct GetReserveState);
273 0 : grs->merchant_url = merchant_url;
274 0 : grs->http_status = http_status;
275 0 : grs->reserve_reference = reserve_reference;
276 0 : grs->fetch_tips = false;
277 : {
278 0 : struct TALER_TESTING_Command cmd = {
279 : .cls = grs,
280 : .label = label,
281 : .run = &get_reserve_run,
282 : .cleanup = &get_reserve_cleanup
283 : };
284 :
285 0 : return cmd;
286 : }
287 : }
288 :
289 :
290 : struct TALER_TESTING_Command
291 0 : TALER_TESTING_cmd_merchant_get_reserve_with_tips (const char *label,
292 : const char *merchant_url,
293 : unsigned int http_status,
294 : const char *reserve_reference,
295 : ...)
296 : {
297 : struct GetReserveState *grs;
298 :
299 0 : grs = GNUNET_new (struct GetReserveState);
300 0 : grs->merchant_url = merchant_url;
301 0 : grs->http_status = http_status;
302 0 : grs->reserve_reference = reserve_reference;
303 0 : grs->fetch_tips = true;
304 : {
305 : const char *clabel;
306 : va_list ap;
307 :
308 0 : va_start (ap, reserve_reference);
309 0 : while (NULL != (clabel = va_arg (ap, const char *)))
310 : {
311 0 : GNUNET_array_append (grs->tips,
312 : grs->tips_length,
313 : clabel);
314 : }
315 0 : va_end (ap);
316 : }
317 : {
318 0 : struct TALER_TESTING_Command cmd = {
319 : .cls = grs,
320 : .label = label,
321 : .run = &get_reserve_run,
322 : .cleanup = &get_reserve_cleanup
323 : };
324 :
325 0 : return cmd;
326 : }
327 : }
328 :
329 :
330 : /* end of testing_api_cmd_get_reserve.c */
|