wallet-core/tests/test_withdrawal.py
2020-07-29 09:33:41 -03:00

157 lines
6.6 KiB
Python

#!/usr/bin/env python3
from taler.util.amount import Amount
from tests import check_single_balance
def test_withdrawal(exchange, bank, wallet):
bank_user = bank.register_random_user()
# assert that we start with no transactions
result = wallet.cmd("getTransactions")
assert not result["transactions"]
# test withdrawal
amount_raw = Amount.parse("TESTKUDOS:5")
wallet.testing_withdraw(amount_raw.stringify(), exchange.url, bank.url)
# check that balance is correct
result = wallet.cmd("getBalances")
amount_effective = Amount("TESTKUDOS", 4, 84000000)
check_single_balance(result["balances"], amount_effective)
# assert that withdrawal shows up properly in transactions
result = wallet.cmd("getTransactions")
assert len(result["transactions"]) == 1
transaction = result["transactions"][0]
assert transaction["type"] == "withdrawal"
assert Amount.parse(transaction["amountEffective"]) == amount_effective
assert Amount.parse(transaction["amountRaw"]) == amount_raw
assert transaction["exchangeBaseUrl"] == exchange.url
assert not transaction["pending"]
withdrawal_details = transaction["withdrawalDetails"]
assert withdrawal_details["type"] == "manual-transfer"
payto_list = ["payto://x-taler-bank/localhost/Exchange"]
assert withdrawal_details["exchangePaytoUris"] == payto_list
# get a withdrawal URI
bank_uri_resp = bank.generate_withdraw_uri(bank_user, "TESTKUDOS:5")
uri = bank_uri_resp.taler_withdraw_uri
assert uri.startswith("taler+http://withdraw")
# get withdrawal details from URI
result = wallet.cmd("getWithdrawalDetailsForUri", {"talerWithdrawUri": uri})
assert Amount.parse(result["amount"]) == amount_raw
assert result["defaultExchangeBaseUrl"] == exchange.url
assert len(result["possibleExchanges"]) == 1
assert result["possibleExchanges"][0]["exchangeBaseUrl"] == exchange.url
assert result["possibleExchanges"][0]["currency"] == "TESTKUDOS"
assert result["possibleExchanges"][0]["paytoUris"] == payto_list
# check withdrawal details for amount
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
result = wallet.cmd("getWithdrawalDetailsForAmount", request)
assert Amount.parse(result["amountRaw"]) == amount_raw
assert Amount.parse(result["amountEffective"]) == amount_effective
assert result["paytoUris"] == payto_list
assert not result["tosAccepted"]
# get ToS
result = wallet.cmd("getExchangeTos", {"exchangeBaseUrl": exchange.url})
assert result["currentEtag"] == exchange.terms_etag
assert result["tos"] == exchange.tos
# accept ToS
request = {"exchangeBaseUrl": exchange.url, "etag": exchange.terms_etag}
wallet.cmd("setExchangeTosAccepted", request)
# check that ToS are now shown as accepted
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
result = wallet.cmd("getWithdrawalDetailsForAmount", request)
assert result["tosAccepted"]
# accept withdrawal
request = {"exchangeBaseUrl": exchange.url, "talerWithdrawUri": uri}
result = wallet.cmd("acceptBankIntegratedWithdrawal", request)
assert result["confirmTransferUrl"].startswith(bank.url + "confirm-withdrawal/")
confirm_url = result["confirmTransferUrl"]
# Let the wallet do its work. At this point, the bank-integrated
# withdrawal won't have succeeded yet, as it's not confirmed at the bank side.
wallet.run_pending()
# check that balance is correct
result = wallet.cmd("getBalances")
check_single_balance(result["balances"], amount_effective, amount_effective)
# assert that 2nd withdrawal shows up properly in transactions
result = wallet.cmd("getTransactions")
assert len(result["transactions"]) == 2
transaction = result["transactions"][0]
assert transaction["type"] == "withdrawal"
assert Amount.parse(transaction["amountEffective"]) == amount_effective
assert Amount.parse(transaction["amountRaw"]) == amount_raw
assert transaction["exchangeBaseUrl"] == exchange.url
assert transaction["pending"]
withdrawal_details = transaction["withdrawalDetails"]
assert withdrawal_details["type"] == "taler-bank-integration-api"
assert not withdrawal_details["confirmed"]
assert withdrawal_details["bankConfirmationUrl"] == confirm_url
# new withdrawal is newer than old one
timestamp0 = result["transactions"][0]["timestamp"]["t_ms"]
timestamp1 = result["transactions"][1]["timestamp"]["t_ms"]
assert timestamp0 > timestamp1
# now we actually confirm the withdrawal
bank.confirm_withdrawal(bank_user, bank_uri_resp.withdrawal_id)
# It might take some time until the exchange knows about the reserve,
# so we'll try until it works.
wallet.run_until_done()
# check that balance is correct
result = wallet.cmd("getBalances")
check_single_balance(
result["balances"], Amount.parse("TESTKUDOS:9.68"), Amount.parse("TESTKUDOS:0"),
)
# check that transaction is no longer pending, but confirmed
result = wallet.cmd("getTransactions")
assert len(result["transactions"]) == 2
transaction = result["transactions"][1] # TODO this transaction should be at the top now
assert transaction["type"] == "withdrawal"
assert not transaction["pending"]
assert transaction["withdrawalDetails"]["confirmed"]
# one more manual withdrawal
request = {"exchangeBaseUrl": exchange.url, "amount": amount_raw.stringify()}
result = wallet.cmd("acceptManualWithdrawal", request)
assert len(result["exchangePaytoUris"]) == 1
result["exchangePaytoUris"][0].startswith(payto_list[0])
# check that balance is correct
result = wallet.cmd("getBalances")
check_single_balance(
result["balances"], amount_effective + amount_effective, amount_effective
)
# assert that 3nd withdrawal shows up properly in transactions
result = wallet.cmd("getTransactions")
assert len(result["transactions"]) == 3
transaction = result["transactions"][0]
assert transaction["type"] == "withdrawal"
assert Amount.parse(transaction["amountEffective"]) == amount_effective
assert Amount.parse(transaction["amountRaw"]) == amount_raw
assert transaction["exchangeBaseUrl"] == exchange.url
assert transaction["pending"]
withdrawal_details = transaction["withdrawalDetails"]
assert withdrawal_details["type"] == "manual-transfer"
assert len(withdrawal_details["exchangePaytoUris"]) == 1
assert withdrawal_details["exchangePaytoUris"][0].startswith(payto_list[0])
# last withdrawal is newest
timestamp3 = transaction["timestamp"]["t_ms"]
assert timestamp3 > timestamp0
assert timestamp3 > timestamp1