From a4f0dcb22839000eb5f3d31158986403d23a7c6a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 3 May 2020 15:06:13 +0200 Subject: update testing logic for order CMDs --- src/testing/testing_api_cmd_pay_order.c | 480 ++++++-------------------------- 1 file changed, 81 insertions(+), 399 deletions(-) (limited to 'src/testing/testing_api_cmd_pay_order.c') diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c index 02bdf408..dbffe4fa 100644 --- 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 */ - /** - * @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 #include @@ -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 */ -- cgit v1.2.3