merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit a4f0dcb22839000eb5f3d31158986403d23a7c6a
parent 8d883327c61fbfbbce5c2453d8886956ff01d25a
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  3 May 2020 15:06:13 +0200

update testing logic for order CMDs

Diffstat:
Msrc/include/taler_merchant_service.h | 12+-----------
Msrc/include/taler_merchant_testing_lib.h | 170++++++++++++++++++++++++++++---------------------------------------------------
Msrc/lib/merchant_api_post_order_pay.c | 1-
Msrc/lib/merchant_api_post_order_refund.c | 14+++++++-------
Msrc/testing/Makefile.am | 2+-
Msrc/testing/testing_api_cmd_abort_order.c | 104++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/testing/testing_api_cmd_pay_order.c | 480++++++++++++++-----------------------------------------------------------------
Dsrc/testing/testing_api_cmd_refund_increase.c | 236-------------------------------------------------------------------------------
Asrc/testing/testing_api_cmd_refund_order.c | 227+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 420 insertions(+), 826 deletions(-)

diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h @@ -1485,11 +1485,6 @@ struct TALER_MERCHANT_PaidCoin struct TALER_Amount amount_without_fee; /** - * Fee the exchange charges for refunds of this coin. - */ - struct TALER_Amount refund_fee; - - /** * What is the URL of the exchange that issued @a coin_pub? */ const char *exchange_url; @@ -1565,11 +1560,6 @@ struct TALER_MERCHANT_PayCoin struct TALER_Amount amount_without_fee; /** - * Fee the exchange charges for refunds of this coin. - */ - struct TALER_Amount refund_fee; - - /** * URL of the exchange that issued @e coin_priv. */ const char *exchange_url; @@ -1778,7 +1768,7 @@ typedef void * @param cb callback processing the response from /refund * @param cb_cls closure for cb */ -struct TALER_MERCHANT_OrderRefundHandle +struct TALER_MERCHANT_OrderRefundHandle * TALER_MERCHANT_post_order_refund (struct GNUNET_CURL_Context *ctx, const char *backend_url, const char *order_id, diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h @@ -444,6 +444,67 @@ TALER_TESTING_cmd_merchant_claim_order (const char *label, const char *order_id); +/** + * Make a "pay" test command. + * + * @param label command label. + * @param merchant_url merchant base url + * @param http_status expected HTTP response code. + * @param proposal_reference the proposal whose payment status + * is going to be checked. + * @param coin_reference reference to any command which is able + * to provide coins to use for paying. + * @param amount_with_fee amount to pay, including the deposit + * fee + * @param amount_without_fee amount to pay, no fees included. + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_pay_order (const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee); + +/** + * Make an "abort" test command. + * + * @param label command label + * @param merchant_url merchant base URL + * @param pay_reference reference to the payment to abort + * @param http_status expected HTTP response code + * @return the command + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_order_abort (const char *label, + const char *merchant_url, + const char *pay_reference, + unsigned int http_status); + + +/** + * Define a "refund" order CMD. + * + * @param label command label. + * @param merchant_url base URL of the backend serving the + * "refund increase" request. + * @param reason refund justification, human-readable. + * @param order_id order id of the contract to refund. + * @param refund_amount amount to be refund-increased. + * @param http_code expected HTTP response code. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_order_refund (const char *label, + const char *merchant_url, + const char *reason, + const char *order_id, + const char *refund_amount, + unsigned int http_code); + + /* ******************** OLD ******************* */ @@ -540,92 +601,6 @@ TALER_TESTING_cmd_poll_payment_conclude (const char *label, /** - * Make a "pay" test command. - * - * @param label command label. - * @param merchant_url merchant base url - * @param http_status expected HTTP response code. - * @param proposal_reference the proposal whose payment status - * is going to be checked. - * @param coin_reference reference to any command which is able - * to provide coins to use for paying. - * @param amount_with_fee amount to pay, including the deposit - * fee - * @param amount_without_fee amount to pay, no fees included. - * @param refund_fee fee for refunding this payment. - * @return the command - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_pay (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *refund_fee); - -/** - * Make a "pay again" test command. Its purpose is to - * take all the data from a aborted "pay" CMD, and use - * good coins - found in @a coin_reference - to correctly - * pay for it. - * - * @param label command label - * @param merchant_url merchant base URL - * @param pay_reference reference to the payment to replay - * @param coin_reference reference to the coins to use - * @param http_status expected HTTP response code - * - * @return the command - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_pay_again (const char *label, - const char *merchant_url, - const char *pay_reference, - const char *coin_reference, - const char *refund_fee, - unsigned int http_status); - -/** - * Make a "pay abort" test command. - * - * @param label command label - * @param merchant_url merchant base URL - * @param pay_reference reference to the payment to abort - * @param http_status expected HTTP response code - * - * @return the command - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_pay_abort (const char *label, - const char *merchant_url, - const char *pay_reference, - unsigned int http_status); - -/** - * Make a "pay abort refund" CMD. This command uses the - * refund permission from a "pay abort" CMD, and redeems it - * at the exchange. - * - * @param label command label. - * @param abort_reference reference to the "pay abort" CMD that - * will offer the refund permission. - * @param num_coins how many coins are expected to be refunded. - * @param refund_amount the amount we are going to redeem as - * refund. - * @param refund_fee the refund fee (FIXME: who pays it?) - * @param http_status expected HTTP response code. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_pay_abort_refund (const char *label, - const char *abort_reference, - unsigned int num_coins, - const char *refund_amount, - const char *refund_fee, - unsigned int http_status); - -/** * Define a "refund lookup" CMD. * * @param label command label. @@ -682,29 +657,6 @@ TALER_TESTING_cmd_refund_lookup_with_amount (const char *label, /** - * Define a "refund increase" CMD. - * - * @param label command label. - * @param merchant_url base URL of the backend serving the - * "refund increase" request. - * @param reason refund justification, human-readable. - * @param order_id order id of the contract to refund. - * @param refund_amount amount to be refund-increased. - * @param refund_fee refund fee. - * @param http_code expected HTTP response code. - * - * @return the command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_refund_increase (const char *label, - const char *merchant_url, - const char *reason, - const char *order_id, - const char *refund_amount, - const char *refund_fee, - unsigned int http_code); - -/** * Make a "history" command. * * @param label command label. diff --git a/src/lib/merchant_api_post_order_pay.c b/src/lib/merchant_api_post_order_pay.c @@ -621,7 +621,6 @@ TALER_MERCHANT_order_pay (struct GNUNET_CURL_Context *ctx, p->coin_pub = dr.coin_pub; p->amount_with_fee = coin->amount_with_fee; p->amount_without_fee = coin->amount_without_fee; - p->refund_fee = coin->refund_fee; p->exchange_url = coin->exchange_url; } return TALER_MERCHANT_order_pay_frontend (ctx, diff --git a/src/lib/merchant_api_post_order_refund.c b/src/lib/merchant_api_post_order_refund.c @@ -152,13 +152,13 @@ TALER_MERCHANT_post_order_refund_cancel ( * @param cb_cls closure for cb */ struct TALER_MERCHANT_OrderRefundHandle * -TALER_MERCHANT_order_refund (struct GNUNET_CURL_Context *ctx, - const char *backend_url, - const char *order_id, - const struct TALER_Amount *refund, - const char *reason, - TALER_MERCHANT_RefundCallback cb, - void *cb_cls) +TALER_MERCHANT_post_order_refund (struct GNUNET_CURL_Context *ctx, + const char *backend_url, + const char *order_id, + const struct TALER_Amount *refund, + const char *reason, + TALER_MERCHANT_RefundCallback cb, + void *cb_cls) { struct TALER_MERCHANT_OrderRefundHandle *orh; json_t *req; diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am @@ -30,11 +30,11 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_post_orders.c \ testing_api_cmd_patch_instance.c \ testing_api_cmd_patch_product.c \ + testing_api_cmd_refund_order.c \ \ testing_api_cmd_check_payment.c \ testing_api_cmd_history.c \ testing_api_cmd_poll_payment.c \ - testing_api_cmd_refund_increase.c \ testing_api_cmd_refund_lookup.c \ testing_api_cmd_rewind.c \ testing_api_cmd_tip_authorize.c \ diff --git a/src/testing/testing_api_cmd_abort_order.c b/src/testing/testing_api_cmd_abort_order.c @@ -37,11 +37,6 @@ struct AbortState { /** - * Merchant public key. - */ - struct TALER_MerchantPublicKeyP merchant_pub; - - /** * Reference to the "pay" command to abort. */ const char *pay_reference; @@ -138,19 +133,20 @@ build_coins (struct TALER_MERCHANT_AbortCoin **ac, GNUNET_break (0); return GNUNET_SYSERR; } - GNUNET_array_grow (*pc, - *npc, - (*npc) + 1); - icoin = &((*pc)[(*npc) - 1]); + GNUNET_array_grow (*ac, + *nac, + (*nac) + 1); + icoin = &((*ac)[(*nac) - 1]); { - const struct TALER_CoinSpendPublicKeyP *coin_pub; + const struct TALER_CoinSpendPrivateKeyP *coin_priv; GNUNET_assert (GNUNET_OK == - TALER_TESTING_get_trait_coin_pub (coin_cmd, - 0, - &coin_pub)); - icoin->coin_pub = *coin_pub; + TALER_TESTING_get_trait_coin_priv (coin_cmd, + 0, + &coin_priv)); + GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, + &icoin->coin_pub.eddsa_pub); } GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_url (coin_cmd, @@ -185,7 +181,7 @@ abort_cb (void *cls, { struct AbortState *as = cls; - as->pao = NULL; + as->oah = NULL; if (as->http_status != hr->http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -200,14 +196,13 @@ abort_cb (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u refunds\n", - num_refunds); + num_aborts); as->acs_length = num_aborts; as->acs = GNUNET_new_array (num_aborts, struct TALER_MERCHANT_AbortedCoin); - memcpy (as->res, + memcpy (as->acs, res, - num_refunds * sizeof (struct TALER_MERCHANT_AbortedCoin)); - as->merchant_pub = *merchant_pub; + num_aborts * sizeof (struct TALER_MERCHANT_AbortedCoin)); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successful pay-abort (HTTP status: %u)\n", @@ -235,15 +230,14 @@ abort_run (void *cls, const char *amount_with_fee; const struct TALER_TESTING_Command *proposal_cmd; const char *order_id; - struct TALER_MerchantPublicKeyP merchant_pub; const struct GNUNET_HashCode *h_proposal; + struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_Amount total_amount; const char *error_name; unsigned int error_line; struct TALER_MERCHANT_AbortCoin *abort_coins; unsigned int nabort_coins; char *cr; - struct TALER_MERCHANT_OrderAbortHandle *oah; as->is = is; pay_cmd = TALER_TESTING_interpreter_lookup_command (is, @@ -269,10 +263,7 @@ abort_run (void *cls, proposal_reference); if (NULL == proposal_cmd) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); { const json_t *contract_terms; @@ -281,10 +272,7 @@ abort_run (void *cls, TALER_TESTING_get_trait_contract_terms (proposal_cmd, 0, &contract_terms)) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); { /* Get information that needs to be put verbatim in the * deposit permission */ @@ -292,7 +280,7 @@ abort_run (void *cls, GNUNET_JSON_spec_string ("order_id", &order_id), GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &as->merchant_pub), + &merchant_pub), TALER_JSON_spec_amount ("amount", &total_amount), GNUNET_JSON_spec_end () @@ -314,15 +302,14 @@ abort_run (void *cls, error_line, js); free (js); - GNUNET_break_op (0); - return NULL; + TALER_TESTING_FAIL (is); } } } cr = GNUNET_strdup (coin_reference); - pay_coins = NULL; - npay_coins = 0; + abort_coins = NULL; + nabort_coins = 0; if (GNUNET_OK != build_coins (&abort_coins, &nabort_coins, @@ -330,12 +317,11 @@ abort_run (void *cls, is, amount_with_fee)) { - GNUNET_array_grow (pay_coins, - npay_coins, + GNUNET_array_grow (abort_coins, + nabort_coins, 0); GNUNET_free (cr); - GNUNET_break (0); - return NULL; + TALER_TESTING_FAIL (is); } GNUNET_free (cr); @@ -343,23 +329,20 @@ abort_run (void *cls, TALER_TESTING_get_trait_h_contract_terms (proposal_cmd, 0, &h_proposal)) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); as->oah = TALER_MERCHANT_order_abort (is->ctx, - merchant_url, + as->merchant_url, order_id, - &as->merchant_pub, + &merchant_pub, h_proposal, nabort_coins, abort_coins, - api_cb, - api_cb_cls); - GNUNET_array_grow (pay_coins, - npay_coins, + &abort_cb, + as); + GNUNET_array_grow (abort_coins, + nabort_coins, 0); - if (NULL == as->pao) + if (NULL == as->oah) TALER_TESTING_FAIL (is); } @@ -376,15 +359,17 @@ abort_cleanup (void *cls, { struct AbortState *as = cls; - if (NULL != as->pao) + if (NULL != as->acs) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Command `%s' did not complete.\n", TALER_TESTING_interpreter_get_current_label ( as->is)); - TALER_MERCHANT_pay_cancel (as->pao); + TALER_MERCHANT_order_abort_cancel (as->oah); } - GNUNET_free_non_null (as->res); + GNUNET_array_grow (as->acs, + as->acs_length, + 0); GNUNET_free (as); } @@ -406,15 +391,10 @@ abort_traits (void *cls, { struct AbortState *as = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_merchant_pub (0, - &as->merchant_pub), - TALER_TESTING_make_trait_refund_entry (0, - as->acs), - TALER_TESTING_make_trait_uint (0, - &as->num_refunds), TALER_TESTING_trait_end () }; + (void) as; return TALER_TESTING_get_trait (traits, ret, trait, @@ -432,10 +412,10 @@ abort_traits (void *cls, * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_abort (const char *label, - const char *merchant_url, - const char *pay_reference, - unsigned int http_status) +TALER_TESTING_cmd_merchant_order_abort (const char *label, + const char *merchant_url, + const char *pay_reference, + unsigned int http_status) { struct AbortState *as; diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018 Taler Systems SA + Copyright (C) 2014-2018, 2020 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -16,13 +16,12 @@ License along with TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** - * @file lib/testing_api_cmd_pay.c - * @brief command to test the /pay feature. + * @file lib/testing_api_cmd_pay_order.c + * @brief command to test the /orders/ID/pay feature. * @author Marcello Stanisci + * @author Christian Grothoff */ - #include "platform.h" #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> @@ -30,9 +29,6 @@ #include "taler_merchant_service.h" #include "taler_merchant_testing_lib.h" -#define AMOUNT_WITH_FEE 0 -#define AMOUNT_WITHOUT_FEE 1 -#define REFUND_FEE 2 /** * State for a /pay CMD. @@ -82,58 +78,10 @@ struct PayState const char *amount_without_fee; /** - * Fee for refunding this payment. - */ - const char *refund_fee; - - /** - * Handle to the /pay operation. - */ - struct TALER_MERCHANT_Pay *po; - -}; - - -/** - * State for a "pay again" CMD. - */ -struct PayAgainState -{ - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Reference to the "pay" command to abort. - */ - const char *pay_reference; - - /** - * Reference to the coins to use. - */ - const char *coin_reference; - - /** - * Merchant URL. + * Handle to the pay operation. */ - const char *merchant_url; + struct TALER_MERCHANT_OrderPayHandle *oph; - /** - * Refund fee. - */ - const char *refund_fee; - - /** - * Handle to a "pay again" operation. - */ - struct TALER_MERCHANT_Pay *pao; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; }; @@ -149,7 +97,6 @@ struct PayAgainState * @param amount_with_fee total amount to be paid for a contract. * @param amount_without_fee to be removed, there is no * per-contract fee, only per-coin exists. - * @param refund_fee per-contract? per-coin? * @return #GNUNET_OK on success */ static int @@ -158,8 +105,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, char *coins, struct TALER_TESTING_Interpreter *is, const char *amount_with_fee, - const char *amount_without_fee, - const char *refund_fee) + const char *amount_without_fee) { char *token; @@ -244,9 +190,6 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, TALER_TESTING_get_trait_url (coin_cmd, TALER_TESTING_UT_EXCHANGE_BASE_URL, &icoin->exchange_url)); - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (refund_fee, - &icoin->refund_fee)); } return GNUNET_OK; @@ -271,7 +214,7 @@ pay_cb (void *cls, unsigned int error_line; const struct TALER_MerchantPublicKeyP *merchant_pub; - ps->po = NULL; + ps->oph = NULL; if (ps->http_status != hr->http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -331,40 +274,18 @@ pay_cb (void *cls, /** - * Function used by both "pay" and "abort" operations. - * It prepares data and sends the "pay" request to the - * backend. + * Run a "pay" CMD. * - * @param merchant_url base URL of the merchant serving the - * request. - * @param coin_reference reference to the CMD(s) that offer - * "coins" traits. It is possible to give multiple - * references by using semicolons to separate them. - * @param proposal_refere reference to a "proposal" CMD. + * @param cls closure. + * @param cmd current CMD being run. * @param is interpreter state. - * @param amount_with_fee amount to be paid, including deposit - * fee. - * @param amount_without_fee amount to be paid, without deposit - * fee. - * @param refund_fee refund fee. - * @param api_func "lib" function that will be called to either - * issue a "pay" or "abort" request. - * @param api_cb callback for @a api_func. - * @param api_cb_cls closure for @a api_cb - * - * @return handle to the operation, NULL if errors occur. */ -static struct TALER_MERCHANT_Pay * -_pay_run (const char *merchant_url, - const char *coin_reference, - const char *proposal_reference, - struct TALER_TESTING_Interpreter *is, - const char *amount_with_fee, - const char *amount_without_fee, - const char *refund_fee, - TALER_MERCHANT_PayCallback api_cb, - void *api_cb_cls) +static void +pay_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) { + struct PayState *ps = cls; const struct TALER_TESTING_Command *proposal_cmd; const json_t *contract_terms; const char *order_id; @@ -380,27 +301,21 @@ _pay_run (const char *merchant_url, unsigned int error_line; struct TALER_MERCHANT_PayCoin *pay_coins; unsigned int npay_coins; - char *cr; struct TALER_MerchantSignatureP *merchant_sig; - struct TALER_MERCHANT_Pay *ret; - proposal_cmd = TALER_TESTING_interpreter_lookup_command (is, - proposal_reference); + ps->is = is; + proposal_cmd = TALER_TESTING_interpreter_lookup_command ( + is, + ps->proposal_reference); if (NULL == proposal_cmd) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); if (GNUNET_OK != TALER_TESTING_get_trait_contract_terms (proposal_cmd, 0, &contract_terms)) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); { /* Get information that needs to be put verbatim in the * deposit permission */ @@ -440,96 +355,64 @@ _pay_run (const char *merchant_url, error_line, js); free (js); - GNUNET_break_op (0); - return NULL; + TALER_TESTING_FAIL (is); } } - cr = GNUNET_strdup (coin_reference); - pay_coins = NULL; - npay_coins = 0; - if (GNUNET_OK != - build_coins (&pay_coins, - &npay_coins, - cr, - is, - amount_with_fee, - amount_without_fee, - refund_fee)) { - GNUNET_array_grow (pay_coins, - npay_coins, - 0); + char *cr; + + cr = GNUNET_strdup (ps->coin_reference); + pay_coins = NULL; + npay_coins = 0; + if (GNUNET_OK != + build_coins (&pay_coins, + &npay_coins, + cr, + is, + ps->amount_with_fee, + ps->amount_without_fee)) + { + GNUNET_array_grow (pay_coins, + npay_coins, + 0); + GNUNET_free (cr); + TALER_TESTING_FAIL (is); + } GNUNET_free (cr); - GNUNET_break (0); - return NULL; } - - GNUNET_free (cr); if (GNUNET_OK != TALER_TESTING_get_trait_merchant_sig (proposal_cmd, 0, &merchant_sig)) - { - GNUNET_break (0); - return NULL; - } + TALER_TESTING_FAIL (is); + if (GNUNET_OK != TALER_TESTING_get_trait_h_contract_terms (proposal_cmd, 0, &h_proposal)) - { - GNUNET_break (0); - return NULL; - } - ret = TALER_MERCHANT_pay_wallet (is->ctx, - merchant_url, - h_proposal, - &total_amount, - &max_fee, - &merchant_pub, - merchant_sig, - timestamp, - refund_deadline, - pay_deadline, - &h_wire, - order_id, - npay_coins, - pay_coins, - api_cb, - api_cb_cls); + TALER_TESTING_FAIL (is); + ps->oph = TALER_MERCHANT_order_pay (is->ctx, + ps->merchant_url, + "", /* session ID */ + h_proposal, + &total_amount, + &max_fee, + &merchant_pub, + merchant_sig, + timestamp, + refund_deadline, + pay_deadline, + &h_wire, + order_id, + npay_coins, + pay_coins, + &pay_cb, + ps); GNUNET_array_grow (pay_coins, npay_coins, 0); - return ret; -} - - -/** - * Run a "pay" CMD. - * - * @param cls closure. - * @param cmd current CMD being run. - * @param is interpreter state. - */ -static void -pay_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - - struct PayState *ps = cls; - - ps->is = is; - if (NULL == (ps->po = _pay_run (ps->merchant_url, - ps->coin_reference, - ps->proposal_reference, - is, - ps->amount_with_fee, - ps->amount_without_fee, - ps->refund_fee, - &pay_cb, - ps))) + if (NULL == ps->oph) TALER_TESTING_FAIL (is); } @@ -546,13 +429,13 @@ pay_cleanup (void *cls, { struct PayState *ps = cls; - if (NULL != ps->po) + if (NULL != ps->oph) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Command `%s' did not complete.\n", TALER_TESTING_interpreter_get_current_label ( ps->is)); - TALER_MERCHANT_pay_cancel (ps->po); + TALER_MERCHANT_order_pay_cancel (ps->oph); } GNUNET_free (ps); @@ -605,18 +488,14 @@ pay_traits (void *cls, } { struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_string - (AMOUNT_WITH_FEE, ps->amount_with_fee), - TALER_TESTING_make_trait_string - (AMOUNT_WITHOUT_FEE, ps->amount_without_fee), - TALER_TESTING_make_trait_string - (REFUND_FEE, ps->refund_fee), - TALER_TESTING_make_trait_proposal_reference - (0, ps->proposal_reference), - TALER_TESTING_make_trait_coin_reference - (0, ps->coin_reference), - TALER_TESTING_make_trait_order_id (0, order_id), - TALER_TESTING_make_trait_merchant_pub (0, merchant_pub), + TALER_TESTING_make_trait_proposal_reference (0, + ps->proposal_reference), + TALER_TESTING_make_trait_coin_reference (0, + ps->coin_reference), + TALER_TESTING_make_trait_order_id (0, + order_id), + TALER_TESTING_make_trait_merchant_pub (0, + merchant_pub), TALER_TESTING_trait_end () }; @@ -641,19 +520,16 @@ pay_traits (void *cls, * @param amount_with_fee amount to pay, including the deposit * fee * @param amount_without_fee amount to pay, no fees included. - * @param refund_fee fee for refunding this payment. - * * @return the command */ struct TALER_TESTING_Command -TALER_TESTING_cmd_pay (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *proposal_reference, - const char *coin_reference, - const char *amount_with_fee, - const char *amount_without_fee, - const char *refund_fee) +TALER_TESTING_cmd_merchant_pay_order (const char *label, + const char *merchant_url, + unsigned int http_status, + const char *proposal_reference, + const char *coin_reference, + const char *amount_with_fee, + const char *amount_without_fee) { struct PayState *ps; @@ -664,7 +540,6 @@ TALER_TESTING_cmd_pay (const char *label, ps->merchant_url = merchant_url; ps->amount_with_fee = amount_with_fee; ps->amount_without_fee = amount_without_fee; - ps->refund_fee = refund_fee; { struct TALER_TESTING_Command cmd = { .cls = ps, @@ -679,197 +554,4 @@ TALER_TESTING_cmd_pay (const char *label, } -/** - * Function called with the result of a /pay again operation, - * check signature and HTTP response code are good. - * - * @param cls closure with the interpreter state - * @param hr HTTP response - */ -static void -pay_again_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) -{ - struct PayAgainState *pas = cls; - struct GNUNET_CRYPTO_EddsaSignature sig; - const char *error_name; - unsigned int error_line; - const struct TALER_TESTING_Command *pay_cmd; - const struct TALER_MerchantPublicKeyP *merchant_pub; - - pas->pao = NULL; - if (pas->http_status != hr->http_status) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, - TALER_TESTING_interpreter_get_current_label (pas->is)); - TALER_TESTING_interpreter_fail (pas->is); - return; - } - - if (NULL == - (pay_cmd = TALER_TESTING_interpreter_lookup_command (pas->is, - pas->pay_reference))) - TALER_TESTING_FAIL (pas->is); - - if (MHD_HTTP_OK == hr->http_status) - { - struct PaymentResponsePS mr; - /* Check signature */ - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_fixed_auto ("sig", - &sig), - GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &mr.h_contract_terms), - GNUNET_JSON_spec_end () - }; - - GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (hr->reply, - spec, - &error_name, - &error_line)); - mr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_PAYMENT_OK); - mr.purpose.size = htonl (sizeof (mr)); - - if (GNUNET_OK != - TALER_TESTING_get_trait_merchant_pub (pay_cmd, - 0, - &merchant_pub)) - TALER_TESTING_FAIL (pas->is); - - if (GNUNET_OK != - GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_PAYMENT_OK, - &mr, - &sig, - &merchant_pub->eddsa_pub)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Merchant signature given in" - " response to /pay invalid\n"); - TALER_TESTING_FAIL (pas->is); - } - } - - TALER_TESTING_interpreter_next (pas->is); -} - - -/** - * Run a "pay again" CMD. - * - * @param cls closure. - * @param cmd command currently being run. - * @param is interpreter state. - */ -static void -pay_again_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct PayAgainState *pas = cls; - const struct TALER_TESTING_Command *pay_cmd; - const char *proposal_reference; - const char *amount_with_fee; - const char *amount_without_fee; - - pas->is = is; - pay_cmd = TALER_TESTING_interpreter_lookup_command - (is, pas->pay_reference); - if (NULL == pay_cmd) - TALER_TESTING_FAIL (is); - - if (GNUNET_OK != TALER_TESTING_get_trait_proposal_reference - (pay_cmd, 0, &proposal_reference)) - TALER_TESTING_FAIL (is); - - if (GNUNET_OK != TALER_TESTING_get_trait_string - (pay_cmd, AMOUNT_WITH_FEE, &amount_with_fee)) - TALER_TESTING_FAIL (is); - - if (GNUNET_OK != TALER_TESTING_get_trait_string - (pay_cmd, AMOUNT_WITHOUT_FEE, &amount_without_fee)) - TALER_TESTING_FAIL (is); - - if (NULL == (pas->pao = _pay_run (pas->merchant_url, - pas->coin_reference, - proposal_reference, - is, - amount_with_fee, - amount_without_fee, - pas->refund_fee, - &pay_again_cb, - pas))) - TALER_TESTING_FAIL (is); -} - - -/** - * Free and possibly cancel a "pay again" CMD. - * - * @param cls closure. - * @param cmd command currently being freed. - */ -static void -pay_again_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct PayAgainState *pas = cls; - - if (NULL != pas->pao) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Command `%s' did not complete.\n", - TALER_TESTING_interpreter_get_current_label ( - pas->is)); - TALER_MERCHANT_pay_cancel (pas->pao); - } - GNUNET_free (pas); -} - - -/** - * Make a "pay again" test command. Its purpose is to - * take all the data from a aborted "pay" CMD, and use - * good coins - found in @a coin_reference - to correctly - * pay for it. - * - * @param label command label - * @param merchant_url merchant base URL - * @param pay_reference reference to the payment to replay - * @param coin_reference reference to the coins to use - * @param http_status expected HTTP response code - * - * @return the command - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_pay_again (const char *label, - const char *merchant_url, - const char *pay_reference, - const char *coin_reference, - const char *refund_fee, - unsigned int http_status) -{ - struct PayAgainState *pas; - - pas = GNUNET_new (struct PayAgainState); - pas->http_status = http_status; - pas->pay_reference = pay_reference; - pas->coin_reference = coin_reference; - pas->merchant_url = merchant_url; - pas->refund_fee = refund_fee; - { - struct TALER_TESTING_Command cmd = { - .cls = pas, - .label = label, - .run = &pay_again_run, - .cleanup = &pay_again_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_pay.c */ +/* end of testing_api_cmd_pay_order.c */ diff --git a/src/testing/testing_api_cmd_refund_increase.c b/src/testing/testing_api_cmd_refund_increase.c @@ -1,236 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2019 Taler Systems SA - - TALER is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 3, or - (at your option) any later version. - - TALER is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with TALER; see the file COPYING. If not, see - <http://www.gnu.org/licenses/> -*/ -/** - * @file lib/testing_api_cmd_refund_increase.c - * @brief command to test refunds. - * @author Marcello Stanisci - * @author Christian Grothoff - */ -#include "platform.h" -#include <taler/taler_exchange_service.h> -#include <taler/taler_testing_lib.h> -#include "taler_merchant_service.h" -#include "taler_merchant_testing_lib.h" - - -/** - * State for a "refund increase" CMD. - */ -struct RefundIncreaseState -{ - /** - * Operation handle for a POST /refund request. - */ - struct TALER_MERCHANT_RefundIncreaseOperation *rio; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Order id of the contract to refund. - */ - const char *order_id; - - /** - * The amount to refund. - */ - const char *refund_amount; - - /** - * Refund fee. - */ - const char *refund_fee; - - /** - * Human-readable justification for the refund. - */ - const char *reason; - - /** - * Interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Expected HTTP response code. - */ - unsigned int http_code; -}; - - -/** - * Free the state of a "refund increase" CMD, and - * possibly cancel a pending "refund increase" operation. - * - * @param cls closure - * @param cmd command currently being freed. - */ -static void -refund_increase_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct RefundIncreaseState *ris = cls; - - if (NULL != ris->rio) - { - TALER_LOG_WARNING ("Refund-increase operation" - " did not complete\n"); - TALER_MERCHANT_refund_increase_cancel (ris->rio); - } - GNUNET_free (ris); -} - - -/** - * Process POST /refund (increase) response; just checking - * if the HTTP response code is the one expected. - * - * @param cls closure - * @param hr HTTP response - */ -static void -refund_increase_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) -{ - struct RefundIncreaseState *ris = cls; - - ris->rio = NULL; - if (ris->http_code != hr->http_status) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Expected status %u, got %u(%d) for refund increase\n", - ris->http_code, - hr->http_status, - (int) hr->ec); - TALER_TESTING_FAIL (ris->is); - } - TALER_TESTING_interpreter_next (ris->is); -} - - -/** - * Run the "refund increase" CMD. - * - * @param cls closure. - * @param cmd command currently being run. - * @param is the interpreter state. - */ -static void -refund_increase_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct RefundIncreaseState *ris = cls; - struct TALER_Amount refund_amount; - - ris->is = is; - if (GNUNET_OK != TALER_string_to_amount (ris->refund_amount, - &refund_amount)) - TALER_TESTING_FAIL (is); - ris->rio = TALER_MERCHANT_refund_increase (is->ctx, - ris->merchant_url, - ris->order_id, - &refund_amount, - ris->reason, - &refund_increase_cb, - ris); - if (NULL == ris->rio) - TALER_TESTING_FAIL (is); -} - - -/** - * Offer internal data from the "refund increase" CMD - * state to other commands. - * - * @param cls closure - * @param ret[out] result (could be anything) - * @param trait name of the trait - * @param index index number of the object to extract. - * @return #GNUNET_OK on success - */ -static int -refund_increase_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct RefundIncreaseState *ris = cls; - struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_string (0, - ris->refund_amount), - TALER_TESTING_trait_end () - }; - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * Define a "refund increase" CMD. - * - * @param label command label. - * @param merchant_url base URL of the backend serving the - * "refund increase" request. - * @param reason refund justification, human-readable. - * @param order_id order id of the contract to refund. - * @param refund_amount amount to be refund-increased. - * @param refund_fee refund fee. - * @param http_code expected HTTP response code. - * - * @return the command. - */ -struct TALER_TESTING_Command -TALER_TESTING_cmd_refund_increase (const char *label, - const char *merchant_url, - const char *reason, - const char *order_id, - const char *refund_amount, - const char *refund_fee, - unsigned int http_code) -{ - struct RefundIncreaseState *ris; - - ris = GNUNET_new (struct RefundIncreaseState); - ris->merchant_url = merchant_url; - ris->order_id = order_id; - ris->refund_amount = refund_amount; - ris->refund_fee = refund_fee; - ris->reason = reason; - ris->http_code = http_code; - { - struct TALER_TESTING_Command cmd = { - .cls = ris, - .label = label, - .run = &refund_increase_run, - .cleanup = &refund_increase_cleanup, - .traits = &refund_increase_traits - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_refund_increase.c */ diff --git a/src/testing/testing_api_cmd_refund_order.c b/src/testing/testing_api_cmd_refund_order.c @@ -0,0 +1,227 @@ +/* + This file is part of TALER + Copyright (C) 2014-2019 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 3, or + (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/testing_api_cmd_refund_order.c + * @brief command to test refunds. + * @author Marcello Stanisci + * @author Christian Grothoff + */ +#include "platform.h" +#include <taler/taler_exchange_service.h> +#include <taler/taler_testing_lib.h> +#include "taler_merchant_service.h" +#include "taler_merchant_testing_lib.h" + + +/** + * State for a "refund increase" CMD. + */ +struct RefundState +{ + /** + * Operation handle for a POST /orders/$ID/refund request. + */ + struct TALER_MERCHANT_OrderRefundHandle *orh; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * Order id of the contract to refund. + */ + const char *order_id; + + /** + * The amount to refund. + */ + const char *refund_amount; + + /** + * Human-readable justification for the refund. + */ + const char *reason; + + /** + * Interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Expected HTTP response code. + */ + unsigned int http_code; +}; + + +/** + * Process POST /refund (increase) response; just checking + * if the HTTP response code is the one expected. + * + * @param cls closure + * @param hr HTTP response + */ +static void +refund_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct RefundState *ris = cls; + + ris->orh = NULL; + if (ris->http_code != hr->http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected status %u, got %u(%d) for refund increase\n", + ris->http_code, + hr->http_status, + (int) hr->ec); + TALER_TESTING_FAIL (ris->is); + } + TALER_TESTING_interpreter_next (ris->is); +} + + +/** + * Run the "refund increase" CMD. + * + * @param cls closure. + * @param cmd command currently being run. + * @param is the interpreter state. + */ +static void +refund_increase_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct RefundState *ris = cls; + struct TALER_Amount refund_amount; + + ris->is = is; + if (GNUNET_OK != + TALER_string_to_amount (ris->refund_amount, + &refund_amount)) + TALER_TESTING_FAIL (is); + ris->orh = TALER_MERCHANT_post_order_refund (is->ctx, + ris->merchant_url, + ris->order_id, + &refund_amount, + ris->reason, + &refund_cb, + ris); + if (NULL == ris->orh) + TALER_TESTING_FAIL (is); +} + + +/** + * Offer internal data from the "refund increase" CMD + * state to other commands. + * + * @param cls closure + * @param ret[out] result (could be anything) + * @param trait name of the trait + * @param index index number of the object to extract. + * @return #GNUNET_OK on success + */ +static int +refund_increase_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct RefundState *ris = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_string (0, + ris->refund_amount), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +/** + * Free the state of a "refund increase" CMD, and + * possibly cancel a pending "refund increase" operation. + * + * @param cls closure + * @param cmd command currently being freed. + */ +static void +refund_increase_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct RefundState *ris = cls; + + if (NULL != ris->orh) + { + TALER_LOG_WARNING ("Refund operation did not complete\n"); + TALER_MERCHANT_post_order_refund_cancel (ris->orh); + } + GNUNET_free (ris); +} + + +/** + * Define a "refund order" CMD. + * + * @param label command label. + * @param merchant_url base URL of the backend serving the + * "refund increase" request. + * @param reason refund justification, human-readable. + * @param order_id order id of the contract to refund. + * @param refund_amount amount to be refund-increased. + * @param http_code expected HTTP response code. + * @return the command. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_order_refund (const char *label, + const char *merchant_url, + const char *reason, + const char *order_id, + const char *refund_amount, + unsigned int http_code) +{ + struct RefundState *ris; + + ris = GNUNET_new (struct RefundState); + ris->merchant_url = merchant_url; + ris->order_id = order_id; + ris->refund_amount = refund_amount; + ris->reason = reason; + ris->http_code = http_code; + { + struct TALER_TESTING_Command cmd = { + .cls = ris, + .label = label, + .run = &refund_increase_run, + .cleanup = &refund_increase_cleanup, + .traits = &refund_increase_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_refund_order.c */