From 0fbdd6c6cda1c7e0ad0b4ffc3f22bac3e1176c1d Mon Sep 17 00:00:00 2001 From: Jonathan Buchanan Date: Wed, 24 Jun 2020 17:38:09 -0400 Subject: got refunds working and tested --- src/backend/taler-merchant-httpd_get-orders-ID.c | 2 ++ ...-merchant-httpd_private-post-orders-ID-refund.c | 29 +++++++++++++--- src/backenddb/plugin_merchantdb_postgres.c | 20 ++++++++--- src/include/taler_merchant_testing_lib.h | 10 +++++- src/testing/test_merchant_api.c | 40 ++++++++++++++++++---- src/testing/testing_api_cmd_merchant_get_order.c | 25 +++++++++++++- src/testing/testing_api_cmd_wallet_get_order.c | 34 +++++++++++++++++- 7 files changed, 141 insertions(+), 19 deletions(-) diff --git a/src/backend/taler-merchant-httpd_get-orders-ID.c b/src/backend/taler-merchant-httpd_get-orders-ID.c index 2b1117a4..8dd858a3 100644 --- a/src/backend/taler-merchant-httpd_get-orders-ID.c +++ b/src/backend/taler-merchant-httpd_get-orders-ID.c @@ -888,6 +888,8 @@ TMH_get_orders_ID (const struct TMH_RequestHandler *rh, /* At this point, we know the contract was paid. Let's check for refunds */ + GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (TMH_currency, + &god->refund_amount)); qs = TMH_db->lookup_refunds_detailed (TMH_db->cls, hc->instance->settings.id, &god->h_contract_terms, diff --git a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c index 6db0497a..942892f9 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c +++ b/src/backend/taler-merchant-httpd_private-post-orders-ID-refund.c @@ -189,10 +189,31 @@ TMH_private_post_orders_ID_refund (const struct TMH_RequestHandler *rh, TALER_EC_REFUND_MERCHANT_DB_COMMIT_ERROR, "Internal database error"); case TALER_MERCHANTDB_RS_NO_SUCH_ORDER: - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_NOT_FOUND, - TALER_EC_REFUND_ORDER_ID_UNKNOWN, - "Order unknown (or never paid)"); + { + enum GNUNET_DB_QueryStatus qs; + json_t *contract_terms; + uint64_t order_serial; + + qs = TMH_db->lookup_contract_terms (TMH_db->cls, + hc->instance->settings.id, + hc->infix, + &contract_terms, + &order_serial); + if (qs == 1) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_REFUND_ORDER_ID_UNKNOWN, + "Order never paid"); + } + else + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_REFUND_ORDER_ID_UNKNOWN, + "Order unknown"); + } + } case TALER_MERCHANTDB_RS_SUCCESS: break; } diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 8c6eb802..b5c9ad01 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -2774,16 +2774,16 @@ process_deposits_for_refund_cb (void *cls, case GNUNET_DB_STATUS_HARD_ERROR: GNUNET_break (0); ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; + return; break; case GNUNET_DB_STATUS_SOFT_ERROR: ctx->rs = TALER_MERCHANTDB_RS_SOFT_ERROR; + return; break; default: - GNUNET_break (0); - ctx->rs = TALER_MERCHANTDB_RS_HARD_ERROR; + ctx->rs = qs; break; } - return; } /* stop immediately if we are done */ @@ -6096,7 +6096,17 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) 2), /* for postgres_lookup_order_summary() */ GNUNET_PQ_make_prepare ("lookup_order_summary", - "SELECT" + "(SELECT" + " creation_time" + ",order_serial" + " FROM merchant_contract_terms" + " WHERE merchant_contract_terms.merchant_serial=" + " (SELECT merchant_serial " + " FROM merchant_instances" + " WHERE merchant_id=$1)" + " AND merchant_contract_terms.order_id=$2)" + "UNION" + "(SELECT" " creation_time" ",order_serial" " FROM merchant_orders" @@ -6104,7 +6114,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) " (SELECT merchant_serial " " FROM merchant_instances" " WHERE merchant_id=$1)" - " AND merchant_orders.order_id=$2", + " AND merchant_orders.order_id=$2)", 2), /* for postgres_lookup_orders() */ GNUNET_PQ_make_prepare ("lookup_orders_inc", diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h index 3ae227cd..5ad4ff06 100644 --- a/src/include/taler_merchant_testing_lib.h +++ b/src/include/taler_merchant_testing_lib.h @@ -461,28 +461,36 @@ TALER_TESTING_cmd_merchant_get_orders (const char *label, * @param merchant_url base URL of the merchant which will * serve the request. * @param order_reference reference to a command that created an order. + * @param paid whether the order has been paid for or not. + * @param refunded whether the order has been refunded. * @param http_status expected HTTP response code for the request. */ struct TALER_TESTING_Command TALER_TESTING_cmd_wallet_get_order (const char *label, const char *merchant_url, const char *order_reference, + bool paid, + bool refunded, unsigned int http_status); /** - * Define a GET /private/tips/$TIP_ID CMD. + * Define a GET /private/orders/$ORDER_ID CMD. * * @param label the command label * @param merchant_url base URL of the merchant which will * serve the request. * @param order_reference reference to a command that created an order. + * @param paid whether the order has been paid for or not. + * @param refunded whether the order has been refunded. * @param http_status expected HTTP response code for the request. */ struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_get_order (const char *label, const char *merchant_url, const char *order_reference, + bool paid, + bool refunded, unsigned int http_status); diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index 1752ab16..0856757b 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -291,10 +291,14 @@ run (void *cls, TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1", merchant_url, "create-proposal-1", + false, + false, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1", merchant_url, "create-proposal-1", + false, + false, MHD_HTTP_OK), #if 0 TALER_TESTING_cmd_check_payment ("check-payment-1", @@ -328,6 +332,18 @@ run (void *cls, "withdraw-coin-1", "EUR:5", "EUR:4.99"), + TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2", + merchant_url, + "create-proposal-1", + true, + false, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2", + merchant_url, + "create-proposal-1", + true, + false, + MHD_HTTP_OK), #if 0 TALER_TESTING_cmd_poll_payment_conclude ("poll-payment-conclude-2", MHD_HTTP_OK, @@ -546,6 +562,13 @@ run (void *cls, "1r", /* order ID */ "EUR:0.1", MHD_HTTP_OK), + /* + TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r", + merchant_url, + "create-proposal-1r", + true, + true, + MHD_HTTP_OK),*/ #if 0 TALER_TESTING_cmd_poll_payment_conclude ("poll-payment-refund-conclude-1", MHD_HTTP_OK, @@ -588,12 +611,13 @@ run (void *cls, "EUR:0.1", MHD_HTTP_CONFLICT), /* Try to increase a non existent proposal. */ - TALER_TESTING_cmd_merchant_order_refund ("refund-increase-unpaid-proposal", - merchant_url, - "refund test", - "non-existent-id", - "EUR:0.1", - MHD_HTTP_NOT_FOUND), + TALER_TESTING_cmd_merchant_order_refund ( + "refund-increase-nonexistent-proposal", + merchant_url, + "refund test", + "non-existent-id", + "EUR:0.1", + MHD_HTTP_NOT_FOUND), /* The following block will (1) create a new reserve, then (2) a proposal, then (3) pay for @@ -638,7 +662,7 @@ run (void *cls, TALER_TESTING_cmd_check_bank_transfer ( "check_bank_transfer-paid-unincreased-refund", EXCHANGE_URL, - "EUR:9.88", /* '4.98 from above', plus 4.99 from 'pay-for-refund-1r' + "EUR:9.97", /* '4.98 from above', plus 4.99 from 'pay-for-refund-1r' and MINUS 0.1 PLUS 0.01 (deposit fee) from 'refund-increase-1r' */ exchange_payto, merchant_payto), @@ -1126,8 +1150,10 @@ run (void *cls, 0, 10, 10), +#endif TALER_TESTING_cmd_batch ("refund", refund), +#if 0 // #endif TALER_TESTING_cmd_batch ("tip", tip), diff --git a/src/testing/testing_api_cmd_merchant_get_order.c b/src/testing/testing_api_cmd_merchant_get_order.c index 985e9116..739e4efa 100644 --- a/src/testing/testing_api_cmd_merchant_get_order.c +++ b/src/testing/testing_api_cmd_merchant_get_order.c @@ -57,6 +57,16 @@ struct MerchantGetOrderState * Reference to a command that created an order. */ const char *order_reference; + + /** + * Whether the order was paid or not. + */ + bool paid; + + /** + * Whether the order was refunded or not. + */ + bool refunded; }; @@ -97,6 +107,13 @@ merchant_get_order_cb ( case MHD_HTTP_OK: // FIXME: use gts->tip_reference here to // check if the data returned matches that from the POST / PATCH + if (gos->paid != osr->paid) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order paid does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + return; + } break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -174,18 +191,22 @@ merchant_get_order_cleanup (void *cls, /** - * Define a GET /private/tips/$TIP_ID CMD. + * Define a GET /private/orders/$ORDER_ID CMD. * * @param label the command label * @param merchant_url base URL of the merchant which will * serve the request. * @param order_reference reference to a command that created an order. + * @param paid whether the order has been paid for or not. + * @param refunded whether the order has been refunded. * @param http_status expected HTTP response code for the request. */ struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_get_order (const char *label, const char *merchant_url, const char *order_reference, + bool paid, + bool refunded, unsigned int http_status) { struct MerchantGetOrderState *gos; @@ -193,6 +214,8 @@ TALER_TESTING_cmd_merchant_get_order (const char *label, gos = GNUNET_new (struct MerchantGetOrderState); gos->merchant_url = merchant_url; gos->order_reference = order_reference; + gos->paid = paid; + gos->refunded = refunded; gos->http_status = http_status; { struct TALER_TESTING_Command cmd = { diff --git a/src/testing/testing_api_cmd_wallet_get_order.c b/src/testing/testing_api_cmd_wallet_get_order.c index 1dce69c9..7cc9c352 100644 --- a/src/testing/testing_api_cmd_wallet_get_order.c +++ b/src/testing/testing_api_cmd_wallet_get_order.c @@ -57,6 +57,16 @@ struct WalletGetOrderState * Reference to a command that created an order. */ const char *order_reference; + + /** + * Whether the order was paid or not. + */ + bool paid; + + /** + * Whether the order was refunded or not. + */ + bool refunded; }; @@ -95,6 +105,8 @@ wallet_get_order_cb ( { /* FIXME, deeper checks should be implemented here. */ struct WalletGetOrderState *gos = cls; + bool paid_b = (paid == GNUNET_YES); + bool refunded_b = (refunded == GNUNET_YES); gos->ogh = NULL; if (gos->http_status != hr->http_status) @@ -110,8 +122,22 @@ wallet_get_order_cb ( switch (hr->http_status) { case MHD_HTTP_OK: - // FIXME: use gts->tip_reference here to + // FIXME: use gos->order_reference here to // check if the data returned matches that from the POST / PATCH + if (gos->paid != paid_b) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order paid does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + return; + } + if (gos->refunded != refunded_b) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order refunded does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + return; + } break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -196,12 +222,16 @@ wallet_get_order_cleanup (void *cls, * @param merchant_url base URL of the merchant which will * serve the request. * @param order_reference reference to a command that created an order. + * @param paid whether the order has been paid for or not. + * @param refunded whether the order has been refunded. * @param http_status expected HTTP response code for the request. */ struct TALER_TESTING_Command TALER_TESTING_cmd_wallet_get_order (const char *label, const char *merchant_url, const char *order_reference, + bool paid, + bool refunded, unsigned int http_status) { struct WalletGetOrderState *gos; @@ -210,6 +240,8 @@ TALER_TESTING_cmd_wallet_get_order (const char *label, gos->merchant_url = merchant_url; gos->order_reference = order_reference; gos->http_status = http_status; + gos->paid = paid; + gos->refunded = refunded; { struct TALER_TESTING_Command cmd = { .cls = gos, -- cgit v1.2.3