test_merchant_units.sh (6417B)
1 #!/usr/bin/env bash 2 # This file is part of TALER 3 # Copyright (C) 2026 Taler Systems SA 4 # 5 # TALER is free software; you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as 7 # published by the Free Software Foundation; either version 3, or 8 # (at your option) any later version. 9 # 10 # TALER is distributed in the hope that it will be useful, but 11 # WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public 16 # License along with TALER; see the file COPYING. If not, see 17 # <http://www.gnu.org/licenses/> 18 # 19 20 set -eu 21 22 . setup.sh 23 24 function units_cleanup() 25 { 26 exit_cleanup 27 if [ -n "${LAST_RESPONSE:-}" ] 28 then 29 rm -f "$LAST_RESPONSE" 30 fi 31 } 32 33 trap units_cleanup EXIT 34 35 # Wallets get one public list of active units; private endpoints require a token. 36 function check_unit_access() 37 { 38 local BASE_URL="$1" 39 local ACCESS_TOKEN="$2" 40 local UNIT_BODY 41 local STATUS 42 local EXPECTED_UNITS 43 local ENDPOINT 44 local METHOD 45 46 UNIT_BODY=$(jq -n --arg unit_name "$BASE_URL" '{ 47 unit: "public-test-unit", unit_name_long: $unit_name, 48 unit_name_short: "ptu", unit_name_long_i18n: {de: "Testeinheit"}, 49 unit_name_short_i18n: {de: "te"}, unit_allow_fraction: true, 50 unit_precision_level: 2, unit_active: true 51 }') 52 STATUS=$(curl -s -H "Content-Type: application/json" \ 53 -H "Authorization: Bearer $ACCESS_TOKEN" \ 54 "$BASE_URL/private/units" -d "$UNIT_BODY" \ 55 -w "%{http_code}" -o "$LAST_RESPONSE") 56 if [ "$STATUS" != "204" ] 57 then 58 cat "$LAST_RESPONSE" >&2 59 exit_fail "Expected authenticated unit creation to return 204. Got: $STATUS" 60 fi 61 # Keep an inactive definition in the private catalogue only. 62 STATUS=$(curl -s -H "Content-Type: application/json" \ 63 -H "Authorization: Bearer $ACCESS_TOKEN" \ 64 "$BASE_URL/private/units" \ 65 -d "$(printf '%s' "$UNIT_BODY" | jq '.unit = "inactive-test-unit" | .unit_active = false')" \ 66 -w "%{http_code}" -o "$LAST_RESPONSE") 67 if [ "$STATUS" != "204" ] 68 then 69 exit_fail "Expected inactive unit creation to return 204. Got: $STATUS" 70 fi 71 STATUS=$(curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \ 72 "$BASE_URL/private/units" -w "%{http_code}" -o "$LAST_RESPONSE") 73 if [ "$STATUS" != "200" ] 74 then 75 exit_fail "Expected private catalogue to return 200. Got: $STATUS" 76 fi 77 jq -e 'any(.units[]; .unit == "inactive-test-unit" and .unit_active == false)' \ 78 < "$LAST_RESPONSE" > /dev/null || exit_fail "Private catalogue omits inactive unit" 79 EXPECTED_UNITS=$(jq -c '[.units[] | select(.unit_active)]' < "$LAST_RESPONSE") 80 81 STATUS=$(curl -s "$BASE_URL/units" -w "%{http_code}" -o "$LAST_RESPONSE") 82 if [ "$STATUS" != "200" ] 83 then 84 exit_fail "Expected public catalogue to return 200. Got: $STATUS" 85 fi 86 jq -e --argjson expected "$EXPECTED_UNITS" --argjson unit "$UNIT_BODY" ' 87 .units == $expected and 88 any(.units[]; .unit == $unit.unit and 89 .unit_name_long == $unit.unit_name_long and 90 .unit_name_short == $unit.unit_name_short and 91 .unit_name_long_i18n == $unit.unit_name_long_i18n and 92 .unit_name_short_i18n == $unit.unit_name_short_i18n and 93 .unit_allow_fraction == $unit.unit_allow_fraction and 94 .unit_precision_level == $unit.unit_precision_level) and 95 any(.units[]; .unit_builtin == true) 96 ' < "$LAST_RESPONSE" > /dev/null || exit_fail "Public catalogue has incorrect unit metadata" 97 for ENDPOINT in units units/public-test-unit 98 do 99 STATUS=$(curl -s "$BASE_URL/private/$ENDPOINT" \ 100 -w "%{http_code}" -o "$LAST_RESPONSE") 101 if [ "$STATUS" != "401" ] 102 then 103 exit_fail "Expected unauthenticated private unit read to return 401. Got: $STATUS" 104 fi 105 done 106 # There is no public endpoint for individual units. 107 STATUS=$(curl -s "$BASE_URL/units/public-test-unit" \ 108 -w "%{http_code}" -o "$LAST_RESPONSE") 109 if [ "$STATUS" != "404" ] 110 then 111 exit_fail "Expected public per-unit lookup to return 404. Got: $STATUS" 112 fi 113 for METHOD in POST PATCH DELETE 114 do 115 STATUS=$(curl -s -X "$METHOD" -H "Content-Type: application/json" \ 116 "$BASE_URL/units" -d "$UNIT_BODY" \ 117 -w "%{http_code}" -o "$LAST_RESPONSE") 118 if [ "$STATUS" != "405" ] 119 then 120 exit_fail "Expected $METHOD on public catalogue to return 405. Got: $STATUS" 121 fi 122 ENDPOINT=units/public-test-unit 123 if [ "$METHOD" = POST ] 124 then 125 ENDPOINT=units 126 fi 127 STATUS=$(curl -s -X "$METHOD" -H "Content-Type: application/json" \ 128 "$BASE_URL/private/$ENDPOINT" -d "$UNIT_BODY" \ 129 -w "%{http_code}" -o "$LAST_RESPONSE") 130 if [ "$STATUS" != "401" ] 131 then 132 exit_fail "Expected unauthenticated $METHOD unit request to return 401. Got: $STATUS" 133 fi 134 done 135 } 136 137 # The catalogue tests only need the merchant and its database. 138 setup -c test_template.conf -m 139 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_units_response-XXXXXX) 140 AUTH_HEADERS=() 141 142 for INSTANCE in admin second 143 do 144 echo -n "Checking unit catalogue for $INSTANCE ..." 145 INSTANCE_BODY=$(jq -n --arg id "$INSTANCE" '{ 146 auth: {method: "token", password: "unit_test_password"}, 147 id: $id, name: $id, address: {}, jurisdiction: {}, use_stefan: true, 148 default_wire_transfer_delay: {d_us: 3600000000}, 149 default_pay_delay: {d_us: 3600000000} 150 }') 151 STATUS=$(curl -s -H "Content-Type: application/json" "${AUTH_HEADERS[@]}" \ 152 http://localhost:9966/management/instances -d "$INSTANCE_BODY" \ 153 -w "%{http_code}" -o "$LAST_RESPONSE") 154 if [ "$STATUS" != "204" ] 155 then 156 cat "$LAST_RESPONSE" >&2 157 exit_fail "Expected instance creation to return 204. Got: $STATUS" 158 fi 159 TOKEN=$(merchant_login "$INSTANCE" unit_test_password) 160 if [ "$INSTANCE" = admin ] 161 then 162 AUTH_HEADERS=(-H "Authorization: Bearer $TOKEN") 163 fi 164 INSTANCE_URL=$(merchant_instance_url "$INSTANCE") 165 check_unit_access "${INSTANCE_URL%/}" "$TOKEN" 166 echo " OK" 167 done 168 169 echo "TEST PASSED"