diff options
author | priscilla <priscilla.huang@efrei.net> | 2023-02-03 08:38:40 -0500 |
---|---|---|
committer | priscilla <priscilla.huang@efrei.net> | 2023-02-03 08:38:48 -0500 |
commit | 17ce196e1259bdc2a0899e67e15cde204a2164ee (patch) | |
tree | ce237dc15e2d20e6007decca6548a7e47a3b61e3 /src | |
parent | d4d8114af921f713c4ba6ccde768f901f176b6b4 (diff) | |
download | merchant-17ce196e1259bdc2a0899e67e15cde204a2164ee.tar.gz merchant-17ce196e1259bdc2a0899e67e15cde204a2164ee.tar.bz2 merchant-17ce196e1259bdc2a0899e67e15cde204a2164ee.zip |
new test logic
Diffstat (limited to 'src')
-rw-r--r-- | src/include/taler_merchant_testing_lib.h | 40 | ||||
-rw-r--r-- | src/testing/Makefile.am | 2 | ||||
-rw-r--r-- | src/testing/test_merchant_api.c | 43 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_post_webhooks.c | 4 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_testserver.c | 353 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_webhook.c | 11 |
6 files changed, 444 insertions, 9 deletions
diff --git a/src/include/taler_merchant_testing_lib.h b/src/include/taler_merchant_testing_lib.h index c805afba..9ac15909 100644 --- a/src/include/taler_merchant_testing_lib.h +++ b/src/include/taler_merchant_testing_lib.h @@ -1767,6 +1767,46 @@ TALER_TESTING_cmd_merchant_delete_webhook (const char *label, const char *webhook_id, unsigned int http_status); +/** + * to use the 'taler-merchant-webhook' program. + * + * @param label command label. + * @param configuration file used by the webhook. + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_webhook (const char *label, + const char *config_filename); + + +/** + * This function is used to start the web server. + * + * @param label command label + * @param port is the port of the web server + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_testserver (const char *label, + uint16_t port); + + +/** + * This function is used to check the web server + * + * @param label command label + * @param url of the webhook + * @param http_method of the webhook + * @param header of the webhook + * @param body of the webhook + * @param port is the port of the web server + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_checkserver (const char *label, + char *url, + char *http_method, + char *header, + char *body, + uint16_t port); + /* ****** Specific traits supported by this component ******* */ diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 159b922e..74a818b7 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -76,6 +76,8 @@ libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_wallet_get_order.c \ testing_api_cmd_wallet_get_tip.c \ testing_api_cmd_wallet_post_orders_refund.c \ + testing_api_cmd_webhook.c \ + testing_api_cmd_testserver.c \ testing_api_helpers.c \ testing_api_traits.c diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index a04bbe57..03e03b1a 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -162,6 +162,18 @@ const char *order_1_forgets_3[] = { NULL }; +/** + * Execute the taler-merchant-webhook command with + * our configuration file. + * + * @param label label to use for the command. + */ +static struct TALER_TESTING_Command +cmd_webhook(const char *label) +{ + return TALER_TESTING_cmd_webhook (label, config_file); +} + /** * Execute the taler-exchange-wirewatch command with @@ -315,6 +327,13 @@ run (void *cls, "", "", NULL), + TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-pay-w1", + merchant_url, + "webhook-pay-1", + "pay", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_testserver ("launch-http-server-for-webhooks", + 12345), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1-idem", merchant_url, MHD_HTTP_OK, @@ -414,6 +433,16 @@ run (void *cls, MHD_HTTP_OK, NULL, "poll-order-wallet-start-1"), + /* Check for webhook */ + cmd_webhook ("pending-webhooks-pay-w1"), + /* FIXME: check webhook did anything: have a command that inspects traits of the testserver + and check if the traits have the right values set! */ + TALER_TESTING_cmd_checkserver ("check-http-server-for-webhooks", + "http://localhost:12345/", + "POST", + "Authorization:EFEHYJS", + "{{amount.val}}.{{amount.frac}} {{amount.currecy}}", + 12345), /* Here we expect to run into a timeout, as we do not pay this one */ TALER_TESTING_cmd_wallet_poll_order_conclude2 ("poll-order-1x-conclude", MHD_HTTP_PAYMENT_REQUIRED, @@ -658,6 +687,10 @@ run (void *cls, GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:5.0"), + /*TALER_TESTING_cmd_merchant_delete_webhook ("post-webhooks-pay-w1", + merchant_url, + "webhook-pay-1", + MHD_HTTP_NO_CONTENT),*/ TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"), TALER_TESTING_cmd_end () }; @@ -1425,7 +1458,7 @@ run (void *cls, MHD_HTTP_NOT_FOUND), TALER_TESTING_cmd_end () }; - + /* struct TALER_TESTING_Command webhooks[] = { TALER_TESTING_cmd_merchant_get_webhooks ("get-webhooks-empty", merchant_url, @@ -1465,7 +1498,7 @@ run (void *cls, merchant_url, "webhook-2", "Refund2", - "https://example.com", + "http://localhost:38188/", "POST", "Authorization:WHWOXZXPLL", "Amount", @@ -1499,7 +1532,7 @@ run (void *cls, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_end () }; - + */ struct TALER_TESTING_Command commands[] = { /* general setup */ @@ -1853,8 +1886,8 @@ run (void *cls, auth), TALER_TESTING_cmd_batch ("templates", templates), - TALER_TESTING_cmd_batch ("webhooks", - webhooks), + /* TALER_TESTING_cmd_batch ("webhooks", + webhooks),*/ /** * End the suite. */ diff --git a/src/testing/testing_api_cmd_post_webhooks.c b/src/testing/testing_api_cmd_post_webhooks.c index 9f7c36b7..77ab1213 100644 --- a/src/testing/testing_api_cmd_post_webhooks.c +++ b/src/testing/testing_api_cmd_post_webhooks.c @@ -268,10 +268,10 @@ TALER_TESTING_cmd_merchant_post_webhooks (const char *label, merchant_url, webhook_id, event_type, - "https://example.com", + "http://localhost:12345/", "POST", "Authorization:EFEHYJS", - "$amount", + "{{amount.val}}.{{amount.frac}} {{amount.currecy}}", http_status); } diff --git a/src/testing/testing_api_cmd_testserver.c b/src/testing/testing_api_cmd_testserver.c new file mode 100644 index 00000000..c480e8db --- /dev/null +++ b/src/testing/testing_api_cmd_testserver.c @@ -0,0 +1,353 @@ +/* + This file is part of TALER + Copyright (C) 2021 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/testing_api_cmd_testserver.c + * @brief Implement a CMD to run an Testserver service for faking the legitimation service + * @author Priscilla HUANG + */ +#include "platform.h" +#include "taler/taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler/taler_testing_lib.h" +#include "taler/taler_mhd_lib.h" +#include "taler_merchant_testing_lib.h" +#include "taler_merchant_service.h" +#include <taler/taler_exchange_service.h> + +/** + * State for the testserver CMD. + */ +struct TestserverState +{ + + /** + * Handle to the "testserver" service. + */ + struct MHD_Daemon *mhd; + + /** + * Port to listen on. + */ + uint16_t port; + + // FIXME: record URL, HTTP method, HTTP headers, HTTP body here! + /** + * URL where we are redirect. + */ + const char *url; + + /** + * http method of the webhook. + */ + const char *http_method; + + /** + * header of the webhook. + */ + const char *header; + + /** + * body of the webhook. + */ + const char *body; + // => expose as trait +}; + + +struct RequestCtx +{ + struct MHD_PostProcessor *pp; +}; + + +static MHD_RESULT +handle_post (void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size) +{ + struct RequestCtx *rc = cls; + + (void) kind; + (void) filename; + (void) content_type; + (void) transfer_encoding; + (void) off; + return MHD_YES; +} + + +/** + * A client has requested the given url using the given method + * (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT, + * #MHD_HTTP_METHOD_DELETE, #MHD_HTTP_METHOD_POST, etc). The callback + * must call MHD callbacks to provide content to give back to the + * client and return an HTTP status code (i.e. #MHD_HTTP_OK, + * #MHD_HTTP_NOT_FOUND, etc.). + * + * @param cls argument given together with the function + * pointer when the handler was registered with MHD + * @param connection the connection being handled + * @param url the requested url + * @param method the HTTP method used (#MHD_HTTP_METHOD_GET, + * #MHD_HTTP_METHOD_PUT, etc.) + * @param version the HTTP version string (i.e. + * MHD_HTTP_VERSION_1_1) + * @param upload_data the data being uploaded (excluding HEADERS, + * for a POST that fits into memory and that is encoded + * with a supported encoding, the POST data will NOT be + * given in upload_data and is instead available as + * part of MHD_get_connection_values(); very large POST + * data *will* be made available incrementally in + * @a upload_data) + * @param[in,out] upload_data_size set initially to the size of the + * @a upload_data provided; the method must update this + * value to the number of bytes NOT processed; + * @param[in,out] con_cls pointer that the callback can set to some + * address and that will be preserved by MHD for future + * calls for this request; since the access handler may + * be called many times (i.e., for a PUT/POST operation + * with plenty of upload data) this allows the application + * to easily associate some request-specific state. + * If necessary, this state can be cleaned up in the + * global MHD_RequestCompletedCallback (which + * can be set with the #MHD_OPTION_NOTIFY_COMPLETED). + * Initially, `*con_cls` will be NULL. + * @return #MHD_YES if the connection was handled successfully, + * #MHD_NO if the socket must be closed due to a serious + * error while handling the request + */ +static MHD_RESULT +handler_cb (void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **con_cls) +{ + struct RequestCtx *rc = *con_cls; + json_t *body; + + (void) cls; + (void) version; + if (0 == strcasecmp (method, + MHD_HTTP_METHOD_GET)) + { + body = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "status", + "success")); + return TALER_MHD_reply_json_steal (connection, + body, + MHD_HTTP_OK); + } + if (0 != strcasecmp (method, + MHD_HTTP_METHOD_POST)) + { + GNUNET_break (0); + return MHD_NO; + } + if (NULL == rc) + { + rc = GNUNET_new (struct RequestCtx); + *con_cls = rc; + rc->pp = MHD_create_post_processor (connection, + 12345, + &handle_post, + rc); + return MHD_YES; + } + if (0 != *upload_data_size) + { + MHD_RESULT ret; + + ret = MHD_post_process (rc->pp, + upload_data, + *upload_data_size); + *upload_data_size = 0; + return ret; + } + + body = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("something", + "good")); + return TALER_MHD_reply_json_steal (connection, + body, + MHD_HTTP_OK); +} + + +static void +cleanup (void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + struct RequestCtx *rc = *con_cls; + + (void) cls; + (void) connection; + (void) toe; + if (NULL == rc) + return; + GNUNET_free (rc); +} + + +/** + * Run the command. + * + * @param cls closure. + * @param cmd the command to execute. + * @param is the interpreter state. + */ +static void +testserver_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct TestserverState *ser = cls; + + (void) cmd; + ser->mhd = MHD_start_daemon (MHD_USE_AUTO_INTERNAL_THREAD, + ser->port, + NULL, NULL, + &handler_cb, ser, + MHD_OPTION_NOTIFY_COMPLETED, &cleanup, NULL, + NULL); + TALER_TESTING_interpreter_next (is); +} + + +/** + * Cleanup the state from a "testserver" CMD, and possibly cancel a operation + * thereof. + * + * @param cls closure. + * @param cmd the command which is being cleaned up. + */ +static void +testserver_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct TestserverState *ser = cls; + + (void) cmd; + if (NULL != ser->mhd) + { + MHD_stop_daemon (ser->mhd); + ser->mhd = NULL; + } + GNUNET_free (ser); +} + +static int +traits_testserver (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct TestserverState *ser = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_url (&ser->url), + TALER_TESTING_make_trait_http_method (&ser->http_method), + TALER_TESTING_make_trait_header_template (&ser->header), + TALER_TESTING_make_trait_body_template (&ser->body), + TALER_TESTING_trait_end (), + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + +/** + * This function is used to start the web server. + * + * @param label command label + * @param port is the port of the web server + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_testserver (const char *label, + uint16_t port) +{ + struct TestserverState *ser; + + ser = GNUNET_new (struct TestserverState); + ser->port = port; + { + struct TALER_TESTING_Command cmd = { + .cls = ser, + .label = label, + .run = &testserver_run, + .cleanup = &testserver_cleanup + }; + + return cmd; + } +} + +/** + * This function is used to check the web server + * + * @param label command label + * @param url of the webhook + * @param http_method of the webhook + * @param header of the webhook + * @param body of the webhook + * @param port is the port of the web server + */ +struct TALER_TESTING_Command +TALER_TESTING_cmd_checkserver (const char *label, + char *url, + char *http_method, + char *header, + char *body, + uint16_t port) +{ + struct TestserverState *ser; + + ser = GNUNET_new (struct TestserverState); + ser->url = url; + ser->http_method = http_method; + ser->header = header; + ser->body = body; + ser->port = port; + { + struct TALER_TESTING_Command cmd= { + .cls = ser, + .label = label, + .traits = &traits_testserver + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_testserver.c */ diff --git a/src/testing/testing_api_cmd_webhook.c b/src/testing/testing_api_cmd_webhook.c index fc94495c..e73f3502 100644 --- a/src/testing/testing_api_cmd_webhook.c +++ b/src/testing/testing_api_cmd_webhook.c @@ -64,8 +64,8 @@ webhook_run (void *cls, ws->webhook_proc = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, NULL, NULL, NULL, - "taler-merchant-webhook.c", - "taler-merchant-webhook.c", + "taler-merchant-webhook", + "taler-merchant-webhook", "-c", ws->config_filename, "-t", /* exit when done */ "-L", "DEBUG", @@ -135,6 +135,13 @@ webhook_traits (void *cls, } + +/** + * to use the 'taler-merchant-webhook' program. + * + * @param label command label. + * @param configuration file used by the webhook. + */ struct TALER_TESTING_Command TALER_TESTING_cmd_webhook (const char *label, const char *config_filename) |