merchant

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

test_merchant_product_creation.sh (10768B)


      1 #!/usr/bin/env bash
      2 # This file is part of TALER
      3 # Copyright (C) 2014-2023 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 # Replace with 0 for nexus...
     23 USE_FAKEBANK=1
     24 if [ 1 = "$USE_FAKEBANK" ]
     25 then
     26     ACCOUNT="exchange-account-2"
     27     WIRE_METHOD="x-taler-bank"
     28     BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT"
     29     BANK_URL="http://localhost:8082/"
     30 else
     31     echo -n "Testing for libeufin-bank"
     32     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
     33     echo " FOUND"
     34 
     35     ACCOUNT="exchange-account-1"
     36     WIRE_METHOD="iban"
     37     BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT"
     38     BANK_URL="http://localhost:18082/"
     39 fi
     40 
     41 . setup.sh
     42 
     43 
     44 echo -n "Testing for taler-harness"
     45 taler-harness --help >/dev/null </dev/null || exit_skip " MISSING"
     46 echo " FOUND"
     47 
     48 
     49 # Launch system.
     50 setup -c "test_template.conf" \
     51       -r "merchant-exchange-default" \
     52       -em \
     53       $BANK_FLAGS
     54 
     55 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
     56 WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX)
     57 CONF="test_template.conf.edited"
     58 if [ 1 = "$USE_FAKEBANK" ]
     59 then
     60     FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree"
     61 else
     62     FORTYTHREE=$(get_payto_uri fortythree x)
     63 fi
     64 EXCHANGE_URL="http://localhost:8081/"
     65 
     66 echo -n "Configuring merchant instance ..."
     67 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     68     "http://localhost:9966/management/instances" \
     69     -d '{"auth":{"method":"token","password":"super_secret"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
     70     -w "%{http_code}" -s -o /dev/null)
     71 
     72 if [ "$STATUS" != "204" ]
     73 then
     74     exit_fail "Expected 204 No content, instance created. Got $STATUS instead"
     75 fi
     76 ADMIN_TOKEN=$(merchant_login admin super_secret)
     77 
     78 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     79     -H "Authorization: Bearer $ADMIN_TOKEN" \
     80     http://localhost:9966/private/accounts \
     81     -d '{"payto_uri":"'"$FORTYTHREE"'"}' \
     82     -w "%{http_code}" -s -o /dev/null)
     83 
     84 if [ "$STATUS" != "200" ]
     85 then
     86     exit_fail "Expected 200 OK. Got: $STATUS"
     87 fi
     88 
     89 echo "OK"
     90 
     91 # The products created below are measured in "u", which is not a builtin
     92 # unit; POST/PATCH /private/products reject a unit that does not exist, so
     93 # create it first.
     94 echo -n "Creating unit for the products below ..."
     95 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     96     -H "Authorization: Bearer $ADMIN_TOKEN" \
     97     http://localhost:9966/private/units \
     98     -d '{"unit":"u","unit_name_long":"unit","unit_name_short":"u"}' \
     99     -w "%{http_code}" -s -o /dev/null)
    100 
    101 if [ "$STATUS" != "204" ]
    102 then
    103     exit_fail "Expected 204 No content, unit created. Got: $STATUS"
    104 fi
    105 
    106 echo "OK"
    107 
    108 RANDOM_IMG='data:image/png;base64,abcdefg'
    109 INFINITE_PRODUCT_TEMPLATE='{"product_id":"2","product_name":"stuff","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"-1","unit":"u","image":"'"$RANDOM_IMG"'","taxes":[]}'
    110 MANAGED_PRODUCT_TEMPLATE='{"product_id":"3","product_name":"more stuff","description":"product with id 3 and price :10","unit_price":["TESTKUDOS:150"],"unit_total_stock":"2","unit":"u","image":"'"$RANDOM_IMG"'","taxes":[]}'
    111 
    112 echo -n "Creating products..."
    113 STATUS=$(curl 'http://localhost:9966/private/products' \
    114     -H "Authorization: Bearer $ADMIN_TOKEN" \
    115     -d "$INFINITE_PRODUCT_TEMPLATE" \
    116     -w "%{http_code}" -s -o /dev/null)
    117 
    118 if [ "$STATUS" != "204" ]
    119 then
    120     exit_fail "Expected 204, product created. got: $STATUS"
    121 fi
    122 
    123 STATUS=$(curl 'http://localhost:9966/private/products' \
    124     -H "Authorization: Bearer $ADMIN_TOKEN" \
    125     -d "$MANAGED_PRODUCT_TEMPLATE" \
    126     -w "%{http_code}" -s -o /dev/null)
    127 
    128 if [ "$STATUS" != "204" ]
    129 then
    130     exit_fail "Expected 204, product created. got: $STATUS"
    131 fi
    132 echo "OK"
    133 
    134 
    135 PRODUCT_DATA=$(echo "$INFINITE_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {description: "other description"}')
    136 
    137 echo -n "Updating infinite stock product..."
    138 STATUS=$(curl 'http://localhost:9966/private/products/2' -X PATCH \
    139     -H "Authorization: Bearer $ADMIN_TOKEN" \
    140     -d "$PRODUCT_DATA" \
    141     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    142 
    143 if [ "$STATUS" != "204" ]
    144 then
    145     cat "$LAST_RESPONSE"
    146     exit_fail "Expected 204, updating product. got: $STATUS"
    147 fi
    148 
    149 STATUS=$(curl 'http://localhost:9966/private/products/2' \
    150     -H "Authorization: Bearer $ADMIN_TOKEN" \
    151     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    152 
    153 DESCRIPTION=$(jq -r .description < "$LAST_RESPONSE")
    154 
    155 if [ "$DESCRIPTION" != "other description" ]
    156 then
    157     cat "$LAST_RESPONSE"
    158     exit_fail "Expected 'other description'. Got: $DESCRIPTION"
    159 fi
    160 echo "OK"
    161 
    162 MANAGED_PRODUCT_ID=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq -r '.product_id')
    163 
    164 echo -n "Locking inventory ..."
    165 
    166 STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \
    167     -H "Authorization: Bearer $ADMIN_TOKEN" \
    168     -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"unit_quantity":"10"}' \
    169     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    170 
    171 if [ "$STATUS" != "410" ]
    172 then
    173     cat "$LAST_RESPONSE"
    174     exit_fail "Expected 410, lock failed. got: $STATUS"
    175 fi
    176 
    177 echo -n "."
    178 
    179 STATUS=$(curl "http://localhost:9966/private/products/${MANAGED_PRODUCT_ID}/lock" \
    180     -H "Authorization: Bearer $ADMIN_TOKEN" \
    181     -d '{"lock_uuid":"luck","duration":{"d_us": 100000000},"unit_quantity":"1"}' \
    182     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    183 
    184 if [ "$STATUS" != "204" ]
    185 then
    186     cat "$LAST_RESPONSE"
    187     exit_fail "Expected 204, lock created. got: $STATUS"
    188 fi
    189 echo " OK"
    190 
    191 echo -n "Creating order to be paid..."
    192 STATUS=$(curl 'http://localhost:9966/private/orders' \
    193     -H "Authorization: Bearer $ADMIN_TOKEN" \
    194     -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","unit_quantity":"1"}]}' \
    195     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    196 
    197 if [ "$STATUS" != "200" ]
    198 then
    199     cat "$LAST_RESPONSE"
    200     exit_fail "Expected 200, order created. got: $STATUS"
    201 fi
    202 
    203 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    204 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    205 
    206 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    207     -H "Authorization: Bearer $ADMIN_TOKEN" \
    208     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    209 
    210 if [ "$STATUS" != "200" ]
    211 then
    212     cat "$LAST_RESPONSE"
    213     exit_fail "Expected 200, getting order info before claming it. got: $STATUS"
    214 fi
    215 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    216 
    217 echo -n "."
    218 
    219 STATUS=$(curl 'http://localhost:9966/private/orders' \
    220     -H "Authorization: Bearer $ADMIN_TOKEN" \
    221     -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"'"${MANAGED_PRODUCT_ID}"'","unit_quantity":"1"}]}' \
    222     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    223 
    224 if [ "$STATUS" != "410" ]
    225 then
    226     cat "$LAST_RESPONSE"
    227     exit_fail "Expected 410 out of stock (what remains is locked). got: $STATUS"
    228 fi
    229 
    230 echo -n "."
    231 
    232 # Using the 'luck' inventory lock, order creation should work.
    233 STATUS=$(curl 'http://localhost:9966/private/orders' \
    234     -H "Authorization: Bearer $ADMIN_TOKEN" \
    235     -d '{"order":{"amount":"TESTKUDOS:1","summary":"payme"},"lock_uuids":["luck"],"inventory_products":[{"product_id":"'"$MANAGED_PRODUCT_ID"'","unit_quantity":"1"}]}' \
    236     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    237 
    238 if [ "$STATUS" != "200" ]
    239 then
    240     cat "$LAST_RESPONSE"
    241     exit_fail "Expected 200 OK, lock should apply. Got: $STATUS"
    242 fi
    243 echo " OK"
    244 
    245 echo -n "First withdraw wallet ..."
    246 rm -f "$WALLET_DB"
    247 taler-wallet-cli \
    248     --no-throttle \
    249     --wallet-db="$WALLET_DB" \
    250     api \
    251     --expect-success 'withdrawTestBalance' \
    252   "$(jq -n '
    253     {
    254         amount: "TESTKUDOS:5",
    255         corebankApiBaseUrl: $BANK_URL,
    256         exchangeBaseUrl: $EXCHANGE_URL
    257     }' \
    258     --arg BANK_URL "$BANK_URL" \
    259     --arg EXCHANGE_URL "$EXCHANGE_URL"
    260   )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out
    261 echo -n "."
    262 if [ 1 = "$USE_FAKEBANK" ]
    263 then
    264     # Fakebank is instant...
    265     sleep 0
    266 else
    267     sleep 10
    268     # NOTE: once libeufin can do long-polling, we should
    269     # be able to reduce the delay here and run wirewatch
    270     # always in the background via setup
    271 fi
    272 echo -n "."
    273 taler-exchange-wirewatch -L "INFO" -c "$CONF" -t &> taler-exchange-wirewatch.out
    274 echo -n "."
    275 
    276 timeout 60 taler-wallet-cli \
    277     --wallet-db="$WALLET_DB" \
    278     run-until-done \
    279     2>wallet-withdraw-finish-1.err \
    280     >wallet-withdraw-finish-1.out
    281 echo " OK"
    282 
    283 echo -n "Pay first order ..."
    284 NOW=$(date +%s)
    285 taler-wallet-cli \
    286     --no-throttle \
    287     --wallet-db="$WALLET_DB" \
    288     handle-uri "${PAY_URL}" \
    289     -y \
    290     2> wallet-pay1.err > wallet-pay1.log
    291 NOW2=$(date +%s)
    292 echo " OK (took $(( NOW2 -  NOW)) secs )"
    293 
    294 
    295 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    296     -H "Authorization: Bearer $ADMIN_TOKEN" \
    297     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    298 
    299 if [ "$STATUS" != "200" ]
    300 then
    301     cat "$LAST_RESPONSE"
    302     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    303 fi
    304 
    305 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    306 
    307 if [ "$ORDER_STATUS" != "paid" ]
    308 then
    309     cat "$LAST_RESPONSE"
    310     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    311 fi
    312 
    313 
    314 echo -n "Updating product..."
    315 
    316 PRODUCT_DATA=$(echo "$MANAGED_PRODUCT_TEMPLATE" | jq 'del(.product_id) | . + {"total_stock": (.total_stock + 2) }')
    317 
    318 STATUS=$(curl 'http://localhost:9966/private/products/3' -X PATCH \
    319     -H "Authorization: Bearer $ADMIN_TOKEN" \
    320     -d "$PRODUCT_DATA" \
    321     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    322 
    323 if [ "$STATUS" != "204" ]
    324 then
    325     cat "$LAST_RESPONSE"
    326     exit_fail "Expected 204, updating product. got: $STATUS"
    327 fi
    328 
    329 echo -n "Requesting inventory..."
    330 STATUS=$(curl 'http://localhost:9966/private/products?name_filter=more' \
    331     -H "Authorization: Bearer $ADMIN_TOKEN" \
    332     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    333 
    334 if [ "$STATUS" != "200" ]
    335 then
    336     cat "$LAST_RESPONSE"
    337     exit_fail "Expected 200. got: $STATUS"
    338 fi
    339 
    340 PRODUCT_COUNT=$(jq -r '.products|length' < "$LAST_RESPONSE")
    341 
    342 if [ "$PRODUCT_COUNT" != "1" ]
    343 then
    344     cat "$LAST_RESPONSE"
    345     exit_fail "Expected one product for the 'more'. filter, got: $PRODUCT_COUNT"
    346 fi
    347 echo " OK"
    348 
    349 echo "Test PASSED"
    350 
    351 exit 0