diff options
Diffstat (limited to 'src/testing')
474 files changed, 8637 insertions, 7691 deletions
diff --git a/src/testing/.gitignore b/src/testing/.gitignore index 9898208e..07fd2be3 100644 --- a/src/testing/.gitignore +++ b/src/testing/.gitignore @@ -13,3 +13,6 @@ test_reducer_home/.local/share/taler/exchange-secmod-eddsa/ test_reducer_home/.local/share/taler/exchange-secmod-rsa/ test_reducer_home/ test_kyc_api +test_merchant_api_home/taler/exchange-secmod-* +*.edited +test_merchant_api_home/taler/exchange-offline/secm_tofus.pub diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 159b922e..67bbbced 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -8,74 +8,79 @@ endif check_SCRIPTS = \ - test-merchant-walletharness.sh \ test_merchant_instance_auth.sh \ + test_merchant_instance_creation.sh \ test_merchant_instance_response.sh \ test_merchant_instance_purge.sh \ - test_merchant_reserve_creation.sh \ test_merchant_product_creation.sh \ test_merchant_order_creation.sh \ - test_merchant_transfer_tracking.sh - + test_merchant_transfer_tracking.sh \ + test_merchant_kyc.sh \ + test_merchant_order_autocleanup.sh \ + test_merchant_wirewatch.sh \ + test-merchant-walletharness.sh lib_LTLIBRARIES = \ libtalermerchanttesting.la libtalermerchanttesting_la_LDFLAGS = \ - -version-info 2:0:0 \ + -version-info 4:0:1 \ -no-undefined libtalermerchanttesting_la_SOURCES = \ testing_api_cmd_config.c \ testing_api_cmd_abort_order.c \ testing_api_cmd_claim_order.c \ + testing_api_cmd_depositcheck.c \ testing_api_cmd_get_instance.c \ testing_api_cmd_get_instances.c \ testing_api_cmd_get_orders.c \ + testing_api_cmd_get_otp_device.c \ + testing_api_cmd_get_otp_devices.c \ testing_api_cmd_get_product.c \ testing_api_cmd_get_products.c \ - testing_api_cmd_get_reserve.c \ - testing_api_cmd_get_reserves.c \ - testing_api_cmd_get_tips.c \ testing_api_cmd_get_transfers.c \ testing_api_cmd_get_templates.c \ testing_api_cmd_get_template.c \ testing_api_cmd_get_webhooks.c \ testing_api_cmd_get_webhook.c \ + testing_api_cmd_delete_account.c \ testing_api_cmd_delete_instance.c \ testing_api_cmd_delete_order.c \ + testing_api_cmd_delete_otp_device.c \ testing_api_cmd_delete_product.c \ testing_api_cmd_delete_template.c \ testing_api_cmd_delete_webhook.c \ - testing_api_cmd_delete_reserve.c \ testing_api_cmd_delete_transfer.c \ testing_api_cmd_forget_order.c \ testing_api_cmd_kyc_get.c \ testing_api_cmd_lock_product.c \ testing_api_cmd_instance_auth.c \ testing_api_cmd_merchant_get_order.c \ - testing_api_cmd_merchant_get_tip.c \ + testing_api_cmd_patch_instance.c \ + testing_api_cmd_patch_otp_device.c \ + testing_api_cmd_patch_product.c \ + testing_api_cmd_patch_template.c \ + testing_api_cmd_patch_webhook.c \ testing_api_cmd_pay_order.c \ + testing_api_cmd_post_account.c \ testing_api_cmd_post_instances.c \ testing_api_cmd_post_orders_paid.c \ testing_api_cmd_post_orders.c \ + testing_api_cmd_post_otp_devices.c \ testing_api_cmd_post_products.c \ - testing_api_cmd_post_reserves.c \ testing_api_cmd_post_transfers.c \ testing_api_cmd_post_templates.c \ + testing_api_cmd_post_tokenfamilies.c \ testing_api_cmd_post_using_templates.c \ testing_api_cmd_post_webhooks.c \ - testing_api_cmd_patch_instance.c \ - testing_api_cmd_patch_product.c \ - testing_api_cmd_patch_template.c \ - testing_api_cmd_patch_webhook.c \ testing_api_cmd_refund_order.c \ - \ - testing_api_cmd_tip_authorize.c \ - testing_api_cmd_tip_pickup.c \ + testing_api_cmd_tme.c \ 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_cmd_checkserver.c \ testing_api_helpers.c \ testing_api_traits.c @@ -84,11 +89,13 @@ libtalermerchanttesting_la_LIBADD = \ -ltalerbank \ -ltalerexchange \ -ltalerjson \ + -ltalermhd \ -ltalerutil \ -lgnunetcurl \ -lgnunetjson \ -lgnunetutil \ -ljansson \ + -lmicrohttpd \ -ltalertesting \ $(XLIB) @@ -125,7 +132,6 @@ test_merchant_api_twisted_cs_LDADD = \ -ltalerexchange \ -ltalerjson \ -ltalerutil \ - -lgnunettesting \ -lgnunetjson \ -lgnunetcurl \ -lgnunetutil \ @@ -147,7 +153,6 @@ test_merchant_api_twisted_rsa_LDADD = \ -ltalerexchange \ -ltalerjson \ -ltalerutil \ - -lgnunettesting \ -lgnunetjson \ -lgnunetcurl \ -lgnunetutil \ @@ -168,7 +173,6 @@ test_merchant_api_cs_LDADD = \ -ltalerexchange \ -ltalerjson \ -ltalerutil \ - -lgnunettesting \ -lgnunetjson \ -lgnunetcurl \ -lgnunetutil \ @@ -188,7 +192,6 @@ test_merchant_api_rsa_LDADD = \ -ltalerexchange \ -ltalerjson \ -ltalerutil \ - -lgnunettesting \ -lgnunetjson \ -lgnunetcurl \ -lgnunetutil \ @@ -215,10 +218,10 @@ test_kyc_api_LDADD = \ $(XLIB) EXTRA_DIST = \ - initialize_taler_system.sh \ - test_key_rotation.sh \ + setup.sh \ test_key_rotation.conf \ test_kyc_api.conf \ + test_merchant_api.conf \ test_merchant_api-cs.conf \ test_merchant_api-rsa.conf \ test_merchant_api_twisted-cs.conf \ @@ -226,8 +229,6 @@ EXTRA_DIST = \ test_merchant_api_proxy_merchant.conf \ test_merchant_api_proxy_exchange.conf \ test_merchant_api_home/.local/share/taler/exchange-offline/master.priv \ - test_merchant_api_home/.local/share/taler/exchange/offline-keys/master.priv \ - test_merchant_api_home/.config/taler/exchange/account-2.json \ test_merchant.priv \ test_template.conf \ $(check_SCRIPTS) diff --git a/src/testing/initialize_taler_system.sh b/src/testing/initialize_taler_system.sh deleted file mode 100755 index a74d7e7a..00000000 --- a/src/testing/initialize_taler_system.sh +++ /dev/null @@ -1,283 +0,0 @@ -# This file is part of TALER -# Copyright (C) 2014-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/> -# -## Coloring style Text shell script -COLOR='\033[0;35m' -NOCOLOR='\033[0m' - -set -eu - -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo " SKIP: $1" - exit 77 -} - -# Exit, with error message (hard failure) -function exit_fail() { - echo " FAIL: $1" - exit 1 -} - -# Cleanup to run whenever we exit -function cleanup() -{ - # kill main HTTP servers first - kill ${MERCHANT_HTTPD_PID:-X} &> /dev/null || true - kill ${EXCHANGE_HTTPD_PID:-X} &> /dev/null || true - for n in `jobs -p` - do - kill $n 2> /dev/null || true - done - wait - rm -rf $CONF $WALLET_DB $TMP_DIR $LAST_RESPONSE - # kill euFin - kill `cat libeufin-sandbox.pid 2> /dev/null` &> /dev/null || true - kill `cat libeufin-nexus.pid 2> /dev/null` &> /dev/null || true -} - -NEXUS_PORT=8082 -SANDBOX_URL=http://localhost:1$NEXUS_PORT -export BANK_URL=$SANDBOX_URL/demobanks/default -function get_payto_uri() { - export LIBEUFIN_SANDBOX_USERNAME=$1 - export LIBEUFIN_SANDBOX_PASSWORD=$2 - export LIBEUFIN_SANDBOX_URL=$SANDBOX_URL - libeufin-cli sandbox demobank info --bank-account $1 | jq --raw-output '.paytoUri' -} -export get_payto_uri - -function get_bankaccount_balance() { - export LIBEUFIN_SANDBOX_USERNAME=$1 - export LIBEUFIN_SANDBOX_PASSWORD=$2 - export LIBEUFIN_SANDBOX_URL=$SANDBOX_URL - libeufin-cli sandbox demobank info --bank-account $1 | jq --raw-output '.balance.amount' -} -export get_bankaccount_balance - -function get_bankaccount_transactions() { - export LIBEUFIN_SANDBOX_USERNAME=$1 - export LIBEUFIN_SANDBOX_PASSWORD=$2 - export LIBEUFIN_SANDBOX_URL=$SANDBOX_URL - libeufin-cli sandbox demobank list-transactions --bank-account $1 -} -export get_bankaccount_transactions - -# Exchange configuration file will be edited, so we create one -# from the template. -CONF=`mktemp test_template.conf-XXXXXX` -cp test_template.conf $CONF - -TMP_DIR=`mktemp -d keys-tmp-XXXXXX` -WALLET_DB=`mktemp test_wallet.json-XXXXXX` -LAST_RESPONSE=`mktemp test_response.conf-XXXXXX` - -# Install cleanup handler (except for kill -9) -trap cleanup EXIT - -# Check we can actually run -echo -n "Testing for jq" -jq -h > /dev/null || exit_skip "jq required" -echo " FOUND" - -echo -n "Testing for taler" -taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" -taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" -echo " FOUND" - -echo -n "Testing for libeufin-cli" -libeufin-cli --help >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" -echo -n "Testing for taler-wallet-cli" -taler-wallet-cli -v >/dev/null </dev/null 2> /dev/null || exit_skip " MISSING" -echo " FOUND" - -echo -n "Generating Taler auditor, exchange and merchant configurations ..." - -DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME` -rm -rf $DATA_DIR - -# obtain key configuration data -MASTER_PRIV_FILE=`taler-config -f -c ${CONF} -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE"` -MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE` -mkdir -p $MASTER_PRIV_DIR -gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null -MASTER_PUB=`gnunet-ecc -p ${MASTER_PRIV_FILE}` -EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL` -MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT` -MERCHANT_URL=http://localhost:${MERCHANT_PORT}/ -AUDITOR_URL=http://localhost:8083/ -AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE` -AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE` -mkdir -p $AUDITOR_PRIV_DIR -gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null -AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE` - -# patch configuration -TALER_DB=talercheck -taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB -taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB -taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB -BANK_DB="jdbc:sqlite:$TMP_DIR/$TALER_DB" -taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/" -taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/" - -echo " OK" - -echo "Printing software versions..." - -echo -n "taler-wallet-cli " -taler-wallet-cli --version -taler-exchange-httpd --version -taler-merchant-httpd --version -libeufin-cli --version - -# Setup libeuFin before the exchange, because we must set -# the PAYTO_URI config option (with unguessable IBAN) -# before the exchange starts. -echo "Setting up libeufin ..." -# reset libeufin database -rm -f $TALER_DB -taler-bank-manage-testing $NEXUS_PORT $TALER_DB $EXCHANGE_URL $CONF -echo -n "Setting up exchange ..." -# reset database -dropdb $TALER_DB >/dev/null 2>/dev/null || true -createdb $TALER_DB || exit_skip "Could not create database $TALER_DB" -taler-exchange-dbinit -c $CONF -taler-merchant-dbinit -c $CONF -taler-auditor-dbinit -c $CONF -taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL -taler-exchange-secmod-eddsa -c $CONF -L DEBUG 2> taler-exchange-secmod-eddsa.log & -taler-exchange-secmod-rsa -c $CONF -L DEBUG 2> taler-exchange-secmod-rsa.log & -taler-exchange-secmod-cs -c $CONF -L DEBUG 2> taler-exchange-secmod-cs.log & -taler-exchange-httpd -c $CONF -L DEBUG 2> taler-exchange-httpd.log & -EXCHANGE_HTTPD_PID=$! -taler-merchant-httpd -c $CONF -L DEBUG 2> taler-merchant-httpd.log & -MERCHANT_HTTPD_PID=$! -taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log & -WIREWATCH_PID=$! -taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log & -echo " OK" -# Launch services - -echo -n "Waiting for the bank" -# Wait for bank to be available (usually the slowest) -for n in `seq 1 300` -do - echo -n "." - sleep 0.1 - OK=0 - # bank - wget --waitretry=0 --timeout=1 \ - --user admin --password secret \ - http://localhost:8082/ \ - -o /dev/null \ - -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch services (bank)" -fi -echo " OK" - -echo -n "Waiting for taler services " -# Wait for all other taler services to be available -for n in `seq 1 20` -do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue - # merchant - wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue - # auditor - wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch taler services" -fi - -echo "OK" - -set +e -echo -n 'Wait the exchange for gather its keys ' -for n in `seq 1 50` -do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget --tries=3 --waitretry=0 --timeout=1 http://localhost:8081/management/keys -o /dev/null -O $LAST_RESPONSE >/dev/null - DENOMS_COUNT=`jq '.future_denoms|length' < $LAST_RESPONSE` - SIGNKEYS_COUNT=`jq '.future_signkeys|length' < $LAST_RESPONSE` - [[ -z "$SIGNKEYS_COUNT" || "$SIGNKEYS_COUNT" == "0" || -z "$DENOMS_COUNT" || "$DENOMS_COUNT" == "0" ]] && continue - OK=1 - break; -done -set -e - -if [ 1 != $OK ] -then - exit_skip "Failed to setup exchange keys, check secmod logs" -fi - -echo " OK" - -echo -n "Setting up keys ..." -taler-exchange-offline -c $CONF \ - download \ - sign \ - enable-account `taler-config -c $CONF -s exchange-account-1 -o PAYTO_URI` \ - enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \ - wire-fee now iban TESTKUDOS:0.01 TESTKUDOS:0.01 \ - global-fee now TESTKUDOS:0.01 TESTKUDOS:0.01 TESTKUDOS:0.01 1h 1year 5 \ - upload &> taler-exchange-offline.log - -echo -n "." - -for n in `seq 1 3` -do - echo -n "." - OK=0 - wget --tries=1 --timeout=1 \ - http://localhost:8081/keys \ - -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to setup keys" -fi - -echo " OK" - -echo -n "Setting up auditor signatures ..." -taler-auditor-offline -c $CONF \ - download sign upload &> taler-auditor-offline.log -echo " OK" diff --git a/src/testing/setup.sh b/src/testing/setup.sh new file mode 100755 index 00000000..80933149 --- /dev/null +++ b/src/testing/setup.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# This file is in the public domain + +# Script to be inlined into the main test scripts. Defines function 'setup()' +# which wraps around 'taler-unified-setup.sh' to launch GNU Taler services. +# Call setup() with the arguments to pass to 'taler-unified-setup'. setup() +# will then launch GNU Taler, wait for the process to be complete before +# returning. The script will also install an exit handler to ensure the GNU +# Taler processes are stopped when the shell exits. + +set -eu + +unset XDG_DATA_HOME +unset XDG_CONFIG_HOME + + +# Cleanup to run whenever we exit +function exit_cleanup() +{ + if [ ! -z ${SETUP_PID+x} ] + then + echo "Killing taler-unified-setup ($SETUP_PID)" >&2 + kill -TERM "$SETUP_PID" 2> /dev/null || true + wait "$SETUP_PID" 2> /dev/null || true + fi +} + +# Install cleanup handler (except for kill -9) +trap exit_cleanup EXIT + +function setup() +{ + echo "Starting test system ..." >&2 + # Create a named pipe in a temp directory we own. + FIFO_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d fifo-XXXXXX) + FIFO_OUT=$(echo "$FIFO_DIR/out") + mkfifo "$FIFO_OUT" + # Open pipe as FD 3 (RW) and FD 4 (RO) + exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT" + rm -rf "$FIFO_DIR" + # We require '-W' for our termination logic to work. + taler-unified-setup.sh -W "$@" >&3 & + SETUP_PID=$! + # Close FD3 + exec 3>&- + sed -u '/<<READY>>/ q' <&4 + # Close FD4 + exec 4>&- + echo "Test system ready" >&2 +} + +# Exit, with status code "skip" (no 'real' failure) +function exit_fail() { + echo "$@" >&2 + exit 1 +} + +# Exit, with status code "skip" (no 'real' failure) +function exit_skip() { + echo "SKIPPING: $1" + exit 77 +} + +function get_payto_uri() { + libeufin-bank create-account -u "$1" -p "$2" --name "$1" 2> /dev/null +} + diff --git a/src/testing/test-merchant-walletharness.sh b/src/testing/test-merchant-walletharness.sh index 91cb542a..c3c048d1 100755 --- a/src/testing/test-merchant-walletharness.sh +++ b/src/testing/test-merchant-walletharness.sh @@ -22,21 +22,20 @@ set -eu -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo $1 - exit 77 -} - -# If CLI is installed, assume all the suite is. -echo -n "Testing for libeufin(-cli)" -libeufin-cli --help >/dev/null </dev/null || exit_skip " MISSING" +unset XDG_DATA_HOME +unset XDG_CONFIG_HOME + +. setup.sh + +echo -n "Testing for libeufin-bank" +libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" echo " FOUND" echo -n "Testing for taler-harness" taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" echo " FOUND" + export WALLET_HARNESS_WITH_EUFIN=1 res=0 taler-harness run-integrationtests --dry --suites merchant 2&>/dev/null || res=$? diff --git a/src/testing/test.conf b/src/testing/test.conf new file mode 100644 index 00000000..2cfc0418 --- /dev/null +++ b/src/testing/test.conf @@ -0,0 +1,181 @@ +# This file is in the public domain. +# +[PATHS] +# Persistent data storage for the testcase +TALER_TEST_HOME = test_merchant_api_home/ +TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/ + +# Persistent data storage +TALER_DATA_HOME = $TALER_HOME/.local/share/taler/ + +# Configuration files +TALER_CONFIG_HOME = $TALER_HOME/.config/taler/ + +# Cached data, no big deal if lost +TALER_CACHE_HOME = $TALER_HOME/.cache/taler/ + +[taler] +# What currency do we use? +CURRENCY = EUR +CURRENCY_ROUND_UNIT = EUR:0.01 + +[taler-helper-crypto-rsa] +# Reduce from 1 year to speed up test +LOOKAHEAD_SIGN = 24 days + +[taler-helper-crypto-eddsa] +# Reduce from 1 year to speed up test +LOOKAHEAD_SIGN = 24 days +# Reduce from 12 weeks to ensure we have multiple +DURATION = 14 days + +[bank] +HTTP_PORT = 8082 + +########################################## +# Configuration for the merchant backend # +########################################## + +[merchant] + +# Which port do we run the backend on? (HTTP server) +PORT = 8080 +SERVE = tcp + +# Which plugin (backend) do we use for the DB. +DB = postgres + +# This specifies which database the postgres backend uses. +[merchantdb-postgres] +CONFIG = postgres:///talercheck +SQL_DIR = $DATADIR/sql/merchant/ + +# Sections starting with "merchant-exchange-" specify trusted exchanges +# (by the merchant) +[merchant-exchange-test] +MASTER_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 +EXCHANGE_BASE_URL = http://localhost:8081/ +CURRENCY = EUR + + +####################################################### +# Configuration for the auditor for the testcase +####################################################### +[auditor] +BASE_URL = http://the.auditor/ + + +####################################################### +# Configuration for ??? Is this used? +####################################################### + +# Auditors must be in sections "auditor-", the rest of the section +# name could be anything. +[auditor-ezb] +# Informal name of the auditor. Just for the user. +NAME = European Central Bank + +# URL of the auditor (especially for in the future, when the +# auditor offers an automated issue reporting system). +# Not really used today. +URL = http://taler.ezb.eu/ + +# This is the important bit: the signing key of the auditor. +PUBLIC_KEY = 9QXF7XY7E9VPV47B5Z806NDFSX2VJ79SVHHD29QEQ3BG31ANHZ60 + +# Which currency is this auditor trusted for? +CURRENCY = EUR + + +################################################### +# Configuration for the exchange for the testcase # +################################################### + +[exchange] +AML_THRESHOLD = EUR:1000000 + + +# How to access our database +DB = postgres + +# HTTP port the exchange listens to +PORT = 8081 + +# Our public key +MASTER_PUBLIC_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 + +# Base URL of the exchange. +BASE_URL = "http://localhost:8081/" + + +[exchangedb-postgres] +CONFIG = "postgres:///talercheck" + + +[auditordb-postgres] +CONFIG = postgres:///talercheck + + +# Account of the EXCHANGE +[exchange-account-exchange] +# What is the exchange's bank account (with the "Taler Bank" demo system)? +PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES + +[exchange-accountcredentials-exchange] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = NONE + +[admin-accountcredentials-exchange] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = NONE + + +[coin_eur_ct_1] +value = EUR:0.01 +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.00 +fee_deposit = EUR:0.00 +fee_refresh = EUR:0.01 +fee_refund = EUR:0.01 +rsa_keysize = 1024 +CIPHER = CS + +[coin_eur_ct_10] +value = EUR:0.10 +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +fee_refund = EUR:0.01 +rsa_keysize = 1024 +CIPHER = CS + +[coin_eur_1] +value = EUR:1 +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +fee_refund = EUR:0.01 +rsa_keysize = 1024 +CIPHER = CS + +[coin_eur_5] +value = EUR:5 +duration_withdraw = 7 days +duration_spend = 2 years +duration_legal = 3 years +fee_withdraw = EUR:0.01 +fee_deposit = EUR:0.01 +fee_refresh = EUR:0.03 +fee_refund = EUR:0.01 +rsa_keysize = 1024 +CIPHER = CS diff --git a/src/testing/test_key_rotation.conf b/src/testing/test_key_rotation.conf index 988a5219..cc7035b0 100644 --- a/src/testing/test_key_rotation.conf +++ b/src/testing/test_key_rotation.conf @@ -12,7 +12,6 @@ CURRENCY_ROUND_UNIT = TESTKUDOS:0.01 [exchange] MAX_KEYS_CACHING = forever DB = postgres -MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv SERVE = tcp UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http UNIXPATH_MODE = 660 @@ -69,7 +68,6 @@ UNIXPATH_MODE = 660 PORT = 8083 AUDITOR_URL = http://localhost:8083/ TINY_AMOUNT = TESTKUDOS:0.01 -AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv BASE_URL = "http://localhost:8083/" [bank] @@ -80,7 +78,7 @@ HTTP_PORT = 8082 SUGGESTED_EXCHANGE = http://localhost:8081/ SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2 ALLOW_REGISTRATIONS = YES -SERVE = http +SERVE = tcp [exchangedb] IDLE_RESERVE_EXPIRATION_TIME = 4 weeks @@ -92,7 +90,13 @@ enable_debit = yes enable_credit = yes [exchange-accountcredentials-1] -WIRE_GATEWAY_URL = "http://localhost:8082/taler-wire-gateway/Exchange/" +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/Exchange/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = basic +USERNAME = Exchange +PASSWORD = x + +[admin-accountcredentials-1] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/Exchange/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = Exchange PASSWORD = x diff --git a/src/testing/test_key_rotation.sh b/src/testing/test_key_rotation.sh deleted file mode 100755 index b3609b1d..00000000 --- a/src/testing/test_key_rotation.sh +++ /dev/null @@ -1,411 +0,0 @@ -#!/bin/bash -# This file is part of TALER -# Copyright (C) 2014-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/> -# -# -# Note that this test is intentionally NOT run as part of the standard test -# suite, because it is awfully slow (due to necessary 'wait' operations) and -# may even hang on slower computers (with the wallet trying to withdraw and -# failing because all keys have expired) due to the relatively short timeouts -# involved. -# -## Coloring style Text shell script -COLOR='\033[0;35m' -NOCOLOR='\033[0m' - - -set -eu - -# We use VERY short withdraw periods, set flag to -# tell wallet explicitly that this is OK... -export TALER_WALLET_DEBUG_DENOMSEL_ALLOW_LATE=1 - -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo " SKIP: $1" - exit 77 -} - -# Exit, with error message (hard failure) -function exit_fail() { - echo " FAIL: $1" - exit 1 -} - -# Cleanup to run whenever we exit -function cleanup() -{ - for n in `jobs -p` - do - kill $n 2> /dev/null || true - done - rm -rf $CONF $WALLET_DB $TMP_DIR - wait -} - -# Exchange configuration file will be edited, so we create one -# from the template. -CONF=`mktemp test_template.conf-XXXXXX` -cp test_key_rotation.conf $CONF - -TMP_DIR=`mktemp -d keys-tmp-XXXXXX` -WALLET_DB=`mktemp test_wallet.json-XXXXXX` - -# Install cleanup handler (except for kill -9) -trap cleanup EXIT - -# Check we can actually run -echo -n "Testing for jq" -jq -h > /dev/null || exit_skip "jq required" -echo " FOUND" - -echo -n "Testing for taler" -taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange required" -taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant required" -echo " FOUND" - -echo -n "Testing for taler-bank-manage" -taler-bank-manage --help >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" -echo -n "Testing for taler-wallet-cli" -taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING" -echo " FOUND" - -echo -n "Generating Taler auditor, exchange and merchant configurations ..." - -DATA_DIR=`taler-config -f -c $CONF -s PATHS -o TALER_HOME` -rm -rf $DATA_DIR - -# obtain key configuration data -MASTER_PRIV_FILE=`taler-config -f -c $CONF -s EXCHANGE -o MASTER_PRIV_FILE` -MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE` -mkdir -p $MASTER_PRIV_DIR -gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null 2> /dev/null -MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE` -EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL` -MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT` -MERCHANT_URL=http://localhost:${MERCHANT_PORT}/ -BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT` -BANK_URL=http://localhost:${BANK_PORT}/ -AUDITOR_URL=http://localhost:8083/ -AUDITOR_PRIV_FILE=`taler-config -f -c $CONF -s AUDITOR -o AUDITOR_PRIV_FILE` -AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE` -mkdir -p $AUDITOR_PRIV_DIR -gnunet-ecc -g1 $AUDITOR_PRIV_FILE > /dev/null 2> /dev/null -AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE` - -# patch configuration -TALER_DB=talercheck -taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB -taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB -taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TALER_DB -taler-config -c $CONF -s bank -o database -V postgres:///$TALER_DB -taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/" -taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/" - -echo " OK" - -echo -n "Setting up exchange ..." - -# reset database -dropdb $TALER_DB >/dev/null 2>/dev/null || true -createdb $TALER_DB || exit_skip "Could not create database $TALER_DB" -taler-exchange-dbinit -c $CONF -taler-merchant-dbinit -c $CONF -taler-auditor-dbinit -c $CONF -taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL - -echo " OK" - -# Launch services -echo -n "Launching taler services ..." -taler-bank-manage-testing $CONF postgres:///$TALER_DB serve > taler-bank.log 2> taler-bank.err & -taler-exchange-secmod-eddsa -c $CONF 2> taler-exchange-secmod-eddsa.log & -taler-exchange-secmod-rsa -c $CONF 2> taler-exchange-secmod-rsa.log & -taler-exchange-secmod-cs -c $CONF 2> taler-exchange-secmod-cs.log & -taler-exchange-httpd -c $CONF 2> taler-exchange-httpd.log & -taler-merchant-httpd -c $CONF -L INFO 2> taler-merchant-httpd.log & -taler-exchange-wirewatch -c $CONF 2> taler-exchange-wirewatch.log & -taler-auditor-httpd -L INFO -c $CONF 2> taler-auditor-httpd.log & - -echo " OK" - -# Wait for bank to be available (usually the slowest) -for n in `seq 1 50` -do - echo -n "." - sleep 0.2 - OK=0 - # bank - wget --tries=1 --timeout=1 http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch services (bank)" -fi - -# Wait for all other taler services to be available -for n in `seq 1 50` -do - echo -n "." - sleep 0.1 - OK=0 - # exchange - wget --tries=1 --timeout=1 http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue - # merchant - wget --tries=1 --timeout=1 http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue - # auditor - wget --tries=1 --timeout=1 http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to launch taler services" -fi - -echo "OK" - - -echo -n "Setting up merchant instance" -STATUS=$(curl -H "Content-Type: application/json" -X POST \ - http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ - -w "%{http_code}" -s -o /dev/null) - -if [ "$STATUS" != "204" ] -then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 -fi -echo " OK" - -echo -n "Setting up orders ..." - - -ORDER_1=`curl -s -H "Content-Type: application/json" -X POST \ - http://localhost:9966/private/orders \ - -d '{"create_token":false, "order":{"amount":"TESTKUDOS:0.01","summary":"Minimal test order #1"}}' \ - | jq -er '.order_id'` -PAY1=taler+http://pay/localhost:9966/${ORDER_1}/ - -ORDER_2=`curl -s -H "Content-Type: application/json" -X POST \ - http://localhost:9966/private/orders \ - -d '{"create_token":false, "order":{"amount":"TESTKUDOS:0.01","summary":"Minimal test order #2"}}' \ - | jq -er '.order_id'` -PAY2=taler+http://pay/localhost:9966/${ORDER_2}/ - -ORDER_3=`curl -s -H "Content-Type: application/json" -X POST \ - http://localhost:9966/private/orders \ - -d '{"create_token":false, "order":{"amount":"TESTKUDOS:0.01","summary":"Minimal test order #3"}}' \ - | jq -er '.order_id'` -PAY3=taler+http://pay/localhost:9966/${ORDER_3}/ - -ORDER_4=`curl -s -H "Content-Type: application/json" -X POST \ - http://localhost:9966/private/orders \ - -d '{"create_token":false, "order":{"amount":"TESTKUDOS:0.01","summary":"Minimal test order #4"}}' \ - | jq -er '.order_id'` -PAY4=taler+http://pay/localhost:9966/${ORDER_4}/ - - -if [ "$STATUS" != "204" ] -then - echo 'should respond ok, order created. got:' $STATUS - exit 1 -fi - - -echo "OK" - -export CONF -export AUDITOR_PUB -export AUDITOR_URL -export EXCHANGE_URL -export WALLET_DB - -echo -n "Setting up keys ..." -taler-exchange-offline -L INFO -c $CONF \ - download \ - sign \ - enable-account payto://x-taler-bank/localhost/Exchange \ - enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \ - wire-fee now x-taler-bank TESTKUDOS:0.01 TESTKUDOS:0.01 \ - upload &> taler-exchange-offline.log - -echo -n "." - -for n in `seq 1 30` -do - echo -n "." - OK=0 - wget --tries=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue - OK=1 - sleep 0.1 - break -done - -if [ 1 != $OK ] -then - exit_skip "Failed to setup keys" -fi - -echo " OK" - -echo -n "Setting up auditor signatures ..." -taler-auditor-offline -L INFO -c $CONF \ - download sign upload &> taler-auditor-offline.log -echo " OK" - - -echo -n "First withdraw wallet" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ - "$(jq -n ' - { - amount: "TESTKUDOS:1", - bankBaseUrl: $BANK_URL, - exchangeBaseUrl: $EXCHANGE_URL - }' \ - --arg BANK_URL "$BANK_URL" \ - --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out -echo " OK" - - -echo -n "Pay first order ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri ${PAY1} -y 2> wallet-pay1.err > wallet-pay1.log -echo " OK" - -echo -n "Wait for keys to rotate, but not ALL to expire..." -sleep 20 -echo " OK" - - -echo -n "Updating keys ..." -taler-exchange-offline -L INFO -c $CONF \ - download \ - sign \ - upload &> taler-exchange-offline-2.log -taler-auditor-offline -L INFO -c $CONF \ - download sign upload &> taler-auditor-offline-2.log -echo " OK" - -echo -n "Second withdraw wallet" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ - "$(jq -n ' - { - amount: "TESTKUDOS:1", - bankBaseUrl: $BANK_URL, - exchangeBaseUrl: $EXCHANGE_URL - }' \ - --arg BANK_URL "$BANK_URL" \ - --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2>wallet-withdraw-2.err >wallet-withdraw-2.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-2.err >wallet-withdraw-finish-2.out -echo " OK" - -echo -n "Pay second order ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri ${PAY2} -y 2> wallet-pay2.err > wallet-pay2.log -echo " OK" - - -echo -n "Wait for keys to rotate, and original ones to expire..." -sleep 60 -echo " OK" - -date -echo -n "Updating keys ..." -taler-exchange-offline -c $CONF \ - download > taler-exchange-offline-download-3.log -taler-exchange-offline -c $CONF \ - download sign > taler-exchange-offline-sign-3.log -taler-exchange-offline -L INFO -c $CONF \ - download \ - sign \ - upload &> taler-exchange-offline-3.log -taler-auditor-offline -L INFO -c $CONF \ - download sign upload &> taler-auditor-offline-3.log -echo " OK" - -echo -n "Third withdraw wallet" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ - "$(jq -n ' - { - amount: "TESTKUDOS:1", - bankBaseUrl: $BANK_URL, - exchangeBaseUrl: $EXCHANGE_URL - }' \ - --arg BANK_URL "$BANK_URL" \ - --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2>wallet-withdraw-3.err >wallet-withdraw-3.out - -echo " OK" -date -echo -n "Waiting for wallet to finish ..." -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-3.err >wallet-withdraw-finish-3.out -echo " OK" - -echo -n "Pay third order ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri ${PAY3} -y 2> wallet-pay3.err > wallet-pay3.log -echo " OK" - - -echo -n "Wait for everything to expire..." -sleep 120 -echo " OK" - -echo -n "Updating keys ..." -taler-exchange-offline -L INFO -c $CONF \ - download \ - sign \ - upload &> taler-exchange-offline-4.log -taler-auditor-offline -L INFO -c $CONF \ - download sign upload &> taler-auditor-offline-4.log -echo " OK" - -echo -n "Fourth withdraw wallet" -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'withdrawTestBalance' \ - "$(jq -n ' - { - amount: "TESTKUDOS:1", - bankBaseUrl: $BANK_URL, - exchangeBaseUrl: $EXCHANGE_URL - }' \ - --arg BANK_URL "$BANK_URL" \ - --arg EXCHANGE_URL "$EXCHANGE_URL" - )" 2>wallet-withdraw-4.err >wallet-withdraw-4.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-4.err >wallet-withdraw-finish-4.out -echo " OK" - -echo -n "Pay fourth order ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri ${PAY4} -y 2> wallet-pay4.err > wallet-pay4.log -echo " OK" - - - - -exit 0 diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c index 507338e4..6ef40b45 100644 --- a/src/testing/test_kyc_api.c +++ b/src/testing/test_kyc_api.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -43,8 +43,6 @@ */ #define CONFIG_FILE "test_kyc_api.conf" -#define PAYTO_I1 "payto://x-taler-bank/localhost/3?receiver-name=3" - /** * Exchange base URL. Could also be taken from config. */ @@ -53,32 +51,27 @@ /** * Payto URI of the customer (payer). */ -static char *payer_payto; +static const char *payer_payto; /** * Payto URI of the exchange (escrow account). */ -static char *exchange_payto; +static const char *exchange_payto; /** * Payto URI of the merchant (receiver). */ -static char *merchant_payto; - -/** - * Configuration of the bank. - */ -static struct TALER_TESTING_BankConfiguration bc; +static const char *merchant_payto; /** - * Configuration of the exchange. + * Credentials for the test. */ -static struct TALER_TESTING_ExchangeConfiguration ec; +static struct TALER_TESTING_Credentials cred; /** * Merchant base URL. */ -static char *merchant_url; +static const char *merchant_url; /** * Merchant instance "i1a" base URL. @@ -86,11 +79,6 @@ static char *merchant_url; static char *merchant_url_i1a; /** - * Merchant process. - */ -static struct GNUNET_OS_Process *merchantd; - -/** * Account number of the exchange at the bank. */ #define EXCHANGE_ACCOUNT_NAME "2" @@ -101,18 +89,13 @@ static struct GNUNET_OS_Process *merchantd; #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" /** - * Execute the taler-exchange-aggregator, closer and transfer commands with + * Execute the taler-exchange-aggregator and transfer commands with * our configuration file. * * @param label label to use for the command. @@ -136,7 +119,7 @@ cmd_transfer_to_exchange (const char *label, { return TALER_TESTING_cmd_admin_add_incoming (label, amount, - &bc.exchange_auth, + &cred.ba, payer_payto); } @@ -155,157 +138,321 @@ run (void *cls, /** * Move money to the exchange's bank account. */ - cmd_transfer_to_exchange ("create-reserve-1", - "EUR:10.02"), + cmd_transfer_to_exchange ( + "create-reserve-1", + "EUR:10.02"), /** * Make a reserve exist, according to the previous transfer. */ - TALER_TESTING_cmd_exec_wirewatch ("wirewatch-1", - CONFIG_FILE), - 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", - 0, - MHD_HTTP_OK), - TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", - "create-reserve-1", - "EUR:5", - 0, - MHD_HTTP_OK), - TALER_TESTING_cmd_merchant_get_orders ("get-orders-empty", - merchant_url, - MHD_HTTP_OK, - NULL), + TALER_TESTING_cmd_exec_wirewatch ( + "wirewatch-1", + CONFIG_FILE), + 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", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-2", + "create-reserve-1", + "EUR:5", + 0, + 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_post_orders2 ("create-proposal-1", - merchant_url, - MHD_HTTP_OK, - "1", /* order ID */ - GNUNET_TIME_UNIT_ZERO_TS, - GNUNET_TIME_UNIT_FOREVER_TS, - true, - "EUR:5.0", - "x-taler-bank", - "", - "", - NULL), - TALER_TESTING_cmd_merchant_claim_order ("reclaim-1", - merchant_url, - MHD_HTTP_OK, - "create-proposal-1", - NULL), - TALER_TESTING_cmd_merchant_pay_order ("deposit-simple", - merchant_url, - MHD_HTTP_OK, - "create-proposal-1", - "withdraw-coin-1", - "EUR:5", - "EUR:4.99", - "session-0"), - TALER_TESTING_cmd_merchant_post_orders_paid ("verify-order-1-paid", - merchant_url, - "deposit-simple", - "session-1", - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"), - CMD_EXEC_AGGREGATOR ("run-aggregator"), + TALER_TESTING_cmd_status ( + "withdraw-status-1", + "create-reserve-1", + "EUR:0", + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_orders2 ( + "create-proposal-1", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "1", /* order ID */ + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + true, + "EUR:5.0", + "x-taler-bank", + "", + "", + NULL), + TALER_TESTING_cmd_merchant_claim_order ( + "reclaim-1", + merchant_url, + MHD_HTTP_OK, + "create-proposal-1", + NULL), + TALER_TESTING_cmd_merchant_pay_order ( + "deposit-simple", + merchant_url, + MHD_HTTP_OK, + "create-proposal-1", + "withdraw-coin-1", + "EUR:5", + "EUR:4.99", + "session-0"), + TALER_TESTING_cmd_merchant_post_orders_paid ( + "verify-order-1-paid", + merchant_url, + "deposit-simple", + "session-1", + MHD_HTTP_OK), + TALER_TESTING_cmd_check_bank_empty ( + "check_bank_empty-1"), + CMD_EXEC_AGGREGATOR ( + "run-aggregator"), /* KYC: hence nothing happened at the bank yet: */ - TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"), + TALER_TESTING_cmd_check_bank_empty ( + "check_bank_empty-2"), /* KYC: we don't even know the legitimization UUID yet */ - TALER_TESTING_cmd_merchant_kyc_get ("kyc-pending", - merchant_url, - NULL, - NULL, - EXCHANGE_URL, - MHD_HTTP_NO_CONTENT), - /* now we get the legi UUID */ - TALER_TESTING_cmd_merchant_get_order ("get-order-kyc", - merchant_url, - "create-proposal-1", - TALER_MERCHANT_OSC_PAID, - false, - MHD_HTTP_OK, - NULL), + TALER_TESTING_cmd_merchant_kyc_get ( + "kyc-pending-early", + merchant_url, + NULL, + NULL, + EXCHANGE_URL, + MHD_HTTP_NO_CONTENT, + TALER_AML_NORMAL), + /* now we get the legi UUID by running taler-merchant-depositcheck */ + TALER_TESTING_cmd_depositcheck ( + "deposit-check", + CONFIG_FILE), /* Now we should get a status of pending */ - TALER_TESTING_cmd_merchant_kyc_get ("kyc-pending", - merchant_url, - NULL, - NULL, - EXCHANGE_URL, - MHD_HTTP_ACCEPTED), - TALER_TESTING_cmd_proof_kyc_oauth2 ("kyc-do", - "kyc-pending", - "kyc-provider-test-oauth2", - "pass", - MHD_HTTP_SEE_OTHER), + TALER_TESTING_cmd_merchant_kyc_get ( + "kyc-pending", + merchant_url, + NULL, + NULL, + EXCHANGE_URL, + MHD_HTTP_ACCEPTED, + TALER_AML_NORMAL), + TALER_TESTING_cmd_proof_kyc_oauth2 ( + "kyc-do", + "kyc-pending", + "kyc-provider-test-oauth2", + "pass", + MHD_HTTP_SEE_OTHER), 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_check_bank_empty ("check_bank_empty-3"), + 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", + &cred.ba, + merchant_payto, + merchant_url, + "EUR:4.98", + MHD_HTTP_NO_CONTENT, + "deposit-simple", + NULL), + TALER_TESTING_cmd_run_tme ( + "run taler-merchant-exchange-1", + CONFIG_FILE), + TALER_TESTING_cmd_merchant_get_transfers ( + "get-transfers-1", + merchant_url, + merchant_payto, + MHD_HTTP_OK, + "post-transfer-1", + NULL), + TALER_TESTING_cmd_check_bank_empty ( + "check_bank_empty-3"), TALER_TESTING_cmd_end () }; + struct TALER_TESTING_Command aml[] = { + TALER_TESTING_cmd_set_officer ( + "aml-officer", + NULL, + "Ernest&Young", + true, + false), + cmd_transfer_to_exchange ( + "create-reserve-big", + "EUR:100.02"), + TALER_TESTING_cmd_exec_wirewatch ( + "wirewatch-big", + CONFIG_FILE), + TALER_TESTING_cmd_take_aml_decision ( + "freeze", + "aml-officer", + "post-transfer-1", + "EUR:1", + "suspicious", + TALER_AML_FROZEN, + NULL, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check_bank_transfer-big", + "EUR:100.02", + payer_payto, + exchange_payto, + "create-reserve-big"), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-aml", + "create-reserve-big", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_orders2 ( + "create-proposal-aml", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "10-aml", /* order ID */ + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + true, + "EUR:5.0", + "x-taler-bank", + "", + "", + NULL), + TALER_TESTING_cmd_merchant_claim_order ( + "reclaim-aml", + merchant_url, + MHD_HTTP_OK, + "create-proposal-aml", + NULL), + TALER_TESTING_cmd_merchant_pay_order ( + "deposit-simple", + merchant_url, + MHD_HTTP_OK, + "create-proposal-aml", + "withdraw-coin-aml", + "EUR:5", + "EUR:4.99", + "session-aml"), + TALER_TESTING_cmd_merchant_post_orders_paid ( + "verify-order-aml-paid", + merchant_url, + "deposit-simple", + "session-aml", + MHD_HTTP_OK), + TALER_TESTING_cmd_check_bank_empty ( + "check_bank_empty-aml-1"), + CMD_EXEC_AGGREGATOR ("run-aggregator-aml-frozen"), + /* AML-frozen: hence nothing happened at the bank yet: */ + TALER_TESTING_cmd_check_bank_empty ( + "check_bank_empty-aml-2"), + /* Now we should get a status of frozen */ + TALER_TESTING_cmd_merchant_kyc_get ( + "aml-frozen", + merchant_url, + NULL, /* no instance ID */ + NULL, /* no wire ref */ + EXCHANGE_URL, + MHD_HTTP_ACCEPTED, + TALER_AML_FROZEN), + TALER_TESTING_cmd_sleep ( + "sleep to de-collide AML timestamps", + 1), + TALER_TESTING_cmd_take_aml_decision ( + "unfreeze", + "aml-officer", + "post-transfer-1", + "EUR:100", + "fine", + TALER_AML_NORMAL, + NULL, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_kyc_get ( + "aml-unfrozen", + merchant_url, + NULL, /* no instance ID */ + NULL, /* no wire ref */ + EXCHANGE_URL, + MHD_HTTP_NO_CONTENT, + TALER_AML_NORMAL), + CMD_EXEC_AGGREGATOR ("run-aggregator-aml-normal"), + TALER_TESTING_cmd_check_bank_transfer ( + "check_bank_transfer-498c-post-unfreeze", + EXCHANGE_URL, + "EUR:4.98", + exchange_payto, + merchant_payto), + TALER_TESTING_cmd_merchant_post_transfer ( + "post-transfer-aml", + &cred.ba, + merchant_payto, + merchant_url, + "EUR:4.98", + MHD_HTTP_NO_CONTENT, + "deposit-simple", + NULL), + TALER_TESTING_cmd_run_tme ( + "run taler-merchant-exchange-2-aml", + CONFIG_FILE), + TALER_TESTING_cmd_merchant_get_transfers ( + "get-transfers-aml", + merchant_url, + merchant_payto, + MHD_HTTP_OK, + "post-transfer-1", + "post-transfer-aml", + NULL), + TALER_TESTING_cmd_end () + }; /* end of aml batch */ struct TALER_TESTING_Command commands[] = { /* general setup */ - TALER_TESTING_cmd_oauth ("start-oauth-service", - 6666), - TALER_TESTING_cmd_auditor_add ("add-auditor-OK", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_wire_add ("add-wire-account", - "payto://x-taler-bank/localhost/2?receiver-name=2", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys", - CONFIG_FILE), - TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees", - CONFIG_FILE, - "EUR:0.01", - "EUR:0.01"), - TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", - 1), - TALER_TESTING_cmd_merchant_post_instances ("instance-create-default-setup", - merchant_url, - "default", - PAYTO_I1, - "EUR", - MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_run_fakebank ( + "run-fakebank", + cred.cfg, + "exchange-account-exchange"), + TALER_TESTING_cmd_system_start ( + "start-taler", + CONFIG_FILE, + "-ema", + "-u", "exchange-account-exchange", + NULL), + TALER_TESTING_cmd_get_exchange ( + "get-exchange", + cred.cfg, + NULL, + true, + true), + TALER_TESTING_cmd_oauth ( + "start-oauth-service", + 6666), + TALER_TESTING_cmd_merchant_post_instances ( + "instance-create-default-setup", + merchant_url, + "default", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + merchant_url, + merchant_payto, + NULL, NULL, + MHD_HTTP_OK), TALER_TESTING_cmd_batch ("pay", pay), + TALER_TESTING_cmd_batch ("aml", + aml), TALER_TESTING_cmd_end () }; - TALER_TESTING_run_with_fakebank (is, - commands, - bc.exchange_auth.wire_gateway_url); + TALER_TESTING_run (is, + commands); } @@ -313,68 +460,28 @@ int main (int argc, char *const *argv) { - enum GNUNET_GenericReturnValue ret; - - /* These environment variables get in the way... */ - unsetenv ("XDG_DATA_HOME"); - unsetenv ("XDG_CONFIG_HOME"); - GNUNET_log_setup ("test-kyc-api", - "INFO", - 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 "?receiver-name=" - USER_ACCOUNT_NAME); + "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=" + USER_ACCOUNT_NAME; exchange_payto = - ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" - EXCHANGE_ACCOUNT_NAME); + "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" + EXCHANGE_ACCOUNT_NAME; merchant_payto = - ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" - MERCHANT_ACCOUNT_NAME); - - if (NULL == - (merchant_url = TALER_TESTING_prepare_merchant (CONFIG_FILE))) - return 77; + "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" + MERCHANT_ACCOUNT_NAME; + merchant_url = "http://localhost:8080/"; GNUNET_asprintf (&merchant_url_i1a, "%sinstances/i1a/", merchant_url); - 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; + return TALER_TESTING_main (argv, + "INFO", + CONFIG_FILE, + "exchange-account-exchange", + TALER_TESTING_BS_FAKEBANK, + &cred, + &run, + NULL); } -/* end of test_merchant_api.c */ +/* end of test_kyc_api.c */ diff --git a/src/testing/test_kyc_api.conf b/src/testing/test_kyc_api.conf index c7615cf7..bbbfc17c 100644 --- a/src/testing/test_kyc_api.conf +++ b/src/testing/test_kyc_api.conf @@ -1,109 +1,46 @@ # This file is in the public domain. # [PATHS] -# Persistent data storage for the testcase TALER_TEST_HOME = test_merchant_api_home/ -TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/ - -# Persistent data storage -TALER_DATA_HOME = $TALER_HOME/.local/share/taler/ - -# Configuration files -TALER_CONFIG_HOME = $TALER_HOME/.config/taler/ - -# Cached data, no big deal if lost -TALER_CACHE_HOME = $TALER_HOME/.cache/taler/ [taler] -# What currency do we use? CURRENCY = EUR CURRENCY_ROUND_UNIT = EUR:0.01 [taler-helper-crypto-rsa] -# Reduce from 1 year to speed up test LOOKAHEAD_SIGN = 24 days [taler-helper-crypto-eddsa] -# Reduce from 1 year to speed up test LOOKAHEAD_SIGN = 24 days -# Reduce from 12 weeks to ensure we have multiple DURATION = 14 days [bank] HTTP_PORT = 8082 -########################################## -# Configuration for the merchant backend # -########################################## - [merchant] - -# Which port do we run the backend on? (HTTP server) PORT = 8080 - -# Which plugin (backend) do we use for the DB. +SERVE = tcp DB = postgres # This specifies which database the postgres backend uses. [merchantdb-postgres] CONFIG = postgres:///talercheck +SQL_DIR = $DATADIR/sql/merchant/ -# Sections starting with "merchant-exchange-" specify trusted exchanges -# (by the merchant) [merchant-exchange-test] -MASTER_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG +MASTER_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 EXCHANGE_BASE_URL = http://localhost:8081/ CURRENCY = EUR - -####################################################### -# Configuration for the auditor for the testcase -####################################################### -[auditor] -BASE_URL = http://the.auditor/ - [auditordb-postgres] CONFIG = postgres:///talercheck - -####################################################### -# Configuration for ??? Is this used? -####################################################### - -# Auditors must be in sections "auditor-", the rest of the section -# name could be anything. -[auditor-ezb] -# Informal name of the auditor. Just for the user. -NAME = European Central Bank - -# URL of the auditor (especially for in the future, when the -# auditor offers an automated issue reporting system). -# Not really used today. -URL = http://taler.ezb.eu/ - -# This is the important bit: the signing key of the auditor. -PUBLIC_KEY = 9QXF7XY7E9VPV47B5Z806NDFSX2VJ79SVHHD29QEQ3BG31ANHZ60 - -# Which currency is this auditor trusted for? -CURRENCY = EUR - - -################################################### -# Configuration for the exchange for the testcase # -################################################### - [exchange] -# How to access our database -DB = postgres - -# HTTP port the exchange listens to +AML_THRESHOLD = EUR:1000000 PORT = 8081 - -# Our public key -MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG - -# Base URL of the exchange. +MASTER_PUBLIC_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 BASE_URL = "http://localhost:8081/" +STEFAN_ABS = "EUR:5" [kyc-provider-test-oauth2] COST = 0 @@ -111,12 +48,13 @@ LOGIC = oauth2 USER_TYPE = BUSINESS PROVIDED_CHECKS = DUMMY KYC_OAUTH2_VALIDITY = forever -KYC_OAUTH2_AUTH_URL = http://localhost:6666/oauth/v2/token -KYC_OAUTH2_LOGIN_URL = http://localhost:6666/oauth/v2/login +KYC_OAUTH2_TOKEN_URL = http://localhost:6666/oauth/v2/token +KYC_OAUTH2_AUTHORIZE_URL = http://localhost:6666/oauth/v2/login KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me KYC_OAUTH2_CLIENT_ID = taler-exchange KYC_OAUTH2_CLIENT_SECRET = exchange-secret KYC_OAUTH2_POST_URL = http://example.com/ +KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh [kyc-legitimization-deposit-any] OPERATION_TYPE = DEPOSIT @@ -140,13 +78,16 @@ CONFIG = "postgres:///talercheck" # Account of the EXCHANGE [exchange-account-exchange] -# What is the exchange's bank account (with the "Taler Bank" demo system)? PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" ENABLE_DEBIT = YES ENABLE_CREDIT = YES [exchange-accountcredentials-exchange] -WIRE_GATEWAY_URL = "http://localhost:8082/2/" +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = NONE + +[admin-accountcredentials-exchange] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = NONE diff --git a/src/testing/test_merchant_api-cs.conf b/src/testing/test_merchant_api-cs.conf index 502d807a..4d1c14b6 100644 --- a/src/testing/test_merchant_api-cs.conf +++ b/src/testing/test_merchant_api-cs.conf @@ -1,127 +1,5 @@ # This file is in the public domain. -# -[PATHS] -# Persistent data storage for the testcase -TALER_TEST_HOME = test_merchant_api_home/ -TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/ - -# Persistent data storage -TALER_DATA_HOME = $TALER_HOME/.local/share/taler/ - -# Configuration files -TALER_CONFIG_HOME = $TALER_HOME/.config/taler/ - -# Cached data, no big deal if lost -TALER_CACHE_HOME = $TALER_HOME/.cache/taler/ - -[taler] -# What currency do we use? -CURRENCY = EUR -CURRENCY_ROUND_UNIT = EUR:0.01 - -[taler-helper-crypto-rsa] -# Reduce from 1 year to speed up test -LOOKAHEAD_SIGN = 24 days - -[taler-helper-crypto-eddsa] -# Reduce from 1 year to speed up test -LOOKAHEAD_SIGN = 24 days -# Reduce from 12 weeks to ensure we have multiple -DURATION = 14 days - -[bank] -HTTP_PORT = 8082 - -########################################## -# Configuration for the merchant backend # -########################################## - -[merchant] - -# Which port do we run the backend on? (HTTP server) -PORT = 8080 - -# Which plugin (backend) do we use for the DB. -DB = postgres - -# This specifies which database the postgres backend uses. -[merchantdb-postgres] -CONFIG = postgres:///talercheck - -# Sections starting with "merchant-exchange-" specify trusted exchanges -# (by the merchant) -[merchant-exchange-test] -MASTER_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG -EXCHANGE_BASE_URL = http://localhost:8081/ -CURRENCY = EUR - - -####################################################### -# Configuration for the auditor for the testcase -####################################################### -[auditor] -BASE_URL = http://the.auditor/ - - -####################################################### -# Configuration for ??? Is this used? -####################################################### - -# Auditors must be in sections "auditor-", the rest of the section -# name could be anything. -[auditor-ezb] -# Informal name of the auditor. Just for the user. -NAME = European Central Bank - -# URL of the auditor (especially for in the future, when the -# auditor offers an automated issue reporting system). -# Not really used today. -URL = http://taler.ezb.eu/ - -# This is the important bit: the signing key of the auditor. -PUBLIC_KEY = 9QXF7XY7E9VPV47B5Z806NDFSX2VJ79SVHHD29QEQ3BG31ANHZ60 - -# Which currency is this auditor trusted for? -CURRENCY = EUR - - -################################################### -# Configuration for the exchange for the testcase # -################################################### - -[exchange] -# How to access our database -DB = postgres - -# HTTP port the exchange listens to -PORT = 8081 - -# Our public key -MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG - -# Base URL of the exchange. -BASE_URL = "http://localhost:8081/" - - -[exchangedb-postgres] -CONFIG = "postgres:///talercheck" - - -[auditordb-postgres] -CONFIG = postgres:///talercheck - - -# Account of the EXCHANGE -[exchange-account-exchange] -# What is the exchange's bank account (with the "Taler Bank" demo system)? -PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" -ENABLE_DEBIT = YES -ENABLE_CREDIT = YES - -[exchange-accountcredentials-exchange] -WIRE_GATEWAY_URL = "http://localhost:8082/2/" -WIRE_GATEWAY_AUTH_METHOD = NONE - +@INLINE@ test_merchant_api.conf [coin_eur_ct_1] value = EUR:0.01 diff --git a/src/testing/test_merchant_api-rsa.conf b/src/testing/test_merchant_api-rsa.conf index 5246fc40..44d8e978 100644 --- a/src/testing/test_merchant_api-rsa.conf +++ b/src/testing/test_merchant_api-rsa.conf @@ -1,127 +1,5 @@ # This file is in the public domain. -# -[PATHS] -# Persistent data storage for the testcase -TALER_TEST_HOME = test_merchant_api_home/ -TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/${USER:-}/taler-system-runtime/ - -# Persistent data storage -TALER_DATA_HOME = $TALER_HOME/.local/share/taler/ - -# Configuration files -TALER_CONFIG_HOME = $TALER_HOME/.config/taler/ - -# Cached data, no big deal if lost -TALER_CACHE_HOME = $TALER_HOME/.cache/taler/ - -[taler] -# What currency do we use? -CURRENCY = EUR -CURRENCY_ROUND_UNIT = EUR:0.01 - -[taler-helper-crypto-rsa] -# Reduce from 1 year to speed up test -LOOKAHEAD_SIGN = 24 days - -[taler-helper-crypto-eddsa] -# Reduce from 1 year to speed up test -LOOKAHEAD_SIGN = 24 days -# Reduce from 12 weeks to ensure we have multiple -DURATION = 14 days - -[bank] -HTTP_PORT = 8082 - -########################################## -# Configuration for the merchant backend # -########################################## - -[merchant] - -# Which port do we run the backend on? (HTTP server) -PORT = 8080 - -# Which plugin (backend) do we use for the DB. -DB = postgres - -# This specifies which database the postgres backend uses. -[merchantdb-postgres] -CONFIG = postgres:///talercheck - -# Sections starting with "merchant-exchange-" specify trusted exchanges -# (by the merchant) -[merchant-exchange-test] -MASTER_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG -EXCHANGE_BASE_URL = http://localhost:8081/ -CURRENCY = EUR - - -####################################################### -# Configuration for the auditor for the testcase -####################################################### -[auditor] -BASE_URL = http://the.auditor/ - - -####################################################### -# Configuration for ??? Is this used? -####################################################### - -# Auditors must be in sections "auditor-", the rest of the section -# name could be anything. -[auditor-ezb] -# Informal name of the auditor. Just for the user. -NAME = European Central Bank - -# URL of the auditor (especially for in the future, when the -# auditor offers an automated issue reporting system). -# Not really used today. -URL = http://taler.ezb.eu/ - -# This is the important bit: the signing key of the auditor. -PUBLIC_KEY = 9QXF7XY7E9VPV47B5Z806NDFSX2VJ79SVHHD29QEQ3BG31ANHZ60 - -# Which currency is this auditor trusted for? -CURRENCY = EUR - - -################################################### -# Configuration for the exchange for the testcase # -################################################### - -[exchange] -# How to access our database -DB = postgres - -# HTTP port the exchange listens to -PORT = 8081 - -# Our public key -MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG - -# Base URL of the exchange. -BASE_URL = "http://localhost:8081/" - - -[exchangedb-postgres] -CONFIG = "postgres:///talercheck" - - -[auditordb-postgres] -CONFIG = postgres:///talercheck - - -# Account of the EXCHANGE -[exchange-account-exchange] -# What is the exchange's bank account (with the "Taler Bank" demo system)? -PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" -ENABLE_DEBIT = YES -ENABLE_CREDIT = YES - -[exchange-accountcredentials-exchange] -WIRE_GATEWAY_URL = "http://localhost:8082/2/" -WIRE_GATEWAY_AUTH_METHOD = NONE - +@INLINE@ test_merchant_api.conf [coin_eur_ct_1] value = EUR:0.01 diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index a04bbe57..3f9136bc 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -24,6 +24,7 @@ * @author Marcello Stanisci */ #include "platform.h" +#include <gnunet/gnunet_time_lib.h> #include <taler/taler_util.h> #include <taler/taler_signatures.h> #include <taler/taler_exchange_service.h> @@ -66,39 +67,30 @@ static char *config_file; */ #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; +static const char *payer_payto; /** * Payto URI of the exchange (escrow account). */ -static char *exchange_payto; +static const char *exchange_payto; /** * Payto URI of the merchant (receiver). */ -static char *merchant_payto; - -/** - * Configuration of the bank. - */ -static struct TALER_TESTING_BankConfiguration bc; +static const char *merchant_payto; /** - * Configuration of the exchange. + * Credentials for the test. */ -static struct TALER_TESTING_ExchangeConfiguration ec; +static struct TALER_TESTING_Credentials cred; /** * Merchant base URL. */ -static char *merchant_url; +static const char *merchant_url; /** * Merchant instance "i1a" base URL. @@ -106,11 +98,6 @@ static char *merchant_url; static char *merchant_url_i1a; /** - * Merchant process. - */ -static struct GNUNET_OS_Process *merchantd; - -/** * Account number of the exchange at the bank. */ #define EXCHANGE_ACCOUNT_NAME "2" @@ -130,38 +117,41 @@ static struct GNUNET_OS_Process *merchantd; */ #define MERCHANT_ACCOUNT_NAME "3" -/** - * Payto URIs to use for testing accounts on the merchant. - */ -const char *payto_uris[] = { - PAYTO_I1, - "payto://iban/CH9300762011623852957?receiver-name=Test" - /* Just for testing account inactivation. */ -}; - -const char *order_1_transfers[] = { +static const char *order_1_transfers[] = { "post-transfer-1", NULL }; -const char *order_1_forgets_1[] = { +static const char *order_1_forgets_1[] = { "forget-1", NULL }; -const char *order_1_forgets_2[] = { +static const char *order_1_forgets_2[] = { "forget-1", "forget-order-array-elem", NULL }; -const char *order_1_forgets_3[] = { +static const char *order_1_forgets_3[] = { "forget-1", "forget-order-array-elem", "forget-order-array-wc", 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 @@ -202,7 +192,7 @@ cmd_transfer_to_exchange (const char *label, { return TALER_TESTING_cmd_admin_add_incoming (label, amount, - &bc.exchange_auth, + &cred.ba, payer_payto); } @@ -221,15 +211,28 @@ run (void *cls, TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", merchant_url, "default", - PAYTO_I1, - "EUR", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + merchant_url, + PAYTO_I1, + NULL, NULL, + MHD_HTTP_OK), TALER_TESTING_cmd_merchant_kyc_get ("instance-create-kyc-0", merchant_url, NULL, NULL, EXCHANGE_URL, - MHD_HTTP_NO_CONTENT), + MHD_HTTP_NO_CONTENT, + TALER_AML_NORMAL), + TALER_TESTING_cmd_merchant_post_orders_no_claim ( + "create-proposal-bad-currency", + merchant_url, + MHD_HTTP_BAD_REQUEST, + "4", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + "CHF:5.0"), TALER_TESTING_cmd_merchant_post_orders_no_claim ("create-proposal-4", merchant_url, MHD_HTTP_OK, @@ -304,9 +307,10 @@ run (void *cls, NULL, "1"), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1", + cred.cfg, merchant_url, MHD_HTTP_OK, - "1", /* order ID */ + "1", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, true, @@ -315,10 +319,18 @@ 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", + cred.cfg, merchant_url, MHD_HTTP_OK, - "1", /* order ID */ + "1", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, true, @@ -328,9 +340,10 @@ run (void *cls, "", "create-proposal-1"), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1x", + cred.cfg, merchant_url, MHD_HTTP_OK, - "1x", /* order ID */ + "1x", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, true, @@ -355,6 +368,7 @@ run (void *cls, "create-proposal-1x", NULL), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1-pre-exists", + cred.cfg, merchant_url, MHD_HTTP_CONFLICT, "1", @@ -414,6 +428,13 @@ run (void *cls, MHD_HTTP_OK, NULL, "poll-order-wallet-start-1"), + /* Check for webhook */ + cmd_webhook ("pending-webhooks-pay-w1"), + /* 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", + "launch-http-server-for-webhooks", + 0), /* 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, @@ -424,7 +445,7 @@ run (void *cls, merchant_url, "deposit-simple", "session-1", - MHD_HTTP_NO_CONTENT), + MHD_HTTP_OK), TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2", merchant_url, "create-proposal-1", @@ -432,7 +453,7 @@ run (void *cls, false, false, MHD_HTTP_OK), - TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2", + TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2a", merchant_url, "create-proposal-1", TALER_MERCHANT_OSC_PAID, @@ -461,23 +482,25 @@ run (void *cls, exchange_payto, merchant_payto), TALER_TESTING_cmd_merchant_post_transfer ("post-transfer-1", - &bc.exchange_auth, + &cred.ba, PAYTO_I1, merchant_url, "EUR:4.98", - MHD_HTTP_OK, + MHD_HTTP_NO_CONTENT, "deposit-simple", NULL), + TALER_TESTING_cmd_run_tme ("run taler-merchant-exchange-1", + config_file), TALER_TESTING_cmd_merchant_post_transfer2 ("post-transfer-bad", merchant_url, PAYTO_I1, "EUR:4.98", - NULL /* random WTID */, - /* non-routable IP address, - so we are sure to not get - any reply */ + NULL, + /*non-routable IP address + so we are sure to not get + any reply*/ "http://192.0.2.1/404/", - MHD_HTTP_GATEWAY_TIMEOUT), + MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_get_transfers ("get-transfers-1", merchant_url, PAYTO_I1, @@ -489,19 +512,19 @@ run (void *cls, merchant_url, "post-transfer-bad", MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-2", + TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-2b", merchant_url, "create-proposal-1", TALER_MERCHANT_OSC_PAID, true, - order_1_transfers, + order_1_transfers, /* "post-transfer-1" */ false, NULL, NULL, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_forget_order ("forget-1", merchant_url, - MHD_HTTP_OK, + MHD_HTTP_NO_CONTENT, "create-proposal-1", NULL, "$.dummy_obj", @@ -532,7 +555,7 @@ run (void *cls, NULL), TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-elem", merchant_url, - MHD_HTTP_OK, + MHD_HTTP_NO_CONTENT, "create-proposal-1", NULL, "$.dummy_array[0].item", @@ -549,7 +572,7 @@ run (void *cls, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-wc", merchant_url, - MHD_HTTP_OK, + MHD_HTTP_NO_CONTENT, "create-proposal-1", NULL, "$.dummy_array[*].item", @@ -577,6 +600,20 @@ run (void *cls, "a product", "EUR:1", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_products2 ("post-products-p4", + merchant_url, + "product-4age", + "an age-restricted product", + NULL, + "unit", + "EUR:1", + "", /* image */ + NULL, + 4, + 16 /* minimum age */, + NULL, + GNUNET_TIME_UNIT_FOREVER_TS, + MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3", merchant_url, "product-3", @@ -599,18 +636,20 @@ run (void *cls, 2, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-wm-nx", + cred.cfg, merchant_url, MHD_HTTP_NOT_FOUND, "order-p3", GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, - true, /* claim token */ + true, "EUR:5.0", "unsupported-wire-method", "product-3/2", "", /* locks */ - NULL /* duplicate_of */), + NULL), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-pd-nx", + cred.cfg, merchant_url, MHD_HTTP_NOT_FOUND, "order-p3", @@ -624,6 +663,7 @@ run (void *cls, NULL), TALER_TESTING_cmd_merchant_post_orders2 ( "create-proposal-p3-not-enough-stock", + cred.cfg, merchant_url, MHD_HTTP_GONE, "order-p3", @@ -636,6 +676,7 @@ run (void *cls, "", NULL), TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3", + cred.cfg, merchant_url, MHD_HTTP_OK, "order-p3", @@ -647,23 +688,47 @@ run (void *cls, "product-3/3", "lock-product-p3", NULL), + TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p4-age", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "order-p4-age", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + false, + "EUR:5.0", + "x-taler-bank", + "product-4age", + "", /* locks */ + NULL), + TALER_TESTING_cmd_merchant_get_order4 ("get-order-merchant-p4-age", + merchant_url, + "create-proposal-p4-age", + TALER_MERCHANT_OSC_CLAIMED, + 16, + MHD_HTTP_OK), TALER_TESTING_cmd_merchant_delete_order ("delete-order-paid", merchant_url, "1", MHD_HTTP_CONFLICT), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-no-id", + cred.cfg, merchant_url, MHD_HTTP_OK, NULL, 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 () }; - struct TALER_TESTING_Command double_spending[] = { TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2", + cred.cfg, merchant_url, MHD_HTTP_OK, "2", @@ -721,6 +786,7 @@ run (void *cls, "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1r", + cred.cfg, merchant_url, MHD_HTTP_OK, "1r", @@ -823,6 +889,7 @@ run (void *cls, /* Test /refund on a contract that was never paid. */ TALER_TESTING_cmd_merchant_post_orders ("create-proposal-not-to-be-paid", + cred.cfg, merchant_url, MHD_HTTP_OK, "1-unpaid", @@ -867,6 +934,7 @@ run (void *cls, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ( "create-proposal-unincreased-refund", + cred.cfg, merchant_url, MHD_HTTP_OK, "unincreased-proposal", @@ -897,9 +965,13 @@ run (void *cls, TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1a", merchant_url, "i1a", - PAYTO_I1, - "EUR", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-i1a-account", + merchant_url_i1a, + PAYTO_I1, + NULL, NULL, + MHD_HTTP_OK), TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-1", merchant_url_i1a, "nx-product", @@ -987,183 +1059,6 @@ run (void *cls, 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", - MHD_HTTP_OK), - /* We need to wait until the merchant re-tries fetching the - reserve from the exchange. */ - cmd_exec_wirewatch ("wirewatch-3"), - TALER_TESTING_cmd_sleep ("tip-sleep", 3), - 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-exch", - 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-exch", - NULL), - TALER_TESTING_cmd_merchant_get_reserve ("get-reserve-1", - merchant_url, - MHD_HTTP_OK, - "create-reserve-tip-1-exch"), - TALER_TESTING_cmd_merchant_get_reserve_with_tips ("get-reserve-2", - merchant_url, - MHD_HTTP_OK, - "create-reserve-tip-1-exch", - "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_MERCHANT_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_MERCHANT_PRIVATE_POST_TIP_AUTHORIZE_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", - MHD_HTTP_OK), - cmd_exec_wirewatch ("wirewatch-4"), - 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_MERCHANT_PRIVATE_POST_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_MERCHANT_GENERIC_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), - TALER_TESTING_cmd_end () - }; - struct TALER_TESTING_Command pay_again[] = { cmd_transfer_to_exchange ("create-reserve-20", "EUR:20.04"), @@ -1198,6 +1093,7 @@ run (void *cls, "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-10", + cred.cfg, merchant_url, MHD_HTTP_OK, "10", @@ -1262,6 +1158,7 @@ run (void *cls, "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-11", + cred.cfg, merchant_url, MHD_HTTP_OK, "11", @@ -1270,7 +1167,7 @@ run (void *cls, "EUR:10.0"), TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-good", merchant_url, - MHD_HTTP_NOT_ACCEPTABLE, + MHD_HTTP_BAD_REQUEST, "create-proposal-11", "withdraw-coin-11a", "EUR:5", @@ -1294,6 +1191,38 @@ run (void *cls, }; struct TALER_TESTING_Command templates[] = { + cmd_transfer_to_exchange ("create-reserve-20x", + "EUR:20.04"), + cmd_exec_wirewatch ("wirewatch-20x"), + TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-20x", + "EUR:20.04", + payer_payto, + exchange_payto, + "create-reserve-20x"), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xa", + "create-reserve-20x", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xb", + "create-reserve-20x", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xc", + "create-reserve-20x", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xd", + "create-reserve-20x", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_status ("withdraw-status-20x", + "create-reserve-20x", + "EUR:0", + MHD_HTTP_OK), TALER_TESTING_cmd_merchant_get_templates ("get-templates-empty", merchant_url, MHD_HTTP_OK, @@ -1333,11 +1262,11 @@ run (void *cls, merchant_url, "template-2", "another template", - "data:image/jpeg;base64,RAWDATA", + NULL, GNUNET_JSON_PACK ( - GNUNET_JSON_pack_uint64 ("minimum_age", 0), - GNUNET_JSON_pack_time_rel ("pay_duration", - GNUNET_TIME_UNIT_MINUTES)), + GNUNET_JSON_pack_uint64 ("minimum_age", 0), + GNUNET_JSON_pack_time_rel ("pay_duration", + GNUNET_TIME_UNIT_MINUTES)), MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_get_template ("get-template-t2", merchant_url, @@ -1349,16 +1278,25 @@ run (void *cls, "template-nx", MHD_HTTP_NOT_FOUND, NULL), + TALER_TESTING_cmd_merchant_post_otp_devices ( + "post-otp-device", + merchant_url, + "otp-dev", + "my OTP device", + "FEE4P2J", + TALER_MCA_WITH_PRICE, + 0, + MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_patch_template ( "patch-templates-t3-nx", merchant_url, "template-3", "updated template", - "data:image/jpeg;base64,RAWDATA", + "otp-dev", GNUNET_JSON_PACK ( - GNUNET_JSON_pack_uint64 ("minimum_age", 0), - GNUNET_JSON_pack_time_rel ("pay_duration", - GNUNET_TIME_UNIT_MINUTES)), + GNUNET_JSON_pack_uint64 ("minimum_age", 0), + GNUNET_JSON_pack_time_rel ("pay_duration", + GNUNET_TIME_UNIT_MINUTES)), MHD_HTTP_NOT_FOUND), TALER_TESTING_cmd_merchant_post_templates2 ( "post-templates-t3-amount", @@ -1367,47 +1305,75 @@ run (void *cls, "a different template with an amount", NULL, GNUNET_JSON_PACK ( - GNUNET_JSON_pack_uint64 ("minimum_age", 0), - GNUNET_JSON_pack_time_rel ("pay_duration", - GNUNET_TIME_UNIT_MINUTES), - GNUNET_JSON_pack_string ("amount", - "EUR:4")), + GNUNET_JSON_pack_uint64 ("minimum_age", 0), + GNUNET_JSON_pack_time_rel ("pay_duration", + GNUNET_TIME_UNIT_MINUTES), + GNUNET_JSON_pack_string ("amount", + "EUR:4")), MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_using_templates ( "using-templates-t1", "post-templates-t1", + NULL, merchant_url, + "1", "summary-1", - "EUR:10", + "EUR:9.98", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_using_templates ( "using-templates-t1-amount-missing", "post-templates-t1", + NULL, merchant_url, + "2", "summary-1", NULL, + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_CONFLICT), TALER_TESTING_cmd_merchant_post_using_templates ( "using-templates-t1-summary-missing", "post-templates-t1", + NULL, merchant_url, + "3", NULL, "EUR:10", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_CONFLICT), TALER_TESTING_cmd_merchant_post_using_templates ( "using-templates-t1-amount-conflict", "post-templates-t3-amount", + NULL, merchant_url, + "4", "summary-1", "EUR:10", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_CONFLICT), TALER_TESTING_cmd_merchant_post_using_templates ( "using-templates-t1-amount-duplicate", "post-templates-t3-amount", + NULL, merchant_url, + "4", "summary-1", "EUR:4", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_CONFLICT), + TALER_TESTING_cmd_merchant_pay_order ("pay-100", + merchant_url, + MHD_HTTP_OK, + "using-templates-t1", + "withdraw-coin-xa;withdraw-coin-xb", + "EUR:4.99", + "EUR:4.99", + NULL), TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty", merchant_url, "t1", @@ -1419,10 +1385,56 @@ run (void *cls, TALER_TESTING_cmd_merchant_post_using_templates ( "post-templates-t1-deleted", "post-templates-t1", + NULL, merchant_url, + "0", "summary-1", "EUR:5", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, MHD_HTTP_NOT_FOUND), + TALER_TESTING_cmd_merchant_post_otp_devices ( + "post-otp-device", + merchant_url, + "otp-dev-2", + "my OTP device", + "secret", + TALER_MCA_WITH_PRICE, + 0, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_templates2 ( + "post-templates-with-pos-key", + merchant_url, + "template-key", + "a different template with POS KEY", + "otp-dev-2", + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_uint64 ("minimum_age", 0), + GNUNET_JSON_pack_time_rel ("pay_duration", + GNUNET_TIME_UNIT_MINUTES)), + MHD_HTTP_NO_CONTENT), + + TALER_TESTING_cmd_merchant_post_using_templates ( + "using-templates-pos-key", + "post-templates-with-pos-key", + "post-otp-device", + merchant_url, + "1", + "summary-1-pos", + "EUR:9.98", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_pay_order ("pay-with-pos", + merchant_url, + MHD_HTTP_OK, + "using-templates-pos-key", + "withdraw-coin-xc;withdraw-coin-xd", + "EUR:4.99", + "EUR:4.99", + NULL), + + TALER_TESTING_cmd_end () }; @@ -1465,7 +1477,7 @@ run (void *cls, merchant_url, "webhook-2", "Refund2", - "https://example.com", + "http://localhost:38188/", "POST", "Authorization:WHWOXZXPLL", "Amount", @@ -1499,108 +1511,264 @@ run (void *cls, MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_end () }; + struct TALER_TESTING_Command repurchase[] = { + cmd_transfer_to_exchange ( + "create-reserve-30x", + "EUR:30.06"), + cmd_exec_wirewatch ( + "wirewatch-30x"), + TALER_TESTING_cmd_check_bank_admin_transfer ( + "check_bank_transfer-30x", + "EUR:30.06", + payer_payto, + exchange_payto, + "create-reserve-30x"), + TALER_TESTING_cmd_withdraw_amount ( + "withdraw-coin-rep", + "create-reserve-30x", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_orders3 ( + "post-order-repurchase-original", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "repurchase-original", + GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES), + GNUNET_TIME_UNIT_FOREVER_TS, + "https://fulfillment.example.com/", + "EUR:1.0"), + TALER_TESTING_cmd_merchant_pay_order ( + "repurchase-pay-first", + merchant_url, + MHD_HTTP_OK, + "post-order-repurchase-original", + "withdraw-coin-rep", + "EUR:1.00", + "EUR:0.99", + "repurchase-session"), + TALER_TESTING_cmd_wallet_get_order ( + "repurchase-wallet-check-primary-order", + merchant_url, + "post-order-repurchase-original", + true, + false, + false, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_order3 ( + "repurchase-check-primary-payment", + merchant_url, + "post-order-repurchase-original", + TALER_MERCHANT_OSC_PAID, + "repurchase-session", + NULL, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_order3 ( + "repurchase-check-primary-payment-bad-binding", + merchant_url, + "post-order-repurchase-original", + TALER_MERCHANT_OSC_CLAIMED, /* someone else has it! */ + "wrong-session", + NULL, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_orders3 ( + "post-order-repurchase-secondary", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "repurchase-secondary", + GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES), + GNUNET_TIME_UNIT_FOREVER_TS, + "https://fulfillment.example.com/", + "EUR:1.0"), + TALER_TESTING_cmd_merchant_get_order3 ( + "repurchase-check-secondary-payment", + merchant_url, + "post-order-repurchase-secondary", + TALER_MERCHANT_OSC_UNPAID, + "repurchase-session", + NULL, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_order3 ( + "repurchase-check-secondary-payment", + merchant_url, + "post-order-repurchase-secondary", + TALER_MERCHANT_OSC_UNPAID, + "repurchase-session", + "post-order-repurchase-original", + MHD_HTTP_OK), + TALER_TESTING_cmd_wallet_get_order2 ( + "repurchase-wallet-check-order-secondary", + merchant_url, + "post-order-repurchase-secondary", + "repurchase-session", + false, + false, + false, + "post-order-repurchase-original", + MHD_HTTP_PAYMENT_REQUIRED), + TALER_TESTING_cmd_wallet_get_order2 ( + "repurchase-wallet-check-order-secondary-bad-session", + merchant_url, + "post-order-repurchase-secondary", + "wrong-session", + false, + false, + false, + NULL, + MHD_HTTP_PAYMENT_REQUIRED), + TALER_TESTING_cmd_merchant_order_refund ( + "refund-repurchased", + merchant_url, + "refund repurchase", + "repurchase-original", + "EUR:1.0", + MHD_HTTP_OK), + TALER_TESTING_cmd_wallet_get_order2 ( + "repurchase-wallet-check-primary-order-refunded-no-session", + merchant_url, + "post-order-repurchase-original", + NULL, + true, + true, + true, + "post-order-repurchase-original", + MHD_HTTP_OK), + TALER_TESTING_cmd_wallet_get_order2 ( + "repurchase-wallet-check-primary-order-refunded", + merchant_url, + "post-order-repurchase-original", + "repurchase-session", + true, + true, + true, + "post-order-repurchase-original", + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_get_order3 ( + "repurchase-check-refunded", + merchant_url, + "post-order-repurchase-secondary", + TALER_MERCHANT_OSC_CLAIMED, + "repurchase-session", + NULL, + MHD_HTTP_OK), + TALER_TESTING_cmd_end () + }; + + struct TALER_TESTING_Command tokens[] = { + /** + * Move money to the exchange's bank account. + */ + cmd_transfer_to_exchange ("create-reserve-tokens", + "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-tokens", + "EUR:10.02", + payer_payto, + exchange_payto, + "create-reserve-tokens"), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1", + "create-reserve-tokens", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2", + "create-reserve-tokens", + "EUR:5", + 0, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_tokenfamilies ("create-tokenfamily", + merchant_url, + MHD_HTTP_NO_CONTENT, + "subscription-1", + "Subscription", + "A subscription.", + NULL, + GNUNET_TIME_timestamp_get (), + GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_YEARS), + GNUNET_TIME_UNIT_MONTHS, + "subscription"), + TALER_TESTING_cmd_merchant_post_orders_choices ("create-order-with-choices", + cred.cfg, + merchant_url, + MHD_HTTP_OK, + "create-tokenfamily", + "5-choices", + GNUNET_TIME_UNIT_ZERO_TS, + GNUNET_TIME_UNIT_FOREVER_TS, + "EUR:5.0"), + + TALER_TESTING_cmd_end () + }; struct TALER_TESTING_Command commands[] = { /* general setup */ - TALER_TESTING_cmd_auditor_add ("add-auditor-OK", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_wire_add ("add-wire-account", - "payto://x-taler-bank/localhost/2?receiver-name=2", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys", - config_file), - TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees", - config_file, - "EUR:0.01", - "EUR:0.01"), - TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", - 1), - 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-default-setup", - merchant_url, - "default", - PAYTO_I1, - "EUR", - MHD_HTTP_NO_CONTENT), - 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", - "instance-create-default-setup", - 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-bad-currency", - merchant_url, - "i1", - 2, - payto_uris, - "bob-the-merchant", - json_pack ("{s:s}", - "street", - "bobstreet"), - json_pack ("{s:s}", - "street", - "bobjuryst"), - "USD:0.1", - 4, - "USD:0.5", - GNUNET_TIME_UNIT_MINUTES, - GNUNET_TIME_UNIT_MINUTES, - MHD_HTTP_BAD_REQUEST), - 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_run_fakebank ( + "run-fakebank", + cred.cfg, + "exchange-account-exchange"), + TALER_TESTING_cmd_system_start ( + "start-taler", + config_file, + "-ema", + "-u", "exchange-account-exchange", + NULL), + TALER_TESTING_cmd_get_exchange ( + "get-exchange", + cred.cfg, + NULL, + true, + true), + 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-default-setup", + merchant_url, + "default", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + merchant_url, + PAYTO_I1, + NULL, NULL, + MHD_HTTP_OK), + TALER_TESTING_cmd_merchant_post_instances ( + "instance-create-i1", + merchant_url, + "i1", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_instances ( + "instances-get-i1", + merchant_url, + MHD_HTTP_OK, + "instance-create-i1", + "instance-create-default-setup", + 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-inactivate-account", + "instance-patch-i1", merchant_url, "i1", - 1, - payto_uris, "bob-the-merchant", json_pack ("{s:s}", "street", @@ -1608,235 +1776,240 @@ run (void *cls, json_pack ("{s:s}", "street", "bobjuryst"), - "EUR:0.1", - 4, - "EUR:0.5", + true, 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-bad-currency", - merchant_url, - "i2", - PAYTO_I1, - "USD", - MHD_HTTP_BAD_REQUEST), - TALER_TESTING_cmd_merchant_post_instances2 ("instance-create-ACL", - merchant_url, - "i-acl", - 0, NULL, - "controlled instance", - json_pack ("{s:s}", "city", - "shopcity"), - json_pack ("{s:s}", "city", - "lawyercity"), - "EUR:0.1", - 42, - "EUR:0.2", - GNUNET_TIME_UNIT_MINUTES, - GNUNET_TIME_UNIT_MINUTES, - // FIXME: change this back once - // we have a update auth test CMD - // RFC_8959_PREFIX "EXAMPLE", - NULL, - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_patch_instance ("instance-patch-ACL", - merchant_url, - "i-acl", - 1, - payto_uris, - "controlled instance", - 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_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/?receiver-name=X", - "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-then-purge-i2", - merchant_url, - "i2", - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_purge_instance ("instance-purge-i1", - merchant_url, - "i1", - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_delete_instance ("instance-purge-then-delete-i1", - merchant_url, - "i1", - MHD_HTTP_NOT_FOUND), - TALER_TESTING_cmd_merchant_purge_instance ("instance-purge-i-acl-middle", - merchant_url, - "i-acl", - MHD_HTTP_NO_CONTENT), - TALER_TESTING_cmd_merchant_purge_instance ("instance-purge-default-middle", - merchant_url, - "default", - MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_get_instance ( + "instances-get-i1-2", + merchant_url, + "i1", + MHD_HTTP_OK, + "instance-patch-i1"), + TALER_TESTING_cmd_merchant_get_instance ( + "instances-get-i2-nx", + merchant_url, + "i2", + MHD_HTTP_NOT_FOUND, + NULL), + TALER_TESTING_cmd_merchant_post_instances2 ( + "instance-create-ACL", + merchant_url, + "i-acl", + "controlled instance", + json_pack ("{s:s}", "city", + "shopcity"), + json_pack ("{s:s}", "city", + "lawyercity"), + true, + GNUNET_TIME_UNIT_MINUTES, + GNUNET_TIME_UNIT_MINUTES, + // FIXME: change this back once + // we have a update auth test CMD + // RFC_8959_PREFIX "EXAMPLE", + NULL, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_patch_instance ( + "instance-patch-ACL", + merchant_url, + "i-acl", + "controlled instance", + json_pack ("{s:s}", + "street", + "bobstreet"), + json_pack ("{s:s}", + "street", + "bobjuryst"), + true, + GNUNET_TIME_UNIT_MINUTES, + GNUNET_TIME_UNIT_MINUTES, + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_instances ( + "instance-create-i2", + merchant_url, + "i2", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_instances ( + "instance-create-i2-idem", + merchant_url, + "i2", + MHD_HTTP_NO_CONTENT), + 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-then-purge-i2", + merchant_url, + "i2", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_purge_instance ( + "instance-purge-i1", + merchant_url, + "i1", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_delete_instance ( + "instance-purge-then-delete-i1", + merchant_url, + "i1", + MHD_HTTP_NOT_FOUND), + TALER_TESTING_cmd_merchant_purge_instance ( + "instance-purge-i-acl-middle", + merchant_url, + "i-acl", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_purge_instance ( + "instance-purge-default-middle", + merchant_url, + "default", + MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_instances ( "instance-create-default-after-purge", merchant_url, "default", + MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account-after-purge", + merchant_url, PAYTO_I1, - "EUR", + NULL, NULL, + MHD_HTTP_OK), + 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_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", - "data:image/jpeg;base64,RAWDATA", - json_array (), - 40, - 0, - json_pack ("{s:s}", - "street", - "pstreet"), - GNUNET_TIME_relative_to_timestamp ( - 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_get_product ("get-product-nx", - merchant_url, - "product-nx", - MHD_HTTP_NOT_FOUND, - NULL), - 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", - "data:image/jpeg;base64,RAWDATA", - json_array (), - 40, - 0, - json_pack ("{s:s}", - "street", - "pstreet"), - GNUNET_TIME_relative_to_timestamp ( - 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_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", + "data:image/jpeg;base64,RAWDATA", + json_array (), + 40, + 0, + json_pack ("{s:s}", + "street", + "pstreet"), + GNUNET_TIME_relative_to_timestamp ( + 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_get_product ( + "get-product-nx", + merchant_url, + "product-nx", + MHD_HTTP_NOT_FOUND, + NULL), + 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", + "data:image/jpeg;base64,RAWDATA", + json_array (), + 40, + 0, + json_pack ("{s:s}", + "street", + "pstreet"), + GNUNET_TIME_relative_to_timestamp ( + 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_batch ("pay", pay), TALER_TESTING_cmd_batch ("double-spending", @@ -1847,23 +2020,24 @@ run (void *cls, pay_abort), TALER_TESTING_cmd_batch ("refund", refund), - TALER_TESTING_cmd_batch ("tip", - tip), - TALER_TESTING_cmd_batch ("auth", - auth), TALER_TESTING_cmd_batch ("templates", templates), TALER_TESTING_cmd_batch ("webhooks", webhooks), + TALER_TESTING_cmd_batch ("auth", + auth), + TALER_TESTING_cmd_batch ("repurchase", + repurchase), + TALER_TESTING_cmd_batch ("tokens", + tokens), /** * End the suite. */ TALER_TESTING_cmd_end () }; - TALER_TESTING_run_with_fakebank (is, - commands, - bc.exchange_auth.wire_gateway_url); + TALER_TESTING_run (is, + commands); } @@ -1871,75 +2045,37 @@ int main (int argc, char *const *argv) { - char *cipher; - enum GNUNET_GenericReturnValue ret; - - /* These environment variables get in the way... */ - unsetenv ("XDG_DATA_HOME"); - unsetenv ("XDG_CONFIG_HOME"); - GNUNET_log_setup (argv[0], - "INFO", - NULL); - cipher = GNUNET_TESTING_get_testname_from_underscore (argv[0]); - GNUNET_assert (NULL != cipher); - GNUNET_asprintf (&config_file, - "test_merchant_api-%s.conf", - cipher); - GNUNET_free (cipher); - if (GNUNET_OK != - TALER_TESTING_prepare_fakebank (config_file, - "exchange-account-exchange", - &bc)) - return 77; + { + char *cipher; + cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); + GNUNET_assert (NULL != cipher); + GNUNET_asprintf (&config_file, + "test_merchant_api-%s.conf", + cipher); + GNUNET_free (cipher); + } payer_payto = - ("payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=" - USER_ACCOUNT_NAME); + "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=" + USER_ACCOUNT_NAME; exchange_payto = - ("payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" - EXCHANGE_ACCOUNT_NAME); + "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" + EXCHANGE_ACCOUNT_NAME; merchant_payto = - ("payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" - MERCHANT_ACCOUNT_NAME); - - if (NULL == - (merchant_url = TALER_TESTING_prepare_merchant (config_file))) - return 77; + "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" + MERCHANT_ACCOUNT_NAME; + merchant_url = "http://localhost:8080/"; GNUNET_asprintf (&merchant_url_i1a, "%sinstances/i1a/", merchant_url); - 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; + return TALER_TESTING_main (argv, + "INFO", + config_file, + "exchange-account-exchange", + TALER_TESTING_BS_FAKEBANK, + &cred, + &run, + NULL); } diff --git a/src/testing/test_merchant_api.conf b/src/testing/test_merchant_api.conf new file mode 100644 index 00000000..59da281f --- /dev/null +++ b/src/testing/test_merchant_api.conf @@ -0,0 +1,73 @@ +# This file is in the public domain. +# +[PATHS] +TALER_TEST_HOME = test_merchant_api_home/ + +[taler] +CURRENCY = EUR +CURRENCY_ROUND_UNIT = EUR:0.01 + +[merchant-exchange-kudos] +DISABLED = YES + +[taler-helper-crypto-rsa] +LOOKAHEAD_SIGN = 10 days + +[taler-helper-crypto-eddsa] +LOOKAHEAD_SIGN = 24 days +DURATION = 14 days + +[bank] +HTTP_PORT = 8082 + +[libeufin-bank] +CURRENCY = EUR +WIRE_TYPE = iban +IBAN_PAYTO_BIC = SANDBOXX +DEFAULT_CUSTOMER_DEBT_LIMIT = EUR:200 +DEFAULT_ADMIN_DEBT_LIMIT = EUR:2000 +REGISTRATION_BONUS_ENABLED = yes +REGISTRATION_BONUS = EUR:100 +SUGGESTED_WITHDRAWAL_EXCHANGE = http://localhost:8081/ +SERVE = tcp +PORT = 8082 + +[merchant] +PORT = 8080 +SERVE = tcp +DB = postgres + +[merchantdb-postgres] +CONFIG = postgres:///talercheck +SQL_DIR = $DATADIR/sql/merchant/ + +[merchant-exchange-test] +MASTER_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 +EXCHANGE_BASE_URL = http://localhost:8081/ +CURRENCY = EUR + +[exchange] +AML_THRESHOLD = EUR:1000000 +PORT = 8081 +MASTER_PUBLIC_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 +BASE_URL = "http://localhost:8081/" +STEFAN_ABS = "EUR:5" + +[exchangedb-postgres] +CONFIG = "postgres:///talercheck" + +[auditordb-postgres] +CONFIG = postgres:///talercheck + +[exchange-account-exchange] +PAYTO_URI = "payto://x-taler-bank/localhost/2?receiver-name=2" +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES + +[exchange-accountcredentials-exchange] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = NONE + +[admin-accountcredentials-exchange] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = NONE diff --git a/src/testing/test_merchant_api_home/.config/taler/exchange/account-2.json b/src/testing/test_merchant_api_home/.config/taler/exchange/account-2.json deleted file mode 100644 index b84273e8..00000000 --- a/src/testing/test_merchant_api_home/.config/taler/exchange/account-2.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "payto_uri": "payto://x-taler-bank/localhost/2", - "master_sig": "A296BYJDP182XS8GHB362ENK4JVPQYHJ34AMNC52YKSK78NH85NA3MWCPM7XAYXWSHK0X9SH46JN84T2AYGP0YAV0E9HQXAYZGABP0R" -}
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/.local/share/taler/exchange-offline/master.priv b/src/testing/test_merchant_api_home/.local/share/taler/exchange-offline/master.priv index c20942d6..efee2ec3 100644 --- a/src/testing/test_merchant_api_home/.local/share/taler/exchange-offline/master.priv +++ b/src/testing/test_merchant_api_home/.local/share/taler/exchange-offline/master.priv @@ -1 +1 @@ -åÊk;d³_Uû}£A.wÔ"!Gûçv_m "_ò
\ No newline at end of file +L ›ŠkCOµÒ¦×±Š¡©ñ÷‘èèa–¿MÌ)G@_û
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/auditor/offline-keys/auditor.priv b/src/testing/test_merchant_api_home/taler/auditor/offline-keys/auditor.priv new file mode 100644 index 00000000..b1d1e3e1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/auditor/offline-keys/auditor.priv @@ -0,0 +1 @@ +±Y½74N¤ÉÿŠÃßOíôÀV|1ƒ\uY0G¿rïû
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1696437704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1696437704 new file mode 100644 index 00000000..ab4ab213 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1696437704 @@ -0,0 +1 @@ +æ’àÙž—ÒØÿÊ>e@cD¡ÁÑÓ´_!õŸ.ç"
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697042204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697042204 new file mode 100644 index 00000000..895251e7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697042204 @@ -0,0 +1 @@ +ý57æ´´çTU^«Þ¹QØ&kœ
'¾GRTóóJø diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697646704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697646704 Binary files differnew file mode 100644 index 00000000..bf62233c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1697646704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698251204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698251204 new file mode 100644 index 00000000..0ad216c4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698251204 @@ -0,0 +1 @@ +Šß^úœt…9Æ2L¼j7ÂiS7ûD^¬Öt(¦ü|”
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698855704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698855704 new file mode 100644 index 00000000..31e290ff --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1698855704 @@ -0,0 +1 @@ +ßFl6;åZ›Ì¥hd>cÈ©+œq8ÞÏi÷²]¦Ú
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1699460204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1699460204 Binary files differnew file mode 100644 index 00000000..60a6a9d8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1699460204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700064704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700064704 new file mode 100644 index 00000000..bf23c192 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700064704 @@ -0,0 +1 @@ +ç¸v¤kÅ=²h½L‚2ÑPoK~¡ôáÒˆi¯k—8X
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700669204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700669204 new file mode 100644 index 00000000..bb72cade --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1700669204 @@ -0,0 +1 @@ +ÔGáÈ¢Mw7#9¼\îr¢\#·)‹Çÿù†(ÃK
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701273704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701273704 new file mode 100644 index 00000000..fe214623 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701273704 @@ -0,0 +1 @@ +AÙs¾¤úâ2‚I} yýÕÄeЪÙc0- K‰ÇŠ€
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701878204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701878204 new file mode 100644 index 00000000..dc26e8b6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1701878204 @@ -0,0 +1 @@ +£~òeÇÂGöZÇ; l¾—~Â~K¶Lm%óæ¢
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1702482704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1702482704 new file mode 100644 index 00000000..45bf2bed --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1702482704 @@ -0,0 +1,2 @@ +Ž4|í7&< +_¸Û}€ôúŸ)|5€ÜV·êY¿:ºôP
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703087204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703087204 new file mode 100644 index 00000000..da362cdf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703087204 @@ -0,0 +1 @@ +ÃA0‡>gc¸ÏÄ ÷ÞáFUÄÜ÷û¸hÛt¼.Q
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703691704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703691704 new file mode 100644 index 00000000..ba11ebec --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1703691704 @@ -0,0 +1,2 @@ +ʾ:C§%yÂA +ˆ×íäJÛÜÕ5-»‘
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704296204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704296204 new file mode 100644 index 00000000..727eff6b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704296204 @@ -0,0 +1 @@ +„þ¶{ƒâupÈS©W/WÏ×ßÔúpžVØfKj
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704900704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704900704 new file mode 100644 index 00000000..25552b45 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1704900704 @@ -0,0 +1 @@ +žå–ìKxÆÊaA'¯D41¬²Bž4O[ß
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1705505204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1705505204 Binary files differnew file mode 100644 index 00000000..7242fa0d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1705505204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706109704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706109704 new file mode 100644 index 00000000..34b500c6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706109704 @@ -0,0 +1 @@ +ëD-d…ÿ!Ò!†Ô[y’H$m7•ã‹ù€%
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706714204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706714204 new file mode 100644 index 00000000..3fe013b7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1706714204 @@ -0,0 +1 @@ +©çbðá$àß—•ýºêq_ì~¶9¹o¶g`;½c÷é
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707318704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707318704 new file mode 100644 index 00000000..5053597b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707318704 @@ -0,0 +1,2 @@ +³6Ù_̤êkÆ}©6"TiëCÍŽÁýf +äø
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707923204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707923204 new file mode 100644 index 00000000..5cad2bc1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1707923204 @@ -0,0 +1,2 @@ + +*[ (•mabÄî¿M^+x®Í_¶ÇM×’Ò–ûD
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1708527704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1708527704 Binary files differnew file mode 100644 index 00000000..d1ad1680 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1708527704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709132204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709132204 new file mode 100644 index 00000000..c79ca30e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709132204 @@ -0,0 +1 @@ +Yxþû/*™ÁÇõ†Md2ä-gžŠÀyÔØjÇÎÄN
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709736704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709736704 new file mode 100644 index 00000000..94a9482c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1709736704 @@ -0,0 +1 @@ +ê—Á×p±usFð¬¬mº mDrL’±Ü<áŒwð;?<
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710341204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710341204 new file mode 100644 index 00000000..0ec117aa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710341204 @@ -0,0 +1 @@ +3c&KÓ3ã„P<¯ãóöæYgüÉPeÒèR~ŽºuÃQ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710945704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710945704 Binary files differnew file mode 100644 index 00000000..0afb9a9b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1710945704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1711550204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1711550204 new file mode 100644 index 00000000..2f382d5f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1711550204 @@ -0,0 +1,2 @@ +6€™8h²wb=u¹ˆ§/½« +ð@ò™P_·jDÞ6
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712154704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712154704 new file mode 100644 index 00000000..bf6ed47c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712154704 @@ -0,0 +1 @@ +ÁsôISnµ=k»šßF%*YÆTõ±
k¶óia
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712759204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712759204 new file mode 100644 index 00000000..f0135fb3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1712759204 @@ -0,0 +1 @@ +‚Ôž—øuBUß“(0\ÊÐÌG´®ÔgÖîž·š
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713363704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713363704 Binary files differnew file mode 100644 index 00000000..921f8b6f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713363704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713968204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713968204 new file mode 100644 index 00000000..ca4f82a0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1713968204 @@ -0,0 +1 @@ +|¼XCFÕmž‘Ÿ’6Ç
ÿcBúÇè*)?Wr
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1714572704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1714572704 new file mode 100644 index 00000000..a2a6d38e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1714572704 @@ -0,0 +1 @@ +µµú´N¥TFpI„~WZÕ$n^–}×A–üзÞï²
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715177204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715177204 new file mode 100644 index 00000000..d6712222 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715177204 @@ -0,0 +1 @@ +q„M/ӖΰÄQû¿Ð¹“èCë£ÔèÉhÿL
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715781704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715781704 new file mode 100644 index 00000000..70103e65 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1715781704 @@ -0,0 +1 @@ +×ã7Ö–ô ·^;P_ÝÀ’˜`)¨3:£þ¿QÝó
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716386204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716386204 new file mode 100644 index 00000000..9b43f31d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716386204 @@ -0,0 +1 @@ +©0s23Jßz¶Bp{„¿Q¼%ç—Éœu ªÓ˜Ô
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716990704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716990704 new file mode 100644 index 00000000..27fae6fe --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1716990704 @@ -0,0 +1 @@ +
<Z~V8l(Ó3LJ7³®šøLàãËÚ"Ò
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1717595204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1717595204 new file mode 100644 index 00000000..72ae4efd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_1/1717595204 @@ -0,0 +1 @@ +
;~Îóö¯‘·”´ðû÷ÆD¡l*Ùû,»Ä³×Í
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1696437704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1696437704 new file mode 100644 index 00000000..256151dc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1696437704 @@ -0,0 +1 @@ +9&gÄÙ‡PH<œJ®¶»Ža8DÎ#†ùN°BŠ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697042204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697042204 new file mode 100644 index 00000000..fdae36a5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697042204 @@ -0,0 +1 @@ +ò;sÚ›³ý[öœt¡›§µÚººÀfí'û‡kkC
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697646704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697646704 Binary files differnew file mode 100644 index 00000000..07c534ba --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1697646704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698251204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698251204 new file mode 100644 index 00000000..d733cf16 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698251204 @@ -0,0 +1 @@ +“Ê ;¦»Ð¤Tp2)Dý-hw§M¢:†Ž7ÅQ°M
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698855704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698855704 new file mode 100644 index 00000000..9c5bb02c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1698855704 @@ -0,0 +1 @@ +}묾ÕÕù@,"›ëÂãž LGÇtˆƒß²Ê¸Nê
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1699460204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1699460204 new file mode 100644 index 00000000..98456040 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1699460204 @@ -0,0 +1 @@ +—z§ÜÌržÉ³ ÝúcFáP´R¦¶5k~_ö¶ø
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700064704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700064704 Binary files differnew file mode 100644 index 00000000..2fe3435c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700064704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700669204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700669204 new file mode 100644 index 00000000..6024c31a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1700669204 @@ -0,0 +1 @@ +kS¿ƒMûä(ˆ!·Û÷²ÚtÎ ¢GÐL=œ:
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701273704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701273704 new file mode 100644 index 00000000..36dde967 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701273704 @@ -0,0 +1 @@ +ããénÚÔq5¥—úyÆT°#F3þ‹
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701878204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701878204 new file mode 100644 index 00000000..c65618d6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1701878204 @@ -0,0 +1 @@ +E|çÀ÷`5;‡ÖrœÃ³Îð냅]®`½¡
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1702482704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1702482704 new file mode 100644 index 00000000..4f50e1ec --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1702482704 @@ -0,0 +1,2 @@ +ê0jÉ‹ÃVÜZªüÑŠ´ëŽÛ«öø× +×›ÑÛ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703087204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703087204 Binary files differnew file mode 100644 index 00000000..48a9b32f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703087204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703691704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703691704 new file mode 100644 index 00000000..95978f6c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1703691704 @@ -0,0 +1 @@ +©ó÷`+²zg‘¡0ÛÙbôkÔ?m
ñˆi3uæ
b¸Ÿ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704296204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704296204 new file mode 100644 index 00000000..f476a698 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704296204 @@ -0,0 +1 @@ +Y>Å¡Æ}ο¥ìyKEv™02äüë2PZ©ÕͲ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704900704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704900704 new file mode 100644 index 00000000..01c429af --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1704900704 @@ -0,0 +1 @@ +§IERôÃ…pû!"5—ô”—™IÆ à¢Þp(C×À~
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1705505204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1705505204 new file mode 100644 index 00000000..b8c127a6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1705505204 @@ -0,0 +1 @@ +H‹ìÏfÄY_Éé<Åò…iiýi]«%⩨Q
¯.«|ã
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706109704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706109704 new file mode 100644 index 00000000..e8d10e5a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706109704 @@ -0,0 +1,3 @@ +ÚÇ9B1ŸZ +_ºrpn”‹ë2,ìh{Ú¤ +‹ÎðˆÙ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706714204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706714204 new file mode 100644 index 00000000..f1752f7b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1706714204 @@ -0,0 +1 @@ +Γ[Jù¼Q¡M
º¶OTòN[ðy2Øå6I
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707318704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707318704 new file mode 100644 index 00000000..53710bff --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707318704 @@ -0,0 +1 @@ +OC;.KÛúf0æb©°¾giÞV=cF}‚:Jðżñ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707923204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707923204 Binary files differnew file mode 100644 index 00000000..d8359467 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1707923204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1708527704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1708527704 Binary files differnew file mode 100644 index 00000000..35f5f4c3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1708527704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709132204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709132204 new file mode 100644 index 00000000..f6f02e40 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709132204 @@ -0,0 +1 @@ +sÚ-±*æÁð8üö†Ji<Û‘Äpª÷\ã®ñ¯
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709736704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709736704 new file mode 100644 index 00000000..291492bd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1709736704 @@ -0,0 +1 @@ +µSI¿@Ÿ›fS’¤GÌS·‚VÀd⽄ç&Þ‘b
ó
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710341204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710341204 Binary files differnew file mode 100644 index 00000000..c7e79229 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710341204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710945704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710945704 new file mode 100644 index 00000000..b65e0bda --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1710945704 @@ -0,0 +1 @@ +âK¤þe6£‡nØCAFž~ôÙ<‹Ð—ËÑØc{
öR
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1711550204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1711550204 Binary files differnew file mode 100644 index 00000000..4763e3bf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1711550204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712154704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712154704 new file mode 100644 index 00000000..3803be3c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712154704 @@ -0,0 +1 @@ +”Èñ~vlÞZÄŒdcÑ×iŠäµz?§Ï×C
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712759204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712759204 new file mode 100644 index 00000000..efde898d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1712759204 @@ -0,0 +1 @@ +úÁù2‰œÐÏšªUx«Ÿ^ŽPKýÙDxÞ6
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713363704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713363704 new file mode 100644 index 00000000..8f34857c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713363704 @@ -0,0 +1 @@ +vžQ°7a£®phƒöçl·Û;ðMÿ^U g-
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713968204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713968204 new file mode 100644 index 00000000..8827ac75 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1713968204 @@ -0,0 +1 @@ +FR(r;ö:ÑùŸÃ[N©<™M7æ}Ā͂²IT
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1714572704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1714572704 new file mode 100644 index 00000000..74c227bf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1714572704 @@ -0,0 +1 @@ +æ«È?̵¢¾±¯†,Û@Nœr‘9£¨1ÙÛÜÔË¥¥
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715177204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715177204 new file mode 100644 index 00000000..5442c9b8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715177204 @@ -0,0 +1 @@ +N²^0ÄYmùtºçÒ¯*8Ñ”ÑMˆd¯òäÖˆ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715781704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715781704 new file mode 100644 index 00000000..b6ceae19 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1715781704 @@ -0,0 +1 @@ +M±*κdü&Lõ_žÖZœÍµÞI½šÕö
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716386204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716386204 Binary files differnew file mode 100644 index 00000000..30facaaa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716386204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716990704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716990704 new file mode 100644 index 00000000..0e28c81d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1716990704 @@ -0,0 +1 @@ +ò>]ºéðª»ïyø%à
Y}DxCmá$wGE
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1717595204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1717595204 new file mode 100644 index 00000000..1a5f9273 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_5/1717595204 @@ -0,0 +1,2 @@ ++Ò_RméOÖ°AJ§©¨¨d®ì&íÃÄ} +‹",
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1696437704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1696437704 new file mode 100644 index 00000000..2260d03f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1696437704 @@ -0,0 +1 @@ +uï4Gxnv]·,¥ÐîåuyH¦1rÓ¸
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697042204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697042204 new file mode 100644 index 00000000..193e653d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697042204 @@ -0,0 +1,2 @@ +]¦H<„óõ¡É +øþ".Øk43h‹°W³öxå
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697646704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697646704 new file mode 100644 index 00000000..47bc14d8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1697646704 @@ -0,0 +1 @@ +äéÄð·ÌÕ°ÿ®óþ„ë@Ï[³*U£k¿ûår
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698251204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698251204 new file mode 100644 index 00000000..ba2059c4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698251204 @@ -0,0 +1 @@ +Ø…ðSüGeÎ݉G`\ÖœXYëþ¯P/ÍÂØP”N
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698855704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698855704 new file mode 100644 index 00000000..c41becef --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1698855704 @@ -0,0 +1 @@ +òZäê<îÙfÏ"¸‚!¢)Þ%ºiÝÜ ªÃ¢Ñùt
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1699460204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1699460204 Binary files differnew file mode 100644 index 00000000..ef4541c3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1699460204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700064704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700064704 new file mode 100644 index 00000000..4110af46 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700064704 @@ -0,0 +1 @@ +faN
éH‹â'¢ï…^ô>A•€ã¢ýtn+[#5Y
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700669204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700669204 new file mode 100644 index 00000000..b6bd01a3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1700669204 @@ -0,0 +1 @@ +Ë›oO´¶ P6™ŠQD¨ŠWãq$kŒ0JŽ¢©
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701273704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701273704 new file mode 100644 index 00000000..9785b04d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701273704 @@ -0,0 +1 @@ +×â²ûíwæÄ/É•VŠvß%¶,iŠä 6#ø
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701878204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701878204 new file mode 100644 index 00000000..45dd2690 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1701878204 @@ -0,0 +1 @@ +µ=åpß;Æâã¼T3M[¯ßxÂÀ|œm¦~‰O
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1702482704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1702482704 new file mode 100644 index 00000000..286d043e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1702482704 @@ -0,0 +1 @@ +t6ÌJo§÷“„²qþð`‡KKd:%œŽŽ(±¥S)
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703087204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703087204 new file mode 100644 index 00000000..9a49a0d7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703087204 @@ -0,0 +1 @@ +M°9Î; YÚi—Ã&!BàƒŽOź0,™Aì½Ë’ bæ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703691704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703691704 new file mode 100644 index 00000000..7b831419 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1703691704 @@ -0,0 +1 @@ +NƒîØŒÇD±«§Ö¾q>A-;™»ïÆŒþ¦irf
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704296204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704296204 new file mode 100644 index 00000000..e107b922 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704296204 @@ -0,0 +1 @@ +maíH0ìíl%’åy“âX?Y6_8¹¡X•G
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704900704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704900704 new file mode 100644 index 00000000..455ecdb7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1704900704 @@ -0,0 +1 @@ +ë_¿2y|—²Ó ÚoÝ‹ªÊ[¶Ú£oV’RÕm
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1705505204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1705505204 new file mode 100644 index 00000000..b0afe0cd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1705505204 @@ -0,0 +1 @@ +ÁˈôjèÉ¥<M*‹Ò°{ó²S•H4Ùóõj«³Q¤
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706109704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706109704 new file mode 100644 index 00000000..cf96d588 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706109704 @@ -0,0 +1 @@ +”¶æíBÙyëØ—â~‚{çMŠNWô3KQå5‘»
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706714204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706714204 new file mode 100644 index 00000000..fdce10fe --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1706714204 @@ -0,0 +1 @@ +^ª[ð—ØÄ¿Êê†j>°áÑm0¹YgÚ³yà¸
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707318704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707318704 new file mode 100644 index 00000000..4ce6db5e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707318704 @@ -0,0 +1 @@ +mö¬Ô ÿˆòðƒà{íö¡LO|SߌGö€ðT3e
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707923204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707923204 new file mode 100644 index 00000000..d273e552 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1707923204 @@ -0,0 +1 @@ +T°Ühô2’{ø£5¬ØZ¡zÎD œ”S*¿)6a
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709132204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709132204 new file mode 100644 index 00000000..868af8ef --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709132204 @@ -0,0 +1 @@ +Èn/3ÛìW'ÞÍÛ—=š5mVÁïå[¤³ÿ diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709736704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709736704 new file mode 100644 index 00000000..538ee496 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1709736704 @@ -0,0 +1 @@ +šëÈôHO ˲%ðྡÕñcû]XØÏ>’‡…
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710341204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710341204 new file mode 100644 index 00000000..a24da62f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710341204 @@ -0,0 +1 @@ +ûyz¦ÜÍ¥
ÁHW@-¼ª&y›Ö.¯®…/`Ð-
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710945704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710945704 new file mode 100644 index 00000000..b4ca3f1f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1710945704 @@ -0,0 +1 @@ +Ü€Þ‡#×x0ÐáÆšTcn¤Ù¢Ð-©™¸rÏ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1711550204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1711550204 new file mode 100644 index 00000000..c57cde50 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1711550204 @@ -0,0 +1 @@ +–¥MßdèHn?Ö
3ÐãÜH²ÍÑÕ/ª"Q×
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712154704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712154704 new file mode 100644 index 00000000..c085d0a8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712154704 @@ -0,0 +1 @@ +7 9}…æ3ƒN§vÛVÖ4VMè*džVZä–é
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712759204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712759204 new file mode 100644 index 00000000..a29b261b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1712759204 @@ -0,0 +1 @@ +xâ‡H¬î0iKø‚FoO?PІͤdà…08
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713363704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713363704 new file mode 100644 index 00000000..eb6972f8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713363704 @@ -0,0 +1 @@ +4Íû–,¶@WÁÛ!°X»‘§~<Txqf8A'Có
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713968204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713968204 Binary files differnew file mode 100644 index 00000000..e3e18a16 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1713968204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1714572704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1714572704 Binary files differnew file mode 100644 index 00000000..7d288934 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1714572704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715177204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715177204 new file mode 100644 index 00000000..c44343f9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715177204 @@ -0,0 +1 @@ +I’ñ<58N*'!ç³\AX±,S<~Ì<äEÓÁÞh
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715781704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715781704 new file mode 100644 index 00000000..2521c428 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1715781704 @@ -0,0 +1,2 @@ +rêj>u®ÆlƒHÛ©T!¾Œ·Ë¡? +ºØIDàÇçö diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716386204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716386204 new file mode 100644 index 00000000..7a016552 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716386204 @@ -0,0 +1 @@ +ùŒ)¹F!¾Æ
@™bL`êO]FDü,¯(Ò>å’ñ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716990704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716990704 new file mode 100644 index 00000000..7cafdb67 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1716990704 @@ -0,0 +1 @@ + ÊÜ»(¨FÌN)¶öò1û½cßn8‘TxU
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1717595204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1717595204 Binary files differnew file mode 100644 index 00000000..c7772341 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_1/1717595204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1696437704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1696437704 new file mode 100644 index 00000000..3a48e83c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1696437704 @@ -0,0 +1 @@ + ÈÎÆ´àö1pÁJ9A[àxªýž„³È7.kaþp
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697042204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697042204 new file mode 100644 index 00000000..02fcbef5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697042204 @@ -0,0 +1 @@ +ö(ò¸(Fƒ¿;3,ʇțªWI»hžz!Óï؇[
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697646704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697646704 Binary files differnew file mode 100644 index 00000000..514a546f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1697646704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698251204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698251204 new file mode 100644 index 00000000..b082e7da --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698251204 @@ -0,0 +1 @@ +ÑCx˜,—K¿NÔƆkUY¸ýŽ…þz9„RÙo+nfë
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698855704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698855704 new file mode 100644 index 00000000..969cb8d8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1698855704 @@ -0,0 +1 @@ +MqÚB–’¢ñ4鎥r¶PÙƇ›¸»›Hgi«
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1699460204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1699460204 Binary files differnew file mode 100644 index 00000000..fcfb97a2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1699460204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700064704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700064704 new file mode 100644 index 00000000..d7f0cffe --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700064704 @@ -0,0 +1 @@ +‹µþ‡9RN•H³´›½Ä›ÕL+7NLäiL€Û
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700669204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700669204 new file mode 100644 index 00000000..912e633f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1700669204 @@ -0,0 +1 @@ +AÀ0‘¡$Ñ^†ë¢ˆ£²/¼u SE}†ù¯Èé¥÷
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701273704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701273704 new file mode 100644 index 00000000..c2d88da1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701273704 @@ -0,0 +1 @@ +(®ý* UÇB¹ã«¼´,ÁX'"÷°ò\JÅ|½k3¦
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701878204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701878204 new file mode 100644 index 00000000..14281a72 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1701878204 @@ -0,0 +1 @@ +sƒ›ÌRŠÍÝzü“4Œµ Ÿsd¶_ˆJߣu
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1702482704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1702482704 new file mode 100644 index 00000000..3f1f19d8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1702482704 @@ -0,0 +1 @@ +Mne6ì{Õá’˜¸E1U™ VÑ…÷µúP"?€R
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703087204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703087204 new file mode 100644 index 00000000..4ce8f1ff --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703087204 @@ -0,0 +1 @@ +‘€•Ê…$¾[¹R—ÅÛnîÝÒüí¬P7ÐG‚)
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703691704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703691704 Binary files differnew file mode 100644 index 00000000..1971537b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1703691704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704296204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704296204 new file mode 100644 index 00000000..77c8c1d5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704296204 @@ -0,0 +1 @@ +%yÖk/lw5¼^¾æ_ ÙˆÙt`½2{íT¸Ïû8i
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704900704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704900704 new file mode 100644 index 00000000..c946503d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1704900704 @@ -0,0 +1 @@ +ÿMrqDq±rEtjXØâN{ÌZ„T¨÷Ì
ö4 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1705505204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1705505204 new file mode 100644 index 00000000..86eea5e2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1705505204 @@ -0,0 +1 @@ +òüîxCa^dO–’ô±¾üã¢?©[ÝŒx1VÚå
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706109704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706109704 new file mode 100644 index 00000000..1057eb4c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706109704 @@ -0,0 +1 @@ +P¾ÐEçÆž³ð¼Oæ5rÉ0iH´Kb13
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706714204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706714204 new file mode 100644 index 00000000..3cbb16ef --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1706714204 @@ -0,0 +1 @@ +ÝBÇ€E½À{œ¼“’œ+†’üoPŸá•²¿£Î"
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707318704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707318704 new file mode 100644 index 00000000..7f4ce85b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707318704 @@ -0,0 +1,2 @@ +Í=íʾ°»©E§ +VSÍÙ9ðX„–{}ei\Êïñu
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707923204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707923204 new file mode 100644 index 00000000..d44fbfb7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1707923204 @@ -0,0 +1 @@ +!2^ù.OÛÆIè$^ýÇ0XîÄ´qçæ²néó|4Æ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1708527704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1708527704 Binary files differnew file mode 100644 index 00000000..cba4467a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1708527704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709132204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709132204 new file mode 100644 index 00000000..528b7eee --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709132204 @@ -0,0 +1 @@ +«ÂCCŽeº†A Mîì¾Bd³;/’
ä ÕÝnÅÑ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709736704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709736704 new file mode 100644 index 00000000..a5e1d42a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1709736704 @@ -0,0 +1 @@ +oƒü>ÏIñ”D‰°Å…¨bvJæHNa7)²1‹òi
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710341204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710341204 new file mode 100644 index 00000000..47341063 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710341204 @@ -0,0 +1 @@ +öRÛ¦‰%D1g€B‹YÄÿyípŠå´¢@㥎ix diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710945704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710945704 new file mode 100644 index 00000000..ebbad9d4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1710945704 @@ -0,0 +1 @@ +(~ƒcÝfÛåaMÛøþ M ——JjRª ýôä
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1711550204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1711550204 new file mode 100644 index 00000000..db6a523e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1711550204 @@ -0,0 +1 @@ +!QV¤^p7"î/’¥vê³]ߤ¦dÅ«D°r=ù
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712154704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712154704 Binary files differnew file mode 100644 index 00000000..d281cbcc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712154704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712759204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712759204 new file mode 100644 index 00000000..4cd2c6aa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1712759204 @@ -0,0 +1 @@ +¶ŽÇ÷¥ÚŠ¤úÉÿn·ô<;q.ñŽÚN³
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713363704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713363704 new file mode 100644 index 00000000..dba39243 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713363704 @@ -0,0 +1 @@ +u°>/£{ÖÜ&AN|ÌsŽ3½ CÌZŸ¸·¿-‡Í
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713968204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713968204 new file mode 100644 index 00000000..7cda9094 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1713968204 @@ -0,0 +1 @@ +Ž§?7¯ƒ!CSÈ%Aí ‹È¦‚Ä5CÄ4çá×
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1714572704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1714572704 new file mode 100644 index 00000000..6fe94e82 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1714572704 @@ -0,0 +1 @@ +ctí³BÒiû6,•Ð«uWöC2£nÖáY°]Ÿ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715177204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715177204 Binary files differnew file mode 100644 index 00000000..02d135b2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715177204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715781704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715781704 new file mode 100644 index 00000000..b3015f6f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1715781704 @@ -0,0 +1 @@ +AvGâ!î
áð<ñíÉo”§Sô6÷æ߈nÌ¡®"Ä diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716386204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716386204 Binary files differnew file mode 100644 index 00000000..2f426abf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716386204 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716990704 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716990704 Binary files differnew file mode 100644 index 00000000..61d52a98 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1716990704 diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1717595204 b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1717595204 new file mode 100644 index 00000000..f839fc3d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/keys/coin_eur_ct_10/1717595204 @@ -0,0 +1 @@ +ÿA)ú€œÜÆ/V¿Õ.Ÿçqø¤•u/5PÃxÀó
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/secmod-private-key b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/secmod-private-key Binary files differnew file mode 100644 index 00000000..8c53f4b1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-cs/secmod-private-key diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-eddsa/secmod-private-key b/src/testing/test_merchant_api_home/taler/exchange-secmod-eddsa/secmod-private-key new file mode 100644 index 00000000..a1ae416d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-eddsa/secmod-private-key @@ -0,0 +1 @@ +„\š"þh(QH™,eóÒƒ=Ûœ2ÎNXÁÚšå8‚
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/exchange-secmod-rsa/secmod-private-key b/src/testing/test_merchant_api_home/taler/exchange-secmod-rsa/secmod-private-key new file mode 100644 index 00000000..26eda485 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/exchange-secmod-rsa/secmod-private-key @@ -0,0 +1 @@ +=E€<6œ$ÇÆ1©D·ßqzjþÚpÞJ ºÌOõn
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/auditor/offline-keys/auditor.priv b/src/testing/test_merchant_api_home/taler/taler/auditor/offline-keys/auditor.priv new file mode 100644 index 00000000..b1d1e3e1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/auditor/offline-keys/auditor.priv @@ -0,0 +1 @@ +±Y½74N¤ÉÿŠÃßOíôÀV|1ƒ\uY0G¿rïû
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1626561343 b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1626561343 new file mode 100644 index 00000000..4ebda709 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1626561343 @@ -0,0 +1 @@ +¶_Û¥ÿ2¦r+j@‡ƒõ°(ld¨TeºöåÉKJUtZ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1633818643 b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1633818643 new file mode 100644 index 00000000..f59e876d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1633818643 @@ -0,0 +1 @@ +]tã¾÷R~9©ñ-0F¶NPùg¬zܤIB‹ñH>A
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1641075943 b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1641075943 new file mode 100644 index 00000000..6bff5766 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1641075943 @@ -0,0 +1 @@ +¿7M¥"s`¿ºÈeöó¡¨ð|Ý“È”âN-kŽ
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1648333243 b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1648333243 new file mode 100644 index 00000000..1421144a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1648333243 @@ -0,0 +1 @@ +8:o£`-Øã£ci‡Klçn4<ŠÇbJz'I
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1655590543 b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1655590543 new file mode 100644 index 00000000..6cc325dc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-eddsa/1655590543 @@ -0,0 +1 @@ +£˜ô¹·9Ü$k–‚·..ñÑôl–•_‚L”Êûúo
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1626554443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1626554443 Binary files differnew file mode 100644 index 00000000..c9dc2198 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1626554443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627158943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627158943 Binary files differnew file mode 100644 index 00000000..502eb080 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627158943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627763443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627763443 Binary files differnew file mode 100644 index 00000000..38e4d600 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1627763443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628367943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628367943 Binary files differnew file mode 100644 index 00000000..94b19c17 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628367943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628972443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628972443 Binary files differnew file mode 100644 index 00000000..2d806502 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1628972443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1629576943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1629576943 Binary files differnew file mode 100644 index 00000000..95e73f8d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1629576943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630181443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630181443 Binary files differnew file mode 100644 index 00000000..90ab6274 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630181443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630785943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630785943 Binary files differnew file mode 100644 index 00000000..93a7c0f6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1630785943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631390443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631390443 Binary files differnew file mode 100644 index 00000000..7f1a34b4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631390443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631994943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631994943 Binary files differnew file mode 100644 index 00000000..e7aead59 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1631994943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1632599443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1632599443 Binary files differnew file mode 100644 index 00000000..9a3ca629 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1632599443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633203943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633203943 Binary files differnew file mode 100644 index 00000000..eefe38a7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633203943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633808443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633808443 Binary files differnew file mode 100644 index 00000000..83e32064 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1633808443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1634412943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1634412943 Binary files differnew file mode 100644 index 00000000..34c4f7cc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1634412943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635017443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635017443 Binary files differnew file mode 100644 index 00000000..7003d582 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635017443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635621943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635621943 Binary files differnew file mode 100644 index 00000000..4ec323d5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1635621943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636226443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636226443 Binary files differnew file mode 100644 index 00000000..ddf1340c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636226443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636830943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636830943 Binary files differnew file mode 100644 index 00000000..e621edf4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1636830943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1637435443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1637435443 Binary files differnew file mode 100644 index 00000000..8db32a7e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1637435443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638039943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638039943 Binary files differnew file mode 100644 index 00000000..92ce9d37 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638039943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638644443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638644443 Binary files differnew file mode 100644 index 00000000..68e1385f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1638644443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639248943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639248943 Binary files differnew file mode 100644 index 00000000..0a4a34f4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639248943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639853443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639853443 Binary files differnew file mode 100644 index 00000000..f41231b9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1639853443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1640457943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1640457943 Binary files differnew file mode 100644 index 00000000..1ccd0bf8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1640457943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641062443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641062443 Binary files differnew file mode 100644 index 00000000..1682390a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641062443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641666943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641666943 Binary files differnew file mode 100644 index 00000000..820be0de --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1641666943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642271443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642271443 Binary files differnew file mode 100644 index 00000000..775a21bf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642271443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642875943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642875943 Binary files differnew file mode 100644 index 00000000..bc45ac1b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1642875943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1643480443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1643480443 Binary files differnew file mode 100644 index 00000000..1594724d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1643480443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644084943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644084943 Binary files differnew file mode 100644 index 00000000..77191330 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644084943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644689443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644689443 Binary files differnew file mode 100644 index 00000000..d881d7cb --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1644689443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645293943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645293943 Binary files differnew file mode 100644 index 00000000..c2b33607 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645293943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645898443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645898443 Binary files differnew file mode 100644 index 00000000..bbebc198 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1645898443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1646502943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1646502943 Binary files differnew file mode 100644 index 00000000..ec849ae2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1646502943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647107443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647107443 Binary files differnew file mode 100644 index 00000000..9fa67082 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647107443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647711943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647711943 Binary files differnew file mode 100644 index 00000000..4bddf10c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1647711943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648316443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648316443 Binary files differnew file mode 100644 index 00000000..f20c785d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648316443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648920943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648920943 Binary files differnew file mode 100644 index 00000000..89cfa2fa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1648920943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1649525443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1649525443 Binary files differnew file mode 100644 index 00000000..a2cdc311 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1649525443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650129943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650129943 Binary files differnew file mode 100644 index 00000000..9d028df0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650129943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650734443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650734443 Binary files differnew file mode 100644 index 00000000..b704ed0f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1650734443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651338943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651338943 Binary files differnew file mode 100644 index 00000000..5cba6be3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651338943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651943443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651943443 Binary files differnew file mode 100644 index 00000000..c052e2da --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1651943443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1652547943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1652547943 Binary files differnew file mode 100644 index 00000000..5e9796d9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1652547943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653152443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653152443 Binary files differnew file mode 100644 index 00000000..47132826 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653152443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653756943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653756943 Binary files differnew file mode 100644 index 00000000..c850ac55 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1653756943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654361443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654361443 Binary files differnew file mode 100644 index 00000000..fcc92868 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654361443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654965943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654965943 Binary files differnew file mode 100644 index 00000000..7828b2b5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1654965943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1655570443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1655570443 Binary files differnew file mode 100644 index 00000000..e787aa88 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1655570443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656174943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656174943 Binary files differnew file mode 100644 index 00000000..fce4eb9b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656174943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656779443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656779443 Binary files differnew file mode 100644 index 00000000..b411b18b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1656779443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657383943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657383943 Binary files differnew file mode 100644 index 00000000..60079b13 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657383943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657988443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657988443 Binary files differnew file mode 100644 index 00000000..e52e35c1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1657988443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1658592943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1658592943 Binary files differnew file mode 100644 index 00000000..59425e07 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_1/1658592943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1626554443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1626554443 Binary files differnew file mode 100644 index 00000000..2b0458b0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1626554443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627158943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627158943 Binary files differnew file mode 100644 index 00000000..ff26fa40 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627158943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627763443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627763443 Binary files differnew file mode 100644 index 00000000..c4c1fcdb --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1627763443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628367943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628367943 Binary files differnew file mode 100644 index 00000000..0c085113 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628367943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628972443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628972443 Binary files differnew file mode 100644 index 00000000..ac7ada27 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1628972443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1629576943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1629576943 Binary files differnew file mode 100644 index 00000000..5b89db7d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1629576943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630181443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630181443 Binary files differnew file mode 100644 index 00000000..94693552 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630181443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630785943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630785943 Binary files differnew file mode 100644 index 00000000..78c03b5a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1630785943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631390443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631390443 Binary files differnew file mode 100644 index 00000000..bd93e1ec --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631390443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631994943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631994943 Binary files differnew file mode 100644 index 00000000..5bf7bc2d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1631994943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1632599443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1632599443 Binary files differnew file mode 100644 index 00000000..4e0b5e0f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1632599443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633203943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633203943 Binary files differnew file mode 100644 index 00000000..9826bb6b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633203943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633808443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633808443 Binary files differnew file mode 100644 index 00000000..cb7c3234 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1633808443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1634412943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1634412943 Binary files differnew file mode 100644 index 00000000..41de9949 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1634412943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635017443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635017443 Binary files differnew file mode 100644 index 00000000..1ed3e2e7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635017443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635621943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635621943 Binary files differnew file mode 100644 index 00000000..a5712db6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1635621943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636226443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636226443 Binary files differnew file mode 100644 index 00000000..3c26311d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636226443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636830943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636830943 Binary files differnew file mode 100644 index 00000000..ad2e4fe5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1636830943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1637435443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1637435443 Binary files differnew file mode 100644 index 00000000..423be019 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1637435443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638039943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638039943 Binary files differnew file mode 100644 index 00000000..32b37b0f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638039943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638644443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638644443 Binary files differnew file mode 100644 index 00000000..807680bf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1638644443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639248943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639248943 Binary files differnew file mode 100644 index 00000000..a3b5a0e0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639248943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639853443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639853443 Binary files differnew file mode 100644 index 00000000..931a1b79 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1639853443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1640457943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1640457943 Binary files differnew file mode 100644 index 00000000..b6ca34b5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1640457943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641062443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641062443 Binary files differnew file mode 100644 index 00000000..eb65de21 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641062443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641666943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641666943 Binary files differnew file mode 100644 index 00000000..a1674e27 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1641666943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642271443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642271443 Binary files differnew file mode 100644 index 00000000..4186fed2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642271443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642875943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642875943 Binary files differnew file mode 100644 index 00000000..cc215d0f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1642875943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1643480443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1643480443 Binary files differnew file mode 100644 index 00000000..4b4f7f82 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1643480443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644084943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644084943 Binary files differnew file mode 100644 index 00000000..0b15bd15 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644084943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644689443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644689443 Binary files differnew file mode 100644 index 00000000..ee6e55c0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1644689443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645293943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645293943 Binary files differnew file mode 100644 index 00000000..3a30a716 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645293943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645898443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645898443 Binary files differnew file mode 100644 index 00000000..15d356dc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1645898443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1646502943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1646502943 Binary files differnew file mode 100644 index 00000000..47d0c3a4 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1646502943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647107443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647107443 Binary files differnew file mode 100644 index 00000000..6b111343 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647107443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647711943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647711943 Binary files differnew file mode 100644 index 00000000..2b4cdaf6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1647711943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648316443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648316443 Binary files differnew file mode 100644 index 00000000..0828bec8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648316443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648920943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648920943 Binary files differnew file mode 100644 index 00000000..23c07f08 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1648920943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1649525443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1649525443 Binary files differnew file mode 100644 index 00000000..2f45e330 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1649525443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650129943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650129943 Binary files differnew file mode 100644 index 00000000..1179c2b7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650129943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650734443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650734443 Binary files differnew file mode 100644 index 00000000..780c61d9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1650734443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651338943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651338943 Binary files differnew file mode 100644 index 00000000..c550ea6a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651338943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651943443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651943443 Binary files differnew file mode 100644 index 00000000..601ae6cc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1651943443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1652547943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1652547943 Binary files differnew file mode 100644 index 00000000..cffb0785 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1652547943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653152443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653152443 Binary files differnew file mode 100644 index 00000000..515f1183 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653152443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653756943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653756943 Binary files differnew file mode 100644 index 00000000..533900fd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1653756943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654361443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654361443 Binary files differnew file mode 100644 index 00000000..431bc19e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654361443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654965943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654965943 Binary files differnew file mode 100644 index 00000000..a21336fa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1654965943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1655570443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1655570443 Binary files differnew file mode 100644 index 00000000..43229366 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1655570443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656174943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656174943 Binary files differnew file mode 100644 index 00000000..1925ea41 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656174943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656779443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656779443 Binary files differnew file mode 100644 index 00000000..cd2e5e7b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1656779443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657383943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657383943 Binary files differnew file mode 100644 index 00000000..028daf37 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657383943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657988443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657988443 Binary files differnew file mode 100644 index 00000000..58d9e8f2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1657988443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1658592943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1658592943 Binary files differnew file mode 100644 index 00000000..abc9311b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_5/1658592943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1626554443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1626554443 Binary files differnew file mode 100644 index 00000000..654311d0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1626554443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627158943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627158943 Binary files differnew file mode 100644 index 00000000..4e28d3cf --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627158943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627763443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627763443 Binary files differnew file mode 100644 index 00000000..65de1c88 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1627763443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628367943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628367943 Binary files differnew file mode 100644 index 00000000..fbc5af8c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628367943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628972443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628972443 Binary files differnew file mode 100644 index 00000000..bf78cee2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1628972443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1629576943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1629576943 Binary files differnew file mode 100644 index 00000000..46e87d1d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1629576943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630181443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630181443 Binary files differnew file mode 100644 index 00000000..2de0a06d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630181443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630785943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630785943 Binary files differnew file mode 100644 index 00000000..f3adfb6b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1630785943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631390443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631390443 Binary files differnew file mode 100644 index 00000000..09858250 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631390443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631994943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631994943 Binary files differnew file mode 100644 index 00000000..8b5d1085 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1631994943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1632599443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1632599443 Binary files differnew file mode 100644 index 00000000..0f335ebd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1632599443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633203943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633203943 Binary files differnew file mode 100644 index 00000000..1cc0dce1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633203943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633808443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633808443 Binary files differnew file mode 100644 index 00000000..4aed01bc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1633808443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1634412943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1634412943 Binary files differnew file mode 100644 index 00000000..de1118b1 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1634412943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635017443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635017443 Binary files differnew file mode 100644 index 00000000..bf49a823 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635017443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635621943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635621943 Binary files differnew file mode 100644 index 00000000..5143421a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1635621943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636226443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636226443 Binary files differnew file mode 100644 index 00000000..b3689451 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636226443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636830943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636830943 Binary files differnew file mode 100644 index 00000000..033ad011 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1636830943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1637435443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1637435443 Binary files differnew file mode 100644 index 00000000..2a1805d7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1637435443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638039943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638039943 Binary files differnew file mode 100644 index 00000000..f517aa86 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638039943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638644443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638644443 Binary files differnew file mode 100644 index 00000000..044e0d3e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1638644443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639248943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639248943 Binary files differnew file mode 100644 index 00000000..6e3bdce3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639248943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639853443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639853443 Binary files differnew file mode 100644 index 00000000..57cc9645 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1639853443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1640457943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1640457943 Binary files differnew file mode 100644 index 00000000..ecb4a203 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1640457943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641062443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641062443 Binary files differnew file mode 100644 index 00000000..8a2f3a75 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641062443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641666943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641666943 Binary files differnew file mode 100644 index 00000000..1b261a6d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1641666943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642271443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642271443 Binary files differnew file mode 100644 index 00000000..089b873e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642271443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642875943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642875943 Binary files differnew file mode 100644 index 00000000..4205bc9f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1642875943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1643480443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1643480443 Binary files differnew file mode 100644 index 00000000..c62e385f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1643480443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644084943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644084943 Binary files differnew file mode 100644 index 00000000..0d1aba5a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644084943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644689443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644689443 Binary files differnew file mode 100644 index 00000000..b29f0270 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1644689443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645293943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645293943 Binary files differnew file mode 100644 index 00000000..12941a40 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645293943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645898443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645898443 Binary files differnew file mode 100644 index 00000000..5ecfa498 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1645898443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1646502943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1646502943 Binary files differnew file mode 100644 index 00000000..4ffff379 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1646502943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647107443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647107443 Binary files differnew file mode 100644 index 00000000..8aad7b5d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647107443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647711943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647711943 Binary files differnew file mode 100644 index 00000000..72e89b66 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1647711943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648316443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648316443 Binary files differnew file mode 100644 index 00000000..1456d349 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648316443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648920943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648920943 Binary files differnew file mode 100644 index 00000000..d405c337 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1648920943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1649525443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1649525443 Binary files differnew file mode 100644 index 00000000..f1f93785 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1649525443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650129943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650129943 Binary files differnew file mode 100644 index 00000000..bbfc50dc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650129943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650734443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650734443 Binary files differnew file mode 100644 index 00000000..eb55424d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1650734443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651338943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651338943 Binary files differnew file mode 100644 index 00000000..ffe4fdf0 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651338943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651943443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651943443 Binary files differnew file mode 100644 index 00000000..d1208a2c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1651943443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1652547943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1652547943 Binary files differnew file mode 100644 index 00000000..63b05ec2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1652547943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653152443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653152443 Binary files differnew file mode 100644 index 00000000..f81db926 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653152443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653756943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653756943 Binary files differnew file mode 100644 index 00000000..b6eb861f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1653756943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654361443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654361443 Binary files differnew file mode 100644 index 00000000..23821fae --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654361443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654965943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654965943 Binary files differnew file mode 100644 index 00000000..6d5198fa --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1654965943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1655570443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1655570443 Binary files differnew file mode 100644 index 00000000..311483d9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1655570443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656174943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656174943 Binary files differnew file mode 100644 index 00000000..9a365d77 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656174943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656779443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656779443 Binary files differnew file mode 100644 index 00000000..b4d8d28b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1656779443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657383943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657383943 Binary files differnew file mode 100644 index 00000000..781697b3 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657383943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657988443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657988443 Binary files differnew file mode 100644 index 00000000..18420168 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1657988443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1658592943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1658592943 Binary files differnew file mode 100644 index 00000000..973eb566 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_1/1658592943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1626554443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1626554443 Binary files differnew file mode 100644 index 00000000..5c1e1a7d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1626554443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627158943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627158943 Binary files differnew file mode 100644 index 00000000..96a0efd8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627158943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627763443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627763443 Binary files differnew file mode 100644 index 00000000..eeea5d7b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1627763443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628367943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628367943 Binary files differnew file mode 100644 index 00000000..22ea6727 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628367943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628972443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628972443 Binary files differnew file mode 100644 index 00000000..9a271c2f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1628972443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1629576943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1629576943 Binary files differnew file mode 100644 index 00000000..9b84ae3f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1629576943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630181443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630181443 Binary files differnew file mode 100644 index 00000000..d0ae6246 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630181443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630785943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630785943 Binary files differnew file mode 100644 index 00000000..889130ad --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1630785943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631390443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631390443 Binary files differnew file mode 100644 index 00000000..f41c8d04 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631390443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631994943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631994943 Binary files differnew file mode 100644 index 00000000..0632bddc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1631994943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1632599443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1632599443 Binary files differnew file mode 100644 index 00000000..c13ae3d5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1632599443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633203943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633203943 Binary files differnew file mode 100644 index 00000000..f3d65edd --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633203943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633808443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633808443 Binary files differnew file mode 100644 index 00000000..01190d88 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1633808443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1634412943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1634412943 Binary files differnew file mode 100644 index 00000000..0f1bd20f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1634412943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635017443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635017443 Binary files differnew file mode 100644 index 00000000..109fa02c --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635017443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635621943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635621943 Binary files differnew file mode 100644 index 00000000..575f616a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1635621943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636226443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636226443 Binary files differnew file mode 100644 index 00000000..a98b45f7 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636226443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636830943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636830943 Binary files differnew file mode 100644 index 00000000..c038715a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1636830943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1637435443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1637435443 Binary files differnew file mode 100644 index 00000000..592e22eb --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1637435443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638039943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638039943 Binary files differnew file mode 100644 index 00000000..4609184d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638039943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638644443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638644443 Binary files differnew file mode 100644 index 00000000..32e65969 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1638644443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639248943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639248943 Binary files differnew file mode 100644 index 00000000..e84bc300 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639248943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639853443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639853443 Binary files differnew file mode 100644 index 00000000..0f4a3a0a --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1639853443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1640457943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1640457943 Binary files differnew file mode 100644 index 00000000..9981a143 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1640457943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641062443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641062443 Binary files differnew file mode 100644 index 00000000..7b2bbc6f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641062443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641666943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641666943 Binary files differnew file mode 100644 index 00000000..2ff58656 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1641666943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642271443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642271443 Binary files differnew file mode 100644 index 00000000..cc3c144e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642271443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642875943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642875943 Binary files differnew file mode 100644 index 00000000..24c32e68 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1642875943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1643480443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1643480443 Binary files differnew file mode 100644 index 00000000..9a3d2e91 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1643480443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644084943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644084943 Binary files differnew file mode 100644 index 00000000..bd002e8d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644084943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644689443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644689443 Binary files differnew file mode 100644 index 00000000..820c2362 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1644689443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645293943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645293943 Binary files differnew file mode 100644 index 00000000..3e7f6b71 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645293943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645898443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645898443 Binary files differnew file mode 100644 index 00000000..63bdb271 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1645898443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1646502943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1646502943 Binary files differnew file mode 100644 index 00000000..9fd36ee5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1646502943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647107443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647107443 Binary files differnew file mode 100644 index 00000000..140e200b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647107443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647711943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647711943 Binary files differnew file mode 100644 index 00000000..1118e221 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1647711943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648316443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648316443 Binary files differnew file mode 100644 index 00000000..5c1797ed --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648316443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648920943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648920943 Binary files differnew file mode 100644 index 00000000..fcc85a41 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1648920943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1649525443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1649525443 Binary files differnew file mode 100644 index 00000000..a504ee57 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1649525443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650129943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650129943 Binary files differnew file mode 100644 index 00000000..bcff9616 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650129943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650734443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650734443 Binary files differnew file mode 100644 index 00000000..ec6bbf71 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1650734443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651338943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651338943 Binary files differnew file mode 100644 index 00000000..d6b25100 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651338943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651943443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651943443 Binary files differnew file mode 100644 index 00000000..6b2abf18 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1651943443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1652547943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1652547943 Binary files differnew file mode 100644 index 00000000..8e2df783 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1652547943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653152443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653152443 Binary files differnew file mode 100644 index 00000000..f3fdeec5 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653152443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653756943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653756943 Binary files differnew file mode 100644 index 00000000..b7db07db --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1653756943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654361443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654361443 Binary files differnew file mode 100644 index 00000000..b354955d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654361443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654965943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654965943 Binary files differnew file mode 100644 index 00000000..079028cc --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1654965943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1655570443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1655570443 Binary files differnew file mode 100644 index 00000000..5fdea4a8 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1655570443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656174943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656174943 Binary files differnew file mode 100644 index 00000000..8eb804c2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656174943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656779443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656779443 Binary files differnew file mode 100644 index 00000000..a42b189b --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1656779443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657383943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657383943 Binary files differnew file mode 100644 index 00000000..e1327e45 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657383943 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657988443 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657988443 Binary files differnew file mode 100644 index 00000000..d66e5e7e --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1657988443 diff --git a/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1658592943 b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1658592943 Binary files differnew file mode 100644 index 00000000..71ab361d --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/crypto-rsa/coin_eur_ct_10/1658592943 diff --git a/src/testing/test_merchant_api_home/.local/share/taler/exchange/offline-keys/master.priv b/src/testing/test_merchant_api_home/taler/taler/exchange-offline/master.priv index c20942d6..c20942d6 100644 --- a/src/testing/test_merchant_api_home/.local/share/taler/exchange/offline-keys/master.priv +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-offline/master.priv diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-offline/secm_tofus.pub b/src/testing/test_merchant_api_home/taler/taler/exchange-offline/secm_tofus.pub Binary files differnew file mode 100644 index 00000000..56d1b939 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-offline/secm_tofus.pub diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1686160442 b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1686160442 new file mode 100644 index 00000000..f708cb04 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1686160442 @@ -0,0 +1 @@ +§È¾Æ¾£…×H+O¨‡®H棚þ…¯ªÐ¾rk
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1693417742 b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1693417742 new file mode 100644 index 00000000..a9f1e259 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1693417742 @@ -0,0 +1 @@ +º#[ÕÛ–ôÛRülÚgŒèI×íä´AÓ¼
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1700675042 b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1700675042 new file mode 100644 index 00000000..435cecc9 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1700675042 @@ -0,0 +1 @@ +5þ6`ÿ5Äèêò}ªå¬D½»O€o…zþ¨!íÑr–{
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1707932342 b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1707932342 new file mode 100644 index 00000000..a36b9da2 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1707932342 @@ -0,0 +1 @@ +e•Á)`#¹Ýù
RRïkõbd¦õX¹´Á¸výªjí
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1715189642 b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1715189642 new file mode 100644 index 00000000..774f9a84 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/keys/1715189642 @@ -0,0 +1 @@ +Å=âºY÷”ÎÔ²ž\Þûdx©µw…ˆzõ^-!¾UË
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/secmod-private-key b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/secmod-private-key new file mode 100644 index 00000000..72e0c852 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange-secmod-eddsa/secmod-private-key @@ -0,0 +1,2 @@ +¿Ÿž¶¦]T‘L` +Î)¾û3¡Ÿ‹Eû– ï’+Í#G*
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange/offline-keys/master.priv b/src/testing/test_merchant_api_home/taler/taler/exchange/offline-keys/master.priv new file mode 100644 index 00000000..c20942d6 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange/offline-keys/master.priv @@ -0,0 +1 @@ +åÊk;d³_Uû}£A.wÔ"!Gûçv_m "_ò
\ No newline at end of file diff --git a/src/testing/test_merchant_api_home/taler/taler/exchange/wirefees/x-taler-bank.fee b/src/testing/test_merchant_api_home/taler/taler/exchange/wirefees/x-taler-bank.fee Binary files differnew file mode 100644 index 00000000..771ac455 --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/exchange/wirefees/x-taler-bank.fee diff --git a/src/testing/test_merchant_api_home/taler/taler/merchant/merchant.priv b/src/testing/test_merchant_api_home/taler/taler/merchant/merchant.priv new file mode 100644 index 00000000..fd6e5f7f --- /dev/null +++ b/src/testing/test_merchant_api_home/taler/taler/merchant/merchant.priv @@ -0,0 +1 @@ +¶ù,åY%–FF<ßþR˜‰9ϳ5„¬v\þš×k4«6
\ No newline at end of file diff --git a/src/testing/test_merchant_api_twisted-cs.conf b/src/testing/test_merchant_api_twisted-cs.conf index 6c5416d5..8a6a21c0 100644 --- a/src/testing/test_merchant_api_twisted-cs.conf +++ b/src/testing/test_merchant_api_twisted-cs.conf @@ -8,9 +8,6 @@ EXCHANGE_BASE_URL = http://localhost:8888/ [exchange] BASE_URL = http://localhost:8888/ -[auditor] -BASE_URL = http://the.auditor/ - # merchant: 8080 # exchange: 8081 # (Fake)bank: 8082 diff --git a/src/testing/test_merchant_api_twisted-rsa.conf b/src/testing/test_merchant_api_twisted-rsa.conf index 5a61c855..cfa162b0 100644 --- a/src/testing/test_merchant_api_twisted-rsa.conf +++ b/src/testing/test_merchant_api_twisted-rsa.conf @@ -8,9 +8,6 @@ EXCHANGE_BASE_URL = http://localhost:8888/ [exchange] BASE_URL = http://localhost:8888/ -[auditor] -BASE_URL = http://the.auditor/ - # merchant: 8080 # exchange: 8081 # (Fake)bank: 8082 diff --git a/src/testing/test_merchant_api_twisted.c b/src/testing/test_merchant_api_twisted.c index 73b6905b..446e6eb3 100644 --- a/src/testing/test_merchant_api_twisted.c +++ b/src/testing/test_merchant_api_twisted.c @@ -1,6 +1,6 @@ /** * This file is part of TALER - * Copyright (C) 2014-2018 Taler Systems SA + * Copyright (C) 2014-2023 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,7 +16,6 @@ * License along with TALER; see the file COPYING. If not, see * <http://www.gnu.org/licenses/> */ - /** * @file test_merchant_api_twisted.c * @brief testcase to test exchange's HTTP API interface @@ -63,7 +62,7 @@ static char *config_file; #define USER_ACCOUNT_NAME "62" -#define PAYTO_I1 "payto://x-taler-bank/localhost/3" +#define PAYTO_I1 "payto://x-taler-bank/localhost/3?receiver-name=user3" /** @@ -108,12 +107,7 @@ static char *twister_merchant_url_instance_tor; /** * Merchant base URL. */ -static char *merchant_url; - -/** - * Merchant process. - */ -static struct GNUNET_OS_Process *merchantd; +static const char *merchant_url; /** * Twister process that proxies the exchange. @@ -126,11 +120,10 @@ static struct GNUNET_OS_Process *twisterexchanged; static struct GNUNET_OS_Process *twistermerchantd; -static char *payer_payto; -static char *exchange_payto; -static char *merchant_payto; -static struct TALER_TESTING_BankConfiguration bc; -static struct TALER_TESTING_ExchangeConfiguration ec; +static const char *payer_payto; +static const char *exchange_payto; +static const char *merchant_payto; +static struct TALER_TESTING_Credentials cred; /** * User name. Never checked by fakebank. @@ -180,7 +173,7 @@ CMD_TRANSFER_TO_EXCHANGE (const char *label, { return TALER_TESTING_cmd_admin_add_incoming (label, amount, - &bc.exchange_auth, + &cred.ba, payer_payto); } @@ -222,6 +215,7 @@ run (void *cls, "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-abort-1", + cred.cfg, twister_merchant_url, MHD_HTTP_OK, "abort-one", @@ -232,7 +226,7 @@ run (void *cls, * so we'll then have the right to abort. */ TALER_TESTING_cmd_merchant_pay_order ("deposit-simple-for-abort", twister_merchant_url, - MHD_HTTP_NOT_ACCEPTABLE, + MHD_HTTP_BAD_REQUEST, "create-proposal-abort-1", "withdraw-coin-abort-1", "EUR:1.01", @@ -279,6 +273,7 @@ run (void *cls, "EUR:1.01"), CMD_EXEC_WIREWATCH ("wirewatch-double-spend"), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend", + cred.cfg, twister_merchant_url, MHD_HTTP_OK, "DS-1", @@ -286,6 +281,7 @@ run (void *cls, GNUNET_TIME_UNIT_FOREVER_TS, "EUR:1.0"), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-double-spend-1", + cred.cfg, twister_merchant_url, MHD_HTTP_OK, "DS-2", @@ -325,27 +321,29 @@ run (void *cls, struct TALER_TESTING_Command commands[] = { /* general setup */ - TALER_TESTING_cmd_auditor_add ("add-auditor-OK", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_wire_add ("add-wire-account", - "payto://x-taler-bank/localhost/2", - MHD_HTTP_NO_CONTENT, - false), - TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys", - config_file), - TALER_TESTING_cmd_exec_offline_sign_fees ("offline-sign-fees", - config_file, - "EUR:0.01", - "EUR:0.01"), - TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys", - 1), + TALER_TESTING_cmd_run_fakebank ("run-fakebank", + cred.cfg, + "exchange-account-exchange"), + TALER_TESTING_cmd_system_start ("start-taler", + config_file, + "-ema", + "-u", "exchange-account-exchange", + NULL), + TALER_TESTING_cmd_get_exchange ("get-exchange", + cred.cfg, + NULL, + true, + true), TALER_TESTING_cmd_merchant_post_instances ("instance-create-default", twister_merchant_url, "default", - PAYTO_I1, - "EUR", MHD_HTTP_NO_CONTENT), + TALER_TESTING_cmd_merchant_post_account ( + "instance-create-default-account", + twister_merchant_url, + PAYTO_I1, + NULL, NULL, + MHD_HTTP_OK), TALER_TESTING_cmd_batch ("pay", pay), /* Malform the response from the exchange. */ @@ -358,7 +356,7 @@ run (void *cls, * 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", @@ -394,6 +392,7 @@ run (void *cls, "create-proposal-1", NULL), TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2", + cred.cfg, merchant_url, MHD_HTTP_OK, "2", @@ -402,7 +401,7 @@ run (void *cls, "EUR:6.0"), TALER_TESTING_cmd_merchant_pay_order ("deposit-2", merchant_url, - MHD_HTTP_NOT_ACCEPTABLE, + MHD_HTTP_BAD_REQUEST, "create-proposal-2", "withdraw-coin-1", "EUR:5", @@ -417,9 +416,8 @@ run (void *cls, TALER_TESTING_cmd_end () }; - TALER_TESTING_run_with_fakebank (is, - commands, - bc.exchange_auth.wire_gateway_url); + TALER_TESTING_run (is, + commands); } @@ -431,7 +429,8 @@ run (void *cls, static void purge_process (struct GNUNET_OS_Process *process) { - GNUNET_OS_process_kill (process, SIGINT); + GNUNET_OS_process_kill (process, + SIGINT); GNUNET_OS_process_wait (process); GNUNET_OS_process_destroy (process); } @@ -441,93 +440,55 @@ int main (int argc, char *const *argv) { - char *cipher; - unsigned int ret; - - /* These environment variables get in the way... */ - unsetenv ("XDG_DATA_HOME"); - unsetenv ("XDG_CONFIG_HOME"); - GNUNET_log_setup (argv[0], - "INFO", - NULL); - cipher = GNUNET_TESTING_get_testname_from_underscore (argv[0]); - GNUNET_assert (NULL != cipher); - GNUNET_asprintf (&config_file, - "test_merchant_api_twisted-%s.conf", - cipher); - GNUNET_free (cipher); - if (GNUNET_OK != - TALER_TESTING_prepare_fakebank (config_file, - "exchange-account-exchange", - &bc)) - return 77; - + int ret; - 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; - - if (NULL == (twister_exchange_url = TALER_TWISTER_prepare_twister - (PROXY_EXCHANGE_config_file))) + { + char *cipher; + + cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]); + GNUNET_assert (NULL != cipher); + GNUNET_asprintf (&config_file, + "test_merchant_api_twisted-%s.conf", + cipher); + GNUNET_free (cipher); + } + payer_payto = + "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=user"; + exchange_payto = + "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME + "?receiver-name=exchange"; + merchant_payto = + "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME + "?receiver-name=merchant"; + merchant_url = "http://localhost:8080/"; + if (NULL == (twister_exchange_url = TALER_TWISTER_prepare_twister ( + PROXY_EXCHANGE_config_file))) return 77; - if (NULL == (twister_merchant_url = TALER_TWISTER_prepare_twister - (PROXY_MERCHANT_config_file))) + if (NULL == (twister_merchant_url = TALER_TWISTER_prepare_twister ( + PROXY_MERCHANT_config_file))) return 77; - twister_merchant_url_instance_nonexistent = TALER_url_join ( twister_merchant_url, "instances/foo/", NULL); twister_merchant_url_instance_tor = TALER_url_join ( twister_merchant_url, "instances/tor/", NULL); - - 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: + if (NULL == (twisterexchanged = TALER_TWISTER_run_twister + (PROXY_EXCHANGE_config_file))) return 77; - case GNUNET_OK: - - if (NULL == (merchantd = TALER_TESTING_run_merchant - (config_file, merchant_url))) - // 1 is fine; after all this is merchant test cases. - return 1; - - if (NULL == (twisterexchanged = TALER_TWISTER_run_twister - (PROXY_EXCHANGE_config_file))) - return 77; - - if (NULL == (twistermerchantd = TALER_TWISTER_run_twister - (PROXY_MERCHANT_config_file))) - return 77; - - /* Run the exchange and schedule 'run()' */ - ret = TALER_TESTING_setup_with_exchange (&run, NULL, - config_file); - purge_process (merchantd); - purge_process (twisterexchanged); - purge_process (twistermerchantd); - GNUNET_free (merchant_url); - GNUNET_free (twister_exchange_url); - GNUNET_free (twister_merchant_url); - - if (GNUNET_OK != ret) - return 1; - break; - default: - GNUNET_break (0); - return 1; - } - return 0; + if (NULL == (twistermerchantd = TALER_TWISTER_run_twister + (PROXY_MERCHANT_config_file))) + return 77; + ret = TALER_TESTING_main (argv, + "INFO", + config_file, + "exchange-account-exchange", + TALER_TESTING_BS_FAKEBANK, + &cred, + &run, + NULL); + purge_process (twisterexchanged); + purge_process (twistermerchantd); + return ret; } diff --git a/src/testing/test_merchant_instance_auth.sh b/src/testing/test_merchant_instance_auth.sh index f4534b9a..85857b4f 100755 --- a/src/testing/test_merchant_instance_auth.sh +++ b/src/testing/test_merchant_instance_auth.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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 @@ -17,45 +17,70 @@ # <http://www.gnu.org/licenses/> # -# Exit, with status code "skip" (no 'real' failure) -function exit_skip() { - echo $1 - exit 77 +# Cleanup to run whenever we exit +function my_cleanup() +{ + for n in $(jobs -p) + do + kill "$n" 2> /dev/null || true + done + wait + if [ -n "${LAST_RESPONSE+x}" ] + then + rm -f "${LAST_RESPONSE}" + fi } -. initialize_taler_system.sh +. setup.sh +setup -c test_template.conf -m +CONF="test_template.conf.edited" +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) -echo -n "Configuring 'default' instance ..." +echo -n "Configuring 'default' instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:new_value"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:new_value"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" >&2 fi -echo " OK" +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:new_value' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user43"}' \ + -w "%{http_code}" -s -o /dev/null) + + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi + +echo " OK" >&2 +# Kill merchant +kill -TERM "$SETUP_PID" +wait +unset SETUP_PID -kill $MERCHANT_HTTPD_PID -wait $MERCHANT_HTTPD_PID +setup -c test_template.conf -ef -u "exchange-account-2" NEW_SECRET=secret-token:different_value taler-merchant-httpd -a "${NEW_SECRET}" -c "${CONF}" -L DEBUG 2> taler-merchant-httpd.log & -MERCHANT_HTTPD_PID=$! -#taler-merchant-httpd -c $CONF -L DEBUG 2> taler-merchant-httpd.log & +# Install cleanup handler (except for kill -9) +trap my_cleanup EXIT -echo -n "Waiting for the merchant..." +echo -n "Waiting for the merchant..." >&2 # Wait for merchant to be available (usually the slowest) -for n in `seq 1 50` +for n in $(seq 1 50) do - echo -n "." + echo -n "." >&2 sleep 0.1 OK=0 # merchant @@ -65,71 +90,149 @@ do done if [ "x$OK" != "x1" ] -then - exit_skip "Failed to start merchant backend" +then + exit_fail "Failed to (re)start merchant backend" fi -echo -n "Creating order to test auth is ok..." +echo -n "Creating order to test auth is ok..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ - 'http://localhost:9966/instances/default/private/orders' \ - -H 'Authorization: Bearer '$NEW_SECRET \ + 'http://localhost:9966/private/orders' \ + -H 'Authorization: Bearer '"$NEW_SECRET" \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -H 'Authorization: Bearer '$NEW_SECRET \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -H 'Authorization: Bearer '"$NEW_SECRET" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") -echo OK order $ORDER_ID with $TOKEN +echo "OK order ${ORDER_ID} with ${TOKEN} and ${PAY_URL}" >&2 -echo -n "Configuring 'second' instance ..." +echo -n "Configuring 'second' instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer '$NEW_SECRET \ + -H 'Authorization: Bearer '"$NEW_SECRET" \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:second"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"second","name":"second","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:second"},"id":"second","name":"second","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi -echo "OK" +echo "OK" >&2 -echo -n "Updating 'second' instance token using the 'default' auth token..." +echo -n "Updating 'second' instance token using the 'default' auth token..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer '$NEW_SECRET \ + -H 'Authorization: Bearer '"$NEW_SECRET" \ http://localhost:9966/management/instances/second/auth \ -d '{"method":"token","token":"secret-token:new_one"}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance auth token changed. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance auth token changed. got: $STATUS" +fi +NEW_SECRET="secret-token:new_one" +echo " OK" >&2 + + +echo -n "Requesting login token..." >&2 + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer '"$NEW_SECRET" \ + http://localhost:9966/instances/second/private/token \ + -d '{"scope":"readonly","refreshable":true}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, login token created. got: $STATUS" +fi + +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") + +echo " OK" >&2 + +echo -n "Using login token..." >&2 + +STATUS=$(curl "http://localhost:9966/instances/second/private/orders" \ + -H 'Authorization: Bearer '"$TOKEN" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, getting orders. got: $STATUS" +fi + +echo " OK" >&2 + +echo -n "Refreshing login token..." >&2 + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer '"$TOKEN" \ + http://localhost:9966/instances/second/private/token \ + -d '{"scope":"write","refreshable":true}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "403" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 403, refused to upgrade login token. got: $STATUS" +fi + +echo " OK" >&2 + + +echo -n "Deleting login token..." >&2 + +STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ + -H 'Authorization: Bearer '"$TOKEN" \ + http://localhost:9966/instances/second/private/token \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "204" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 204, login token deleted. got: $STATUS" fi +echo " OK" >&2 + +echo -n "Using deleted login token..." >&2 + +STATUS=$(curl "http://localhost:9966/instances/second/private/orders" \ + -H 'Authorization: Bearer '"$TOKEN" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "401" ] +then + jq < "$LAST_RESPONSE" >&2 + exit_fail "Expected 401, token was deleted. got: $STATUS" +fi + +echo " OK" >&2 -echo " OK" +echo "Test PASSED" exit 0 diff --git a/src/testing/test_merchant_instance_creation.sh b/src/testing/test_merchant_instance_creation.sh index 9fee5773..c7eda54b 100755 --- a/src/testing/test_merchant_instance_creation.sh +++ b/src/testing/test_merchant_instance_creation.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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 @@ -17,19 +17,22 @@ # <http://www.gnu.org/licenses/> # -. initialize_taler_system.sh +. setup.sh + +# Launch only the merchant. +setup -c test_template.conf -m echo -n "Configuring a merchant instance before configuring the default instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"first","name":"test","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"id":"first","name":"test","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS + echo "Expected 204, instance created. got: $STATUS" exit 1 fi @@ -40,12 +43,12 @@ echo -n "Configuring default instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) -if [ "$STATUS" != "204" ] +if [ "$STATUS" != "401" ] then - echo 'should respond ok, instance created. got:' $STATUS + echo "Expected 401, permission denied. got: $STATUS" exit 1 fi @@ -55,16 +58,15 @@ echo -n "Configuring a second merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"second","name":"test","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"id":"second","name":"test","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) -if [ "$STATUS" != "204" ] +if [ "$STATUS" != "401" ] then - echo 'should respond ok, instance created. got:' $STATUS + echo "Expected 401, permission denied. got: $STATUS" exit 1 fi echo " OK" - exit 0 diff --git a/src/testing/test_merchant_instance_purge.sh b/src/testing/test_merchant_instance_purge.sh index 60467385..f3992495 100755 --- a/src/testing/test_merchant_instance_purge.sh +++ b/src/testing/test_merchant_instance_purge.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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 @@ -17,55 +17,51 @@ # <http://www.gnu.org/licenses/> # -. initialize_taler_system.sh +. setup.sh -echo -n "Configuring default instance ..." +# Launch only the merchant. +setup -c test_template.conf -m + +echo -n "Configuring default instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi -echo " OK" +echo " OK" >&2 -echo -n "Configuring merchant instance ..." +echo -n "Configuring merchant instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X POST \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"test","name":"test","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"id":"test","name":"test","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi +echo " OK" >&2 -echo " OK" - - -echo -n "Deleting instance ..." - +echo -n "Deleting instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ "http://localhost:9966/management/instances/test" \ -w "%{http_code}" -s -o /dev/null) - if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance deleted. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance deleted. got: $STATUS" fi -echo " OK" -echo -n "Purging instance ..." +echo " OK" >&2 +echo -n "Purging instance ..." >&2 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ "http://localhost:9966/management/instances/test?purge=yes" \ @@ -74,10 +70,10 @@ STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance deleted. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance deleted. got: $STATUS" fi -echo " OK" +echo " OK" >&2 +echo "Test PASSED" exit 0 diff --git a/src/testing/test_merchant_instance_response.sh b/src/testing/test_merchant_instance_response.sh index 41ac983b..066efb67 100755 --- a/src/testing/test_merchant_instance_response.sh +++ b/src/testing/test_merchant_instance_response.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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 @@ -17,121 +17,113 @@ # <http://www.gnu.org/licenses/> # -. initialize_taler_system.sh +. setup.sh + +# Launch only the merchant. +setup -c test_template.conf -m -# echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X OPTIONS \ - http://localhost:9966/instances/default/private/products \ + http://localhost:9966/private/products \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'options should return 204 when default instance doest not exist yet. got:' $STATUS - exit 1 + exit_fail "Expected 204 when default instance does not exist yet. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X GET \ -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/instances/default/private/products \ + http://localhost:9966/private/products \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "404" ] then - echo 'backend should respond 404 when the default instance is not yet created. got:' $STATUS - exit 1 + exit_fail "Expected 404 when the default instance is not yet created. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"payto_uris":["payto://x-taler-bank/localhost/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ + -d '{"auth":{"method":"token","token":"secret-token:other_secret"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X GET \ - http://localhost:9966/instances/default/private/products \ + http://localhost:9966/private/products \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "401" ] then - echo 'should respond unauthorized without the token for the list of product when the default instance was created. got:' $STATUS - exit 1 + exit_fail "Expected 401 without the token for the list of product when the default instance was created. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X GET \ -H 'Authorization: Bearer secret-token:other_secret' \ - http://localhost:9966/instances/default/private/products \ + http://localhost:9966/private/products \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "200" ] then - echo 'should respond ok for the list of product when the default instance was created. got:' $STATUS - exit 1 + exit_fail "Expected 200 for the list of product when the default instance was created. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:other_secret' \ - http://localhost:9966/instances/default/private/auth \ + http://localhost:9966/private/auth \ -d '{"method":"token","token":"secret-token:zxc"}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance auth token changed. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance auth token changed. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ - "http://localhost:9966/instances/default/private" \ + "http://localhost:9966/private" \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "401" ] then - echo 'should respond unauthorized without the token, when purging the instance. got:' $STATUS - exit 1 + exit_fail "Expected 401 without the token, when purging the instance. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ -H 'Authorization: Bearer secret-token:other_secret' \ - "http://localhost:9966/instances/default/private" \ + "http://localhost:9966/private" \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "401" ] then - echo 'should respond unauthorized using old token, when purging the instance. got:' $STATUS - exit 1 + exit_fail "Expected 401 using old token, when purging the instance. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ -H 'Authorization: Bearer secret-token:zxc' \ - "http://localhost:9966/instances/default/private" \ + "http://localhost:9966/private" \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond unauthorized without the token, when purging the instance. got:' $STATUS - exit 1 + exit_fail "Expected 204 when purging the instance. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X GET \ -H 'Authorization: Bearer secret-token:zxc' \ - http://localhost:9966/instances/default/private/products \ + http://localhost:9966/private/products \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "404" ] then - echo 'should respond not found when trying to list the product and the default instance was deleted. got:' $STATUS - exit 1 + exit_fail "Expected 404 when trying to list the product and the default instance was deleted. got: $STATUS" fi -echo "OK" +echo "Test PASSED" exit 0 diff --git a/src/testing/test_merchant_kyc.sh b/src/testing/test_merchant_kyc.sh index e95e7586..1c818c31 100755 --- a/src/testing/test_merchant_kyc.sh +++ b/src/testing/test_merchant_kyc.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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,22 +16,50 @@ # License along with TALER; see the file COPYING. If not, see # <http://www.gnu.org/licenses/> # +set -eu -. initialize_taler_system.sh +. setup.sh -echo -n "Configuring a merchant instance before configuring the default instance ..." +# Launch system. +setup -c "test_template.conf" -mef -u "exchange-account-2" +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) + +echo -n "Configuring a merchant default instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost:8082/43","payto://x-taler-bank/localhost:8082/44"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204 ok, instance created. got: $STATUS" +fi + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/43?receiver-name=user43"}' \ + -w "%{http_code}" -s -o /dev/null) + + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi + +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"payto://x-taler-bank/localhost:8082/44?receiver-name=user44"}' \ + -w "%{http_code}" -s -o /dev/null) + + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" fi echo " OK" @@ -39,13 +67,12 @@ echo " OK" echo -n "Check the instance exists ..." STATUS=$(curl -H "Content-Type: application/json" -X GET \ - http://localhost:9966/instances/default/private/ \ + http://localhost:9966/private/ \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "200" ] then - echo 'should respond ok, instance exists. got:' $STATUS - exit 1 + exit_fail "Expected 200 ok, instance exists. got: $STATUS" fi echo " OK" @@ -57,52 +84,51 @@ RANDOM_IMG='data:image/png;base64,abcdefg' # echo -n "Creating order without TOKEN..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"create_token":false,"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'$RANDOM_IMG'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"create_token":false,"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` + echo "Should respond 200 OK, order created. got: $STATUS" + jq < "$LAST_RESPONSE" exit 1 fi -ORDER_ID=`jq -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -r .token < "$LAST_RESPONSE") if [ "$TOKEN" != "null" ] then - echo 'token should be null, got:' $TOKEN - exit 1 + exit_fail "Token should be null, got: $TOKEN" fi -echo OK +echo "OK" echo -n "Checking created order without TOKEN..." STATUS=$(curl http://localhost:9966/orders/$ORDER_ID \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") -PAY_URI=`jq -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE") if [ "$PAY_URI" == "null" ] then - echo 'should have a payuri. got:' $PAY_URI `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected a taler_pay_uri. Got: $PAY_URI" fi -echo OK +echo "OK" -echo -n "Getting information about kyc ..." +echo -n "Getting information about KYC ..." STATUS=$(curl -H "Content-Type: application/json" -X GET \ - http://localhost:9966/instances/default/private/kyc \ + http://localhost:9966/private/kyc \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204. got: $STATUS" fi echo " OK" diff --git a/src/testing/test_merchant_order_autocleanup.sh b/src/testing/test_merchant_order_autocleanup.sh index 4a53edca..3f792f12 100755 --- a/src/testing/test_merchant_order_autocleanup.sh +++ b/src/testing/test_merchant_order_autocleanup.sh @@ -1,21 +1,84 @@ #!/bin/bash # This file is in the public domain. -. initialize_taler_system.sh +set -eu + +. setup.sh + + +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:8082/" +else + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + echo -n "Testing for libeufin-bank" + libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" + echo " FOUND" + +fi + +echo -n "Testing for taler-harness" +taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + +# Launch exchange, merchant and bank. +setup -c "test_template.conf" \ + -em \ + $BANK_FLAGS +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) +CONF="test_template.conf.edited" +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) +EXCHANGE_URL="http://localhost:8081/" + echo -n "First, prepare wallet with coins..." -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ +rm -f "$WALLET_DB" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:99", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL" \ + --arg BANK_URL "${BANK_URL}" \ --arg EXCHANGE_URL "$EXCHANGE_URL" )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out +echo -n "." +if [ 1 = "$USE_FAKEBANK" ] +then + # Fakebank is instant... + sleep 0 +else + sleep 10 + # NOTE: once libeufin can do long-polling, we should + # be able to reduce the delay here and run wirewatch + # always in the background via setup +fi +echo -n "." +taler-exchange-wirewatch \ + -L "INFO" \ + -c "$CONF" \ + -t \ + &> taler-exchange-wirewatch.out +echo -n "." + +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish-1.err \ + >wallet-withdraw-finish-1.out echo " OK" # @@ -23,236 +86,254 @@ echo " OK" # echo -n "Configuring merchant instance ..." +if [ 1 = "$USE_FAKEBANK" ] +then + FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree" +else + FORTYTHREE=$(get_payto_uri fortythree x) +fi -# create with 2 address STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost:8082/43","payto://x-taler-bank/localhost:8082/44"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + "http://localhost:9966/management/instances" \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi -# remove one account address -STATUS=$(curl -H "Content-Type: application/json" -X PATCH \ +STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/instances/default/private/ \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost:8082/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ -w "%{http_code}" -s -o /dev/null) -if [ "$STATUS" != "204" ] +if [ "$STATUS" != "200" ] then - echo 'should respond ok, instance updated. got:' $STATUS - exit 1 + exit_fail "Expected '200 OK' response. Got instead $STATUS" fi -echo OK - -NOW=`date +%s` -IN_TEN_SECS=`echo $(( $NOW + 5 ))` +NOW=$(date +%s) +IN_TEN_SECS=$(( NOW + 10 )) echo -n "Creating order to be claimed..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme","pay_deadline": {"t_ms":'$NOW'000}}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme","pay_deadline": {"t_s":'"$IN_TEN_SECS"'}}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") echo "Ok (order $ORDER_ID)" -NOW=`date +%s` +NOW=$(date +%s) echo -n "Claim the order but do not pay it ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB advanced pay-prepare "${PAY_URL}" 2> wallet-pay1.err > wallet-pay1.log +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + advanced pay-prepare \ + "${PAY_URL}" \ + 2> wallet-claim1.err > wallet-claim1.log -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "claimed" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" fi -NOW2=`date +%s` -echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW)) secs)" -echo 'wait 8 secs ' +echo "Wait 8 secs ..." sleep 8 echo -n "Trying to get the list of orders..." -STATUS=$(curl "http://localhost:9966/instances/default/private/orders" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" fi echo "ok" echo -n "Creating a new order that will trigger the db cleanup..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ +STATUS=$(curl 'http://localhost:9966/private/orders' \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") echo "Ok (order $ORDER_ID)" echo -n "Trying to get the list of orders (issue #7025)..." -STATUS=$(curl "http://localhost:9966/instances/default/private/orders" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" fi -echo ok +echo "OK" # set -x echo -n "Now paying this order..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}"\ + -y \ + 2> wallet-pay1.err > wallet-pay1.log -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "paid" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" fi -NOW2=`date +%s` -echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW)) secs )" echo -n "Trying to get the list of orders..." -STATUS=$(curl "http://localhost:9966/instances/default/private/orders" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" fi echo ok echo -n "Finally, create another order..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ +STATUS=$(curl 'http://localhost:9966/private/orders' \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claiming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") echo "Ok (order $ORDER_ID)" echo -n "Now paying this order..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri \ + "${PAY_URL}" \ + -y \ + 2> wallet-pay1.err > wallet-pay1.log -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "paid" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" fi -NOW2=`date +%s` +NOW2=$(date +%s) echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" echo -n "Trying to get the list of orders..." -STATUS=$(curl "http://localhost:9966/instances/default/private/orders" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" fi -echo ok +echo "ok" + +echo "Test PASSED" exit 0 diff --git a/src/testing/test_merchant_order_creation.sh b/src/testing/test_merchant_order_creation.sh index 684803b8..2336ad4e 100755 --- a/src/testing/test_merchant_order_creation.sh +++ b/src/testing/test_merchant_order_creation.sh @@ -3,36 +3,87 @@ set -eu -. initialize_taler_system.sh - -# $1: sandbox username -# $2: sandbox password -# $3: payto with subject -# $4: amount -function wire_funds() { - libeufin-cli sandbox demobank new-transaction +function clean_wallet() { + rm -f "${WALLET_DB}" + exit_cleanup } + +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + BANK_FLAGS="-f -d x-taler-bank -u $ACCOUNT" + BANK_URL="http://localhost:8082/" +else + ACCOUNT="exchange-account-1" + BANK_FLAGS="-ns -d iban -u $ACCOUNT" + BANK_URL="http://localhost:18082/" + echo -n "Testing for libeufin-bank" + libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" + echo " FOUND" + +fi + +. setup.sh + +echo -n "Testing for taler-harness" +taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + +# Launch exchange, merchant and bank. +setup -c "test_template.conf" \ + -em \ + $BANK_FLAGS +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) +CONF="test_template.conf.edited" +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) +EXCHANGE_URL="http://localhost:8081/" + +# Install cleanup handler (except for kill -9) +trap clean_wallet EXIT + echo -n "First prepare wallet with coins ..." -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ +rm -f "$WALLET_DB" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:99", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL/access-api/" \ + --arg BANK_URL "${BANK_URL}" \ --arg EXCHANGE_URL "$EXCHANGE_URL" )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out +echo -n "." +# FIXME-MS: add logic to have nexus check immediately here. +# sleep 10 +echo -n "." +# NOTE: once libeufin can do long-polling, we should +# be able to reduce the delay here and run wirewatch +# always in the background via setup +taler-exchange-wirewatch \ + -a "$ACCOUNT" \ + -L "INFO" \ + -c "$CONF" \ + -t &> taler-exchange-wirewatch.out +echo -n "." +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish-1.err \ + >wallet-withdraw-finish-1.out echo " OK" -CURRENCY_COUNT=$(taler-wallet-cli --wallet-db=$WALLET_DB balance | jq '.balances|length') +CURRENCY_COUNT=$(taler-wallet-cli --wallet-db="$WALLET_DB" balance | jq '.balances|length') if [ "$CURRENCY_COUNT" = "0" ] then - echo 'should have at least one currency, withdrawal failed. check log.' - exit 1 + exit_fail "Expected least one currency, withdrawal failed. check log." fi # @@ -41,35 +92,77 @@ fi echo -n "Configuring merchant instance ..." -# create with 2 address -FORTYTHREE=`get_payto_uri fortythree x` STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["'$FORTYTHREE'","payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected '204 No content' response. Got instead $STATUS" fi +echo "Ok" -# remove one account address +echo -n "Configuring merchant account ..." + +if [ 1 = "$USE_FAKEBANK" ] +then + FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree" +else + FORTYTHREE=$(get_payto_uri fortythree x) +fi +# create with 2 bank account addresses +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ + -w "%{http_code}" -s -o /dev/null) +if [ "$STATUS" != "200" ] +then + exit_fail "Expected '200 OK' response. Got instead $STATUS" +fi +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four"}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected '200 OK' response. Got instead $STATUS" +fi + + +echo "Ok" + +echo -n "Get accounts..." +STATUS=$(curl http://localhost:9966/private/accounts \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") +PAY_URI=$(jq -r .accounts[1].payto_uri < "$LAST_RESPONSE") +H_WIRE=$(jq -r .accounts[1].h_wire < "$LAST_RESPONSE") +if [ "$PAY_URI" != "payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four" ] +then + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected second payto URI. Got $PAY_URI" +fi +echo "OK" + +# remove one account address +echo -n "Deleting one account ..." STATUS=$(curl -H "Content-Type: application/json" -X PATCH \ -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/instances/default/private/ \ - -d '{"auth":{"method":"external"},"payto_uris":["'$FORTYTHREE'"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ + "http://localhost:9966/private/accounts/${H_WIRE}" \ + -X DELETE \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance updated. got:' $STATUS - exit 1 + exit_fail "Expected '204 No content' for deletion of ${H_WIRE}. Got instead: $STATUS" fi +echo "OK" -echo OK RANDOM_IMG='data:image/png;base64,abcdefg' # @@ -77,38 +170,34 @@ RANDOM_IMG='data:image/png;base64,abcdefg' # echo -n "Creating order without TOKEN..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"create_token":false,"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'$RANDOM_IMG'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"create_token":false,"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -r .token < "$LAST_RESPONSE") if [ "$TOKEN" != "null" ] then - echo 'token should be null, got:' $TOKEN - exit 1 + exit_fail "token should be null, got: $TOKEN" fi echo "OK" echo -n "Checking created order without TOKEN..." - -STATUS=$(curl http://localhost:9966/orders/$ORDER_ID \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -PAY_URI=`jq -r .taler_pay_uri < $LAST_RESPONSE` - +STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") +PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE") if [ "$PAY_URI" == "null" ] then - echo 'should have a payuri. got:' $PAY_URI `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected non-NULL payuri. got $PAY_URI" fi echo "OK" @@ -117,86 +206,153 @@ echo "OK" # echo -n "Creating order without TOKEN and fullfilment URL..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"create_token":false,"order":{"fulfillment_url":"go_here_please", "amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'$RANDOM_IMG'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"create_token":false,"order":{"fulfillment_url":"go_here_please", "amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -r .token < "$LAST_RESPONSE") if [ "$TOKEN" != "null" ] then - echo 'token should be null, got:' $TOKEN - exit 1 + exit_fail "Token should be null, got: $TOKEN" fi -STATUS=$(curl http://localhost:9966/orders/$ORDER_ID \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") -PAY_URI=`jq -r .taler_pay_uri < $LAST_RESPONSE` -FULLFILMENT_URL=`jq -r .fulfillment_url < $LAST_RESPONSE` +PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE") +FULLFILMENT_URL=$(jq -r .fulfillment_url < "$LAST_RESPONSE") if [ "$FULLFILMENT_URL" != "go_here_please" ] then - echo 'should have a payuri. got:' $PAY_URI `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected a pay URI. got: $PAY_URI" fi if [ "$PAY_URI" == "null" ] then - echo 'should have a payuri. got:' $PAY_URI `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected non-NULL pay URI. Got: $PAY_URI" fi echo "OK" # +# CREATE TOKEN FAMILY AND V1 ORDER WITH CHOICES +# +echo -n "Creating token family ..." +NOW=$(date +%s) +IN_A_YEAR=$((NOW + 31536000)) +STATUS=$(curl 'http://localhost:9966/private/tokenfamilies' \ + -d '{"slug":"test-sub","kind":"subscription","description":"Test token family","name":"Test Subscription","valid_after":{"t_s":'$NOW'},"valid_before":{"t_s":'$IN_A_YEAR'},"duration": {"d_us": 2592000000}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "204" ] +then + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 204, token family created. got: $STATUS" +fi + +echo " OK" + +echo -n "Creating v1 order with token family ..." +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"version":"1","amount":"TESTKUDOS:7","summary":"with_subscription","fulfillment_message":"Paid successfully","choices":[{"inputs":[{"kind":"token","count":1,"token_family_slug":"test-sub","valid_after":{"t_s":'$NOW'}}],"outputs":[{"kind":"token","count":1,"token_family_slug":"test-sub","valid_after":{"t_s":'$NOW'}}]}]}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order created. got: $STATUS" +fi + +echo " OK" + +echo -n "Claming order with token family ..." + +ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -r .token < "$LAST_RESPONSE") + +STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \ + -d '{"nonce":"","token":"'"$TOKEN"'"}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order claimed. got: $STATUS" +fi + +echo " OK" + +# echo -n "Fetching pay URL for order ..." +# STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ +# -w "%{http_code}" -s -o "$LAST_RESPONSE") + +# if [ "$STATUS" != "200" ] +# then +# jq . < "$LAST_RESPONSE" +# exit_fail "Expected 200, getting order info before claming it. got: $STATUS" +# fi + +# PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") + +# echo " OK" + +# NOW=$(date +%s) + +# echo -n "Pay for order ${PAY_URL} ..." +# taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log +# taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" run-until-done 2> wallet-finish-pay1.err > wallet-finish-pay1.log +# NOW2=$(date +%s) +# echo " OK (took $(( NOW2 - NOW )) secs )" + +# # CREATE ORDER WITH NON-INVENTORY AND CHECK # echo -n "Creating order with non-inventory products..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'$RANDOM_IMG'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -r .token < "$LAST_RESPONSE") -STATUS=$(curl http://localhost:9966/orders/$ORDER_ID/claim \ - -d '{"nonce":"","token":"'$TOKEN'"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \ + -d '{"nonce":"","token":"'"$TOKEN"'"}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order claimed. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" >&2 + exit_fail "Expected 200, order claimed. got: $STATUS" fi -QUANTITY=`jq -r .contract_terms.products[0].quantity < $LAST_RESPONSE` +QUANTITY=$(jq -r .contract_terms.products[0].quantity < "$LAST_RESPONSE") if [ "$QUANTITY" != "1" ] then - echo 'should get quantity 1. got:' $QUANTITY # `jq .contract_terms.products[0] < $LAST_RESPONSE` - exit 1 + exit_fail "Expected quantity 1. got: $QUANTITY" fi -IMAGE=`jq -r .contract_terms.products[0].image < $LAST_RESPONSE` +IMAGE=$(jq -r .contract_terms.products[0].image < "$LAST_RESPONSE") if [ "$IMAGE" != "$RANDOM_IMG" ] then - echo 'should get image but got something else. got:' $IMAGE - exit 1 + exit_fail "Expected $RANDOM_IMG but got something else: $IMAGE" fi -echo OK +echo "OK" # @@ -204,65 +360,62 @@ echo OK # echo -n "Creating product..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/products' \ +STATUS=$(curl 'http://localhost:9966/private/products' \ -d '{"product_id":"2","description":"product with id 2 and price :15","price":"TESTKUDOS:15","total_stock":2,"description_i18n":{},"unit":"","image":"'$RANDOM_IMG'","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, product created. got:' $STATUS - exit 1 + exit_fail "Expected 204, product created. got: $STATUS" fi -echo OK +echo "OK" echo -n "Creating order with inventory products..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ +STATUS=$(curl 'http://localhost:9966/private/orders' \ -d '{"order":{"amount":"TESTKUDOS:7","summary":"3"},"inventory_products":[{"product_id":"2","quantity":1}]}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 OK, order created response. Got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl http://localhost:9966/orders/$ORDER_ID/claim \ - -d '{"nonce":"","token":"'$TOKEN'"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \ + -d '{"nonce":"","token":"'"$TOKEN"'"}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order claimed. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200, order claimed. got: $STATUS" fi -QUANTITY=`jq -r .contract_terms.products[0].quantity < $LAST_RESPONSE` +QUANTITY=$(jq -r .contract_terms.products[0].quantity < "$LAST_RESPONSE") if [ "$QUANTITY" != "1" ] then - echo 'should get quantity 1. got:' $QUANTITY #`jq .contract_terms.products[0] < $LAST_RESPONSE` - exit 1 + exit_fail "Expected quantity 1. got: $QUANTITY" fi echo "OK" # -# CREATE INVALID ORDER +# Create product in another currency # -STATUS=$(curl 'http://localhost:9966/instances/default/private/products' \ +STATUS=$(curl 'http://localhost:9966/private/products' \ -d '{"product_id":"1","description":"product with id 1 and price :15","price":"USD:15","total_stock":1,"description_i18n":{},"unit":"","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \ -w "%{http_code}" -s -o /dev/null) -if [ "$STATUS" != "400" ] +if [ "$STATUS" != "204" ] then - echo 'should respond bad request, product price is in another currency. got:' $STATUS - exit 1 + exit_fail "Expected 204 no content. got: $STATUS" fi # @@ -270,144 +423,123 @@ fi # echo -n "Creating order to be paid..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ +STATUS=$(curl 'http://localhost:9966/private/orders' \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"2","quantity":1}]}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") -echo OK +echo "OK" -NOW=`date +%s` +NOW=$(date +%s) echo -n "Pay first order ${PAY_URL} ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB run-until-done 2> wallet-finish-pay1.err > wallet-finish-pay1.log -NOW2=`date +%s` -echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" +taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log +taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" run-until-done 2> wallet-finish-pay1.err > wallet-finish-pay1.log +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW )) secs )" -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should response ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200, after pay. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "paid" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Order status should be 'paid'. got: $ORDER_STATUS" fi # # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND # -PAY_DEADLINE=`jq -r .contract_terms.pay_deadline.t_s < $LAST_RESPONSE` -WIRE_DEADLINE=`jq -r .contract_terms.wire_transfer_deadline.t_s < $LAST_RESPONSE` +# PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE") +WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE") -NOW=`date +%s` +NOW=$(date +%s) -TO_SLEEP=`echo $(( $WIRE_DEADLINE - $NOW ))` -echo waiting $TO_SLEEP secs for wire transfer +TO_SLEEP=$(( WIRE_DEADLINE - NOW )) +echo "Waiting $TO_SLEEP secs for wire transfer" echo -n "Perform wire transfers ..." -taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggregator.log -taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log +taler-exchange-aggregator -y -c "$CONF" -T "${TO_SLEEP}"000000 -t -L INFO &> aggregator.log +taler-exchange-transfer -c "$CONF" -t -L INFO &> transfer.log echo " DONE" echo -n "Give time to Nexus to route the payment to Sandbox..." +# FIXME-MS: trigger immediate update at nexus +# NOTE: once libeufin can do long-polling, we should +# be able to reduce the delay here and run aggregator/transfer +# always in the background via setup sleep 3 echo " DONE" -echo -n "Obtaining wire transfer details from bank..." -# Emulating the previous pybank-based logic of getting -# the wire transfer information _via the exchange_ bank -# account. NOTE: grabbing tx == 0, since the latest -# transaction appear first in the bank's history. -BANKDATA=`get_bankaccount_transactions exchange x | jq '.transactions[0]'` -SUBJECT=`echo $BANKDATA | jq -r .subject` -WTID=`echo $SUBJECT | awk '{print $1}'` -WURL=`echo $SUBJECT | awk '{print $2}'` -CREDIT_AMOUNT="`echo $BANKDATA | jq -r .currency`:`echo $BANKDATA | jq -r .amount`" -TARGET=`echo $BANKDATA | jq -r .creditorIban` -# 'TARGET' is now the IBAN. -TARGET_PAYTO="payto://iban/SANDBOXX/$TARGET?receiver-name=Forty+Three" +echo -n "Obtaining wire transfer details from bank ($USE_FAKEBANK)..." + +BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=1' -s)" +WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].wtid) +WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].exchange_base_url) +CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].amount) +TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account) if [ "$EXCHANGE_URL" != "$WURL" ] then - exit_fail "Wrong exchange URL in subject '$SUBJECT', expected '$EXCHANGE_URL'" + exit_fail "Wrong exchange URL in '$BANKDATA' response, expected '$EXCHANGE_URL'" fi echo " OK" set +e -export TARGET_PAYTO -export WURL -export WTID -export CREDIT_AMOUNT -export LAST_RESPONSE - echo -n "Notifying merchant of bogus wire transfer ..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'1","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'1","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") -if [ "$STATUS" != "409" ] +if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected to fail since the amount is not valid. got: $STATUS" fi echo "OK" -echo -n "Notifying merchant of bogus wire transfer AGAIN ..." - -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'1","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ - -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) -if [ "$STATUS" != "409" ] -then - jq . < $LAST_RESPONSE - exit_fail "Expected to fail since the amount is not valid. got: $STATUS" -fi - -echo " OK" echo -n "Notifying merchant of correct wire transfer (conflicting with old data)..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "409" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response conflict, after providing conflicting transfer data. got: $STATUS" fi @@ -415,23 +547,23 @@ echo " OK" echo -n "Deleting bogus wire transfer ..." -TID=`curl -s http://localhost:9966/instances/default/private/transfers | jq -r .transfers[0].transfer_serial_id` +TID=$(curl -s http://localhost:9966/private/transfers | jq -r .transfers[0].transfer_serial_id) STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ - "http://localhost:9966/instances/default/private/transfers/$TID" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + "http://localhost:9966/private/transfers/$TID" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 204 No Content, after deleting valid TID. got: $STATUS" fi STATUS=$(curl -H "Content-Type: application/json" -X DELETE \ - "http://localhost:9966/instances/default/private/transfers/$TID" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + "http://localhost:9966/private/transfers/$TID" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "404" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 404 Not found, after deleting TID again. got: $STATUS" fi @@ -439,148 +571,124 @@ echo " OK" echo -n "Notifying merchant of correct wire transfer (now working)..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") -if [ "$STATUS" != "200" ] +if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok, after providing transfer data. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 204 No content, after providing transfer data. got: $STATUS" fi echo " OK" + echo -n "Testing idempotence ..." set -e + # Test idempotence: do it again! -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") -if [ "$STATUS" != "200" ] +if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok, after providing transfer data. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected response No Content, after providing transfer data. got: $STATUS" fi echo " OK" -echo -n "Sending bogus WTID ..." -# -# CHECK TRANSFER API -# - -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +echo -n "Testing taler-merchant-exchange ..." +set -e +taler-merchant-exchange -L INFO -c "$CONF" -t &> taler-merchant-exchange.log +echo " OK" -if [ "$STATUS" != "502" ] -then - jq . < $LAST_RESPONSE - exit_fail "Expected response invalid since the WTID is fake. got: $STATUS" -fi -echo "OK" echo -n "Fetching wire transfers ..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 200 Ok. got: $STATUS" fi -TRANSFERS_LIST_SIZE=`jq -r '.transfers | length' < $LAST_RESPONSE` +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") -if [ "$TRANSFERS_LIST_SIZE" != "2" ] +if [ "$TRANSFERS_LIST_SIZE" != "1" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected 1 entry in transfer list. Got: $TRANSFERS_LIST_SIZE" fi echo "OK" -echo -n "Fetching wire transfer details of bogus WTID ..." - -# Test for #6854: use a bogus WTID, causing the exchange to fail to -# find the WTID. -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "502" ] -then - jq . < $LAST_RESPONSE - exit_fail "Expected response invalid since the WTID is fake. got: $STATUS" -fi - -echo " OK" echo -n "Checking order status ..." - -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}?transfer=YES" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - - - +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?transfer=YES" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE - exit_fail 'should response ok, after order inquiry. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200, after order inquiry. got: $STATUS" fi - -DEPOSIT_TOTAL=`jq -r .deposit_total < $LAST_RESPONSE` - +DEPOSIT_TOTAL=$(jq -r .deposit_total < "$LAST_RESPONSE") if [ "$DEPOSIT_TOTAL" == "TESTKUDOS:0" ] then - echo 'deposit total is zero, expected greater than zero. got:' $DEPOSIT_TOTAL `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected non-zero deposit total. got: $DEPOSIT_TOTAL" fi - echo " OK" -ACCOUNT_PASSWORD="fortythree:x" -BANK_HOST="localhost:18082" - -# Can be replaced by the libeufin-cli way. -STATUS=$(curl "http://$ACCOUNT_PASSWORD@$BANK_HOST/demobanks/default/access-api/accounts/fortythree" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "200" ] -then - jq . < $LAST_RESPONSE - echo "Expected response 200 Ok, getting account status. Got: $STATUS" - exit 1 +echo -n "Checking bank account status ..." +if [ 1 = "$USE_FAKEBANK" ] +then + STATUS=$(curl "http://localhost:8082/accounts/fortythree" \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") + if [ "$STATUS" != "200" ] + then + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 200 Ok, getting account status. Got: $STATUS" + fi + BALANCE=$(jq -r .balance.amount < "$LAST_RESPONSE") + if [ "$BALANCE" == "TESTKUDOS:0" ] + then + jq . < "$LAST_RESPONSE" + exit_fail "Wire transfer did not happen. Got: $BALANCE" + fi +else + ACCOUNT_PASSWORD="fortythree:x" + BANK_HOST="localhost:18082" + STATUS=$(curl "http://$ACCOUNT_PASSWORD@$BANK_HOST/accounts/fortythree" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + if [ "$STATUS" != "200" ] + then + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 200 Ok, getting account status. Got: $STATUS" + fi + BALANCE=$(jq -r .balance.amount < "$LAST_RESPONSE") + if [ "$BALANCE" == "TESTKUDOS:0" ] + then + jq . < "$LAST_RESPONSE" + exit_fail "Wire transfer did not happen. Got: $BALANCE" + fi fi - -BALANCE=`jq -r .balance.amount < $LAST_RESPONSE` - -if [ "$BALANCE" == "TESTKUDOS:0" ] -then - jq . < $LAST_RESPONSE - echo "Wire transfer did not happen. Got: $BALANCE" - exit 1 -fi - echo " OK" - echo -n "Getting information about kyc ..." - STATUS=$(curl -H "Content-Type: application/json" -X GET \ - http://localhost:9966/instances/default/private/kyc \ + http://localhost:9966/private/kyc \ -w "%{http_code}" -s -o /dev/null) - if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204. Got: $STATUS" fi - echo " OK" exit 0 diff --git a/src/testing/test_merchant_product_creation.sh b/src/testing/test_merchant_product_creation.sh index 702b0e53..e745774c 100755 --- a/src/testing/test_merchant_product_creation.sh +++ b/src/testing/test_merchant_product_creation.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2023 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 @@ -17,216 +17,282 @@ # <http://www.gnu.org/licenses/> # -. initialize_taler_system.sh +set -eu + +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:8082/" +else + echo -n "Testing for libeufin-bank" + libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" + echo " FOUND" + + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" +fi + +. setup.sh + + +echo -n "Testing for taler-harness" +taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + + +# Launch system. +setup -c "test_template.conf" \ + -em \ + $BANK_FLAGS +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) +CONF="test_template.conf.edited" +if [ 1 = "$USE_FAKEBANK" ] +then + FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree" +else + FORTYTHREE=$(get_payto_uri fortythree x) +fi +EXCHANGE_URL="http://localhost:8081/" -FORTYTHREE=`get_payto_uri fortythree x` echo -n "Configuring merchant instance ..." STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["'$FORTYTHREE'"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + "http://localhost:9966/management/instances" \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo "Should have responded 204 No content, instance created. Got $STATUS instead" - exit 1 + exit_fail "Expected 204 No content, instance created. Got $STATUS instead" fi -echo OK -RANDOM_IMG='data:image/png;base64,abcdefg' -INFINITE_PRODUCT_TEMPLATE='{"product_id":"2","description":"product with id 2 and price :15","price":"TESTKUDOS:15","total_stock":-1,"unit":"","image":"'$RANDOM_IMG'","taxes":[]}' -MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","description":"product with id 3 and price :10","price":"TESTKUDOS:150","total_stock":2,"unit":"","image":"'$RANDOM_IMG'","taxes":[]}' +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi + +echo "OK" + +RANDOM_IMG='data:image/png;base64,abcdefg' +INFINITE_PRODUCT_TEMPLATE='{"product_id":"2","description":"product with id 2 and price :15","price":"TESTKUDOS:15","total_stock":-1,"unit":"","image":"'"$RANDOM_IMG"'","taxes":[]}' +MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","description":"product with id 3 and price :10","price":"TESTKUDOS:150","total_stock":2,"unit":"","image":"'"$RANDOM_IMG"'","taxes":[]}' echo -n "Creating products..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/products' \ +STATUS=$(curl 'http://localhost:9966/private/products' \ -d "$INFINITE_PRODUCT_TEMPLATE" \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, product created. got:' $STATUS - exit 1 + exit_fail "Expected 204, product created. got: $STATUS" fi -STATUS=$(curl 'http://localhost:9966/instances/default/private/products' \ +STATUS=$(curl 'http://localhost:9966/private/products' \ -d "$MANAGED_PRODUCT_TEMPLATE" \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, product created. got:' $STATUS - exit 1 + exit_fail "Expected 204, product created. got: $STATUS" fi -echo OK +echo "OK" -PRODUCT_DATA=$(echo $INFINITE_PRODUCT_TEMPLATE | jq 'del(.product_id) | . + {description: "other description"}') +PRODUCT_DATA=$(echo "$INFINITE_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {description: "other description"}') echo -n "Updating infinite stock product..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/products/2' -X PATCH \ +STATUS=$(curl 'http://localhost:9966/private/products/2' -X PATCH \ -d "$PRODUCT_DATA" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] then - echo 'should respond ok, updating product. got:' $STATUS - cat $LAST_RESPONSE - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 204, updating product. got: $STATUS" fi -STATUS=$(curl 'http://localhost:9966/instances/default/private/products/2' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/products/2' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") -DESCRIPTION=`jq -r .description < $LAST_RESPONSE` +DESCRIPTION=$(jq -r .description < "$LAST_RESPONSE") if [ "$DESCRIPTION" != "other description" ] then - echo 'should change description. got:' $DESCRIPTION - cat $LAST_RESPONSE - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'other description'. Got: $DESCRIPTION" fi -echo OK +echo "OK" -MANAGED_PRODUCT_ID=$(echo $MANAGED_PRODUCT_TEMPLATE | jq -r '.product_id') +MANAGED_PRODUCT_ID=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq -r '.product_id') echo -n "Locking inventory ..." -STATUS=$(curl "http://localhost:9966/instances/default/private/products/${MANAGED_PRODUCT_ID}/lock" \ +STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \ -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"quantity":10}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "410" ] then - echo 'should respond gone, lock failed. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 410, lock failed. got: $STATUS" fi echo -n "." -STATUS=$(curl "http://localhost:9966/instances/default/private/products/${MANAGED_PRODUCT_ID}/lock" \ +STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \ -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"quantity":1}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] then - echo 'should respond ok, lock created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 204, lock created. got: $STATUS" fi - echo " OK" - echo -n "Creating order to be paid..." - - -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'${MANAGED_PRODUCT_ID}'","quantity":1}]}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","quantity":1}]}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +#TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") echo -n "." -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'${MANAGED_PRODUCT_ID}'","quantity":1}]}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","quantity":1}]}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "410" ] then - echo 'should respond out of stock (what remains is locked). got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 410 out of stock (what remains is locked). got: $STATUS" fi echo -n "." # Using the 'luck' inventory lock, order creation should work. -STATUS=$(curl 'http://localhost:9966/instances/default/private/orders' \ - -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"lock_uuids":["luck"],"inventory_products":[{"product_id":"'$MANAGED_PRODUCT_ID'","quantity":1}]}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"lock_uuids":["luck"],"inventory_products":[{"product_id":"'"$MANAGED_PRODUCT_ID"'","quantity":1}]}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'Should respond 200 OK, lock should apply. Got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 OK, lock should apply. Got: $STATUS" fi - - echo " OK" echo -n "First withdraw wallet ..." -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ +rm -f "$WALLET_DB" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:5", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL/access-api/" \ + --arg BANK_URL "$BANK_URL" \ --arg EXCHANGE_URL "$EXCHANGE_URL" )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out echo -n "." -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out +if [ 1 = "$USE_FAKEBANK" ] +then + # Fakebank is instant... + sleep 0 +else + sleep 10 + # NOTE: once libeufin can do long-polling, we should + # be able to reduce the delay here and run wirewatch + # always in the background via setup +fi +echo -n "." +taler-exchange-wirewatch -L "INFO" -c "$CONF" -t &> taler-exchange-wirewatch.out +echo -n "." + +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out echo " OK" echo -n "Pay first order ..." -NOW=`date +%s` -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log -NOW2=`date +%s` -echo " OK (took $( echo -n $(($NOW2 - $NOW)) ) secs )" +NOW=$(date +%s) +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}" \ + -y \ + 2> wallet-pay1.err > wallet-pay1.log +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW)) secs )" -STATUS=$(curl "http://localhost:9966/instances/default/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "paid" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" fi echo -n "Updating product..." -PRODUCT_DATA=$(echo $MANAGED_PRODUCT_TEMPLATE | jq 'del(.product_id) | . + {"total_stock": (.total_stock + 2) }') +PRODUCT_DATA=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {"total_stock": (.total_stock + 2) }') -STATUS=$(curl 'http://localhost:9966/instances/default/private/products/3' -X PATCH \ +STATUS=$(curl 'http://localhost:9966/private/products/3' -X PATCH \ -d "$PRODUCT_DATA" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "204" ] then - echo 'should respond ok, updating product. got:' $STATUS - cat $LAST_RESPONSE - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 204, updating product. got: $STATUS" fi - echo " OK" exit 0 diff --git a/src/testing/test_merchant_reserve_creation.sh b/src/testing/test_merchant_reserve_creation.sh deleted file mode 100755 index f97986b3..00000000 --- a/src/testing/test_merchant_reserve_creation.sh +++ /dev/null @@ -1,179 +0,0 @@ -#!/bin/bash -# This file is part of TALER -# Copyright (C) 2014-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/> -# - -set -eu - -. initialize_taler_system.sh - -echo -n "Configuring merchant instance ..." - -# create instance -FORTYTHREE=`get_payto_uri fortythree x` -STATUS=$(curl -H "Content-Type: application/json" -X POST \ - -H 'Authorization: Bearer secret-token:super_secret' \ - http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["payto://x-taler-bank/localhost:1'$NEXUS_PORT'/43"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ - -w "%{http_code}" -s -o /dev/null) - -if [ "$STATUS" != "204" ] -then - echo 'Expected 204, instance created. Got instead: ' $STATUS - exit 1 -fi -echo "OK" - -echo -n "Creating reserve ..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves' \ - -d '{"initial_balance":"TESTKUDOS:2","exchange_url":"'$EXCHANGE_URL'","wire_method":"iban"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "200" ] -then - echo 'Expected 200, reserve created. Got instead: ' $STATUS - exit 1 -fi - -echo "OK" - -RESERVE_PUB=`jq -r .reserve_pub < $LAST_RESPONSE` - -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves/'$RESERVE_PUB \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -FUNDED=`jq -r '.merchant_initial_amount == .exchange_initial_amount' < $LAST_RESPONSE` - -if [ "$FUNDED" != "false" ] -then - echo 'Should not yet be funded if we just created. Got:' $STATUS 'is founded: ' $FUNDED - cat $LAST_RESPONSE - exit 1 -fi - - -echo -n "Wire transferring... " -# Exchange wants TESTKUDOS:2 from account 43, under RESERVE_PUB. - -EXCHANGE_PAYTO=`get_payto_uri exchange x` -export LIBEUFIN_SANDBOX_USERNAME=fortythree -export LIBEUFIN_SANDBOX_PASSWORD=x -export LIBEUFIN_SANDBOX_URL="http://localhost:18082/" -libeufin-cli sandbox demobank new-transaction \ - --bank-account fortythree \ - --payto-with-subject "$EXCHANGE_PAYTO&message=$RESERVE_PUB" \ - --amount TESTKUDOS:2 -unset LIBEUFIN_SANDBOX_USERNAME -unset LIBEUFIN_SANDBOX_PASSWORD -unset LIBEUFIN_SANDBOX_URL -echo "OK" -echo -n "Give Nexus time to detect the payment... " -sleep 10 # FIXME-MS: replace with call to Nexus to right now poll the sandbox ... -echo "OK" - -# Stop existing background service, we need to run it here, now, and only once -kill -TERM $WIREWATCH_PID -wait $WIREWATCH_PID - -taler-exchange-wirewatch -c $CONF -t -L INFO &> taler-exchange-wirewatch.log - -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves/'$RESERVE_PUB \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -FUNDED=`jq -r '.merchant_initial_amount == .exchange_initial_amount' < $LAST_RESPONSE` - -if [ "$FUNDED" != "true" ] -then - echo 'should be funded. got:' $STATUS 'is founded: ' $FUNDED - cat $LAST_RESPONSE - exit 1 -fi - - -echo -n "authorizing tip ..." - -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves/'$RESERVE_PUB'/authorize-tip' \ - -d '{"amount":"TESTKUDOS:1","justification":"off course","next_url":"https://taler.net/"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "200" ] -then - echo 'should respond failed, we did not fund yet. got:' $STATUS - exit 1 -fi - -echo OK - -echo -n Checking tip .... -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves/'$RESERVE_PUB'?tips=yes' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -TIPS_SIZE=`jq -r ".tips | length" < $LAST_RESPONSE` - -if [ "$TIPS_SIZE" != "1" ] -then - echo 'should respond 1, just 1 tip. got:' $TIPS_SIZE - cat $LAST_RESPONSE - exit 1 -fi - -TIP_ID=`jq -r .tips[0].tip_id < $LAST_RESPONSE` - -echo found - -echo -n Checking tip status .... - -STATUS=$(curl 'http://localhost:9966/instances/default/private/tips/'$TIP_ID \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "200" ] -then - echo 'should respond ok, tip found. got:' $STATUS - cat $LAST_RESPONSE - exit 1 -fi - -echo -n " ... " - -STATUS=$(curl 'http://localhost:9966/instances/default/private/tips/'$TIP_ID'?pickups=yes' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "200" ] -then - echo 'should respond ok, tip found. got:' $STATUS - cat $LAST_RESPONSE - exit 1 -fi - -echo OK - -echo -n "trying to create invalid reserve ..." - -STATUS=$(curl 'http://localhost:9966/instances/default/private/reserves' \ - -d '{"initial_balance":"INVALID:2","exchange_url":"'$EXCHANGE_URL'","wire_method":"iban"}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) - -if [ "$STATUS" != "400" ] -then - echo 'should respond invalid, bad currency. got:' $STATUS - exit 1 -fi - -echo "FAILED (which is ok)" - - -exit 0 diff --git a/src/testing/test_merchant_transfer_tracking.sh b/src/testing/test_merchant_transfer_tracking.sh index 8fb7be64..41a20c11 100755 --- a/src/testing/test_merchant_transfer_tracking.sh +++ b/src/testing/test_merchant_transfer_tracking.sh @@ -1,6 +1,6 @@ #!/bin/bash # This file is part of TALER -# Copyright (C) 2014-2021 Taler Systems SA +# Copyright (C) 2014-2024 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,23 +16,82 @@ # License along with TALER; see the file COPYING. If not, see # <http://www.gnu.org/licenses/> # -# Testcase for #6912 (failed to reproduce so far) +# Testcase for #6912 and #8061 -. initialize_taler_system.sh +set -eu + +. setup.sh + +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:8082/" +else + echo -n "Testing for libeufin-bank" + libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" + echo " FOUND" + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" +fi + + +echo -n "Testing for taler-harness" +taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + +# Launch system. +setup -c "test_template.conf" \ + -em \ + $BANK_FLAGS +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) +CONF="test_template.conf.edited" +EXCHANGE_URL="http://localhost:8081/" echo -n "First prepare wallet with coins..." -rm $WALLET_DB -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \ +rm -f "$WALLET_DB" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ "$(jq -n ' { amount: "TESTKUDOS:99", - bankBaseUrl: $BANK_URL, + corebankApiBaseUrl: $BANK_URL, exchangeBaseUrl: $EXCHANGE_URL }' \ - --arg BANK_URL "$BANK_URL/access-api/" \ + --arg BANK_URL "${BANK_URL}" \ --arg EXCHANGE_URL "$EXCHANGE_URL" )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out -taler-wallet-cli --wallet-db=$WALLET_DB run-until-done 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out +echo -n "." +if [ 1 = "$USE_FAKEBANK" ] +then + # Fakebank is instant... + sleep 0 +else + sleep 10 + # NOTE: once libeufin can do long-polling, we should + # be able to reduce the delay here and run wirewatch + # always in the background via setup +fi +echo -n "." +# NOTE: once libeufin can do long-polling, we should +# be able to reduce the delay here and run wirewatch +# always in the background via setup +taler-exchange-wirewatch -L "INFO" -c "$CONF" -t &> taler-exchange-wirewatch.out +echo -n "." + +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish-1.err >wallet-withdraw-finish-1.out echo " OK" # @@ -40,104 +99,143 @@ echo " OK" # echo -n "Configuring merchant default instance ..." -TOR_PAYTO=`get_payto_uri tor x` -GNUNET_PAYTO=`get_payto_uri gnunet x` +if [ 1 = "$USE_FAKEBANK" ] +then + TOR_PAYTO="payto://x-taler-bank/localhost/tor?receiver-name=tor" + GNUNET_PAYTO="payto://x-taler-bank/localhost/gnunet?receiver-name=gnunet" + SURVEY_PAYTO="payto://x-taler-bank/localhost/survey?receiver-name=survey" + TUTORIAL_PAYTO="payto://x-taler-bank/localhost/tutorial?receiver-name=tutorial" +else + TOR_PAYTO=$(get_payto_uri tor x) + GNUNET_PAYTO=$(get_payto_uri gnunet x) + SURVEY_PAYTO=$(get_payto_uri survey x) + TUTORIAL_PAYTO=$(get_payto_uri tutorial x) +fi # create with 2 address STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["'$TOR_PAYTO'","'$GNUNET_PAYTO'"],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" fi -echo OK +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$TOR_PAYTO"'"}' \ + -w "%{http_code}" -s -o /dev/null) +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$GNUNET_PAYTO"'"}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi + +echo "OK" echo -n "Configuring merchant test instance ..." -SURVEY_PAYTO=`get_payto_uri survey x` -TUTORIAL_PAYTO=`get_payto_uri tutorial x` # create with 2 address STATUS=$(curl -H "Content-Type: application/json" -X POST \ -H 'Authorization: Bearer secret-token:super_secret' \ http://localhost:9966/management/instances \ - -d '{"auth":{"method":"external"},"payto_uris":["'$SURVEY_PAYTO'","'$TUTORIAL_PAYTO'"],"id":"test","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -d '{"auth":{"method":"external"},"id":"test","name":"test","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ -w "%{http_code}" -s -o /dev/null) if [ "$STATUS" != "204" ] then - echo 'should respond ok, instance created. got:' $STATUS - exit 1 + exit_fail "Expected 204, instance created. got: $STATUS" +fi +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/instances/test/private/accounts \ + -d '{"payto_uri":"'"$SURVEY_PAYTO"'","credit_facade_url":"http://localhost:8082/accounts/survey/taler-revenue/","credit_facade_credentials":{"type":"basic","username":"survey","password":"x"}}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" fi -echo OK -RANDOM_IMG='data:image/png;base64,abcdefg' # CREATE ORDER AND SELL IT echo -n "Creating order to be paid..." STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, order created. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" fi -ORDER_ID=`jq -e -r .order_id < $LAST_RESPONSE` -TOKEN=`jq -e -r .token < $LAST_RESPONSE` +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +#TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, getting order info before claming it. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS" fi -PAY_URL=`jq -e -r .taler_pay_uri < $LAST_RESPONSE` -echo OK +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") +echo "OK" -NOW=`date +%s` +NOW=$(date +%s) echo -n "Pay first order ..." -taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log -NOW2=`date +%s` -echo " OK (took $( echo -n $(($NOW2 - $NOW))) secs)" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}" \ + -y \ + 2> wallet-pay1.err > wallet-pay1.log +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW )) secs)" STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - echo 'should respond ok, after pay. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" fi -ORDER_STATUS=`jq -r .order_status < $LAST_RESPONSE` +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") if [ "$ORDER_STATUS" != "paid" ] then - echo 'order should be paid. got:' $ORDER_STATUS `cat $LAST_RESPONSE` - exit 1 + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" fi # # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND # -PAY_DEADLINE=`jq -r .contract_terms.pay_deadline.t_s < $LAST_RESPONSE` -WIRE_DEADLINE=`jq -r .contract_terms.wire_transfer_deadline.t_s < $LAST_RESPONSE` +#PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE") +WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE") -NOW=`date +%s` +NOW=$(date +%s) -TO_SLEEP=`echo $(( $WIRE_DEADLINE - $NOW ))` +TO_SLEEP=$(( WIRE_DEADLINE - NOW )) echo "waiting $TO_SLEEP secs for wire transfer" echo -n "Perform wire transfers ..." @@ -145,124 +243,111 @@ taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggrega taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log echo " DONE" -echo -n "waiting for Nexus and Sandbox to settle the payment .." -sleep 3 -echo " DONE" - echo -n "Obtaining wire transfer details from bank..." -# Emulating the previous pybank-based logic of getting -# the wire transfer information _via the exchange_ bank -# account. NOTE: grabbing tx == 0, since the latest -# transaction appear first in the bank's history. -export BANKDATA=`get_bankaccount_transactions exchange x | jq '.transactions[0]'` -export SUBJECT=`echo $BANKDATA | jq -r .subject` -export WTID=`echo $SUBJECT | awk '{print $1}'` -export WURL=`echo $SUBJECT | awk '{print $2}'` -export CREDIT_AMOUNT="`echo $BANKDATA | jq -r .currency`:`echo $BANKDATA | jq -r .amount`" -export TARGET=`echo $BANKDATA | jq -r .creditorIban` + +BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=1' -s)" +WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].wtid) +WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].exchange_base_url) +CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].amount) +TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account) +TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}') + # Figure out which account got paid, in order to # resort the right (and complete: including the receiver-name) # TARGET_PAYTO -if `echo $SURVEY_PAYTO | grep -q $TARGET`; then - export TARGET_PAYTO=$SURVEY_PAYTO; +if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then + TARGET_PAYTO="$SURVEY_PAYTO"; fi -if `echo $TUTORIAL_PAYTO | grep -q $TARGET`; then - export TARGET_PAYTO=$TUTORIAL_PAYTO; +if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then + TARGET_PAYTO="$SURVEY_PAYTO"; fi -echo " DONE" if [ "$EXCHANGE_URL" != "$WURL" ] then exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL" fi - echo " OK" set +e -export TARGET_PAYTO -export WURL -export WTID -export CREDIT_AMOUNT -export LAST_RESPONSE - echo -n "Notifying merchant of correct wire transfer, but on wrong instance..." #issue 6912 #here we are notifying the transfer into a wrong instance (default) and the payto_uri of the default instance -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ +STATUS=$(curl 'http://localhost:9966/private/transfers' \ -d "{\"credit_amount\":\"$CREDIT_AMOUNT\",\"wtid\":\"$WTID\",\"payto_uri\":\"$TOR_PAYTO\",\"exchange_url\":\"$WURL\"}" \ -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") -if [ "$STATUS" != "200" ] +if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok, after providing transfer data. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 204 no content, after providing transfer data. Got: $STATUS" fi echo " OK" echo -n "Fetching wire transfers of DEFAULT instance ..." -STATUS=$(curl 'http://localhost:9966/instances/default/private/transfers' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 200 Ok. got: $STATUS" fi -TRANSFERS_LIST_SIZE=`jq -r '.transfers | length' < $LAST_RESPONSE` +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") if [ "$TRANSFERS_LIST_SIZE" != "1" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE" fi echo "OK" +echo -n "Fetching running taler-merchant-exchange on bogus transfer ..." +taler-merchant-exchange -c "$CONF" -L INFO -t &> taler-merchant-exchange-bad.log +echo "OK" + echo -n "Fetching wire transfers of 'test' instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 200 Ok. got: $STATUS" fi -TRANSFERS_LIST_SIZE=`jq -r '.transfers | length' < $LAST_RESPONSE` +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") if [ "$TRANSFERS_LIST_SIZE" != "0" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected non-empty transfer list size. got: $TRANSFERS_LIST_SIZE" fi echo "OK" - echo -n "Checking order status ..." STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}?transfer=YES" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE - exit_fail 'should response ok, after order inquiry. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after order inquiry. got: $STATUS" fi -WAS_WIRED=`jq -r .wired < $LAST_RESPONSE` +WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE") if [ "$WAS_WIRED" == "true" ] then - jq . < $LAST_RESPONSE - echo '.wired true, expected false' - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail ".wired is true, expected false" fi echo " OK" @@ -271,58 +356,357 @@ echo -n "Notifying merchant of correct wire transfer in the correct instance..." #this time in the correct instance so the order will be marked as wired... STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ - -d '{"credit_amount":"'$CREDIT_AMOUNT'","wtid":"'$WTID'","payto_uri":"'$TARGET_PAYTO'","exchange_url":"'$WURL'"}' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ -m 3 \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") -if [ "$STATUS" != "200" ] +if [ "$STATUS" != "204" ] then - jq . < $LAST_RESPONSE - exit_fail "Expected response ok, after providing transfer data. got: $STATUS" + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 204 no content, after providing transfer data. got: $STATUS" fi echo " OK" +echo -n "Fetching running taler-merchant-exchange on good transfer ..." +taler-merchant-exchange -c $CONF -L INFO -t &> taler-merchant-exchange-bad.log +echo "OK" + echo -n "Fetching wire transfers of TEST instance ..." STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ - -w "%{http_code}" -s -o $LAST_RESPONSE) + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected response 200 Ok. got: $STATUS" fi -TRANSFERS_LIST_SIZE=`jq -r '.transfers | length' < $LAST_RESPONSE` +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") if [ "$TRANSFERS_LIST_SIZE" != "1" ] then - jq . < $LAST_RESPONSE + jq . < "$LAST_RESPONSE" exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE" fi echo "OK" echo -n "Checking order status ..." -STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}?transfer=YES" \ - -w "%{http_code}" -s -o $LAST_RESPONSE) +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") if [ "$STATUS" != "200" ] then - jq . < $LAST_RESPONSE - exit_fail 'should response ok, after order inquiry. got:' $STATUS `cat $LAST_RESPONSE` - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after order inquiry. got: $STATUS" fi -WAS_WIRED=`jq -r .wired < $LAST_RESPONSE` +WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE") if [ "$WAS_WIRED" != "true" ] then - jq . < $LAST_RESPONSE - echo '.wired false, expected true' - exit 1 + jq . < "$LAST_RESPONSE" + exit_fail ".wired false, expected true" +fi + +echo " OK" + + +echo "================== 2nd order ====================== " + + + +# CREATE ORDER AND SELL IT +echo -n "Creating 2nd order to be paid..." +STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:2","summary":"payme"}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" fi +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +#TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") + +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS" +fi +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") +echo "OK" + +NOW=$(date +%s) +echo -n "Pay second order ..." +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}" \ + -y \ + 2> wallet-pay2.err > wallet-pay2.log +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW )) secs)" + +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" +fi + +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") + +if [ "$ORDER_STATUS" != "paid" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" +fi + +# +# WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND +# + +#PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE") +WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE") + +NOW=$(date +%s) + +TO_SLEEP=$(( WIRE_DEADLINE - NOW )) +echo "waiting $TO_SLEEP secs for wire transfer" + +echo -n "Pre-check for exchange deposit ..." +taler-merchant-depositcheck -c $CONF -t -L INFO &> depositcheck2a.log +echo " DONE" + +echo -n "Perform wire transfers ..." +taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggregator2.log +taler-exchange-transfer -c $CONF -t -L INFO &> transfer2.log +echo " DONE" + +echo -n "Post-check for exchange deposit ..." +taler-merchant-depositcheck -c $CONF -t -T ${TO_SLEEP}000000 -L INFO &> depositcheck2b.log +echo " DONE" + + +echo -n "Obtaining wire transfer details from bank..." + +BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=2' -s)" + +WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].wtid) +WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].exchange_base_url) +CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].amount) +TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].credit_account) +TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}') + +# Figure out which account got paid, in order to +# resort the right (and complete: including the receiver-name) +# TARGET_PAYTO +if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then + TARGET_PAYTO="$SURVEY_PAYTO"; +fi +if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then + TARGET_PAYTO="$SURVEY_PAYTO"; +fi +if [ "$EXCHANGE_URL" != "$WURL" ] +then + exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL" +fi echo " OK" +echo -n "Notifying merchant of correct wire transfer in the correct instance..." +#this time in the correct instance so the order will be marked as wired... + +STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \ + -m 3 \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "204" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 204 no content, after providing transfer data. got: $STATUS" +fi +echo " OK" + +echo -n "Fetching running taler-merchant-exchange on good transfer ..." +taler-merchant-exchange -c $CONF -L INFO -t &> taler-merchant-exchange2.log +echo "OK" + +echo -n "Fetching wire transfers of TEST instance ..." + +STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 200 Ok. got: $STATUS" +fi + +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") + +if [ "$TRANSFERS_LIST_SIZE" != "2" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected two transfers. got: $TRANSFERS_LIST_SIZE" +fi + +echo "OK" + +echo -n "Checking order status ..." +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after order inquiry. got: $STATUS" +fi + +WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE") + +if [ "$WAS_WIRED" != "true" ] +then + jq . < "$LAST_RESPONSE" + exit_fail ".wired false, expected true" +fi + +echo " OK" + +echo "================== 3rd order ====================== " + +# CREATE ORDER AND SELL IT +echo -n "Creating 3rd order to be paid..." +STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:3","summary":"payme"}}' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, order created. got: $STATUS" +fi + +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +#TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") + +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS" +fi +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") +echo "OK" + +NOW=$(date +%s) +echo -n "Pay third order ..." +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}" \ + -y \ + 2> wallet-pay2.err > wallet-pay2.log +NOW2=$(date +%s) +echo " OK (took $(( NOW2 - NOW )) secs)" + +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after pay. got: $STATUS" +fi + +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") + +if [ "$ORDER_STATUS" != "paid" ] +then + cat "$LAST_RESPONSE" + exit_fail "Expected 'paid'. got: $ORDER_STATUS" +fi + +# +# WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND +# + +#PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE") +WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE") + +NOW=$(date +%s) + +TO_SLEEP=$(( WIRE_DEADLINE - NOW )) +echo "waiting $TO_SLEEP secs for wire transfer" + +echo -n "Perform wire transfers ..." +taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggregator3.log +taler-exchange-transfer -c $CONF -t -L INFO &> transfer3.log +echo " DONE" + +echo -n "Running taler-merchant-wirewatch to check transfer ..." +taler-merchant-wirewatch -c $CONF -t -L INFO &> taler-merchant-wirewatch.log +echo " DONE" + +echo -n "Post-wirewatch check for exchange deposit ..." +taler-merchant-depositcheck -c $CONF -t -T ${TO_SLEEP}000000 -L INFO &> depositcheck2b.log +echo " DONE" + +echo -n "Fetching wire transfers of TEST instance ..." + +STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected response 200 Ok. got: $STATUS" +fi + +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") + +if [ "$TRANSFERS_LIST_SIZE" != "3" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected three transfers. got: $TRANSFERS_LIST_SIZE" +fi + +echo "OK" + +echo -n "Fetching running taler-merchant-exchange on good transfer ..." +taler-merchant-exchange -c $CONF -L INFO -t &> taler-merchant-exchange2.log +echo "OK" + +echo -n "Checking order status ..." +STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \ + -w "%{http_code}" -s -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 ok, after order inquiry. got: $STATUS" +fi + +WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE") + +if [ "$WAS_WIRED" != "true" ] +then + jq . < "$LAST_RESPONSE" + exit_fail ".wired false, expected true" +fi + +echo " OK" + + exit 0 diff --git a/src/testing/test_merchant_wirewatch.sh b/src/testing/test_merchant_wirewatch.sh new file mode 100755 index 00000000..61bd2049 --- /dev/null +++ b/src/testing/test_merchant_wirewatch.sh @@ -0,0 +1,376 @@ +#!/bin/bash +# This file is part of TALER +# Copyright (C) 2014-2023 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/> +# +# Testcase for #6363 (WiP) +set -eu + +# Exit, with status code "skip" (no 'real' failure) +function exit_skip() { + echo $1 + exit 77 +} + +echo -n "Testing for taler-harness" +taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" +echo " FOUND" + + +# Replace with 0 for nexus... +USE_FAKEBANK=1 +if [ 1 = "$USE_FAKEBANK" ] +then + ACCOUNT="exchange-account-2" + WIRE_METHOD="x-taler-bank" + BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:8082/" +else + echo -n "Testing for libeufin-bank" + libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" + echo " FOUND" + + ACCOUNT="exchange-account-1" + WIRE_METHOD="iban" + BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT" + BANK_URL="http://localhost:18082/" +fi + +. setup.sh +# Launch exchange, merchant and bank. +setup -c "test_template.conf" \ + -em \ + $BANK_FLAGS +LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) +CONF="test_template.conf.edited" +WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) +EXCHANGE_URL="http://localhost:8081/" + + +if [ 1 = "$USE_FAKEBANK" ] +then + FACADE_URL="http://localhost:8082/accounts/gnunet/taler-revenue/" + FACADE_USERNAME="gnunet" + FACADE_PASSWORD="x" +else + echo "not implemented for current libeufin-bank" + exit 1 + export LIBEUFIN_SANDBOX_DB_CONNECTION='postgresql:///talercheck' + export LIBEUFIN_SANDBOX_ADMIN_PASSWORD="secret" + export LIBEUFIN_SANDBOX_URL="http://localhost:18082/" + + export EBICS_HOST="talerebics" + export LIBEUFIN_SANDBOX_USERNAME="admin" + export LIBEUFIN_SANDBOX_PASSWORD="secret" + export EBICS_USER_ID="gnunet_ebics" + export EBICS_PARTNER="GnunetPartner" + export BANK_CONNECTION_NAME="gnunet-connection" + export NEXUS_ACCOUNT_NAME="GnunetCredit" + # The 'gnunet' account is created by + # taler-bank-manage-testing and used for + # the 'default' instance, so this must be used here. + export SANDBOX_ACCOUNT_NAME="gnunet" + + export LIBEUFIN_NEXUS_URL="http://localhost:8082" + # These two are from taler-bank-manage-testing... + + # Define credentials for wirewatch user, will be Merchant client. + CREDIT_USERNAME="merchant-wirewatch" + CREDIT_PASSWORD="merchant-wirewatch-password" + + echo -n "Create credit user (for gnunet-merchant) at Nexus ..." + + export LIBEUFIN_NEXUS_DB_CONNECTION='postgresql:///talercheck' + libeufin-nexus \ + superuser "$CREDIT_USERNAME" \ + --password="$CREDIT_PASSWORD" \ + &> nexus-credit-create.log + echo " OK" + export LIBEUFIN_NEXUS_USERNAME="$CREDIT_USERNAME" + export LIBEUFIN_NEXUS_PASSWORD="$CREDIT_PASSWORD" + export GNUNET_CREDIT_FACADE=facade-gnunet-credit + + libeufin-cli sandbox \ + demobank \ + new-ebicssubscriber \ + --host-id ${EBICS_HOST} \ + --user-id ${NEXUS_ACCOUNT_NAME} \ + --partner-id ${EBICS_PARTNER} \ + --bank-account ${SANDBOX_ACCOUNT_NAME} \ + &> sandbox-subscriber-create.log + + libeufin-cli \ + connections \ + new-ebics-connection \ + --ebics-url="${LIBEUFIN_SANDBOX_URL}ebicsweb" \ + --host-id=${EBICS_HOST} \ + --partner-id=${EBICS_PARTNER} \ + --ebics-user-id=${NEXUS_ACCOUNT_NAME} \ + ${BANK_CONNECTION_NAME} \ + &> nexus-connection-create.log + + libeufin-cli \ + connections \ + connect \ + ${BANK_CONNECTION_NAME} \ + &> nexus-connection-connect.log + + libeufin-cli \ + connections \ + download-bank-accounts \ + ${BANK_CONNECTION_NAME} \ + &> nexus-account-download.log + + libeufin-cli \ + connections \ + import-bank-account \ + --offered-account-id=${SANDBOX_ACCOUNT_NAME} \ + --nexus-bank-account-id=${NEXUS_ACCOUNT_NAME} \ + ${BANK_CONNECTION_NAME} \ + &> nexus-account-import.log + + libeufin-cli \ + facades \ + new-anastasis-facade \ + --currency=TESTKUDOS \ + --facade-name=${GNUNET_CREDIT_FACADE} \ + ${BANK_CONNECTION_NAME} \ + ${NEXUS_ACCOUNT_NAME} \ + &> nexus-new-facade.log + + FACADE_URL="http://localhost:18082/accounts/admin/taler-revenue/" + # WAS: $(libeufin-cli facades list | jq .facades[0].baseUrl | tr -d \") + + # FIXME: is this correct? Strange to use the super-user + # credentials here! + FACADE_USERNAME="${CREDIT_USERNAME}" + FACADE_PASSWORD="${CREDIT_PASSWORD}" +fi + +echo -n "First prepare wallet with coins..." +rm -f "${WALLET_DB}" +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + api \ + --expect-success 'withdrawTestBalance' \ + "$(jq -n ' + { + amount: "TESTKUDOS:99", + corebankApiBaseUrl: $BANK_URL, + exchangeBaseUrl: $EXCHANGE_URL + }' \ + --arg BANK_URL "$BANK_URL" \ + --arg EXCHANGE_URL "$EXCHANGE_URL" + )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out +echo -n "." +if [ 1 = "$USE_FAKEBANK" ] +then + # Fakebank is instant... + sleep 0 +else + sleep 10 + # NOTE: once libeufin can do long-polling, we should + # be able to reduce the delay here and run wirewatch + # always in the background via setup +fi +echo -n "." +taler-exchange-wirewatch \ + -L "INFO" \ + -c "$CONF" \ + -t \ + &> taler-exchange-wirewatch.out +echo -n "." +taler-wallet-cli \ + --wallet-db="$WALLET_DB" \ + run-until-done \ + 2>wallet-withdraw-finish-1.err \ + >wallet-withdraw-finish-1.out +echo " OK" + +# +# CREATE INSTANCE FOR TESTING +# + +echo -n "Configuring merchant default instance ..." +if [ 1 = "$USE_FAKEBANK" ] +then + GNUNET_PAYTO="payto://x-taler-bank/localhost/gnunet?receiver-name=gnunet" +else + GNUNET_PAYTO=$(get_payto_uri gnunet x) +fi +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/management/instances \ + -d '{"auth":{"method":"external"},"id":"default","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "204" ] +then + exit_fail "Expected 204 no content. Got: $STATUS" +fi +echo "OK" + +echo -n "Configuring bank account..." +STATUS=$(curl -H "Content-Type: application/json" -X POST \ + -H 'Authorization: Bearer secret-token:super_secret' \ + http://localhost:9966/private/accounts \ + -d '{"payto_uri":"'"$GNUNET_PAYTO"'","credit_facade_url":"'"${FACADE_URL}"'","credit_facade_credentials":{"type":"basic","username":"'"$FACADE_USERNAME"'","password":"'"$FACADE_PASSWORD"'"}}' \ + -w "%{http_code}" -s -o /dev/null) + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS" +fi + +echo "OK" + +# CREATE ORDER AND SELL IT +echo -n "Creating order to be paid..." +STATUS=$(curl 'http://localhost:9966/private/orders' \ + -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 OK. Got: $STATUS " "$(cat "$LAST_RESPONSE")" +fi + +ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 ok. Got: $STATUS" "$(cat "$LAST_RESPONSE")" +fi +PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") +echo OK + +NOW=$(date +%s) +echo -n "Pay first order ..." +taler-wallet-cli \ + --no-throttle \ + --wallet-db="$WALLET_DB" \ + handle-uri "${PAY_URL}" \ + -y 2> wallet-pay1.err > wallet-pay1.log +NOW2=$(date +%s) +echo "OK. Took $(( NOW2 - NOW))s." + +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + exit_fail "Expected 200 Ok. Got: $STATUS" "$(cat "$LAST_RESPONSE")" +fi + +ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") +if [ "$ORDER_STATUS" != "paid" ] +then + exit_fail "Expected order status 'paid'. Got: $ORDER_STATUS" "$(cat "$LAST_RESPONSE")" +fi + +# +# WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND +# + +WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE") +NOW=$(date +%s) + +TO_SLEEP="$(( 1 + WIRE_DEADLINE - NOW ))" +echo -n "Perform wire transfers (with ${TO_SLEEP}s timeshift) ..." +taler-exchange-aggregator \ + -y \ + -c "$CONF" \ + -T "${TO_SLEEP}000000" \ + -t \ + -L INFO &> aggregator.log +taler-exchange-transfer\ + -c "$CONF" \ + -t \ + -L INFO &> transfer.log +echo " DONE" + +if [ 1 != "$USE_FAKEBANK" ] +then + echo -n "Waiting for Nexus and Sandbox to settle the payment ..." + sleep 3 # FIXME-MS: replace with call to Nexus to right now poll the sandbox ... + libeufin-cli \ + accounts \ + fetch-transactions \ + ${NEXUS_ACCOUNT_NAME} \ + &> libeufin-transfer-fetch.out + echo " DONE" +fi + +echo -n "Obtaining wire transfer details from bank..." +taler-merchant-wirewatch \ + -c "$CONF" \ + -t \ + -L INFO &> merchant-wirewatch.log +echo " OK" + +echo -n "Fetching wire transfers of DEFAULT instance ..." +STATUS=$(curl 'http://localhost:9966/private/transfers' \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") +if [ "$STATUS" != "200" ] +then + exit_fail "Expected response 200 Ok. Got: $STATUS" "$(jq . < "$LAST_RESPONSE")" +fi +TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE") +if [ "$TRANSFERS_LIST_SIZE" != "1" ] +then + exit_fail "Expected one transfer. Got: $TRANSFERS_LIST_SIZE" "$(jq . < "$LAST_RESPONSE")" +fi +echo " OK" + +echo -n "Integrating wire transfer data with exchange..." +taler-merchant-exchange \ + -c "$CONF" \ + -t \ + -L INFO &> merchant-exchange.log +echo " OK" + +echo -n "Checking order status ..." +STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?transfer=YES" \ + -w "%{http_code}" \ + -s \ + -o "$LAST_RESPONSE") + +if [ "$STATUS" != "200" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Expected 200 ok. got: $STATUS" "$(cat "$LAST_RESPONSE")" +fi + +WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE") +if [ "$WAS_WIRED" != "true" ] +then + jq . < "$LAST_RESPONSE" + exit_fail "Got .wired 'false', expected 'true'" +fi +echo " OK" + +exit 0 diff --git a/src/testing/test_template.conf b/src/testing/test_template.conf index 21bb6186..8f3dc4da 100644 --- a/src/testing/test_template.conf +++ b/src/testing/test_template.conf @@ -1,18 +1,18 @@ [PATHS] -TALER_HOME = ${PWD}/test_reducer_home/ -TALER_DATA_HOME = $TALER_HOME/.local/share/taler/ -TALER_CONFIG_HOME = $TALER_HOME/.config/taler/ -TALER_CACHE_HOME = $TALER_HOME/.cache/taler/ -TALER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/taler-system-runtime/ +TALER_TEST_HOME = test_merchant_api_home/ [taler] CURRENCY = TESTKUDOS CURRENCY_ROUND_UNIT = TESTKUDOS:0.01 +[merchant-exchange-kudos] +DISABLED = YES + [exchange] +AML_THRESHOLD = TESTKUDOS:1000000 MAX_KEYS_CACHING = forever DB = postgres -MASTER_PRIV_FILE = ${TALER_DATA_HOME}/exchange/offline-keys/master.priv +MASTER_PUBLIC_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 SERVE = tcp UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http UNIXPATH_MODE = 660 @@ -26,6 +26,9 @@ REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/ TERMS_ETAG = 0 PRIVACY_ETAG = 0 +[exchangedb-postgres] +CONFIG = postgres:///talercheck + [merchant] SERVE = tcp PORT = 9966 @@ -34,17 +37,27 @@ UNIXPATH_MODE = 660 DEFAULT_WIRE_FEE_AMORTIZATION = 1 DB = postgres WIREFORMAT = default -# Set very low, so we can be sure that the database generated -# will contain wire transfers "ready" for the aggregator. WIRE_TRANSFER_DELAY = 1 minute DEFAULT_PAY_DEADLINE = 1 day DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1 KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10 - -# Ensure that merchant reports EVERY deposit confirmation to auditor FORCE_AUDIT = YES +[merchantdb-postgres] +CONFIG = postgres:///talercheck +SQL_DIR = $DATADIR/sql/merchant/ + +[bank] +HTTP_PORT = 8082 + +[libeufin-nexus] +DB_CONNECTION="postgresql:///talercheck" + +[libeufin-sandbox] +DB_CONNECTION="postgresql:///talercheck" + + [auditor] DB = postgres AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv @@ -54,7 +67,6 @@ UNIXPATH_MODE = 660 PORT = 8083 AUDITOR_URL = http://localhost:8083/ TINY_AMOUNT = TESTKUDOS:0.01 -AUDITOR_PRIV_FILE = ${TALER_DATA_HOME}/auditor/offline-keys/auditor.priv BASE_URL = "http://localhost:8083/" [exchangedb] @@ -63,18 +75,38 @@ LEGAL_RESERVE_EXPIRATION_TIME = 7 years [exchange-account-1] # PAYTO_URI comes by patching. -enable_debit = yes -enable_credit = yes +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES [exchange-accountcredentials-1] -WIRE_GATEWAY_URL = "http://localhost:8082/facades/test-facade/taler-wire-gateway/" +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" +WIRE_GATEWAY_AUTH_METHOD = basic +USERNAME = exchange +PASSWORD = x + +[admin-accountcredentials-1] +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" WIRE_GATEWAY_AUTH_METHOD = basic USERNAME = exchange PASSWORD = x +[exchange-account-2] +PAYTO_URI = "payto://x-taler-bank/localhost/exchange?receiver-name=exchange" +ENABLE_DEBIT = YES +ENABLE_CREDIT = YES + +[exchange-accountcredentials-2] +WIRE_GATEWAY_AUTH_METHOD = none +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" + +[admin-accountcredentials-2] +WIRE_GATEWAY_AUTH_METHOD = none +WIRE_GATEWAY_URL = "http://localhost:8082/accounts/exchange/taler-wire-gateway/" + [merchant-exchange-default] EXCHANGE_BASE_URL = http://localhost:8081/ CURRENCY = TESTKUDOS +MASTER_KEY = NKX42KSCQHDQK7CF1PC6X9DMQPXW6KHXKGD3DPQJMP32FKXSWYK0 [payments-generator] currency = TESTKUDOS diff --git a/src/testing/testing_api_cmd_abort_order.c b/src/testing/testing_api_cmd_abort_order.c index b9f7682b..1e6da35c 100644 --- a/src/testing/testing_api_cmd_abort_order.c +++ b/src/testing/testing_api_cmd_abort_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -116,7 +116,6 @@ build_coins (struct TALER_MERCHANT_AbortCoin **ac, } { const struct TALER_TESTING_Command *coin_cmd; - const char **exchange_url; coin_cmd = TALER_TESTING_interpreter_lookup_command (is, token); @@ -142,8 +141,7 @@ build_coins (struct TALER_MERCHANT_AbortCoin **ac, } GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_exchange_url (coin_cmd, - &exchange_url)); - icoin->exchange_url = *exchange_url; + &icoin->exchange_url)); { const struct TALER_Amount *denom_value; @@ -165,48 +163,42 @@ build_coins (struct TALER_MERCHANT_AbortCoin **ac, * in the state. * * @param cls closure. - * @param hr HTTP response - * @param merchant_pub public key of the merchant refunding the - * contract. - * @param num_aborts length of the @a res array - * @param res array containing the abort confirmations + * @param ar response */ static void abort_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_MerchantPublicKeyP *merchant_pub, - unsigned int num_aborts, - const struct TALER_MERCHANT_AbortedCoin res[]) + const struct TALER_MERCHANT_AbortResponse *ar) { struct AbortState *as = cls; as->oah = NULL; - if (as->http_status != hr->http_status) + if (as->http_status != ar->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command `%s' (expected %u)\n", - hr->http_status, - (int) hr->ec, + ar->hr.http_status, + (int) ar->hr.ec, TALER_TESTING_interpreter_get_current_label (as->is), as->http_status); TALER_TESTING_FAIL (as->is); } - if ( (MHD_HTTP_OK == hr->http_status) && - (TALER_EC_NONE == hr->ec) ) + if ( (MHD_HTTP_OK == ar->hr.http_status) && + (TALER_EC_NONE == ar->hr.ec) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received %u refunds\n", - num_aborts); - as->acs_length = num_aborts; - as->acs = GNUNET_new_array (num_aborts, + ar->details.ok.num_aborts); + as->acs_length = ar->details.ok.num_aborts; + as->acs = GNUNET_new_array (as->acs_length, struct TALER_MERCHANT_AbortedCoin); - memcpy (as->acs, - res, - num_aborts * sizeof (struct TALER_MERCHANT_AbortedCoin)); + GNUNET_memcpy (as->acs, + ar->details.ok.aborts, + as->acs_length + * sizeof (struct TALER_MERCHANT_AbortedCoin)); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successful pay-abort (HTTP status: %u)\n", - hr->http_status); + ar->hr.http_status); TALER_TESTING_interpreter_next (as->is); } @@ -225,8 +217,8 @@ abort_run (void *cls, { struct AbortState *as = cls; const struct TALER_TESTING_Command *pay_cmd; - const char **proposal_reference; - const char **coin_reference; + const char *proposal_reference; + const char *coin_reference; const struct TALER_TESTING_Command *proposal_cmd; const char *order_id; const struct TALER_PrivateContractHashP *h_proposal; @@ -253,7 +245,7 @@ abort_run (void *cls, &coin_reference)) TALER_TESTING_FAIL (is); proposal_cmd = TALER_TESTING_interpreter_lookup_command (is, - *proposal_reference); + proposal_reference); if (NULL == proposal_cmd) TALER_TESTING_FAIL (is); @@ -299,7 +291,7 @@ abort_run (void *cls, } } - cr = GNUNET_strdup (*coin_reference); + cr = GNUNET_strdup (coin_reference); abort_coins = NULL; nabort_coins = 0; if (GNUNET_OK != @@ -320,7 +312,8 @@ abort_run (void *cls, TALER_TESTING_get_trait_h_contract_terms (proposal_cmd, &h_proposal)) TALER_TESTING_FAIL (is); - as->oah = TALER_MERCHANT_order_abort (is->ctx, + as->oah = TALER_MERCHANT_order_abort (TALER_TESTING_interpreter_get_context ( + is), as->merchant_url, order_id, &merchant_pub, diff --git a/src/testing/testing_api_cmd_checkserver.c b/src/testing/testing_api_cmd_checkserver.c new file mode 100644 index 00000000..5b10b1fc --- /dev/null +++ b/src/testing/testing_api_cmd_checkserver.c @@ -0,0 +1,270 @@ +/* + This file is part of TALER + Copyright (C) 2023 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_checkserver.c + * @brief Implement a CMD to run an Checkserver 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 a "checkserver" CMD. + */ +struct CheckState +{ + /** + * Handle to the "testserver" service. + */ + struct MHD_Daemon *mhd; + + /** + * Our interpreter. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Index to know which web server we check. + */ + unsigned int index; + + /** + * Reference to command to the previous set server status operation. + */ + const char *ref_operation; + + /** + * Expected method of the pending webhook. + */ + const char *expected_method; + + /** + * Expected url of the pending webhook. + */ + const char *expected_url; + + /** + * Expected header of the pending webhook. + */ + const char *expected_header; + + /** + * Expected body of the pending webhook. + */ + const char *expected_body; + +}; + + +/** + * Run the command. + * + * @param cls closure. + * @param cmd the command to execute. + * @param is the interpreter state. + */ +static void +checkserver_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct CheckState *cs = cls; + const struct TALER_TESTING_Command *ref; + const char *url; + const char *http_method; + const char *header; + const void *body; + const size_t *body_size; + + (void) cmd; + cs->is = is; + ref = TALER_TESTING_interpreter_lookup_command (is, + cs->ref_operation); + if (NULL == ref) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "ref NULL\n"); + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_urls (ref, + cs->index, + &url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Trait url does not work\n"); + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (NULL == url) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Trait for url is NULL!?\n"); + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + if (0 != strcmp (cs->expected_url, + url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "URL does not match: `%s' != `%s'\n", + cs->expected_url, + url); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_http_methods (ref, + cs->index, + &http_method)) + TALER_TESTING_interpreter_fail (is); + if (0 != strcmp (cs->expected_method, + http_method)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "http_method does not match\n"); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_http_header (ref, + cs->index, + &header)) + TALER_TESTING_interpreter_fail (is); + if ( ( (NULL == cs->expected_header) && (NULL != header)) || + ( (NULL != cs->expected_header) && (NULL == header)) || + ( (NULL != cs->expected_header) && + (0 != strcmp (cs->expected_header, + header)) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "header does not match: `%s' != `%s'\n", + cs->expected_header, + header); + TALER_TESTING_interpreter_fail (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_http_body (ref, + cs->index, + &body)) + TALER_TESTING_interpreter_fail (is); + if (GNUNET_OK != + TALER_TESTING_get_trait_http_body_size (ref, + cs->index, + &body_size)) + TALER_TESTING_interpreter_fail (is); + if ( ( (NULL == cs->expected_body) && + (NULL != body) ) || + ( (NULL != cs->expected_body) && + (NULL == body) ) || + ( (NULL != cs->expected_body) && + ( (*body_size != strlen (cs->expected_body)) || + (0 != memcmp (cs->expected_body, + body, + *body_size) ) ) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "body does not match : `%s' and `%.*s'\n", + cs->expected_body, + (int) *body_size, + (const char *) body); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_interpreter_next (is); +} + + +/** + * Free the state of a "checkserver" CMD. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +checkserver_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct CheckState *cs = cls; + + GNUNET_free (cs); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_checkserver2 (const char *label, + const char *ref_operation, + unsigned int index, + const char *expected_url, + const char *expected_method, + const char *expected_header, + const char *expected_body) +{ + struct CheckState *cs; + + cs = GNUNET_new (struct CheckState); + cs->ref_operation = ref_operation; + cs->index = index; + cs->expected_url = expected_url; + cs->expected_method = expected_method; + cs->expected_header = expected_header; + cs->expected_body = expected_body; + + { + struct TALER_TESTING_Command cmd = { + .cls = cs, + .label = label, + .run = &checkserver_run, + .cleanup = &checkserver_cleanup + }; + + return cmd; + } +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_checkserver (const char *label, + const char *ref_operation, + unsigned int index) +{ + return TALER_TESTING_cmd_checkserver2 (label, + ref_operation, + index, + "/", + "POST", + "EFEHYJS-Bakery", + "5.0 EUR"); +} + + +/* end of testing_api_cmd_checkserver.c */ diff --git a/src/testing/testing_api_cmd_claim_order.c b/src/testing/testing_api_cmd_claim_order.c index d7a3ec41..aec03876 100644 --- a/src/testing/testing_api_cmd_claim_order.c +++ b/src/testing/testing_api_cmd_claim_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -123,34 +123,23 @@ order_claim_cleanup (void *cls, * response code is as expected. * * @param cls closure - * @param hr HTTP response we got - * @param contract_terms the contract terms; they are the - * backend-filled up order minus cryptographic - * information. - * @param sig merchant signature over the contract terms. - * @param hash hash code of the contract terms. + * @param ocr response we got */ static void order_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) + const struct TALER_MERCHANT_OrderClaimResponse *ocr) { struct OrderClaimState *pls = cls; pls->och = NULL; - if (pls->http_status != hr->http_status) + if (pls->http_status != ocr->hr.http_status) TALER_TESTING_FAIL (pls->is); - if (MHD_HTTP_OK == hr->http_status) + if (MHD_HTTP_OK == ocr->hr.http_status) { - pls->contract_terms = json_object_get (hr->reply, - "contract_terms"); - if (NULL == pls->contract_terms) - TALER_TESTING_FAIL (pls->is); - json_incref (pls->contract_terms); - pls->contract_terms_hash = *hash; - pls->merchant_sig = *sig; + pls->contract_terms + = json_incref ((json_t *) ocr->details.ok.contract_terms); + pls->contract_terms_hash = ocr->details.ok.h_contract_terms; + pls->merchant_sig = ocr->details.ok.sig; { const char *error_name; unsigned int error_line; @@ -161,7 +150,7 @@ order_claim_cb (void *cls, }; if (GNUNET_OK != - GNUNET_JSON_parse (contract_terms, + GNUNET_JSON_parse (pls->contract_terms, spec, &error_name, &error_line)) @@ -185,7 +174,7 @@ order_claim_run (void *cls, struct TALER_TESTING_Interpreter *is) { struct OrderClaimState *pls = cls; - const char **order_id; + const char *order_id; const struct GNUNET_CRYPTO_EddsaPublicKey *nonce; /* Only used if we do NOT use the nonce/token from traits. */ struct GNUNET_CRYPTO_EddsaPublicKey dummy_nonce; @@ -194,7 +183,7 @@ order_claim_run (void *cls, pls->is = is; if (NULL != pls->order_id) { - order_id = &pls->order_id; + order_id = pls->order_id; GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &dummy_nonce, sizeof (dummy_nonce)); @@ -228,9 +217,10 @@ order_claim_run (void *cls, &order_id)) TALER_TESTING_FAIL (is); } - pls->och = TALER_MERCHANT_order_claim (is->ctx, + pls->och = TALER_MERCHANT_order_claim (TALER_TESTING_interpreter_get_context ( + is), pls->merchant_url, - *order_id, + order_id, nonce, claim_token, &order_claim_cb, diff --git a/src/testing/testing_api_cmd_config.c b/src/testing/testing_api_cmd_config.c index 6487be4e..adde106a 100644 --- a/src/testing/testing_api_cmd_config.c +++ b/src/testing/testing_api_cmd_config.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -84,24 +84,22 @@ config_cleanup (void *cls, * Process "GET /public/config" (lookup) response. * * @param cls closure - * @param hr HTTP response we got - * @param ci basic information about the merchant - * @param compat protocol compatibility information + * @param cr response we got */ static void config_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_MERCHANT_ConfigInformation *ci, - enum TALER_MERCHANT_VersionCompatibility compat) + const struct TALER_MERCHANT_ConfigResponse *cr) { struct ConfigState *cs = cls; - (void) ci; cs->vgh = NULL; - if (cs->http_code != hr->http_status) - TALER_TESTING_FAIL (cs->is); - if (TALER_MERCHANT_VC_MATCH != compat) + if (cs->http_code != cr->hr.http_status) TALER_TESTING_FAIL (cs->is); + if (MHD_HTTP_OK == cr->hr.http_status) + { + if (TALER_MERCHANT_VC_MATCH != cr->details.ok.compat) + TALER_TESTING_FAIL (cs->is); + } TALER_TESTING_interpreter_next (cs->is); } @@ -121,7 +119,8 @@ config_run (void *cls, struct ConfigState *cs = cls; cs->is = is; - cs->vgh = TALER_MERCHANT_config_get (is->ctx, + cs->vgh = TALER_MERCHANT_config_get (TALER_TESTING_interpreter_get_context ( + is), cs->merchant_url, &config_cb, cs); diff --git a/src/testing/testing_api_cmd_delete_account.c b/src/testing/testing_api_cmd_delete_account.c new file mode 100644 index 00000000..681faa3c --- /dev/null +++ b/src/testing/testing_api_cmd_delete_account.c @@ -0,0 +1,213 @@ +/* + This file is part of TALER + Copyright (C) 2023 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_delete_account.c + * @brief command to test DELETE /account/$H_WIRE + * @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 "DELETE /accounts/$H_WIRE" CMD. + */ +struct DeleteAccountState +{ + + /** + * Handle for a "DELETE account" request. + */ + struct TALER_MERCHANT_AccountDeleteHandle *adh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the command to get account details from. + */ + const char *create_account_ref; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a DELETE /account/$H_WIRE operation. + * + * @param cls closure for this function + * @param adr response being processed + */ +static void +delete_account_cb (void *cls, + const struct TALER_MERCHANT_AccountDeleteResponse *adr) +{ + struct DeleteAccountState *das = cls; + + das->adh = NULL; + if (das->http_status != adr->hr.http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + adr->hr.http_status, + (int) adr->hr.ec, + TALER_TESTING_interpreter_get_current_label (das->is)); + TALER_TESTING_interpreter_fail (das->is); + return; + } + switch (adr->hr.http_status) + { + case MHD_HTTP_NO_CONTENT: + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + break; + case MHD_HTTP_CONFLICT: + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u for DELETE account.\n", + adr->hr.http_status); + } + TALER_TESTING_interpreter_next (das->is); +} + + +/** + * Run the "DELETE account" CMD. + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +delete_account_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct DeleteAccountState *das = cls; + const struct TALER_TESTING_Command *ref; + const struct TALER_MerchantWireHashP *h_wire; + const char *merchant_url; + + das->is = is; + ref = TALER_TESTING_interpreter_lookup_command (is, + das->create_account_ref); + if (NULL == ref) + { + GNUNET_break (0); + TALER_TESTING_FAIL (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_merchant_base_url (ref, + &merchant_url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Command %s lacked merchant base URL\n", + das->create_account_ref); + GNUNET_break (0); + TALER_TESTING_FAIL (is); + return; + } + if (GNUNET_OK != + TALER_TESTING_get_trait_h_wires (ref, + 0, + &h_wire)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Command %s did not return H_WIRE\n", + das->create_account_ref); + GNUNET_break (0); + TALER_TESTING_FAIL (is); + return; + } + GNUNET_assert (NULL != h_wire); + das->adh = TALER_MERCHANT_account_delete ( + TALER_TESTING_interpreter_get_context (is), + merchant_url, + h_wire, + &delete_account_cb, + das); + GNUNET_assert (NULL != das->adh); +} + + +/** + * Free the state of a "DELETE account" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +delete_account_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct DeleteAccountState *das = cls; + + if (NULL != das->adh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "DELETE /accounts/$ID operation did not complete\n"); + TALER_MERCHANT_account_delete_cancel (das->adh); + } + GNUNET_free (das); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_delete_account (const char *label, + const char *create_account_ref, + unsigned int http_status) +{ + struct DeleteAccountState *das; + + das = GNUNET_new (struct DeleteAccountState); + das->create_account_ref = create_account_ref; + das->http_status = http_status; + { + struct TALER_TESTING_Command cmd = { + .cls = das, + .label = label, + .run = &delete_account_run, + .cleanup = &delete_account_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_delete_account.c */ diff --git a/src/testing/testing_api_cmd_delete_instance.c b/src/testing/testing_api_cmd_delete_instance.c index 9d3bd7d5..36cc2964 100644 --- a/src/testing/testing_api_cmd_delete_instance.c +++ b/src/testing/testing_api_cmd_delete_instance.c @@ -123,17 +123,19 @@ delete_instance_run (void *cls, dis->is = is; if (dis->purge) - dis->igh = TALER_MERCHANT_instance_purge (is->ctx, - dis->merchant_url, - dis->instance_id, - &delete_instance_cb, - dis); + dis->igh = TALER_MERCHANT_instance_purge ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->instance_id, + &delete_instance_cb, + dis); else - dis->igh = TALER_MERCHANT_instance_delete (is->ctx, - dis->merchant_url, - dis->instance_id, - &delete_instance_cb, - dis); + dis->igh = TALER_MERCHANT_instance_delete ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->instance_id, + &delete_instance_cb, + dis); GNUNET_assert (NULL != dis->igh); } diff --git a/src/testing/testing_api_cmd_delete_order.c b/src/testing/testing_api_cmd_delete_order.c index 7c1ddfff..163538ca 100644 --- a/src/testing/testing_api_cmd_delete_order.c +++ b/src/testing/testing_api_cmd_delete_order.c @@ -121,12 +121,13 @@ delete_order_run (void *cls, struct DeleteOrderState *dos = cls; dos->is = is; - dos->odh = TALER_MERCHANT_order_delete (is->ctx, - dos->merchant_url, - dos->order_id, - false, /* FIXME: support testing force... */ - &delete_order_cb, - dos); + dos->odh = TALER_MERCHANT_order_delete ( + TALER_TESTING_interpreter_get_context (is), + dos->merchant_url, + dos->order_id, + false, /* FIXME: support testing force... */ + &delete_order_cb, + dos); GNUNET_assert (NULL != dos->odh); } diff --git a/src/testing/testing_api_cmd_delete_otp_device.c b/src/testing/testing_api_cmd_delete_otp_device.c new file mode 100644 index 00000000..3d15c645 --- /dev/null +++ b/src/testing/testing_api_cmd_delete_otp_device.c @@ -0,0 +1,181 @@ +/* + This file is part of TALER + Copyright (C) 2022 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_delete_otp_device.c + * @brief command to test DELETE /otp-devices/$ID + * @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 "DELETE /otp-devices/$ID" CMD. + */ +struct DeleteOtpDeviceState +{ + + /** + * Handle for a "DELETE otp_device" request. + */ + struct TALER_MERCHANT_OtpDeviceDeleteHandle *tdh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the otp_device to run DELETE for. + */ + const char *otp_device_id; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a /delete/otp-devices/$ID operation. + * + * @param cls closure for this function + * @param hr response being processed + */ +static void +delete_otp_device_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct DeleteOtpDeviceState *dis = cls; + + dis->tdh = NULL; + if (dis->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 (dis->is)); + TALER_TESTING_interpreter_fail (dis->is); + return; + } + switch (hr->http_status) + { + case MHD_HTTP_NO_CONTENT: + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + break; + case MHD_HTTP_CONFLICT: + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u for DELETE otp_device.\n", + hr->http_status); + } + TALER_TESTING_interpreter_next (dis->is); +} + + +/** + * Run the "DELETE otp_device" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +delete_otp_device_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct DeleteOtpDeviceState *dis = cls; + + dis->is = is; + dis->tdh = TALER_MERCHANT_otp_device_delete ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->otp_device_id, + &delete_otp_device_cb, + dis); + GNUNET_assert (NULL != dis->tdh); +} + + +/** + * Free the state of a "DELETE otp_device" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +delete_otp_device_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct DeleteOtpDeviceState *dis = cls; + + if (NULL != dis->tdh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "DELETE /otp-devices/$ID operation did not complete\n"); + TALER_MERCHANT_otp_device_delete_cancel (dis->tdh); + } + GNUNET_free (dis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_delete_otp_device (const char *label, + const char *merchant_url, + const char *otp_device_id, + unsigned int http_status) +{ + struct DeleteOtpDeviceState *dis; + + dis = GNUNET_new (struct DeleteOtpDeviceState); + dis->merchant_url = merchant_url; + dis->otp_device_id = otp_device_id; + dis->http_status = http_status; + { + struct TALER_TESTING_Command cmd = { + .cls = dis, + .label = label, + .run = &delete_otp_device_run, + .cleanup = &delete_otp_device_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_delete_otp_device.c */ diff --git a/src/testing/testing_api_cmd_delete_product.c b/src/testing/testing_api_cmd_delete_product.c index 6fed8d46..77de9261 100644 --- a/src/testing/testing_api_cmd_delete_product.c +++ b/src/testing/testing_api_cmd_delete_product.c @@ -120,11 +120,12 @@ delete_product_run (void *cls, struct DeleteProductState *dis = cls; dis->is = is; - dis->pdh = TALER_MERCHANT_product_delete (is->ctx, - dis->merchant_url, - dis->product_id, - &delete_product_cb, - dis); + dis->pdh = TALER_MERCHANT_product_delete ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->product_id, + &delete_product_cb, + dis); GNUNET_assert (NULL != dis->pdh); } diff --git a/src/testing/testing_api_cmd_delete_reserve.c b/src/testing/testing_api_cmd_delete_reserve.c deleted file mode 100644 index 65d27fa6..00000000 --- a/src/testing/testing_api_cmd_delete_reserve.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - 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_delete_reserve.c - * @brief command to test DELETE /reserves/$RESERVE_PUB - * @author Jonathan Buchanan - */ -#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 "DELETE /reserves/$RESERVE_PUB" CMD. - */ -struct DeleteReserveState -{ - - /** - * Handle for a "DELETE reserve" request. - */ - struct TALER_MERCHANT_ReserveDeleteHandle *rdh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Reference to a command that provides a reserve. - */ - const char *reserve_reference; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Use purge, not delete. - */ - bool purge; - -}; - - -/** - * Callback for a DELETE /reserves/$RESERVE_PUB operation. - * - * @param cls closure for this function - * @param hr response being processed - */ -static void -delete_reserve_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) -{ - struct DeleteReserveState *drs = cls; - - drs->rdh = NULL; - if (drs->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 (drs->is)); - TALER_TESTING_interpreter_fail (drs->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_NO_CONTENT: - break; - case MHD_HTTP_NOT_FOUND: - break; - case MHD_HTTP_CONFLICT: - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status %u for DELETE reserve.\n", - hr->http_status); - } - TALER_TESTING_interpreter_next (drs->is); -} - - -/** - * Run the "DELETE reserve" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -delete_reserve_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct DeleteReserveState *drs = cls; - const struct TALER_TESTING_Command *reserve_cmd; - const struct TALER_ReservePublicKeyP *reserve_pub; - - reserve_cmd = TALER_TESTING_interpreter_lookup_command ( - is, - drs->reserve_reference); - if (GNUNET_OK != - TALER_TESTING_get_trait_reserve_pub (reserve_cmd, - &reserve_pub)) - TALER_TESTING_FAIL (is); - - drs->is = is; - if (drs->purge) - drs->rdh = TALER_MERCHANT_reserve_purge (is->ctx, - drs->merchant_url, - reserve_pub, - &delete_reserve_cb, - drs); - else - drs->rdh = TALER_MERCHANT_reserve_delete (is->ctx, - drs->merchant_url, - reserve_pub, - &delete_reserve_cb, - drs); - - GNUNET_assert (NULL != drs->rdh); -} - - -/** - * Free the state of a "DELETE reserve" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -delete_reserve_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct DeleteReserveState *drs = cls; - - if (NULL != drs->rdh) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "DELETE /reserves/$RESERVE_PUB operation did not complete\n"); - TALER_MERCHANT_reserve_delete_cancel (drs->rdh); - } - GNUNET_free (drs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_delete_reserve (const char *label, - const char *merchant_url, - const char *reserve_reference, - unsigned int http_status) -{ - struct DeleteReserveState *drs; - - drs = GNUNET_new (struct DeleteReserveState); - drs->merchant_url = merchant_url; - drs->reserve_reference = reserve_reference; - drs->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = drs, - .label = label, - .run = &delete_reserve_run, - .cleanup = &delete_reserve_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_purge_reserve (const char *label, - const char *merchant_url, - const char *reserve_reference, - unsigned int http_status) -{ - struct DeleteReserveState *drs; - - drs = GNUNET_new (struct DeleteReserveState); - drs->merchant_url = merchant_url; - drs->reserve_reference = reserve_reference; - drs->http_status = http_status; - drs->purge = true; - { - struct TALER_TESTING_Command cmd = { - .cls = drs, - .label = label, - .run = &delete_reserve_run, - .cleanup = &delete_reserve_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_delete_reserve.c */ diff --git a/src/testing/testing_api_cmd_delete_template.c b/src/testing/testing_api_cmd_delete_template.c index dd2d38c8..6227c543 100644 --- a/src/testing/testing_api_cmd_delete_template.c +++ b/src/testing/testing_api_cmd_delete_template.c @@ -70,19 +70,17 @@ struct DeleteTemplateState */ static void delete_template_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) + const struct TALER_MERCHANT_HttpResponse *hr) { struct DeleteTemplateState *dis = cls; dis->tdh = NULL; if (dis->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 (dis->is)); - TALER_TESTING_interpreter_fail (dis->is); + TALER_TESTING_unexpected_status_with_body (dis->is, + hr->http_status, + dis->http_status, + hr->reply); return; } switch (hr->http_status) @@ -114,17 +112,18 @@ delete_template_cb (void *cls, */ static void delete_template_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) { struct DeleteTemplateState *dis = cls; dis->is = is; - dis->tdh = TALER_MERCHANT_template_delete (is->ctx, - dis->merchant_url, - dis->template_id, - &delete_template_cb, - dis); + dis->tdh = TALER_MERCHANT_template_delete ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->template_id, + &delete_template_cb, + dis); GNUNET_assert (NULL != dis->tdh); } @@ -138,7 +137,7 @@ delete_template_run (void *cls, */ static void delete_template_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) + const struct TALER_TESTING_Command *cmd) { struct DeleteTemplateState *dis = cls; @@ -154,9 +153,9 @@ delete_template_cleanup (void *cls, struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_delete_template (const char *label, - const char *merchant_url, - const char *template_id, - unsigned int http_status) + const char *merchant_url, + const char *template_id, + unsigned int http_status) { struct DeleteTemplateState *dis; diff --git a/src/testing/testing_api_cmd_delete_transfer.c b/src/testing/testing_api_cmd_delete_transfer.c index 6ccef365..ae872dee 100644 --- a/src/testing/testing_api_cmd_delete_transfer.c +++ b/src/testing/testing_api_cmd_delete_transfer.c @@ -145,11 +145,12 @@ delete_transfer_run (void *cls, TALER_TESTING_interpreter_fail (dts->is); return; } - dts->tdh = TALER_MERCHANT_transfer_delete (is->ctx, - dts->merchant_url, - *tid, - &delete_transfer_cb, - dts); + dts->tdh = TALER_MERCHANT_transfer_delete ( + TALER_TESTING_interpreter_get_context (is), + dts->merchant_url, + *tid, + &delete_transfer_cb, + dts); GNUNET_assert (NULL != dts->tdh); } diff --git a/src/testing/testing_api_cmd_delete_webhook.c b/src/testing/testing_api_cmd_delete_webhook.c index d1060226..12654fe6 100644 --- a/src/testing/testing_api_cmd_delete_webhook.c +++ b/src/testing/testing_api_cmd_delete_webhook.c @@ -120,11 +120,12 @@ delete_webhook_run (void *cls, struct DeleteWebhookState *dis = cls; dis->is = is; - dis->wdh = TALER_MERCHANT_webhook_delete (is->ctx, - dis->merchant_url, - dis->webhook_id, - &delete_webhook_cb, - dis); + dis->wdh = TALER_MERCHANT_webhook_delete ( + TALER_TESTING_interpreter_get_context (is), + dis->merchant_url, + dis->webhook_id, + &delete_webhook_cb, + dis); GNUNET_assert (NULL != dis->wdh); } diff --git a/src/testing/testing_api_cmd_depositcheck.c b/src/testing/testing_api_cmd_depositcheck.c new file mode 100644 index 00000000..ad033d2e --- /dev/null +++ b/src/testing/testing_api_cmd_depositcheck.c @@ -0,0 +1,162 @@ +/* + This file is part of TALER + Copyright (C) 2024 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_depositcheck.c + * @brief run the taler-merchant-depositcheck command + * @author Priscilla HUANG + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler/taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler/taler_signatures.h" +#include "taler/taler_testing_lib.h" + + +/** + * State for a "depositcheck" CMD. + */ +struct DepositcheckState +{ + + /** + * Process for the depositcheck. + */ + struct GNUNET_OS_Process *depositcheck_proc; + + /** + * Configuration file used by the depositcheck. + */ + const char *config_filename; +}; + + +/** + * Run the command; use the `taler-merchant-depositcheck' program. + * + * @param cls closure. + * @param cmd command currently being executed. + * @param is interpreter state. + */ +static void +depositcheck_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct DepositcheckState *ws = cls; + + (void) cmd; + ws->depositcheck_proc + = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, + NULL, NULL, NULL, + "taler-merchant-depositcheck", + "taler-merchant-depositcheck", + "-c", ws->config_filename, + "-t", /* exit when done */ + "-L", "DEBUG", + NULL); + if (NULL == ws->depositcheck_proc) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state of a "depositcheck" CMD, and possibly + * kills its process if it did not terminate regularly. + * + * @param cls closure. + * @param cmd the command being freed. + */ +static void +depositcheck_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct DepositcheckState *ws = cls; + + (void) cmd; + if (NULL != ws->depositcheck_proc) + { + GNUNET_break (0 == + GNUNET_OS_process_kill (ws->depositcheck_proc, + SIGKILL)); + GNUNET_OS_process_wait (ws->depositcheck_proc); + GNUNET_OS_process_destroy (ws->depositcheck_proc); + ws->depositcheck_proc = NULL; + } + GNUNET_free (ws); +} + + +/** + * Offer "depositcheck" CMD internal data to other commands. + * + * @param cls closure. + * @param[out] ret result. + * @param trait name of the trait. + * @param index index number of the object to offer. + * @return #GNUNET_OK on success. + */ +static enum GNUNET_GenericReturnValue +depositcheck_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct DepositcheckState *ws = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_process (&ws->depositcheck_proc), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_depositcheck (const char *label, + const char *config_filename) +{ + struct DepositcheckState *ws; + + ws = GNUNET_new (struct DepositcheckState); + ws->config_filename = config_filename; + + { + struct TALER_TESTING_Command cmd = { + .cls = ws, + .label = label, + .run = &depositcheck_run, + .cleanup = &depositcheck_cleanup, + .traits = &depositcheck_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_depositcheck.c */ diff --git a/src/testing/testing_api_cmd_forget_order.c b/src/testing/testing_api_cmd_forget_order.c index 5e6225d4..172ac295 100644 --- a/src/testing/testing_api_cmd_forget_order.c +++ b/src/testing/testing_api_cmd_forget_order.c @@ -120,7 +120,13 @@ order_forget_cb (void *cls, ofs->ofh = NULL; if (ofs->http_status != hr->http_status) - TALER_TESTING_FAIL (ofs->is); + { + TALER_TESTING_unexpected_status_with_body (ofs->is, + hr->http_status, + ofs->http_status, + hr->reply); + return; + } TALER_TESTING_interpreter_next (ofs->is); } @@ -138,12 +144,12 @@ order_forget_run (void *cls, struct TALER_TESTING_Interpreter *is) { struct OrderForgetState *ofs = cls; - const char **order_id; + const char *order_id; ofs->is = is; if (NULL != ofs->order_id) { - order_id = &ofs->order_id; + order_id = ofs->order_id; } else { @@ -159,13 +165,14 @@ order_forget_run (void *cls, &order_id)) TALER_TESTING_FAIL (is); } - ofs->ofh = TALER_MERCHANT_order_forget (is->ctx, - ofs->merchant_url, - *order_id, - ofs->paths_length, - ofs->paths, - &order_forget_cb, - ofs); + ofs->ofh = TALER_MERCHANT_order_forget ( + TALER_TESTING_interpreter_get_context (is), + ofs->merchant_url, + order_id, + ofs->paths_length, + ofs->paths, + &order_forget_cb, + ofs); GNUNET_assert (NULL != ofs->ofh); } @@ -191,7 +198,7 @@ order_forget_traits (void *cls, traits[0] = TALER_TESTING_make_trait_paths_length (&ofs->paths_length); for (unsigned int i = 0; i < ofs->paths_length; ++i) traits[i + 1] = TALER_TESTING_make_trait_paths (i, - &ofs->paths[i]); + ofs->paths[i]); traits[ofs->paths_length + 1] = TALER_TESTING_trait_end (); return TALER_TESTING_get_trait (traits, diff --git a/src/testing/testing_api_cmd_get_instance.c b/src/testing/testing_api_cmd_get_instance.c index 95dc7282..c3199a7e 100644 --- a/src/testing/testing_api_cmd_get_instance.c +++ b/src/testing/testing_api_cmd_get_instance.c @@ -60,31 +60,6 @@ struct GetInstanceState const char *instance_reference; /** - * Whether we should check the instance's accounts or not. - */ - bool cmp_accounts; - - /** - * The accounts of the merchant we expect to be active. - */ - const char **active_accounts; - - /** - * The length of @e active_accounts. - */ - unsigned int active_accounts_length; - - /** - * The accounts of the merchant we expect to be inactive. - */ - const char **inactive_accounts; - - /** - * The length of @e inactive_accounts. - */ - unsigned int inactive_accounts_length; - - /** * Expected HTTP response code. */ unsigned int http_status; @@ -96,17 +71,11 @@ struct GetInstanceState * Callback for a /get/instance/$ID operation. * * @param cls closure for this function - * @param hr HTTP response - * @param accounts_length how many bank accounts the instance has - * @param accounts the list of the instance's bank accounts - * @param details all the details related to this particular instance + * @param igr response */ static void get_instance_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int accounts_length, - const struct TALER_MERCHANT_Account accounts[], - const struct TALER_MERCHANT_InstanceDetails *details) + const struct TALER_MERCHANT_InstanceGetResponse *igr) { struct GetInstanceState *gis = cls; const struct TALER_TESTING_Command *instance_cmd; @@ -116,208 +85,116 @@ get_instance_cb (void *cls, gis->instance_reference); gis->igh = NULL; - if (gis->http_status != hr->http_status) + if (gis->http_status != igr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + igr->hr.http_status, + (int) igr->hr.ec, TALER_TESTING_interpreter_get_current_label (gis->is)); TALER_TESTING_interpreter_fail (gis->is); return; } - switch (hr->http_status) + switch (igr->hr.http_status) { case MHD_HTTP_OK: { - const char **name; - - if (GNUNET_OK != - TALER_TESTING_get_trait_instance_name (instance_cmd, - &name)) - TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (details->name, - *name)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance name does not match: Got `%s', wanted `%s'\n", - details->name, - *name); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - { - const json_t *address; - - if (GNUNET_OK != - TALER_TESTING_get_trait_address (instance_cmd, - &address)) - TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (details->address, - address)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance address does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - { - const struct json_t *jurisdiction; - - if (GNUNET_OK != - TALER_TESTING_get_trait_jurisdiction (instance_cmd, - &jurisdiction)) - TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (details->jurisdiction, - jurisdiction)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance jurisdiction does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - { - const struct TALER_Amount *default_max_wire_fee; - - if (GNUNET_OK != - TALER_TESTING_get_trait_max_wire_fee (instance_cmd, - &default_max_wire_fee)) - TALER_TESTING_interpreter_fail (gis->is); - if ((GNUNET_OK != TALER_amount_cmp_currency ( - details->default_max_wire_fee, - default_max_wire_fee)) || - (0 != TALER_amount_cmp (details->default_max_wire_fee, - default_max_wire_fee))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance default max wire fee does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - { - const uint32_t *default_wire_fee_amortization; - - if (GNUNET_OK != - TALER_TESTING_get_trait_wire_fee_amortization (instance_cmd, - & - default_wire_fee_amortization)) - TALER_TESTING_interpreter_fail (gis->is); - if (details->default_wire_fee_amortization != - *default_wire_fee_amortization) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance default wire fee amortization does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - { - const struct TALER_Amount *default_max_deposit_fee; - - if (GNUNET_OK != - TALER_TESTING_get_trait_max_deposit_fee (instance_cmd, - &default_max_deposit_fee)) - TALER_TESTING_interpreter_fail (gis->is); - if ( (GNUNET_OK != - TALER_amount_cmp_currency ( - details->default_max_deposit_fee, - default_max_deposit_fee)) || - (0 != TALER_amount_cmp (details->default_max_deposit_fee, - default_max_deposit_fee)) ) + const struct TALER_MERCHANT_InstanceDetails *details = + &igr->details.ok.details; + { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance default max deposit fee %s does not match\n", - TALER_amount2s (details->default_max_deposit_fee)); - TALER_TESTING_interpreter_fail (gis->is); - return; + const char *name; + + if (GNUNET_OK != + TALER_TESTING_get_trait_instance_name (instance_cmd, + &name)) + TALER_TESTING_interpreter_fail (gis->is); + if (0 != strcmp (details->name, + name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance name does not match: Got `%s', wanted `%s'\n", + details->name, + name); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } - } - { - const struct GNUNET_TIME_Relative *default_wire_transfer_delay; - - if (GNUNET_OK != - TALER_TESTING_get_trait_wire_delay (instance_cmd, - &default_wire_transfer_delay)) - TALER_TESTING_interpreter_fail (gis->is); - if (details->default_wire_transfer_delay.rel_value_us != - default_wire_transfer_delay->rel_value_us) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance default wire transfer delay does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; + const json_t *address; + + if (GNUNET_OK != + TALER_TESTING_get_trait_address (instance_cmd, + &address)) + TALER_TESTING_interpreter_fail (gis->is); + if (1 != json_equal (details->address, + address)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance address does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } - } - { - const struct GNUNET_TIME_Relative *default_pay_delay; - if (GNUNET_OK != - TALER_TESTING_get_trait_pay_delay (instance_cmd, - &default_pay_delay)) - TALER_TESTING_interpreter_fail (gis->is); - if (details->default_pay_delay.rel_value_us != - default_pay_delay->rel_value_us) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance default pay delay does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - } - /* We aren't guaranteed an order for the accounts, so we just have to check - that we can match each account returned with exactly one account - expected. */ - if (gis->cmp_accounts) - { - unsigned int expected_accounts_length = - gis->active_accounts_length + gis->inactive_accounts_length; - unsigned int matches[accounts_length]; + const json_t *jurisdiction; - if (accounts_length != expected_accounts_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Accounts length does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; + if (GNUNET_OK != + TALER_TESTING_get_trait_jurisdiction (instance_cmd, + &jurisdiction)) + TALER_TESTING_interpreter_fail (gis->is); + if (1 != json_equal (details->jurisdiction, + jurisdiction)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance jurisdiction does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } - - memset (matches, - 0, - sizeof (unsigned int) * accounts_length); - - /* Compare the accounts */ - for (unsigned int i = 0; i < accounts_length; ++i) { - for (unsigned int j = 0; j < gis->active_accounts_length; ++j) + const bool *use_stefan; + + if (GNUNET_OK != + TALER_TESTING_get_trait_use_stefan (instance_cmd, + &use_stefan)) + TALER_TESTING_interpreter_fail (gis->is); + if (*use_stefan != details->use_stefan) { - if ((0 == strcasecmp (accounts[i].payto_uri, - gis->active_accounts[j])) && - (true == accounts[i].active)) - { - matches[i] += 1; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance use_stefan value does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; } - for (unsigned int j = 0; j < gis->inactive_accounts_length; ++j) + } + { + const struct GNUNET_TIME_Relative *default_wire_transfer_delay; + + if (GNUNET_OK != + TALER_TESTING_get_trait_wire_delay (instance_cmd, + &default_wire_transfer_delay)) + TALER_TESTING_interpreter_fail (gis->is); + if (details->default_wire_transfer_delay.rel_value_us != + default_wire_transfer_delay->rel_value_us) { - if ((0 == strcasecmp (accounts[i].payto_uri, - gis->inactive_accounts[j])) && - (false == accounts[i].active)) - { - matches[i] += 1; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance default wire transfer delay does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; } } - - // Each account should have exactly one match. - for (unsigned int i = 0; i < accounts_length; ++i) { - if (1 != matches[i]) + const struct GNUNET_TIME_Relative *default_pay_delay; + + if (GNUNET_OK != + TALER_TESTING_get_trait_pay_delay (instance_cmd, + &default_pay_delay)) + TALER_TESTING_interpreter_fail (gis->is); + if (details->default_pay_delay.rel_value_us != + default_pay_delay->rel_value_us) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance account does not match\n"); + "Instance default pay delay does not match\n"); TALER_TESTING_interpreter_fail (gis->is); return; } @@ -331,7 +208,7 @@ get_instance_cb (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u for GET instance ID.\n", - hr->http_status); + igr->hr.http_status); } TALER_TESTING_interpreter_next (gis->is); } @@ -353,11 +230,12 @@ get_instance_run (void *cls, struct GetInstanceState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_instance_get (is->ctx, - gis->merchant_url, - gis->instance_id, - &get_instance_cb, - gis); + gis->igh = TALER_MERCHANT_instance_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + gis->instance_id, + &get_instance_cb, + gis); GNUNET_assert (NULL != gis->igh); } @@ -385,6 +263,35 @@ get_instance_cleanup (void *cls, } +/** + * Offers information from the GET /instance/$ID 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 enum GNUNET_GenericReturnValue +get_instance_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct GetInstanceState *pps = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_merchant_base_url (pps->merchant_url), + TALER_TESTING_trait_end (), + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_get_instance (const char *label, const char *merchant_url, @@ -399,49 +306,13 @@ TALER_TESTING_cmd_merchant_get_instance (const char *label, gis->instance_id = instance_id; gis->http_status = http_status; gis->instance_reference = instance_reference; - gis->cmp_accounts = false; - { - struct TALER_TESTING_Command cmd = { - .cls = gis, - .label = label, - .run = &get_instance_run, - .cleanup = &get_instance_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_instance2 (const char *label, - const char *merchant_url, - const char *instance_id, - unsigned int http_status, - const char *instance_reference, - const char *active_accounts[], - unsigned int active_accounts_length, - const char *inactive_accounts[], - unsigned int inactive_accounts_length) -{ - struct GetInstanceState *gis; - - gis = GNUNET_new (struct GetInstanceState); - gis->merchant_url = merchant_url; - gis->instance_id = instance_id; - gis->http_status = http_status; - gis->instance_reference = instance_reference; - gis->cmp_accounts = true; - gis->active_accounts = active_accounts; - gis->active_accounts_length = active_accounts_length; - gis->inactive_accounts = inactive_accounts; - gis->inactive_accounts_length = inactive_accounts_length; { struct TALER_TESTING_Command cmd = { .cls = gis, .label = label, .run = &get_instance_run, - .cleanup = &get_instance_cleanup + .cleanup = &get_instance_cleanup, + .traits = &get_instance_traits }; return cmd; diff --git a/src/testing/testing_api_cmd_get_instances.c b/src/testing/testing_api_cmd_get_instances.c index 8aee04b1..dbf61fd6 100644 --- a/src/testing/testing_api_cmd_get_instances.c +++ b/src/testing/testing_api_cmd_get_instances.c @@ -71,16 +71,13 @@ struct GetInstancesState * Callback for a GET /instances operation. * * @param cls closure for this function - * @param hr HTTP response - * @param iis_length how many instances are returned - * @param iis all the instances details + * @param igr response */ static void get_instances_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int iis_length, - const struct TALER_MERCHANT_InstanceInformation iis[]) + const struct TALER_MERCHANT_InstancesGetResponse *igr) { + const struct TALER_MERCHANT_HttpResponse *hr = &igr->hr; struct GetInstancesState *gis = cls; gis->igh = NULL; @@ -97,68 +94,75 @@ get_instances_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - if (iis_length != gis->instances_length) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Length of instances found does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - for (unsigned int i = 0; i < iis_length; ++i) - { - const struct TALER_TESTING_Command *instance_cmd; - - instance_cmd = TALER_TESTING_interpreter_lookup_command ( - gis->is, - gis->instances[i]); + unsigned int iis_length + = igr->details.ok.iis_length; + const struct TALER_MERCHANT_InstanceInformation *iis + = igr->details.ok.iis; + if (iis_length != gis->instances_length) { - const char **name; - - if (GNUNET_OK != - TALER_TESTING_get_trait_instance_name (instance_cmd, - &name)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch instance name\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - if (0 != strcmp (iis[i].name, - *name)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance name does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Length of instances found does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; } - + for (unsigned int i = 0; i < iis_length; ++i) { - const char **id; + const struct TALER_TESTING_Command *instance_cmd; + + instance_cmd = TALER_TESTING_interpreter_lookup_command ( + gis->is, + gis->instances[i]); - if (GNUNET_OK != - TALER_TESTING_get_trait_instance_id (instance_cmd, - &id)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch instance id\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; + const char *name; + + if (GNUNET_OK != + TALER_TESTING_get_trait_instance_name (instance_cmd, + &name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not fetch instance name\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + if (0 != strcmp (iis[i].name, + name)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance name does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } - if (0 != strcmp (iis[i].id, - *id)) + { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Instance id does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; + const char *id; + + if (GNUNET_OK != + TALER_TESTING_get_trait_instance_id (instance_cmd, + &id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not fetch instance id\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + if (0 != strcmp (iis[i].id, + id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Instance id does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } } - } - // FIXME: compare payment_targets - break; + // FIXME: compare payment_targets + break; + } default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u for GET /instances.\n", @@ -184,10 +188,11 @@ get_instances_run (void *cls, struct GetInstancesState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_instances_get (is->ctx, - gis->merchant_url, - &get_instances_cb, - gis); + gis->igh = TALER_MERCHANT_instances_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + &get_instances_cb, + gis); GNUNET_assert (NULL != gis->igh); } diff --git a/src/testing/testing_api_cmd_get_orders.c b/src/testing/testing_api_cmd_get_orders.c index 7a271521..0eab0b7f 100644 --- a/src/testing/testing_api_cmd_get_orders.c +++ b/src/testing/testing_api_cmd_get_orders.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -71,41 +71,39 @@ struct GetOrdersState * Callback for a GET /orders operation. * * @param cls closure for this function - * @param hr HTTP response - * @param orders_length how many orders are returned - * @param orders all the orders' details + * @param ogr response */ static void get_orders_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int orders_length, - const struct TALER_MERCHANT_OrderEntry orders[]) + const struct TALER_MERCHANT_OrdersGetResponse *ogr) { struct GetOrdersState *gos = cls; gos->ogh = NULL; - if (gos->http_status != hr->http_status) + if (gos->http_status != ogr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + ogr->hr.http_status, + (int) ogr->hr.ec, TALER_TESTING_interpreter_get_current_label (gos->is)); TALER_TESTING_interpreter_fail (gos->is); return; } - switch (hr->http_status) + switch (ogr->hr.http_status) { case MHD_HTTP_OK: - if (orders_length != gos->orders_length) + if (ogr->details.ok.orders_length != gos->orders_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Number of orders found does not match\n"); TALER_TESTING_interpreter_fail (gos->is); return; } - for (unsigned int i = 0; i < orders_length; ++i) + for (unsigned int i = 0; i < ogr->details.ok.orders_length; ++i) { + const struct TALER_MERCHANT_OrderEntry *order = + &ogr->details.ok.orders[i]; const struct TALER_TESTING_Command *order_cmd; order_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -113,7 +111,7 @@ get_orders_cb (void *cls, gos->orders[i]); { - const char **order_id; + const char *order_id; if (GNUNET_OK != TALER_TESTING_get_trait_order_id (order_cmd, @@ -124,8 +122,8 @@ get_orders_cb (void *cls, TALER_TESTING_interpreter_fail (gos->is); return; } - if (0 != strcmp (orders[i].order_id, - *order_id)) + if (0 != strcmp (order->order_id, + order_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order id does not match\n"); @@ -165,11 +163,11 @@ get_orders_cb (void *cls, return; } if ((0 != strcmp (summary, - orders[i].summary)) || + order->summary)) || (GNUNET_OK != TALER_amount_cmp_currency (&amount, - &orders[i].amount)) || + &order->amount)) || (0 != TALER_amount_cmp (&amount, - &orders[i].amount))) + &order->amount))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order summary and/or amount does not match\n"); @@ -205,7 +203,8 @@ get_orders_run (void *cls, struct GetOrdersState *gos = cls; gos->is = is; - gos->ogh = TALER_MERCHANT_orders_get (is->ctx, + gos->ogh = TALER_MERCHANT_orders_get (TALER_TESTING_interpreter_get_context ( + is), gos->merchant_url, &get_orders_cb, gos); @@ -396,31 +395,27 @@ conclude_task (void *cls) * Callback to process a GET /orders request * * @param cls closure - * @param hr HTTP response details - * @param orders_length how many orders are returned - * @param orders the returned orders + * @param ogr response details */ static void merchant_poll_orders_cb ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int orders_length, - const struct TALER_MERCHANT_OrderEntry orders[]) + const struct TALER_MERCHANT_OrdersGetResponse *ogr) { struct MerchantPollOrdersStartState *pos = cls; pos->ogh = NULL; - if (MHD_HTTP_OK != hr->http_status) + if (MHD_HTTP_OK != ogr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + ogr->hr.http_status, + (int) ogr->hr.ec, TALER_TESTING_interpreter_get_current_label (pos->is)); TALER_TESTING_interpreter_fail (pos->is); return; } - switch (hr->http_status) + switch (ogr->hr.http_status) { case MHD_HTTP_OK: // FIXME: use order references to check if the data returned matches that from the POST / PATCH @@ -429,7 +424,7 @@ merchant_poll_orders_cb ( GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status.\n"); } - pos->http_status = hr->http_status; + pos->http_status = ogr->hr.http_status; if (NULL != pos->cs) { GNUNET_SCHEDULER_cancel (pos->cs->task); @@ -459,7 +454,8 @@ merchant_poll_orders_start_run (void *cls, GNUNET_TIME_relative_add (pos->timeout, GNUNET_TIME_UNIT_SECONDS)); pos->is = is; - pos->ogh = TALER_MERCHANT_orders_get2 (is->ctx, + pos->ogh = TALER_MERCHANT_orders_get2 (TALER_TESTING_interpreter_get_context ( + is), pos->merchant_url, TALER_EXCHANGE_YNA_ALL, TALER_EXCHANGE_YNA_ALL, diff --git a/src/testing/testing_api_cmd_get_otp_device.c b/src/testing/testing_api_cmd_get_otp_device.c new file mode 100644 index 00000000..3f086529 --- /dev/null +++ b/src/testing/testing_api_cmd_get_otp_device.c @@ -0,0 +1,206 @@ +/* + This file is part of TALER + Copyright (C) 2022 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_get_otp_device.c + * @brief command to test GET /otp-devices/$ID + * @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 "GET OTP device" CMD. + */ +struct GetOtpDeviceState +{ + + /** + * Handle for a "GET /otp-device/$ID" request. + */ + struct TALER_MERCHANT_OtpDeviceGetHandle *igh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the otp_device to run GET for. + */ + const char *otp_device_id; + + /** + * Reference for a POST or PATCH /otp-devices CMD (optional). + */ + const char *otp_device_reference; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a GET /otp-devices/$ID operation. + * + * @param cls closure for this function + * @param tgr HTTP response details + */ +static void +get_otp_device_cb (void *cls, + const struct TALER_MERCHANT_OtpDeviceGetResponse *tgr) +{ + struct GetOtpDeviceState *gis = cls; + const struct TALER_TESTING_Command *otp_device_cmd; + + gis->igh = NULL; + if (gis->http_status != tgr->hr.http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + tgr->hr.http_status, + (int) tgr->hr.ec, + TALER_TESTING_interpreter_get_current_label (gis->is)); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + switch (tgr->hr.http_status) + { + case MHD_HTTP_OK: + { + const char *expected_description; + + otp_device_cmd = TALER_TESTING_interpreter_lookup_command ( + gis->is, + gis->otp_device_reference); + if (GNUNET_OK != + TALER_TESTING_get_trait_otp_device_description (otp_device_cmd, + &expected_description)) + TALER_TESTING_interpreter_fail (gis->is); + if (0 != strcmp (tgr->details.ok.otp_device_description, + expected_description)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "OtpDevice description does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + } + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status.\n"); + } + TALER_TESTING_interpreter_next (gis->is); +} + + +/** + * Run the "GET /otp-device/$ID" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +get_otp_device_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct GetOtpDeviceState *gis = cls; + + gis->is = is; + gis->igh = TALER_MERCHANT_otp_device_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + gis->otp_device_id, + &get_otp_device_cb, + gis); + GNUNET_assert (NULL != gis->igh); +} + + +/** + * Free the state of a "GET /otp-device/$ID" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +get_otp_device_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct GetOtpDeviceState *gis = cls; + + if (NULL != gis->igh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "GET /otp-devices/$ID operation did not complete\n"); + TALER_MERCHANT_otp_device_get_cancel (gis->igh); + } + GNUNET_free (gis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_otp_device ( + const char *label, + const char *merchant_url, + const char *otp_device_id, + unsigned int http_status, + const char *otp_device_reference) +{ + struct GetOtpDeviceState *gis; + + gis = GNUNET_new (struct GetOtpDeviceState); + gis->merchant_url = merchant_url; + gis->otp_device_id = otp_device_id; + gis->http_status = http_status; + gis->otp_device_reference = otp_device_reference; + { + struct TALER_TESTING_Command cmd = { + .cls = gis, + .label = label, + .run = &get_otp_device_run, + .cleanup = &get_otp_device_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_get_otp_device.c */ diff --git a/src/testing/testing_api_cmd_get_otp_devices.c b/src/testing/testing_api_cmd_get_otp_devices.c new file mode 100644 index 00000000..b4f370c5 --- /dev/null +++ b/src/testing/testing_api_cmd_get_otp_devices.c @@ -0,0 +1,238 @@ +/* + This file is part of TALER + Copyright (C) 2022 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_get_otp_devices.c + * @brief command to test GET /otp-devices + * @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 "GET /otp-devices" CMD. + */ +struct GetOtpDevicesState +{ + + /** + * Handle for a "GET /otp-devices" request. + */ + struct TALER_MERCHANT_OtpDevicesGetHandle *igh; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + + /** + * The list of otp_device references. + */ + const char **otp_devices; + + /** + * Length of @e otp_devices. + */ + unsigned int otp_devices_length; + +}; + + +/** + * Callback for a GET /otp-devices operation. + * + * @param cls closure for this function + * @param tgr response details + */ +static void +get_otp_devices_cb (void *cls, + const struct TALER_MERCHANT_OtpDevicesGetResponse *tgr) +{ + struct GetOtpDevicesState *gis = cls; + + gis->igh = NULL; + if (gis->http_status != tgr->hr.http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + tgr->hr.http_status, + (int) tgr->hr.ec, + TALER_TESTING_interpreter_get_current_label (gis->is)); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + switch (tgr->hr.http_status) + { + case MHD_HTTP_OK: + if (tgr->details.ok.otp_devices_length != gis->otp_devices_length) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Length of otp_devices found does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + for (unsigned int i = 0; i < gis->otp_devices_length; ++i) + { + const struct TALER_TESTING_Command *otp_device_cmd; + + otp_device_cmd = TALER_TESTING_interpreter_lookup_command ( + gis->is, + gis->otp_devices[i]); + + { + const char *otp_device_id; + + if (GNUNET_OK != + TALER_TESTING_get_trait_otp_id (otp_device_cmd, + &otp_device_id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not fetch otp_device id\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + if (0 != strcmp (tgr->details.ok.otp_devices[i].otp_device_id, + otp_device_id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "OtpDevice id does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + } + } + break; + case MHD_HTTP_UNAUTHORIZED: + break; + case MHD_HTTP_NOT_FOUND: + /* instance does not exist */ + break; + default: + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u (%d).\n", + tgr->hr.http_status, + tgr->hr.ec); + break; + } + TALER_TESTING_interpreter_next (gis->is); +} + + +/** + * Run the "GET /otp-devices" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +get_otp_devices_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct GetOtpDevicesState *gis = cls; + + gis->is = is; + gis->igh = TALER_MERCHANT_otp_devices_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + &get_otp_devices_cb, + gis); + GNUNET_assert (NULL != gis->igh); +} + + +/** + * Free the state of a "GET otp_device" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +get_otp_devices_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct GetOtpDevicesState *gis = cls; + + if (NULL != gis->igh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "GET /otp-devices operation did not complete\n"); + TALER_MERCHANT_otp_devices_get_cancel (gis->igh); + } + GNUNET_array_grow (gis->otp_devices, + gis->otp_devices_length, + 0); + GNUNET_free (gis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_otp_devices (const char *label, + const char *merchant_url, + unsigned int http_status, + ...) +{ + struct GetOtpDevicesState *gis; + + gis = GNUNET_new (struct GetOtpDevicesState); + gis->merchant_url = merchant_url; + gis->http_status = http_status; + { + const char *clabel; + va_list ap; + + va_start (ap, http_status); + while (NULL != (clabel = va_arg (ap, const char *))) + { + GNUNET_array_append (gis->otp_devices, + gis->otp_devices_length, + clabel); + } + va_end (ap); + } + { + struct TALER_TESTING_Command cmd = { + .cls = gis, + .label = label, + .run = &get_otp_devices_run, + .cleanup = &get_otp_devices_cleanup + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_get_otp_devices.c */ diff --git a/src/testing/testing_api_cmd_get_product.c b/src/testing/testing_api_cmd_get_product.c index ece36e71..a7d8c186 100644 --- a/src/testing/testing_api_cmd_get_product.c +++ b/src/testing/testing_api_cmd_get_product.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -71,60 +71,31 @@ struct GetProductState * Callback for a /get/product/$ID operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param description description of the product - * @param description_i18n Map from IETF BCP 47 language tags to localized descriptions - * @param unit unit in which the product is measured (liters, kilograms, packages, etc.) - * @param price the price for one @a unit of the product, zero is used to imply that - * this product is not sold separately or that the price is not fixed and - * must be supplied by the front-end. If non-zero, price must include - * applicable taxes. - * @param image base64-encoded product image - * @param taxes list of taxes paid by the merchant - * @param total_stock in @a units, -1 to indicate "infinite" (i.e. electronic books), - * does NOT indicate remaining stocks, to get remaining stocks, - * subtract @a total_sold and @a total_lost. Note that this still - * does not then say how many of the remaining inventory are locked. - * @param total_sold in @a units, total number of @a unit of product sold - * @param total_lost in @a units, total number of @a unit of product lost from inventory - * @param location where the product is in stock - * @param next_restock when the next restocking is expected to happen, 0 for unknown, - * #GNUNET_TIME_UNIT_FOREVER_ABS for 'never'. + * @param pgr response details */ static void get_product_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *description, - const json_t *description_i18n, - const char *unit, - const struct TALER_Amount *price, - const char *image, - const json_t *taxes, - int64_t total_stock, - uint64_t total_sold, - uint64_t total_lost, - const json_t *location, - struct GNUNET_TIME_Timestamp next_restock) + const struct TALER_MERCHANT_ProductGetResponse *pgr) { struct GetProductState *gis = cls; const struct TALER_TESTING_Command *product_cmd; gis->igh = NULL; - if (gis->http_status != hr->http_status) + if (gis->http_status != pgr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + pgr->hr.http_status, + (int) pgr->hr.ec, TALER_TESTING_interpreter_get_current_label (gis->is)); TALER_TESTING_interpreter_fail (gis->is); return; } - switch (hr->http_status) + switch (pgr->hr.http_status) { case MHD_HTTP_OK: { - const char **expected_description; + const char *expected_description; product_cmd = TALER_TESTING_interpreter_lookup_command ( gis->is, @@ -133,8 +104,8 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_product_description (product_cmd, &expected_description)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (description, - *expected_description)) + if (0 != strcmp (pgr->details.ok.description, + expected_description)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Product description does not match\n"); @@ -149,7 +120,7 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_i18n_description (product_cmd, &expected_description_i18n)) TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (description_i18n, + if (1 != json_equal (pgr->details.ok.description_i18n, expected_description_i18n)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -165,9 +136,10 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_amount (product_cmd, &expected_price)) TALER_TESTING_interpreter_fail (gis->is); - if ((GNUNET_OK != TALER_amount_cmp_currency (price, - expected_price)) || - (0 != TALER_amount_cmp (price, + if ((GNUNET_OK != + TALER_amount_cmp_currency (&pgr->details.ok.price, + expected_price)) || + (0 != TALER_amount_cmp (&pgr->details.ok.price, expected_price))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -177,14 +149,14 @@ get_product_cb (void *cls, } } { - const char **expected_image; + const char *expected_image; if (GNUNET_OK != TALER_TESTING_get_trait_product_image (product_cmd, &expected_image)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (image, - *expected_image)) + if (0 != strcmp (pgr->details.ok.image, + expected_image)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Product image does not match\n"); @@ -199,7 +171,7 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_taxes (product_cmd, &expected_taxes)) TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (taxes, + if (1 != json_equal (pgr->details.ok.taxes, expected_taxes)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -209,14 +181,14 @@ get_product_cb (void *cls, } } { - const char **expected_unit; + const char *expected_unit; if (GNUNET_OK != TALER_TESTING_get_trait_product_unit (product_cmd, &expected_unit)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (unit, - *expected_unit)) + if (0 != strcmp (pgr->details.ok.unit, + expected_unit)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Product unit does not match\n"); @@ -231,7 +203,7 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_address (product_cmd, &expected_location)) TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (location, + if (1 != json_equal (pgr->details.ok.location, expected_location)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -247,7 +219,7 @@ get_product_cb (void *cls, TALER_TESTING_get_trait_product_stock (product_cmd, &expected_total_stock)) TALER_TESTING_interpreter_fail (gis->is); - if (total_stock != *expected_total_stock) + if (pgr->details.ok.total_stock != *expected_total_stock) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Product total stock does not match\n"); @@ -263,7 +235,7 @@ get_product_cb (void *cls, 0, &expected_next_restock)) TALER_TESTING_interpreter_fail (gis->is); - if (GNUNET_TIME_timestamp_cmp (next_restock, + if (GNUNET_TIME_timestamp_cmp (pgr->details.ok.next_restock, !=, *expected_next_restock)) { @@ -302,7 +274,8 @@ get_product_run (void *cls, struct GetProductState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_product_get (is->ctx, + gis->igh = TALER_MERCHANT_product_get (TALER_TESTING_interpreter_get_context ( + is), gis->merchant_url, gis->product_id, &get_product_cb, diff --git a/src/testing/testing_api_cmd_get_products.c b/src/testing/testing_api_cmd_get_products.c index 190bb4c1..97a105be 100644 --- a/src/testing/testing_api_cmd_get_products.c +++ b/src/testing/testing_api_cmd_get_products.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -71,17 +71,14 @@ struct GetProductsState * Callback for a GET /products operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param products_length length of the @a products array - * @param products array of products the requested instance offers + * @param gpr response details */ static void get_products_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int products_length, - const struct TALER_MERCHANT_InventoryEntry products[]) + const struct TALER_MERCHANT_GetProductsResponse *gpr) { struct GetProductsState *gis = cls; + const struct TALER_MERCHANT_HttpResponse *hr = &gpr->hr; gis->igh = NULL; if (gis->http_status != hr->http_status) @@ -97,40 +94,47 @@ get_products_cb (void *cls, switch (hr->http_status) { case MHD_HTTP_OK: - if (products_length != gis->products_length) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Length of products found does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - for (unsigned int i = 0; i < gis->products_length; ++i) - { - const struct TALER_TESTING_Command *product_cmd; - - product_cmd = TALER_TESTING_interpreter_lookup_command ( - gis->is, - gis->products[i]); + unsigned int products_length + = gpr->details.ok.products_length; + const struct TALER_MERCHANT_InventoryEntry *products + = gpr->details.ok.products; + if (products_length != gis->products_length) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Length of products found does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + for (unsigned int i = 0; i < gis->products_length; ++i) { - const char **product_id; + const struct TALER_TESTING_Command *product_cmd; + + product_cmd = TALER_TESTING_interpreter_lookup_command ( + gis->is, + gis->products[i]); - if (GNUNET_OK != - TALER_TESTING_get_trait_product_id (product_cmd, - &product_id)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch product id\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; - } - if (0 != strcmp (products[i].product_id, - *product_id)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Product id does not match\n"); - TALER_TESTING_interpreter_fail (gis->is); - return; + const char *product_id; + + if (GNUNET_OK != + TALER_TESTING_get_trait_product_id (product_cmd, + &product_id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not fetch product id\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } + if (0 != strcmp (products[i].product_id, + product_id)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Product id does not match\n"); + TALER_TESTING_interpreter_fail (gis->is); + return; + } } } } @@ -166,10 +170,11 @@ get_products_run (void *cls, struct GetProductsState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_products_get (is->ctx, - gis->merchant_url, - &get_products_cb, - gis); + gis->igh = TALER_MERCHANT_products_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + &get_products_cb, + gis); GNUNET_assert (NULL != gis->igh); } diff --git a/src/testing/testing_api_cmd_get_reserve.c b/src/testing/testing_api_cmd_get_reserve.c deleted file mode 100644 index ef7f67e0..00000000 --- a/src/testing/testing_api_cmd_get_reserve.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - 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_get_reserve.c - * @brief command to test GET /private/reserves/$RESERVE_PUB - * @author Jonathan Buchanan - */ -#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" - - -struct GetReserveState -{ - - /** - * Handle for a "GET reserve" request. - */ - struct TALER_MERCHANT_ReserveGetHandle *rgh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Label for a command that created a reserve. - */ - const char *reserve_reference; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Fetch tips - */ - bool fetch_tips; - - /** - * Length of @e tips. - */ - unsigned int tips_length; - - /** - * The list of references to tips. - */ - const char **tips; -}; - - -static void -get_reserve_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_MERCHANT_ReserveSummary *rs, - bool active, - const char *exchange_url, - const char *payto_uri, - unsigned int tips_length, - const struct TALER_MERCHANT_TipDetails tips[]) -{ - struct GetReserveState *grs = cls; - const struct TALER_TESTING_Command *reserve_cmd; - - reserve_cmd = TALER_TESTING_interpreter_lookup_command ( - grs->is, - grs->reserve_reference); - - grs->rgh = NULL; - if (grs->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 (grs->is)); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_OK: - { - const struct TALER_Amount *initial_amount; - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (reserve_cmd, - &initial_amount)) - TALER_TESTING_interpreter_fail (grs->is); - if ((GNUNET_OK != - TALER_amount_cmp_currency (&rs->merchant_initial_amount, - initial_amount)) || - (0 != TALER_amount_cmp (&rs->merchant_initial_amount, - initial_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Reserve initial amount does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - } - if (tips_length != grs->tips_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Number of tips authorized does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - for (unsigned int i = 0; i < tips_length; ++i) - { - const struct TALER_TESTING_Command *tip_cmd; - - tip_cmd = TALER_TESTING_interpreter_lookup_command (grs->is, - grs->tips[i]); - { - const struct TALER_TipIdentifierP *tip_id; - - if (GNUNET_OK != - TALER_TESTING_get_trait_tip_id (tip_cmd, - &tip_id)) - TALER_TESTING_interpreter_fail (grs->is); - - if (0 != GNUNET_memcmp (&tips[i].tip_id, - tip_id)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Reserve tip id does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - } - { - const struct TALER_Amount *total_amount; - - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (tip_cmd, - &total_amount)) - TALER_TESTING_interpreter_fail (grs->is); - - if ((GNUNET_OK != - TALER_amount_cmp_currency (&tips[i].amount, - total_amount)) || - (0 != TALER_amount_cmp (&tips[i].amount, - total_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Reserve tip amount does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - } - { - const char **reason; - - if (GNUNET_OK != - TALER_TESTING_get_trait_reason (tip_cmd, - &reason)) - TALER_TESTING_interpreter_fail (grs->is); - - if (0 != strcmp (tips[i].reason, - *reason)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Reserve tip reason does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - } - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (grs->is); -} - - -/** - * Run the "GET /private/reserves/$RESERVE_PUB" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -get_reserve_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct GetReserveState *grs = cls; - const struct TALER_TESTING_Command *reserve_cmd; - const struct TALER_ReservePublicKeyP *reserve_pub; - - reserve_cmd = TALER_TESTING_interpreter_lookup_command ( - is, - grs->reserve_reference); - if (GNUNET_OK != - TALER_TESTING_get_trait_reserve_pub (reserve_cmd, - &reserve_pub)) - TALER_TESTING_FAIL (is); - - grs->is = is; - grs->rgh = TALER_MERCHANT_reserve_get (is->ctx, - grs->merchant_url, - reserve_pub, - grs->fetch_tips, - &get_reserve_cb, - grs); - - GNUNET_assert (NULL != grs->rgh); -} - - -/** - * Free the state of a "GET reserve" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -get_reserve_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct GetReserveState *grs = cls; - - if (NULL != grs->rgh) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "GET /private/reserve/$RESERVE_PUB operation did not complete\n"); - TALER_MERCHANT_reserve_get_cancel (grs->rgh); - } - GNUNET_array_grow (grs->tips, - grs->tips_length, - 0); - GNUNET_free (grs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_reserve (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *reserve_reference) -{ - struct GetReserveState *grs; - - grs = GNUNET_new (struct GetReserveState); - grs->merchant_url = merchant_url; - grs->http_status = http_status; - grs->reserve_reference = reserve_reference; - grs->fetch_tips = false; - { - struct TALER_TESTING_Command cmd = { - .cls = grs, - .label = label, - .run = &get_reserve_run, - .cleanup = &get_reserve_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_reserve_with_tips (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *reserve_reference, - ...) -{ - struct GetReserveState *grs; - - grs = GNUNET_new (struct GetReserveState); - grs->merchant_url = merchant_url; - grs->http_status = http_status; - grs->reserve_reference = reserve_reference; - grs->fetch_tips = true; - { - const char *clabel; - va_list ap; - - va_start (ap, reserve_reference); - while (NULL != (clabel = va_arg (ap, const char *))) - { - GNUNET_array_append (grs->tips, - grs->tips_length, - clabel); - } - va_end (ap); - } - { - struct TALER_TESTING_Command cmd = { - .cls = grs, - .label = label, - .run = &get_reserve_run, - .cleanup = &get_reserve_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_get_reserve.c */ diff --git a/src/testing/testing_api_cmd_get_reserves.c b/src/testing/testing_api_cmd_get_reserves.c deleted file mode 100644 index ea860c27..00000000 --- a/src/testing/testing_api_cmd_get_reserves.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - 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_get_reserves.c - * @brief command to test GET /private/reserves - * @author Jonathan Buchanan - */ -#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 "GET reserves" CMD - */ -struct GetReservesState -{ - - /** - * Handle for a "GET reserves" request. - */ - struct TALER_MERCHANT_ReservesGetHandle *rgh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * A list of reserves to compare with. - */ - const char **reserves; - - /** - * Length of @e reserve_refs. - */ - unsigned int reserves_length; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; -}; - - -static void -get_reserves_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int reserves_length, - const struct TALER_MERCHANT_ReserveSummary reserves[]) -{ - struct GetReservesState *grs = cls; - bool matched[reserves_length]; - bool fail = false; - - grs->rgh = NULL; - if (grs->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 (grs->is)); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_OK: - if (reserves_length != grs->reserves_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Length of reserves found does not match\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - /* check if the data returned matches that from the POST / PATCH */ - memset (matched, 0, sizeof (matched)); - for (unsigned int i = 0; i < reserves_length; ++i) - for (unsigned int j = 0; j < reserves_length; ++j) - { - const struct TALER_TESTING_Command *reserve_cmd; - bool match = true; - - reserve_cmd = TALER_TESTING_interpreter_lookup_command ( - grs->is, - grs->reserves[j]); - { - const struct TALER_ReservePublicKeyP *reserve_pub; - - if (GNUNET_OK != - TALER_TESTING_get_trait_reserve_pub (reserve_cmd, - &reserve_pub)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch reserve public key\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - if (0 != GNUNET_memcmp (&reserves[i].reserve_pub, - reserve_pub)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reserve public key does not match, got %s\n", - TALER_B2S (&reserves[i].reserve_pub)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reserve public key does not match, expected %s\n", - TALER_B2S (reserve_pub)); - match = false; - } - } - { - const struct TALER_Amount *initial; - - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (reserve_cmd, - &initial)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch reserve initial balance\n"); - TALER_TESTING_interpreter_fail (grs->is); - return; - } - if ((GNUNET_OK != - TALER_amount_cmp_currency (&reserves[i].merchant_initial_amount, - initial)) || - (0 != TALER_amount_cmp (&reserves[i].merchant_initial_amount, - initial))) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reserve initial amount does not match, got %s\n", - TALER_amount2s (&reserves[i].merchant_initial_amount)); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reserve initial amount does not match, wanted %s\n", - TALER_amount2s (initial)); - match = false; - } - } - if (match) - matched[i] = true; - } - for (unsigned int i = 0; i < reserves_length; ++i) - if (! matched[i]) - fail = true; - if (fail) - { - TALER_TESTING_interpreter_fail (grs->is); - return; - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (grs->is); -} - - -/** - * Run the "GET /private/reserves" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -get_reserves_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct GetReservesState *grs = cls; - - grs->is = is; - grs->rgh = TALER_MERCHANT_reserves_get (is->ctx, - grs->merchant_url, - GNUNET_TIME_UNIT_ZERO_TS, - TALER_EXCHANGE_YNA_ALL, - TALER_EXCHANGE_YNA_ALL, - &get_reserves_cb, - grs); - - GNUNET_assert (NULL != grs->rgh); -} - - -/** - * Free the state of a "GET reserves" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -get_reserves_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct GetReservesState *grs = cls; - - if (NULL != grs->rgh) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "GET /private/reserves operation did not complete\n"); - TALER_MERCHANT_reserves_get_cancel (grs->rgh); - } - GNUNET_array_grow (grs->reserves, - grs->reserves_length, - 0); - GNUNET_free (grs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_reserves (const char *label, - const char *merchant_url, - unsigned int http_status, - ...) -{ - struct GetReservesState *grs; - - grs = GNUNET_new (struct GetReservesState); - grs->merchant_url = merchant_url; - grs->http_status = http_status; - { - const char *clabel; - va_list ap; - - va_start (ap, http_status); - while (NULL != (clabel = va_arg (ap, const char *))) - { - GNUNET_array_append (grs->reserves, - grs->reserves_length, - clabel); - } - va_end (ap); - } - { - struct TALER_TESTING_Command cmd = { - .cls = grs, - .label = label, - .run = &get_reserves_run, - .cleanup = &get_reserves_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_get_reserves.c */ diff --git a/src/testing/testing_api_cmd_get_template.c b/src/testing/testing_api_cmd_get_template.c index bd9afff3..377ffe44 100644 --- a/src/testing/testing_api_cmd_get_template.c +++ b/src/testing/testing_api_cmd_get_template.c @@ -71,37 +71,31 @@ struct GetTemplateState * Callback for a /get/templates/$ID operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param template_description description of the template - * @param image base64-encoded template image - * @param template_contract where the contract of the company is + * @param tgr HTTP response details */ static void get_template_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *template_description, - const char *image, - const json_t *template_contract) + const struct TALER_MERCHANT_TemplateGetResponse *tgr) { struct GetTemplateState *gis = cls; const struct TALER_TESTING_Command *template_cmd; gis->igh = NULL; - if (gis->http_status != hr->http_status) + if (gis->http_status != tgr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + tgr->hr.http_status, + (int) tgr->hr.ec, TALER_TESTING_interpreter_get_current_label (gis->is)); TALER_TESTING_interpreter_fail (gis->is); return; } - switch (hr->http_status) + switch (tgr->hr.http_status) { case MHD_HTTP_OK: { - const char **expected_description; + const char *expected_description; template_cmd = TALER_TESTING_interpreter_lookup_command ( gis->is, @@ -110,8 +104,8 @@ get_template_cb (void *cls, TALER_TESTING_get_trait_template_description (template_cmd, &expected_description)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (template_description, - *expected_description)) + if (0 != strcmp (tgr->details.ok.template_description, + expected_description)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Template description does not match\n"); @@ -120,22 +114,22 @@ get_template_cb (void *cls, } } { - const char **expected_image; + const char *expected_otp_id; if (GNUNET_OK != - TALER_TESTING_get_trait_template_image (template_cmd, - &expected_image)) + TALER_TESTING_get_trait_otp_id (template_cmd, + &expected_otp_id)) TALER_TESTING_interpreter_fail (gis->is); - if ( ( (NULL == image) && (NULL != *expected_image)) || - ( (NULL != image) && (NULL == *expected_image)) || - ( (NULL != image) && - (0 != strcmp (image, - *expected_image)) ) ) + if ( ( (NULL == tgr->details.ok.otp_id) && (NULL != expected_otp_id)) || + ( (NULL != tgr->details.ok.otp_id) && (NULL == expected_otp_id)) || + ( (NULL != tgr->details.ok.otp_id) && + (0 != strcmp (tgr->details.ok.otp_id, + expected_otp_id)) ) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Template image `%s' does not match `%s'\n", - image, - *expected_image); + "Template pos_key `%s' does not match `%s'\n", + tgr->details.ok.otp_id, + expected_otp_id); TALER_TESTING_interpreter_fail (gis->is); return; } @@ -147,7 +141,7 @@ get_template_cb (void *cls, TALER_TESTING_get_trait_template_contract (template_cmd, &expected_template_contract)) TALER_TESTING_interpreter_fail (gis->is); - if (1 != json_equal (template_contract, + if (1 != json_equal (tgr->details.ok.template_contract, expected_template_contract)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -185,11 +179,12 @@ get_template_run (void *cls, struct GetTemplateState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_template_get (is->ctx, - gis->merchant_url, - gis->template_id, - &get_template_cb, - gis); + gis->igh = TALER_MERCHANT_template_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + gis->template_id, + &get_template_cb, + gis); GNUNET_assert (NULL != gis->igh); } diff --git a/src/testing/testing_api_cmd_get_templates.c b/src/testing/testing_api_cmd_get_templates.c index 3e9d59c6..bc971dc2 100644 --- a/src/testing/testing_api_cmd_get_templates.c +++ b/src/testing/testing_api_cmd_get_templates.c @@ -71,33 +71,29 @@ struct GetTemplatesState * Callback for a GET /templates operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param templates_length length of the @a templates array - * @param templates array of templates the requested instance offers + * @param tgr response details */ static void get_templates_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int templates_length, - const struct TALER_MERCHANT_TemplateEntry templates[]) + const struct TALER_MERCHANT_TemplatesGetResponse *tgr) { struct GetTemplatesState *gis = cls; gis->igh = NULL; - if (gis->http_status != hr->http_status) + if (gis->http_status != tgr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + tgr->hr.http_status, + (int) tgr->hr.ec, TALER_TESTING_interpreter_get_current_label (gis->is)); TALER_TESTING_interpreter_fail (gis->is); return; } - switch (hr->http_status) + switch (tgr->hr.http_status) { case MHD_HTTP_OK: - if (templates_length != gis->templates_length) + if (tgr->details.ok.templates_length != gis->templates_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Length of templates found does not match\n"); @@ -113,19 +109,19 @@ get_templates_cb (void *cls, gis->templates[i]); { - const char **template_id; + const char *template_id; if (GNUNET_OK != TALER_TESTING_get_trait_template_id (template_cmd, - &template_id)) + &template_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not fetch template id\n"); TALER_TESTING_interpreter_fail (gis->is); return; } - if (0 != strcmp (templates[i].template_id, - *template_id)) + if (0 != strcmp (tgr->details.ok.templates[i].template_id, + template_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Template id does not match\n"); @@ -143,8 +139,9 @@ get_templates_cb (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u (%d).\n", - hr->http_status, - hr->ec); + tgr->hr.http_status, + tgr->hr.ec); + break; } TALER_TESTING_interpreter_next (gis->is); } @@ -160,16 +157,17 @@ get_templates_cb (void *cls, */ static void get_templates_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) { struct GetTemplatesState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_templates_get (is->ctx, - gis->merchant_url, - &get_templates_cb, - gis); + gis->igh = TALER_MERCHANT_templates_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + &get_templates_cb, + gis); GNUNET_assert (NULL != gis->igh); } @@ -183,7 +181,7 @@ get_templates_run (void *cls, */ static void get_templates_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) + const struct TALER_TESTING_Command *cmd) { struct GetTemplatesState *gis = cls; @@ -202,9 +200,9 @@ get_templates_cleanup (void *cls, struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_get_templates (const char *label, - const char *merchant_url, - unsigned int http_status, - ...) + const char *merchant_url, + unsigned int http_status, + ...) { struct GetTemplatesState *gis; diff --git a/src/testing/testing_api_cmd_get_tips.c b/src/testing/testing_api_cmd_get_tips.c deleted file mode 100644 index 89a82202..00000000 --- a/src/testing/testing_api_cmd_get_tips.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - 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_get_tips.c - * @brief command to test GET /private/tips - * @author Jonathan Buchanan - */ -#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 "GET tips" CMD. - */ -struct GetTipsState -{ - - /** - * Handle for a "GET tips" request. - */ - struct TALER_MERCHANT_TipsGetHandle *tgh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Base URL of the merchant serving the request. - */ - const char *merchant_url; - - /** - * Row to start querying the database from. - */ - uint64_t offset; - - /** - * How many rows to return (with direction). - */ - int64_t limit; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Length of @e tips. - */ - unsigned int tips_length; - - /** - * References to tips that we expect to be found. - */ - const char **tips; - -}; - -/** - * Callback for a GET /private/tips operation. - * - * @param cls closure for this function - * @param hr HTTP response details - * @param tips_length length of the @a tips array - * @param tips array of tips - */ -static void -get_tips_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int tips_length, - const struct TALER_MERCHANT_TipEntry tips[]) -{ - struct GetTipsState *gts = cls; - - gts->tgh = NULL; - if (gts->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 (gts->is)); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_OK: - if (tips_length != gts->tips_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tips length does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - for (unsigned int i = 0; i < tips_length; ++i) - { - const struct TALER_TESTING_Command *tip_cmd; - - tip_cmd = TALER_TESTING_interpreter_lookup_command ( - gts->is, - gts->tips[i]); - { - const struct TALER_TipIdentifierP *tip_id; - - if (GNUNET_OK != - TALER_TESTING_get_trait_tip_id (tip_cmd, - &tip_id)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch tip id\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - if (0 != GNUNET_memcmp (tip_id, - &tips[i].tip_id)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip id does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - { - const struct TALER_Amount *tip_amount; - - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (tip_cmd, - &tip_amount)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch tip amount\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - if ((GNUNET_OK != TALER_amount_cmp_currency (tip_amount, - &tips[i].tip_amount)) || - (0 != TALER_amount_cmp (tip_amount, - &tips[i].tip_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip amount does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (gts->is); -} - - -/** - * Run the "GET /private/tips" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -get_tips_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct GetTipsState *gts = cls; - - gts->is = is; - gts->tgh = TALER_MERCHANT_tips_get2 (is->ctx, - gts->merchant_url, - TALER_EXCHANGE_YNA_NO, - gts->limit, - gts->offset, - &get_tips_cb, - gts); - - GNUNET_assert (NULL != gts->tgh); -} - - -/** - * Free the state of a "GET tips" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -get_tips_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct GetTipsState *gts = cls; - - if (NULL != gts->tgh) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "GET /private/tips operation did not complete\n"); - TALER_MERCHANT_tips_get_cancel (gts->tgh); - } - GNUNET_array_grow (gts->tips, - gts->tips_length, - 0); - GNUNET_free (gts); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_get_tips (const char *label, - const char *merchant_url, - unsigned int http_status, - ...) -{ - struct GetTipsState *gts; - - gts = GNUNET_new (struct GetTipsState); - gts->merchant_url = merchant_url; - gts->offset = INT64_MAX; - gts->limit = -20; - gts->http_status = http_status; - { - const char *clabel; - va_list ap; - - va_start (ap, http_status); - while (NULL != (clabel = va_arg (ap, const char *))) - { - GNUNET_array_append (gts->tips, - gts->tips_length, - clabel); - } - va_end (ap); - } - { - struct TALER_TESTING_Command cmd = { - .cls = gts, - .label = label, - .run = &get_tips_run, - .cleanup = &get_tips_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_get_tips2 (const char *label, - const char *merchant_url, - uint64_t offset, - int64_t limit, - unsigned int http_status, - ...) -{ - struct GetTipsState *gts; - - gts = GNUNET_new (struct GetTipsState); - gts->merchant_url = merchant_url; - gts->offset = offset; - gts->limit = limit; - gts->http_status = http_status; - { - const char *clabel; - va_list ap; - - va_start (ap, http_status); - while (NULL != (clabel = va_arg (ap, const char *))) - { - GNUNET_array_append (gts->tips, - gts->tips_length, - clabel); - } - va_end (ap); - } - { - struct TALER_TESTING_Command cmd = { - .cls = gts, - .label = label, - .run = &get_tips_run, - .cleanup = &get_tips_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_get_tips.c */ diff --git a/src/testing/testing_api_cmd_get_transfers.c b/src/testing/testing_api_cmd_get_transfers.c index fe50c349..b5b05295 100644 --- a/src/testing/testing_api_cmd_get_transfers.c +++ b/src/testing/testing_api_cmd_get_transfers.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -83,42 +83,42 @@ struct GetTransfersState * Check the result of our GET /transfers request to a merchant * * @param cls closure - * @param hr HTTP response details - * @param transfers_length length of the @a transfers array - * @param transfers array with details about the transfers we received + * @param gtr response details */ static void get_transfers_cb ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int transfers_length, - const struct TALER_MERCHANT_TransferData transfers[]) + const struct TALER_MERCHANT_GetTransfersResponse *gtr) { struct GetTransfersState *gts = cls; gts->gth = NULL; - if (gts->http_status != hr->http_status) + if (gts->http_status != gtr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + gtr->hr.http_status, + (int) gtr->hr.ec, TALER_TESTING_interpreter_get_current_label (gts->is)); TALER_TESTING_interpreter_fail (gts->is); return; } - switch (hr->http_status) + switch (gtr->hr.http_status) { case MHD_HTTP_OK: - if (transfers_length != gts->transfers_length) + if (gtr->details.ok.transfers_length != gts->transfers_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Transfers length does not match\n"); + "Transfers length does not match (got %u/want %u)\n", + gtr->details.ok.transfers_length, + gts->transfers_length); TALER_TESTING_interpreter_fail (gts->is); return; } - for (unsigned int i = 0; i < transfers_length; ++i) + for (unsigned int i = 0; i < gtr->details.ok.transfers_length; ++i) { + const struct TALER_MERCHANT_TransferData *transfer + = >r->details.ok.transfers[i]; const struct TALER_TESTING_Command *transfer_cmd; transfer_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -145,7 +145,7 @@ get_transfers_cb ( return; } if (0 != GNUNET_memcmp (wtid, - &transfers[i].wtid)) + &transfer->wtid)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire transfer id does not match\n"); @@ -154,10 +154,10 @@ get_transfers_cb ( } TALER_TESTING_cmd_merchant_post_transfer_set_serial ( (struct TALER_TESTING_Command *) transfer_cmd, - transfers[i].credit_serial); + transfer->credit_serial); } { - const char **payto_uri; + const char *payto_uri; if (GNUNET_OK != TALER_TESTING_get_trait_credit_payto_uri (transfer_cmd, @@ -168,13 +168,13 @@ get_transfers_cb ( TALER_TESTING_interpreter_fail (gts->is); return; } - if (0 != strcmp (*payto_uri, - transfers[i].payto_uri)) + if (0 != strcmp (payto_uri, + transfer->payto_uri)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire transfer payto uri does not match: %s != %s\n", - *payto_uri, - transfers[i].payto_uri); + payto_uri, + transfer->payto_uri); TALER_TESTING_interpreter_fail (gts->is); return; } @@ -193,9 +193,9 @@ get_transfers_cb ( } if ( (GNUNET_OK != TALER_amount_cmp_currency (credit_amount, - &transfers[i].credit_amount)) || + &transfer->credit_amount)) || (0 != TALER_amount_cmp (credit_amount, - &transfers[i].credit_amount))) + &transfer->credit_amount))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire transfer credit amount does not match\n"); @@ -204,7 +204,7 @@ get_transfers_cb ( } } { - const char **exchange_url; + const char *exchange_url; if (GNUNET_OK != TALER_TESTING_get_trait_exchange_url (transfer_cmd, @@ -215,8 +215,8 @@ get_transfers_cb ( TALER_TESTING_interpreter_fail (gts->is); return; } - if (0 != strcmp (*exchange_url, - transfers[i].exchange_url)) + if (0 != strcmp (exchange_url, + transfer->exchange_url)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire transfer exchange url does not match\n"); @@ -224,34 +224,13 @@ get_transfers_cb ( return; } } - { - const struct GNUNET_TIME_Timestamp *execution_time; - - if (GNUNET_OK != - TALER_TESTING_get_trait_timestamp (transfer_cmd, - 0, - &execution_time)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch wire transfer execution time\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - if (GNUNET_TIME_timestamp_cmp (*execution_time, - !=, - transfers[i].execution_time)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Wire transfer execution time does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } } break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); + "Unhandled HTTP status %u.\n", + gtr->hr.http_status); + break; } TALER_TESTING_interpreter_next (gts->is); } @@ -272,16 +251,17 @@ get_transfers_run (void *cls, struct GetTransfersState *gts = cls; gts->is = is; - gts->gth = TALER_MERCHANT_transfers_get (is->ctx, - gts->merchant_url, - gts->payto_uri, - GNUNET_TIME_UNIT_FOREVER_TS, - GNUNET_TIME_UNIT_ZERO_TS, - INT64_MAX, - 0, - TALER_EXCHANGE_YNA_ALL, - &get_transfers_cb, - gts); + gts->gth = TALER_MERCHANT_transfers_get ( + TALER_TESTING_interpreter_get_context (is), + gts->merchant_url, + gts->payto_uri, + GNUNET_TIME_UNIT_FOREVER_TS, + GNUNET_TIME_UNIT_ZERO_TS, + INT64_MAX, + 0, + TALER_EXCHANGE_YNA_ALL, + &get_transfers_cb, + gts); GNUNET_assert (NULL != gts->gth); } @@ -313,11 +293,12 @@ get_transfers_cleanup (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_transfers (const char *label, - const char *merchant_url, - const char *payto_uri, - unsigned int http_code, - ...) +TALER_TESTING_cmd_merchant_get_transfers ( + const char *label, + const char *merchant_url, + const char *payto_uri, + unsigned int http_code, + ...) { struct GetTransfersState *gts; diff --git a/src/testing/testing_api_cmd_get_webhook.c b/src/testing/testing_api_cmd_get_webhook.c index 7acc344e..aef6c555 100644 --- a/src/testing/testing_api_cmd_get_webhook.c +++ b/src/testing/testing_api_cmd_get_webhook.c @@ -105,7 +105,7 @@ get_webhook_cb (void *cls, { case MHD_HTTP_OK: { - const char **expected_event_type; + const char *expected_event_type; webhook_cmd = TALER_TESTING_interpreter_lookup_command ( gis->is, @@ -114,8 +114,8 @@ get_webhook_cb (void *cls, TALER_TESTING_get_trait_event_type (webhook_cmd, &expected_event_type)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (event_type, - *expected_event_type)) + if (0 != strcmp (event_type, + expected_event_type)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Event type does not match\n"); @@ -124,14 +124,14 @@ get_webhook_cb (void *cls, } } { - const char **expected_url; + const char *expected_url; if (GNUNET_OK != TALER_TESTING_get_trait_url (webhook_cmd, &expected_url)) TALER_TESTING_interpreter_fail (gis->is); if (0 != strcmp (url, - *expected_url)) + expected_url)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "URL does not match\n"); @@ -140,14 +140,14 @@ get_webhook_cb (void *cls, } } { - const char **expected_http_method; + const char *expected_http_method; if (GNUNET_OK != TALER_TESTING_get_trait_http_method (webhook_cmd, &expected_http_method)) TALER_TESTING_interpreter_fail (gis->is); if (0 != strcmp (http_method, - *expected_http_method)) + expected_http_method)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "http_method does not match\n"); @@ -156,14 +156,17 @@ get_webhook_cb (void *cls, } } { - const char **expected_header_template; + const char *expected_header_template; if (GNUNET_OK != TALER_TESTING_get_trait_header_template (webhook_cmd, &expected_header_template)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (header_template, - *expected_header_template)) + if ( ( (NULL == header_template) && (NULL != expected_header_template)) || + ( (NULL != header_template) && (NULL == expected_header_template)) || + ( (NULL != header_template) && + (0 != strcmp (header_template, + expected_header_template)) ) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "header template does not match\n"); @@ -172,14 +175,17 @@ get_webhook_cb (void *cls, } } { - const char **expected_body_template; + const char *expected_body_template; if (GNUNET_OK != TALER_TESTING_get_trait_body_template (webhook_cmd, &expected_body_template)) TALER_TESTING_interpreter_fail (gis->is); - if (0 != strcmp (body_template, - *expected_body_template)) + if ( ( (NULL == body_template) && (NULL != expected_body_template)) || + ( (NULL != body_template) && (NULL == expected_body_template)) || + ( (NULL != body_template) && + (0 != strcmp (body_template, + expected_body_template)) ) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "body template does not match\n"); @@ -216,7 +222,8 @@ get_webhook_run (void *cls, struct GetWebhookState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_webhook_get (is->ctx, + gis->igh = TALER_MERCHANT_webhook_get (TALER_TESTING_interpreter_get_context ( + is), gis->merchant_url, gis->webhook_id, &get_webhook_cb, diff --git a/src/testing/testing_api_cmd_get_webhooks.c b/src/testing/testing_api_cmd_get_webhooks.c index 536512aa..56bf43e8 100644 --- a/src/testing/testing_api_cmd_get_webhooks.c +++ b/src/testing/testing_api_cmd_get_webhooks.c @@ -71,33 +71,29 @@ struct GetWebhooksState * Callback for a GET /webhooks operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param webhooks_length length of the @a webhooks array - * @param webhooks array of webhooks the requested instance offers + * @param wgr response details */ static void get_webhooks_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - unsigned int webhooks_length, - const struct TALER_MERCHANT_WebhookEntry webhooks[]) + const struct TALER_MERCHANT_WebhooksGetResponse *wgr) { struct GetWebhooksState *gis = cls; gis->igh = NULL; - if (gis->http_status != hr->http_status) + if (gis->http_status != wgr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + wgr->hr.http_status, + (int) wgr->hr.ec, TALER_TESTING_interpreter_get_current_label (gis->is)); TALER_TESTING_interpreter_fail (gis->is); return; } - switch (hr->http_status) + switch (wgr->hr.http_status) { case MHD_HTTP_OK: - if (webhooks_length != gis->webhooks_length) + if (wgr->details.ok.webhooks_length != gis->webhooks_length) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Length of webhooks found does not match\n"); @@ -113,7 +109,7 @@ get_webhooks_cb (void *cls, gis->webhooks[i]); { - const char **webhook_id; + const char *webhook_id; if (GNUNET_OK != TALER_TESTING_get_trait_webhook_id (webhook_cmd, @@ -124,8 +120,8 @@ get_webhooks_cb (void *cls, TALER_TESTING_interpreter_fail (gis->is); return; } - if (0 != strcmp (webhooks[i].webhook_id, - *webhook_id)) + if (0 != strcmp (wgr->details.ok.webhooks[i].webhook_id, + webhook_id)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Webhook id does not match\n"); @@ -143,8 +139,8 @@ get_webhooks_cb (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u (%d).\n", - hr->http_status, - hr->ec); + wgr->hr.http_status, + wgr->hr.ec); } TALER_TESTING_interpreter_next (gis->is); } @@ -166,10 +162,11 @@ get_webhooks_run (void *cls, struct GetWebhooksState *gis = cls; gis->is = is; - gis->igh = TALER_MERCHANT_webhooks_get (is->ctx, - gis->merchant_url, - &get_webhooks_cb, - gis); + gis->igh = TALER_MERCHANT_webhooks_get ( + TALER_TESTING_interpreter_get_context (is), + gis->merchant_url, + &get_webhooks_cb, + gis); GNUNET_assert (NULL != gis->igh); } diff --git a/src/testing/testing_api_cmd_instance_auth.c b/src/testing/testing_api_cmd_instance_auth.c index f9597464..58f6f9c9 100644 --- a/src/testing/testing_api_cmd_instance_auth.c +++ b/src/testing/testing_api_cmd_instance_auth.c @@ -125,12 +125,13 @@ auth_instance_run (void *cls, struct AuthInstanceState *ais = cls; ais->is = is; - ais->iaph = TALER_MERCHANT_instance_auth_post (is->ctx, - ais->merchant_url, - ais->instance_id, - ais->auth_token, - &auth_instance_cb, - ais); + ais->iaph = TALER_MERCHANT_instance_auth_post ( + TALER_TESTING_interpreter_get_context (is), + ais->merchant_url, + ais->instance_id, + ais->auth_token, + &auth_instance_cb, + ais); GNUNET_assert (NULL != ais->iaph); } @@ -175,7 +176,7 @@ auth_instance_traits (void *cls, { struct AuthInstanceState *ais = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_auth_token (&ais->auth_token), + TALER_TESTING_make_trait_auth_token (ais->auth_token), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_kyc_get.c b/src/testing/testing_api_cmd_kyc_get.c index 96d0b58c..a8f29264 100644 --- a/src/testing/testing_api_cmd_kyc_get.c +++ b/src/testing/testing_api_cmd_kyc_get.c @@ -73,6 +73,11 @@ struct KycGetState unsigned int expected_http_status; /** + * Expected AML state. + */ + enum TALER_AmlDecisionState expected_aml_state; + + /** * Interpreter state. */ struct TALER_TESTING_Interpreter *is; @@ -126,7 +131,21 @@ kyc_get_cb (void *cls, switch (kr->hr.http_status) { case MHD_HTTP_ACCEPTED: - if (0 != kr->details.kyc_status.pending_kycs_length) + + if ( ( (TALER_AML_NORMAL != cs->expected_aml_state) && + (0 == kr->details.kyc_status.pending_kycs_length) ) || + ( (0 < kr->details.kyc_status.pending_kycs_length) && + (cs->expected_aml_state != + kr->details.kyc_status.pending_kycs[0].aml_status) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected AML state %u, got %u/%u\n", + cs->expected_aml_state, + kr->details.kyc_status.pending_kycs[0].aml_status, + kr->details.kyc_status.pending_kycs_length); + TALER_TESTING_FAIL (cs->is); + } + for (unsigned int i = 0; i<kr->details.kyc_status.pending_kycs_length; i++) { const char *url; const char *tok; @@ -136,7 +155,21 @@ kyc_get_cb (void *cls, const char *nq; size_t toklen; - url = kr->details.kyc_status.pending_kycs[0].kyc_url; + url = kr->details.kyc_status.pending_kycs[i].kyc_url; + if (NULL == url) + { + /* AML status here must be either pending or frozne */ + switch (kr->details.kyc_status.pending_kycs[i].aml_status) + { + case TALER_AML_NORMAL: + TALER_TESTING_FAIL (cs->is); + case TALER_AML_PENDING: + continue; + case TALER_AML_FROZEN: + continue; + } + TALER_TESTING_FAIL (cs->is); + } tok = strstr (url, "&redirect_uri="); if (NULL == tok) TALER_TESTING_FAIL (cs->is); @@ -159,18 +192,18 @@ kyc_get_cb (void *cls, GNUNET_free (dec); TALER_TESTING_FAIL (cs->is); } - eq += strlen ("/kyc-proof/"); - eq = strstr (eq, "state="); + GNUNET_free (dec); + + eq = strstr (url, "&state="); if (NULL == eq) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received unexpected 'state'-less KYC URL `%s' (%s)\n", url, dec); - GNUNET_free (dec); TALER_TESTING_FAIL (cs->is); } - eq += strlen ("state="); + eq += strlen ("&state="); nq = strchr (eq, '&'); if (NULL == nq) nq = eq + strlen (eq); @@ -183,11 +216,9 @@ kyc_get_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received unexpected KYC URL `%s' (%s) - no h_payto in state\n", url, - dec); - GNUNET_free (dec); + eq); TALER_TESTING_FAIL (cs->is); } - GNUNET_free (dec); } break; } @@ -234,7 +265,8 @@ kyc_get_run (void *cls, } } if (NULL == cs->instance_id) - cs->kgh = TALER_MERCHANT_kyc_get (is->ctx, + cs->kgh = TALER_MERCHANT_kyc_get (TALER_TESTING_interpreter_get_context ( + is), cs->merchant_url, h_wire, cs->exchange_url, @@ -242,14 +274,15 @@ kyc_get_run (void *cls, &kyc_get_cb, cs); else - cs->kgh = TALER_MERCHANT_management_kyc_get (is->ctx, - cs->merchant_url, - cs->instance_id, - h_wire, - cs->exchange_url, - GNUNET_TIME_UNIT_ZERO, - &kyc_get_cb, - cs); + cs->kgh = TALER_MERCHANT_management_kyc_get ( + TALER_TESTING_interpreter_get_context (is), + cs->merchant_url, + cs->instance_id, + h_wire, + cs->exchange_url, + GNUNET_TIME_UNIT_ZERO, + &kyc_get_cb, + cs); GNUNET_assert (NULL != cs->kgh); } @@ -285,12 +318,14 @@ kyc_get_traits (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_kyc_get (const char *label, - const char *merchant_url, - const char *instance_id, - const char *h_wire_ref, - const char *exchange_url, - unsigned int expected_http_status) +TALER_TESTING_cmd_merchant_kyc_get ( + const char *label, + const char *merchant_url, + const char *instance_id, + const char *h_wire_ref, + const char *exchange_url, + unsigned int expected_http_status, + enum TALER_AmlDecisionState expected_aml_state) { struct KycGetState *cs; @@ -300,6 +335,7 @@ TALER_TESTING_cmd_merchant_kyc_get (const char *label, cs->h_wire_ref = h_wire_ref; cs->exchange_url = exchange_url; cs->expected_http_status = expected_http_status; + cs->expected_aml_state = expected_aml_state; { struct TALER_TESTING_Command cmd = { .cls = cs, diff --git a/src/testing/testing_api_cmd_lock_product.c b/src/testing/testing_api_cmd_lock_product.c index da9e8832..5703b9c2 100644 --- a/src/testing/testing_api_cmd_lock_product.c +++ b/src/testing/testing_api_cmd_lock_product.c @@ -135,14 +135,15 @@ lock_product_run (void *cls, struct LockProductState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_product_lock (is->ctx, - pis->merchant_url, - pis->product_id, - pis->uuid, - pis->duration, - pis->quantity, - &lock_product_cb, - pis); + pis->iph = TALER_MERCHANT_product_lock ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->product_id, + pis->uuid, + pis->duration, + pis->quantity, + &lock_product_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -188,8 +189,7 @@ lock_product_traits (void *cls, { struct LockProductState *lps = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_lock_uuid ( - (const char **) &lps->uuid), + TALER_TESTING_make_trait_lock_uuid (lps->uuid), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_merchant_get_order.c b/src/testing/testing_api_cmd_merchant_get_order.c index 467b6d61..6301c9f6 100644 --- a/src/testing/testing_api_cmd_merchant_get_order.c +++ b/src/testing/testing_api_cmd_merchant_get_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2024 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 @@ -94,6 +94,28 @@ struct MerchantGetOrderState unsigned int forgets_length; /** + * Set to a session ID, if we should pass one as part + * of the request. + */ + const char *session_id; + + /** + * Set if we expect to be referred to another equivalent order which was + * already paid by the wallet under this @e session_id. + */ + const char *repurchase_order_ref; + + /** + * Expected minimum age. + */ + unsigned int expected_min_age; + + /** + * True if we should pass the 'allow_refunded_for_repurchase' flag. + */ + bool allow_refunded_for_repurchase; + + /** * Whether the order was refunded or not. */ bool refunded; @@ -156,20 +178,33 @@ merchant_get_order_cb ( switch (osr->hr.http_status) { case MHD_HTTP_OK: - if (gos->osc != osr->details.success.status) + if (gos->osc != osr->details.ok.status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Order paid does not match\n"); + "Order paid does not match: %d vs %d\n", + gos->osc, + osr->details.ok.status); TALER_TESTING_interpreter_fail (gos->is); return; } - switch (osr->details.success.status) + switch (osr->details.ok.status) { case TALER_MERCHANT_OSC_PAID: { const struct TALER_TESTING_Command *order_cmd; struct TALER_Amount refunded_total; + if ( (0 != gos->expected_min_age) && + (gos->expected_min_age != + json_integer_value ( + json_object_get ( + osr->details.ok.details.paid.contract_terms, + "minimum_age"))) ) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (gos->is); + return; + } order_cmd = TALER_TESTING_interpreter_lookup_command ( gos->is, gos->order_reference); @@ -212,7 +247,7 @@ merchant_get_order_cb ( for (unsigned int j = 0; j < *paths_length; ++j) { - const char **path; + const char *path; int res = GNUNET_OK; if (GNUNET_OK != @@ -228,7 +263,7 @@ merchant_get_order_cb ( GNUNET_assert (GNUNET_OK == TALER_JSON_expand_path (ct, - *path, + path, &apply_forget, &res)); GNUNET_assert (GNUNET_OK == res); @@ -236,7 +271,7 @@ merchant_get_order_cb ( } if (1 != json_equal (ct, - osr->details.success.details.paid.contract_terms)) + osr->details.ok.details.paid.contract_terms)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order contract terms do not match\n"); @@ -246,14 +281,14 @@ merchant_get_order_cb ( json_decref (ct); } - if (gos->wired != osr->details.success.details.paid.wired) + if (gos->wired != osr->details.ok.details.paid.wired) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order wired does not match\n"); TALER_TESTING_interpreter_fail (gos->is); return; } - if (gos->transfers_length != osr->details.success.details.paid.wts_len) + if (gos->transfers_length != osr->details.ok.details.paid.wts_len) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Number of transfers found does not match\n"); @@ -280,7 +315,7 @@ merchant_get_order_cb ( return; } if (0 != GNUNET_memcmp (wtid, - &osr->details.success.details.paid.wts[i]. + &osr->details.ok.details.paid.wts[i]. wtid)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -290,7 +325,7 @@ merchant_get_order_cb ( } } { - const char **exchange_url; + const char *exchange_url; if (GNUNET_OK != TALER_TESTING_get_trait_exchange_url (transfer_cmd, @@ -301,9 +336,9 @@ merchant_get_order_cb ( TALER_TESTING_interpreter_fail (gos->is); return; } - if (0 != strcmp (*exchange_url, - osr->details.success.details.paid.wts[i]. - exchange_url)) + if (0 != strcmp ( + exchange_url, + osr->details.ok.details.paid.wts[i].exchange_url)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Wire transfer exchange url does not match\n"); @@ -311,48 +346,8 @@ merchant_get_order_cb ( return; } } - { - struct TALER_Amount transfer_total; - const struct TALER_Amount *transfer_amount; - const struct TALER_Amount *transfer_fee; - - if ((GNUNET_OK != - TALER_TESTING_get_trait_amount (transfer_cmd, - &transfer_amount)) || - (GNUNET_OK != - TALER_TESTING_get_trait_fee (transfer_cmd, - &transfer_fee))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not fetch wire transfer amount/fee\n"); - TALER_TESTING_interpreter_fail (gos->is); - return; - } - if (0 > TALER_amount_add (&transfer_total, - transfer_amount, - transfer_fee)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not total wire transfer\n"); - TALER_TESTING_interpreter_fail (gos->is); - return; - } - if ((GNUNET_OK != - TALER_amount_cmp_currency ( - &transfer_total, - &osr->details.success.details.paid.wts[i].total_amount)) || - (0 != TALER_amount_cmp ( - &transfer_total, - &osr->details.success.details.paid.wts[i].total_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Wire transfer total does not match\n"); - TALER_TESTING_interpreter_fail (gos->is); - return; - } - } } - if (gos->refunded != osr->details.success.details.paid.refunded) + if (gos->refunded != osr->details.ok.details.paid.refunded) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order refunded does not match\n"); @@ -360,7 +355,7 @@ merchant_get_order_cb ( return; } if (gos->refunds_length != - osr->details.success.details.paid.refunds_len) + osr->details.ok.details.paid.refunds_len) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Number of refunds found does not match\n"); @@ -371,7 +366,7 @@ merchant_get_order_cb ( GNUNET_assert ( GNUNET_OK == TALER_amount_set_zero ( - osr->details.success.details.paid.refund_amount.currency, + osr->details.ok.details.paid.refund_amount.currency, &refunded_total)); for (unsigned int i = 0; i < gos->refunds_length; ++i) { @@ -383,7 +378,7 @@ merchant_get_order_cb ( { const struct TALER_Amount *expected_amount; struct TALER_Amount *amount_found = - &osr->details.success.details.paid.refunds[i].refund_amount; + &osr->details.ok.details.paid.refunds[i].refund_amount; if (GNUNET_OK != TALER_TESTING_get_trait_amount (refund_cmd, @@ -410,7 +405,7 @@ merchant_get_order_cb ( } } { - const char **expected_reason; + const char *expected_reason; if (GNUNET_OK != TALER_TESTING_get_trait_reason (refund_cmd, @@ -421,9 +416,10 @@ merchant_get_order_cb ( TALER_TESTING_interpreter_fail (gos->is); return; } - if (0 != strcmp ( - *expected_reason, - osr->details.success.details.paid.refunds[i].reason)) + if (0 != + strcmp ( + expected_reason, + osr->details.ok.details.paid.refunds[i].reason)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Refund reason does not match\n"); @@ -433,7 +429,7 @@ merchant_get_order_cb ( } } - if (gos->wired != osr->details.success.details.paid.wired) + if (gos->wired != osr->details.ok.details.paid.wired) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order wired does not match\n"); @@ -444,22 +440,58 @@ merchant_get_order_cb ( break; case TALER_MERCHANT_OSC_CLAIMED: /* FIXME: Check contract terms... */ + if ( (0 != gos->expected_min_age) && + (gos->expected_min_age != + json_integer_value ( + json_object_get ( + osr->details.ok.details.claimed.contract_terms, + "minimum_age"))) ) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (gos->is); + return; + } break; case TALER_MERCHANT_OSC_UNPAID: { struct TALER_MERCHANT_PayUriData pud; const struct TALER_TESTING_Command *order_cmd; - const char **order_id; + const char *order_id; const struct TALER_ClaimTokenP *claim_token; + if (NULL != gos->repurchase_order_ref) + { + const struct TALER_TESTING_Command *rep_cmd; + const char *rep_id; + const char *ri; + + rep_cmd = TALER_TESTING_interpreter_lookup_command ( + gos->is, + gos->repurchase_order_ref); + if (GNUNET_OK != + TALER_TESTING_get_trait_order_id (rep_cmd, + &rep_id)) + { + TALER_TESTING_FAIL (gos->is); + } + ri = osr->details.ok.details.unpaid.already_paid_order_id; + if ( (NULL == ri) || + (0 != + strcmp (ri, + rep_id)) ) + { + TALER_TESTING_FAIL (gos->is); + } + } + if (GNUNET_OK != TALER_MERCHANT_parse_pay_uri ( - osr->details.success.details.unpaid.taler_pay_uri, + osr->details.ok.details.unpaid.taler_pay_uri, &pud)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Taler pay uri `%s' is malformed\n", - osr->details.success.details.unpaid.taler_pay_uri); + osr->details.ok.details.unpaid.taler_pay_uri); TALER_TESTING_interpreter_fail (gos->is); return; } @@ -484,37 +516,21 @@ merchant_get_order_cb ( TALER_TESTING_FAIL (gos->is); } { - char *port; char *host; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (gos->is->cfg, - "merchant", - "PORT", - &port)) - { - /* How did we get here without a configured port? */ - GNUNET_break (0); - TALER_TESTING_interpreter_fail (gos->is); - TALER_MERCHANT_parse_pay_uri_free (&pud); - return; - } - GNUNET_asprintf (&host, - "localhost:%s", - port); - GNUNET_free (port); + host = TALER_MERCHANT_TESTING_extract_host (gos->merchant_url); if ((0 != strcmp (host, pud.merchant_host)) || (NULL != pud.merchant_prefix_path) || - (0 != strcmp (*order_id, + (0 != strcmp (order_id, pud.order_id)) || (NULL != pud.ssid)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order pay uri `%s' does not match, wanted %s/%s\n", - osr->details.success.details.unpaid.taler_pay_uri, + osr->details.ok.details.unpaid.taler_pay_uri, host, - *order_id); + order_id); TALER_TESTING_interpreter_fail (gos->is); TALER_MERCHANT_parse_pay_uri_free (&pud); GNUNET_free (host); @@ -568,7 +584,7 @@ merchant_get_order_run (void *cls, { struct MerchantGetOrderState *gos = cls; const struct TALER_TESTING_Command *order_cmd; - const char **order_id; + const char *order_id; const struct TALER_PrivateContractHashP *h_contract; order_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -586,14 +602,14 @@ merchant_get_order_run (void *cls, TALER_TESTING_FAIL (is); gos->is = is; - gos->ogh = TALER_MERCHANT_merchant_order_get (is->ctx, - gos->merchant_url, - *order_id, - NULL, - true, - GNUNET_TIME_UNIT_ZERO, - &merchant_get_order_cb, - gos); + gos->ogh = TALER_MERCHANT_merchant_order_get ( + TALER_TESTING_interpreter_get_context (is), + gos->merchant_url, + order_id, + gos->session_id, + GNUNET_TIME_UNIT_ZERO, + &merchant_get_order_cb, + gos); } @@ -612,7 +628,7 @@ merchant_get_order_cleanup (void *cls, if (NULL != gos->ogh) { - TALER_LOG_WARNING ("Get tip operation did not complete\n"); + TALER_LOG_WARNING ("Get order operation did not complete\n"); TALER_MERCHANT_merchant_order_get_cancel (gos->ogh); } GNUNET_array_grow (gos->transfers, @@ -629,13 +645,14 @@ merchant_get_order_cleanup (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_order (const char *label, - const char *merchant_url, - const char *order_reference, - enum TALER_MERCHANT_OrderStatusCode osc, - bool refunded, - unsigned int http_status, - ...) +TALER_TESTING_cmd_merchant_get_order ( + const char *label, + const char *merchant_url, + const char *order_reference, + enum TALER_MERCHANT_OrderStatusCode osc, + bool refunded, + unsigned int http_status, + ...) { struct MerchantGetOrderState *gos; @@ -673,16 +690,17 @@ TALER_TESTING_cmd_merchant_get_order (const char *label, struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_order2 (const char *label, - const char *merchant_url, - const char *order_reference, - enum TALER_MERCHANT_OrderStatusCode osc, - bool wired, - const char **transfers, - bool refunded, - const char **refunds, - const char **forgets, - unsigned int http_status) +TALER_TESTING_cmd_merchant_get_order2 ( + const char *label, + const char *merchant_url, + const char *order_reference, + enum TALER_MERCHANT_OrderStatusCode osc, + bool wired, + const char **transfers, + bool refunded, + const char **refunds, + const char **forgets, + unsigned int http_status) { struct MerchantGetOrderState *gos; @@ -733,6 +751,68 @@ TALER_TESTING_cmd_merchant_get_order2 (const char *label, } +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_order3 ( + const char *label, + const char *merchant_url, + const char *order_reference, + enum TALER_MERCHANT_OrderStatusCode osc, + const char *session_id, + const char *repurchase_order_ref, + unsigned int expected_http_status) +{ + struct MerchantGetOrderState *gos; + + gos = GNUNET_new (struct MerchantGetOrderState); + gos->merchant_url = merchant_url; + gos->order_reference = order_reference; + gos->osc = osc; + gos->session_id = session_id; + gos->repurchase_order_ref = repurchase_order_ref; + gos->http_status = expected_http_status; + { + struct TALER_TESTING_Command cmd = { + .cls = gos, + .label = label, + .run = &merchant_get_order_run, + .cleanup = &merchant_get_order_cleanup + }; + + return cmd; + } +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_get_order4 ( + const char *label, + const char *merchant_url, + const char *order_reference, + enum TALER_MERCHANT_OrderStatusCode osc, + uint32_t expected_min_age, + unsigned int expected_http_status) +{ + struct MerchantGetOrderState *gos; + + gos = GNUNET_new (struct MerchantGetOrderState); + gos->merchant_url = merchant_url; + gos->order_reference = order_reference; + gos->osc = osc; + gos->expected_min_age = expected_min_age; + gos->http_status = expected_http_status; + { + struct TALER_TESTING_Command cmd = { + .cls = gos, + .label = label, + .run = &merchant_get_order_run, + .cleanup = &merchant_get_order_cleanup + }; + + return cmd; + } +} + + struct MerchantPollOrderConcludeState { /** @@ -907,14 +987,14 @@ merchant_poll_order_start_run (void *cls, = GNUNET_TIME_absolute_add (GNUNET_TIME_relative_to_absolute (pos->timeout), GNUNET_TIME_UNIT_SECONDS); pos->is = is; - pos->ogh = TALER_MERCHANT_merchant_order_get (is->ctx, - pos->merchant_url, - pos->order_id, - NULL, - false, - pos->timeout, - &merchant_poll_order_cb, - pos); + pos->ogh = TALER_MERCHANT_merchant_order_get ( + TALER_TESTING_interpreter_get_context (is), + pos->merchant_url, + pos->order_id, + NULL, + pos->timeout, + &merchant_poll_order_cb, + pos); GNUNET_assert (NULL != pos->ogh); /* We CONTINUE to run the interpreter while the long-polled command completes asynchronously! */ @@ -947,14 +1027,12 @@ merchant_poll_order_start_cleanup (void *cls, } -/** - * Start a long poll for GET /private/orders/$ORDER_ID. - */ struct TALER_TESTING_Command -TALER_TESTING_cmd_poll_order_start (const char *label, - const char *merchant_url, - const char *order_id, - struct GNUNET_TIME_Relative timeout) +TALER_TESTING_cmd_poll_order_start ( + const char *label, + const char *merchant_url, + const char *order_id, + struct GNUNET_TIME_Relative timeout) { struct MerchantPollOrderStartState *pos; @@ -1042,9 +1120,6 @@ merchant_poll_order_conclude_cleanup (void *cls, } -/** - * Complete a long poll for GET /private/orders/$ORDER_ID. - */ struct TALER_TESTING_Command TALER_TESTING_cmd_poll_order_conclude (const char *label, unsigned int http_status, diff --git a/src/testing/testing_api_cmd_merchant_get_tip.c b/src/testing/testing_api_cmd_merchant_get_tip.c deleted file mode 100644 index a8e7a67e..00000000 --- a/src/testing/testing_api_cmd_merchant_get_tip.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - 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_merchant_get_tip.c - * @brief command to test GET /private/tips/$TIP_ID. - * @author Jonathan Buchanan - */ -#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 for a GET /private/tips/$TIP_ID CMD. - */ -struct MerchantTipGetState -{ - - /** - * The merchant base URL. - */ - const char *merchant_url; - - /** - * Expected HTTP response code for this CMD. - */ - unsigned int http_status; - - /** - * Whether to fetch and compare pickups. - */ - bool fetch_pickups; - - /** - * The length of @e pickups. - */ - unsigned int pickups_length; - - /** - * The NULL-terminated list of pickup commands associated with the tip. - */ - const char **pickups; - - /** - * The handle to the current GET /tips/$TIP_ID request. - */ - struct TALER_MERCHANT_TipMerchantGetHandle *tgh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Reference to a command that created a tip. - */ - const char *tip_reference; -}; - - -/** - * Callback for a GET /private/tips/$TIP_ID operation. - * - * @param cls closure for this function - * @param tsr response - */ -static void -merchant_get_tip_cb (void *cls, - const struct TALER_MERCHANT_TipStatusResponse *tsr) -{ - struct MerchantTipGetState *gts = cls; - const struct TALER_TESTING_Command *authorize_cmd; - struct TALER_Amount expected_total_picked_up; - - authorize_cmd = TALER_TESTING_interpreter_lookup_command (gts->is, - gts->tip_reference); - - gts->tgh = NULL; - if (gts->http_status != tsr->hr.http_status) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u (%d) to command %s\n", - tsr->hr.http_status, - (int) tsr->hr.ec, - TALER_TESTING_interpreter_get_current_label (gts->is)); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - switch (tsr->hr.http_status) - { - case MHD_HTTP_OK: - { - const struct TALER_Amount *initial_amount; - - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (tsr->details.success.total_picked_up.currency, - &expected_total_picked_up)); - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (authorize_cmd, - &initial_amount)) - TALER_TESTING_FAIL (gts->is); - if ((GNUNET_OK != - TALER_amount_cmp_currency (&tsr->details.success.total_authorized, - initial_amount)) || - (0 != TALER_amount_cmp (&tsr->details.success.total_authorized, - initial_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip authorized amount does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - { - const char **justification; - - if (GNUNET_OK != - TALER_TESTING_get_trait_reason (authorize_cmd, - &justification)) - TALER_TESTING_FAIL (gts->is); - if (0 != strcmp (tsr->details.success.reason, - *justification)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip authorized reason does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - { - const struct GNUNET_TIME_Timestamp *tip_expiration; - - if (GNUNET_OK != - TALER_TESTING_get_trait_timestamp (authorize_cmd, - 0, - &tip_expiration)) - TALER_TESTING_FAIL (gts->is); - if (GNUNET_TIME_timestamp_cmp (*tip_expiration, - !=, - tsr->details.success.expiration)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip authorized expiration does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - if (tsr->details.success.pickups_length != gts->pickups_length) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Length of pickups array does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - { - for (unsigned int i = 0; i < gts->pickups_length; ++i) - { - const struct TALER_TESTING_Command *pickup_cmd; - - pickup_cmd = TALER_TESTING_interpreter_lookup_command (gts->is, - gts->pickups[i]); - { - const uint32_t *num_planchets; - - if (GNUNET_OK != - TALER_TESTING_get_trait_num_planchets (pickup_cmd, - &num_planchets)) - TALER_TESTING_FAIL (gts->is); - - if (*num_planchets != tsr->details.success.pickups[i].num_planchets) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Pickup planchet count does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - { - const struct TALER_Amount *total; - - if (GNUNET_OK != - TALER_TESTING_get_trait_amount (pickup_cmd, - &total)) - TALER_TESTING_FAIL (gts->is); - - if ( (GNUNET_OK != - TALER_amount_cmp_currency (total, - &tsr->details.success.pickups[i].requested_amount)) || - (0 != TALER_amount_cmp (total, - &tsr->details.success.pickups[i].requested_amount))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Pickup planchet sum does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - GNUNET_assert (0 < TALER_amount_add (&expected_total_picked_up, - &expected_total_picked_up, - total)); - } - } - if ( (GNUNET_OK != - TALER_amount_cmp_currency (&expected_total_picked_up, - &tsr->details.success.total_picked_up)) || - (0 != - TALER_amount_cmp (&expected_total_picked_up, - &tsr->details.success.total_picked_up)) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip picked up amount does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (gts->is); -} - - -/** - * Run the "GET tip" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -merchant_get_tip_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct MerchantTipGetState *tgs = cls; - const struct TALER_TESTING_Command *tip_cmd; - const struct TALER_TipIdentifierP *tip_id; - - tip_cmd = TALER_TESTING_interpreter_lookup_command (is, - tgs->tip_reference); - - if (GNUNET_OK != - TALER_TESTING_get_trait_tip_id (tip_cmd, - &tip_id)) - TALER_TESTING_FAIL (is); - - tgs->is = is; - tgs->tgh = TALER_MERCHANT_merchant_tip_get (is->ctx, - tgs->merchant_url, - tip_id, - NULL, - GNUNET_TIME_UNIT_ZERO, - tgs->fetch_pickups, - &merchant_get_tip_cb, - tgs); - GNUNET_assert (NULL != tgs->tgh); -} - - -/** -* Free the state of a "GET tip" CMD, and possibly -* cancel a pending operation thereof. -* -* @param cls closure. -* @param cmd command being run. -*/ -static void -merchant_get_tip_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct MerchantTipGetState *tgs = cls; - - if (NULL != tgs->tgh) - { - TALER_LOG_WARNING ("Get tip operation did not complete\n"); - TALER_MERCHANT_merchant_tip_get_cancel (tgs->tgh); - } - GNUNET_array_grow (tgs->pickups, - tgs->pickups_length, - 0); - GNUNET_free (tgs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_tip (const char *label, - const char *merchant_url, - const char *tip_reference, - unsigned int http_status) -{ - struct MerchantTipGetState *tgs; - - tgs = GNUNET_new (struct MerchantTipGetState); - tgs->merchant_url = merchant_url; - tgs->tip_reference = tip_reference; - tgs->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = tgs, - .label = label, - .run = &merchant_get_tip_run, - .cleanup = &merchant_get_tip_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_get_tip_with_pickups (const char *label, - const char *merchant_url, - const char *tip_reference, - unsigned int http_status, - ...) -{ - struct MerchantTipGetState *tgs; - - tgs = GNUNET_new (struct MerchantTipGetState); - tgs->merchant_url = merchant_url; - tgs->tip_reference = tip_reference; - tgs->fetch_pickups = true; - tgs->http_status = http_status; - { - const char *clabel; - va_list ap; - - va_start (ap, http_status); - while (NULL != (clabel = va_arg (ap, const char *))) - { - GNUNET_array_append (tgs->pickups, - tgs->pickups_length, - clabel); - } - va_end (ap); - } - { - struct TALER_TESTING_Command cmd = { - .cls = tgs, - .label = label, - .run = &merchant_get_tip_run, - .cleanup = &merchant_get_tip_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_merchant_get_tip.c */ diff --git a/src/testing/testing_api_cmd_patch_instance.c b/src/testing/testing_api_cmd_patch_instance.c index 348163af..cef38bec 100644 --- a/src/testing/testing_api_cmd_patch_instance.c +++ b/src/testing/testing_api_cmd_patch_instance.c @@ -55,16 +55,6 @@ struct PatchInstanceState const char *instance_id; /** - * Length of the @payto_uris array - */ - unsigned int payto_uris_length; - - /** - * Array of payto URIs. - */ - const char **payto_uris; - - /** * Name of the instance. */ const char *name; @@ -80,19 +70,9 @@ struct PatchInstanceState json_t *jurisdiction; /** - * Wire fee to use. - */ - struct TALER_Amount default_max_wire_fee; - - /** - * Amortization to use. - */ - uint32_t default_wire_fee_amortization; - - /** - * Deposit fee ceiling to use. + * Use STEFAN curve? */ - struct TALER_Amount default_max_deposit_fee; + bool use_stefan; /** * Wire transfer delay to use. @@ -173,21 +153,19 @@ patch_instance_run (void *cls, struct PatchInstanceState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_instance_patch (is->ctx, - pis->merchant_url, - pis->instance_id, - pis->payto_uris_length, - pis->payto_uris, - pis->name, - pis->address, - pis->jurisdiction, - &pis->default_max_wire_fee, - pis->default_wire_fee_amortization, - &pis->default_max_deposit_fee, - pis->default_wire_transfer_delay, - pis->default_pay_delay, - &patch_instance_cb, - pis); + pis->iph = TALER_MERCHANT_instance_patch ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->instance_id, + pis->name, + TALER_KYCLOGIC_KYC_UT_BUSINESS, + pis->address, + pis->jurisdiction, + pis->use_stefan, + pis->default_wire_transfer_delay, + pis->default_pay_delay, + &patch_instance_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -202,44 +180,23 @@ patch_instance_run (void *cls, * @param index index number of the object to extract. * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue patch_instance_traits (void *cls, const void **ret, const char *trait, unsigned int index) { struct PatchInstanceState *pis = cls; - #define NUM_TRAITS (pis->payto_uris_length) + 11 - struct TALER_TESTING_Trait traits[NUM_TRAITS]; - traits[0] = - TALER_TESTING_make_trait_instance_name (&pis->name); - traits[1] = - TALER_TESTING_make_trait_instance_id (&pis->instance_id); - traits[2] = - TALER_TESTING_make_trait_address (pis->address); - traits[3] = - TALER_TESTING_make_trait_jurisdiction (pis->jurisdiction); - traits[4] = - TALER_TESTING_make_trait_max_wire_fee (&pis->default_max_wire_fee); - traits[5] = - TALER_TESTING_make_trait_wire_fee_amortization ( - &pis->default_wire_fee_amortization); - traits[6] = - TALER_TESTING_make_trait_max_deposit_fee (&pis->default_max_deposit_fee); - traits[7] = - TALER_TESTING_make_trait_wire_delay (&pis->default_wire_transfer_delay); - traits[8] = - TALER_TESTING_make_trait_pay_delay (&pis->default_pay_delay); - traits[9] = - TALER_TESTING_make_trait_payto_length (&pis->payto_uris_length); - traits[NUM_TRAITS - 1] = - TALER_TESTING_trait_end (); - for (unsigned int i = 0; i < pis->payto_uris_length; ++i) - { - traits[10 + i] = - TALER_TESTING_make_trait_payto_uris (i, - &pis->payto_uris[i]); - } + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_instance_name (pis->name), + TALER_TESTING_make_trait_instance_id (pis->instance_id), + TALER_TESTING_make_trait_address (pis->address), + TALER_TESTING_make_trait_jurisdiction (pis->jurisdiction), + TALER_TESTING_make_trait_use_stefan (&pis->use_stefan), + TALER_TESTING_make_trait_wire_delay (&pis->default_wire_transfer_delay), + TALER_TESTING_make_trait_pay_delay (&pis->default_pay_delay), + TALER_TESTING_trait_end () + }; return TALER_TESTING_get_trait (traits, ret, @@ -267,9 +224,8 @@ patch_instance_cleanup (void *cls, "PATCH /instance/$ID operation did not complete\n"); TALER_MERCHANT_instance_patch_cancel (pis->iph); } - json_decref (pis->address); json_decref (pis->jurisdiction); - GNUNET_free (pis->payto_uris); + json_decref (pis->address); GNUNET_free (pis); } @@ -279,14 +235,10 @@ TALER_TESTING_cmd_merchant_patch_instance ( const char *label, const char *merchant_url, const char *instance_id, - unsigned int payto_uris_length, - const char *payto_uris[], const char *name, json_t *address, json_t *jurisdiction, - const char *default_max_wire_fee, - uint32_t default_wire_fee_amortization, - const char *default_max_deposit_fee, + bool use_stefan, struct GNUNET_TIME_Relative default_wire_transfer_delay, struct GNUNET_TIME_Relative default_pay_delay, unsigned int http_status) @@ -297,22 +249,10 @@ TALER_TESTING_cmd_merchant_patch_instance ( pis->merchant_url = merchant_url; pis->instance_id = instance_id; pis->http_status = http_status; - pis->payto_uris_length = payto_uris_length; - pis->payto_uris = GNUNET_new_array (payto_uris_length, - const char *); - memcpy (pis->payto_uris, - payto_uris, - sizeof (const char *) * payto_uris_length); pis->name = name; pis->address = address; /* ownership transfer! */ pis->jurisdiction = jurisdiction; /* ownership transfer! */ - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (default_max_wire_fee, - &pis->default_max_wire_fee)); - pis->default_wire_fee_amortization = default_wire_fee_amortization; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (default_max_deposit_fee, - &pis->default_max_deposit_fee)); + pis->use_stefan = use_stefan; pis->default_wire_transfer_delay = default_wire_transfer_delay; pis->default_pay_delay = default_pay_delay; { diff --git a/src/testing/testing_api_cmd_patch_otp_device.c b/src/testing/testing_api_cmd_patch_otp_device.c new file mode 100644 index 00000000..ce263908 --- /dev/null +++ b/src/testing/testing_api_cmd_patch_otp_device.c @@ -0,0 +1,250 @@ +/* + This file is part of TALER + Copyright (C) 2022 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_patch_otp_device.c + * @brief command to test PATCH /otp-device + * @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 "PATCH /otp-device" CMD. + */ +struct PatchOtpDeviceState +{ + + /** + * Handle for a "GET otp_device" request. + */ + struct TALER_MERCHANT_OtpDevicePatchHandle *iph; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the otp_device to run GET for. + */ + const char *otp_device_id; + + /** + * description of the otp_device + */ + const char *otp_device_description; + + /** + * base64-encoded key + */ + char *otp_key; + + /** + * Algorithm used by the OTP device + */ + enum TALER_MerchantConfirmationAlgorithm otp_alg; + + /** + * Counter of the device (if in counter mode). + */ + uint64_t otp_ctr; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a PATCH /otp-devices/$ID operation. + * + * @param cls closure for this function + * @param hr response being processed + */ +static void +patch_otp_device_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct PatchOtpDeviceState *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_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u for PATCH /otp-devices/ID.\n", + hr->http_status); + } + TALER_TESTING_interpreter_next (pis->is); +} + + +/** + * Run the "PATCH /otp-devices/$ID" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +patch_otp_device_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PatchOtpDeviceState *pis = cls; + + pis->is = is; + pis->iph = TALER_MERCHANT_otp_device_patch ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->otp_device_id, + pis->otp_device_description, + pis->otp_key, + pis->otp_alg, + pis->otp_ctr, + &patch_otp_device_cb, + pis); + GNUNET_assert (NULL != pis->iph); +} + + +/** + * Offers information from the PATCH /otp-devices 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 enum GNUNET_GenericReturnValue +patch_otp_device_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct PatchOtpDeviceState *pts = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_otp_device_description (pts->otp_device_description), + TALER_TESTING_make_trait_otp_key (pts->otp_key), + TALER_TESTING_make_trait_otp_alg (&pts->otp_alg), + TALER_TESTING_make_trait_otp_id (pts->otp_device_id), + TALER_TESTING_trait_end (), + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +/** + * Free the state of a "GET otp_device" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +patch_otp_device_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PatchOtpDeviceState *pis = cls; + + if (NULL != pis->iph) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "PATCH /otp-devices/$ID operation did not complete\n"); + TALER_MERCHANT_otp_device_patch_cancel (pis->iph); + } + GNUNET_free (pis->otp_key); + GNUNET_free (pis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_patch_otp_device ( + const char *label, + const char *merchant_url, + const char *otp_device_id, + const char *otp_device_description, + const char *otp_key, + const enum TALER_MerchantConfirmationAlgorithm otp_alg, + uint64_t otp_ctr, + unsigned int http_status) +{ + struct PatchOtpDeviceState *pis; + + pis = GNUNET_new (struct PatchOtpDeviceState); + pis->merchant_url = merchant_url; + pis->otp_device_id = otp_device_id; + pis->http_status = http_status; + pis->otp_device_description = otp_device_description; + pis->otp_key = GNUNET_strdup (otp_key); + pis->otp_alg = otp_alg; + pis->otp_ctr = otp_ctr; + { + struct TALER_TESTING_Command cmd = { + .cls = pis, + .label = label, + .run = &patch_otp_device_run, + .cleanup = &patch_otp_device_cleanup, + .traits = &patch_otp_device_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_patch_otp_device.c */ diff --git a/src/testing/testing_api_cmd_patch_product.c b/src/testing/testing_api_cmd_patch_product.c index 4715ce1f..702ef85a 100644 --- a/src/testing/testing_api_cmd_patch_product.c +++ b/src/testing/testing_api_cmd_patch_product.c @@ -172,21 +172,22 @@ patch_product_run (void *cls, struct PatchProductState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_product_patch (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->total_lost, - pis->address, - pis->next_restock, - &patch_product_cb, - pis); + pis->iph = TALER_MERCHANT_product_patch ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->product_id, + pis->description, + pis->description_i18n, + pis->unit, + &pis->price, + pis->image, + pis->taxes, + pis->total_stock, + pis->total_lost, + pis->address, + pis->next_restock, + &patch_product_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -209,18 +210,17 @@ patch_product_traits (void *cls, { struct PatchProductState *pps = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_product_description (&pps->description), + 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_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_product_image (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_make_trait_product_id (pps->product_id), TALER_TESTING_trait_end (), }; diff --git a/src/testing/testing_api_cmd_patch_template.c b/src/testing/testing_api_cmd_patch_template.c index a2a75b89..8ad9d9dc 100644 --- a/src/testing/testing_api_cmd_patch_template.c +++ b/src/testing/testing_api_cmd_patch_template.c @@ -60,9 +60,9 @@ struct PatchTemplateState const char *template_description; /** - * base64-encoded template image + * OTP device ID */ - char *image; + char *otp_id; /** * Contract of the company @@ -85,7 +85,7 @@ struct PatchTemplateState */ static void patch_template_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) + const struct TALER_MERCHANT_HttpResponse *hr) { struct PatchTemplateState *pis = cls; @@ -131,20 +131,21 @@ patch_template_cb (void *cls, */ static void patch_template_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) { struct PatchTemplateState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_template_patch (is->ctx, - pis->merchant_url, - pis->template_id, - pis->template_description, - pis->image, - pis->template_contract, - &patch_template_cb, - pis); + pis->iph = TALER_MERCHANT_template_patch ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->template_id, + pis->template_description, + pis->otp_id, + pis->template_contract, + &patch_template_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -161,17 +162,16 @@ patch_template_run (void *cls, */ static enum GNUNET_GenericReturnValue patch_template_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) + const void **ret, + const char *trait, + unsigned int index) { struct PatchTemplateState *pts = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_template_description (&pts->template_description), - TALER_TESTING_make_trait_template_image ( - (const char **) &pts->image), + TALER_TESTING_make_trait_template_description (pts->template_description), + TALER_TESTING_make_trait_otp_id (pts->otp_id), TALER_TESTING_make_trait_template_contract (pts->template_contract), - TALER_TESTING_make_trait_template_id (&pts->template_id), + TALER_TESTING_make_trait_template_id (pts->template_id), TALER_TESTING_trait_end (), }; @@ -191,7 +191,7 @@ patch_template_traits (void *cls, */ static void patch_template_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) + const struct TALER_TESTING_Command *cmd) { struct PatchTemplateState *pis = cls; @@ -201,7 +201,7 @@ patch_template_cleanup (void *cls, "PATCH /templates/$ID operation did not complete\n"); TALER_MERCHANT_template_patch_cancel (pis->iph); } - GNUNET_free (pis->image); + GNUNET_free (pis->otp_id); json_decref (pis->template_contract); GNUNET_free (pis); } @@ -213,7 +213,7 @@ TALER_TESTING_cmd_merchant_patch_template ( const char *merchant_url, const char *template_id, const char *template_description, - const char *image, + const char *otp_id, json_t *template_contract, unsigned int http_status) { @@ -224,7 +224,7 @@ TALER_TESTING_cmd_merchant_patch_template ( pis->template_id = template_id; pis->http_status = http_status; pis->template_description = template_description; - pis->image = (NULL == image) ? NULL : GNUNET_strdup (image); + pis->otp_id = (NULL == otp_id) ? NULL : GNUNET_strdup (otp_id); pis->template_contract = template_contract; /* ownership taken */ { struct TALER_TESTING_Command cmd = { diff --git a/src/testing/testing_api_cmd_patch_webhook.c b/src/testing/testing_api_cmd_patch_webhook.c index a2fea433..0b066371 100644 --- a/src/testing/testing_api_cmd_patch_webhook.c +++ b/src/testing/testing_api_cmd_patch_webhook.c @@ -147,16 +147,17 @@ patch_webhook_run (void *cls, struct PatchWebhookState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_webhook_patch (is->ctx, - pis->merchant_url, - pis->webhook_id, - pis->event_type, - pis->url, - pis->http_method, - pis->header_template, - pis->body_template, - &patch_webhook_cb, - pis); + pis->iph = TALER_MERCHANT_webhook_patch ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->webhook_id, + pis->event_type, + pis->url, + pis->http_method, + pis->header_template, + pis->body_template, + &patch_webhook_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -179,12 +180,12 @@ patch_webhook_traits (void *cls, { struct PatchWebhookState *pws = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_event_type (&pws->event_type), - TALER_TESTING_make_trait_url (&pws->url), - TALER_TESTING_make_trait_http_method (&pws->http_method), - TALER_TESTING_make_trait_header_template (&pws->header_template), - TALER_TESTING_make_trait_body_template (&pws->body_template), - TALER_TESTING_make_trait_webhook_id (&pws->webhook_id), + TALER_TESTING_make_trait_event_type (pws->event_type), + TALER_TESTING_make_trait_url (pws->url), + TALER_TESTING_make_trait_http_method (pws->http_method), + TALER_TESTING_make_trait_header_template (pws->header_template), + TALER_TESTING_make_trait_body_template (pws->body_template), + TALER_TESTING_make_trait_webhook_id (pws->webhook_id), TALER_TESTING_trait_end (), }; @@ -239,8 +240,8 @@ TALER_TESTING_cmd_merchant_patch_webhook ( pis->event_type = event_type; pis->url = url; pis->http_method = http_method; - pis->header_template = header_template; - pis->body_template = body_template; + pis->header_template = (NULL == header_template) ? NULL : header_template; + pis->body_template = (NULL == body_template) ? NULL : body_template; { struct TALER_TESTING_Command cmd = { .cls = pis, diff --git a/src/testing/testing_api_cmd_pay_order.c b/src/testing/testing_api_cmd_pay_order.c index cd589965..0b84c8a6 100644 --- a/src/testing/testing_api_cmd_pay_order.c +++ b/src/testing/testing_api_cmd_pay_order.c @@ -68,6 +68,11 @@ struct PayState const char *merchant_url; /** + * Total amount to be paid. + */ + struct TALER_Amount total_amount; + + /** * Amount to be paid, plus the deposit fee. */ const char *amount_with_fee; @@ -91,6 +96,17 @@ struct PayState * The session for which the payment is made. */ const char *session_id; + + /** + * base64-encoded key + */ + const char *pos_key; + + /** + * Option that add amount of the order + */ + enum TALER_MerchantConfirmationAlgorithm pos_alg; + }; @@ -117,6 +133,14 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, const char *amount_without_fee) { char *token; + struct TALER_EXCHANGE_Keys *keys; + + keys = TALER_TESTING_get_keys (is); + if (NULL == keys) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } for (token = strtok (coins, ";"); NULL != token; @@ -127,7 +151,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, unsigned int ci; struct TALER_MERCHANT_PayCoin *icoin; const struct TALER_EXCHANGE_DenomPublicKey *dpk; - const char **exchange_url; + const char *exchange_url; /* Token syntax is "LABEL[/NUMBER]" */ ctok = strchr (token, '/'); @@ -194,7 +218,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, icoin->h_age_commitment = h_age_commitment; } GNUNET_assert (NULL != (dpk = - TALER_TESTING_find_pk (is->keys, + TALER_TESTING_find_pk (keys, &icoin->denom_value, false))); @@ -205,7 +229,7 @@ build_coins (struct TALER_MERCHANT_PayCoin **pc, GNUNET_assert (GNUNET_OK == TALER_TESTING_get_trait_exchange_url (coin_cmd, &exchange_url)); - icoin->exchange_url = *exchange_url; + icoin->exchange_url = exchange_url; } return GNUNET_OK; @@ -238,7 +262,43 @@ pay_cb (void *cls, } if (MHD_HTTP_OK == pr->hr.http_status) { - ps->merchant_sig = pr->details.success.merchant_sig; + ps->merchant_sig = pr->details.ok.merchant_sig; + if (NULL != ps->pos_key) + { + char *pc; + bool found = false; + + if (NULL == pr->details.ok.pos_confirmation) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (ps->is); + return; + } + pc = TALER_build_pos_confirmation (ps->pos_key, + ps->pos_alg, + &ps->total_amount, + GNUNET_TIME_timestamp_get ()); + /* Check if *any* of our TOTP codes overlaps + with any of the returned TOTP codes. */ + for (const char *tok = strtok (pc, "\n"); + NULL != tok; + tok = strtok (NULL, "\n")) + { + if (NULL != strstr (pr->details.ok.pos_confirmation, + tok)) + { + found = true; + break; + } + } + GNUNET_free (pc); + if (! found) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (ps->is); + return; + } + } } TALER_TESTING_interpreter_next (ps->is); } @@ -266,13 +326,13 @@ pay_run (void *cls, struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantWireHashP h_wire; const struct TALER_PrivateContractHashP *h_proposal; - struct TALER_Amount total_amount; struct TALER_Amount max_fee; - const char *error_name; - unsigned int error_line; + const char *error_name = NULL; + unsigned int error_line = 0; struct TALER_MERCHANT_PayCoin *pay_coins; unsigned int npay_coins; const struct TALER_MerchantSignatureP *merchant_sig; + const enum TALER_MerchantConfirmationAlgorithm *alg_ptr; ps->is = is; proposal_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -286,6 +346,17 @@ pay_run (void *cls, TALER_TESTING_get_trait_contract_terms (proposal_cmd, &contract_terms)) TALER_TESTING_FAIL (is); + if (NULL == contract_terms) + TALER_TESTING_FAIL (is); + if (GNUNET_OK != + TALER_TESTING_get_trait_otp_key (proposal_cmd, + &ps->pos_key)) + ps->pos_key = NULL; + if ( (GNUNET_OK == + TALER_TESTING_get_trait_otp_alg (proposal_cmd, + &alg_ptr)) && + (NULL != alg_ptr) ) + ps->pos_alg = *alg_ptr; { /* Get information that needs to be put verbatim in the * deposit permission */ @@ -303,7 +374,7 @@ pay_run (void *cls, GNUNET_JSON_spec_fixed_auto ("h_wire", &h_wire), TALER_JSON_spec_amount_any ("amount", - &total_amount), + &ps->total_amount), TALER_JSON_spec_amount_any ("max_fee", &max_fee), /* FIXME oec: parse minimum age, use data later? */ @@ -362,11 +433,13 @@ pay_run (void *cls, &h_proposal)) TALER_TESTING_FAIL (is); ps->h_contract_terms = *h_proposal; - ps->oph = TALER_MERCHANT_order_pay (is->ctx, + ps->oph = TALER_MERCHANT_order_pay (TALER_TESTING_interpreter_get_context ( + is), ps->merchant_url, ps->session_id, h_proposal, - &total_amount, + NULL, + &ps->total_amount, &max_fee, &merchant_pub, merchant_sig, @@ -429,7 +502,7 @@ pay_traits (void *cls, { struct PayState *ps = cls; - const char **order_id; + const char *order_id; const struct TALER_TESTING_Command *proposal_cmd; const struct TALER_MerchantPublicKeyP *merchant_pub; @@ -465,13 +538,15 @@ pay_traits (void *cls, &amount_with_fee)); { struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_proposal_reference (&ps->proposal_reference), + TALER_TESTING_make_trait_proposal_reference (ps->proposal_reference), TALER_TESTING_make_trait_coin_reference (0, - &ps->coin_reference), + ps->coin_reference), TALER_TESTING_make_trait_order_id (order_id), TALER_TESTING_make_trait_merchant_pub (merchant_pub), TALER_TESTING_make_trait_merchant_sig (&ps->merchant_sig), TALER_TESTING_make_trait_amount (&amount_with_fee), + TALER_TESTING_make_trait_otp_key (ps->pos_key), + TALER_TESTING_make_trait_otp_alg (&ps->pos_alg), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_post_account.c b/src/testing/testing_api_cmd_post_account.c new file mode 100644 index 00000000..8ddad94c --- /dev/null +++ b/src/testing/testing_api_cmd_post_account.c @@ -0,0 +1,250 @@ +/* + This file is part of TALER + Copyright (C) 2023 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_account.c + * @brief command to test POST /account + * @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 /account" CMD. + */ +struct PostAccountState +{ + + /** + * Handle for a "GET product" request. + */ + struct TALER_MERCHANT_AccountsPostHandle *aph; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * Wire hash of the created account, set on success. + */ + struct TALER_MerchantWireHashP h_wire; + + /** + * RFC 8905 URI for the account to create. + */ + char *payto_uri; + + /** + * Credit facade URL for the account to create. + */ + char *credit_facade_url; + + /** + * Credit facade credentials for the account to create. + */ + json_t *credit_facade_credentials; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a POST /account operation. + * + * @param cls closure for this function + * @param apr response being processed + */ +static void +post_account_cb (void *cls, + const struct TALER_MERCHANT_AccountsPostResponse *apr) +{ + struct PostAccountState *pas = cls; + + pas->aph = NULL; + if (pas->http_status != apr->hr.http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u (%d) to command %s\n", + apr->hr.http_status, + (int) apr->hr.ec, + TALER_TESTING_interpreter_get_current_label (pas->is)); + TALER_TESTING_interpreter_fail (pas->is); + return; + } + switch (apr->hr.http_status) + { + case MHD_HTTP_OK: + pas->h_wire = apr->details.ok.h_wire; + 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 /account.\n", + apr->hr.http_status); + } + TALER_TESTING_interpreter_next (pas->is); +} + + +/** + * Run the "POST /account" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +post_account_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PostAccountState *pas = cls; + + pas->is = is; + pas->aph = TALER_MERCHANT_accounts_post ( + TALER_TESTING_interpreter_get_context (is), + pas->merchant_url, + pas->payto_uri, + pas->credit_facade_url, + pas->credit_facade_credentials, + &post_account_cb, + pas); + GNUNET_assert (NULL != pas->aph); +} + + +/** + * Offers information from the POST /account 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 enum GNUNET_GenericReturnValue +post_account_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct PostAccountState *pps = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_h_wires ( + 0, + &pps->h_wire), + TALER_TESTING_make_trait_payto_uris ( + 0, + pps->payto_uri), + TALER_TESTING_make_trait_merchant_base_url ( + pps->merchant_url), + 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_account_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PostAccountState *pas = cls; + + if (NULL != pas->aph) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "POST /account operation did not complete\n"); + TALER_MERCHANT_accounts_post_cancel (pas->aph); + } + GNUNET_free (pas->payto_uri); + GNUNET_free (pas->credit_facade_url); + json_decref (pas->credit_facade_credentials); + GNUNET_free (pas); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_account ( + const char *label, + const char *merchant_url, + const char *payto_uri, + const char *credit_facade_url, + const json_t *credit_facade_credentials, + unsigned int http_status) +{ + struct PostAccountState *pas; + + pas = GNUNET_new (struct PostAccountState); + pas->merchant_url = merchant_url; + pas->payto_uri = GNUNET_strdup (payto_uri); + if (NULL != credit_facade_url) + pas->credit_facade_url = GNUNET_strdup (credit_facade_url); + if (NULL != credit_facade_credentials) + pas->credit_facade_credentials + = json_incref ((json_t *) credit_facade_credentials); + pas->http_status = http_status; + { + struct TALER_TESTING_Command cmd = { + .cls = pas, + .label = label, + .run = &post_account_run, + .cleanup = &post_account_cleanup, + .traits = &post_account_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_post_account.c */ diff --git a/src/testing/testing_api_cmd_post_instances.c b/src/testing/testing_api_cmd_post_instances.c index 4d1f0d26..0d081026 100644 --- a/src/testing/testing_api_cmd_post_instances.c +++ b/src/testing/testing_api_cmd_post_instances.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -55,16 +55,6 @@ struct PostInstancesState const char *instance_id; /** - * Length of the @payto_uris array - */ - unsigned int payto_uris_length; - - /** - * Array of payto URIs. - */ - const char **payto_uris; - - /** * Name of the instance. */ const char *name; @@ -85,19 +75,9 @@ struct PostInstancesState const char *auth_token; /** - * Wire fee to use. - */ - struct TALER_Amount default_max_wire_fee; - - /** - * Amortization to use. + * Use STEFAN curves? */ - uint32_t default_wire_fee_amortization; - - /** - * Deposit fee ceiling to use. - */ - struct TALER_Amount default_max_deposit_fee; + bool use_stefan; /** * Wire transfer delay to use. @@ -132,11 +112,10 @@ post_instances_cb (void *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_unexpected_status_with_body (pis->is, + hr->http_status, + pis->http_status, + hr->reply); TALER_TESTING_interpreter_fail (pis->is); return; } @@ -180,22 +159,20 @@ post_instances_run (void *cls, struct PostInstancesState *pis = cls; pis->is = is; - pis->iph = TALER_MERCHANT_instances_post (is->ctx, - pis->merchant_url, - pis->instance_id, - pis->payto_uris_length, - pis->payto_uris, - pis->name, - pis->address, - pis->jurisdiction, - &pis->default_max_wire_fee, - pis->default_wire_fee_amortization, - &pis->default_max_deposit_fee, - pis->default_wire_transfer_delay, - pis->default_pay_delay, - pis->auth_token, - &post_instances_cb, - pis); + pis->iph = TALER_MERCHANT_instances_post ( + TALER_TESTING_interpreter_get_context (is), + pis->merchant_url, + pis->instance_id, + pis->name, + TALER_KYCLOGIC_KYC_UT_BUSINESS, + pis->address, + pis->jurisdiction, + pis->use_stefan, + pis->default_wire_transfer_delay, + pis->default_pay_delay, + pis->auth_token, + &post_instances_cb, + pis); if (NULL == pis->iph) { GNUNET_break (0); @@ -222,37 +199,16 @@ post_instances_traits (void *cls, unsigned int index) { struct PostInstancesState *pis = cls; - #define NUM_TRAITS (pis->payto_uris_length) + 11 - struct TALER_TESTING_Trait traits[NUM_TRAITS]; - traits[0] = - TALER_TESTING_make_trait_instance_name (&pis->name); - traits[1] = - TALER_TESTING_make_trait_instance_id (&pis->instance_id); - traits[2] = - TALER_TESTING_make_trait_address (pis->address); - traits[3] = - TALER_TESTING_make_trait_jurisdiction (pis->jurisdiction); - traits[4] = - TALER_TESTING_make_trait_max_wire_fee (&pis->default_max_wire_fee); - traits[5] = - TALER_TESTING_make_trait_wire_fee_amortization ( - &pis->default_wire_fee_amortization); - traits[6] = - TALER_TESTING_make_trait_max_deposit_fee (&pis->default_max_deposit_fee); - traits[7] = - TALER_TESTING_make_trait_wire_delay (&pis->default_wire_transfer_delay); - traits[8] = - TALER_TESTING_make_trait_pay_delay (&pis->default_pay_delay); - traits[9] = - TALER_TESTING_make_trait_payto_length (&pis->payto_uris_length); - traits[NUM_TRAITS - 1] = - TALER_TESTING_trait_end (); - for (unsigned int i = 0; i < pis->payto_uris_length; ++i) - { - traits[10 + i] = - TALER_TESTING_make_trait_payto_uris (i, - &pis->payto_uris[i]); - } + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_instance_name (pis->name), + TALER_TESTING_make_trait_instance_id (pis->instance_id), + TALER_TESTING_make_trait_address (pis->address), + TALER_TESTING_make_trait_jurisdiction (pis->jurisdiction), + TALER_TESTING_make_trait_use_stefan (&pis->use_stefan), + TALER_TESTING_make_trait_wire_delay (&pis->default_wire_transfer_delay), + TALER_TESTING_make_trait_pay_delay (&pis->default_pay_delay), + TALER_TESTING_trait_end () + }; return TALER_TESTING_get_trait (traits, ret, @@ -282,7 +238,6 @@ post_instances_cleanup (void *cls, } json_decref (pis->address); json_decref (pis->jurisdiction); - GNUNET_free (pis->payto_uris); GNUNET_free (pis); } @@ -292,14 +247,10 @@ TALER_TESTING_cmd_merchant_post_instances2 ( const char *label, const char *merchant_url, const char *instance_id, - unsigned int payto_uris_length, - const char *payto_uris[], const char *name, json_t *address, json_t *jurisdiction, - const char *default_max_wire_fee, - uint32_t default_wire_fee_amortization, - const char *default_max_deposit_fee, + bool use_stefan, struct GNUNET_TIME_Relative default_wire_transfer_delay, struct GNUNET_TIME_Relative default_pay_delay, const char *auth_token, @@ -311,22 +262,10 @@ TALER_TESTING_cmd_merchant_post_instances2 ( pis->merchant_url = merchant_url; pis->instance_id = instance_id; pis->http_status = http_status; - pis->payto_uris_length = payto_uris_length; - pis->payto_uris = GNUNET_new_array (payto_uris_length, - const char *); - memcpy (pis->payto_uris, - payto_uris, - sizeof (const char *) * payto_uris_length); pis->name = name; pis->address = address; /* ownership transfer! */ pis->jurisdiction = jurisdiction; /* ownership transfer! */ - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (default_max_wire_fee, - &pis->default_max_wire_fee)); - pis->default_wire_fee_amortization = default_wire_fee_amortization; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (default_max_deposit_fee, - &pis->default_max_deposit_fee)); + pis->use_stefan = use_stefan; pis->default_wire_transfer_delay = default_wire_transfer_delay; pis->default_pay_delay = default_pay_delay; pis->auth_token = auth_token; @@ -348,34 +287,16 @@ struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_post_instances (const char *label, const char *merchant_url, const char *instance_id, - const char *payto_uri, - const char *currency, unsigned int http_status) { - const char *payto_uris[] = { - payto_uri - }; - struct TALER_Amount default_max_fee; - const char *default_max_fee_s; - - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (currency, - &default_max_fee)); - default_max_fee.value = 1; - default_max_fee_s = TALER_amount2s (&default_max_fee); - return TALER_TESTING_cmd_merchant_post_instances2 ( label, merchant_url, instance_id, - 1, - payto_uris, instance_id, json_pack ("{s:s}", "city", "shopcity"), json_pack ("{s:s}", "city", "lawyercity"), - default_max_fee_s, - 10, - default_max_fee_s, + true, GNUNET_TIME_UNIT_ZERO, /* no wire transfer delay */ GNUNET_TIME_UNIT_MINUTES, NULL, diff --git a/src/testing/testing_api_cmd_post_orders.c b/src/testing/testing_api_cmd_post_orders.c index b818bd8c..8f7bd46d 100644 --- a/src/testing/testing_api_cmd_post_orders.c +++ b/src/testing/testing_api_cmd_post_orders.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2024 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 @@ -24,6 +24,10 @@ */ #include "platform.h" +#include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_time_lib.h> +#include <jansson.h> +#include <stdint.h> #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> #include "taler_merchant_service.h" @@ -46,11 +50,21 @@ struct OrdersState const char *order_id; /** + * Our configuration. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** * The order id we expect the merchant to assign (if not NULL). */ const char *expected_order_id; /** + * Reference to a POST /tokenfamilies command. Can be NULL. + */ + const char *token_family_reference; + + /** * Contract terms obtained from the backend. */ json_t *contract_terms; @@ -61,6 +75,11 @@ struct OrdersState json_t *order_terms; /** + * Choices array with inputs and outputs for v1 order. + */ + json_t *choices; + + /** * Contract terms hash code. */ struct TALER_PrivateContractHashP h_contract_terms; @@ -157,7 +176,7 @@ orders_traits (void *cls, { struct OrdersState *ps = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_order_id (&ps->order_id), + TALER_TESTING_make_trait_order_id (ps->order_id), TALER_TESTING_make_trait_contract_terms (ps->contract_terms), TALER_TESTING_make_trait_order_terms (ps->order_terms), TALER_TESTING_make_trait_h_contract_terms (&ps->h_contract_terms), @@ -181,43 +200,41 @@ orders_traits (void *cls, * 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 + * @param ocr response we got */ 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) + const struct TALER_MERCHANT_OrderClaimResponse *ocr) { struct OrdersState *ps = 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), + &ps->merchant_pub), GNUNET_JSON_spec_end () }; ps->och = NULL; - if (ps->http_status != hr->http_status) + if (ps->http_status != ocr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expected status %u, got %u\n", ps->http_status, - hr->http_status); + ocr->hr.http_status); TALER_TESTING_FAIL (ps->is); } - - ps->contract_terms = json_deep_copy (contract_terms); - ps->h_contract_terms = *hash; - ps->merchant_sig = *sig; + if (MHD_HTTP_OK != ocr->hr.http_status) + { + TALER_TESTING_interpreter_next (ps->is); + return; + } + ps->contract_terms = json_deep_copy ( + (json_t *) ocr->details.ok.contract_terms); + ps->h_contract_terms = ocr->details.ok.h_contract_terms; + ps->merchant_sig = ocr->details.ok.sig; if (GNUNET_OK != - GNUNET_JSON_parse (contract_terms, + GNUNET_JSON_parse (ps->contract_terms, spec, &error_name, &error_line)) @@ -236,16 +253,14 @@ orders_claim_cb (void *cls, free (log); TALER_TESTING_FAIL (ps->is); } - ps->merchant_pub = merchant_pub; TALER_TESTING_interpreter_next (ps->is); } /** - * Callback that processes the response following a - * POST /orders. NOTE: no contract terms are included - * here; they need to be taken via the "orders lookup" - * method. + * Callback that processes the response following a POST /orders. NOTE: no + * contract terms are included here; they need to be taken via the "orders + * lookup" method. * * @param cls closure. * @param por details about the response @@ -259,20 +274,19 @@ order_cb (void *cls, ps->po = NULL; if (ps->http_status != por->hr.http_status) { - TALER_LOG_ERROR ("Given vs expected: %u(%d) vs %u\n", - por->hr.http_status, - (int) por->hr.ec, - ps->http_status); - TALER_TESTING_FAIL (ps->is); + TALER_TESTING_unexpected_status_with_body (ps->is, + por->hr.http_status, + ps->http_status, + por->hr.reply); + TALER_TESTING_interpreter_fail (ps->is); + return; } - if (0 == ps->http_status) + switch (por->hr.http_status) { + case 0: TALER_LOG_DEBUG ("/orders, expected 0 status code\n"); TALER_TESTING_interpreter_next (ps->is); return; - } - switch (por->hr.http_status) - { case MHD_HTTP_OK: if (NULL != por->details.ok.token) ps->claim_token = *por->details.ok.token; @@ -351,13 +365,14 @@ order_cb (void *cls, return; } if (NULL == - (ps->och = TALER_MERCHANT_order_claim (ps->is->ctx, - ps->merchant_url, - ps->order_id, - &ps->nonce, - &ps->claim_token, - &orders_claim_cb, - ps))) + (ps->och = TALER_MERCHANT_order_claim ( + TALER_TESTING_interpreter_get_context (ps->is), + ps->merchant_url, + ps->order_id, + &ps->nonce, + &ps->claim_token, + &orders_claim_cb, + ps))) TALER_TESTING_FAIL (ps->is); } @@ -383,7 +398,7 @@ orders_run (void *cls, struct GNUNET_TIME_Absolute now; char *order_id; - now = GNUNET_TIME_absolute_get_monotonic (is->cfg); + now = GNUNET_TIME_absolute_get_monotonic (ps->cfg); order_id = GNUNET_STRINGS_data_to_string_alloc ( &now, sizeof (now)); @@ -396,7 +411,8 @@ orders_run (void *cls, GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &ps->nonce, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); - ps->po = TALER_MERCHANT_orders_post (is->ctx, + ps->po = TALER_MERCHANT_orders_post (TALER_TESTING_interpreter_get_context ( + is), ps->merchant_url, ps->order_terms, GNUNET_TIME_UNIT_ZERO, @@ -456,7 +472,7 @@ orders_run2 (void *cls, struct GNUNET_TIME_Absolute now; char *order_id; - now = GNUNET_TIME_absolute_get_monotonic (is->cfg); + now = GNUNET_TIME_absolute_get_monotonic (ps->cfg); order_id = GNUNET_STRINGS_data_to_string_alloc ( &now.abs_value_us, sizeof (now.abs_value_us)); @@ -514,7 +530,7 @@ orders_run2 (void *cls, token = strtok (NULL, ";")) { const struct TALER_TESTING_Command *lock_cmd; - const char **uuid; + const char *uuid; lock_cmd = TALER_TESTING_interpreter_lookup_command ( is, @@ -532,20 +548,22 @@ orders_run2 (void *cls, GNUNET_array_append (locks, locks_length, - *uuid); + uuid); } - ps->po = TALER_MERCHANT_orders_post2 (is->ctx, - ps->merchant_url, - order, - GNUNET_TIME_UNIT_ZERO, - ps->payment_target, - products_length, - products, - locks_length, - locks, - ps->make_claim_token, - &order_cb, - ps); + ps->po = TALER_MERCHANT_orders_post2 ( + TALER_TESTING_interpreter_get_context ( + is), + ps->merchant_url, + order, + GNUNET_TIME_UNIT_ZERO, + ps->payment_target, + products_length, + products, + locks_length, + locks, + ps->make_claim_token, + &order_cb, + ps); GNUNET_free (products_string); GNUNET_free (locks_string); GNUNET_array_grow (products, @@ -559,6 +577,118 @@ orders_run2 (void *cls, /** + * Constructs the json for a the choices of an order request. + * + * @param slug the name of the order to add, can be NULL. + * @param valid_after valid_after date for the input and output token. + * @param[out] choices where to write the json string. + */ +static void +make_choices_json ( + const char *input_slug, + const char *output_slug, + uint16_t input_count, + uint16_t output_count, + struct GNUNET_TIME_Timestamp input_valid_after, + struct GNUNET_TIME_Timestamp output_valid_after, + json_t **choices) +{ + json_t *c; + + c = json_pack("[{s:o, s:o}]", + "inputs", json_pack("[{s:s, s:i, s:s, s:o}]", + "kind", "token", + "count", input_count, + "token_family_slug", input_slug, + "valid_after", GNUNET_JSON_from_timestamp(input_valid_after)), + "outputs", json_pack("[{s:s, s:i, s:s, s:o}]", + "kind", "token", + "count", output_count, + "token_family_slug", output_slug, + "valid_after", GNUNET_JSON_from_timestamp(output_valid_after))); + + *choices = c; +} + + +/** + * Run a "orders" CMD. + * + * @param cls closure. + * @param cmd command currently being run. + * @param is interpreter state. + */ +static void +orders_run3 (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct OrdersState *ps = cls; + struct GNUNET_TIME_Absolute now; + const char *slug; + + ps->is = is; + now = GNUNET_TIME_absolute_get_monotonic (ps->cfg); + if (NULL == json_object_get (ps->order_terms, + "order_id")) + { + char *order_id; + + order_id = GNUNET_STRINGS_data_to_string_alloc ( + &now, + sizeof (now)); + GNUNET_assert (0 == + json_object_set_new (ps->order_terms, + "order_id", + json_string (order_id))); + GNUNET_free (order_id); + } + + { + const struct TALER_TESTING_Command *token_family_cmd; + token_family_cmd = + TALER_TESTING_interpreter_lookup_command (is, + ps->token_family_reference); + if (NULL == token_family_cmd) + TALER_TESTING_FAIL (is); + if (GNUNET_OK != + TALER_TESTING_get_trait_token_family_slug (token_family_cmd, + &slug)) + TALER_TESTING_FAIL (is); + } + make_choices_json (slug, slug, + 1, 1, + GNUNET_TIME_absolute_to_timestamp(now), + GNUNET_TIME_absolute_to_timestamp(now), + &ps->choices); + + GNUNET_assert (0 == + json_object_set_new (ps->order_terms, + "choices", + ps->choices) + ); + GNUNET_assert (0 == + json_object_set_new (ps->order_terms, + "version", + json_string ("1")) + ); + + + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &ps->nonce, + sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); + ps->po = TALER_MERCHANT_orders_post (TALER_TESTING_interpreter_get_context ( + is), + ps->merchant_url, + ps->order_terms, + GNUNET_TIME_UNIT_ZERO, + &order_cb, + ps); + GNUNET_assert (NULL != ps->po); +} + + +/** * Free the state of a "orders" CMD, and possibly * cancel it if it did not complete. * @@ -647,8 +777,7 @@ make_order_json (const char *order_id, "dummy_array", /* For testing forgetting parts of arrays */ "item", "speakers", "item", "headphones", - "item", "earbuds" - ); + "item", "earbuds"); GNUNET_assert (GNUNET_OK == TALER_JSON_expand_path (contract_terms, "$.dummy_obj", @@ -684,7 +813,6 @@ TALER_TESTING_cmd_merchant_post_orders_no_claim ( ps->http_status = http_status; ps->expected_order_id = order_id; ps->merchant_url = merchant_url; - ps->with_claim = false; { struct TALER_TESTING_Command cmd = { .cls = ps, @@ -702,6 +830,7 @@ TALER_TESTING_cmd_merchant_post_orders_no_claim ( struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_post_orders ( const char *label, + const struct GNUNET_CONFIGURATION_Handle *cfg, const char *merchant_url, unsigned int http_status, const char *order_id, @@ -712,6 +841,7 @@ TALER_TESTING_cmd_merchant_post_orders ( struct OrdersState *ps; ps = GNUNET_new (struct OrdersState); + ps->cfg = cfg; make_order_json (order_id, refund_deadline, pay_deadline, @@ -738,6 +868,7 @@ TALER_TESTING_cmd_merchant_post_orders ( struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_post_orders2 ( const char *label, + const struct GNUNET_CONFIGURATION_Handle *cfg, const char *merchant_url, unsigned int http_status, const char *order_id, @@ -753,6 +884,7 @@ TALER_TESTING_cmd_merchant_post_orders2 ( struct OrdersState *ps; ps = GNUNET_new (struct OrdersState); + ps->cfg = cfg; make_order_json (order_id, refund_deadline, pay_deadline, @@ -779,3 +911,85 @@ TALER_TESTING_cmd_merchant_post_orders2 ( return cmd; } } + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_orders3 ( + const char *label, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *merchant_url, + unsigned int expected_http_status, + const char *order_id, + struct GNUNET_TIME_Timestamp refund_deadline, + struct GNUNET_TIME_Timestamp pay_deadline, + const char *fulfillment_url, + const char *amount) +{ + struct OrdersState *ps; + + ps = GNUNET_new (struct OrdersState); + ps->cfg = cfg; + make_order_json (order_id, + refund_deadline, + pay_deadline, + amount, + &ps->order_terms); + GNUNET_assert (0 == + json_object_set_new (ps->order_terms, + "fulfillment_url", + json_string (fulfillment_url))); + ps->http_status = expected_http_status; + ps->merchant_url = merchant_url; + ps->with_claim = true; + { + struct TALER_TESTING_Command cmd = { + .cls = ps, + .label = label, + .run = &orders_run, + .cleanup = &orders_cleanup, + .traits = &orders_traits + }; + + return cmd; + } +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_orders_choices ( + const char *label, + const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *merchant_url, + unsigned int http_status, + const char *token_family_reference, + const char *order_id, + struct GNUNET_TIME_Timestamp refund_deadline, + struct GNUNET_TIME_Timestamp pay_deadline, + const char *amount) +{ + struct OrdersState *ps; + + ps = GNUNET_new (struct OrdersState); + ps->cfg = cfg; + make_order_json (order_id, + refund_deadline, + pay_deadline, + amount, + &ps->order_terms); + ps->http_status = http_status; + ps->token_family_reference = token_family_reference; + ps->expected_order_id = order_id; + ps->merchant_url = merchant_url; + ps->with_claim = true; + { + struct TALER_TESTING_Command cmd = { + .cls = ps, + .label = label, + .run = &orders_run3, + .cleanup = &orders_cleanup, + .traits = &orders_traits + }; + + return cmd; + } +}
\ No newline at end of file diff --git a/src/testing/testing_api_cmd_post_orders_paid.c b/src/testing/testing_api_cmd_post_orders_paid.c index 6c4e41cd..f4806788 100644 --- a/src/testing/testing_api_cmd_post_orders_paid.c +++ b/src/testing/testing_api_cmd_post_orders_paid.c @@ -55,7 +55,7 @@ struct PostOrdersPaidState const char *pay_reference; /** - * The session to use for the requet. + * The session to use for the request. */ const char *session_id; @@ -71,21 +71,21 @@ struct PostOrdersPaidState * Response from the merchant after POST /paid. * * @param cls pointer to `struct PostOrdersPaidState`. - * @param hr the http response. + * @param opr the response. */ static void paid_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr) + const struct TALER_MERCHANT_OrderPaidResponse *opr) { struct PostOrdersPaidState *ops = cls; ops->oph = NULL; - if (ops->http_status != hr->http_status) + if (ops->http_status != opr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + opr->hr.http_status, + (int) opr->hr.ec, TALER_TESTING_interpreter_get_current_label (ops->is)); TALER_TESTING_FAIL (ops->is); } @@ -110,7 +110,7 @@ paid_run (void *cls, { struct PostOrdersPaidState *ops = cls; const struct TALER_TESTING_Command *pay_cmd; - const char **proposal_reference; + const char *proposal_reference; const struct TALER_TESTING_Command *proposal_cmd; const char *order_id; const struct TALER_PrivateContractHashP *h_contract_terms; @@ -130,7 +130,7 @@ paid_run (void *cls, &proposal_reference)) TALER_TESTING_FAIL (is); proposal_cmd = TALER_TESTING_interpreter_lookup_command (is, - *proposal_reference); + proposal_reference); if (NULL == proposal_cmd) TALER_TESTING_FAIL (is); @@ -179,11 +179,13 @@ paid_run (void *cls, &h_contract_terms)) TALER_TESTING_FAIL (is); - ops->oph = TALER_MERCHANT_order_paid (is->ctx, + ops->oph = TALER_MERCHANT_order_paid (TALER_TESTING_interpreter_get_context ( + is), ops->merchant_url, order_id, ops->session_id, h_contract_terms, + NULL, merchant_sig, &paid_cb, ops); diff --git a/src/testing/testing_api_cmd_post_otp_devices.c b/src/testing/testing_api_cmd_post_otp_devices.c new file mode 100644 index 00000000..09358274 --- /dev/null +++ b/src/testing/testing_api_cmd_post_otp_devices.c @@ -0,0 +1,256 @@ +/* + This file is part of TALER + Copyright (C) 2022 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_otp_devices.c + * @brief command to test POST /otp-devices + * @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 /otp-devices" CMD. + */ +struct PostOtpDevicesState +{ + + /** + * Handle for a "GET otp_device" request. + */ + struct TALER_MERCHANT_OtpDevicesPostHandle *iph; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * ID of the otp_device to run POST for. + */ + const char *otp_device_id; + + /** + * description of the otp_device + */ + const char *otp_device_description; + + /** + * base64-encoded key + */ + char *otp_key; + + /** + * Option that add amount of the order + */ + enum TALER_MerchantConfirmationAlgorithm otp_alg; + + /** + * Counter at the OTP device. + */ + uint64_t otp_ctr; + + /** + * Expected HTTP response code. + */ + unsigned int http_status; + +}; + + +/** + * Callback for a POST /otp-devices operation. + * + * @param cls closure for this function + * @param hr response being processed + */ +static void +post_otp_devices_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct PostOtpDevicesState *tis = cls; + + tis->iph = NULL; + if (tis->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 (tis->is)); + TALER_TESTING_interpreter_fail (tis->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 /otp-devices.\n", + hr->http_status); + } + TALER_TESTING_interpreter_next (tis->is); +} + + +/** + * Run the "POST /otp-devices" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +post_otp_devices_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PostOtpDevicesState *tis = cls; + + tis->is = is; + tis->iph = TALER_MERCHANT_otp_devices_post ( + TALER_TESTING_interpreter_get_context (is), + tis->merchant_url, + tis->otp_device_id, + tis->otp_device_description, + tis->otp_key, + tis->otp_alg, + tis->otp_ctr, + &post_otp_devices_cb, + tis); + if (NULL == tis->iph) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (tis->is); + return; + } +} + + +/** + * Offers information from the POST /otp-devices 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 enum GNUNET_GenericReturnValue +post_otp_devices_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct PostOtpDevicesState *pts = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_otp_device_description (pts->otp_device_description), + TALER_TESTING_make_trait_otp_key (pts->otp_key), + TALER_TESTING_make_trait_otp_alg (&pts->otp_alg), + TALER_TESTING_make_trait_otp_id (pts->otp_device_id), + TALER_TESTING_trait_end (), + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +/** + * Free the state of a "POST otp_device" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +post_otp_devices_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PostOtpDevicesState *tis = cls; + + if (NULL != tis->iph) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "POST /otp-devices operation did not complete\n"); + TALER_MERCHANT_otp_devices_post_cancel (tis->iph); + } + GNUNET_free (tis->otp_key); + GNUNET_free (tis); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_otp_devices ( + const char *label, + const char *merchant_url, + const char *otp_device_id, + const char *otp_device_description, + const char *otp_key, + const enum TALER_MerchantConfirmationAlgorithm otp_alg, + uint64_t otp_ctr, + unsigned int http_status) +{ + struct PostOtpDevicesState *tis; + + tis = GNUNET_new (struct PostOtpDevicesState); + tis->merchant_url = merchant_url; + tis->otp_device_id = otp_device_id; + tis->http_status = http_status; + tis->otp_device_description = otp_device_description; + tis->otp_key = GNUNET_strdup (otp_key); + tis->otp_alg = otp_alg; + tis->otp_ctr = otp_ctr; + { + struct TALER_TESTING_Command cmd = { + .cls = tis, + .label = label, + .run = &post_otp_devices_run, + .cleanup = &post_otp_devices_cleanup, + .traits = &post_otp_devices_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_post_otp_devices.c */ diff --git a/src/testing/testing_api_cmd_post_products.c b/src/testing/testing_api_cmd_post_products.c index be3c3071..c841f1b1 100644 --- a/src/testing/testing_api_cmd_post_products.c +++ b/src/testing/testing_api_cmd_post_products.c @@ -35,7 +35,7 @@ struct PostProductsState { /** - * Handle for a "GET product" request. + * Handle for a "POST /products" request. */ struct TALER_MERCHANT_ProductsPostHandle *iph; @@ -95,6 +95,11 @@ struct PostProductsState json_t *address; /** + * Minimum age requirement to use for the product. + */ + unsigned int minimum_age; + + /** * when the next restocking is expected to happen, 0 for unknown, */ struct GNUNET_TIME_Timestamp next_restock; @@ -168,20 +173,22 @@ post_products_run (void *cls, 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); + pis->iph = TALER_MERCHANT_products_post2 ( + TALER_TESTING_interpreter_get_context (is), + 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, + pis->minimum_age, + &post_products_cb, + pis); GNUNET_assert (NULL != pis->iph); } @@ -196,7 +203,7 @@ post_products_run (void *cls, * @param index index number of the object to extract. * @return #GNUNET_OK on success */ -static int +static enum GNUNET_GenericReturnValue post_products_traits (void *cls, const void **ret, const char *trait, @@ -204,18 +211,17 @@ post_products_traits (void *cls, { struct PostProductsState *pps = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_product_description (&pps->description), + 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_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_product_image (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_make_trait_product_id (pps->product_id), TALER_TESTING_trait_end (), }; @@ -265,6 +271,7 @@ TALER_TESTING_cmd_merchant_post_products2 ( const char *image, json_t *taxes, int64_t total_stock, + uint32_t minimum_age, json_t *address, struct GNUNET_TIME_Timestamp next_restock, unsigned int http_status) @@ -288,6 +295,7 @@ TALER_TESTING_cmd_merchant_post_products2 ( pis->image = GNUNET_strdup (image); pis->taxes = taxes; /* ownership taken */ pis->total_stock = total_stock; + pis->minimum_age = minimum_age; pis->address = address; /* ownership taken */ pis->next_restock = next_restock; { @@ -305,12 +313,13 @@ TALER_TESTING_cmd_merchant_post_products2 ( 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) +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, @@ -322,7 +331,8 @@ TALER_TESTING_cmd_merchant_post_products (const char *label, price, "", json_array (), - 4, + 4, /* total stock */ + 0, /* minimum age */ json_pack ("{s:s}", "street", "my street"), GNUNET_TIME_UNIT_ZERO_TS, http_status); diff --git a/src/testing/testing_api_cmd_post_reserves.c b/src/testing/testing_api_cmd_post_reserves.c deleted file mode 100644 index b2167534..00000000 --- a/src/testing/testing_api_cmd_post_reserves.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - 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_reserves.c - * @brief command to test POST /reserves - * @author Jonathan Buchanan - */ -#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 /reserves" CMD. - */ -struct PostReservesState -{ - /** - * Handle for a "POST /reserves" request. - */ - struct TALER_MERCHANT_PostReservesHandle *prh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Base URL of the merchant - */ - const char *merchant_url; - - /** - * Base URL of the exchange. - */ - const char *exchange_url; - - /** - * Wire method for the reserve. - */ - const char *wire_method; - - /** - * The initial balance of the reserve. - */ - struct TALER_Amount initial_balance; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Public key assigned to the reserve - */ - struct TALER_ReservePublicKeyP reserve_pub; -}; - - -/** - * Callbacks of this type are used to work the result of submitting a - * POST /reserves request to a merchant - * - * @param cls closure - * @param hr HTTP response details - * @param reserve_pub public key of the created reserve, NULL on error - * @param payto_uri where to make the payment to for filling the reserve, NULL on error - */ -static void -post_reserves_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_ReservePublicKeyP *reserve_pub, - const char *payto_uri) -{ - struct PostReservesState *prs = cls; - - prs->prh = NULL; - if (prs->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 (prs->is)); - TALER_TESTING_interpreter_fail (prs->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_OK: - break; - case MHD_HTTP_ACCEPTED: - break; - case MHD_HTTP_UNAUTHORIZED: - break; - case MHD_HTTP_NOT_FOUND: - break; - default: - GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status %u for POST /reserves.\n", - hr->http_status); - } - prs->reserve_pub = *reserve_pub; - TALER_TESTING_interpreter_next (prs->is); -} - - -/** - * Offers information from the POST /reserves 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 enum GNUNET_GenericReturnValue -post_reserves_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct PostReservesState *prs = cls; - struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_reserve_pub (&prs->reserve_pub), - TALER_TESTING_make_trait_amount (&prs->initial_balance), - TALER_TESTING_trait_end (), - }; - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * Run the "POST /reserves" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -post_reserves_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct PostReservesState *prs = cls; - - prs->is = is; - prs->prh = TALER_MERCHANT_reserves_post (is->ctx, - prs->merchant_url, - &prs->initial_balance, - prs->exchange_url, - prs->wire_method, - &post_reserves_cb, - prs); - GNUNET_assert (NULL != prs->prh); -} - - -/** - * Run the fake "POST /reserves" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -post_reserves_fake_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct PostReservesState *prs = cls; - struct TALER_ReservePrivateKeyP reserve_priv; - - prs->is = is; - GNUNET_CRYPTO_eddsa_key_create (&reserve_priv.eddsa_priv); - GNUNET_CRYPTO_eddsa_key_get_public (&reserve_priv.eddsa_priv, - &prs->reserve_pub.eddsa_pub); - - GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:100.00", - &prs->initial_balance)); - TALER_TESTING_interpreter_next (prs->is); -} - - -/** - * Free the state of a "POST /reserves" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -post_reserves_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct PostReservesState *prs = cls; - - if (NULL != prs->prh) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "POST /reserves operation did not complete\n"); - TALER_MERCHANT_reserves_post_cancel (prs->prh); - } - GNUNET_free (prs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_post_reserves (const char *label, - const char *merchant_url, - const char *initial_balance, - const char *exchange_url, - const char *wire_method, - unsigned int http_status) -{ - struct PostReservesState *prs; - - prs = GNUNET_new (struct PostReservesState); - prs->merchant_url = merchant_url; - prs->exchange_url = exchange_url; - prs->wire_method = wire_method; - prs->http_status = http_status; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (initial_balance, - &prs->initial_balance)); - { - struct TALER_TESTING_Command cmd = { - .cls = prs, - .label = label, - .run = &post_reserves_run, - .cleanup = &post_reserves_cleanup, - .traits = &post_reserves_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_merchant_post_reserves_fake (const char *label) -{ - struct PostReservesState *prs; - - prs = GNUNET_new (struct PostReservesState); - { - struct TALER_TESTING_Command cmd = { - .cls = prs, - .label = label, - .run = &post_reserves_fake_run, - .cleanup = &post_reserves_cleanup, - .traits = &post_reserves_traits - }; - - return cmd; - } -} diff --git a/src/testing/testing_api_cmd_post_templates.c b/src/testing/testing_api_cmd_post_templates.c index 32b8d627..f0b6d713 100644 --- a/src/testing/testing_api_cmd_post_templates.c +++ b/src/testing/testing_api_cmd_post_templates.c @@ -60,9 +60,9 @@ struct PostTemplatesState const char *template_description; /** - * base64-encoded product image + * OTP device ID. */ - char *image; + char *otp_id; /** * Contract of the company @@ -92,12 +92,10 @@ post_templates_cb (void *cls, tis->iph = NULL; if (tis->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 (tis->is)); - TALER_TESTING_interpreter_fail (tis->is); + TALER_TESTING_unexpected_status_with_body (tis->is, + hr->http_status, + tis->http_status, + hr->reply); return; } switch (hr->http_status) @@ -110,6 +108,8 @@ 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, @@ -136,14 +136,15 @@ post_templates_run (void *cls, struct PostTemplatesState *tis = cls; tis->is = is; - tis->iph = TALER_MERCHANT_templates_post (is->ctx, - tis->merchant_url, - tis->template_id, - tis->template_description, - tis->image, - tis->template_contract, - &post_templates_cb, - tis); + tis->iph = TALER_MERCHANT_templates_post ( + TALER_TESTING_interpreter_get_context (is), + tis->merchant_url, + tis->template_id, + tis->template_description, + tis->otp_id, + tis->template_contract, + &post_templates_cb, + tis); if (NULL == tis->iph) { GNUNET_break (0); @@ -171,11 +172,10 @@ post_templates_traits (void *cls, { struct PostTemplatesState *pts = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_template_description (&pts->template_description), - TALER_TESTING_make_trait_template_image ( - (const char **) &pts->image), + TALER_TESTING_make_trait_template_description (pts->template_description), + TALER_TESTING_make_trait_otp_id (pts->otp_id), TALER_TESTING_make_trait_template_contract (pts->template_contract), - TALER_TESTING_make_trait_template_id (&pts->template_id), + TALER_TESTING_make_trait_template_id (pts->template_id), TALER_TESTING_trait_end (), }; @@ -205,7 +205,7 @@ post_templates_cleanup (void *cls, "POST /templates operation did not complete\n"); TALER_MERCHANT_templates_post_cancel (tis->iph); } - GNUNET_free (tis->image); + GNUNET_free (tis->otp_id); json_decref (tis->template_contract); GNUNET_free (tis); } @@ -217,7 +217,7 @@ TALER_TESTING_cmd_merchant_post_templates2 ( const char *merchant_url, const char *template_id, const char *template_description, - const char *image, + const char *otp_id, json_t *template_contract, unsigned int http_status) { @@ -231,7 +231,7 @@ TALER_TESTING_cmd_merchant_post_templates2 ( tis->template_id = template_id; tis->http_status = http_status; tis->template_description = template_description; - tis->image = (NULL == image) ? NULL : GNUNET_strdup (image); + tis->otp_id = (NULL == otp_id) ? NULL : GNUNET_strdup (otp_id); tis->template_contract = template_contract; { struct TALER_TESTING_Command cmd = { diff --git a/src/testing/testing_api_cmd_post_tokenfamilies.c b/src/testing/testing_api_cmd_post_tokenfamilies.c new file mode 100644 index 00000000..aafff9ef --- /dev/null +++ b/src/testing/testing_api_cmd_post_tokenfamilies.c @@ -0,0 +1,272 @@ +/* + This file is part of TALER + Copyright (C) 2024 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_tokenfamilies.c + * @brief command to run POST /tokenfamilies + * @author Christian Blättler + */ +#include "platform.h" +#include <gnunet/gnunet_time_lib.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 /tokenfamilies" CMD. + */ +struct PostTokenFamiliesState +{ + + /** + * Expected status code. + */ + unsigned int http_status; + + /** + * Handle for a "POST /tokenfamilies" request. + */ + struct TALER_MERCHANT_TokenFamiliesPostHandle *handle; + + /** + * The interpreter state. + */ + struct TALER_TESTING_Interpreter *is; + + /** + * Base URL of the merchant serving the request. + */ + const char *merchant_url; + + /** + * Slug of the token family. + */ + const char *slug; + + /** + * Name of the token family. + */ + const char *name; + + /** + * Description of the token family. + */ + const char *description; + + /** + * Map from IETF BCP 47 language tags to localized descriptions. + */ + json_t *description_i18n; + + /** + * Start of the validity period. + */ + struct GNUNET_TIME_Timestamp valid_after; + + /** + * End of the validity period. + */ + struct GNUNET_TIME_Timestamp valid_before; + + /** + * Validity duation of issued tokens of this family. + */ + struct GNUNET_TIME_Relative duration; + + /** + * Kind of the token family. "subscription" or "discount". + */ + const char *kind; +}; + + +/** + * Callback for a POST /tokenfamilies operation. + * + * @param cls closure for this function + * @param hr response being processed + */ +static void +post_tokenfamilies_cb (void *cls, + const struct TALER_MERCHANT_HttpResponse *hr) +{ + struct PostTokenFamiliesState *state = cls; + + state->handle = NULL; + if (state->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 (state->is)); + TALER_TESTING_interpreter_fail (state->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; + default: + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Unhandled HTTP status %u for POST /tokenfamilies.\n", + hr->http_status); + } + TALER_TESTING_interpreter_next (state->is); +} + +/** + * Run the "POST /tokenfamilies" CMD. + * + * + * @param cls closure. + * @param cmd command being run now. + * @param is interpreter state. + */ +static void +post_tokenfamilies_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct PostTokenFamiliesState *state = cls; + + state->is = is; + state->handle = TALER_MERCHANT_token_families_post ( + TALER_TESTING_interpreter_get_context (is), + state->merchant_url, + state->slug, + state->name, + state->description, + state->description_i18n, + state->valid_after, + state->valid_before, + state->duration, + state->kind, + &post_tokenfamilies_cb, + state); + GNUNET_assert (NULL != state->handle); +} + +/** + * Offers information from the "POST /tokenfamilies" 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 enum GNUNET_GenericReturnValue +post_tokenfamilies_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct PostTokenFamiliesState *state = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_token_family_slug (state->slug), + TALER_TESTING_make_trait_timestamp (0, + &state->valid_after), + TALER_TESTING_make_trait_timestamp (1, + &state->valid_before), + TALER_TESTING_make_trait_token_family_duration (&state->duration), + TALER_TESTING_make_trait_token_family_kind (state->kind), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + +/** + * Free the state of a "POST /tokenfamilies" CMD, and possibly + * cancel a pending operation thereof. + * + * @param cls closure. + * @param cmd command being run. + */ +static void +post_tokenfamilies_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct PostTokenFamiliesState *state = cls; + + if (NULL != state->handle) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "POST /tokenfamilies operation did not complete\n"); + TALER_MERCHANT_token_families_post_cancel (state->handle); + } + json_decref (state->description_i18n); + GNUNET_free (state); +} + +struct TALER_TESTING_Command +TALER_TESTING_cmd_merchant_post_tokenfamilies ( + const char *label, + const char *merchant_url, + unsigned int http_status, + const char *slug, + const char *name, + const char *description, + json_t *description_i18n, + struct GNUNET_TIME_Timestamp valid_after, + struct GNUNET_TIME_Timestamp valid_before, + struct GNUNET_TIME_Relative duration, + const char *kind) /* "subscription" or "discount" */ +{ + struct PostTokenFamiliesState *state; + + GNUNET_assert ((NULL == description_i18n) || + json_is_object (description_i18n)); + state = GNUNET_new (struct PostTokenFamiliesState); + state->merchant_url = merchant_url; + state->http_status = http_status; + state->slug = slug; + state->name = name; + state->description = description; + state->description_i18n = description_i18n; /* ownership taken */ + state->valid_after = valid_after; + state->valid_before = valid_before; + state->duration = duration; + state->kind = kind; + { + struct TALER_TESTING_Command cmd = { + .cls = state, + .label = label, + .run = &post_tokenfamilies_run, + .cleanup = &post_tokenfamilies_cleanup, + .traits = &post_tokenfamilies_traits + }; + + return cmd; + } +}
\ No newline at end of file diff --git a/src/testing/testing_api_cmd_post_transfers.c b/src/testing/testing_api_cmd_post_transfers.c index dee1b183..c194bd1e 100644 --- a/src/testing/testing_api_cmd_post_transfers.c +++ b/src/testing/testing_api_cmd_post_transfers.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020, 2023 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 @@ -70,6 +70,11 @@ struct PostTransfersState const char *payto_uri; /** + * Set to the hash of the @e payto_uri. + */ + struct TALER_PaytoHashP h_payto; + + /** * Authentication details to authenticate to the bank. */ struct TALER_BANK_AuthenticationData auth; @@ -85,11 +90,6 @@ struct PostTransfersState struct TALER_Amount credit_amount; /** - * The fee incurred on the wire transfer. - */ - struct TALER_Amount wire_fee; - - /** * Expected HTTP response code. */ unsigned int http_status; @@ -110,10 +110,6 @@ struct PostTransfersState */ unsigned int deposits_length; - /** - * When the exchange executed the transfer. - */ - struct GNUNET_TIME_Timestamp execution_time; }; @@ -121,185 +117,29 @@ struct PostTransfersState * Callback for a POST /transfers operation. * * @param cls closure for this function - * @param hr HTTP response details - * @param execution_time when did the transfer happen (according to the exchange), - * #GNUNET_TIME_UNIT_FOREVER_ABS if the transfer did not yet happen or if - * we have no data from the exchange about it - * @param total_amount total amount of the wire transfer, or NULL if the exchange did - * not provide any details - * @param wire_fee how much did the exchange charge in terms of wire fees, or NULL - * if the exchange did not provide any details - * @param details_length length of the @a details array - * @param details array with details about the combined transactions + * @param ptr response details */ static void transfers_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - struct GNUNET_TIME_Timestamp execution_time, - const struct TALER_Amount *total_amount, - const struct TALER_Amount *wire_fee, - unsigned int details_length, - const struct TALER_MERCHANT_TrackTransferDetail details[]) + const struct TALER_MERCHANT_PostTransfersResponse *ptr) { struct PostTransfersState *pts = cls; pts->pth = NULL; - if (pts->http_status != hr->http_status) + if (pts->http_status != ptr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - (int) hr->ec, + ptr->hr.http_status, + (int) ptr->hr.ec, TALER_TESTING_interpreter_get_current_label (pts->is)); + GNUNET_break (0); TALER_TESTING_interpreter_fail (pts->is); return; } - switch (hr->http_status) + switch (ptr->hr.http_status) { - case MHD_HTTP_OK: - { - pts->execution_time = execution_time; - pts->wire_fee = *wire_fee; - fprintf (stderr, - "FIXME"); - json_dumpf (hr->reply, - stderr, - 0); -#if FIXME_WRITE_PROPPER_CHECK_OF_RETURNED_DATA_HERE - /* this code is some legacy logic that is close to what we - need but needs to be updated to the current API */ - struct TALER_Amount total; - - if (0 > - TALER_amount_subtract (&total, - total_amount, - wire_fee)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - if (0 != - TALER_amount_cmp (&total, - &pts->credit_amount)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - TALER_amount_set_zero (total.currency, - &total); - for (unsigned int i = 0; i<details_length; i++) - { - const struct TALER_MERCHANT_TrackTransferDetail *tdd = &details[i]; - struct TALER_Amount sum; - struct TALER_Amount fees; - - TALER_amount_set_zero (tdd->deposit_value.currency, - &sum); - TALER_amount_set_zero (tdd->deposit_fee.currency, - &fees); - for (unsigned int j = 0; j<pts->deposits_length; j++) - { - const char *label = pts->deposits[j]; - const struct TALER_TESTING_Command *cmd; - const json_t *contract_terms; - const struct TALER_Amount *deposit_value; - const struct TALER_Amount *deposit_fee; - const char *order_id; - - cmd = TALER_TESTING_interpreter_lookup_command (pts->is, - label); - if (NULL == cmd) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - if ( (GNUNET_OK != - TALER_TESTING_get_trait_contract_terms (cmd, - 0, - &contract_terms)) || - (GNUNET_OK != - TALER_TESTING_get_trait_amount_obj (cmd, - TALER_TESTING_CMD_DEPOSIT_TRAIT_IDX_DEPOSIT_VALUE, - &deposit_value)) || - (GNUNET_OK != - TALER_TESTING_get_trait_amount_obj (cmd, - TALER_TESTING_CMD_DEPOSIT_TRAIT_IDX_DEPOSIT_FEE, - &deposit_fee)) ) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - order_id = json_string_value (json_object_get (contract_terms, - "order_id")); - if (NULL == order_id) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - if (0 != strcmp (tdd->order_id, - order_id)) - continue; - if (0 > - TALER_amount_add (&sum, - &sum, - deposit_value)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - if (0 > - TALER_amount_add (&fees, - &fees, - deposit_fee)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - } - if (0 != - TALER_amount_cmp (&sum, - &tdd->deposit_value)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - if (0 != - TALER_amount_cmp (&fees, - &tdd->deposit_fee)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } - GNUNET_assert (0 <= - TALER_amount_add (&total, - &total, - &tdd->deposit_value)); - GNUNET_assert (0 <= - TALER_amount_subtract (&total, - &total, - &tdd->deposit_fee)); - } - if (0 != - TALER_amount_cmp (&total, - &pts->credit_amount)) - { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (pts->is); - return; - } -#endif - break; - } - case MHD_HTTP_ACCEPTED: + case MHD_HTTP_NO_CONTENT: break; case MHD_HTTP_UNAUTHORIZED: break; @@ -311,7 +151,7 @@ transfers_cb (void *cls, GNUNET_break (0); GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u for POST /transfers.\n", - hr->http_status); + ptr->hr.http_status); } TALER_TESTING_interpreter_next (pts->is); } @@ -336,14 +176,10 @@ post_transfers_traits (void *cls, struct PostTransfersState *pts = cls; struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_wtid (&pts->wtid), - TALER_TESTING_make_trait_credit_payto_uri ( - (const char **) &pts->credit_account), + TALER_TESTING_make_trait_credit_payto_uri (pts->credit_account), + TALER_TESTING_make_trait_h_payto (&pts->h_payto), TALER_TESTING_make_trait_amount (&pts->credit_amount), - TALER_TESTING_make_trait_fee (&pts->wire_fee), - TALER_TESTING_make_trait_exchange_url ( - (const char **) &pts->exchange_url), - TALER_TESTING_make_trait_timestamp (0, - &pts->execution_time), + TALER_TESTING_make_trait_exchange_url (pts->exchange_url), TALER_TESTING_make_trait_bank_row (&pts->serial), TALER_TESTING_trait_end (), }; @@ -371,14 +207,15 @@ post_transfers_run2 (void *cls, struct PostTransfersState *pts = cls; pts->is = is; - pts->pth = TALER_MERCHANT_transfers_post (pts->is->ctx, - pts->merchant_url, - &pts->credit_amount, - &pts->wtid, - pts->credit_account, - pts->exchange_url, - &transfers_cb, - pts); + pts->pth = TALER_MERCHANT_transfers_post ( + TALER_TESTING_interpreter_get_context (pts->is), + pts->merchant_url, + &pts->credit_amount, + &pts->wtid, + pts->credit_account, + pts->exchange_url, + &transfers_cb, + pts); GNUNET_assert (NULL != pts->pth); } @@ -400,22 +237,22 @@ debit_cb ( pts->dhh = NULL; switch (reply->http_status) { + case MHD_HTTP_OK: + /* handled below */ + break; case MHD_HTTP_NO_CONTENT: GNUNET_break (0); TALER_TESTING_interpreter_fail (pts->is); return; - case MHD_HTTP_OK: - /* handled below */ - break; default: GNUNET_break (0); TALER_TESTING_interpreter_fail (pts->is); return; } - for (unsigned int i = 0; i<reply->details.success.details_length; i++) + for (unsigned int i = 0; i<reply->details.ok.details_length; i++) { const struct TALER_BANK_DebitDetails *details - = &reply->details.success.details[i]; + = &reply->details.ok.details[i]; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bank reports transfer of %s to %s\n", @@ -434,17 +271,24 @@ debit_cb ( pts->payto_uri, pts->exchange_url, TALER_B2S (&pts->wtid)); - pts->pth = TALER_MERCHANT_transfers_post (pts->is->ctx, - pts->merchant_url, - &pts->credit_amount, - &pts->wtid, - pts->credit_account, - pts->exchange_url, - &transfers_cb, - pts); + pts->pth = TALER_MERCHANT_transfers_post ( + TALER_TESTING_interpreter_get_context (pts->is), + pts->merchant_url, + &pts->credit_amount, + &pts->wtid, + pts->credit_account, + pts->exchange_url, + &transfers_cb, + pts); GNUNET_assert (NULL != pts->pth); break; } + if (NULL == pts->pth) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (pts->is); + return; + } } @@ -468,7 +312,8 @@ post_transfers_run (void *cls, "Looking for transfer of %s from %s at bank\n", TALER_amount2s (&pts->credit_amount), pts->payto_uri); - pts->dhh = TALER_BANK_debit_history (is->ctx, + pts->dhh = TALER_BANK_debit_history (TALER_TESTING_interpreter_get_context ( + is), &pts->auth, UINT64_MAX, -INT64_MAX, @@ -529,6 +374,8 @@ TALER_TESTING_cmd_merchant_post_transfer ( pts->merchant_url = merchant_url; pts->auth = *auth; pts->payto_uri = payto_uri; + TALER_payto_hash (payto_uri, + &pts->h_payto); GNUNET_assert (GNUNET_OK == TALER_string_to_amount (credit_amount, &pts->credit_amount)); diff --git a/src/testing/testing_api_cmd_post_using_templates.c b/src/testing/testing_api_cmd_post_using_templates.c index 956a421a..7aeec33d 100644 --- a/src/testing/testing_api_cmd_post_using_templates.c +++ b/src/testing/testing_api_cmd_post_using_templates.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022-2023 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 @@ -27,6 +27,7 @@ #include "taler_merchant_service.h" #include "taler_merchant_testing_lib.h" + /** * State of a "POST /templates" CMD. */ @@ -44,11 +45,23 @@ 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; /** + * ID of the using template to run. + */ + const char *using_template_id; + + /** * Summary given by the customer. */ const char *summary; @@ -64,12 +77,145 @@ struct PostUsingTemplatesState const char *template_ref; /** + * Order id. + */ + 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; + + /** + * Label of command creating/updating OTP device, or NULL. + */ + const char *otp_ref; + + /** + * Encoded key for the payment verification. + */ + const char *otp_key; + + /** + * Option that add amount of the order + */ + const enum TALER_MerchantConfirmationAlgorithm *otp_alg; + + /** * Expected HTTP response code. */ unsigned int http_status; }; +/** + * Used to fill the "using_template" CMD state with backend-provided + * values. Also double-checks that the using_template was correctly + * created. + * + * @param cls closure + * @param ocr response we got + */ +static void +using_claim_cb (void *cls, + const struct TALER_MERCHANT_OrderClaimResponse *ocr) +{ + struct PostUsingTemplatesState *tis = cls; + const char *error_name; + unsigned int error_line; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &tis->merchant_pub), + GNUNET_JSON_spec_end () + }; + + tis->och = NULL; + if (tis->http_status != ocr->hr.http_status) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected status %u, got %u\n", + tis->http_status, + ocr->hr.http_status); + TALER_TESTING_FAIL (tis->is); + } + if (MHD_HTTP_OK != ocr->hr.http_status) + { + TALER_TESTING_interpreter_next (tis->is); + return; + } + tis->contract_terms = json_deep_copy ( + (json_t *) ocr->details.ok.contract_terms); + tis->h_contract_terms = ocr->details.ok.h_contract_terms; + tis->merchant_sig = ocr->details.ok.sig; + if (GNUNET_OK != + GNUNET_JSON_parse (tis->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); + } + TALER_TESTING_interpreter_next (tis->is); +} + /** * Callback for a POST /using-templates operation. @@ -94,22 +240,102 @@ 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 for order switch (por->hr.http_status) { case MHD_HTTP_OK: - break; - case MHD_HTTP_CONFLICT: + 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: - break; + 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: - GNUNET_break (0); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status %u for POST /templates/$ID.\n", - por->hr.http_status); - break; + { + 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; } - TALER_TESTING_interpreter_next (tis->is); + + if (! tis->with_claim) + { + TALER_TESTING_interpreter_next (tis->is); + return; + } + if (NULL == + (tis->och = TALER_MERCHANT_order_claim ( + TALER_TESTING_interpreter_get_context (tis->is), + tis->merchant_url, + tis->order_id, + &tis->nonce, + &tis->claim_token, + &using_claim_cb, + tis))) + TALER_TESTING_FAIL (tis->is); } @@ -128,7 +354,7 @@ post_using_templates_run (void *cls, { struct PostUsingTemplatesState *tis = cls; const struct TALER_TESTING_Command *ref; - const char **template_id; + const char *template_id; tis->is = is; ref = TALER_TESTING_interpreter_lookup_command (is, @@ -137,10 +363,23 @@ post_using_templates_run (void *cls, TALER_TESTING_get_trait_template_id (ref, &template_id)) TALER_TESTING_FAIL (is); + if (NULL != tis->otp_ref) + { + ref = TALER_TESTING_interpreter_lookup_command (is, + tis->otp_ref); + if (GNUNET_OK != + TALER_TESTING_get_trait_otp_key (ref, + &tis->otp_key)) + TALER_TESTING_FAIL (is); + if (GNUNET_OK != + TALER_TESTING_get_trait_otp_alg (ref, + &tis->otp_alg)) + TALER_TESTING_FAIL (is); + } tis->iph = TALER_MERCHANT_using_templates_post ( - is->ctx, + TALER_TESTING_interpreter_get_context (is), tis->merchant_url, - *template_id, + template_id, tis->summary, TALER_amount_is_valid (&tis->amount) ? &tis->amount @@ -169,6 +408,16 @@ 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_otp_key (pts->otp_key), + TALER_TESTING_make_trait_otp_alg (pts->otp_alg), TALER_TESTING_trait_end (), }; @@ -199,25 +448,144 @@ post_using_templates_cleanup (void *cls, "POST /using-templates operation did not complete\n"); TALER_MERCHANT_using_templates_post_cancel (tis->iph); } + json_decref (tis->order_terms); + json_decref (tis->contract_terms); + GNUNET_free (tis->order_id); GNUNET_free (tis); } +/** + * Mark part of the contract terms as possible to forget. + * + * @param cls pointer to the result of the forget operation. + * @param object_id name of the object to forget. + * @param parent parent of the object at @e object_id. + */ +static void +mark_forgettable (void *cls, + const char *object_id, + json_t *parent) +{ + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_mark_forgettable (parent, + object_id)); +} + + +/** + * Constructs the json for a POST using template request. + * + * @param using_template_id the name of the using_template to add, can be NULL. + * @param refund_deadline the deadline for refunds on this using template. + * @param pay_deadline the deadline for payment on this using template. + * @param amount the amount this using template is for. + * @param[out] using_template where to write the json string. + */ +static void +make_order_json (const char *using_template_id, + struct GNUNET_TIME_Timestamp refund_deadline, + struct GNUNET_TIME_Timestamp pay_deadline, + const char *amount, + json_t **using_template) +{ + struct GNUNET_TIME_Timestamp refund = refund_deadline; + struct GNUNET_TIME_Timestamp pay = pay_deadline; + json_t *contract_terms; + struct TALER_Amount tamount; + json_t *arr; + + if (NULL != amount) + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (amount, + &tamount)); + /* Include required fields and some dummy objects to test forgetting. */ + arr = json_array (); + GNUNET_assert (NULL != arr); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "speakers")))); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "headphones")))); + GNUNET_assert (0 == + json_array_append_new ( + arr, + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "item", "earbuds")))); + contract_terms = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("summary", + "merchant-lib testcase"), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ( + "using_template_id", using_template_id)), + NULL == amount + ? GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("amount", + NULL)) + : TALER_JSON_pack_amount ("amount", + &tamount), + GNUNET_JSON_pack_string ("fulfillment_url", + "https://example.com"), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("refund_deadline", + refund)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_timestamp ("pay_deadline", + pay)), + GNUNET_JSON_pack_string ("dummy_obj", + "EUR:1.0"), + GNUNET_JSON_pack_array_steal ("dummy_array", + arr)); + GNUNET_assert (GNUNET_OK == + TALER_JSON_expand_path (contract_terms, + "$.dummy_obj", + &mark_forgettable, + NULL)); + GNUNET_assert (GNUNET_OK == + TALER_JSON_expand_path (contract_terms, + "$.dummy_array[*].item", + &mark_forgettable, + NULL)); + *using_template = contract_terms; +} + + struct TALER_TESTING_Command TALER_TESTING_cmd_merchant_post_using_templates ( const char *label, const char *template_ref, + const char *otp_ref, const char *merchant_url, + const char *using_template_id, const char *summary, - const char *amount, unsigned int http_status) + const char *amount, + struct GNUNET_TIME_Timestamp refund_deadline, + struct GNUNET_TIME_Timestamp pay_deadline, + unsigned int http_status) { struct PostUsingTemplatesState *tis; tis = GNUNET_new (struct PostUsingTemplatesState); tis->template_ref = template_ref; + tis->otp_ref = otp_ref; tis->merchant_url = merchant_url; + tis->using_template_id = using_template_id; tis->http_status = http_status; tis->summary = summary; + tis->with_claim = true; + make_order_json (using_template_id, + refund_deadline, + pay_deadline, + amount, + &tis->order_terms); if (NULL != amount) GNUNET_assert (GNUNET_OK == TALER_string_to_amount (amount, diff --git a/src/testing/testing_api_cmd_post_webhooks.c b/src/testing/testing_api_cmd_post_webhooks.c index d1628429..c3a8d1b3 100644 --- a/src/testing/testing_api_cmd_post_webhooks.c +++ b/src/testing/testing_api_cmd_post_webhooks.c @@ -78,7 +78,7 @@ struct PostWebhooksState * body of the webhook */ const char *body_template; - + /** * Expected HTTP response code. */ @@ -148,16 +148,17 @@ post_webhooks_run (void *cls, struct PostWebhooksState *wis = cls; wis->is = is; - wis->iph = TALER_MERCHANT_webhooks_post (is->ctx, - wis->merchant_url, - wis->webhook_id, - wis->event_type, - wis->url, - wis->http_method, - wis->header_template, - wis->body_template, - &post_webhooks_cb, - wis); + wis->iph = TALER_MERCHANT_webhooks_post ( + TALER_TESTING_interpreter_get_context (is), + wis->merchant_url, + wis->webhook_id, + wis->event_type, + wis->url, + wis->http_method, + wis->header_template, + wis->body_template, + &post_webhooks_cb, + wis); GNUNET_assert (NULL != wis->iph); } @@ -180,12 +181,12 @@ post_webhooks_traits (void *cls, { struct PostWebhooksState *pws = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_event_type (&pws->event_type), - TALER_TESTING_make_trait_url (&pws->url), - TALER_TESTING_make_trait_http_method (&pws->http_method), - TALER_TESTING_make_trait_header_template (&pws->header_template), - TALER_TESTING_make_trait_body_template (&pws->body_template), - TALER_TESTING_make_trait_webhook_id (&pws->webhook_id), + TALER_TESTING_make_trait_event_type (pws->event_type), + TALER_TESTING_make_trait_url (pws->url), + TALER_TESTING_make_trait_http_method (pws->http_method), + TALER_TESTING_make_trait_header_template (pws->header_template), + TALER_TESTING_make_trait_body_template (pws->body_template), + TALER_TESTING_make_trait_webhook_id (pws->webhook_id), TALER_TESTING_trait_end (), }; @@ -240,8 +241,8 @@ TALER_TESTING_cmd_merchant_post_webhooks2 ( wis->event_type = event_type; wis->url = url; wis->http_method = http_method; - wis->header_template = header_template; - wis->body_template = body_template; + wis->header_template = (NULL==header_template) ? NULL : header_template; + wis->body_template = (NULL==body_template) ? NULL : body_template; { struct TALER_TESTING_Command cmd = { .cls = wis, @@ -268,10 +269,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", + "Taler-test-header: EFEHYJS-Bakery", + "5.0 EUR", http_status); } diff --git a/src/testing/testing_api_cmd_refund_order.c b/src/testing/testing_api_cmd_refund_order.c index 0f94622c..7cc71e21 100644 --- a/src/testing/testing_api_cmd_refund_order.c +++ b/src/testing/testing_api_cmd_refund_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2019 Taler Systems SA + Copyright (C) 2014-2023 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 @@ -76,39 +76,34 @@ struct RefundState * if the HTTP response code is the one expected. * * @param cls closure - * @param hr HTTP response - * @param taler_refund_uri the refund uri offered to the wallet - * @param h_contract hash of the contract a Browser may need to authorize - * obtaining the HTTP response. + * @param rr response */ static void refund_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const char *taler_refund_uri, - const struct TALER_PrivateContractHashP *h_contract) + const struct TALER_MERCHANT_RefundResponse *rr) { struct RefundState *ris = cls; - (void) h_contract; ris->orh = NULL; - if (ris->http_code != hr->http_status) + if (ris->http_code != rr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expected status %u, got %u(%d) for refund increase\n", ris->http_code, - hr->http_status, - (int) hr->ec); + rr->hr.http_status, + (int) rr->hr.ec); TALER_TESTING_FAIL (ris->is); } - switch (hr->http_status) + switch (rr->hr.http_status) { case MHD_HTTP_OK: { struct TALER_MERCHANT_RefundUriData rud; if (GNUNET_OK != - TALER_MERCHANT_parse_refund_uri (taler_refund_uri, - &rud)) + TALER_MERCHANT_parse_refund_uri ( + rr->details.ok.taler_refund_uri, + &rud)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Taler refund uri is malformed\n"); @@ -116,25 +111,9 @@ refund_cb (void *cls, return; } { - char *port; char *host; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (ris->is->cfg, - "merchant", - "PORT", - &port)) - { - /* How did we get here without a configured port? */ - GNUNET_break (0); - TALER_TESTING_interpreter_fail (ris->is); - TALER_MERCHANT_parse_refund_uri_free (&rud); - return; - } - GNUNET_asprintf (&host, - "localhost:%s", - port); - GNUNET_free (port); + host = TALER_MERCHANT_TESTING_extract_host (ris->merchant_url); if ((0 != strcmp (host, rud.merchant_host)) || (NULL != rud.merchant_prefix_path) || @@ -165,7 +144,7 @@ refund_cb (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unhandled HTTP status %u for refund order.\n", - hr->http_status); + rr->hr.http_status); } TALER_TESTING_interpreter_next (ris->is); } @@ -186,13 +165,14 @@ refund_increase_run (void *cls, struct RefundState *ris = cls; ris->is = is; - ris->orh = TALER_MERCHANT_post_order_refund (is->ctx, - ris->merchant_url, - ris->order_id, - &ris->refund_amount, - ris->reason, - &refund_cb, - ris); + ris->orh = TALER_MERCHANT_post_order_refund ( + TALER_TESTING_interpreter_get_context (is), + ris->merchant_url, + ris->order_id, + &ris->refund_amount, + ris->reason, + &refund_cb, + ris); if (NULL == ris->orh) TALER_TESTING_FAIL (is); } @@ -217,7 +197,7 @@ refund_increase_traits (void *cls, struct RefundState *ris = cls; struct TALER_TESTING_Trait traits[] = { TALER_TESTING_make_trait_amount (&ris->refund_amount), - TALER_TESTING_make_trait_reason (&ris->reason), + TALER_TESTING_make_trait_reason (ris->reason), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_testserver.c b/src/testing/testing_api_cmd_testserver.c new file mode 100644 index 00000000..f47502a6 --- /dev/null +++ b/src/testing/testing_api_cmd_testserver.c @@ -0,0 +1,374 @@ +/* + This file is part of TALER + Copyright (C) 2023 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; + + /** + * Array where we remember all of the requests this + * server answered. + */ + struct RequestCtx **rcs; + + /** + * Length of the @a rcs array + */ + unsigned int rcs_length; +}; + + +struct RequestCtx +{ + /** + * URL where we are redirect. + */ + char *url; + + /** + * http method of the webhook. + */ + char *http_method; + + /** + * header of the webhook. + */ + char *header; + + /** + * body of the webhook. + */ + void *body; + + /** + * size of the body + */ + size_t body_size; + + /** + * Set to true when we are done with the request. + */ + bool done; +}; + + +/** + * 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 TestserverState *ts = cls; + struct RequestCtx *rc = *con_cls; + + (void) version; + if (NULL == rc) + { + const char *hdr; + + rc = GNUNET_new (struct RequestCtx); + *con_cls = rc; + rc->http_method = GNUNET_strdup (method); + hdr = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + "Taler-test-header"); + if (NULL != hdr) + rc->header = GNUNET_strdup (hdr); + if (NULL != url) + rc->url = GNUNET_strdup (url); + GNUNET_array_append (ts->rcs, + ts->rcs_length, + rc); + fprintf (stderr, + "Webhook called server at `%s' with header `%s'\n", + url, + hdr); + return MHD_YES; + } + if (0 == strcasecmp (method, + MHD_HTTP_METHOD_GET)) + { + json_t *reply; + + reply = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ( + "status", + "success")); + return TALER_MHD_reply_json_steal (connection, + reply, + MHD_HTTP_OK); + } + if (0 != strcasecmp (method, + MHD_HTTP_METHOD_POST)) + { + GNUNET_break (0); + return MHD_NO; + } + if (0 != *upload_data_size) + { + void *body; + + body = GNUNET_malloc (rc->body_size + *upload_data_size); + GNUNET_memcpy (body, + rc->body, + rc->body_size); + GNUNET_free (rc->body); + GNUNET_memcpy (body + rc->body_size, + upload_data, + *upload_data_size); + rc->body = body; + rc->body_size += *upload_data_size; + *upload_data_size = 0; + return MHD_YES; + } + + { + json_t *reply; + + reply = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("something", + "good")); + return TALER_MHD_reply_json_steal (connection, + reply, + 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; + rc->done = true; +} + + +/** + * 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); + if (NULL == ser->mhd) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + 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; + } + for (unsigned int i = 0; i<ser->rcs_length; i++) + { + struct RequestCtx *rc = ser->rcs[i]; + + GNUNET_assert (rc->done); + GNUNET_free (rc->url); + GNUNET_free (rc->http_method); + GNUNET_free (rc->header); + GNUNET_free (rc->body); + GNUNET_free (rc); + } + GNUNET_array_grow (ser->rcs, + ser->rcs_length, + 0); + GNUNET_free (ser); +} + + +static enum GNUNET_GenericReturnValue +traits_testserver (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct TestserverState *ser = cls; + + if (index >= ser->rcs_length) + return GNUNET_NO; + + { + const struct RequestCtx *rc = ser->rcs[index]; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_urls (index, + rc->url), + TALER_TESTING_make_trait_http_methods (index, + rc->http_method), + TALER_TESTING_make_trait_http_header (index, + rc->header), + TALER_TESTING_make_trait_http_body (index, + rc->body), + TALER_TESTING_make_trait_http_body_size (index, + &rc->body_size), + TALER_TESTING_trait_end (), + }; + + if (! rc->done) + return GNUNET_NO; + 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, + .traits = &traits_testserver + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_checkserver.c */ diff --git a/src/testing/testing_api_cmd_tip_authorize.c b/src/testing/testing_api_cmd_tip_authorize.c deleted file mode 100644 index 3d6893d9..00000000 --- a/src/testing/testing_api_cmd_tip_authorize.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - 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 - <http://www.gnu.org/licenses/> -*/ - -/** - * @file testing_api_cmd_tip_authorize.c - * @brief command to test the tipping. - * @author Marcello Stanisci - */ - -#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 for a /tip-authorize CMD. - */ -struct TipAuthorizeState -{ - - /** - * Merchant base URL. - */ - const char *merchant_url; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Reference to the reserv to authorize the tip - * from (if NULL, the merchant decides). - */ - const char *reserve_reference; - - /** - * Human-readable justification for the - * tip authorization carried on by this CMD. - */ - const char *justification; - - /** - * Amount that should be authorized for tipping. - */ - struct TALER_Amount amount; - - /** - * Expected Taler error code for this CMD. - */ - enum TALER_ErrorCode expected_ec; - - /** - * Tip taler:// URI. - */ - char *tip_uri; - - /** - * The tip id; set when the CMD succeeds. - */ - struct TALER_TipIdentifierP tip_id; - - /** - * Expiration date for this tip. - */ - struct GNUNET_TIME_Timestamp tip_expiration; - - /** - * Handle to the on-going /tip-authorize request. - */ - struct TALER_MERCHANT_TipAuthorizeHandle *tao; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Task used for retries. - */ - struct GNUNET_SCHEDULER_Task *retry_task; - - /** - * How long do we wait between retries? - */ - struct GNUNET_TIME_Relative backoff; - - /** - * How many retries are left? - */ - unsigned int retries_left; - -}; - - -/** - * Run the main logic of talking to the merchant. - * - * @param cls a `struct TipAuthorizeState`. - */ -static void -do_retry (void *cls); - - -/** - * Callback for a /tip-authorize request. Set into the state - * what was returned from the backend (@a tip_id and @a - * tip_expiration). - * - * @param cls closure - * @param hr HTTP response we got - * @param tip_id unique identifier for the tip - * @param taler_tip_uri URI to let the wallet know about the tip - * @param expiration when the tip expires - */ -static void -tip_authorize_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - struct TALER_TipIdentifierP *tip_id, - const char *taler_tip_uri, - struct GNUNET_TIME_Timestamp expiration) -{ - struct TipAuthorizeState *tas = cls; - - tas->tao = NULL; - if (tas->http_status != hr->http_status) - { - if ( (MHD_HTTP_NOT_FOUND == hr->http_status) && - (0 < tas->retries_left) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Reserve authorization failed. Reserve may not yet be ready, retrying %u more times.\n", - tas->retries_left); - tas->retries_left--; - tas->backoff = GNUNET_TIME_randomized_backoff (tas->backoff, - GNUNET_TIME_UNIT_SECONDS); - tas->retry_task = GNUNET_SCHEDULER_add_delayed (tas->backoff, - &do_retry, - tas); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u (%d) to command %s\n", - hr->http_status, - hr->ec, - TALER_TESTING_interpreter_get_current_label (tas->is)); - TALER_TESTING_interpreter_fail (tas->is); - return; - } - - if (tas->expected_ec != hr->ec) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected error code %d (%u) to command %s\n", - (int) hr->ec, - hr->http_status, - TALER_TESTING_interpreter_get_current_label (tas->is)); - TALER_TESTING_interpreter_fail (tas->is); - return; - } - if ( (MHD_HTTP_OK == hr->http_status) && - (TALER_EC_NONE == hr->ec) ) - { - tas->tip_uri = strdup (taler_tip_uri); - tas->tip_id = *tip_id; - tas->tip_expiration = expiration; - } - TALER_TESTING_interpreter_next (tas->is); -} - - -/** - * Offers information from the /tip-authorize 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 enum GNUNET_GenericReturnValue -tip_authorize_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct TipAuthorizeState *tas = cls; - struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_tip_id (&tas->tip_id), - TALER_TESTING_make_trait_amount (&tas->amount), - TALER_TESTING_make_trait_reason (&tas->justification), - TALER_TESTING_make_trait_timestamp (0, - &tas->tip_expiration), - TALER_TESTING_trait_end (), - }; - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); -} - - -/** - * Runs the /tip-authorize CMD - * - * @param cls closure - * @param cmd the CMD representing _this_ command - * @param is interpreter state - */ -static void -tip_authorize_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct TipAuthorizeState *tas = cls; - - tas->retries_left = 16; - tas->is = is; - tas->retry_task = GNUNET_SCHEDULER_add_now (&do_retry, - tas); -} - - -static void -do_retry (void *cls) -{ - struct TipAuthorizeState *tas = cls; - - tas->retry_task = NULL; - if (NULL == tas->reserve_reference) - { - tas->tao = TALER_MERCHANT_tip_authorize (tas->is->ctx, - tas->merchant_url, - "http://merchant.com/pickup", - &tas->amount, - tas->justification, - &tip_authorize_cb, - tas); - } - else - { - const struct TALER_TESTING_Command *reserve_cmd; - const struct TALER_ReservePublicKeyP *reserve_pub; - - reserve_cmd = TALER_TESTING_interpreter_lookup_command ( - tas->is, - tas->reserve_reference); - GNUNET_assert (GNUNET_OK == - TALER_TESTING_get_trait_reserve_pub (reserve_cmd, - &reserve_pub)); - tas->tao = TALER_MERCHANT_tip_authorize2 (tas->is->ctx, - tas->merchant_url, - reserve_pub, - "http://merchant.com/pickup", - &tas->amount, - tas->justification, - &tip_authorize_cb, - tas); - } - GNUNET_assert (NULL != tas->tao); -} - - -/** - * Run the /tip-authorize CMD, the "fake" version of it. - * - * @param cls closure - * @param cmd the CMD representing _this_ command - * @param is interpreter state * - */ -static void -tip_authorize_fake_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct TipAuthorizeState *tas = cls; - - /* Make up a tip id. */ - GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, - &tas->tip_id, - sizeof (struct TALER_TipIdentifierP)); - TALER_TESTING_interpreter_next (is); -} - - -/** - * Free the state from a /tip-authorize CMD, and possibly - * cancel any pending operation. - * - * @param cls closure - * @param cmd the /tip-authorize CMD that is about to be freed. - */ -static void -tip_authorize_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct TipAuthorizeState *tas = cls; - - if (NULL != tas->tao) - { - TALER_LOG_WARNING ("Tip-autorize operation" - " did not complete\n"); - TALER_MERCHANT_tip_authorize_cancel (tas->tao); - } - if (NULL != tas->retry_task) - { - GNUNET_SCHEDULER_cancel (tas->retry_task); - tas->retry_task = NULL; - } - GNUNET_free (tas->tip_uri); - GNUNET_free (tas); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize_with_ec (const char *label, - const char *merchant_url, - const char *exchange_url, - unsigned int http_status, - const char *justification, - const char *amount, - enum TALER_ErrorCode ec) -{ - struct TipAuthorizeState *tas; - - tas = GNUNET_new (struct TipAuthorizeState); - tas->merchant_url = merchant_url; - tas->justification = justification; - tas->http_status = http_status; - tas->expected_ec = ec; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (amount, - &tas->amount)); - { - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = tas, - .run = &tip_authorize_run, - .cleanup = &tip_authorize_cleanup, - .traits = &tip_authorize_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize_from_reserve_with_ec ( - const char *label, - const char *merchant_url, - const char *exchange_url, - const char *reserve_reference, - unsigned int http_status, - const char *justification, - const char *amount, - enum TALER_ErrorCode ec) -{ - struct TipAuthorizeState *tas; - - tas = GNUNET_new (struct TipAuthorizeState); - tas->merchant_url = merchant_url; - tas->justification = justification; - tas->http_status = http_status; - tas->expected_ec = ec; - tas->reserve_reference = reserve_reference; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (amount, - &tas->amount)); - { - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = tas, - .run = &tip_authorize_run, - .cleanup = &tip_authorize_cleanup, - .traits = &tip_authorize_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize (const char *label, - const char *merchant_url, - const char *exchange_url, - unsigned int http_status, - const char *justification, - const char *amount) -{ - struct TipAuthorizeState *tas; - - tas = GNUNET_new (struct TipAuthorizeState); - tas->merchant_url = merchant_url; - tas->justification = justification; - tas->http_status = http_status; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (amount, - &tas->amount)); - { - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = tas, - .run = &tip_authorize_run, - .cleanup = &tip_authorize_cleanup, - .traits = &tip_authorize_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize_from_reserve (const char *label, - const char *merchant_url, - const char *exchange_url, - const char *reserve_reference, - unsigned int http_status, - const char *justification, - const char *amount) -{ - struct TipAuthorizeState *tas; - - tas = GNUNET_new (struct TipAuthorizeState); - tas->merchant_url = merchant_url; - tas->reserve_reference = reserve_reference; - tas->justification = justification; - tas->http_status = http_status; - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (amount, - &tas->amount)); - { - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = tas, - .run = &tip_authorize_run, - .cleanup = &tip_authorize_cleanup, - .traits = &tip_authorize_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_authorize_fake (const char *label) -{ - struct TipAuthorizeState *tas; - - tas = GNUNET_new (struct TipAuthorizeState); - { - struct TALER_TESTING_Command cmd = { - .label = label, - .cls = tas, - .run = &tip_authorize_fake_run, - .cleanup = &tip_authorize_cleanup, - .traits = &tip_authorize_traits - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_tip_authorize.c */ diff --git a/src/testing/testing_api_cmd_tip_pickup.c b/src/testing/testing_api_cmd_tip_pickup.c deleted file mode 100644 index 76eac167..00000000 --- a/src/testing/testing_api_cmd_tip_pickup.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - This file is part of TALER - Copyright (C) 2014-2022 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_tip_pickup.c - * @brief command to test the tipping. - * @author Marcello Stanisci - */ -#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 for a /tip-pickup CMD. - */ -struct TipPickupState -{ - /** - * Merchant base URL. - */ - const char *merchant_url; - - /** - * Exchange base URL. - */ - const char *exchange_url; - - /** - * Expected HTTP response code. - */ - unsigned int http_status; - - /** - * Reference to a /tip/authorize CMD. This will be used to - * get the tip id to make the request with. - */ - const char *authorize_reference; - - /** - * If set to non NULL, it references another pickup CMD - * that will provide all the data which is needed to issue - * the request (like planchet secrets, denomination keys..). - */ - const char *replay_reference; - - /** - * Handle to a on-going /tip/pickup request. - */ - struct TALER_MERCHANT_TipPickupHandle *tpo; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * An array of string-defined amounts that indicates - * which denominations are going to be used to receive - * tips. - */ - const char **amounts; - - /** - * The object version of the above @a amounts. - */ - struct TALER_Amount *amounts_obj; - - /** - * The sum of the the amounts above. - */ - struct TALER_Amount total_amount; - - /** - * The array of denomination keys, in the same order of @a - * amounts. - */ - const struct TALER_EXCHANGE_DenomPublicKey **dks; - - /** - * The array of planchet secrets, in the same order of @a - * amounts. - */ - struct TALER_PlanchetMasterSecretP *psa; - - /** - * Set (by the interpreter) to an array of @a num_coins - * details on coins created from the (successful) tip operation. - */ - struct TALER_EXCHANGE_PrivateCoinDetails *pcds; - - /** - * How many coins are involved in the tipping operation. - */ - uint32_t num_coins; - - /** - * Expected Taler error code (NOTE: this is NOT the HTTP - * response code). - */ - enum TALER_ErrorCode expected_ec; -}; - - -/** - * Callback for a /tip-pickup request, it mainly checks if - * values returned from the backend are as expected, and if so - * (and if the status was 200 OK) proceede with the withdrawal. - * - * @param cls closure - * @param pd details about the result of the operation - */ -static void -pickup_cb (void *cls, - const struct TALER_MERCHANT_PickupDetails *pd) -{ - struct TipPickupState *tps = cls; - - tps->tpo = NULL; - if (pd->hr.http_status != tps->http_status) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected response code %u (%d) to command %s\n", - pd->hr.http_status, - (int) pd->hr.ec, - TALER_TESTING_interpreter_get_current_label (tps->is)); - TALER_TESTING_FAIL (tps->is); - } - - if (pd->hr.ec != tps->expected_ec) - TALER_TESTING_FAIL (tps->is); - - /* Safe to go ahead: http status was expected. */ - if ( (MHD_HTTP_OK != pd->hr.http_status) || - (TALER_EC_NONE != pd->hr.ec) ) - { - TALER_TESTING_interpreter_next (tps->is); - return; - } - if (pd->details.success.num_sigs != tps->num_coins) - TALER_TESTING_FAIL (tps->is); - tps->pcds = GNUNET_new_array (tps->num_coins, - struct TALER_EXCHANGE_PrivateCoinDetails); - for (unsigned int i = 0; i<tps->num_coins; i++) - { - struct TALER_EXCHANGE_PrivateCoinDetails *pcd = - &pd->details.success.pcds[i]; - - tps->pcds[i] = *pcd; - TALER_denom_sig_deep_copy (&tps->pcds[i].sig, - &pcd->sig); - } - TALER_TESTING_interpreter_next (tps->is); -} - - -/** - * Run a /tip-pickup CMD. - * - * @param cls closure - * @param cmd the current /tip-pickup CMD. - * @param is interpreter state. - */ -static void -tip_pickup_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct TipPickupState *tps = cls; - unsigned int num_planchets; - const struct TALER_TESTING_Command *replay_cmd; - const struct TALER_TESTING_Command *authorize_cmd; - const struct TALER_TipIdentifierP *tip_id; - - tps->is = is; - tps->exchange_url = TALER_EXCHANGE_get_base_url (is->exchange); - if (NULL == tps->replay_reference) - { - replay_cmd = NULL; - - /* Count planchets. */ - for (num_planchets = 0; - NULL != tps->amounts[num_planchets]; - num_planchets++) - ; - } - else - { - const uint32_t *np; - - if (NULL == /* looking for "parent" tip-pickup command */ - (replay_cmd - = TALER_TESTING_interpreter_lookup_command (is, - tps->replay_reference)) ) - TALER_TESTING_FAIL (is); - - if (GNUNET_OK != - TALER_TESTING_get_trait_num_planchets (replay_cmd, - &np)) - TALER_TESTING_FAIL (is); - num_planchets = *np; - } - - if (NULL == - (authorize_cmd - = TALER_TESTING_interpreter_lookup_command (is, - tps->authorize_reference)) ) - TALER_TESTING_FAIL (is); - - tps->num_coins = num_planchets; - { - struct TALER_MERCHANT_PlanchetData planchets[num_planchets]; - - tps->psa = GNUNET_new_array (num_planchets, - struct TALER_PlanchetMasterSecretP); - tps->dks = GNUNET_new_array (num_planchets, - const struct TALER_EXCHANGE_DenomPublicKey *); - tps->amounts_obj = GNUNET_new_array (num_planchets, - struct TALER_Amount); - for (unsigned int i = 0; i<num_planchets; i++) - { - if (NULL == replay_cmd) - { - GNUNET_assert (GNUNET_OK == - TALER_string_to_amount (tps->amounts[i], - &tps->amounts_obj[i])); - if (0 == i) - GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (tps->amounts_obj[i].currency, - &tps->total_amount)); - - GNUNET_assert (0 < - TALER_amount_add (&tps->total_amount, - &tps->total_amount, - &tps->amounts_obj[i])); - tps->dks[i] = TALER_TESTING_find_pk (is->keys, - &tps->amounts_obj[i], - false); - if (NULL == tps->dks[i]) - TALER_TESTING_FAIL (is); - TALER_planchet_master_setup_random (&tps->psa[i]); - } - else - { - const struct TALER_PlanchetMasterSecretP *ps; - - if (GNUNET_OK != - TALER_TESTING_get_trait_denom_pub (replay_cmd, - i, - &tps->dks[i])) - TALER_TESTING_FAIL (is); - if (GNUNET_OK != - TALER_TESTING_get_trait_planchet_secrets (replay_cmd, - i, - &ps)) - TALER_TESTING_FAIL (is); - tps->psa[i] = *ps; - } - planchets[i].pk = tps->dks[i]; - planchets[i].ps = tps->psa[i]; - } - if (GNUNET_OK != - TALER_TESTING_get_trait_tip_id (authorize_cmd, - &tip_id)) - TALER_TESTING_FAIL (is); - tps->tpo = TALER_MERCHANT_tip_pickup (is->ctx, - is->exchange, - tps->merchant_url, - tip_id, - num_planchets, - planchets, - &pickup_cb, - tps); - GNUNET_assert (NULL != tps->tpo); - } -} - - -/** - * Free a /tip-pickup CMD state, and possibly cancel a - * pending /tip-pickup request. - * - * @param cls closure. - * @param cmd current CMD to be freed. - */ -static void -tip_pickup_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct TipPickupState *tps = cls; - - GNUNET_free (tps->amounts_obj); - GNUNET_free (tps->dks); - GNUNET_free (tps->psa); - if (NULL != tps->pcds) - { - for (unsigned int i = 0; i<tps->num_coins; i++) - TALER_denom_sig_free (&tps->pcds[i].sig); - GNUNET_free (tps->pcds); - } - if (NULL != tps->tpo) - { - TALER_LOG_WARNING ("Tip-pickup operation did not complete\n"); - TALER_MERCHANT_tip_pickup_cancel (tps->tpo); - } - GNUNET_free (tps); -} - - -static enum GNUNET_GenericReturnValue -tip_pickup_traits (void *cls, - const void **ret, - const char *trait, - unsigned int index) -{ - struct TipPickupState *tps = cls; - - if (index >= tps->num_coins) - return GNUNET_SYSERR; - { - struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_planchet_secrets (index, - &tps->psa[index]), - TALER_TESTING_make_trait_coin_priv (index, - &tps->pcds[index].coin_priv), - TALER_TESTING_make_trait_denom_pub (index, - tps->dks[index]), - TALER_TESTING_make_trait_denom_sig (index, - &tps->pcds[index].sig), - TALER_TESTING_make_trait_amounts (index, - &tps->amounts_obj[index]), - TALER_TESTING_make_trait_amount (&tps->total_amount), - TALER_TESTING_make_trait_num_planchets (&tps->num_coins), - TALER_TESTING_make_trait_exchange_url (&tps->exchange_url), - TALER_TESTING_trait_end () - }; - - return TALER_TESTING_get_trait (traits, - ret, - trait, - index); - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_pickup (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *authorize_reference, - const char **amounts) -{ - struct TipPickupState *tps; - - tps = GNUNET_new (struct TipPickupState); - tps->merchant_url = merchant_url; - tps->authorize_reference = authorize_reference; - tps->amounts = amounts; - tps->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = tps, - .label = label, - .run = &tip_pickup_run, - .cleanup = &tip_pickup_cleanup, - .traits = &tip_pickup_traits - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_tip_pickup_with_ec (const char *label, - const char *merchant_url, - unsigned int http_status, - const char *authorize_reference, - const char **amounts, - enum TALER_ErrorCode ec) -{ - struct TALER_TESTING_Command cmd; - struct TipPickupState *tps; - - cmd = TALER_TESTING_cmd_tip_pickup (label, - merchant_url, - http_status, - authorize_reference, - amounts); - tps = cmd.cls; - tps->expected_ec = ec; - return cmd; -} - - -/* end of testing_api_cmd_tip_pickup.c */ diff --git a/src/testing/testing_api_cmd_tme.c b/src/testing/testing_api_cmd_tme.c new file mode 100644 index 00000000..b84e1df5 --- /dev/null +++ b/src/testing/testing_api_cmd_tme.c @@ -0,0 +1,161 @@ +/* + This file is part of TALER + Copyright (C) 2023 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_tme.c + * @brief run the taler-merchant-exchange command + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler/taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler/taler_signatures.h" +#include "taler/taler_testing_lib.h" + + +/** + * State for a "taler-merchant-exchange" CMD. + */ +struct MerchantExchangeState +{ + + /** + * Process for taler-merchant-exchange + */ + struct GNUNET_OS_Process *merchant_exchange_proc; + + /** + * Configuration file used by the program. + */ + const char *config_filename; +}; + + +/** + * Run the command; use the `taler-merchant-exchange' program. + * + * @param cls closure. + * @param cmd command currently being executed. + * @param is interpreter state. + */ +static void +tme_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct MerchantExchangeState *ws = cls; + + (void) cmd; + ws->merchant_exchange_proc + = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, + NULL, NULL, NULL, + "taler-merchant-exchange", + "taler-merchant-exchange", + "-c", ws->config_filename, + "-t", /* exit when done */ + "-L", "DEBUG", + NULL); + if (NULL == ws->merchant_exchange_proc) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state of a "exchange" CMD, and possibly + * kills its process if it did not terminate regularly. + * + * @param cls closure. + * @param cmd the command being freed. + */ +static void +tme_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct MerchantExchangeState *ws = cls; + + (void) cmd; + if (NULL != ws->merchant_exchange_proc) + { + GNUNET_break (0 == + GNUNET_OS_process_kill (ws->merchant_exchange_proc, + SIGKILL)); + GNUNET_OS_process_wait (ws->merchant_exchange_proc); + GNUNET_OS_process_destroy (ws->merchant_exchange_proc); + ws->merchant_exchange_proc = NULL; + } + GNUNET_free (ws); +} + + +/** + * Offer "tme" CMD internal data to other commands. + * + * @param cls closure. + * @param[out] ret result. + * @param trait name of the trait. + * @param index index number of the object to offer. + * @return #GNUNET_OK on success. + */ +static enum GNUNET_GenericReturnValue +tme_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct MerchantExchangeState *ws = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_process (&ws->merchant_exchange_proc), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_run_tme (const char *label, + const char *config_filename) +{ + struct MerchantExchangeState *ws; + + ws = GNUNET_new (struct MerchantExchangeState); + ws->config_filename = config_filename; + + { + struct TALER_TESTING_Command cmd = { + .cls = ws, + .label = label, + .run = &tme_run, + .cleanup = &tme_cleanup, + .traits = &tme_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_tme.c */ diff --git a/src/testing/testing_api_cmd_wallet_get_order.c b/src/testing/testing_api_cmd_wallet_get_order.c index ac448499..d55ff0a7 100644 --- a/src/testing/testing_api_cmd_wallet_get_order.c +++ b/src/testing/testing_api_cmd_wallet_get_order.c @@ -59,6 +59,18 @@ struct WalletGetOrderState const char *order_reference; /** + * Reference to a command that created a paid + * equivalent order that we expect to be referred + * to during repurchase detection, or NULL. + */ + const char *repurchase_order_ref; + + /** + * Session Id the order needs to be bound to. + */ + const char *session_id; + + /** * Whether the order was paid or not. */ bool paid; @@ -103,14 +115,14 @@ wallet_get_order_cb ( switch (hr->http_status) { case MHD_HTTP_OK: - if (gos->refunded != owgr->details.success.refunded) + if (gos->refunded != owgr->details.ok.refunded) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order refunded does not match\n"); TALER_TESTING_interpreter_fail (gos->is); return; } - if (gos->refund_pending != owgr->details.success.refund_pending) + if (gos->refund_pending != owgr->details.ok.refund_pending) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Order refund pending does not match\n"); @@ -122,9 +134,34 @@ wallet_get_order_cb ( { struct TALER_MERCHANT_PayUriData pud; const struct TALER_TESTING_Command *order_cmd; - const char **order_id; + const char *order_id; const struct TALER_ClaimTokenP *claim_token; + if (NULL != gos->repurchase_order_ref) + { + const struct TALER_TESTING_Command *rep_cmd; + const char *rep_id; + const char *ri; + + rep_cmd = TALER_TESTING_interpreter_lookup_command ( + gos->is, + gos->repurchase_order_ref); + if (GNUNET_OK != + TALER_TESTING_get_trait_order_id (rep_cmd, + &rep_id)) + { + TALER_TESTING_FAIL (gos->is); + } + ri = owgr->details.payment_required.already_paid_order_id; + if ( (NULL == ri) || + (0 != + strcmp (ri, + rep_id)) ) + { + TALER_TESTING_FAIL (gos->is); + } + } + if (GNUNET_OK != TALER_MERCHANT_parse_pay_uri ( owgr->details.payment_required.taler_pay_uri, @@ -158,29 +195,13 @@ wallet_get_order_cb ( } { - char *port; char *host; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (gos->is->cfg, - "merchant", - "PORT", - &port)) - { - /* How did we get here without a configured port? */ - GNUNET_break (0); - TALER_TESTING_interpreter_fail (gos->is); - TALER_MERCHANT_parse_pay_uri_free (&pud); - return; - } - GNUNET_asprintf (&host, - "localhost:%s", - port); - GNUNET_free (port); + host = TALER_MERCHANT_TESTING_extract_host (gos->merchant_url); if ((0 != strcmp (host, pud.merchant_host)) || (NULL != pud.merchant_prefix_path) || - (0 != strcmp (*order_id, + (0 != strcmp (order_id, pud.order_id)) || (NULL != pud.ssid)) { @@ -235,7 +256,7 @@ wallet_get_order_run (void *cls, { struct WalletGetOrderState *gos = cls; const struct TALER_TESTING_Command *order_cmd; - const char **order_id; + const char *order_id; const struct TALER_PrivateContractHashP *h_contract; order_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -253,16 +274,17 @@ wallet_get_order_run (void *cls, TALER_TESTING_FAIL (is); gos->is = is; - gos->ogh = TALER_MERCHANT_wallet_order_get (is->ctx, - gos->merchant_url, - *order_id, - h_contract, - GNUNET_TIME_UNIT_ZERO, - NULL, - NULL, - false, - &wallet_get_order_cb, - gos); + gos->ogh = TALER_MERCHANT_wallet_order_get ( + TALER_TESTING_interpreter_get_context (is), + gos->merchant_url, + order_id, + h_contract, + GNUNET_TIME_UNIT_ZERO, + gos->session_id, + NULL, + false, + &wallet_get_order_cb, + gos); } @@ -281,7 +303,7 @@ wallet_get_order_cleanup (void *cls, if (NULL != gos->ogh) { - TALER_LOG_WARNING ("Get tip operation did not complete\n"); + TALER_LOG_WARNING ("Get order operation did not complete\n"); TALER_MERCHANT_wallet_order_get_cancel (gos->ogh); } GNUNET_free (gos); @@ -289,13 +311,48 @@ wallet_get_order_cleanup (void *cls, struct TALER_TESTING_Command -TALER_TESTING_cmd_wallet_get_order (const char *label, - const char *merchant_url, - const char *order_reference, - bool paid, - bool refunded, - bool refund_pending, - unsigned int http_status) +TALER_TESTING_cmd_wallet_get_order ( + const char *label, + const char *merchant_url, + const char *order_reference, + bool paid, + bool refunded, + bool refund_pending, + unsigned int http_status) +{ + struct WalletGetOrderState *gos; + + gos = GNUNET_new (struct WalletGetOrderState); + gos->merchant_url = merchant_url; + gos->order_reference = order_reference; + gos->http_status = http_status; + gos->paid = paid; + gos->refunded = refunded; + gos->refund_pending = refund_pending; + { + struct TALER_TESTING_Command cmd = { + .cls = gos, + .label = label, + .run = &wallet_get_order_run, + .cleanup = &wallet_get_order_cleanup + }; + + return cmd; + } +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_wallet_get_order2 ( + const char *label, + const char *merchant_url, + const char *order_reference, + const char *session_id, + bool paid, + bool refunded, + bool refund_pending, + const char *repurchase_order_ref, + unsigned int http_status) { struct WalletGetOrderState *gos; @@ -304,8 +361,10 @@ TALER_TESTING_cmd_wallet_get_order (const char *label, gos->order_reference = order_reference; gos->http_status = http_status; gos->paid = paid; + gos->session_id = session_id; gos->refunded = refunded; gos->refund_pending = refund_pending; + gos->repurchase_order_ref = repurchase_order_ref; { struct TALER_TESTING_Command cmd = { .cls = gos, @@ -554,10 +613,10 @@ wallet_poll_order_cb ( { case MHD_HTTP_OK: pos->paid = true; - pos->refunded = owgr->details.success.refunded; - pos->refund_pending = owgr->details.success.refund_pending; - if (owgr->details.success.refunded) - pos->refund_available = owgr->details.success.refund_amount; + pos->refunded = owgr->details.ok.refunded; + pos->refund_pending = owgr->details.ok.refund_pending; + if (owgr->details.ok.refunded) + pos->refund_available = owgr->details.ok.refund_amount; break; case MHD_HTTP_PAYMENT_REQUIRED: if (NULL != owgr->details.payment_required.already_paid_order_id) @@ -593,7 +652,7 @@ wallet_poll_order_start_run (void *cls, { struct WalletPollOrderStartState *pos = cls; const struct TALER_TESTING_Command *order_cmd; - const char **order_id; + const char *order_id; const struct TALER_PrivateContractHashP *h_contract; order_cmd = TALER_TESTING_interpreter_lookup_command ( @@ -615,18 +674,19 @@ wallet_poll_order_start_run (void *cls, = GNUNET_TIME_absolute_add (GNUNET_TIME_relative_to_absolute (pos->timeout), GNUNET_TIME_UNIT_SECONDS); pos->is = is; - pos->ogh = TALER_MERCHANT_wallet_order_get (is->ctx, - pos->merchant_url, - *order_id, - h_contract, - pos->timeout, - pos->session_id, - pos->wait_for_refund - ? &pos->refund_threshold - : NULL, - false, /* await_refund_obtained */ - &wallet_poll_order_cb, - pos); + pos->ogh = TALER_MERCHANT_wallet_order_get ( + TALER_TESTING_interpreter_get_context (is), + pos->merchant_url, + order_id, + h_contract, + pos->timeout, + pos->session_id, + pos->wait_for_refund + ? &pos->refund_threshold + : NULL, + false, /* await_refund_obtained */ + &wallet_poll_order_cb, + pos); GNUNET_assert (NULL != pos->ogh); /* We CONTINUE to run the interpreter while the long-polled command completes asynchronously! */ diff --git a/src/testing/testing_api_cmd_wallet_get_tip.c b/src/testing/testing_api_cmd_wallet_get_tip.c deleted file mode 100644 index 0c19a5b9..00000000 --- a/src/testing/testing_api_cmd_wallet_get_tip.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - 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 - <http://www.gnu.org/licenses/> -*/ -/** - * @file testing_api_cmd_wallet_get_tip.c - * @brief command to test the tipping. - * @author Marcello Stanisci - */ -#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 for a GET /tips/$TIP_ID CMD. - */ -struct WalletTipGetState -{ - - /** - * The merchant base URL. - */ - const char *merchant_url; - - /** - * Expected HTTP response code for this CMD. - */ - unsigned int http_status; - - /** - * Whether to compare amounts or not. - */ - bool cmp_amounts; - - /** - * The expected amount remaining. - */ - struct TALER_Amount amount_remaining; - - /** - * The handle to the current GET /tips/$TIP_ID request. - */ - struct TALER_MERCHANT_TipWalletGetHandle *tgh; - - /** - * The interpreter state. - */ - struct TALER_TESTING_Interpreter *is; - - /** - * Reference to a command that created a tip. - */ - const char *tip_reference; -}; - - -/** - * Callback to process a GET /tips/$TIP_ID request, it mainly - * checks that what the backend returned matches the command's - * expectations. - * - * @param cls closure - * @param hr HTTP response - * @param reserve_expiration when the tip reserve will expire - * @param exchange_url from where to pick up the tip - * @param amount_remaining how much is remaining - */ -static void -wallet_tip_get_cb (void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - struct GNUNET_TIME_Timestamp reserve_expiration, - const char *exchange_url, - const struct TALER_Amount *amount_remaining) -{ - struct WalletTipGetState *gts = cls; - const struct TALER_TESTING_Command *tip_cmd; - - tip_cmd = TALER_TESTING_interpreter_lookup_command ( - gts->is, - gts->tip_reference); - - gts->tgh = NULL; - if (gts->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 (gts->is)); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - switch (hr->http_status) - { - case MHD_HTTP_OK: - if (gts->cmp_amounts) - { - if ((GNUNET_OK != TALER_amount_cmp_currency (>s->amount_remaining, - amount_remaining)) || - (0 != TALER_amount_cmp (>s->amount_remaining, - amount_remaining))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Amount remaining on tip does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - { - const struct GNUNET_TIME_Timestamp *expiration; - - if (GNUNET_OK != - TALER_TESTING_get_trait_timestamp (tip_cmd, - 0, - &expiration)) - TALER_TESTING_interpreter_fail (gts->is); - if (GNUNET_TIME_timestamp_cmp (*expiration, - !=, - reserve_expiration)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Tip expiration does not match\n"); - TALER_TESTING_interpreter_fail (gts->is); - return; - } - } - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Unhandled HTTP status.\n"); - } - TALER_TESTING_interpreter_next (gts->is); -} - - -/** - * Run the "GET tip" CMD. - * - * @param cls closure. - * @param cmd command being run now. - * @param is interpreter state. - */ -static void -wallet_get_tip_run (void *cls, - const struct TALER_TESTING_Command *cmd, - struct TALER_TESTING_Interpreter *is) -{ - struct WalletTipGetState *tgs = cls; - const struct TALER_TESTING_Command *tip_cmd; - const struct TALER_TipIdentifierP *tip_id; - - tip_cmd = TALER_TESTING_interpreter_lookup_command (is, - tgs->tip_reference); - - if (GNUNET_OK != - TALER_TESTING_get_trait_tip_id (tip_cmd, - &tip_id)) - TALER_TESTING_FAIL (is); - - tgs->is = is; - tgs->tgh = TALER_MERCHANT_wallet_tip_get (is->ctx, - tgs->merchant_url, - tip_id, - &wallet_tip_get_cb, - tgs); -} - - -/** - * Free the state of a "GET tip" CMD, and possibly - * cancel a pending operation thereof. - * - * @param cls closure. - * @param cmd command being run. - */ -static void -wallet_get_tip_cleanup (void *cls, - const struct TALER_TESTING_Command *cmd) -{ - struct WalletTipGetState *tgs = cls; - - if (NULL != tgs->tgh) - { - TALER_LOG_WARNING ("Get tip operation did not complete\n"); - TALER_MERCHANT_wallet_tip_get_cancel (tgs->tgh); - } - GNUNET_free (tgs); -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_wallet_get_tip (const char *label, - const char *merchant_url, - const char *tip_reference, - unsigned int http_status) -{ - struct WalletTipGetState *tgs; - - tgs = GNUNET_new (struct WalletTipGetState); - tgs->merchant_url = merchant_url; - tgs->tip_reference = tip_reference; - tgs->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = tgs, - .label = label, - .run = &wallet_get_tip_run, - .cleanup = &wallet_get_tip_cleanup - }; - - return cmd; - } -} - - -struct TALER_TESTING_Command -TALER_TESTING_cmd_wallet_get_tip2 (const char *label, - const char *merchant_url, - const char *tip_reference, - const char *amount_remaining, - unsigned int http_status) -{ - struct WalletTipGetState *tgs; - - tgs = GNUNET_new (struct WalletTipGetState); - tgs->merchant_url = merchant_url; - tgs->tip_reference = tip_reference; - tgs->cmp_amounts = true; - GNUNET_assert (GNUNET_OK == TALER_string_to_amount (amount_remaining, - &tgs->amount_remaining)); - tgs->http_status = http_status; - { - struct TALER_TESTING_Command cmd = { - .cls = tgs, - .label = label, - .run = &wallet_get_tip_run, - .cleanup = &wallet_get_tip_cleanup - }; - - return cmd; - } -} - - -/* end of testing_api_cmd_wallet_get_tip.c */ diff --git a/src/testing/testing_api_cmd_wallet_post_orders_refund.c b/src/testing/testing_api_cmd_wallet_post_orders_refund.c index b9e7981f..617d33fb 100644 --- a/src/testing/testing_api_cmd_wallet_post_orders_refund.c +++ b/src/testing/testing_api_cmd_wallet_post_orders_refund.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020 Taler Systems SA + Copyright (C) 2020-2023 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 @@ -76,44 +76,39 @@ struct WalletRefundState * if the HTTP response code is the one expected. * * @param cls closure - * @param hr HTTP response - * @param refund_amount refund amount - * @param merchant_pub public key of the merchant giving the refund - * @param refunds the given refunds - * @param refunds_length how many refunds were given + * @param wrr response */ static void refund_cb ( void *cls, - const struct TALER_MERCHANT_HttpResponse *hr, - const struct TALER_Amount *refund_amount, - const struct TALER_MerchantPublicKeyP *merchant_pub, - struct TALER_MERCHANT_RefundDetail refunds[], - unsigned int refunds_length) + const struct TALER_MERCHANT_WalletRefundResponse *wrr) { struct WalletRefundState *wrs = cls; wrs->orh = NULL; - if (wrs->http_code != hr->http_status) + if (wrs->http_code != wrr->hr.http_status) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expected status %u, got %u(%d) for refund increase\n", wrs->http_code, - hr->http_status, - (int) hr->ec); + wrr->hr.http_status, + (int) wrr->hr.ec); TALER_TESTING_FAIL (wrs->is); } - switch (hr->http_status) + switch (wrr->hr.http_status) { case MHD_HTTP_OK: { struct TALER_Amount refunded_total; - if (refunds_length > 0) + if (wrr->details.ok.refunds_length > 0) GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (refunds[0].refund_amount.currency, - &refunded_total)); - for (unsigned int i = 0; i < refunds_length; ++i) + TALER_amount_set_zero ( + wrr->details.ok.refunds[0].refund_amount.currency, + &refunded_total)); + for (unsigned int i = 0; i < wrr->details.ok.refunds_length; ++i) { + const struct TALER_MERCHANT_RefundDetail *refund + = &wrr->details.ok.refunds[wrr->details.ok.refunds_length - 1 - i]; const struct TALER_TESTING_Command *refund_cmd; const struct TALER_Amount *expected_amount; @@ -133,13 +128,12 @@ refund_cb ( /* The most recent refunds are returned first */ GNUNET_assert (0 <= TALER_amount_add (&refunded_total, &refunded_total, - &refunds[refunds_length - 1 - - i].refund_amount)); - if ((GNUNET_OK != - TALER_amount_cmp_currency (expected_amount, - &refunded_total)) || - (0 != TALER_amount_cmp (expected_amount, - &refunded_total))) + &refund->refund_amount)); + if ( (GNUNET_OK != + TALER_amount_cmp_currency (expected_amount, + &refunded_total)) || + (0 != TALER_amount_cmp (expected_amount, + &refunded_total)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Refund amounts do not match\n"); @@ -150,7 +144,6 @@ refund_cb ( } break; default: - break; } TALER_TESTING_interpreter_next (wrs->is); @@ -224,7 +217,7 @@ obtain_refunds_run (void *cls, wrs->is = is; wrs->orh = TALER_MERCHANT_wallet_post_order_refund ( - is->ctx, + TALER_TESTING_interpreter_get_context (is), wrs->merchant_url, order_id, h_contract_terms, diff --git a/src/testing/testing_api_cmd_webhook.c b/src/testing/testing_api_cmd_webhook.c new file mode 100644 index 00000000..8c5df5b9 --- /dev/null +++ b/src/testing/testing_api_cmd_webhook.c @@ -0,0 +1,161 @@ +/* + This file is part of TALER + Copyright (C) 2023 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_webhook.c + * @brief run the taler-merchant-webhook command + * @author Priscilla HUANG + */ +#include "platform.h" +#include "taler/taler_json_lib.h" +#include <gnunet/gnunet_curl_lib.h> +#include "taler/taler_signatures.h" +#include "taler/taler_testing_lib.h" + + +/** + * State for a "webhook" CMD. + */ +struct WebhookState +{ + + /** + * Process for the webhook. + */ + struct GNUNET_OS_Process *webhook_proc; + + /** + * Configuration file used by the webhook. + */ + const char *config_filename; +}; + + +/** + * Run the command; use the `taler-merchant-webhook' program. + * + * @param cls closure. + * @param cmd command currently being executed. + * @param is interpreter state. + */ +static void +webhook_run (void *cls, + const struct TALER_TESTING_Command *cmd, + struct TALER_TESTING_Interpreter *is) +{ + struct WebhookState *ws = cls; + + (void) cmd; + ws->webhook_proc + = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, + NULL, NULL, NULL, + "taler-merchant-webhook", + "taler-merchant-webhook", + "-c", ws->config_filename, + "-t", /* exit when done */ + "-L", "DEBUG", + NULL); + if (NULL == ws->webhook_proc) + { + GNUNET_break (0); + TALER_TESTING_interpreter_fail (is); + return; + } + TALER_TESTING_wait_for_sigchld (is); +} + + +/** + * Free the state of a "webhook" CMD, and possibly + * kills its process if it did not terminate regularly. + * + * @param cls closure. + * @param cmd the command being freed. + */ +static void +webhook_cleanup (void *cls, + const struct TALER_TESTING_Command *cmd) +{ + struct WebhookState *ws = cls; + + (void) cmd; + if (NULL != ws->webhook_proc) + { + GNUNET_break (0 == + GNUNET_OS_process_kill (ws->webhook_proc, + SIGKILL)); + GNUNET_OS_process_wait (ws->webhook_proc); + GNUNET_OS_process_destroy (ws->webhook_proc); + ws->webhook_proc = NULL; + } + GNUNET_free (ws); +} + + +/** + * Offer "webhook" CMD internal data to other commands. + * + * @param cls closure. + * @param[out] ret result. + * @param trait name of the trait. + * @param index index number of the object to offer. + * @return #GNUNET_OK on success. + */ +static enum GNUNET_GenericReturnValue +webhook_traits (void *cls, + const void **ret, + const char *trait, + unsigned int index) +{ + struct WebhookState *ws = cls; + struct TALER_TESTING_Trait traits[] = { + TALER_TESTING_make_trait_process (&ws->webhook_proc), + TALER_TESTING_trait_end () + }; + + return TALER_TESTING_get_trait (traits, + ret, + trait, + index); +} + + +struct TALER_TESTING_Command +TALER_TESTING_cmd_webhook (const char *label, + const char *config_filename) +{ + struct WebhookState *ws; + + ws = GNUNET_new (struct WebhookState); + ws->config_filename = config_filename; + + { + struct TALER_TESTING_Command cmd = { + .cls = ws, + .label = label, + .run = &webhook_run, + .cleanup = &webhook_cleanup, + .traits = &webhook_traits + }; + + return cmd; + } +} + + +/* end of testing_api_cmd_webhook.c */ diff --git a/src/testing/testing_api_helpers.c b/src/testing/testing_api_helpers.c index ea7f2dea..dbc7a6eb 100644 --- a/src/testing/testing_api_helpers.c +++ b/src/testing/testing_api_helpers.c @@ -1,4 +1,3 @@ - /* This file is part of TALER Copyright (C) 2014-2018 Taler Systems SA @@ -22,153 +21,51 @@ * @file testing_api_helpers.c * @brief helper functions for test library. * @author Christian Grothoff - * @author Marcello Stanisci */ - #include "platform.h" #include <taler/taler_exchange_service.h> #include <taler/taler_testing_lib.h> #include "taler_merchant_testing_lib.h" -struct GNUNET_OS_Process * -TALER_TESTING_run_merchant (const char *config_filename, - const char *merchant_url) -{ - struct GNUNET_OS_Process *merchant_proc; - unsigned int iter; - char *wget_cmd; - - merchant_proc - = GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_ALL, - NULL, NULL, NULL, - "taler-merchant-httpd", - "taler-merchant-httpd", - "--log=INFO", - "-c", config_filename, - NULL); - if (NULL == merchant_proc) - MERCHANT_FAIL (); - - GNUNET_asprintf (&wget_cmd, - "wget -q -t 1 -T 1" - " --header='Authorization: ApiKey sandbox'" - " %s" - " -o /dev/null -O /dev/null", - merchant_url); - - /* give child time to start and bind against the socket */ - fprintf (stderr, - "Waiting for `taler-merchant-httpd' to be ready\n"); - iter = 0; - do - { - if (10 == iter) - { - fprintf (stderr, - "Failed to launch" - " `taler-merchant-httpd' (or `wget')\n"); - GNUNET_OS_process_kill (merchant_proc, - SIGTERM); - GNUNET_OS_process_wait (merchant_proc); - GNUNET_OS_process_destroy (merchant_proc); - MERCHANT_FAIL (); - } - fprintf (stderr, ".\n"); - sleep (1); - iter++; - } - while (0 != system (wget_cmd)); - GNUNET_free (wget_cmd); - fprintf (stderr, "\n"); - - return merchant_proc; -} - - char * -TALER_TESTING_prepare_merchant (const char *config_filename) +TALER_MERCHANT_TESTING_extract_host (const char *merchant_url) { - struct GNUNET_CONFIGURATION_Handle *cfg; - unsigned long long port; - struct GNUNET_OS_Process *dbinit_proc; - enum GNUNET_OS_ProcessStatusType type; - unsigned long code; - char *base_url; + const char *hosts = strchr (merchant_url, '/'); + const char *hend; + const char *pstr; + const char *pend; + char *host; - cfg = GNUNET_CONFIGURATION_create (); - if (GNUNET_OK != - GNUNET_CONFIGURATION_load (cfg, - config_filename)) - MERCHANT_FAIL (); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, - "merchant", - "PORT", - &port)) + if (NULL == hosts) { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "merchant", - "PORT"); - GNUNET_CONFIGURATION_destroy (cfg); - MERCHANT_FAIL (); + GNUNET_break (0); + return NULL; } - - GNUNET_CONFIGURATION_destroy (cfg); - - if (GNUNET_OK != - GNUNET_NETWORK_test_port_free (IPPROTO_TCP, - (uint16_t) port)) + if (hosts[1] != '/') { - fprintf (stderr, - "Required port %llu not available, skipping.\n", - port); - MERCHANT_FAIL (); + GNUNET_break (0); + return NULL; } - - /* DB preparation */ - if (NULL == (dbinit_proc = GNUNET_OS_start_process ( - GNUNET_OS_INHERIT_STD_ALL, - NULL, NULL, NULL, - "taler-merchant-dbinit", - "taler-merchant-dbinit", - "-c", config_filename, - "-r", - NULL))) + hosts += 2; + pstr = strchr (hosts, ':'); + if (NULL == pstr) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to run taler-merchant-dbinit. Check your PATH.\n"); - MERCHANT_FAIL (); + hend = &hosts[strlen (hosts)]; + pstr = "80"; + pend = &pstr[2]; } - - if (GNUNET_SYSERR == - GNUNET_OS_process_wait_status (dbinit_proc, - &type, - &code)) + else { - GNUNET_OS_process_destroy (dbinit_proc); - MERCHANT_FAIL (); + hend = pstr; + pstr++; + pend = strchr (pstr, '/'); } - if ( (type == GNUNET_OS_PROCESS_EXITED) && - (0 != code) ) - { - fprintf (stderr, - "Failed to setup database\n"); - MERCHANT_FAIL (); - } - if ( (type != GNUNET_OS_PROCESS_EXITED) || - (0 != code) ) - { - fprintf (stderr, - "Unexpected error running" - " `taler-merchant-dbinit'!\n"); - MERCHANT_FAIL (); - } - GNUNET_OS_process_destroy (dbinit_proc); - - - GNUNET_asprintf (&base_url, - "http://localhost:%llu/", - port); - return base_url; + GNUNET_asprintf (&host, + "%.*s:%.*s", + (int) (hend - hosts), + hosts, + (int) (pend - pstr), + pstr); + return host; } |