diff --git a/ihatemoney/tests/api_test.py b/ihatemoney/tests/api_test.py index 7da55425..6d241bd1 100644 --- a/ihatemoney/tests/api_test.py +++ b/ihatemoney/tests/api_test.py @@ -575,6 +575,157 @@ class APITestCase(IhatemoneyTestCase): ) self.assertStatus(400, req) + def test_currencies(self): + # create project with a default currency + resp = self.api_create("raclette", default_currency="EUR") + self.assertTrue(201, resp.status_code) + + # get information about it + resp = self.client.get( + "/api/projects/raclette", headers=self.get_auth("raclette") + ) + + self.assertTrue(200, resp.status_code) + expected = { + "members": [], + "name": "raclette", + "contact_email": "raclette@notmyidea.org", + "default_currency": "EUR", + "id": "raclette", + "logging_preference": 1, + } + decoded_resp = json.loads(resp.data.decode("utf-8")) + self.assertDictEqual(decoded_resp, expected) + + # Add members + self.api_add_member("raclette", "zorglub") + self.api_add_member("raclette", "fred") + self.api_add_member("raclette", "quentin") + + # Add a bill without explicit currency + req = self.client.post( + "/api/projects/raclette/bills", + data={ + "date": "2011-08-10", + "what": "fromage", + "payer": "1", + "payed_for": ["1", "2"], + "amount": "25", + "external_link": "https://raclette.fr", + }, + headers=self.get_auth("raclette"), + ) + + # should return the id + self.assertStatus(201, req) + self.assertEqual(req.data.decode("utf-8"), "1\n") + + # get this bill details + req = self.client.get( + "/api/projects/raclette/bills/1", headers=self.get_auth("raclette") + ) + + # compare with the added info + self.assertStatus(200, req) + expected = { + "what": "fromage", + "payer_id": 1, + "owers": [ + {"activated": True, "id": 1, "name": "zorglub", "weight": 1}, + {"activated": True, "id": 2, "name": "fred", "weight": 1}, + ], + "amount": 25.0, + "date": "2011-08-10", + "id": 1, + "converted_amount": 25.0, + "original_currency": "EUR", + "external_link": "https://raclette.fr", + } + + got = json.loads(req.data.decode("utf-8")) + self.assertEqual( + datetime.date.today(), + datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(), + ) + del got["creation_date"] + self.assertDictEqual(expected, got) + + # Change bill amount and currency + req = self.client.put( + "/api/projects/raclette/bills/1", + data={ + "date": "2011-08-10", + "what": "fromage", + "payer": "1", + "payed_for": ["1", "2"], + "amount": "30", + "external_link": "https://raclette.fr", + "original_currency": "CAD", + }, + headers=self.get_auth("raclette"), + ) + self.assertStatus(200, req) + + # Check result + req = self.client.get( + "/api/projects/raclette/bills/1", headers=self.get_auth("raclette") + ) + self.assertStatus(200, req) + expected_amount = self.converter.exchange_currency(30.0, "CAD", "EUR") + expected = { + "what": "fromage", + "payer_id": 1, + "owers": [ + {"activated": True, "id": 1, "name": "zorglub", "weight": 1.0}, + {"activated": True, "id": 2, "name": "fred", "weight": 1.0}, + ], + "amount": 30.0, + "date": "2011-08-10", + "id": 1, + "converted_amount": expected_amount, + "original_currency": "CAD", + "external_link": "https://raclette.fr", + } + + got = json.loads(req.data.decode("utf-8")) + del got["creation_date"] + self.assertDictEqual(expected, got) + + # Add a bill with yet another currency + req = self.client.post( + "/api/projects/raclette/bills", + data={ + "date": "2011-09-10", + "what": "Pierogi", + "payer": "1", + "payed_for": ["2", "3"], + "amount": "80", + "original_currency": "PLN", + }, + headers=self.get_auth("raclette"), + ) + + # should return the id + self.assertStatus(201, req) + self.assertEqual(req.data.decode("utf-8"), "2\n") + + # Try to remove default project currency, it should fail + req = self.client.put( + "/api/projects/raclette", + data={ + "contact_email": "yeah@notmyidea.org", + "default_currency": "XXX", + "password": "raclette", + "name": "The raclette party", + }, + headers=self.get_auth("raclette"), + ) + self.assertStatus(400, req) + self.assertIn("This project cannot be set", req.data.decode("utf-8")) + self.assertIn( + "because it contains bills in multiple currencies", req.data.decode("utf-8") + ) + def test_statistics(self): # create a project self.api_create("raclette") diff --git a/ihatemoney/tests/common/ihatemoney_testcase.py b/ihatemoney/tests/common/ihatemoney_testcase.py index 2c34e1e1..a0068660 100644 --- a/ihatemoney/tests/common/ihatemoney_testcase.py +++ b/ihatemoney/tests/common/ihatemoney_testcase.py @@ -24,7 +24,13 @@ class BaseTestCase(TestCase): def setUp(self): db.create_all() # Add dummy data to CurrencyConverter for all tests (since it's a singleton) - mock_data = {"USD": 1, "EUR": 0.8, "CAD": 1.2, CurrencyConverter.no_currency: 1} + mock_data = { + "USD": 1, + "EUR": 0.8, + "CAD": 1.2, + "PLN": 4, + CurrencyConverter.no_currency: 1, + } converter = CurrencyConverter() converter.get_rates = MagicMock(return_value=mock_data) # Also add it to an attribute to make tests clearer diff --git a/ihatemoney/tests/main_test.py b/ihatemoney/tests/main_test.py index 604aedd2..69392267 100644 --- a/ihatemoney/tests/main_test.py +++ b/ihatemoney/tests/main_test.py @@ -288,7 +288,13 @@ class CaptchaTestCase(IhatemoneyTestCase): class TestCurrencyConverter(unittest.TestCase): converter = CurrencyConverter() - mock_data = {"USD": 1, "EUR": 0.8, "CAD": 1.2, CurrencyConverter.no_currency: 1} + mock_data = { + "USD": 1, + "EUR": 0.8, + "CAD": 1.2, + "PLN": 4, + CurrencyConverter.no_currency: 1, + } converter.get_rates = MagicMock(return_value=mock_data) def test_only_one_instance(self): @@ -299,7 +305,7 @@ class TestCurrencyConverter(unittest.TestCase): def test_get_currencies(self): self.assertCountEqual( self.converter.get_currencies(), - ["USD", "EUR", "CAD", CurrencyConverter.no_currency], + ["USD", "EUR", "CAD", "PLN", CurrencyConverter.no_currency], ) def test_exchange_currency(self):