Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014--2022 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/test_exchange_api.c
21 : * @brief testcase to test exchange's HTTP API interface
22 : * @author Sree Harsha Totakura <sreeharsha@totakura.in>
23 : * @author Christian Grothoff
24 : * @author Marcello Stanisci
25 : */
26 : #include "taler/taler_util.h"
27 : #include "taler/taler_signatures.h"
28 : #include "taler/taler_json_lib.h"
29 : #include <gnunet/gnunet_util_lib.h>
30 : #include <gnunet/gnunet_testing_lib.h>
31 : #include <microhttpd.h>
32 : #include "taler/taler_bank_service.h"
33 : #include "taler/taler_testing_lib.h"
34 :
35 : /**
36 : * Configuration file we use. One (big) configuration is used
37 : * for the various components for this test.
38 : */
39 : static char *config_file;
40 :
41 : /**
42 : * Special configuration file to use when we want reserves
43 : * to expire 'immediately'.
44 : */
45 : static char *config_file_expire_reserve_now;
46 :
47 : /**
48 : * Our credentials.
49 : */
50 : static struct TALER_TESTING_Credentials cred;
51 :
52 : /**
53 : * Some tests behave differently when using CS as we cannot
54 : * reuse the coin private key for different denominations
55 : * due to the derivation of it with the /csr values. Hence
56 : * some tests behave differently in CS mode, hence this
57 : * flag.
58 : */
59 : static bool uses_cs;
60 :
61 : /**
62 : * Execute the taler-exchange-wirewatch command with
63 : * our configuration file.
64 : *
65 : * @param label label to use for the command.
66 : */
67 : #define CMD_EXEC_WIREWATCH(label) \
68 : TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
69 : "exchange-account-2")
70 :
71 : /**
72 : * Execute the taler-exchange-aggregator, closer and transfer commands with
73 : * our configuration file.
74 : *
75 : * @param label label to use for the command.
76 : */
77 : #define CMD_EXEC_AGGREGATOR(label) \
78 : TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
79 : TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
80 : TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
81 :
82 :
83 : /**
84 : * Run wire transfer of funds from some user's account to the
85 : * exchange.
86 : *
87 : * @param label label to use for the command.
88 : * @param amount amount to transfer, i.e. "EUR:1"
89 : */
90 : #define CMD_TRANSFER_TO_EXCHANGE(label,amount) \
91 : TALER_TESTING_cmd_admin_add_incoming (label, amount, \
92 : &cred.ba, \
93 : cred.user42_payto)
94 :
95 : /**
96 : * Main function that will tell the interpreter what commands to
97 : * run.
98 : *
99 : * @param cls closure
100 : * @param is interpreter we use to run commands
101 : */
102 : static void
103 2 : run (void *cls,
104 : struct TALER_TESTING_Interpreter *is)
105 : {
106 : /**
107 : * Test withdrawal plus spending.
108 : */
109 : struct TALER_TESTING_Command withdraw[] = {
110 : /**
111 : * Move money to the exchange's bank account.
112 : */
113 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1",
114 : "EUR:6.02"),
115 2 : TALER_TESTING_cmd_reserve_poll ("poll-reserve-1",
116 : "create-reserve-1",
117 : "EUR:6.02",
118 : GNUNET_TIME_UNIT_MINUTES,
119 : MHD_HTTP_OK),
120 2 : TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1",
121 : "EUR:6.02",
122 : cred.user42_payto,
123 : cred.exchange_payto,
124 : "create-reserve-1"),
125 : /**
126 : * Make a reserve exist, according to the previous
127 : * transfer.
128 : */
129 2 : CMD_EXEC_WIREWATCH ("wirewatch-1"),
130 2 : TALER_TESTING_cmd_reserve_poll_finish ("finish-poll-reserve-1",
131 : GNUNET_TIME_relative_multiply (
132 : GNUNET_TIME_UNIT_SECONDS,
133 : 2),
134 : "poll-reserve-1"),
135 : /**
136 : * Withdraw EUR:5.
137 : */
138 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
139 : "create-reserve-1",
140 : "EUR:5",
141 : 0, /* age restriction off */
142 : MHD_HTTP_OK),
143 : /**
144 : * Idempotent withdrawal. Note that in the case of CS, this is _not_
145 : * idempotent because the blinding nonces still differ, so instead,
146 : * it is an overcharging of the reserve.
147 : */
148 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1-idem",
149 : "create-reserve-1",
150 : "EUR:5",
151 : 0, /* age restriction off */
152 : "withdraw-coin-1",
153 : (uses_cs)
154 2 : ? MHD_HTTP_CONFLICT
155 : : MHD_HTTP_OK),
156 : /**
157 : * Withdraw EUR:1 using the SAME private coin key as for the previous coin
158 : * (in violation of the specification, to be detected on spending!).
159 : * However, note that this does NOT work with 'CS', as for a different
160 : * denomination we get different R0/R1 values from the exchange, and
161 : * thus will generate a different coin private key as R0/R1 are hashed
162 : * into the coin priv. So here, we fail to 'reuse' the key due to the
163 : * cryptographic construction!
164 : */
165 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
166 : "create-reserve-1",
167 : "EUR:1",
168 : 0, /* age restriction off */
169 : "withdraw-coin-1",
170 : MHD_HTTP_OK),
171 : /**
172 : * Check the reserve is depleted.
173 : */
174 2 : TALER_TESTING_cmd_status ("status-1",
175 : "create-reserve-1",
176 : "EUR:0",
177 : MHD_HTTP_OK),
178 : /*
179 : * Try to overdraw.
180 : */
181 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
182 : "create-reserve-1",
183 : "EUR:5",
184 : 0, /* age restriction off */
185 : MHD_HTTP_CONFLICT),
186 2 : TALER_TESTING_cmd_end ()
187 : };
188 :
189 : struct TALER_TESTING_Command spend[] = {
190 : /**
191 : * Spend the coin.
192 : */
193 2 : TALER_TESTING_cmd_set_var (
194 : "account-priv",
195 : TALER_TESTING_cmd_deposit (
196 : "deposit-simple-fail-kyc",
197 : "withdraw-coin-1",
198 : 0,
199 : cred.user42_payto,
200 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
201 2 : GNUNET_TIME_UNIT_ZERO,
202 : "EUR:5",
203 : MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
204 2 : TALER_TESTING_cmd_admin_add_kycauth (
205 : "kyc-auth-transfer",
206 : "EUR:0.01",
207 : &cred.ba,
208 : cred.user42_payto,
209 : "deposit-simple-fail-kyc"),
210 2 : CMD_EXEC_WIREWATCH (
211 : "import-kyc-account-withdraw"),
212 2 : TALER_TESTING_cmd_deposit_replay (
213 : "deposit-simple",
214 : "deposit-simple-fail-kyc",
215 : MHD_HTTP_OK),
216 2 : TALER_TESTING_cmd_deposit_replay (
217 : "deposit-simple-replay-1",
218 : "deposit-simple",
219 : MHD_HTTP_OK),
220 2 : TALER_TESTING_cmd_sleep (
221 : "sleep-before-deposit-replay",
222 : 1),
223 2 : TALER_TESTING_cmd_deposit_replay (
224 : "deposit-simple-replay-2",
225 : "deposit-simple",
226 : MHD_HTTP_OK),
227 : /* This creates a conflict, as we have the same coin public key (reuse!),
228 : but different denomination public keys (which is not allowed).
229 : However, note that this does NOT work with 'CS', as for a different
230 : denomination we get different R0/R1 values from the exchange, and
231 : thus will generate a different coin private key as R0/R1 are hashed
232 : into the coin priv. So here, we fail to 'reuse' the key due to the
233 : cryptographic construction! */
234 2 : TALER_TESTING_cmd_deposit (
235 : "deposit-reused-coin-key-failure",
236 : "withdraw-coin-1x",
237 : 0,
238 : cred.user42_payto,
239 : "{\"items\":[{\"name\":\"conflicting ice cream\",\"value\":1}]}",
240 2 : GNUNET_TIME_UNIT_ZERO,
241 : "EUR:1",
242 : uses_cs
243 2 : ? MHD_HTTP_OK
244 : : MHD_HTTP_CONFLICT),
245 : /**
246 : * Try to double spend using different wire details.
247 : */
248 2 : TALER_TESTING_cmd_admin_add_kycauth (
249 : "kyc-auth-transfer-2",
250 : "EUR:0.01",
251 : &cred.ba,
252 : cred.user43_payto,
253 : "deposit-simple-fail-kyc"),
254 2 : CMD_EXEC_WIREWATCH (
255 : "import-kyc-account-1"),
256 2 : TALER_TESTING_cmd_deposit (
257 : "deposit-double-1",
258 : "withdraw-coin-1",
259 : 0,
260 : cred.user43_payto,
261 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
262 2 : GNUNET_TIME_UNIT_ZERO,
263 : "EUR:5",
264 : MHD_HTTP_CONFLICT),
265 : /* Try to double spend using a different transaction id.
266 : * The test needs the contract terms to differ. This
267 : * is currently the case because of the "timestamp" field,
268 : * which is set automatically by #TALER_TESTING_cmd_deposit().
269 : * This could theoretically fail if at some point a deposit
270 : * command executes in less than 1 ms. */
271 2 : TALER_TESTING_cmd_deposit (
272 : "deposit-double-1",
273 : "withdraw-coin-1",
274 : 0,
275 : cred.user43_payto,
276 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
277 2 : GNUNET_TIME_UNIT_ZERO,
278 : "EUR:5",
279 : MHD_HTTP_CONFLICT),
280 : /**
281 : * Try to double spend with different proposal.
282 : */
283 2 : TALER_TESTING_cmd_deposit (
284 : "deposit-double-2",
285 : "withdraw-coin-1",
286 : 0,
287 : cred.user43_payto,
288 : "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
289 2 : GNUNET_TIME_UNIT_ZERO,
290 : "EUR:5",
291 : MHD_HTTP_CONFLICT),
292 2 : TALER_TESTING_cmd_end ()
293 : };
294 :
295 : struct TALER_TESTING_Command refresh[] = {
296 : /**
297 : * Try to melt the coin that shared the private key with another
298 : * coin (should fail). Note that in the CS-case, we fail also
299 : * with MHD_HTTP_CONFLICT, but for a different reason: here it
300 : * is not a denomination conflict, but a double-spending conflict.
301 : */
302 2 : TALER_TESTING_cmd_melt (
303 : "refresh-melt-reused-coin-key-failure",
304 : "withdraw-coin-1x",
305 : MHD_HTTP_CONFLICT,
306 : NULL),
307 :
308 : /* Fill reserve with EUR:5, 1ct is for fees. */
309 2 : CMD_TRANSFER_TO_EXCHANGE (
310 : "refresh-create-reserve-1",
311 : "EUR:5.01"),
312 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
313 : "ck-refresh-create-reserve-1",
314 : "EUR:5.01",
315 : cred.user42_payto,
316 : cred.exchange_payto,
317 : "refresh-create-reserve-1"),
318 : /**
319 : * Make previous command effective.
320 : */
321 2 : CMD_EXEC_WIREWATCH ("wirewatch-2"),
322 : /**
323 : * Withdraw EUR:5.
324 : */
325 2 : TALER_TESTING_cmd_withdraw_amount (
326 : "refresh-withdraw-coin-1",
327 : "refresh-create-reserve-1",
328 : "EUR:5",
329 : 0, /* age restriction off */
330 : MHD_HTTP_OK),
331 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
332 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
333 : * deposit fee)
334 : */
335 2 : TALER_TESTING_cmd_deposit (
336 : "refresh-deposit-partial",
337 : "refresh-withdraw-coin-1",
338 : 0,
339 : cred.user42_payto,
340 : "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}",
341 2 : GNUNET_TIME_UNIT_ZERO,
342 : "EUR:1",
343 : MHD_HTTP_OK),
344 : /**
345 : * Melt the rest of the coin's value
346 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
347 2 : TALER_TESTING_cmd_melt_double (
348 : "refresh-melt-1",
349 : "refresh-withdraw-coin-1",
350 : MHD_HTTP_OK,
351 : NULL),
352 : /**
353 : * Complete (successful) melt operation, and
354 : * withdraw the coins
355 : */
356 2 : TALER_TESTING_cmd_melt_reveal (
357 : "refresh-reveal-1",
358 : "refresh-melt-1",
359 : MHD_HTTP_OK),
360 : /**
361 : * Do it again to check idempotency
362 : */
363 2 : TALER_TESTING_cmd_melt_reveal (
364 : "refresh-reveal-1-idempotency",
365 : "refresh-melt-1",
366 : MHD_HTTP_OK),
367 : /**
368 : * Try to spend a refreshed EUR:1 coin
369 : */
370 2 : TALER_TESTING_cmd_deposit (
371 : "refresh-deposit-refreshed-1a",
372 : "refresh-reveal-1-idempotency",
373 : 0,
374 : cred.user42_payto,
375 : "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}",
376 2 : GNUNET_TIME_UNIT_ZERO,
377 : "EUR:1",
378 : MHD_HTTP_OK),
379 : /**
380 : * Try to spend a refreshed EUR:0.1 coin
381 : */
382 2 : TALER_TESTING_cmd_deposit (
383 : "refresh-deposit-refreshed-1b",
384 : "refresh-reveal-1",
385 : 3,
386 : cred.user43_payto,
387 : "{\"items\":[{\"name\":\"cheap ice cream\",\"value\":3}]}",
388 2 : GNUNET_TIME_UNIT_ZERO,
389 : "EUR:0.1",
390 : MHD_HTTP_OK),
391 : /* Test running a failing melt operation (same operation
392 : * again must fail) */
393 2 : TALER_TESTING_cmd_melt (
394 : "refresh-melt-failing",
395 : "refresh-withdraw-coin-1",
396 : MHD_HTTP_CONFLICT,
397 : NULL),
398 : /* Test running a failing melt operation (on a coin that
399 : was itself revealed and subsequently deposited) */
400 2 : TALER_TESTING_cmd_melt (
401 : "refresh-melt-failing-2",
402 : "refresh-reveal-1",
403 : MHD_HTTP_CONFLICT,
404 : NULL),
405 :
406 2 : TALER_TESTING_cmd_end ()
407 : };
408 :
409 : /**
410 : * Test withdrawal with age restriction. Success is expected, so it MUST be
411 : * called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called,
412 : * i. e. age restriction is activated in the exchange!
413 : *
414 : * FIXME[oec]: create a test that tries to withdraw coins with age restriction but
415 : * (expectedly) fails because the exchange doesn't support age restriction
416 : * yet.
417 : */
418 : struct TALER_TESTING_Command withdraw_age[] = {
419 : /**
420 : * Move money to the exchange's bank account.
421 : */
422 2 : CMD_TRANSFER_TO_EXCHANGE (
423 : "create-reserve-age",
424 : "EUR:6.01"),
425 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
426 : "check-create-reserve-age",
427 : "EUR:6.01",
428 : cred.user42_payto,
429 : cred.exchange_payto,
430 : "create-reserve-age"),
431 : /**
432 : * Make a reserve exist, according to the previous
433 : * transfer.
434 : */
435 2 : CMD_EXEC_WIREWATCH ("wirewatch-age"),
436 : /**
437 : * Withdraw EUR:5.
438 : */
439 2 : TALER_TESTING_cmd_withdraw_amount (
440 : "withdraw-coin-age-1",
441 : "create-reserve-age",
442 : "EUR:5",
443 : 13,
444 : MHD_HTTP_OK),
445 :
446 2 : TALER_TESTING_cmd_end ()
447 : };
448 :
449 : struct TALER_TESTING_Command spend_age[] = {
450 : /**
451 : * Spend the coin.
452 : */
453 2 : TALER_TESTING_cmd_deposit (
454 : "deposit-simple-age",
455 : "withdraw-coin-age-1",
456 : 0,
457 : cred.user42_payto,
458 : "{\"items\":[{\"name\":\"unique ice cream\",\"value\":1}]}",
459 2 : GNUNET_TIME_UNIT_ZERO,
460 : "EUR:4.99",
461 : MHD_HTTP_OK),
462 2 : TALER_TESTING_cmd_deposit_replay (
463 : "deposit-simple-replay-age",
464 : "deposit-simple-age",
465 : MHD_HTTP_OK),
466 2 : TALER_TESTING_cmd_deposit_replay (
467 : "deposit-simple-replay-age-1",
468 : "deposit-simple-age",
469 : MHD_HTTP_OK),
470 2 : TALER_TESTING_cmd_sleep (
471 : "sleep-before-age-deposit-replay",
472 : 1),
473 2 : TALER_TESTING_cmd_deposit_replay (
474 : "deposit-simple-replay-age-2",
475 : "deposit-simple-age",
476 : MHD_HTTP_OK),
477 2 : TALER_TESTING_cmd_end ()
478 : };
479 :
480 : struct TALER_TESTING_Command track[] = {
481 : /* Try resolving a deposit's WTID, as we never triggered
482 : * execution of transactions, the answer should be that
483 : * the exchange knows about the deposit, but has no WTID yet.
484 : */
485 2 : TALER_TESTING_cmd_deposits_get (
486 : "deposit-wtid-found",
487 : "deposit-simple",
488 : 0,
489 : MHD_HTTP_ACCEPTED,
490 : NULL),
491 : /* Try resolving a deposit's WTID for a failed deposit.
492 : * As the deposit failed, the answer should be that the
493 : * exchange does NOT know about the deposit.
494 : */
495 2 : TALER_TESTING_cmd_deposits_get (
496 : "deposit-wtid-failing",
497 : "deposit-double-2",
498 : 0,
499 : MHD_HTTP_NOT_FOUND,
500 : NULL),
501 : /* Try resolving an undefined (all zeros) WTID; this
502 : * should fail as obviously the exchange didn't use that
503 : * WTID value for any transaction.
504 : */
505 2 : TALER_TESTING_cmd_track_transfer_empty (
506 : "wire-deposit-failing",
507 : NULL,
508 : MHD_HTTP_NOT_FOUND),
509 : /* Run transfers. */
510 2 : CMD_EXEC_AGGREGATOR ("run-aggregator"),
511 : /**
512 : * Check all the transfers took place.
513 : */
514 2 : TALER_TESTING_cmd_check_bank_transfer (
515 : "check_bank_transfer-42-aggregate",
516 2 : cred.exchange_url,
517 : /* In case of CS, one transaction above succeeded that
518 : failed for RSA, hence we get a larger amount here */
519 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
520 : cred.exchange_payto,
521 : cred.user42_payto),
522 2 : TALER_TESTING_cmd_check_bank_transfer (
523 : "check_bank_transfer-43-aggregate",
524 2 : cred.exchange_url,
525 : "EUR:0.17",
526 : cred.exchange_payto,
527 : cred.user43_payto),
528 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_empty"),
529 2 : TALER_TESTING_cmd_deposits_get (
530 : "deposit-wtid-ok",
531 : "deposit-simple",
532 : 0,
533 : MHD_HTTP_OK,
534 : "check_bank_transfer-42-aggregate"),
535 2 : TALER_TESTING_cmd_track_transfer (
536 : "wire-deposit-success-bank",
537 : "check_bank_transfer-42-aggregate",
538 : MHD_HTTP_OK,
539 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
540 : "EUR:0.01"),
541 2 : TALER_TESTING_cmd_track_transfer (
542 : "wire-deposits-success-wtid",
543 : "check_bank_transfer-43-aggregate",
544 : MHD_HTTP_OK,
545 : "EUR:0.17",
546 : "EUR:0.01"),
547 2 : TALER_TESTING_cmd_end ()
548 : };
549 :
550 : /**
551 : * This block checks whether a wire deadline
552 : * very far in the future does NOT get aggregated now.
553 : */
554 : struct TALER_TESTING_Command unaggregation[] = {
555 2 : TALER_TESTING_cmd_check_bank_empty ("far-future-aggregation-a"),
556 2 : CMD_TRANSFER_TO_EXCHANGE (
557 : "create-reserve-unaggregated",
558 : "EUR:5.01"),
559 : /* "consume" reserve creation transfer. */
560 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
561 : "check-create-reserve-unaggregated",
562 : "EUR:5.01",
563 : cred.user42_payto,
564 : cred.exchange_payto,
565 : "create-reserve-unaggregated"),
566 2 : CMD_EXEC_WIREWATCH ("wirewatch-unaggregated"),
567 2 : TALER_TESTING_cmd_withdraw_amount (
568 : "withdraw-coin-unaggregated",
569 : "create-reserve-unaggregated",
570 : "EUR:5",
571 : 0, /* age restriction off */
572 : MHD_HTTP_OK),
573 2 : TALER_TESTING_cmd_deposit (
574 : "deposit-unaggregated",
575 : "withdraw-coin-unaggregated",
576 : 0,
577 : cred.user43_payto,
578 : "{\"items\":[{\"name\":\"different ice cream\",\"value\":1}]}",
579 : GNUNET_TIME_relative_multiply (
580 : GNUNET_TIME_UNIT_YEARS,
581 : 3000),
582 : "EUR:5",
583 : MHD_HTTP_OK),
584 2 : CMD_EXEC_AGGREGATOR ("aggregation-attempt"),
585 :
586 2 : TALER_TESTING_cmd_check_bank_empty (
587 : "far-future-aggregation-b"),
588 :
589 2 : TALER_TESTING_cmd_end ()
590 : };
591 :
592 : struct TALER_TESTING_Command refresh_age[] = {
593 : /* Fill reserve with EUR:5, 1ct is for fees. */
594 2 : CMD_TRANSFER_TO_EXCHANGE (
595 : "refresh-create-reserve-age-1",
596 : "EUR:6.01"),
597 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
598 : "ck-refresh-create-reserve-age-1",
599 : "EUR:6.01",
600 : cred.user42_payto,
601 : cred.exchange_payto,
602 : "refresh-create-reserve-age-1"),
603 : /**
604 : * Make previous command effective.
605 : */
606 2 : CMD_EXEC_WIREWATCH ("wirewatch-age-2"),
607 : /**
608 : * Withdraw EUR:7 with age restriction for age 13.
609 : */
610 2 : TALER_TESTING_cmd_withdraw_amount (
611 : "refresh-withdraw-coin-age-1",
612 : "refresh-create-reserve-age-1",
613 : "EUR:5",
614 : 13,
615 : MHD_HTTP_OK),
616 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
617 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
618 : * deposit fee)
619 : */
620 2 : TALER_TESTING_cmd_deposit (
621 : "refresh-deposit-partial-age",
622 : "refresh-withdraw-coin-age-1",
623 : 0,
624 : cred.user42_payto,
625 : "{\"items\":[{\"name\":\"special ice cream\",\"value\":\"EUR:1\"}]}",
626 2 : GNUNET_TIME_UNIT_ZERO,
627 : "EUR:1",
628 : MHD_HTTP_OK),
629 : /**
630 : * Melt the rest of the coin's value
631 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
632 2 : TALER_TESTING_cmd_melt_double (
633 : "refresh-melt-age-1",
634 : "refresh-withdraw-coin-age-1",
635 : MHD_HTTP_OK,
636 : NULL),
637 : /**
638 : * Complete (successful) melt operation, and
639 : * withdraw the coins
640 : */
641 2 : TALER_TESTING_cmd_melt_reveal (
642 : "refresh-reveal-age-1",
643 : "refresh-melt-age-1",
644 : MHD_HTTP_OK),
645 : /**
646 : * Do it again to check idempotency
647 : */
648 2 : TALER_TESTING_cmd_melt_reveal (
649 : "refresh-reveal-age-1-idempotency",
650 : "refresh-melt-age-1",
651 : MHD_HTTP_OK),
652 : /**
653 : * Try to spend a refreshed EUR:1 coin
654 : */
655 2 : TALER_TESTING_cmd_deposit (
656 : "refresh-deposit-refreshed-age-1a",
657 : "refresh-reveal-age-1-idempotency",
658 : 0,
659 : cred.user42_payto,
660 : "{\"items\":[{\"name\":\"garlic ice cream\",\"value\":3}]}",
661 2 : GNUNET_TIME_UNIT_ZERO,
662 : "EUR:1",
663 : MHD_HTTP_OK),
664 : /**
665 : * Try to spend a refreshed EUR:0.1 coin
666 : */
667 2 : TALER_TESTING_cmd_deposit (
668 : "refresh-deposit-refreshed-age-1b",
669 : "refresh-reveal-age-1",
670 : 3,
671 : cred.user43_payto,
672 : "{\"items\":[{\"name\":\"spicy ice cream\",\"value\":3}]}",
673 2 : GNUNET_TIME_UNIT_ZERO,
674 : "EUR:0.1",
675 : MHD_HTTP_OK),
676 : /* Test running a failing melt operation (same operation
677 : * again must fail) */
678 2 : TALER_TESTING_cmd_melt (
679 : "refresh-melt-failing-age",
680 : "refresh-withdraw-coin-age-1",
681 : MHD_HTTP_CONFLICT,
682 : NULL),
683 : /* Test running a failing melt operation (on a coin that
684 : was itself revealed and subsequently deposited) */
685 2 : TALER_TESTING_cmd_melt (
686 : "refresh-melt-failing-age-2",
687 : "refresh-reveal-age-1",
688 : MHD_HTTP_CONFLICT,
689 : NULL),
690 2 : TALER_TESTING_cmd_end ()
691 : };
692 :
693 : /**
694 : * This block exercises the aggretation logic by making two payments
695 : * to the same merchant.
696 : */
697 : struct TALER_TESTING_Command aggregation[] = {
698 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-aggtest",
699 : "EUR:5.01"),
700 : /* "consume" reserve creation transfer. */
701 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
702 : "check-create-reserve-aggtest",
703 : "EUR:5.01",
704 : cred.user42_payto,
705 : cred.exchange_payto,
706 : "create-reserve-aggtest"),
707 2 : CMD_EXEC_WIREWATCH ("wirewatch-aggtest"),
708 2 : TALER_TESTING_cmd_withdraw_amount (
709 : "withdraw-coin-aggtest",
710 : "create-reserve-aggtest",
711 : "EUR:5",
712 : 0, /* age restriction off */
713 : MHD_HTTP_OK),
714 2 : TALER_TESTING_cmd_deposit (
715 : "deposit-aggtest-1",
716 : "withdraw-coin-aggtest",
717 : 0,
718 : cred.user43_payto,
719 : "{\"items\":[{\"name\":\"cinamon ice cream\",\"value\":1}]}",
720 2 : GNUNET_TIME_UNIT_ZERO,
721 : "EUR:2",
722 : MHD_HTTP_OK),
723 2 : TALER_TESTING_cmd_deposit_with_ref (
724 : "deposit-aggtest-2",
725 : "withdraw-coin-aggtest",
726 : 0,
727 : cred.user43_payto,
728 : "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}",
729 2 : GNUNET_TIME_UNIT_ZERO,
730 : "EUR:2",
731 : MHD_HTTP_OK,
732 : "deposit-aggtest-1"),
733 2 : CMD_EXEC_AGGREGATOR ("aggregation-aggtest"),
734 2 : TALER_TESTING_cmd_check_bank_transfer (
735 : "check-bank-transfer-aggtest",
736 2 : cred.exchange_url,
737 : "EUR:3.97",
738 : cred.exchange_payto,
739 : cred.user43_payto),
740 2 : TALER_TESTING_cmd_check_bank_empty ("check-bank-empty-aggtest"),
741 2 : TALER_TESTING_cmd_end ()
742 : };
743 :
744 : struct TALER_TESTING_Command refund[] = {
745 : /**
746 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
747 : * config.
748 : */
749 2 : CMD_TRANSFER_TO_EXCHANGE (
750 : "create-reserve-r1",
751 : "EUR:5.01"),
752 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
753 : "check-create-reserve-r1",
754 : "EUR:5.01",
755 : cred.user42_payto,
756 : cred.exchange_payto,
757 : "create-reserve-r1"),
758 : /**
759 : * Run wire-watch to trigger the reserve creation.
760 : */
761 2 : CMD_EXEC_WIREWATCH ("wirewatch-3"),
762 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
763 2 : TALER_TESTING_cmd_withdraw_amount (
764 : "withdraw-coin-r1",
765 : "create-reserve-r1",
766 : "EUR:5",
767 : 0, /* age restriction off */
768 : MHD_HTTP_OK),
769 : /**
770 : * Spend 5 EUR of the 5 EUR coin (in full) (merchant would
771 : * receive EUR:4.99 due to 1 ct deposit fee)
772 : */
773 2 : TALER_TESTING_cmd_deposit (
774 : "deposit-refund-1",
775 : "withdraw-coin-r1",
776 : 0,
777 : cred.user42_payto,
778 : "{\"items\":[{\"name\":\"blue ice cream\",\"value\":\"EUR:5\"}]}",
779 : GNUNET_TIME_UNIT_MINUTES,
780 : "EUR:5",
781 : MHD_HTTP_OK),
782 : /**
783 : * Run transfers. Should do nothing as refund deadline blocks it
784 : */
785 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-refund"),
786 : /* Check that aggregator didn't do anything, as expected.
787 : * Note, this operation takes two commands: one to "flush"
788 : * the preliminary transfer (used to withdraw) from the
789 : * fakebank and the second to actually check there are not
790 : * other transfers around. */
791 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_transfer-pre-refund"),
792 2 : TALER_TESTING_cmd_refund_with_id (
793 : "refund-ok",
794 : MHD_HTTP_OK,
795 : "EUR:3",
796 : "deposit-refund-1",
797 : 3),
798 2 : TALER_TESTING_cmd_refund_with_id (
799 : "refund-ok-double",
800 : MHD_HTTP_OK,
801 : "EUR:3",
802 : "deposit-refund-1",
803 : 3),
804 : /* Previous /refund(s) had id == 0. */
805 2 : TALER_TESTING_cmd_refund_with_id (
806 : "refund-conflicting",
807 : MHD_HTTP_CONFLICT,
808 : "EUR:5",
809 : "deposit-refund-1",
810 : 1),
811 2 : TALER_TESTING_cmd_deposit (
812 : "deposit-refund-insufficient-refund",
813 : "withdraw-coin-r1",
814 : 0,
815 : cred.user42_payto,
816 : "{\"items\":[{\"name\":\"fruit ice cream\",\"value\":\"EUR:4\"}]}",
817 : GNUNET_TIME_UNIT_MINUTES,
818 : "EUR:4",
819 : MHD_HTTP_CONFLICT),
820 2 : TALER_TESTING_cmd_refund_with_id (
821 : "refund-ok-increase",
822 : MHD_HTTP_OK,
823 : "EUR:2",
824 : "deposit-refund-1",
825 : 2),
826 : /**
827 : * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone
828 : * due to refund) (merchant would receive EUR:4.98 due to
829 : * 1 ct deposit fee) */
830 2 : TALER_TESTING_cmd_deposit (
831 : "deposit-refund-2",
832 : "withdraw-coin-r1",
833 : 0,
834 : cred.user42_payto,
835 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}",
836 2 : GNUNET_TIME_UNIT_ZERO,
837 : "EUR:4.99",
838 : MHD_HTTP_OK),
839 : /**
840 : * Run transfers. This will do the transfer as refund deadline
841 : * was 0
842 : */
843 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3"),
844 : /**
845 : * Check that deposit did run.
846 : */
847 2 : TALER_TESTING_cmd_check_bank_transfer (
848 : "check_bank_transfer-pre-refund",
849 2 : cred.exchange_url,
850 : "EUR:4.97",
851 : cred.exchange_payto,
852 : cred.user42_payto),
853 : /**
854 : * Run failing refund, as past deadline & aggregation.
855 : */
856 2 : TALER_TESTING_cmd_refund (
857 : "refund-fail",
858 : MHD_HTTP_GONE,
859 : "EUR:4.99",
860 : "deposit-refund-2"),
861 2 : TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"),
862 : /**
863 : * Test refunded coins are never executed, even past
864 : * refund deadline
865 : */
866 2 : CMD_TRANSFER_TO_EXCHANGE (
867 : "create-reserve-rb",
868 : "EUR:5.01"),
869 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
870 : "check-create-reserve-rb",
871 : "EUR:5.01",
872 : cred.user42_payto,
873 : cred.exchange_payto,
874 : "create-reserve-rb"),
875 2 : CMD_EXEC_WIREWATCH ("wirewatch-rb"),
876 2 : TALER_TESTING_cmd_withdraw_amount (
877 : "withdraw-coin-rb",
878 : "create-reserve-rb",
879 : "EUR:5",
880 : 0, /* age restriction off */
881 : MHD_HTTP_OK),
882 2 : TALER_TESTING_cmd_deposit (
883 : "deposit-refund-1b",
884 : "withdraw-coin-rb",
885 : 0,
886 : cred.user42_payto,
887 : "{\"items\":[{\"name\":\"purple ice cream\",\"value\":\"EUR:5\"}]}",
888 2 : GNUNET_TIME_UNIT_ZERO,
889 : "EUR:5",
890 : MHD_HTTP_OK),
891 : /**
892 : * Trigger refund (before aggregator had a chance to execute
893 : * deposit, even though refund deadline was zero).
894 : */
895 2 : TALER_TESTING_cmd_refund (
896 : "refund-ok-fast",
897 : MHD_HTTP_OK,
898 : "EUR:5",
899 : "deposit-refund-1b"),
900 : /**
901 : * Run transfers. This will do the transfer as refund deadline
902 : * was 0, except of course because the refund succeeded, the
903 : * transfer should no longer be done.
904 : */
905 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3b"),
906 : /* check that aggregator didn't do anything, as expected */
907 2 : TALER_TESTING_cmd_check_bank_empty ("check-refund-fast-not-run"),
908 2 : TALER_TESTING_cmd_end ()
909 : };
910 :
911 : #if FIXME_9828
912 : struct TALER_TESTING_Command recoup[] = {
913 : /**
914 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
915 : * config.
916 : */
917 : CMD_TRANSFER_TO_EXCHANGE (
918 : "recoup-create-reserve-1",
919 : "EUR:15.02"),
920 : TALER_TESTING_cmd_check_bank_admin_transfer (
921 : "recoup-create-reserve-1-check",
922 : "EUR:15.02",
923 : cred.user42_payto,
924 : cred.exchange_payto,
925 : "recoup-create-reserve-1"),
926 : /**
927 : * Run wire-watch to trigger the reserve creation.
928 : */
929 : CMD_EXEC_WIREWATCH ("wirewatch-4"),
930 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
931 : TALER_TESTING_cmd_withdraw_amount (
932 : "recoup-withdraw-coin-1",
933 : "recoup-create-reserve-1",
934 : "EUR:5",
935 : 0, /* age restriction off */
936 : MHD_HTTP_OK),
937 : /* Withdraw a 10 EUR coin, at fee of 1 ct */
938 : TALER_TESTING_cmd_withdraw_amount (
939 : "recoup-withdraw-coin-1b",
940 : "recoup-create-reserve-1",
941 : "EUR:10",
942 : 0, /* age restriction off */
943 : MHD_HTTP_OK),
944 : /* melt 10 EUR coin to get 5 EUR refreshed coin */
945 : TALER_TESTING_cmd_melt (
946 : "recoup-melt-coin-1b",
947 : "recoup-withdraw-coin-1b",
948 : MHD_HTTP_OK,
949 : "EUR:5",
950 : NULL),
951 : TALER_TESTING_cmd_melt_reveal (
952 : "recoup-reveal-coin-1b",
953 : "recoup-melt-coin-1b",
954 : MHD_HTTP_OK),
955 : /* Revoke both 5 EUR coins */
956 : TALER_TESTING_cmd_revoke (
957 : "revoke-0-EUR:5",
958 : MHD_HTTP_OK,
959 : "recoup-withdraw-coin-1",
960 : config_file),
961 : /* Recoup coin to reserve */
962 : TALER_TESTING_cmd_recoup (
963 : "recoup-1",
964 : MHD_HTTP_OK,
965 : "recoup-withdraw-coin-1",
966 : "EUR:5"),
967 : /* Check the money is back with the reserve */
968 : TALER_TESTING_cmd_status (
969 : "recoup-reserve-status-1",
970 : "recoup-create-reserve-1",
971 : "EUR:5.0",
972 : MHD_HTTP_OK),
973 : /* Recoup-refresh coin to 10 EUR coin */
974 : TALER_TESTING_cmd_recoup_refresh (
975 : "recoup-1b",
976 : MHD_HTTP_OK,
977 : "recoup-reveal-coin-1b",
978 : "recoup-melt-coin-1b",
979 : "EUR:5"),
980 : /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */
981 : TALER_TESTING_cmd_melt (
982 : "recoup-remelt-coin-1a",
983 : "recoup-withdraw-coin-1b",
984 : MHD_HTTP_OK,
985 : "EUR:1",
986 : NULL),
987 : TALER_TESTING_cmd_melt_reveal (
988 : "recoup-reveal-coin-1a",
989 : "recoup-remelt-coin-1a",
990 : MHD_HTTP_OK),
991 : /* Try melting for more than the residual value to provoke an error */
992 : TALER_TESTING_cmd_melt (
993 : "recoup-remelt-coin-1b",
994 : "recoup-withdraw-coin-1b",
995 : MHD_HTTP_OK,
996 : "EUR:1",
997 : NULL),
998 : TALER_TESTING_cmd_melt (
999 : "recoup-remelt-coin-1c",
1000 : "recoup-withdraw-coin-1b",
1001 : MHD_HTTP_OK,
1002 : "EUR:1",
1003 : NULL),
1004 : TALER_TESTING_cmd_melt (
1005 : "recoup-remelt-coin-1d",
1006 : "recoup-withdraw-coin-1b",
1007 : MHD_HTTP_OK,
1008 : "EUR:1",
1009 : NULL),
1010 : TALER_TESTING_cmd_melt (
1011 : "recoup-remelt-coin-1e",
1012 : "recoup-withdraw-coin-1b",
1013 : MHD_HTTP_OK,
1014 : "EUR:1",
1015 : NULL),
1016 : TALER_TESTING_cmd_melt (
1017 : "recoup-remelt-coin-1f",
1018 : "recoup-withdraw-coin-1b",
1019 : MHD_HTTP_OK,
1020 : "EUR:1",
1021 : NULL),
1022 : TALER_TESTING_cmd_melt (
1023 : "recoup-remelt-coin-1g",
1024 : "recoup-withdraw-coin-1b",
1025 : MHD_HTTP_OK,
1026 : "EUR:1",
1027 : NULL),
1028 : TALER_TESTING_cmd_melt (
1029 : "recoup-remelt-coin-1h",
1030 : "recoup-withdraw-coin-1b",
1031 : MHD_HTTP_OK,
1032 : "EUR:1",
1033 : NULL),
1034 : TALER_TESTING_cmd_melt (
1035 : "recoup-remelt-coin-1i",
1036 : "recoup-withdraw-coin-1b",
1037 : MHD_HTTP_OK,
1038 : "EUR:1",
1039 : NULL),
1040 : TALER_TESTING_cmd_melt (
1041 : "recoup-remelt-coin-1b-failing",
1042 : "recoup-withdraw-coin-1b",
1043 : MHD_HTTP_CONFLICT,
1044 : "EUR:1",
1045 : NULL),
1046 : /* Re-withdraw from this reserve */
1047 : TALER_TESTING_cmd_withdraw_amount (
1048 : "recoup-withdraw-coin-2",
1049 : "recoup-create-reserve-1",
1050 : "EUR:1",
1051 : 0, /* age restriction off */
1052 : MHD_HTTP_OK),
1053 : /**
1054 : * This withdrawal will test the logic to create a "recoup"
1055 : * element to insert into the reserve's history.
1056 : */
1057 : TALER_TESTING_cmd_withdraw_amount (
1058 : "recoup-withdraw-coin-2-over",
1059 : "recoup-create-reserve-1",
1060 : "EUR:10",
1061 : 0, /* age restriction off */
1062 : MHD_HTTP_CONFLICT),
1063 : TALER_TESTING_cmd_status (
1064 : "recoup-reserve-status-2",
1065 : "recoup-create-reserve-1",
1066 : "EUR:3.99",
1067 : MHD_HTTP_OK),
1068 : /* These commands should close the reserve because
1069 : * the aggregator is given a config file that overrides
1070 : * the reserve expiration time (making it now-ish) */
1071 : CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve",
1072 : "EUR:5.01"),
1073 : TALER_TESTING_cmd_check_bank_admin_transfer (
1074 : "check-short-lived-reserve",
1075 : "EUR:5.01",
1076 : cred.user42_payto,
1077 : cred.exchange_payto,
1078 : "short-lived-reserve"),
1079 : TALER_TESTING_cmd_exec_wirewatch2 (
1080 : "short-lived-aggregation",
1081 : config_file_expire_reserve_now,
1082 : "exchange-account-2"),
1083 : TALER_TESTING_cmd_exec_closer (
1084 : "close-reserves",
1085 : config_file_expire_reserve_now,
1086 : "EUR:5",
1087 : "EUR:0.01",
1088 : "short-lived-reserve"),
1089 : TALER_TESTING_cmd_exec_transfer (
1090 : "close-reserves-transfer",
1091 : config_file_expire_reserve_now),
1092 :
1093 : TALER_TESTING_cmd_status (
1094 : "short-lived-status",
1095 : "short-lived-reserve",
1096 : "EUR:0",
1097 : MHD_HTTP_OK),
1098 : TALER_TESTING_cmd_withdraw_amount (
1099 : "expired-withdraw",
1100 : "short-lived-reserve",
1101 : "EUR:1",
1102 : 0, /* age restriction off */
1103 : MHD_HTTP_CONFLICT),
1104 : TALER_TESTING_cmd_check_bank_transfer (
1105 : "check_bank_short-lived_reimburse",
1106 : cred.exchange_url,
1107 : "EUR:5",
1108 : cred.exchange_payto,
1109 : cred.user42_payto),
1110 : /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per
1111 : * config, then withdraw two coin, partially spend one, and
1112 : * then have the rest paid back. Check deposit of other coin
1113 : * fails. Do not use EUR:5 here as the EUR:5 coin was
1114 : * revoked and we did not bother to create a new one... */
1115 : CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2",
1116 : "EUR:2.02"),
1117 : TALER_TESTING_cmd_check_bank_admin_transfer (
1118 : "ck-recoup-create-reserve-2",
1119 : "EUR:2.02",
1120 : cred.user42_payto,
1121 : cred.exchange_payto,
1122 : "recoup-create-reserve-2"),
1123 : /* Make previous command effective. */
1124 : CMD_EXEC_WIREWATCH ("wirewatch-5"),
1125 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1126 : TALER_TESTING_cmd_withdraw_amount (
1127 : "recoup-withdraw-coin-2a",
1128 : "recoup-create-reserve-2",
1129 : "EUR:1",
1130 : 0, /* age restriction off */
1131 : MHD_HTTP_OK),
1132 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1133 : TALER_TESTING_cmd_withdraw_amount (
1134 : "recoup-withdraw-coin-2b",
1135 : "recoup-create-reserve-2",
1136 : "EUR:1",
1137 : 0, /* age restriction off */
1138 : MHD_HTTP_OK),
1139 : TALER_TESTING_cmd_deposit (
1140 : "recoup-deposit-partial",
1141 : "recoup-withdraw-coin-2a",
1142 : 0,
1143 : cred.user42_payto,
1144 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}",
1145 : GNUNET_TIME_UNIT_ZERO,
1146 : "EUR:0.5",
1147 : MHD_HTTP_OK),
1148 : TALER_TESTING_cmd_revoke (
1149 : "revoke-1-EUR:1",
1150 : MHD_HTTP_OK,
1151 : "recoup-withdraw-coin-2a",
1152 : config_file),
1153 : /* Check recoup is failing for the coin with the reused coin key
1154 : (fails either because of denomination conflict (RSA) or
1155 : double-spending (CS))*/
1156 : TALER_TESTING_cmd_recoup (
1157 : "recoup-2x",
1158 : MHD_HTTP_CONFLICT,
1159 : "withdraw-coin-1x",
1160 : "EUR:1"),
1161 : TALER_TESTING_cmd_recoup (
1162 : "recoup-2",
1163 : MHD_HTTP_OK,
1164 : "recoup-withdraw-coin-2a",
1165 : "EUR:0.5"),
1166 : /* Idempotency of recoup (withdrawal variant) */
1167 : TALER_TESTING_cmd_recoup (
1168 : "recoup-2b",
1169 : MHD_HTTP_OK,
1170 : "recoup-withdraw-coin-2a",
1171 : "EUR:0.5"),
1172 : TALER_TESTING_cmd_deposit (
1173 : "recoup-deposit-revoked",
1174 : "recoup-withdraw-coin-2b",
1175 : 0,
1176 : cred.user42_payto,
1177 : "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}",
1178 : GNUNET_TIME_UNIT_ZERO,
1179 : "EUR:1",
1180 : MHD_HTTP_GONE),
1181 : /* Test deposit fails after recoup, with proof in recoup */
1182 :
1183 : /* Note that, the exchange will never return the coin's transaction
1184 : * history with recoup data, as we get a 410 on the DK! */
1185 : TALER_TESTING_cmd_deposit (
1186 : "recoup-deposit-partial-after-recoup",
1187 : "recoup-withdraw-coin-2a",
1188 : 0,
1189 : cred.user42_payto,
1190 : "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}",
1191 : GNUNET_TIME_UNIT_ZERO,
1192 : "EUR:0.5",
1193 : MHD_HTTP_GONE),
1194 : /* Test that revoked coins cannot be withdrawn */
1195 : CMD_TRANSFER_TO_EXCHANGE (
1196 : "recoup-create-reserve-3",
1197 : "EUR:1.01"),
1198 : TALER_TESTING_cmd_check_bank_admin_transfer (
1199 : "check-recoup-create-reserve-3",
1200 : "EUR:1.01",
1201 : cred.user42_payto,
1202 : cred.exchange_payto,
1203 : "recoup-create-reserve-3"),
1204 : CMD_EXEC_WIREWATCH ("wirewatch-6"),
1205 : TALER_TESTING_cmd_withdraw_amount (
1206 : "recoup-withdraw-coin-3-revoked",
1207 : "recoup-create-reserve-3",
1208 : "EUR:1",
1209 : 0, /* age restriction off */
1210 : MHD_HTTP_GONE),
1211 : /* check that we are empty before the rejection test */
1212 : TALER_TESTING_cmd_check_bank_empty ("check-empty-again"),
1213 :
1214 : TALER_TESTING_cmd_end ()
1215 : };
1216 : #endif
1217 :
1218 : /**
1219 : * Test batch withdrawal plus spending.
1220 : */
1221 : struct TALER_TESTING_Command batch_withdraw[] = {
1222 : /**
1223 : * Move money to the exchange's bank account.
1224 : */
1225 2 : CMD_TRANSFER_TO_EXCHANGE (
1226 : "create-batch-reserve-1",
1227 : "EUR:6.03"),
1228 2 : TALER_TESTING_cmd_reserve_poll (
1229 : "poll-batch-reserve-1",
1230 : "create-batch-reserve-1",
1231 : "EUR:6.03",
1232 : GNUNET_TIME_UNIT_MINUTES,
1233 : MHD_HTTP_OK),
1234 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
1235 : "check-create-batch-reserve-1",
1236 : "EUR:6.03",
1237 : cred.user42_payto,
1238 : cred.exchange_payto,
1239 : "create-batch-reserve-1"),
1240 : /*
1241 : * Make a reserve exist, according to the previous
1242 : * transfer.
1243 : */
1244 2 : CMD_EXEC_WIREWATCH ("wirewatch-batch-1"),
1245 2 : TALER_TESTING_cmd_reserve_poll_finish (
1246 : "finish-poll-batch-reserve-1",
1247 : GNUNET_TIME_UNIT_SECONDS,
1248 : "poll-batch-reserve-1"),
1249 : /**
1250 : * Withdraw EUR:5 AND EUR:1.
1251 : */
1252 2 : TALER_TESTING_cmd_batch_withdraw (
1253 : "batch-withdraw-coin-1",
1254 : "create-batch-reserve-1",
1255 : MHD_HTTP_OK,
1256 : "EUR:5",
1257 : "EUR:1",
1258 : NULL),
1259 : /**
1260 : * Check the reserve is (almost) depleted.
1261 : */
1262 2 : TALER_TESTING_cmd_status (
1263 : "status-batch-1",
1264 : "create-batch-reserve-1",
1265 : "EUR:0.01",
1266 : MHD_HTTP_OK),
1267 2 : TALER_TESTING_cmd_reserve_history (
1268 : "history-batch-1",
1269 : "create-batch-reserve-1",
1270 : "EUR:0.01",
1271 : MHD_HTTP_OK),
1272 : /**
1273 : * Spend the coins.
1274 : */
1275 2 : TALER_TESTING_cmd_batch_deposit (
1276 : "batch-deposit-1",
1277 : cred.user42_payto,
1278 : "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}",
1279 2 : GNUNET_TIME_UNIT_ZERO,
1280 : MHD_HTTP_OK,
1281 : "batch-withdraw-coin-1#0",
1282 : "EUR:5",
1283 : "batch-withdraw-coin-1#1",
1284 : "EUR:1",
1285 : NULL),
1286 2 : TALER_TESTING_cmd_coin_history (
1287 : "coin-history-batch-1",
1288 : "batch-withdraw-coin-1#0",
1289 : "EUR:0.0",
1290 : MHD_HTTP_OK),
1291 2 : TALER_TESTING_cmd_end ()
1292 : };
1293 :
1294 :
1295 : #define RESERVE_OPEN_CLOSE_CHUNK 4
1296 : #define RESERVE_OPEN_CLOSE_ITERATIONS 3
1297 :
1298 : struct TALER_TESTING_Command reserve_open_close[(RESERVE_OPEN_CLOSE_ITERATIONS
1299 : * RESERVE_OPEN_CLOSE_CHUNK)
1300 : + 1];
1301 :
1302 : (void) cls;
1303 2 : for (unsigned int i = 0;
1304 8 : i < RESERVE_OPEN_CLOSE_ITERATIONS;
1305 6 : i++)
1306 : {
1307 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 0]
1308 6 : = CMD_TRANSFER_TO_EXCHANGE ("reserve-open-close-key",
1309 : "EUR:20");
1310 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 1]
1311 6 : = TALER_TESTING_cmd_exec_wirewatch2 ("reserve-open-close-wirewatch",
1312 : config_file_expire_reserve_now,
1313 : "exchange-account-2");
1314 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 2]
1315 6 : = TALER_TESTING_cmd_exec_closer ("reserve-open-close-aggregation",
1316 : config_file_expire_reserve_now,
1317 : "EUR:19.99",
1318 : "EUR:0.01",
1319 : "reserve-open-close-key");
1320 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 3]
1321 6 : = TALER_TESTING_cmd_status ("reserve-open-close-status",
1322 : "reserve-open-close-key",
1323 : "EUR:0",
1324 : MHD_HTTP_OK);
1325 : }
1326 : reserve_open_close[RESERVE_OPEN_CLOSE_ITERATIONS * RESERVE_OPEN_CLOSE_CHUNK]
1327 2 : = TALER_TESTING_cmd_end ();
1328 :
1329 : {
1330 : struct TALER_TESTING_Command commands[] = {
1331 2 : TALER_TESTING_cmd_run_fakebank ("run-fakebank",
1332 2 : cred.cfg,
1333 : "exchange-account-2"),
1334 2 : TALER_TESTING_cmd_system_start ("start-taler",
1335 : config_file,
1336 : "-e",
1337 : NULL),
1338 2 : TALER_TESTING_cmd_get_exchange ("get-exchange",
1339 2 : cred.cfg,
1340 : NULL,
1341 : true,
1342 : true),
1343 2 : TALER_TESTING_cmd_batch ("withdraw",
1344 : withdraw),
1345 2 : TALER_TESTING_cmd_batch ("spend",
1346 : spend),
1347 2 : TALER_TESTING_cmd_batch ("refresh",
1348 : refresh),
1349 2 : TALER_TESTING_cmd_batch ("withdraw-age",
1350 : withdraw_age),
1351 2 : TALER_TESTING_cmd_batch ("spend-age",
1352 : spend_age),
1353 2 : TALER_TESTING_cmd_batch ("refresh-age",
1354 : refresh_age),
1355 2 : TALER_TESTING_cmd_batch ("track",
1356 : track),
1357 2 : TALER_TESTING_cmd_batch ("unaggregation",
1358 : unaggregation),
1359 2 : TALER_TESTING_cmd_batch ("aggregation",
1360 : aggregation),
1361 2 : TALER_TESTING_cmd_batch ("refund",
1362 : refund),
1363 2 : TALER_TESTING_cmd_batch ("batch-withdraw",
1364 : batch_withdraw),
1365 : #if FIXME_9828
1366 : TALER_TESTING_cmd_batch ("recoup",
1367 : recoup),
1368 : #endif
1369 2 : TALER_TESTING_cmd_batch ("reserve-open-close",
1370 : reserve_open_close),
1371 : /* End the suite. */
1372 2 : TALER_TESTING_cmd_end ()
1373 : };
1374 :
1375 2 : TALER_TESTING_run (is,
1376 : commands);
1377 : }
1378 2 : }
1379 :
1380 :
1381 : int
1382 2 : main (int argc,
1383 : char *const *argv)
1384 : {
1385 : (void) argc;
1386 : {
1387 : char *cipher;
1388 :
1389 2 : cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
1390 2 : GNUNET_assert (NULL != cipher);
1391 2 : uses_cs = (0 == strcmp (cipher,
1392 2 : "cs"));
1393 2 : GNUNET_asprintf (&config_file,
1394 : "test_exchange_api-%s.conf",
1395 : cipher);
1396 2 : GNUNET_asprintf (&config_file_expire_reserve_now,
1397 : "test_exchange_api_expire_reserve_now-%s.conf",
1398 : cipher);
1399 2 : GNUNET_free (cipher);
1400 : }
1401 2 : return TALER_TESTING_main (argv,
1402 : "INFO",
1403 : config_file,
1404 : "exchange-account-2",
1405 : TALER_TESTING_BS_FAKEBANK,
1406 : &cred,
1407 : &run,
1408 : NULL);
1409 : }
1410 :
1411 :
1412 : /* end of test_exchange_api.c */
|