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_get_transfers.c
21 : * @brief command to test GET /transfers.
22 : * @author Marcello Stanisci
23 : * @author Christian Grothoff
24 : */
25 : #include "platform.h"
26 : struct GetTransfersState;
27 : #define TALER_MERCHANT_GET_PRIVATE_TRANSFERS_RESULT_CLOSURE struct GetTransfersState
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/get-private-transfers.h>
33 :
34 :
35 : /**
36 : * State of a GET transfers CMD.
37 : */
38 : struct GetTransfersState
39 : {
40 :
41 : /**
42 : * Handle for a "get transfer" request.
43 : */
44 : struct TALER_MERCHANT_GetPrivateTransfersHandle *gth;
45 :
46 : /**
47 : * The interpreter state.
48 : */
49 : struct TALER_TESTING_Interpreter *is;
50 :
51 : /**
52 : * Base URL of the merchant serving the request.
53 : */
54 : const char *merchant_url;
55 :
56 : /**
57 : * payto URI of the merchant to filter by.
58 : */
59 : struct TALER_FullPayto payto_uri;
60 :
61 : /**
62 : * Expected HTTP response code.
63 : */
64 : unsigned int http_status;
65 :
66 : /**
67 : * Reference for a "check bank" CMD. It offers the
68 : * WTID to get.
69 : */
70 : const char *check_bank_reference;
71 :
72 : /**
73 : * Array of POST /transfer command labels we expect to see listed.
74 : */
75 : const char **transfers;
76 :
77 : /**
78 : * Length of @e transfers.
79 : */
80 : unsigned int transfers_length;
81 :
82 : };
83 :
84 :
85 : /**
86 : * Check the result of our GET /transfers request to a merchant
87 : *
88 : * @param cls closure
89 : * @param gtr response details
90 : */
91 : static void
92 4 : get_transfers_cb (
93 : struct GetTransfersState *gts,
94 : const struct TALER_MERCHANT_GetPrivateTransfersResponse *gtr)
95 : {
96 :
97 4 : gts->gth = NULL;
98 4 : if (gts->http_status != gtr->hr.http_status)
99 : {
100 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
101 : "Unexpected response code %u (%d) to command %s\n",
102 : gtr->hr.http_status,
103 : (int) gtr->hr.ec,
104 : TALER_TESTING_interpreter_get_current_label (gts->is));
105 0 : TALER_TESTING_interpreter_fail (gts->is);
106 0 : return;
107 : }
108 4 : switch (gtr->hr.http_status)
109 : {
110 4 : case MHD_HTTP_OK:
111 4 : if (gtr->details.ok.transfers_length != gts->transfers_length)
112 : {
113 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
114 : "Transfers length does not match (got %u/want %u)\n",
115 : gtr->details.ok.transfers_length,
116 : gts->transfers_length);
117 0 : TALER_TESTING_interpreter_fail (gts->is);
118 0 : return;
119 : }
120 11 : for (unsigned int i = 0; i < gtr->details.ok.transfers_length; ++i)
121 : {
122 7 : const struct TALER_MERCHANT_GetPrivateTransfersTransferData *transfer
123 7 : = >r->details.ok.transfers[i];
124 : const struct TALER_TESTING_Command *transfer_cmd;
125 :
126 7 : transfer_cmd = TALER_TESTING_interpreter_lookup_command (
127 : gts->is,
128 7 : gts->transfers[i]);
129 7 : if (NULL == transfer_cmd)
130 : {
131 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
132 : "Command `%s' not found!\n",
133 : gts->transfers[i]);
134 0 : TALER_TESTING_interpreter_fail (gts->is);
135 0 : return;
136 : }
137 : {
138 : const struct TALER_WireTransferIdentifierRawP *wtid;
139 :
140 7 : if (GNUNET_OK !=
141 7 : TALER_TESTING_get_trait_wtid (transfer_cmd,
142 : &wtid))
143 : {
144 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
145 : "Could not fetch wire transfer id\n");
146 0 : TALER_TESTING_interpreter_fail (gts->is);
147 0 : return;
148 : }
149 7 : if (0 != GNUNET_memcmp (wtid,
150 : &transfer->wtid))
151 : {
152 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
153 : "Wire transfer id does not match\n");
154 0 : TALER_TESTING_interpreter_fail (gts->is);
155 0 : return;
156 : }
157 7 : TALER_TESTING_cmd_merchant_post_transfer_set_serial (
158 : (struct TALER_TESTING_Command *) transfer_cmd,
159 7 : transfer->transfer_serial_id);
160 : }
161 : {
162 : const struct TALER_FullPayto *payto_uri;
163 :
164 7 : if (GNUNET_OK !=
165 7 : TALER_TESTING_get_trait_credit_payto_uri (transfer_cmd,
166 : &payto_uri))
167 : {
168 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
169 : "Could not fetch wire transfer payto uri\n");
170 0 : TALER_TESTING_interpreter_fail (gts->is);
171 0 : return;
172 : }
173 7 : if (0 !=
174 7 : TALER_full_payto_cmp (*payto_uri,
175 : transfer->payto_uri))
176 : {
177 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
178 : "Wire transfer payto uri does not match: %s != %s\n",
179 : payto_uri->full_payto,
180 : transfer->payto_uri.full_payto);
181 0 : TALER_TESTING_interpreter_fail (gts->is);
182 0 : return;
183 : }
184 : }
185 : {
186 : const struct TALER_Amount *credit_amount;
187 :
188 7 : if (GNUNET_OK !=
189 7 : TALER_TESTING_get_trait_amount (transfer_cmd,
190 : &credit_amount))
191 : {
192 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
193 : "Could not fetch wire transfer credit amount\n");
194 0 : TALER_TESTING_interpreter_fail (gts->is);
195 0 : return;
196 : }
197 7 : if ( (GNUNET_OK !=
198 7 : TALER_amount_cmp_currency (credit_amount,
199 7 : &transfer->credit_amount)) ||
200 7 : (0 != TALER_amount_cmp (credit_amount,
201 : &transfer->credit_amount)))
202 : {
203 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
204 : "Wire transfer credit amount does not match\n");
205 0 : TALER_TESTING_interpreter_fail (gts->is);
206 0 : return;
207 : }
208 : }
209 : {
210 : const char *exchange_url;
211 :
212 7 : if (GNUNET_OK !=
213 7 : TALER_TESTING_get_trait_exchange_url (transfer_cmd,
214 : &exchange_url))
215 : {
216 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217 : "Could not fetch wire transfer exchange url\n");
218 0 : TALER_TESTING_interpreter_fail (gts->is);
219 0 : return;
220 : }
221 7 : if (0 != strcmp (exchange_url,
222 7 : transfer->exchange_url))
223 : {
224 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
225 : "Wire transfer exchange url does not match\n");
226 0 : TALER_TESTING_interpreter_fail (gts->is);
227 0 : return;
228 : }
229 : }
230 : }
231 4 : break;
232 0 : default:
233 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
234 : "Unhandled HTTP status %u.\n",
235 : gtr->hr.http_status);
236 0 : break;
237 : }
238 4 : TALER_TESTING_interpreter_next (gts->is);
239 : }
240 :
241 :
242 : /**
243 : * Run the "get transfer" CMD.
244 : *
245 : * @param cls closure.
246 : * @param cmd command being run now.
247 : * @param is interpreter state.
248 : */
249 : static void
250 4 : get_transfers_run (void *cls,
251 : const struct TALER_TESTING_Command *cmd,
252 : struct TALER_TESTING_Interpreter *is)
253 : {
254 4 : struct GetTransfersState *gts = cls;
255 :
256 4 : gts->is = is;
257 4 : gts->gth = TALER_MERCHANT_get_private_transfers_create (
258 : TALER_TESTING_interpreter_get_context (is),
259 : gts->merchant_url);
260 4 : TALER_MERCHANT_get_private_transfers_set_options (
261 : gts->gth,
262 : TALER_MERCHANT_get_private_transfers_option_payto_uri (gts->payto_uri),
263 : TALER_MERCHANT_get_private_transfers_option_before (
264 : GNUNET_TIME_UNIT_FOREVER_TS),
265 : TALER_MERCHANT_get_private_transfers_option_after (GNUNET_TIME_UNIT_ZERO_TS)
266 : ,
267 : TALER_MERCHANT_get_private_transfers_option_limit (INT64_MAX),
268 : TALER_MERCHANT_get_private_transfers_option_offset (0),
269 : TALER_MERCHANT_get_private_transfers_option_expected (TALER_EXCHANGE_YNA_ALL
270 : ));
271 : {
272 : enum TALER_ErrorCode ec;
273 :
274 4 : ec = TALER_MERCHANT_get_private_transfers_start (
275 : gts->gth,
276 : &get_transfers_cb,
277 : gts);
278 4 : GNUNET_assert (TALER_EC_NONE == ec);
279 : }
280 4 : }
281 :
282 :
283 : /**
284 : * Free the state of a "get transfer" CMD, and possibly
285 : * cancel a pending operation thereof.
286 : *
287 : * @param cls closure.
288 : * @param cmd command being run.
289 : */
290 : static void
291 4 : get_transfers_cleanup (void *cls,
292 : const struct TALER_TESTING_Command *cmd)
293 : {
294 4 : struct GetTransfersState *gts = cls;
295 :
296 4 : if (NULL != gts->gth)
297 : {
298 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
299 : "GET /transfer operation did not complete\n");
300 0 : TALER_MERCHANT_get_private_transfers_cancel (gts->gth);
301 : }
302 4 : GNUNET_array_grow (gts->transfers,
303 : gts->transfers_length,
304 : 0);
305 4 : GNUNET_free (gts);
306 4 : }
307 :
308 :
309 : struct TALER_TESTING_Command
310 4 : TALER_TESTING_cmd_merchant_get_transfers (
311 : const char *label,
312 : const char *merchant_url,
313 : struct TALER_FullPayto payto_uri,
314 : unsigned int http_code,
315 : ...)
316 : {
317 : struct GetTransfersState *gts;
318 :
319 4 : gts = GNUNET_new (struct GetTransfersState);
320 4 : gts->merchant_url = merchant_url;
321 4 : gts->payto_uri = payto_uri;
322 4 : gts->http_status = http_code;
323 : {
324 : const char *clabel;
325 : va_list ap;
326 :
327 4 : va_start (ap, http_code);
328 11 : while (NULL != (clabel = va_arg (ap, const char *)))
329 : {
330 7 : GNUNET_array_append (gts->transfers,
331 : gts->transfers_length,
332 : clabel);
333 : }
334 4 : va_end (ap);
335 : }
336 : {
337 4 : struct TALER_TESTING_Command cmd = {
338 : .cls = gts,
339 : .label = label,
340 : .run = &get_transfers_run,
341 : .cleanup = &get_transfers_cleanup
342 : };
343 :
344 4 : return cmd;
345 : }
346 : }
347 :
348 :
349 : /* end of testing_api_cmd_get_transfers.c */
|