merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

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"