test_merchant_order_refund.sh (8465B)
1 #!/usr/bin/env bash 2 # This file is in the public domain. 3 4 set -eu 5 6 function clean_wallet() { 7 echo rm -f "${WALLET_DB}" 8 rm -f "${HTML_RESPONSE}" 9 exit_cleanup 10 } 11 12 function assert_html_contains() { 13 if ! grep -Fq -- "$2" "$1" 14 then 15 cat "$1" >&2 16 exit_fail "Expected rendered HTML to contain: $2" 17 fi 18 } 19 20 function assert_html_rendered() { 21 if grep -Fq -- '{{' "$1" 22 then 23 cat "$1" >&2 24 exit_fail "Rendered HTML contains unresolved Mustache markup" 25 fi 26 } 27 28 29 # Replace with 0 for nexus... 30 USE_FAKEBANK=1 31 if [ 1 = "$USE_FAKEBANK" ] 32 then 33 ACCOUNT="exchange-account-2" 34 BANK_FLAGS="-f -d x-taler-bank -u $ACCOUNT" 35 BANK_URL="http://localhost:8082/" 36 else 37 ACCOUNT="exchange-account-1" 38 BANK_FLAGS="-ns -d iban -u $ACCOUNT" 39 BANK_URL="http://localhost:18082/" 40 echo -n "Testing for libeufin-bank" 41 libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING" 42 echo " FOUND" 43 44 fi 45 46 . setup.sh 47 48 echo -n "Testing for taler-harness" 49 taler-harness --help >/dev/null </dev/null || exit_skip " MISSING" 50 echo " FOUND" 51 52 # Launch exchange, merchant and bank. 53 setup -c "test_template.conf" \ 54 -em \ 55 -r "merchant-exchange-default" \ 56 $BANK_FLAGS 57 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX) 58 HTML_RESPONSE="${LAST_RESPONSE}.html" 59 CONF="test_template.conf.edited" 60 WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX) 61 EXCHANGE_URL="http://localhost:8081/" 62 63 # Install cleanup handler (except for kill -9) 64 trap clean_wallet EXIT 65 66 echo -n "First prepare wallet with coins ..." 67 rm -f "$WALLET_DB" 68 taler-wallet-cli \ 69 --no-throttle \ 70 --wallet-db="$WALLET_DB" \ 71 api \ 72 --expect-success 'withdrawTestBalance' \ 73 "$(jq -n ' 74 { 75 amount: "TESTKUDOS:99", 76 corebankApiBaseUrl: $BANK_URL, 77 exchangeBaseUrl: $EXCHANGE_URL 78 }' \ 79 --arg BANK_URL "${BANK_URL}" \ 80 --arg EXCHANGE_URL "$EXCHANGE_URL" 81 )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out 82 echo -n "." 83 # FIXME-MS: add logic to have nexus check immediately here. 84 # sleep 10 85 echo -n "." 86 # NOTE: once libeufin can do long-polling, we should 87 # be able to reduce the delay here and run wirewatch 88 # always in the background via setup 89 taler-exchange-wirewatch \ 90 -a "$ACCOUNT" \ 91 -L "INFO" \ 92 -c "$CONF" \ 93 -t &> taler-exchange-wirewatch.out 94 echo -n "." 95 timeout 60 taler-wallet-cli \ 96 --wallet-db="$WALLET_DB" \ 97 run-until-done \ 98 2>wallet-withdraw-finish-1.err \ 99 >wallet-withdraw-finish-1.out 100 echo " OK" 101 102 CURRENCY_COUNT=$(taler-wallet-cli --wallet-db="$WALLET_DB" balance | jq '.balances|length') 103 if [ "$CURRENCY_COUNT" = "0" ] 104 then 105 exit_fail "Expected least one currency, withdrawal failed. check log." 106 fi 107 108 # 109 # CREATE INSTANCE FOR TESTING 110 # 111 112 echo -n "Configuring merchant instance ..." 113 114 STATUS=$(curl -H "Content-Type: application/json" -X POST \ 115 -H 'Authorization: Bearer secret-token:super_secret' \ 116 http://localhost:9966/management/instances \ 117 -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \ 118 -w "%{http_code}" -s -o /dev/null) 119 120 if [ "$STATUS" != "204" ] 121 then 122 exit_fail "Expected '204 No content' response. Got instead $STATUS" 123 fi 124 echo "Ok" 125 126 echo -n "Configuring merchant account ..." 127 128 if [ 1 = "$USE_FAKEBANK" ] 129 then 130 FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree" 131 else 132 FORTYTHREE=$(get_payto_uri fortythree x) 133 fi 134 # create with 2 bank account addresses 135 STATUS=$(curl -H "Content-Type: application/json" -X POST \ 136 -H 'Authorization: Bearer secret-token:super_secret' \ 137 http://localhost:9966/private/accounts \ 138 -d '{"payto_uri":"'"$FORTYTHREE"'"}' \ 139 -w "%{http_code}" -s -o /dev/null) 140 141 if [ "$STATUS" != "200" ] 142 then 143 exit_fail "Expected '200 OK' response. Got instead $STATUS" 144 fi 145 146 echo "Ok" 147 148 149 # 150 # CREATE ORDER AND SELL IT 151 # 152 153 echo -n "Creating order to be paid..." 154 STATUS=$(curl 'http://localhost:9966/private/orders' \ 155 -d '{"order":{"amount":"TESTKUDOS:5","summary":"payme","auto_refund":{"d_us":180000000}}}' \ 156 -w "%{http_code}" -s -o "$LAST_RESPONSE") 157 158 if [ "$STATUS" != "200" ] 159 then 160 jq . < "$LAST_RESPONSE" 161 exit_fail "Expected 200, order created. got: $STATUS" 162 fi 163 164 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE") 165 TOKEN=$(jq -e -r .token < "$LAST_RESPONSE") 166 167 RESPONSE_HEADERS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ 168 -w "%{header_json}" \ 169 -s \ 170 -o "$LAST_RESPONSE") 171 172 ETAG=$(echo "$RESPONSE_HEADERS" | jq -r .etag[0]) 173 ETAG_NQ=$(echo "$ETAG" | tr -d '"') 174 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE") 175 176 echo "OK" 177 178 LP_START=$(date +%s) 179 180 echo -n "Long-polling for order status change paid..." 181 182 curl "http://localhost:9966/private/orders/${ORDER_ID}?timeout_ms=30000&lp_not_etag=${ETAG_NQ}" \ 183 -H "If-none-match: $ETAG" \ 184 -w "%{header_json}" \ 185 -s \ 186 -o "${LAST_RESPONSE}-long-poll" & 187 LP_PID="$!" 188 189 # 190 # PAY THE ORDER 191 # 192 193 # FIXME: use claim-only first: 194 # $ taler-wallet-cli api 'preparePayForUri' '{"talerPayUri":"taler://pay/backend.demo.taler.net/instances/blog/2026.035-0184YVPMMWKKE/b4f09f9c-f863-4805-9caf-4f849e5eb34b?c=0P603WJ9T6TYTC7Z6QRDFXEJQ0"}' 195 196 197 # set -x 198 PAYMENT_START=$(date +%s) 199 echo "Pay first order ${PAY_URL} ..." 200 taler-wallet-cli \ 201 --no-throttle \ 202 -V \ 203 --wallet-db="$WALLET_DB" \ 204 handle-uri "${PAY_URL}" \ 205 -y \ 206 2> wallet-pay1.err \ 207 > wallet-pay1.log 208 PAYMENT_END=$(date +%s) 209 echo " OK (payment took $(( PAYMENT_END - PAYMENT_START )) secs )" 210 211 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \ 212 -w "%{http_code}" -s -o "$LAST_RESPONSE") 213 214 if [ "$STATUS" != "200" ] 215 then 216 jq . < "$LAST_RESPONSE" 217 exit_fail "Expected 200, after pay. got: $STATUS" 218 fi 219 220 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE") 221 222 if [ "$ORDER_STATUS" != "paid" ] 223 then 224 jq . < "$LAST_RESPONSE" 225 exit_fail "Order status should be 'paid'. got: $ORDER_STATUS" 226 fi 227 228 # Wait for long-poller 229 echo -e "Wait for long-poller ..." 230 wait $LP_PID &> /dev/null 231 LP_END=$(date +%s) 232 233 if (( "$LP_END" - "$LP_START" > 10 )) 234 then 235 exit_fail "Expected long-poller to return quickly. Instead took from $LP_START to $LP_END" 236 fi 237 echo " OK" 238 239 echo -n "Sending refund for TESTKUDOS:1 ..." 240 241 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \ 242 -d '{"refund":"TESTKUDOS:1","reason":"duplicated"}' \ 243 -w "%{http_code}" \ 244 -s \ 245 -o "$LAST_RESPONSE") 246 247 if [ "$STATUS" != "200" ] 248 then 249 jq . < "$LAST_RESPONSE" 250 exit_fail "Expected 200, after refund. got: $STATUS" 251 fi 252 REFUND_URI=$(jq -e -r .taler_refund_uri < "$LAST_RESPONSE") 253 echo " OK" 254 255 echo -n "Checking refund HTML..." 256 STATUS=$(curl -H 'Accept: text/html' \ 257 "http://localhost:9966/orders/${ORDER_ID}?token=${TOKEN}" \ 258 -w "%{http_code}" -s -o "$HTML_RESPONSE") 259 if [ "$STATUS" != "200" ] 260 then 261 cat "$HTML_RESPONSE" >&2 262 exit_fail "Expected 200 refund HTML. Got: $STATUS" 263 fi 264 assert_html_contains "$HTML_RESPONSE" 'Collect your refund' 265 assert_html_contains "$HTML_RESPONSE" 'TESTKUDOS:1' 266 assert_html_contains "$HTML_RESPONSE" 'class="qr-frame"' 267 assert_html_rendered "$HTML_RESPONSE" 268 echo "OK" 269 270 REFUND_START=$(date +%s) 271 echo "First refund order ${REFUND_URI} ..." 272 set -x 273 timeout 60 taler-wallet-cli \ 274 --no-throttle \ 275 --wallet-db="$WALLET_DB" \ 276 handle-uri "${REFUND_URI}" \ 277 -y \ 278 2> wallet-refund1.err \ 279 > wallet-refund1.log 280 REFUND_END=$(date +%s) 281 echo " OK (refund1 took $(( REFUND_END - REFUND_START )) secs)" 282 283 echo -n "Increasing refund for TESTKUDOS:3 ..." 284 285 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \ 286 -d '{"refund":"TESTKUDOS:5","reason":"duplicated"}' \ 287 -w "%{http_code}" -s -o "$LAST_RESPONSE") 288 289 if [ "$STATUS" != "200" ] 290 then 291 jq . < "$LAST_RESPONSE" 292 exit_fail "Expected 200, after refund. got: $STATUS" 293 fi 294 REFUND_URI=$(jq -e -r .taler_refund_uri < "$LAST_RESPONSE") 295 echo " OK" 296 297 REFUND2_START=$(date +%s) 298 echo -n "Second refund order ${REFUND_URI} ..." 299 timeout 60 taler-wallet-cli \ 300 --no-throttle \ 301 --wallet-db="$WALLET_DB" \ 302 handle-uri "${REFUND_URI}" \ 303 -y \ 304 2> wallet-refund2.err \ 305 > wallet-refund2.log 306 REFUND2_END=$(date +%s) 307 echo " OK (refund2 took $(( REFUND2_END - REFUND_START )) secs)" 308 309 echo "TEST PASSED" 310 exit 0