diff options
Diffstat (limited to 'src/testing/testing_api_cmd_post_using_templates.c')
-rw-r--r-- | src/testing/testing_api_cmd_post_using_templates.c | 245 |
1 files changed, 244 insertions, 1 deletions
diff --git a/src/testing/testing_api_cmd_post_using_templates.c b/src/testing/testing_api_cmd_post_using_templates.c index 137c7df1..d8f2c0a9 100644 --- a/src/testing/testing_api_cmd_post_using_templates.c +++ b/src/testing/testing_api_cmd_post_using_templates.c @@ -44,6 +44,13 @@ struct PostUsingTemplatesState struct TALER_TESTING_Interpreter *is; /** + * The (initial) POST /orders/$ID/claim operation handle. + * The logic is such that after an order creation, + * we immediately claim the order. + */ + struct TALER_MERCHANT_OrderClaimHandle *och; + + /** * Base URL of the merchant serving the request. */ const char *merchant_url; @@ -64,12 +71,138 @@ struct PostUsingTemplatesState const char *template_ref; /** + * Order id. + */ + const char *order_id; + + /** + * The order id we expect the merchant to assign (if not NULL). + */ + const char *expected_order_id; + + /** + * Contract terms obtained from the backend. + */ + json_t *contract_terms; + + /** + * Order submitted to the backend. + */ + json_t *order_terms; + + /** + * Contract terms hash code. + */ + struct TALER_PrivateContractHashP h_contract_terms; + + /** + * Merchant signature over the orders. + */ + struct TALER_MerchantSignatureP merchant_sig; + + /** + * Merchant public key. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * The nonce. + */ + struct GNUNET_CRYPTO_EddsaPublicKey nonce; + + /** + * The claim token + */ + struct TALER_ClaimTokenP claim_token; + + /** + * Should the command also CLAIM the order? + */ + bool with_claim; + + /** + * If not NULL, the command should duplicate the request and verify the + * response is the same as in this command. + */ + const char *duplicate_of; + + /** + * Encoded key for the payment verification. + */ + const char **template_pos_key; + + /** * Expected HTTP response code. */ unsigned int http_status; }; +/** + * Used to fill the "orders" CMD state with backend-provided + * values. Also double-checks that the order was correctly + * created. + * + * @param cls closure + * @param hr HTTP response we got + * @param contract_terms contract terms of this order + * @param sig merchant's signature + * @param hash hash over the contract + */ +static void +orders_claim_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr, + const json_t *contract_terms, + const struct TALER_MerchantSignatureP *sig, + const struct TALER_PrivateContractHashP *hash) +{ + struct PostUsingTemplatesState *tis = cls; + struct TALER_MerchantPublicKeyP merchant_pub; + const char *error_name; + unsigned int error_line; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &merchant_pub), + GNUNET_JSON_spec_end () + }; + + tis->och = NULL; + if (tis->http_status != hr->http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected status %u, got %u\n", + tis->http_status, + hr->http_status); + TALER_TESTING_FAIL (tis->is); + } + + tis->contract_terms = json_deep_copy (contract_terms); + tis->h_contract_terms = *hash; + tis->merchant_sig = *sig; + if (GNUNET_OK != + GNUNET_JSON_parse (contract_terms, + spec, + &error_name, + &error_line)) + { + char *log; + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Parser failed on %s:%u\n", + error_name, + error_line); + log = json_dumps (tis->contract_terms, + JSON_INDENT (1)); + fprintf (stderr, + "%s\n", + log); + free (log); + TALER_TESTING_FAIL (tis->is); + } + tis->merchant_pub = merchant_pub; + TALER_TESTING_interpreter_next (tis->is); +} + /** * Callback for a POST /using-templates operation. @@ -94,6 +227,103 @@ post_using_templates_cb (void *cls, TALER_TESTING_interpreter_fail (tis->is); return; } + if (0 == tis->http_status) + { + TALER_LOG_DEBUG ("/using_templates, expected 0 status code\n"); + TALER_TESTING_interpreter_next (tis->is); + return; + } + // check the rest of the function to adapt to using_template + switch (por->hr.http_status) + { + case MHD_HTTP_OK: + if (NULL != por->details.ok.token) + tis->claim_token = *por->details.ok.token; + tis->order_id = GNUNET_strdup (por->details.ok.order_id); + if ((NULL != tis->expected_order_id) && + (0 != strcmp (por->details.ok.order_id, + tis->expected_order_id))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order id assigned does not match\n"); + TALER_TESTING_interpreter_fail (tis->is); + return; + } + if (NULL != tis->duplicate_of) + { + const struct TALER_TESTING_Command *order_cmd; + const struct TALER_ClaimTokenP *prev_token; + struct TALER_ClaimTokenP zero_token = {0}; + + order_cmd = TALER_TESTING_interpreter_lookup_command ( + tis->is, + tis->duplicate_of); + if (GNUNET_OK != + TALER_TESTING_get_trait_claim_token (order_cmd, + &prev_token)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not fetch previous order claim token\n"); + TALER_TESTING_interpreter_fail (tis->is); + return; + } + if (NULL == por->details.ok.token) + prev_token = &zero_token; + if (0 != GNUNET_memcmp (prev_token, + por->details.ok.token)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Claim tokens for identical requests do not match\n"); + TALER_TESTING_interpreter_fail (tis->is); + return; + } + } + break; + case MHD_HTTP_NOT_FOUND: + TALER_TESTING_interpreter_next (tis->is); + return; + case MHD_HTTP_GONE: + TALER_TESTING_interpreter_next (tis->is); + return; + case MHD_HTTP_CONFLICT: + TALER_TESTING_interpreter_next (tis->is); + return; + default: + { + char *s = json_dumps (por->hr.reply, + JSON_COMPACT); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected status code from /orders: %u (%d) at %s; JSON: %s\n", + por->hr.http_status, + (int) por->hr.ec, + TALER_TESTING_interpreter_get_current_label (tis->is), + s); + GNUNET_free (s); + /** + * Not failing, as test cases are _supposed_ + * to create non 200 OK situations. + */ + TALER_TESTING_interpreter_next (tis->is); + } + return; + } + + if (! tis->with_claim) + { + TALER_TESTING_interpreter_next (tis->is); + return; + } + if (NULL == + (tis->och = TALER_MERCHANT_order_claim (tis->is->ctx, + tis->merchant_url, + tis->order_id, + &tis->nonce, + &tis->claim_token, + &orders_claim_cb, + tis))) + TALER_TESTING_FAIL (tis->is); + + /* switch (por->hr.http_status) { case MHD_HTTP_OK: @@ -109,7 +339,7 @@ post_using_templates_cb (void *cls, por->hr.http_status); break; } - TALER_TESTING_interpreter_next (tis->is); + TALER_TESTING_interpreter_next (tis->is);*/ } @@ -137,6 +367,10 @@ post_using_templates_run (void *cls, TALER_TESTING_get_trait_template_id (ref, &template_id)) TALER_TESTING_FAIL (is); + if (GNUNET_OK != + TALER_TESTING_get_trait_template_pos_key (ref, + &tis->template_pos_key)) + TALER_TESTING_FAIL (is); tis->iph = TALER_MERCHANT_using_templates_post ( is->ctx, tis->merchant_url, @@ -169,6 +403,15 @@ post_using_templates_traits (void *cls, { struct PostUsingTemplatesState *pts = cls; struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_order_id (&pts->order_id), + TALER_TESTING_make_trait_contract_terms (pts->contract_terms), + TALER_TESTING_make_trait_order_terms (pts->order_terms), + TALER_TESTING_make_trait_h_contract_terms (&pts->h_contract_terms), + TALER_TESTING_make_trait_merchant_sig (&pts->merchant_sig), + TALER_TESTING_make_trait_merchant_pub (&pts->merchant_pub), + TALER_TESTING_make_trait_claim_nonce (&pts->nonce), + TALER_TESTING_make_trait_claim_token (&pts->claim_token), + TALER_TESTING_make_trait_template_pos_key (pts->template_pos_key), // extract from template creation CMD TALER_TESTING_trait_end (), }; |