588 lines
20 KiB
Python
588 lines
20 KiB
Python
import logging
|
|
from unittest.mock import patch
|
|
|
|
from django.test import TransactionTestCase
|
|
|
|
from core.clients.aggregator import AggregatorClient
|
|
from core.models import Aggregator, Platform, Trade, Transaction, User
|
|
|
|
|
|
class TestTransactions(TransactionTestCase):
|
|
def setUp(self):
|
|
logging.disable(logging.CRITICAL)
|
|
self.user = User.objects.create_user(
|
|
username="testuser", email="test@example.com", password="test"
|
|
)
|
|
self.aggregator = Aggregator.objects.create(
|
|
user=self.user,
|
|
name="Test",
|
|
service="nordigen",
|
|
secret_id="a",
|
|
secret_key="a",
|
|
)
|
|
|
|
self.agg_client = AggregatorClient()
|
|
self.agg_client.instance = self.aggregator
|
|
|
|
self.platform = Platform.objects.create(
|
|
user=self.user,
|
|
name="Test",
|
|
service="agora",
|
|
token="a",
|
|
password="a",
|
|
otp_token="a",
|
|
username="myuser",
|
|
)
|
|
self.transaction = Transaction.objects.create(
|
|
aggregator=self.aggregator,
|
|
account_id="my account id",
|
|
transaction_id="BANKTX",
|
|
amount=1,
|
|
currency="GBP",
|
|
note="TEST-1",
|
|
)
|
|
|
|
self.trades = {
|
|
1: {
|
|
"contact_id": "uuid1",
|
|
"buyer": "test_buyer_1",
|
|
"currency": "GBP",
|
|
"asset": "XMR",
|
|
"amount_fiat": 1,
|
|
"amount_crypto": 0.3,
|
|
"reference": "TEST-1",
|
|
"provider": "REVOLUT",
|
|
},
|
|
2: {
|
|
"contact_id": "uuid2",
|
|
"buyer": "test_buyer_2",
|
|
"currency": "GBP",
|
|
"asset": "XMR",
|
|
"amount_fiat": 1,
|
|
"amount_crypto": 0.3,
|
|
"reference": "TEST-2",
|
|
"provider": "REVOLUT",
|
|
},
|
|
3: {
|
|
"contact_id": "uuid3",
|
|
"buyer": "test_buyer_3",
|
|
"currency": "GBP",
|
|
"asset": "XMR",
|
|
"amount_fiat": 1000,
|
|
"amount_crypto": 3,
|
|
"reference": "TEST-3",
|
|
"provider": "REVOLUT",
|
|
},
|
|
4: {
|
|
"contact_id": "uuid4",
|
|
"buyer": "test_buyer_4",
|
|
"currency": "GBP",
|
|
"asset": "XMR",
|
|
"amount_fiat": 10,
|
|
"amount_crypto": 0.5,
|
|
"reference": "TEST-4",
|
|
"provider": "REVOLUT",
|
|
},
|
|
5: { # to conflict with 1
|
|
"contact_id": "uuid1",
|
|
"buyer": "test_buyer_2",
|
|
"currency": "GBP",
|
|
"asset": "XMR",
|
|
"amount_fiat": 1,
|
|
"amount_crypto": 0.3,
|
|
"reference": "TEST-1",
|
|
"provider": "REVOLUT",
|
|
},
|
|
}
|
|
|
|
def create_trades(self, *numbers):
|
|
for trade_key in self.trades.keys():
|
|
if trade_key in numbers:
|
|
Trade.objects.create(
|
|
platform=self.platform,
|
|
# open=True,
|
|
**self.trades[trade_key],
|
|
)
|
|
|
|
def mock_to_usd(self, amount, currency):
|
|
if currency == "GBP":
|
|
return amount * 1.3
|
|
elif currency == "USD":
|
|
return amount
|
|
# fuck it who cares
|
|
elif currency == "SEK":
|
|
return 100
|
|
elif currency == "EUR":
|
|
return 10
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_reference_partial_check(self, _):
|
|
self.create_trades(1, 2, 3, 4)
|
|
|
|
result = await self.agg_client.reference_partial_check(
|
|
self.platform,
|
|
"TEST-1",
|
|
"for notifications only",
|
|
"GBP",
|
|
1,
|
|
)
|
|
self.assertEqual(result, "TEST-1")
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_reference_partial_check_subset(self, _):
|
|
self.create_trades(1, 2, 3, 4)
|
|
|
|
result = await self.agg_client.reference_partial_check(
|
|
self.platform,
|
|
"the TEST-1 in string",
|
|
"for notifications only",
|
|
"GBP",
|
|
1,
|
|
)
|
|
self.assertEqual(result, "TEST-1")
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_reference_partial_check_multiple_match(self, _):
|
|
self.create_trades(1, 2, 3, 4, 5)
|
|
|
|
result = await self.agg_client.reference_partial_check(
|
|
self.platform,
|
|
"TEST-1",
|
|
"for notifications only",
|
|
"GBP",
|
|
1,
|
|
)
|
|
self.assertEqual(result, False)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_reference_partial_check_none(self, _):
|
|
# self.create_trades(1, 2, 3, 4, 5)
|
|
|
|
result = await self.agg_client.reference_partial_check(
|
|
self.platform,
|
|
"TEST-1",
|
|
"for notifications only",
|
|
"GBP",
|
|
1,
|
|
)
|
|
self.assertEqual(result, None)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_reference_partial_check_none_match(self, _):
|
|
self.create_trades(1, 2, 3, 4, 5)
|
|
|
|
result = await self.agg_client.reference_partial_check(
|
|
self.platform,
|
|
"NOWHERE",
|
|
"for notifications only",
|
|
"GBP",
|
|
1,
|
|
)
|
|
self.assertEqual(result, None)
|
|
|
|
def test_valid_transaction(self):
|
|
result = self.agg_client.valid_transaction(self.transaction)
|
|
self.assertEqual(result, True)
|
|
|
|
def test_valid_transaction_fail(self):
|
|
self.transaction.amount = -100
|
|
result = self.agg_client.valid_transaction(self.transaction)
|
|
self.assertEqual(result, False)
|
|
|
|
self.transaction.amount = 1
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
async def test_can_alt_lookup(self, *args):
|
|
result = await self.agg_client.can_alt_lookup(
|
|
self.platform,
|
|
999999999, # ignored
|
|
"GBP",
|
|
"IGNORED",
|
|
)
|
|
|
|
self.assertEqual(result, True)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=500)
|
|
async def test_can_alt_lookup_fail(self, *args):
|
|
result = await self.agg_client.can_alt_lookup(
|
|
self.platform,
|
|
999999999, # ignored
|
|
"GBP",
|
|
"IGNORED",
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
def test_find_trade(self):
|
|
self.create_trades(1, 3, 4)
|
|
|
|
result = self.agg_client.find_trade(
|
|
self.platform,
|
|
"BANKTX",
|
|
"GBP",
|
|
1,
|
|
)
|
|
|
|
self.assertEqual(result.reference, "TEST-1")
|
|
self.assertEqual(result.currency, "GBP")
|
|
self.assertEqual(result.amount_fiat, 1)
|
|
|
|
def test_find_trade_fail_two_match(self):
|
|
self.create_trades(1, 2, 3, 4) # 2 trades with same amount and currency
|
|
result = self.agg_client.find_trade(
|
|
self.platform,
|
|
"BANKTX",
|
|
"GBP",
|
|
1,
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
def test_find_trade_fail_two_match_alt(self):
|
|
self.create_trades(1, 3, 4)
|
|
result = self.agg_client.find_trade(
|
|
self.platform,
|
|
"BANKTX",
|
|
"GBP",
|
|
88,
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
async def test_amount_currency_lookup(self, *args):
|
|
self.create_trades(1, 3, 4)
|
|
result = await self.agg_client.amount_currency_lookup(
|
|
self.platform,
|
|
1,
|
|
"GBP",
|
|
"BANKTX",
|
|
"TEST-1",
|
|
)
|
|
|
|
self.assertEqual(result.reference, "TEST-1")
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
async def test_amount_currency_lookup_fail(self, *args):
|
|
self.create_trades(1, 3, 4)
|
|
result = await self.agg_client.amount_currency_lookup(
|
|
self.platform,
|
|
88,
|
|
"GBP",
|
|
"BANKTX",
|
|
"TEST-1",
|
|
)
|
|
|
|
self.assertEqual(result, None)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=500)
|
|
async def test_amount_currency_lookup_fail_too_high(self, *args):
|
|
self.create_trades(1, 3, 4)
|
|
result = await self.agg_client.amount_currency_lookup(
|
|
self.platform,
|
|
1,
|
|
"GBP",
|
|
"BANKTX",
|
|
"TEST-1",
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_normal_lookup(self, _):
|
|
self.create_trades(1, 2, 3, 4)
|
|
|
|
result = await self.agg_client.normal_lookup(
|
|
self.platform,
|
|
"TEST-1",
|
|
"BANKTX",
|
|
"GBP",
|
|
1,
|
|
)
|
|
|
|
self.assertEqual(result.reference, "TEST-1")
|
|
self.assertEqual(result.currency, "GBP")
|
|
self.assertEqual(result.amount_fiat, 1)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_currency_check(self, _):
|
|
self.create_trades(1)
|
|
trade = Trade.objects.all().first()
|
|
result = await self.agg_client.currency_check(
|
|
"GBP",
|
|
trade,
|
|
)
|
|
|
|
self.assertEqual(result, True)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
async def test_currency_check_fail(self, _):
|
|
self.create_trades(1)
|
|
trade = Trade.objects.all().first()
|
|
result = await self.agg_client.currency_check(
|
|
"AYZ",
|
|
trade,
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
async def test_alt_amount_check(self, *args):
|
|
self.create_trades(1)
|
|
trade = Trade.objects.all().first()
|
|
|
|
result = await self.agg_client.alt_amount_check(
|
|
self.platform,
|
|
1.123,
|
|
"GBP",
|
|
trade,
|
|
)
|
|
|
|
self.assertEqual(result, True)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
async def test_alt_amount_check_fail(self, *args):
|
|
self.create_trades(1)
|
|
trade = Trade.objects.all().first()
|
|
|
|
result = await self.agg_client.alt_amount_check(
|
|
self.platform,
|
|
1.501,
|
|
"GBP",
|
|
trade,
|
|
)
|
|
|
|
self.assertEqual(result, False)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_called_once_with("uuid1", "TEST-1")
|
|
self.assertEqual(self.transaction.reconciled, True)
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_second(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.note = "TEST-2"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_called_once_with("uuid2", "TEST-2")
|
|
self.assertEqual(self.transaction.reconciled, True)
|
|
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_invalid(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.amount = -1
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|
|
|
|
# def test_transaction_malformed(self):
|
|
# malformed_data = self.test_data_copy
|
|
# del malformed_data["amount"]
|
|
# self.transactions.transaction(malformed_data)
|
|
# self.transactions.release_funds.assert_not_called()
|
|
|
|
# malformed_data = self.test_data_copy
|
|
# del malformed_data["currency"]
|
|
# self.transactions.transaction(malformed_data)
|
|
# self.transactions.release_funds.assert_not_called()
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_no_reference_fail(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.note = "none"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1.5)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_no_reference_pass(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1)
|
|
self.transaction.note = "none"
|
|
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_called_with("uuid1", "TEST-1")
|
|
self.assertEqual(self.transaction.reconciled, True)
|
|
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1000)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_large(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.amount = 1000
|
|
self.transaction.note = "TEST-3"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_called_once_with("uuid3", "TEST-3")
|
|
self.assertEqual(self.transaction.reconciled, True)
|
|
|
|
self.transaction_amount_fiat = 1
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=1000)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_no_reference_exceeds_max(
|
|
self, release, gam, to_usd, sendmsg
|
|
):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.amount = 1000
|
|
self.transaction.note = "noref"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_wrong_currency(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.currency = "EUR"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.currency = "GBP"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_wrong_currency_noref(
|
|
self, release, gam, to_usd, sendmsg
|
|
):
|
|
self.transaction.currency = "EUR"
|
|
self.transaction.note = "none"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.currency = "GBP"
|
|
self.transaction.note = "TEST-1"
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.8, 1.8)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_wrong_amount(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.amount = 10
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.8, 1.8)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_wrong_amount_noref(self, release, gam, to_usd, sendmsg):
|
|
self.transaction.amount = 10
|
|
self.transaction.note = "none"
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|
|
self.transaction.note = "TEST-1"
|
|
|
|
# def test_transaction_pending(self):
|
|
# pending_tx = self.test_data_copy
|
|
# pending_tx["data"]["state"] = "pending"
|
|
# self.transactions.transaction(pending_tx)
|
|
# self.transactions.release_funds.assert_not_called()
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_too_low(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
|
|
self.transaction.amount = 5
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|
|
|
|
@patch("core.lib.notify.sendmsg")
|
|
@patch("core.clients.aggregator.money.to_usd", return_value=100)
|
|
@patch(
|
|
"core.clients.aggregator.money.get_acceptable_margins", return_value=(0.5, 1)
|
|
)
|
|
@patch("core.clients.aggregator.AgoraClient.release_trade_escrow")
|
|
async def test_transaction_too_high(self, release, gam, to_usd, sendmsg):
|
|
self.create_trades(1, 2, 3, 4)
|
|
self.transaction.amount = 15
|
|
await self.agg_client.transaction([self.platform], self.transaction)
|
|
release.assert_not_called()
|
|
self.assertEqual(self.transaction.reconciled, False)
|
|
|
|
self.transaction.amount = 1
|