diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-01-16 18:11:35 +0100 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-01-16 18:11:40 +0100 |
commit | 47ff439abf85ecea69d7f281ca30a00143c8a868 (patch) | |
tree | f6bde35d3dd4fbe962c726b3dc2e032adfe7f223 /talerbank/app/tests.py | |
parent | 55addfc68f26f50425e3af84972f4d342a99939f (diff) | |
download | bank-47ff439abf85ecea69d7f281ca30a00143c8a868.tar.gz bank-47ff439abf85ecea69d7f281ca30a00143c8a868.tar.bz2 bank-47ff439abf85ecea69d7f281ca30a00143c8a868.zip |
preparations towards the new bank API
Diffstat (limited to 'talerbank/app/tests.py')
-rw-r--r-- | talerbank/app/tests.py | 691 |
1 files changed, 210 insertions, 481 deletions
diff --git a/talerbank/app/tests.py b/talerbank/app/tests.py index 87d7283..61aec9e 100644 --- a/talerbank/app/tests.py +++ b/talerbank/app/tests.py @@ -31,17 +31,23 @@ from django.urls import reverse from django.conf import settings from django.contrib.auth.models import User from mock import patch, MagicMock -from .models import BankAccount, BankTransaction, \ - BankAccountDoesNotExist, BankTransactionDoesNotExist +from .models import BankAccount, BankTransaction from . import urls from .views import wire_transfer -from taler.util.amount import Amount, CurrencyMismatch, BadFormatAmount +from taler.util.amount import ( + Amount, + SignedAmount, + CurrencyMismatchError, + AmountFormatError, +) LOGGER = logging.getLogger() -LOGGER.setLevel(logging.INFO) +LOGGER.setLevel(logging.DEBUG) -logging.disable(logging.CRITICAL) +# logging.disable(logging.CRITICAL) # reenable: logging.disable(logging.NOTSET) +logging.disable(logging.NOTSET) + def make_auth_line(username, password): credentials = "%s:%s" % (username, password) @@ -49,14 +55,13 @@ def make_auth_line(username, password): header_line = "Basic %s" % b64enc.decode() return header_line + def clear_db(): User.objects.all().delete() BankAccount.objects.all().delete() BankTransaction.objects.all().delete() with connection.cursor() as cursor: - cursor.execute( - "ALTER SEQUENCE app_bankaccount_account_no_seq" \ - " RESTART") + cursor.execute("ALTER SEQUENCE app_bankaccount_account_no_seq" " RESTART") cursor.execute("ALTER SEQUENCE app_banktransaction_id_seq RESTART") @@ -64,13 +69,9 @@ def clear_db(): # to some endpoint that needs to authenticate the # user. class MalformedLoginTestCase(TestCase): - def test_malformed_login(self): - self.client.generic( - "POST", - reverse("add-incoming", urlconf=urls), - "malformed" - ) + self.client.generic("POST", reverse("add-incoming", urlconf=urls), "malformed") + class PublicAccountsTestCase(TestCase): def setUp(self): @@ -96,22 +97,20 @@ class WithdrawTestCase(TestCase): user=User.objects.create_user( username="test_user", password="test_password" ), - account_no=100 + account_no=100, ) self.user_bank_account.save() self.exchange_bank_account = BankAccount( - user=User.objects.create_user( - username="test_exchange", password="" - ), - account_no=99 + user=User.objects.create_user(username="test_exchange", password=""), + account_no=99, ) self.exchange_bank_account.save() self.client = Client() - @patch('talerbank.app.views.wire_transfer') - @patch('hashlib.new') - @patch('time.time') + @patch("talerbank.app.views.wire_transfer") + @patch("hashlib.new") + @patch("time.time") @unittest.skip("skip outdated test case") def test_withdraw(self, mocked_time, mocked_hashlib, mocked_wire_transfer): amount = Amount(settings.TALER_CURRENCY, 0, 1) @@ -121,13 +120,11 @@ class WithdrawTestCase(TestCase): "amount_currency": amount.currency, "reserve_pub": "UVZ789", "exchange": "https://exchange.example.com/", - "exchange_wire_details": "payto://x-taler-bank/bank.example/99" + "exchange_wire_details": "payto://x-taler-bank/bank.example/99", } self.client.login(username="test_user", password="test_password") - response = self.client.get( - reverse("pin-question", urlconf=urls), params - ) + response = self.client.get(reverse("pin-question", urlconf=urls), params) self.assertEqual(response.status_code, 200) # We mock hashlib in order to fake the CAPTCHA. hasher = MagicMock() @@ -143,10 +140,11 @@ class WithdrawTestCase(TestCase): args, kwargs = mocked_wire_transfer.call_args del kwargs self.assertTrue( - args[0].dump() == amount.dump() \ - and self.user_bank_account in args \ - and "UVZ789" in args \ - and self.exchange_bank_account in args) + args[0].dump() == amount.dump() + and self.user_bank_account in args + and "UVZ789" in args + and self.exchange_bank_account in args + ) def tearDown(self): clear_db() @@ -155,10 +153,10 @@ class WithdrawTestCase(TestCase): class InternalWireTransferTestCase(TestCase): def setUp(self): BankAccount( - user=User.objects.create_user(username='give_money', password="gm") + user=User.objects.create_user(username="give_money", password="gm") ).save() self.take_money = BankAccount( - user=User.objects.create_user(username='take_money'), account_no=4 + user=User.objects.create_user(username="take_money"), account_no=4 ) self.take_money.save() @@ -169,25 +167,25 @@ class InternalWireTransferTestCase(TestCase): client = Client() client.login(username="give_money", password="gm") response = client.post( - reverse("profile", urlconf=urls), { + reverse("profile", urlconf=urls), + { "amount": 3.0, "receiver": self.take_money.account_no, - "subject": "charity" - } + "subject": "charity", + }, ) take_money = BankAccount.objects.get(account_no=4) - self.assertEqual( - 0, - Amount.cmp(Amount(settings.TALER_CURRENCY, 3), take_money.amount) - ) + r = SignedAmount.parse(f"{settings.TALER_CURRENCY}:3.0") + self.assertEqual(take_money.balance, r) self.assertEqual(302, response.status_code) class RegisterTestCase(TestCase): """User registration""" + def setUp(self): clear_db() - BankAccount(user=User.objects.create_user(username='Bank')).save() + BankAccount(user=User.objects.create_user(username="Bank")).save() def tearDown(self): clear_db() @@ -195,11 +193,9 @@ class RegisterTestCase(TestCase): def test_register(self): client = Client() response = client.post( - reverse("register", urlconf=urls), { - "username": "test_register", - "password": "test_register" - }, - follow=True + reverse("register", urlconf=urls), + {"username": "test_register", "password": "test_register"}, + follow=True, ) self.assertIn(("/profile", 302), response.redirect_chain) # this assertion tests "/profile""s view @@ -210,10 +206,8 @@ class RegisterTestCase(TestCase): # Normal case. response = client.post( - reverse("register-headless", urlconf=urls), { - "username": "test_register_headless", - "password": "password*+#@" - } + reverse("register-headless", urlconf=urls), + {"username": "test_register_headless", "password": "password*+#@"}, ) self.assertEqual(200, response.status_code) @@ -226,29 +220,27 @@ class RegisterTestCase(TestCase): # Try registering unavailable username. response = client.post( - reverse("register-headless", urlconf=urls), { - "username": "test_register_headless", - "password": "password" - } + reverse("register-headless", urlconf=urls), + {"username": "test_register_headless", "password": "password"}, ) self.assertEqual(409, response.status_code) # NOTE: Django 2.2.2 allows ANY character! Is this normal? response = client.post( - reverse("register-headless", urlconf=urls), { - "username": "'''+++;;;'''", - "password": "password2" - } + reverse("register-headless", urlconf=urls), + {"username": "'''+++;;;'''", "password": "password2"}, ) self.assertEqual(200, response.status_code) class LoginTestCase(TestCase): """User login""" + def setUp(self): BankAccount( - user=User.objects. - create_user(username="test_user", password="test_password") + user=User.objects.create_user( + username="test_user", password="test_password" + ) ).save() self.client = Client() @@ -265,178 +257,112 @@ class LoginTestCase(TestCase): def test_failing_login(self): response = self.client.get( - reverse("history", urlconf=urls), {"auth": "basic"}, **{ - "HTTP_AUTHORIZATION": make_auth_line("Wrong", "Credentials") - } + reverse("history", urlconf=urls), + {"auth": "basic"}, + HTTP_AUTHORIZATION=make_auth_line("Wrong", "Credentials"), ) data = response.content.decode("utf-8") self.assertEqual(401, response.status_code) -class AmountTestCase(TestCase): - def test_cmp(self): - amount1 = Amount("X", 1) - _amount1 = Amount("X", 1) - amount2 = Amount("X", 2) - - self.assertEqual(-1, Amount.cmp(amount1, amount2)) - self.assertEqual(1, Amount.cmp(amount2, amount1)) - self.assertEqual(0, Amount.cmp(amount1, _amount1)) - - # Trying to compare amount of different currencies - def test_cmp_diff_curr(self): - amount1 = Amount("X", 1) - amount2 = Amount("Y", 2) - with self.assertRaises(CurrencyMismatch): - Amount.cmp(amount1, amount2) - - -class RejectTestCase(TestCase): - def setUp(self): - BankAccount( - user=User.objects. - create_user(username="rejected_user", password="rejected_password") - ).save() - BankAccount( - user=User.objects.create_user( - username="rejecting_user", password="rejecting_password" - ) - ).save() - - def tearDown(self): - clear_db() - - def test_reject(self): - client = Client() - rejecting = User.objects.get(username="rejecting_user") - data = '{"auth": {"type": "basic"}, \ - "credit_account": %d, \ - "subject": "TESTWTID", \ - "exchange_url": "https://exchange.test", \ - "amount": "%s:5.0"}' \ - % (rejecting.bankaccount.account_no, - settings.TALER_CURRENCY) - response = client.post( - reverse("add-incoming", urlconf=urls), - data=data, - content_type="application/json", - follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("rejected_user", "rejected_password"), - } - ) - self.assertEqual(response.status_code, 200) - data = response.content.decode("utf-8") - jdata = json.loads(data) - rejected = User.objects.get(username="rejected_user") - response = client.put( - reverse("reject", urlconf=urls), - data='{"row_id": %d, \ - "auth": {"type": "basic"}, \ - "account_number": %d}' \ - % (jdata["row_id"], - rejected.bankaccount.account_no), - content_type="application/json", - **{ - "HTTP_AUTHORIZATION": make_auth_line("rejecting_user", "rejecting_password"), - }) - self.assertEqual(response.status_code, 204) - - class WithdrawHeadlessTestCase(TestCase): def setUp(self): BankAccount( user=User.objects.create_user( username="headless_wallet", password="headless_password" ), - amount=Amount(settings.TALER_CURRENCY, 10) + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 10, 0)), ).save() # Gets account #2, in line with config. BankAccount( user=User.objects.create_user( username="normal_exchange", password="normal_password" ), - account_no=2 + account_no=2, ).save() def test_withdraw_headless(self): client = Client() # Use default exchange. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "reserve_pub": "RESERVEPUB", \ - "amount": "%s:10"}' % settings.TALER_CURRENCY + "amount": "%s:10"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("withdraw-headless", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("headless_wallet", "headless_password") - - } + HTTP_AUTHORIZATION=make_auth_line("headless_wallet", "headless_password"), ) self.assertEqual(200, response.status_code) # Try withdrawing more than owning. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "reserve_pub": "RESERVEPUB", \ - "amount": "%s:100"}' % settings.TALER_CURRENCY + "amount": "%s:100"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("withdraw-headless", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("headless_wallet", "headless_password") - } + HTTP_AUTHORIZATION=make_auth_line("headless_wallet", "headless_password"), ) self.assertEqual(406, response.status_code) # Try withdrawing giving exchange field. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "exchange_wire_details": "payto://x-taler-bank/bank.example.com/2", \ "reserve_pub": "RESERVEPUB", \ - "amount": "%s:0.4"}' % settings.TALER_CURRENCY + "amount": "%s:0.4"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("withdraw-headless", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("headless_wallet", "headless_password") - } + HTTP_AUTHORIZATION=make_auth_line("headless_wallet", "headless_password"), ) self.assertEqual(200, response.status_code) # Try withdrawing giving non-existent recipient. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "exchange_wire_details": "payto://x-taler-bank/bank.example.com/2222", \ "reserve_pub": "RESERVEPUB", \ - "amount": "%s:0.4"}' % settings.TALER_CURRENCY + "amount": "%s:0.4"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("withdraw-headless", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("headless_wallet", "headless_password") - } + HTTP_AUTHORIZATION=make_auth_line("headless_wallet", "headless_password"), ) self.assertEqual(404, response.status_code) # Try withdrawing giving invalid JSON. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "XXX": "YYY", \ - "amount": "%s:0.4"}' % settings.TALER_CURRENCY + "amount": "%s:0.4"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("withdraw-headless", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("headless_wallet", "headless_password") - } + HTTP_AUTHORIZATION=make_auth_line("headless_wallet", "headless_password"), ) self.assertEqual(400, response.status_code) @@ -446,14 +372,17 @@ class WithdrawHeadlessTestCase(TestCase): class AddIncomingTestCase(TestCase): """Test money transfer's API""" + def setUp(self): BankAccount( - user=User.objects. - create_user(username="bank_user", password="bank_password") + user=User.objects.create_user( + username="bank_user", password="bank_password" + ) ).save() BankAccount( - user=User.objects. - create_user(username="user_user", password="user_password") + user=User.objects.create_user( + username="user_user", password="user_password" + ) ).save() def tearDown(self): @@ -461,20 +390,20 @@ class AddIncomingTestCase(TestCase): def test_add_incoming(self): client = Client() - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "credit_account": 1, \ "subject": "TESTWTID", \ "exchange_url": "https://exchange.test", \ - "amount": "%s:1.0"}' \ - % settings.TALER_CURRENCY + "amount": "%s:1.0"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("add-incoming", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("user_user", "user_password") - } + HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), ) self.assertEqual(200, response.status_code) @@ -485,10 +414,8 @@ class AddIncomingTestCase(TestCase): data=zdata, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("user_user", "user_password"), - "HTTP_CONTENT_ENCODING": "deflate" - } + HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), + HTTP_CONTENT_ENCODING="deflate", ) self.assertEqual(200, response.status_code) @@ -503,360 +430,181 @@ class AddIncomingTestCase(TestCase): data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("user_user", "user_password") - } + HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), ) # note: a bad currency request gets 400. - self.assertRaises(CurrencyMismatch) - self.assertEqual(406, response.status_code) + self.assertEqual(400, response.status_code) LOGGER.info(response.content.decode("utf-8")) # Try to go debit - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "credit_account": 1, \ "subject": "TESTWTID", \ "exchange_url": "https://exchange.test", \ - "amount": "%s:50.1"}' % settings.TALER_CURRENCY + "amount": "%s:50.1"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("add-incoming", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("user_user", "user_password") - } + HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), ) self.assertEqual(406, response.status_code) # Try use a non-existent recipient. - data = '{"auth": {"type": "basic"}, \ + data = ( + '{"auth": {"type": "basic"}, \ "credit_account": 1987, \ "subject": "TESTWTID", \ "exchange_url": "https://exchange.test", \ - "amount": "%s:1"}' % settings.TALER_CURRENCY + "amount": "%s:1"}' + % settings.TALER_CURRENCY + ) response = client.post( reverse("add-incoming", urlconf=urls), data=data, content_type="application/json", follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("user_user", "user_password") - } + HTTP_AUTHORIZATION=make_auth_line("user_user", "user_password"), ) self.assertEqual(404, response.status_code) -class HistoryContext: - def __init__(self, expected_resp, **kwargs): - self.expected_resp = expected_resp - self.urlargs = kwargs - self.urlargs.update({"auth": "basic"}) - - def dump(self): - return self.urlargs - class CustomDoesNotExistTestCase(TestCase): - def test_bankaccount_doesnotexist(self): - with self.assertRaises(BankAccountDoesNotExist): + with self.assertRaises(BankAccount.DoesNotExist): BankAccount.objects.get(account_no=1000) - with self.assertRaises(BankTransactionDoesNotExist): + with self.assertRaises(BankTransaction.DoesNotExist): BankTransaction.objects.get(subject="1000") + class HistoryTestCase(TestCase): def setUp(self): clear_db() debit_account = BankAccount( - user=User.objects.create_user(username='User', password="Password"), - amount=Amount(settings.TALER_CURRENCY, 100) + user=User.objects.create_user(username="User", password="Password"), + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 100, 0)), ) debit_account.save() credit_account = BankAccount( - user=User.objects. - create_user(username='User0', password="Password0") + user=User.objects.create_user(username="User0", password="Password0") ) credit_account.save() for subject in ("a", "b", "c", "d", "e", "f", "g", "h", "i"): wire_transfer( - Amount(settings.TALER_CURRENCY, 1), debit_account, - credit_account, subject + Amount(settings.TALER_CURRENCY, 1, 0), + debit_account, + credit_account, + subject, ) - # reject transaction 'i'. - trans_i = BankTransaction.objects.get(subject="i") - self.client = Client() - self.client.post( - reverse("reject", urlconf=urls), - data='{"auth": {"type": "basic"}, \ - "row_id": %d, \ - "account_number": 44}' % trans_i.id, # Ignored - content_type="application/json", - follow=True, - **{ - "HTTP_AUTHORIZATION": make_auth_line("User0", "Password0") - } - ) def tearDown(self): clear_db() - def assert_result(self, response, ctx): - - data = response.content.decode("utf-8") - try: - # FIXME, not always data is found this way. - data = json.loads(data)["data"][0] - except (json.JSONDecodeError, KeyError): - data = {} - self.assertEqual( - ctx.expected_resp.get("status"), - response.status_code, - "Failing request: %s?%s => raw body: %s" % \ - (response.request["PATH_INFO"], - unquote(response.request["QUERY_STRING"]), - response.content.decode("utf-8"))) - - # extract expected data from response - expected_data = {} - response_data = {} - for key, value in ctx.expected_resp.get("fields", []): - response_data.update({key: data.get(key)}) - expected_data.update({key: value}) - - self.assertEqual(expected_data, response_data) - - def test_history_range(self): - now = int(time.time()) - - for ctx in ( - - # Expect empty results, range too ancient. - HistoryContext( - expected_resp={"status": 204}, start=1, end=2, direction="both" - ), - - # Expect empty results, range too ahead. - HistoryContext( - expected_resp={"status": 200}, - start=now + 40, - end=now + 50, - direction="both" - ), - - # Expect non empty results. - HistoryContext( - expected_resp={"status": 200}, - start=now - 30, - end=now + 30, - direction="both" - ) - ): - - response = self.client.get( - reverse("history-range", urlconf=urls), ctx.urlargs, **{ - "HTTP_AUTHORIZATION": make_auth_line("User", "Password") - } - ) - - self.assert_result(response, ctx) - def test_history(self): - for ctx in ( - HistoryContext( - expected_resp={"status": 200}, delta="-4", direction="both" - ), - HistoryContext( - expected_resp={ - "fields": [("row_id", 9)], - "status": 200 - }, - delta="+1", - start="5", - direction="both" - ), - HistoryContext( - expected_resp={ - "fields": [("wt_subject", "c")], - "status": 200 - }, - delta="1", - start=2, - direction="both", - ordering="ascending" - ), - HistoryContext( - expected_resp={ - "fields": [("wt_subject", "a")], - "status": 200 - }, - delta="-1", - start=2, - direction="both" - ), - HistoryContext( - expected_resp={"status": 204}, - delta="1", - start="11", - direction="both" - ), - HistoryContext( - expected_resp={ - "status": 200, - "fields": [("wt_subject", "i"), ("sign", "cancel-")] - }, - start=8, - delta="+1", - direction="cancel-" - ), - HistoryContext( - expected_resp={"status": 204}, - start=8, - delta="+1", - direction="cancel-", - cancelled="omit" - ), - HistoryContext( - expected_resp={"status": 204}, - start=8, - delta="-1", - direction="cancel-" - ), - HistoryContext( - expected_resp={"status": 204}, delta="+1", direction="cancel+" - ), - HistoryContext( - expected_resp={"status": 200}, delta="-1", direction="debit" - ) - ): + def histquery(**urlargs): response = self.client.get( - reverse("history", urlconf=urls), ctx.urlargs, **{ - "HTTP_AUTHORIZATION": make_auth_line("User", "Password") - } + reverse("history", urlconf=urls), + urlargs, + HTTP_AUTHORIZATION=make_auth_line("User", "Password"), ) - self.assert_result(response, ctx) - - -class DBAmountSubtraction(TestCase): - def setUp(self): - BankAccount( - user=User.objects.create_user(username='U'), - amount=Amount(settings.TALER_CURRENCY, 3) - ).save() - - def tearDown(self): - clear_db() + return response + + # test query #1 + r = histquery(delta="-4", direction="both") + rd = json.loads(r.content) + self.assertEqual(r.status_code, 200) + + # test query #2 + r = histquery(delta="+1", start="5", direction="both") + self.assertEqual(r.status_code, 200) + rd = json.loads(r.content) + self.assertEqual(r.status_code, 200) + self.assertEqual(rd["data"][0]["row_id"], 6) + + # test query #3 + r = histquery(delta="+1", start="2", direction="both") + self.assertEqual(r.status_code, 200) + rd = json.loads(r.content) + self.assertEqual(rd["data"][0]["wt_subject"], "c") + + # test query #4 + r = histquery(delta="-1", start="2", direction="both") + self.assertEqual(r.status_code, 200) + rd = json.loads(r.content) + self.assertEqual(rd["data"][0]["wt_subject"], "a") + + # test query #5 + r = histquery(delta="1", start="11", direction="both") + self.assertEqual(r.status_code, 200) + rd = json.loads(r.content) + self.assertEqual(len(rd["data"]), 0) - def test_subtraction(self): - user_bankaccount = BankAccount.objects.get( - user=User.objects.get(username='U') - ) - user_bankaccount.amount.subtract(Amount(settings.TALER_CURRENCY, 2)) - self.assertEqual( - Amount.cmp(Amount(settings.TALER_CURRENCY, 1), user_bankaccount.amount), 0 - ) class DBCustomColumnTestCase(TestCase): def setUp(self): - BankAccount(user=User.objects.create_user(username='U')).save() + BankAccount(user=User.objects.create_user(username="U")).save() def tearDown(self): clear_db() def test_exists(self): - user_bankaccount = BankAccount.objects.get( - user=User.objects.get(username='U') - ) - self.assertTrue(isinstance(user_bankaccount.amount, Amount)) + user_bankaccount = BankAccount.objects.get(user=User.objects.get(username="U")) + self.assertTrue(isinstance(user_bankaccount.balance, SignedAmount)) ## This tests whether a bank account goes debit and then goes >=0 ## again class DebitTestCase(TestCase): def setUp(self): - BankAccount(user=User.objects.create_user(username='U')).save() - BankAccount(user=User.objects.create_user(username='U0')).save() + BankAccount(user=User.objects.create_user(username="U")).save() + BankAccount(user=User.objects.create_user(username="U0")).save() def tearDown(self): clear_db() def test_green(self): - user_bankaccount = BankAccount.objects.get( - user=User.objects.get(username='U') - ) - self.assertEqual(False, user_bankaccount.debit) + user_bankaccount = BankAccount.objects.get(user=User.objects.get(username="U")) + self.assertTrue(user_bankaccount.balance.is_zero()) def test_red(self): - user_bankaccount = BankAccount.objects.get( - user=User.objects.get(username='U') - ) + user_bankaccount = BankAccount.objects.get(user=User.objects.get(username="U")) user_bankaccount0 = BankAccount.objects.get( - user=User.objects.get(username='U0') + user=User.objects.get(username="U0") ) wire_transfer( - Amount(settings.TALER_CURRENCY, 10, 0), user_bankaccount0, - user_bankaccount, "Go green" + Amount(settings.TALER_CURRENCY, 10, 0), + user_bankaccount0, + user_bankaccount, + "Go green", ) - tmp = Amount(settings.TALER_CURRENCY, 10) - self.assertEqual(0, Amount.cmp(user_bankaccount.amount, tmp)) - self.assertEqual(0, Amount.cmp(user_bankaccount0.amount, tmp)) - self.assertFalse(user_bankaccount.debit) - - self.assertTrue(user_bankaccount0.debit) wire_transfer( - Amount(settings.TALER_CURRENCY, 11), user_bankaccount, - user_bankaccount0, "Go red" + Amount(settings.TALER_CURRENCY, 11, 0), + user_bankaccount, + user_bankaccount0, + "Go red", ) - tmp.value = 1 - self.assertTrue(user_bankaccount.debit) - self.assertFalse(user_bankaccount0.debit) - self.assertEqual(0, Amount.cmp(user_bankaccount.amount, tmp)) - self.assertEqual(0, Amount.cmp(user_bankaccount0.amount, tmp)) + amt_one = SignedAmount.parse(f"{settings.TALER_CURRENCY}:1") - -class ParseAmountTestCase(TestCase): - def test_parse_amount(self): - ret = Amount.parse("KUDOS:4.0") - self.assertJSONEqual( - '{"value": 4, \ - "fraction": 0, \ - "currency": "KUDOS"}', ret.dump() - ) - ret = Amount.parse("KUDOS:4.3") - self.assertJSONEqual( - '{"value": 4, \ - "fraction": 30000000, \ - "currency": "KUDOS"}', ret.dump() - ) - ret = Amount.parse("KUDOS:4") - self.assertJSONEqual( - '{"value": 4, "fraction": 0, "currency": "KUDOS"}', ret.dump() - ) - ret = Amount.parse("KUDOS:4.") # forbid? - self.assertJSONEqual( - '{"value": 4, "fraction": 0, "currency": "KUDOS"}', ret.dump() - ) - try: - Amount.parse("Buggy") - except BadFormatAmount as err: - return - # make sure the control doesn't get here - self.assertEqual(True, False) + self.assertEqual(user_bankaccount.balance, -amt_one) + self.assertEqual(user_bankaccount0.balance, amt_one) class MeasureHistory(TestCase): def setUp(self): self.user_bankaccount0 = BankAccount( - user=User.objects.create_user(username='U0'), - amount=Amount(settings.TALER_CURRENCY, 3000) + user=User.objects.create_user(username="U0"), + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 3000, 0)), ) self.user_bankaccount0.save() - user_bankaccount = BankAccount( - user=User.objects.create_user(username='U') - ) + user_bankaccount = BankAccount(user=User.objects.create_user(username="U")) user_bankaccount.save() self.ntransfers = 1000 @@ -866,8 +614,10 @@ class MeasureHistory(TestCase): for i in range(self.ntransfers): del i # to pacify PEP checkers wire_transfer( - Amount(settings.TALER_CURRENCY, 1), self.user_bankaccount0, - user_bankaccount, "bulk" + Amount(settings.TALER_CURRENCY, 1, 0), + self.user_bankaccount0, + user_bankaccount, + "bulk", ) def tearDown(self): @@ -880,7 +630,7 @@ class MeasureHistory(TestCase): timer = timeit.Timer( stmt="extract_history(self.user_bankaccount0, False)", setup="from talerbank.app.views import extract_history", - globals=locals() + globals=locals(), ) total_time = timer.timeit(number=1) allowed_time_per_record = 0.003 @@ -890,14 +640,14 @@ class MeasureHistory(TestCase): class BalanceTestCase(TestCase): def setUp(self): self.the_bank = BankAccount( - user=User.objects.create_user(username='U0', password='U0PASS'), - amount=Amount(settings.TALER_CURRENCY, 3) + user=User.objects.create_user(username="U0", password="U0PASS"), + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 3, 0)), ) self.the_bank.save() user = BankAccount( - user=User.objects.create_user(username='U'), - amount=Amount(settings.TALER_CURRENCY, 10) + user=User.objects.create_user(username="U"), + balance=SignedAmount(True, Amount(settings.TALER_CURRENCY, 10, 0)), ) user.save() @@ -905,27 +655,27 @@ class BalanceTestCase(TestCase): # bank: 2, user: 11 wire_transfer( - Amount(settings.TALER_CURRENCY, 1), self.the_bank, user, "mock" + Amount(settings.TALER_CURRENCY, 1, 0), self.the_bank, user, "mock" ) # bank: 4, user: 9 wire_transfer( - Amount(settings.TALER_CURRENCY, 2), user, self.the_bank, "mock" + Amount(settings.TALER_CURRENCY, 2, 0), user, self.the_bank, "mock" ) # bank: -1, user: 14 wire_transfer( - Amount(settings.TALER_CURRENCY, 5), self.the_bank, user, "mock" + Amount(settings.TALER_CURRENCY, 5, 0), self.the_bank, user, "mock" ) # bank: 7, user: 6 (END) wire_transfer( - Amount(settings.TALER_CURRENCY, 8), user, self.the_bank, "mock" + Amount(settings.TALER_CURRENCY, 8, 0), user, self.the_bank, "mock" ) # bank: -3, user: 16 (END) wire_transfer( - Amount(settings.TALER_CURRENCY, 10), user, self.the_bank, "mock" + Amount(settings.TALER_CURRENCY, 10, 0), self.the_bank, user, "mock" ) self.client = Client() @@ -937,44 +687,23 @@ class BalanceTestCase(TestCase): self.client.login(username="U0", password="U0PASS") response = self.client.get( reverse("history", urlconf=urls), - { - "auth": "basic", - "delta": -30, - "direction": "both", - "account_number": 55 - }, # unused - **{ - "HTTP_AUTHORIZATION": make_auth_line("U0", "U0PASS") - } + {"delta": -30, "direction": "both", "account_number": 55}, + HTTP_AUTHORIZATION=make_auth_line("U0", "U0PASS"), ) data = response.content.decode("utf-8") self.assertEqual(response.status_code, 200) entries = json.loads(data) - acc_in = Amount(settings.TALER_CURRENCY) - acc_out = Amount(settings.TALER_CURRENCY) + acc_bal = SignedAmount(True, Amount(settings.TALER_CURRENCY, 10, 0)) + print("acc_bal start", acc_bal) - for entry in entries["data"]: - if entry["sign"] == "+": - acc_in.add(Amount(**entry["amount"])) + for entry in reversed(entries["data"]): + print("entry", entry) if entry["sign"] == "-": - acc_out.add(Amount(**entry["amount"])) - - expected_amount = Amount(settings.TALER_CURRENCY, 3) - try: - debit = False - acc_in.subtract(acc_out) - expected_amount.add(acc_in) - except ValueError: - # "out" is bigger than "in" - LOGGER.info("out > in") - acc_out.subtract(acc_in) - try: - expected_amount.subtract(acc_out) - except ValueError: - # initial amount wasn't enough to cover expenses - debit = True - acc_out.subtract(expected_amount) - expected_amount = acc_out - - self.assertEqual(Amount.cmp(expected_amount, self.the_bank.amount), 0) + acc_bal += SignedAmount.parse(entry["amount"]) + if entry["sign"] == "+": + acc_bal -= SignedAmount.parse(entry["amount"]) + print("acc_bal after", acc_bal) + + expected_amount = SignedAmount.parse(f"{settings.TALER_CURRENCY}:16.0") + self.assertEqual(acc_bal, expected_amount) |