Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-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 : /**
21 : * @file testing/testing_api_cmd_transfer_get.c
22 : * @brief Implement the testing CMDs for the /transfer GET operation.
23 : * @author Marcello Stanisci
24 : */
25 : #include "platform.h"
26 : #include "taler_json_lib.h"
27 : #include <gnunet/gnunet_curl_lib.h>
28 : #include "taler_testing_lib.h"
29 :
30 : /**
31 : * State for a "track transfer" CMD.
32 : */
33 : struct TrackTransferState
34 : {
35 :
36 : /**
37 : * Expected amount for the WTID being tracked.
38 : */
39 : const char *expected_total_amount;
40 :
41 : /**
42 : * Expected fee for this WTID.
43 : */
44 : const char *expected_wire_fee;
45 :
46 : /**
47 : * Reference to any operation that can provide a WTID.
48 : * Will be the WTID to track.
49 : */
50 : const char *wtid_reference;
51 :
52 : /**
53 : * Reference to any operation that can provide wire details.
54 : * Those wire details will then be matched against the credit
55 : * bank account of the tracked WTID. This way we can test that
56 : * a wire transfer paid back one particular bank account.
57 : */
58 : const char *wire_details_reference;
59 :
60 : /**
61 : * Reference to any operation that can provide an amount.
62 : * This way we can check that the transferred amount matches
63 : * our expectations.
64 : */
65 : const char *total_amount_reference;
66 :
67 : /**
68 : * Handle to a pending "track transfer" operation.
69 : */
70 : struct TALER_EXCHANGE_TransfersGetHandle *tth;
71 :
72 : /**
73 : * Interpreter state.
74 : */
75 : struct TALER_TESTING_Interpreter *is;
76 :
77 : /**
78 : * Expected HTTP response code.
79 : */
80 : unsigned int expected_response_code;
81 :
82 : };
83 :
84 :
85 : /**
86 : * Cleanup the state for a "track transfer" CMD, and possibly
87 : * cancel a pending operation thereof.
88 : *
89 : * @param cls closure.
90 : * @param cmd the command which is being cleaned up.
91 : */
92 : static void
93 0 : track_transfer_cleanup (void *cls,
94 : const struct TALER_TESTING_Command *cmd)
95 : {
96 :
97 0 : struct TrackTransferState *tts = cls;
98 :
99 0 : if (NULL != tts->tth)
100 : {
101 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
102 : "Command %u (%s) did not complete\n",
103 : tts->is->ip,
104 : cmd->label);
105 0 : TALER_EXCHANGE_transfers_get_cancel (tts->tth);
106 0 : tts->tth = NULL;
107 : }
108 0 : GNUNET_free (tts);
109 0 : }
110 :
111 :
112 : /**
113 : * Check whether the HTTP response code from a "track transfer"
114 : * operation is acceptable, and all other values like total amount,
115 : * wire fees and hashed wire details as well.
116 : *
117 : * @param cls closure.
118 : * @param hr HTTP response details
119 : * @param ta transfer data returned by the exchange
120 : */
121 : static void
122 0 : track_transfer_cb (void *cls,
123 : const struct TALER_EXCHANGE_HttpResponse *hr,
124 : const struct TALER_EXCHANGE_TransferData *ta)
125 : {
126 0 : struct TrackTransferState *tts = cls;
127 0 : struct TALER_TESTING_Interpreter *is = tts->is;
128 0 : struct TALER_TESTING_Command *cmd = &is->commands[is->ip];
129 : struct TALER_Amount expected_amount;
130 :
131 0 : tts->tth = NULL;
132 0 : if (tts->expected_response_code != hr->http_status)
133 : {
134 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
135 : "Unexpected response code %u/%d to command %s in %s:%u\n",
136 : hr->http_status,
137 : (int) hr->ec,
138 : cmd->label,
139 : __FILE__,
140 : __LINE__);
141 0 : json_dumpf (hr->reply,
142 : stderr,
143 : 0);
144 0 : TALER_TESTING_interpreter_fail (is);
145 0 : return;
146 : }
147 :
148 0 : switch (hr->http_status)
149 : {
150 0 : case MHD_HTTP_OK:
151 0 : if (NULL == tts->expected_total_amount)
152 : {
153 0 : GNUNET_break (0);
154 0 : TALER_TESTING_interpreter_fail (is);
155 0 : return;
156 : }
157 0 : if (NULL == tts->expected_wire_fee)
158 : {
159 0 : GNUNET_break (0);
160 0 : TALER_TESTING_interpreter_fail (is);
161 0 : return;
162 : }
163 :
164 0 : if (GNUNET_OK !=
165 0 : TALER_string_to_amount (tts->expected_total_amount,
166 : &expected_amount))
167 : {
168 0 : GNUNET_break (0);
169 0 : TALER_TESTING_interpreter_fail (is);
170 0 : return;
171 : }
172 0 : if (0 != TALER_amount_cmp (&ta->total_amount,
173 : &expected_amount))
174 : {
175 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
176 : "Total amount mismatch to command %s - "
177 : "%s vs %s\n",
178 : cmd->label,
179 : TALER_amount_to_string (&ta->total_amount),
180 : TALER_amount_to_string (&expected_amount));
181 0 : json_dumpf (hr->reply,
182 : stderr,
183 : 0);
184 0 : fprintf (stderr, "\n");
185 0 : TALER_TESTING_interpreter_fail (is);
186 0 : return;
187 : }
188 :
189 0 : if (GNUNET_OK !=
190 0 : TALER_string_to_amount (tts->expected_wire_fee,
191 : &expected_amount))
192 : {
193 0 : GNUNET_break (0);
194 0 : TALER_TESTING_interpreter_fail (is);
195 0 : return;
196 : }
197 :
198 0 : if (0 != TALER_amount_cmp (&ta->wire_fee,
199 : &expected_amount))
200 : {
201 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
202 : "Wire fee mismatch to command %s\n",
203 : cmd->label);
204 0 : json_dumpf (hr->reply,
205 : stderr,
206 : 0);
207 0 : TALER_TESTING_interpreter_fail (is);
208 0 : return;
209 : }
210 :
211 : /**
212 : * Optionally checking: (1) wire-details for this transfer
213 : * match the ones from a referenced "deposit" operation -
214 : * or any operation that could provide wire-details. (2)
215 : * Total amount for this transfer matches the one from any
216 : * referenced command that could provide one.
217 : */
218 0 : if (NULL != tts->wire_details_reference)
219 : {
220 : const struct TALER_TESTING_Command *wire_details_cmd;
221 : const char **payto_uri;
222 : struct TALER_PaytoHashP h_payto;
223 :
224 : wire_details_cmd
225 0 : = TALER_TESTING_interpreter_lookup_command (is,
226 : tts->wire_details_reference);
227 0 : if (NULL == wire_details_cmd)
228 : {
229 0 : GNUNET_break (0);
230 0 : TALER_TESTING_interpreter_fail (is);
231 0 : return;
232 : }
233 0 : if (GNUNET_OK !=
234 0 : TALER_TESTING_get_trait_payto_uri (wire_details_cmd,
235 : &payto_uri))
236 : {
237 0 : GNUNET_break (0);
238 0 : TALER_TESTING_interpreter_fail (is);
239 0 : return;
240 : }
241 0 : TALER_payto_hash (*payto_uri,
242 : &h_payto);
243 0 : if (0 != GNUNET_memcmp (&h_payto,
244 : &ta->h_payto))
245 : {
246 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
247 : "Wire hash missmath to command %s\n",
248 : cmd->label);
249 0 : json_dumpf (hr->reply,
250 : stderr,
251 : 0);
252 0 : TALER_TESTING_interpreter_fail (is);
253 0 : return;
254 : }
255 : }
256 0 : if (NULL != tts->total_amount_reference)
257 : {
258 : const struct TALER_TESTING_Command *total_amount_cmd;
259 : const struct TALER_Amount *total_amount_from_reference;
260 :
261 : total_amount_cmd
262 0 : = TALER_TESTING_interpreter_lookup_command (is,
263 : tts->total_amount_reference);
264 0 : if (NULL == total_amount_cmd)
265 : {
266 0 : GNUNET_break (0);
267 0 : TALER_TESTING_interpreter_fail (is);
268 0 : return;
269 : }
270 0 : if (GNUNET_OK !=
271 0 : TALER_TESTING_get_trait_amount (total_amount_cmd,
272 : &total_amount_from_reference))
273 : {
274 0 : GNUNET_break (0);
275 0 : TALER_TESTING_interpreter_fail (is);
276 0 : return;
277 : }
278 0 : if (0 != TALER_amount_cmp (&ta->total_amount,
279 : total_amount_from_reference))
280 : {
281 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
282 : "Amount missmath to command %s\n",
283 : cmd->label);
284 0 : json_dumpf (hr->reply,
285 : stderr,
286 : 0);
287 0 : TALER_TESTING_interpreter_fail (is);
288 0 : return;
289 : }
290 : }
291 : }
292 0 : TALER_TESTING_interpreter_next (is);
293 : }
294 :
295 :
296 : /**
297 : * Run the command.
298 : *
299 : * @param cls closure.
300 : * @param cmd the command under execution.
301 : * @param is the interpreter state.
302 : */
303 : static void
304 0 : track_transfer_run (void *cls,
305 : const struct TALER_TESTING_Command *cmd,
306 : struct TALER_TESTING_Interpreter *is)
307 : {
308 : /* looking for a wtid to track .. */
309 0 : struct TrackTransferState *tts = cls;
310 : struct TALER_WireTransferIdentifierRawP wtid;
311 : const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
312 :
313 : /* If no reference is given, we'll use a all-zeros
314 : * WTID */
315 0 : memset (&wtid,
316 : 0,
317 : sizeof (wtid));
318 0 : wtid_ptr = &wtid;
319 :
320 0 : tts->is = is;
321 0 : if (NULL != tts->wtid_reference)
322 : {
323 : const struct TALER_TESTING_Command *wtid_cmd;
324 :
325 0 : wtid_cmd = TALER_TESTING_interpreter_lookup_command (tts->is,
326 : tts->wtid_reference);
327 0 : if (NULL == wtid_cmd)
328 : {
329 0 : GNUNET_break (0);
330 0 : TALER_TESTING_interpreter_fail (tts->is);
331 0 : return;
332 : }
333 :
334 0 : if (GNUNET_OK !=
335 0 : TALER_TESTING_get_trait_wtid (wtid_cmd,
336 : &wtid_ptr))
337 : {
338 0 : GNUNET_break (0);
339 0 : TALER_TESTING_interpreter_fail (tts->is);
340 0 : return;
341 : }
342 0 : GNUNET_assert (NULL != wtid_ptr);
343 : }
344 0 : tts->tth = TALER_EXCHANGE_transfers_get (is->exchange,
345 : wtid_ptr,
346 : &track_transfer_cb,
347 : tts);
348 0 : GNUNET_assert (NULL != tts->tth);
349 : }
350 :
351 :
352 : struct TALER_TESTING_Command
353 0 : TALER_TESTING_cmd_track_transfer_empty (const char *label,
354 : const char *wtid_reference,
355 : unsigned int expected_response_code)
356 : {
357 : struct TrackTransferState *tts;
358 :
359 0 : tts = GNUNET_new (struct TrackTransferState);
360 0 : tts->wtid_reference = wtid_reference;
361 0 : tts->expected_response_code = expected_response_code;
362 : {
363 0 : struct TALER_TESTING_Command cmd = {
364 : .cls = tts,
365 : .label = label,
366 : .run = &track_transfer_run,
367 : .cleanup = &track_transfer_cleanup
368 : };
369 :
370 0 : return cmd;
371 : }
372 : }
373 :
374 :
375 : struct TALER_TESTING_Command
376 0 : TALER_TESTING_cmd_track_transfer (const char *label,
377 : const char *wtid_reference,
378 : unsigned int expected_response_code,
379 : const char *expected_total_amount,
380 : const char *expected_wire_fee)
381 : {
382 : struct TrackTransferState *tts;
383 :
384 0 : tts = GNUNET_new (struct TrackTransferState);
385 0 : tts->wtid_reference = wtid_reference;
386 0 : tts->expected_response_code = expected_response_code;
387 0 : tts->expected_total_amount = expected_total_amount;
388 0 : tts->expected_wire_fee = expected_wire_fee;
389 : {
390 0 : struct TALER_TESTING_Command cmd = {
391 : .cls = tts,
392 : .label = label,
393 : .run = &track_transfer_run,
394 : .cleanup = &track_transfer_cleanup
395 : };
396 :
397 0 : return cmd;
398 : }
399 : }
400 :
401 :
402 : /* end of testing_api_cmd_gransfer_get.c */
|