diff options
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 6 | ||||
-rw-r--r-- | src/lib/merchant_api_post_templates.c | 4 | ||||
-rw-r--r-- | src/testing/#testing_api_cmd_post_products.c# | 332 | ||||
-rw-r--r-- | src/testing/test_merchant_api.c | 6 | ||||
-rw-r--r-- | src/testing/test_merchant_template_creation.sh | 0 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_post_templates.c | 8 |
6 files changed, 343 insertions, 13 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 1e3de641..01a515b3 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -933,7 +933,7 @@ url_handler (void *cls, }, /* POST /templates: */ { - .url_prefix = "/templates/", + .url_prefix = "/templates", .method = MHD_HTTP_METHOD_POST, .handler = &TMH_private_post_templates, /* allow template data of up to 8 MB, that should be plenty; @@ -979,13 +979,13 @@ url_handler (void *cls, }, /* GET /webhooks: */ { - .url_prefix = "/webhooks/", + .url_prefix = "/webhooks", .method = MHD_HTTP_METHOD_GET, .handler = &TMH_private_get_webhooks }, /* POST /webhooks: */ { - .url_prefix = "/webhooks/", + .url_prefix = "/webhooks", .method = MHD_HTTP_METHOD_POST, .handler = &TMH_private_post_webhooks, /* allow webhook data of up to 8 MB, that should be plenty; diff --git a/src/lib/merchant_api_post_templates.c b/src/lib/merchant_api_post_templates.c index b4d286aa..002896ed 100644 --- a/src/lib/merchant_api_post_templates.c +++ b/src/lib/merchant_api_post_templates.c @@ -129,10 +129,6 @@ handle_post_templates_finished (void *cls, happen, we should pass the JSON reply to the application */ break; - case MHD_HTTP_CONFLICT: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); - break; case MHD_HTTP_INTERNAL_SERVER_ERROR: hr.ec = TALER_JSON_get_error_code (json); hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/testing/#testing_api_cmd_post_products.c# b/src/testing/#testing_api_cmd_post_products.c# new file mode 100644 index 00000000..be3c3071 --- /dev/null +++ b/src/testing/#testing_api_cmd_post_products.c# @@ -0,0 +1,332 @@ +/* + This file is part of TALER + Copyright (C) 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 + 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 testing_api_cmd_post_products.c + * @brief command to test POST /products + * @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 of a "POST /products" CMD. + */ +struct PostProductsState +{ + + /** + * Handle for a "GET product" request. + */ + struct TALER_MERCHANT_ProductsPostHandle *iph; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the product to run POST for. + */ + const char *product_id; + + /** + * description of the product + */ + const char *description; + + /** + * Map from IETF BCP 47 language tags to localized descriptions + */ + json_t *description_i18n; + + /** + * unit in which the product is measured (liters, kilograms, packages, etc.) + */ + const char *unit; + + /** + * the price for one @a unit of the product + */ + struct TALER_Amount price; + + /** + * base64-encoded product image + */ + char *image; + + /** + * list of taxes paid by the merchant + */ + json_t *taxes; + + /** + * in @e units, -1 to indicate "infinite" (i.e. electronic books) + */ + int64_t total_stock; + + /** + * where the product is in stock + */ + json_t *address; + + /** + * when the next restocking is expected to happen, 0 for unknown, + */ + struct GNUNET_TIME_Timestamp next_restock; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a POST /products operation. + * + * @param cls closure for this function + * @param hr response being processed + */ +static void +post_products_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct PostProductsState *pis = cls; + + pis->iph = NULL; + if (pis->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 (pis->is)); + TALER_TESTING_interpreter_fail (pis->is); + return; + } + switch (hr->http_status) + { + case MHD_HTTP_NO_CONTENT: + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_FORBIDDEN: + break; + case MHD_HTTP_NOT_FOUND: + break; + case MHD_HTTP_CONFLICT: + break; + default: + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u for POST /products.\n", + hr->http_status); + } + TALER_TESTING_interpreter_next (pis->is); +} + + +/** + * Run the "POST /products" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +post_products_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PostProductsState *pis = cls; + + pis->is = is; + pis->iph = TALER_MERCHANT_products_post (is->ctx, + pis->merchant_url, + pis->product_id, + pis->description, + pis->description_i18n, + pis->unit, + &pis->price, + pis->image, + pis->taxes, + pis->total_stock, + pis->address, + pis->next_restock, + &post_products_cb, + pis); + GNUNET_assert (NULL != pis->iph); +} + + +/** + * Offers information from the POST /products CMD state to other + * commands. + * + * @param cls closure + * @param[out] ret 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 +post_products_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct PostProductsState *pps = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_product_description (&pps->description), + TALER_TESTING_make_trait_i18n_description (pps->description_i18n), + TALER_TESTING_make_trait_product_unit (&pps->unit), + TALER_TESTING_make_trait_amount (&pps->price), + TALER_TESTING_make_trait_product_image ( + (const char **) &pps->image), + TALER_TESTING_make_trait_taxes (pps->taxes), + TALER_TESTING_make_trait_product_stock (&pps->total_stock), + TALER_TESTING_make_trait_address (pps->address), + TALER_TESTING_make_trait_timestamp (0, + &pps->next_restock), + TALER_TESTING_make_trait_product_id (&pps->product_id), + TALER_TESTING_trait_end (), + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +/** + * Free the state of a "POST product" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +post_products_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PostProductsState *pis = cls; + + if (NULL != pis->iph) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "POST /products operation did not complete\n"); + TALER_MERCHANT_products_post_cancel (pis->iph); + } + json_decref (pis->description_i18n); + GNUNET_free (pis->image); + json_decref (pis->taxes); + json_decref (pis->address); + GNUNET_free (pis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_products2 ( + const char *label, + const char *merchant_url, + const char *product_id, + const char *description, + json_t *description_i18n, + const char *unit, + const char *price, + const char *image, + json_t *taxes, + int64_t total_stock, + json_t *address, + struct GNUNET_TIME_Timestamp next_restock, + unsigned int http_status) +{ + struct PostProductsState *pis; + + GNUNET_assert ((NULL == taxes) || + json_is_array (taxes)); + GNUNET_assert ((NULL == description_i18n) || + json_is_object (description_i18n)); + pis = GNUNET_new (struct PostProductsState); + pis->merchant_url = merchant_url; + pis->product_id = product_id; + pis->http_status = http_status; + pis->description = description; + pis->description_i18n = description_i18n; /* ownership taken */ + pis->unit = unit; + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (price, + &pis->price)); + pis->image = GNUNET_strdup (image); + pis->taxes = taxes; /* ownership taken */ + pis->total_stock = total_stock; + pis->address = address; /* ownership taken */ + pis->next_restock = next_restock; + { + struct TALER_TESTING_Command cmd = { + .cls = pis, + .label = label, + .run = &post_products_run, + .cleanup = &post_products_cleanup, + .traits = &post_products_traits + }; + + return cmd; + } +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_products (const char *label, + const char *merchant_url, + const char *product_id, + const char *description, + const char *price, + unsigned int http_status) +{ + return TALER_TESTING_cmd_merchant_post_products2 ( + label, + merchant_url, + product_id, + description, + json_pack ("{s:s}", "en", description), + "test-unit", + price, + "", + json_array (), + 4, + json_pack ("{s:s}", "street", "my street"), + GNUNET_TIME_UNIT_ZERO_TS, + http_status); +} + + +/* end of testing_api_cmd_post_products.c */ diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index 1b7cba30..299e800c 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -1333,7 +1333,8 @@ run (void *cls, "template-2", "another template", "data:image/jpeg;base64,RAWDATA", - json_pack ("summary", + json_pack ("{s:s}", + "summary", "EUR:1"), MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_get_template ("get-template-t2", @@ -1351,7 +1352,8 @@ run (void *cls, "template-3", "nx updated template", "data:image/jpeg;base64,RAWDATA", - json_pack ("summary", + json_pack ("{s:s}", + "summary", "EUR:1"), MHD_HTTP_NOT_FOUND), TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty", diff --git a/src/testing/test_merchant_template_creation.sh b/src/testing/test_merchant_template_creation.sh deleted file mode 100644 index e69de29b..00000000 --- a/src/testing/test_merchant_template_creation.sh +++ /dev/null diff --git a/src/testing/testing_api_cmd_post_templates.c b/src/testing/testing_api_cmd_post_templates.c index 7bdd2e97..3708a467 100644 --- a/src/testing/testing_api_cmd_post_templates.c +++ b/src/testing/testing_api_cmd_post_templates.c @@ -110,8 +110,6 @@ post_templates_cb (void *cls, break; case MHD_HTTP_NOT_FOUND: break; - case MHD_HTTP_CONFLICT: - break; default: GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -220,6 +218,9 @@ TALER_TESTING_cmd_merchant_post_templates2 ( { struct PostTemplatesState *tis; + GNUNET_assert ((NULL == template_contract) || + json_is_object (template_contract)); + tis = GNUNET_new (struct PostTemplatesState); tis->merchant_url = merchant_url; tis->template_id = template_id; @@ -233,7 +234,6 @@ TALER_TESTING_cmd_merchant_post_templates2 ( .label = label, .run = &post_templates_run, .cleanup = &post_templates_cleanup, - .traits = &post_templates_traits }; @@ -255,7 +255,7 @@ TALER_TESTING_cmd_merchant_post_templates (const char *label, template_id, template_description, "", - json_pack ("{s:I}", "merchant", "1"), + json_pack ("{s:s}", "merchant", "Pay"), http_status); } |