/*
This file is part of TALER
Copyright (C) 2014-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
*/
/**
* @file lib/test_merchant_api.c
* @brief testcase to test exchange's HTTP API interface
* @author Sree Harsha Totakura
* @author Christian Grothoff
* @author Marcello Stanisci
*/
#include "platform.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "taler_merchant_testing_lib.h"
/**
* Configuration file we use. One (big) configuration is used
* for the various components for this test.
*/
#define CONFIG_FILE "test_merchant_api.conf"
#define PAYTO_I1 "payto://x-taler-bank/localhost/3"
/**
* Exchange base URL. Could also be taken from config.
*/
#define EXCHANGE_URL "http://localhost:8081/"
static const char *pickup_amounts_1[] = {"EUR:5", NULL};
static const char *pickup_amounts_2[] = {"EUR:0.01", NULL};
/**
* Payto URI of the customer (payer).
*/
static char *payer_payto;
/**
* Payto URI of the exchange (escrow account).
*/
static char *exchange_payto;
/**
* Payto URI of the merchant (receiver).
*/
static char *merchant_payto;
/**
* Configuration of the bank.
*/
static struct TALER_TESTING_BankConfiguration bc;
/**
* Configuration of the exchange.
*/
static struct TALER_TESTING_ExchangeConfiguration ec;
/**
* Merchant base URL.
*/
static char *merchant_url;
/**
* Merchant process.
*/
static struct GNUNET_OS_Process *merchantd;
/**
* Account number of the exchange at the bank.
*/
#define EXCHANGE_ACCOUNT_NAME "2"
/**
* Account number of some user.
*/
#define USER_ACCOUNT_NAME "62"
/**
* Account number of some other user.
*/
#define USER_ACCOUNT_NAME2 "63"
/**
* Account number used by the merchant
*/
#define MERCHANT_ACCOUNT_NAME "3"
/**
* Payto URIs to use for testing accounts on the merchant.
*/
const char *payto_uris[] = {
PAYTO_I1,
"payto://sepa/CH9300762011623852957" /* Just for testing account
inactivation. */
};
/**
* Execute the taler-exchange-wirewatch command with
* our configuration file.
*
* @param label label to use for the command.
*/
static struct TALER_TESTING_Command
cmd_exec_wirewatch (char *label)
{
return TALER_TESTING_cmd_exec_wirewatch (label, CONFIG_FILE);
}
/**
* Execute the taler-exchange-aggregator, closer and transfer commands with
* our configuration file.
*
* @param label label to use for the command.
*/
#define CMD_EXEC_AGGREGATOR(label) \
TALER_TESTING_cmd_exec_aggregator (label "-aggregator", CONFIG_FILE), \
TALER_TESTING_cmd_exec_transfer (label "-transfer", CONFIG_FILE)
/**
* Run wire transfer of funds from some user's account to the
* exchange.
*
* @param label label to use for the command.
* @param amount amount to transfer, i.e. "EUR:1"
* @param url exchange_url
*/
static struct TALER_TESTING_Command
cmd_transfer_to_exchange (const char *label,
const char *amount)
{
return TALER_TESTING_cmd_admin_add_incoming (label,
amount,
&bc.exchange_auth,
payer_payto);
}
/**
* Main function that will tell the interpreter what commands to
* run.
*
* @param cls closure
*/
static void
run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
const char *order_1_transfers[] = {
"post-transfer-1",
NULL
};
struct TALER_TESTING_Command get_private_order_id[] = {
TALER_TESTING_cmd_merchant_post_instances ("instance-create-default",
merchant_url,
"default",
PAYTO_I1,
"EUR",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_orders_no_claim ("create-proposal-4",
merchant_url,
MHD_HTTP_OK,
"1",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_merchant_get_order ("get-order-4",
merchant_url,
"create-proposal-4",
false,
false,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_purge_instance ("purge-default",
merchant_url,
"default",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command pay[] = {
/**
* Move money to the exchange's bank account.
*/
cmd_transfer_to_exchange ("create-reserve-1",
"EUR:10.02"),
/**
* Make a reserve exist,
* according to the previous
* transfer.
*///
cmd_exec_wirewatch ("wirewatch-1"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2",
"EUR:10.02",
payer_payto,
exchange_payto,
"create-reserve-1"),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
"create-reserve-1",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
"create-reserve-1",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_get_orders ("get-orders-empty",
merchant_url,
MHD_HTTP_OK,
NULL),
/**
* Check the reserve is depleted.
*/
TALER_TESTING_cmd_status ("withdraw-status-1",
"create-reserve-1",
"EUR:0",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_delete_order ("delete-order-nx",
merchant_url,
"1",
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_poll_orders_start ("poll-orders-1-start",
merchant_url,
GNUNET_TIME_UNIT_MINUTES),
TALER_TESTING_cmd_merchant_claim_order ("claim-order-nx",
merchant_url,
MHD_HTTP_NOT_FOUND,
NULL,
"1"),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1",
merchant_url,
MHD_HTTP_OK,
"1",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_merchant_claim_order ("reclaim-1",
merchant_url,
MHD_HTTP_OK,
"create-proposal-1",
NULL),
TALER_TESTING_cmd_merchant_claim_order ("reclaim-1-bad-nonce",
merchant_url,
MHD_HTTP_CONFLICT,
NULL,
"1"),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1-pre-exists",
merchant_url,
MHD_HTTP_BAD_REQUEST,
"1",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_poll_orders_conclude ("poll-orders-1-conclude",
MHD_HTTP_OK,
"poll-orders-1-start"),
TALER_TESTING_cmd_merchant_get_orders ("get-orders-1",
merchant_url,
MHD_HTTP_OK,
"create-proposal-1",
NULL),
TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1",
merchant_url,
"create-proposal-1",
false,
false,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1",
merchant_url,
"create-proposal-1",
false,
false,
MHD_HTTP_OK),
TALER_TESTING_cmd_poll_order_start ("poll-order-merchant-1-start",
merchant_url,
"1",
GNUNET_TIME_UNIT_MINUTES),
TALER_TESTING_cmd_merchant_pay_order ("deposit-simple",
merchant_url,
MHD_HTTP_OK,
"create-proposal-1",
"withdraw-coin-1",
"EUR:5",
"EUR:4.99"),
TALER_TESTING_cmd_poll_order_conclude ("poll-order-merchant-1-conclude",
MHD_HTTP_OK,
"poll-order-merchant-1-start"),
TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2",
merchant_url,
"create-proposal-1",
true,
false,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2",
merchant_url,
"create-proposal-1",
true,
false,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_pay_order ("replay-simple",
merchant_url,
MHD_HTTP_OK,
"create-proposal-1",
"withdraw-coin-1",
"EUR:5",
"EUR:4.99"),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"),
CMD_EXEC_AGGREGATOR ("run-aggregator"),
TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-498c",
EXCHANGE_URL,
"EUR:4.98",
exchange_payto,
merchant_payto),
TALER_TESTING_cmd_merchant_post_transfer ("post-transfer-1",
&bc.exchange_auth,
PAYTO_I1,
merchant_url,
"EUR:4.98",
MHD_HTTP_OK,
"deposit-simple",
NULL),
TALER_TESTING_cmd_merchant_get_transfers ("get-transfers-1",
merchant_url,
PAYTO_I1,
MHD_HTTP_OK,
"post-transfer-1",
NULL),
TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-2",
merchant_url,
"create-proposal-1",
true,
true,
order_1_transfers,
false,
NULL,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_post_products ("post-products-p3",
merchant_url,
"product-3",
"a product",
"EUR:1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3",
merchant_url,
"product-3",
"a product",
json_object (),
"can",
"EUR:1",
json_object (),
json_object (),
5,
0,
json_object (),
GNUNET_TIME_relative_to_absolute (
GNUNET_TIME_UNIT_MINUTES),
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_lock_product ("lock-product-p3",
merchant_url,
"product-3",
GNUNET_TIME_UNIT_MINUTES,
2,
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-wm-nx",
merchant_url,
MHD_HTTP_NOT_FOUND,
"order-p3",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0",
"unsupported-wire-method",
"product-3/2",
""),
TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-pd-nx",
merchant_url,
MHD_HTTP_NOT_FOUND,
"order-p3",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0",
"x-taler-bank",
"unknown-product/2",
""),
TALER_TESTING_cmd_merchant_post_orders2 (
"create-proposal-p3-not-enough-stock",
merchant_url,
MHD_HTTP_GONE,
"order-p3",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0",
"x-taler-bank",
"product-3/24",
""),
TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3",
merchant_url,
MHD_HTTP_OK,
"order-p3",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0",
"x-taler-bank",
"product-3/3",
"lock-product-p3"),
TALER_TESTING_cmd_merchant_delete_order ("delete-order-1",
merchant_url,
"1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-no-id",
merchant_url,
MHD_HTTP_OK,
NULL,
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command double_spending[] = {
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2",
merchant_url,
MHD_HTTP_OK,
"2",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_merchant_claim_order ("fetch-proposal-2",
merchant_url,
MHD_HTTP_OK,
"create-proposal-2",
NULL),
TALER_TESTING_cmd_merchant_pay_order ("deposit-double-2",
merchant_url,
MHD_HTTP_CONFLICT,
"create-proposal-2",
"withdraw-coin-1",
"EUR:5",
"EUR:4.99"),
#if 0
TALER_TESTING_cmd_history ("history-0",
merchant_url,
MHD_HTTP_OK,
/**
* all records to be returned; setting date as 0 lets the
* interpreter set it as 'now' + one hour delta, just to
* make sure it surpasses the proposal's timestamp.
*/GNUNET_TIME_UNIT_ZERO_ABS,
/**
* We only expect ONE result (create-proposal-1) to be
* included in /history response, because create-proposal-3
* did NOT go through because of double spending.
*/1, // nresult
10, // start
-10), // nrows
#endif
TALER_TESTING_cmd_end ()
};
const char *order_1r_refunds[] = {
"refund-increase-1r",
NULL
};
struct TALER_TESTING_Command refund[] = {
cmd_transfer_to_exchange ("create-reserve-1r",
"EUR:10.02"),
/**
* Make a reserve exist, according to the previous transfer.
*///
cmd_exec_wirewatch ("wirewatch-1r"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2r",
"EUR:10.02",
payer_payto,
exchange_payto,
"create-reserve-1r"),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1r",
"create-reserve-1r",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2r",
"create-reserve-1r",
"EUR:5",
MHD_HTTP_OK),
/**
* Check the reserve is depleted.
*/
TALER_TESTING_cmd_status ("withdraw-status-1r",
"create-reserve-1r",
"EUR:0",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1r",
merchant_url,
MHD_HTTP_OK,
"1r",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_merchant_pay_order ("pay-for-refund-1r",
merchant_url,
MHD_HTTP_OK,
"create-proposal-1r",
"withdraw-coin-1r",
"EUR:5",
"EUR:4.99"),
#if 0
TALER_TESTING_cmd_poll_payment_start ("poll-payment-refund-1",
merchant_url,
"create-proposal-1r",
"EUR:0.0",
GNUNET_TIME_UNIT_MINUTES),
#endif
TALER_TESTING_cmd_merchant_order_refund ("refund-increase-1r",
merchant_url,
"refund test",
"1r", /* order ID */
"EUR:0.1",
MHD_HTTP_OK),
TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r",
merchant_url,
"create-proposal-1r",
true,
true,
MHD_HTTP_OK,
"refund-increase-1r",
NULL),
TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1r",
merchant_url,
"create-proposal-1r",
true,
true,
MHD_HTTP_OK,
"refund-increase-1r",
NULL),
TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1r-2",
merchant_url,
"create-proposal-1r",
true,
false,
NULL,
true,
order_1r_refunds,
MHD_HTTP_OK),
#if 0
TALER_TESTING_cmd_poll_payment_conclude ("poll-payment-refund-conclude-1",
MHD_HTTP_OK,
"poll-payment-refund-1",
GNUNET_YES),
/* Ordinary refund. */
TALER_TESTING_cmd_refund_lookup ("refund-lookup-1r",
merchant_url,
"refund-increase-1r",
"pay-for-refund-1r",
"1r",
MHD_HTTP_OK),
/* Trying to pick up refund from non existent proposal. */
TALER_TESTING_cmd_refund_lookup ("refund-lookup-non-existent",
merchant_url,
"refund-increase-1r",
"deposit-simple",
"non-existend-id",
MHD_HTTP_NOT_FOUND),
#endif
/* Test /refund on a contract that was never paid. */
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-not-to-be-paid",
merchant_url,
MHD_HTTP_OK,
"1-unpaid",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
/* Try to increase a non paid proposal. */
TALER_TESTING_cmd_merchant_order_refund ("refund-increase-unpaid-proposal",
merchant_url,
"refund test",
"1-unpaid",
"EUR:0.1",
MHD_HTTP_CONFLICT),
/* Try to increase a non existent proposal. */
TALER_TESTING_cmd_merchant_order_refund (
"refund-increase-nonexistent-proposal",
merchant_url,
"refund test",
"non-existent-id",
"EUR:0.1",
MHD_HTTP_NOT_FOUND),
/*
The following block will (1) create a new
reserve, then (2) a proposal, then (3) pay for
it, and finally (4) attempt to pick up a refund
from it without any increasing taking place
in the first place.
*///
cmd_transfer_to_exchange ("create-reserve-unincreased-refund",
"EUR:5.01"),
cmd_exec_wirewatch ("wirewatch-unincreased-refund"),
TALER_TESTING_cmd_check_bank_admin_transfer (
"check_bank_transfer-unincreased-refund",
"EUR:5.01",
payer_payto,
exchange_payto,
"create-reserve-unincreased-refund"),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-unincreased-refund",
"create-reserve-unincreased-refund",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_post_orders (
"create-proposal-unincreased-refund",
merchant_url,
MHD_HTTP_OK,
"unincreased-proposal",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:5.0"),
TALER_TESTING_cmd_merchant_pay_order ("pay-unincreased-proposal",
merchant_url,
MHD_HTTP_OK,
"create-proposal-unincreased-refund",
"withdraw-coin-unincreased-refund",
"EUR:5",
"EUR:4.99"),
CMD_EXEC_AGGREGATOR ("run-aggregator-unincreased-refund"),
TALER_TESTING_cmd_check_bank_transfer (
"check_bank_transfer-paid-unincreased-refund",
EXCHANGE_URL,
"EUR:9.88", /* '4.98 from above', plus 4.99 from 'pay-for-refund-1r'
and MINUS 0.1 PLUS 0.01 (deposit fee) from 'refund-increase-1r' */
exchange_payto,
merchant_payto),
/* Actually try to pick up the refund from the "unincreased proposal". */
#if 0
TALER_TESTING_cmd_refund_lookup_with_amount ("refund-lookup-unincreased",
merchant_url,
NULL,
"pay-unincreased-proposal",
"unincreased-proposal",
MHD_HTTP_NOT_FOUND,
/* If a lookup is attempted
* on an unincreased
* proposal, the backend will
* simply respond with a
* empty refunded coin "set",
* but the HTTP response code
* is 200 OK. *///
"EUR:0"),
#endif
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command tip[] = {
TALER_TESTING_cmd_merchant_post_reserves ("create-reserve-tip-1",
merchant_url,
"EUR:20.04",
EXCHANGE_URL,
"x-taler-bank",
MHD_HTTP_OK),
TALER_TESTING_cmd_admin_add_incoming_with_ref ("create-reserve-tip-1-exch",
"EUR:20.04",
&bc.exchange_auth,
payer_payto,
"create-reserve-tip-1"),
cmd_exec_wirewatch ("wirewatch-3"),
/* Sleep so the merchant discovers that the reserve exists at the exchange
before trying to authorize a tip. */
TALER_TESTING_cmd_sleep ("wait-reserve-1",
1),
TALER_TESTING_cmd_tip_authorize ("authorize-tip-1",
merchant_url,
EXCHANGE_URL,
MHD_HTTP_OK,
"tip 1",
"EUR:5.01"),
TALER_TESTING_cmd_tip_authorize_from_reserve ("authorize-tip-2",
merchant_url,
EXCHANGE_URL,
"create-reserve-tip-1",
MHD_HTTP_OK,
"tip 2",
"EUR:5.01"),
TALER_TESTING_cmd_wallet_get_tip ("get-tip-1",
merchant_url,
"authorize-tip-1",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_get_tip ("merchant-get-tip-1",
merchant_url,
"authorize-tip-1",
MHD_HTTP_OK),
TALER_TESTING_cmd_get_tips ("get-tips-1",
merchant_url,
MHD_HTTP_OK,
"authorize-tip-2",
"authorize-tip-1",
NULL),
TALER_TESTING_cmd_get_tips2 ("get-tips-1-asc",
merchant_url,
0,
20,
MHD_HTTP_OK,
"authorize-tip-1",
"authorize-tip-2",
NULL),
TALER_TESTING_cmd_get_tips2 ("get-tips-1-asc-offset",
merchant_url,
1,
20,
MHD_HTTP_OK,
"authorize-tip-2",
NULL),
TALER_TESTING_cmd_merchant_get_reserves ("get-reserves-1",
merchant_url,
MHD_HTTP_OK,
"create-reserve-tip-1",
NULL),
TALER_TESTING_cmd_merchant_get_reserve ("get-reserve-1",
merchant_url,
MHD_HTTP_OK,
"create-reserve-tip-1"),
TALER_TESTING_cmd_merchant_get_reserve_with_tips ("get-reserve-2",
merchant_url,
MHD_HTTP_OK,
"create-reserve-tip-1",
"authorize-tip-1",
"authorize-tip-2",
NULL),
TALER_TESTING_cmd_tip_pickup ("pickup-tip-1",
merchant_url,
MHD_HTTP_OK,
"authorize-tip-1",
pickup_amounts_1),
TALER_TESTING_cmd_wallet_get_tip2 ("query-tip-2",
merchant_url,
"authorize-tip-1",
"EUR:0.01",
MHD_HTTP_OK),
TALER_TESTING_cmd_tip_pickup ("pickup-tip-2",
merchant_url,
MHD_HTTP_OK,
"authorize-tip-2",
pickup_amounts_1),
TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-tip-3-too-much",
merchant_url,
MHD_HTTP_BAD_REQUEST,
"authorize-tip-1",
pickup_amounts_1,
TALER_EC_TIP_PICKUP_AMOUNT_EXCEEDS_TIP_REMAINING),
TALER_TESTING_cmd_tip_pickup ("pickup-tip-4",
merchant_url,
MHD_HTTP_OK,
"authorize-tip-1",
pickup_amounts_2),
TALER_TESTING_cmd_merchant_get_tip_with_pickups ("merchant-get-tip-2",
merchant_url,
"authorize-tip-1",
MHD_HTTP_OK,
"pickup-tip-1",
"pickup-tip-4",
NULL),
/* This command tests the authorization of tip
* against a reserve that does not exist. This is
* implemented by passing a "tip instance" that
* specifies a reserve key that was never used to
* actually create a reserve. *///
TALER_TESTING_cmd_merchant_post_reserves_fake ("create-reserve-tip-2-fake"),
TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec ("authorize-tip-null",
merchant_url,
EXCHANGE_URL,
"create-reserve-tip-2-fake",
MHD_HTTP_NOT_FOUND,
"tip 3",
"EUR:5.01",
TALER_EC_TIP_AUTHORIZE_DB_RESERVE_NOT_FOUND),
// Test reserve with insufficient funds
TALER_TESTING_cmd_merchant_post_reserves ("create-reserve-tip-2",
merchant_url,
"EUR:1.04",
EXCHANGE_URL,
"x-taler-bank",
MHD_HTTP_OK),
TALER_TESTING_cmd_admin_add_incoming_with_ref ("create-reserve-tip-2-exch",
"EUR:1.04",
&bc.exchange_auth,
payer_payto,
"create-reserve-tip-2"),
cmd_exec_wirewatch ("wirewatch-4"),
TALER_TESTING_cmd_sleep ("wait-reserve-2",
1),
TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec (
"authorize-tip-insufficient-funds",
merchant_url,
EXCHANGE_URL,
"create-reserve-tip-2",
MHD_HTTP_PRECONDITION_FAILED,
"tip 4",
"EUR:5.01",
TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS),
TALER_TESTING_cmd_tip_authorize_fake ("fake-tip-authorization"),
TALER_TESTING_cmd_tip_pickup_with_ec ("pickup-non-existent-id",
merchant_url,
MHD_HTTP_NOT_FOUND,
"fake-tip-authorization",
pickup_amounts_1,
TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN),
TALER_TESTING_cmd_merchant_get_reserves ("get-reserves-2",
merchant_url,
MHD_HTTP_OK,
"create-reserve-tip-1",
"create-reserve-tip-2",
NULL),
TALER_TESTING_cmd_merchant_delete_reserve ("delete-reserve-tip-1",
merchant_url,
"create-reserve-tip-1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-2",
merchant_url,
"create-reserve-tip-1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_purge_reserve ("delete-reserve-tip-3",
merchant_url,
"create-reserve-tip-1",
MHD_HTTP_NOT_FOUND),
#if 0
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-tip-1",
merchant_url_internal ("tip"),
MHD_HTTP_OK,
"{\"max_fee\":\"EUR:0.5\",\
\"order_id\":\"1-tip\", \
\"refund_deadline\":{\"t_ms\":0},\
\"pay_deadline\":{\"t_ms\":\"never\"},\
\"amount\":\"EUR:5.0\",\
\"summary\": \"useful product\",\
\"fulfillment_url\": \"https://example.com/\",\
\"products\": [ {\"description\":\"ice cream\",\
\"value\":\"{EUR:5}\"} ] }"),
TALER_TESTING_cmd_merchant_pay_order ("deposit-tip-simple",
merchant_url_external ("tip"),
MHD_HTTP_OK,
"create-proposal-tip-1",
"pickup-tip-1",
"EUR:5", // amount + fee
"EUR:4.99"), // amount - fee
CMD_EXEC_AGGREGATOR ("aggregator-tip-1"),
TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-tip-498c",
EXCHANGE_URL,
"EUR:4.98",
exchange_payto,
merchant_payto),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-at-tips"),
#endif
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command pay_again[] = {
cmd_transfer_to_exchange ("create-reserve-10",
"EUR:10.02"),
cmd_exec_wirewatch ("wirewatch-10"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-10",
"EUR:10.02",
payer_payto,
exchange_payto,
"create-reserve-10"),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10a",
"create-reserve-10",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10b",
"create-reserve-10",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_status ("withdraw-status-10",
"create-reserve-10",
"EUR:0",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-10",
merchant_url,
MHD_HTTP_OK,
"10",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:10.0"),
TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-10",
merchant_url,
MHD_HTTP_CONFLICT,
"create-proposal-10",
"withdraw-coin-10a;withdraw-coin-1",
"EUR:5",
"EUR:4.99"),
TALER_TESTING_cmd_merchant_pay_order ("pay-again-10",
merchant_url,
MHD_HTTP_OK,
"create-proposal-10",
"withdraw-coin-10a;withdraw-coin-10b",
"EUR:5",
"EUR:4.99"),
CMD_EXEC_AGGREGATOR ("run-aggregator-10"),
TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-9.97-10",
EXCHANGE_URL,
"EUR:9.97",
exchange_payto,
merchant_payto),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-10"),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command pay_abort[] = {
cmd_transfer_to_exchange ("create-reserve-11",
"EUR:10.02"),
cmd_exec_wirewatch ("wirewatch-11"),
TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-11",
"EUR:10.02",
payer_payto,
exchange_payto,
"create-reserve-11"),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11a",
"create-reserve-11",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11b",
"create-reserve-11",
"EUR:5",
MHD_HTTP_OK),
TALER_TESTING_cmd_status ("withdraw-status-11",
"create-reserve-11",
"EUR:0",
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_post_orders ("create-proposal-11",
merchant_url,
MHD_HTTP_OK,
"11",
GNUNET_TIME_UNIT_ZERO_ABS,
GNUNET_TIME_UNIT_FOREVER_ABS,
"EUR:10.0"),
TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-good",
merchant_url,
MHD_HTTP_NOT_ACCEPTABLE,
"create-proposal-11",
"withdraw-coin-11a",
"EUR:5",
"EUR:4.99"),
TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-bad",
merchant_url,
MHD_HTTP_CONFLICT,
"create-proposal-11",
"withdraw-coin-1",
"EUR:5",
"EUR:4.99"),
TALER_TESTING_cmd_merchant_order_abort ("pay-abort-11",
merchant_url,
"pay-fail-partial-double-11-good",
MHD_HTTP_OK),
CMD_EXEC_AGGREGATOR ("run-aggregator-11"),
TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-11"),
TALER_TESTING_cmd_end ()
};
struct TALER_TESTING_Command commands[] = {
TALER_TESTING_cmd_batch ("orders-id",
get_private_order_id),
TALER_TESTING_cmd_config ("config",
merchant_url,
MHD_HTTP_OK),
TALER_TESTING_cmd_merchant_get_instances ("instances-empty",
merchant_url,
MHD_HTTP_OK,
NULL),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1",
merchant_url,
"i1",
PAYTO_I1,
"EUR",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_instances ("instances-get-i1",
merchant_url,
MHD_HTTP_OK,
"instance-create-i1",
NULL),
TALER_TESTING_cmd_merchant_get_instance ("instances-get-i1",
merchant_url,
"i1",
MHD_HTTP_OK,
"instance-create-i1"),
TALER_TESTING_cmd_merchant_patch_instance ("instance-patch-i1",
merchant_url,
"i1",
2,
payto_uris,
"bob-the-merchant",
json_pack ("{s:s}",
"street",
"bobstreet"),
json_pack ("{s:s}",
"street",
"bobjuryst"),
"EUR:0.1",
4,
"EUR:0.5",
GNUNET_TIME_UNIT_MINUTES,
GNUNET_TIME_UNIT_MINUTES,
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_instance2 ("instances-get-i1-2",
merchant_url,
"i1",
MHD_HTTP_OK,
"instance-patch-i1",
payto_uris,
2,
NULL,
0),
TALER_TESTING_cmd_merchant_patch_instance (
"instance-patch-i1-inactivate-account",
merchant_url,
"i1",
1,
payto_uris,
"bob-the-merchant",
json_pack ("{s:s}",
"street",
"bobstreet"),
json_pack ("{s:s}",
"street",
"bobjuryst"),
"EUR:0.1",
4,
"EUR:0.5",
GNUNET_TIME_UNIT_MINUTES,
GNUNET_TIME_UNIT_MINUTES,
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_instance2 ("instances-get-i1-3",
merchant_url,
"i1",
MHD_HTTP_OK,
"instance-patch-i1-inactivate-account",
payto_uris,
1,
&payto_uris[1],
1),
TALER_TESTING_cmd_merchant_get_instance ("instances-get-i2-nx",
merchant_url,
"i2",
MHD_HTTP_NOT_FOUND,
NULL),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-i2",
merchant_url,
"i2",
PAYTO_I1,
"EUR",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-i2-idem",
merchant_url,
"i2",
PAYTO_I1,
"EUR",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-i2-non-idem",
merchant_url,
"i2",
"payto://other-method/",
"EUR",
MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_merchant_delete_instance ("instance-delete-i2",
merchant_url,
"i2",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_instance ("instances-get-i2-post-deletion",
merchant_url,
"i2",
MHD_HTTP_NOT_FOUND,
NULL),
TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i2-again",
merchant_url,
"i2",
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_merchant_post_instances ("instance-create-default",
merchant_url,
"default",
PAYTO_I1,
"EUR",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_products ("get-products-empty",
merchant_url,
MHD_HTTP_OK,
NULL),
TALER_TESTING_cmd_merchant_post_products ("post-products-p1",
merchant_url,
"product-1",
"a product",
"EUR:1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_products ("post-products-p1-idem",
merchant_url,
"product-1",
"a product",
"EUR:1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_post_products ("post-products-p1-non-idem",
merchant_url,
"product-1",
"a different product",
"EUR:1",
MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_merchant_get_products ("get-products-p1",
merchant_url,
MHD_HTTP_OK,
"post-products-p1",
NULL),
TALER_TESTING_cmd_merchant_get_product ("get-product-p1",
merchant_url,
"product-1",
MHD_HTTP_OK,
"post-products-p1"),
TALER_TESTING_cmd_merchant_post_products ("post-products-p2",
merchant_url,
"product-2",
"a product",
"EUR:1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_patch_product ("patch-products-p2",
merchant_url,
"product-2",
"another product",
json_pack ("{s:s}", "en", "text"),
"kg",
"EUR:1",
json_object (),
json_object (),
40,
0,
json_pack ("{s:s}",
"street",
"pstreet"),
GNUNET_TIME_relative_to_absolute (
GNUNET_TIME_UNIT_MINUTES),
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_get_product ("get-product-p2",
merchant_url,
"product-2",
MHD_HTTP_OK,
"patch-products-p2"),
TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3-nx",
merchant_url,
"product-3",
"nx updated product",
json_pack ("{s:s}", "en", "text"),
"kg",
"EUR:1",
json_object (),
json_object (),
40,
0,
json_pack ("{s:s}",
"street",
"pstreet"),
GNUNET_TIME_relative_to_absolute (
GNUNET_TIME_UNIT_MINUTES),
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_merchant_delete_product ("get-products-empty",
merchant_url,
"p1",
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_merchant_delete_product ("get-products-empty",
merchant_url,
"product-1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_lock_product ("lock-product-p2",
merchant_url,
"product-2",
GNUNET_TIME_UNIT_MINUTES,
2,
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_lock_product ("lock-product-nx",
merchant_url,
"product-nx",
GNUNET_TIME_UNIT_MINUTES,
2,
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_merchant_lock_product ("lock-product-too-much",
merchant_url,
"product-2",
GNUNET_TIME_UNIT_MINUTES,
39,
MHD_HTTP_GONE),
TALER_TESTING_cmd_merchant_delete_product ("delete-product-locked",
merchant_url,
"product-2",
MHD_HTTP_CONFLICT),
TALER_TESTING_cmd_merchant_purge_instance ("instance-purge-i1",
merchant_url,
"i1",
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_delete_instance ("instance-delete-i1-again",
merchant_url,
"i1",
MHD_HTTP_NOT_FOUND),
TALER_TESTING_cmd_batch ("pay",
pay),
TALER_TESTING_cmd_batch ("double-spending",
double_spending),
TALER_TESTING_cmd_batch ("pay-again",
pay_again),
TALER_TESTING_cmd_batch ("pay-abort",
pay_abort),
TALER_TESTING_cmd_batch ("refund",
refund),
TALER_TESTING_cmd_batch ("tip",
tip),
/**
* End the suite. Fixme: better to have a label for this
* too, as it shows a "(null)" token on logs.
*/
TALER_TESTING_cmd_end ()
};
TALER_TESTING_run_with_fakebank (is,
commands,
bc.exchange_auth.wire_gateway_url);
}
int
main (int argc,
char *const *argv)
{
unsigned int ret;
/* These environment variables get in the way... */
unsetenv ("XDG_DATA_HOME");
unsetenv ("XDG_CONFIG_HOME");
GNUNET_log_setup ("test-merchant-api",
"DEBUG",
NULL);
if (GNUNET_OK != TALER_TESTING_prepare_fakebank (CONFIG_FILE,
"exchange-account-exchange",
&bc))
return 77;
payer_payto = ("payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME);
exchange_payto = ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME);
merchant_payto = ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME);
if (NULL ==
(merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE)))
return 77;
TALER_TESTING_cleanup_files (CONFIG_FILE);
switch (TALER_TESTING_prepare_exchange (CONFIG_FILE,
GNUNET_YES,
&ec))
{
case GNUNET_SYSERR:
GNUNET_break (0);
return 1;
case GNUNET_NO:
return 77;
case GNUNET_OK:
if (NULL == (merchantd =
TALER_TESTING_run_merchant (CONFIG_FILE,
merchant_url)))
return 1;
ret = TALER_TESTING_setup_with_exchange (&run,
NULL,
CONFIG_FILE);
GNUNET_OS_process_kill (merchantd, SIGTERM);
GNUNET_OS_process_wait (merchantd);
GNUNET_OS_process_destroy (merchantd);
GNUNET_free (merchant_url);
if (GNUNET_OK != ret)
return 1;
break;
default:
GNUNET_break (0);
return 1;
}
return 0;
}
/* end of test_merchant_api.c */