diff --git a/src/bank-lib/bank_api_history.c b/src/bank-lib/bank_api_history.c index 5083e3918..a83ad8fce 100644 --- a/src/bank-lib/bank_api_history.c +++ b/src/bank-lib/bank_api_history.c @@ -250,12 +250,12 @@ TALER_BANK_history (struct GNUNET_CURL_Context *ctx, { if (TALER_BANK_DIRECTION_BOTH == direction) GNUNET_asprintf (&url, - "/history?account_number=%llu&num_results=%lld", + "/history?auth=basic&account_number=%llu&delta=%lld", (unsigned long long) account_number, (long long) num_results); else GNUNET_asprintf (&url, - "/history?account_number=%llu&num_results=%lld&direction=%s", + "/history?auth=basic&account_number=%llu&delta=%lld&direction=%s", (unsigned long long) account_number, (long long) num_results, (TALER_BANK_DIRECTION_CREDIT == direction) ? "credit" : "debit"); @@ -265,13 +265,13 @@ TALER_BANK_history (struct GNUNET_CURL_Context *ctx, { if (TALER_BANK_DIRECTION_BOTH == direction) GNUNET_asprintf (&url, - "/history?account_number=%llu&num_results=%lld&start_row=%llu", + "/history?auth=basic&account_number=%llu&delta=%lld&start_row=%llu", (unsigned long long) account_number, (long long) num_results, (unsigned long long) start_row); else GNUNET_asprintf (&url, - "/history?account_number=%llu&num_results=%lld&start_row=%llu&direction=%s", + "/history?auth=basic&account_number=%llu&delta=%lld&start_row=%llu&direction=%s", (unsigned long long) account_number, (long long) num_results, (unsigned long long) start_row, diff --git a/src/bank-lib/fakebank.c b/src/bank-lib/fakebank.c index 3f067ee89..eb7656383 100644 --- a/src/bank-lib/fakebank.c +++ b/src/bank-lib/fakebank.c @@ -400,6 +400,8 @@ handle_history (struct TALER_FAKEBANK_Handle *h, MHD_GET_ARGUMENT_KIND, "account_number"); if ( (NULL == auth) || + (0 != strcasecmp (auth, + "basic")) || (NULL == acc) || (NULL == delta) ) { @@ -456,7 +458,6 @@ handle_history (struct TALER_FAKEBANK_Handle *h, } pos = pos->next; } - GNUNET_assert (pos->serial_id == start_number); } history = json_array (); while ( (NULL != pos) && diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c index 28b0b6dca..ee85fa610 100644 --- a/src/bank-lib/test_bank_api.c +++ b/src/bank-lib/test_bank_api.c @@ -40,13 +40,48 @@ run (void *cls) static struct TBI_Command commands[] = { /* Add EUR:5.01 to account 42 */ + { .oc = TBI_OC_HISTORY, + .label = "history-0", + .details.history.account_number = 1, + .details.history.direction = TALER_BANK_DIRECTION_BOTH, + .details.history.start_row = 0, + .details.history.num_results = 5 }, { .oc = TBI_OC_ADMIN_ADD_INCOMING, .label = "deposit-1", .details.admin_add_incoming.expected_response_code = MHD_HTTP_OK, .details.admin_add_incoming.credit_account_no = 1, .details.admin_add_incoming.debit_account_no = 2, .details.admin_add_incoming.amount = "PUDOS:5.01" }, - + { .oc = TBI_OC_ADMIN_ADD_INCOMING, + .label = "deposit-2", + .details.admin_add_incoming.expected_response_code = MHD_HTTP_OK, + .details.admin_add_incoming.credit_account_no = 1, + .details.admin_add_incoming.debit_account_no = 2, + .details.admin_add_incoming.amount = "PUDOS:5.01" }, + { .oc = TBI_OC_HISTORY, + .label = "history-1c", + .details.history.account_number = 1, + .details.history.direction = TALER_BANK_DIRECTION_CREDIT, + .details.history.start_row = 0, + .details.history.num_results = 5 }, + { .oc = TBI_OC_HISTORY, + .label = "history-2d", + .details.history.account_number = 2, + .details.history.direction = TALER_BANK_DIRECTION_DEBIT, + .details.history.start_row = 0, + .details.history.num_results = 5 }, + { .oc = TBI_OC_HISTORY, + .label = "history-2dr", + .details.history.account_number = 2, + .details.history.direction = TALER_BANK_DIRECTION_DEBIT, + .details.history.start_row = UINT64_MAX, + .details.history.num_results = -5 }, + { .oc = TBI_OC_HISTORY, + .label = "history-2fwd", + .details.history.account_number = 2, + .details.history.direction = TALER_BANK_DIRECTION_DEBIT, + .details.history.start_row = 1, + .details.history.num_results = 5 }, { .oc = TBI_OC_END } }; @@ -92,7 +127,7 @@ main (int argc, "serve-http", "--port", "8081", NULL); - if (NULL == bankd_admin) + if (NULL == bankd_admin) { fprintf (stderr, "Failed to launch `taler-bank-manage' for admin, skipping test\n"); diff --git a/src/bank-lib/test_bank_api_with_fakebank.c b/src/bank-lib/test_bank_api_with_fakebank.c index 3c726a749..9729fb8cb 100644 --- a/src/bank-lib/test_bank_api_with_fakebank.c +++ b/src/bank-lib/test_bank_api_with_fakebank.c @@ -39,29 +39,69 @@ run (void *cls) int *resultp = cls; static struct TBI_Command commands[] = { + { .oc = TBI_OC_HISTORY, + .label = "history-0", + .details.history.account_number = 1, + .details.history.direction = TALER_BANK_DIRECTION_BOTH, + .details.history.start_row = 0, + .details.history.num_results = 1 }, /* Add EUR:5.01 to account 1 */ { .oc = TBI_OC_ADMIN_ADD_INCOMING, - .label = "deposit-1", + .label = "debit-1", .details.admin_add_incoming.expected_response_code = MHD_HTTP_OK, .details.admin_add_incoming.credit_account_no = 1, .details.admin_add_incoming.debit_account_no = 2, .details.admin_add_incoming.exchange_base_url = "https://exchange.net/", .details.admin_add_incoming.amount = "PUDOS:5.01" }, /* Add EUR:3.21 to account 3 */ + { .oc = TBI_OC_HISTORY, + .label = "history-1c", + .details.history.account_number = 1, + .details.history.direction = TALER_BANK_DIRECTION_CREDIT, + .details.history.start_row = 0, + .details.history.num_results = 5 }, + { .oc = TBI_OC_HISTORY, + .label = "history-1d", + .details.history.account_number = 1, + .details.history.direction = TALER_BANK_DIRECTION_DEBIT, + .details.history.start_row = 0, + .details.history.num_results = 5 }, { .oc = TBI_OC_ADMIN_ADD_INCOMING, - .label = "deposit-2", + .label = "debit-2", .details.admin_add_incoming.expected_response_code = MHD_HTTP_OK, .details.admin_add_incoming.credit_account_no = 3, .details.admin_add_incoming.debit_account_no = 2, .details.admin_add_incoming.exchange_base_url = "https://exchange.org/", .details.admin_add_incoming.amount = "PUDOS:3.21" }, + { .oc = TBI_OC_ADMIN_ADD_INCOMING, + .label = "credit-2", + .details.admin_add_incoming.expected_response_code = MHD_HTTP_OK, + .details.admin_add_incoming.credit_account_no = 2, + .details.admin_add_incoming.debit_account_no = 3, + .details.admin_add_incoming.exchange_base_url = "https://exchange.org/", + .details.admin_add_incoming.amount = "PUDOS:3.21" }, + { .oc = TBI_OC_HISTORY, + .label = "history-2b", + .details.history.account_number = 2, + .details.history.direction = TALER_BANK_DIRECTION_BOTH, + .details.history.start_row = 0, + .details.history.num_results = 5 }, + { .oc = TBI_OC_HISTORY, + .label = "history-2bi", + .details.history.account_number = 2, + .details.history.direction = TALER_BANK_DIRECTION_BOTH, + .details.history.start_row = 1, + .details.history.num_results = 5 }, /* check transfers arrived at fakebank */ { .oc = TBI_OC_EXPECT_TRANSFER, - .label = "expect-2", - .details.expect_transfer.cmd_ref = "deposit-2" }, + .label = "expect-2d", + .details.expect_transfer.cmd_ref = "credit-2" }, + { .oc = TBI_OC_EXPECT_TRANSFER, + .label = "expect-2c", + .details.expect_transfer.cmd_ref = "debit-2" }, { .oc = TBI_OC_EXPECT_TRANSFER, .label = "expect-1", - .details.expect_transfer.cmd_ref = "deposit-1" }, + .details.expect_transfer.cmd_ref = "debit-1" }, /* check transfer list is now empty */ { .oc = TBI_OC_EXPECT_TRANSFERS_EMPTY, .label = "expect-empty" }, diff --git a/src/bank-lib/test_bank_interpreter.c b/src/bank-lib/test_bank_interpreter.c index 5f2d66648..da3984861 100644 --- a/src/bank-lib/test_bank_interpreter.c +++ b/src/bank-lib/test_bank_interpreter.c @@ -174,6 +174,44 @@ add_incoming_cb (void *cls, } +/** + * Callbacks of this type are used to serve the result of asking + * the bank for the transaction history. + * + * @param cls closure + * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request + * 0 if the bank's reply is bogus (fails to follow the protocol), + * #MHD_HTTP_NO_CONTENT if there are no more results; on success the + * last callback is always of this status (even if `abs(num_results)` were + * already returned). + * @param dir direction of the transfer + * @param serial_id monotonically increasing counter corresponding to the transaction + * @param details details about the wire transfer + * @param json detailed response from the HTTPD, or NULL if reply was not in JSON + */ +static void +history_cb (void *cls, + unsigned int http_status, + enum TALER_BANK_Direction dir, + uint64_t serial_id, + const struct TALER_BANK_TransferDetails *details, + const json_t *json) +{ + struct InterpreterState *is = cls; + struct TBI_Command *cmd = &is->commands[is->ip]; + + if (MHD_HTTP_OK != http_status) + { + cmd->details.history.hh = NULL; + is->ip++; + is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, + is); + return; + } + /* FIXME: check history data is OK! */ +} + + /** * Run the main interpreter loop that performs bank operations. * @@ -199,6 +237,9 @@ interpreter_run (void *cls) fail (is); return; } + auth.method = TALER_BANK_AUTH_BASIC; /* or "NONE"? */ + auth.details.basic.username = "user"; + auth.details.basic.password = "pass"; switch (cmd->oc) { case TBI_OC_END: @@ -220,9 +261,6 @@ interpreter_run (void *cls) GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cmd->details.admin_add_incoming.wtid, sizeof (cmd->details.admin_add_incoming.wtid)); - auth.method = TALER_BANK_AUTH_BASIC; /* or "NONE"? */ - auth.details.basic.username = "user"; - auth.details.basic.password = "pass"; cmd->details.admin_add_incoming.aih = TALER_BANK_admin_add_incoming (is->ctx, "http://localhost:8081", @@ -241,6 +279,24 @@ interpreter_run (void *cls) return; } return; + case TBI_OC_HISTORY: + cmd->details.history.hh + = TALER_BANK_history (is->ctx, + "http://localhost:8081", + &auth, + cmd->details.history.account_number, + cmd->details.history.direction, + cmd->details.history.start_row, + cmd->details.history.num_results, + &history_cb, + is); + if (NULL == cmd->details.history.hh) + { + GNUNET_break (0); + fail (is); + return; + } + return; case TBI_OC_EXPECT_TRANSFER: ref = find_command (is, cmd->details.expect_transfer.cmd_ref); @@ -346,6 +402,21 @@ do_shutdown (void *cls) cmd->details.admin_add_incoming.aih = NULL; } break; + case TBI_OC_HISTORY: + if (NULL != cmd->details.history.hh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Command %u (%s) did not complete\n", + i, + cmd->label); + TALER_BANK_history_cancel (cmd->details.history.hh); + cmd->details.history.hh = NULL; + } + break; + case TBI_OC_EXPECT_TRANSFER: + break; + case TBI_OC_EXPECT_TRANSFERS_EMPTY: + break; default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown instruction %d at %u (%s)\n", diff --git a/src/bank-lib/test_bank_interpreter.h b/src/bank-lib/test_bank_interpreter.h index 1f2772ca7..06b4e2d7f 100644 --- a/src/bank-lib/test_bank_interpreter.h +++ b/src/bank-lib/test_bank_interpreter.h @@ -44,6 +44,11 @@ enum TBI_OpCode */ TBI_OC_ADMIN_ADD_INCOMING, + /** + * Request wire transfer history. + */ + TBI_OC_HISTORY, + /** * Expect that we have received the specified transfer at fakebank. */ @@ -122,6 +127,36 @@ struct TBI_Command } admin_add_incoming; + struct { + + /** + * For which account do we query the history. + */ + uint64_t account_number; + + /** + * Which types of transactions should be listed? + */ + enum TALER_BANK_Direction direction; + + /** + * At which offset do we start? + * Use UINT64_MAX or 0 for the extremes. + */ + uint64_t start_row; + + /** + * How many results should be returned (if available)? + */ + int64_t num_results; + + /** + * Set to the API's handle during the operation. + */ + struct TALER_BANK_HistoryHandle *hh; + + } history; + /** * If @e opcode is #TBI_OC_EXPECT_TRANSFER, this * specifies which transfer we expected.