diff --git a/atm_service.py b/atm_service.py index ec2eaf0..1648561 100644 --- a/atm_service.py +++ b/atm_service.py @@ -4,6 +4,8 @@ from atm_repository_mem import InMemoryInventoryService from atm_repository_sqllite import SQLiteInventoryService +DEVISION_MULTIPLIER = 100 + MULTIPLIER_FOR_DIVISION = 100 ERR_20_MAX_AMOUNT = "Amount exceeds the maximum withdrawal limit of 2000" @@ -33,14 +35,14 @@ def _propose_withdrawal(self, amount): for denomination in denominations: if amount == 0: break - num_notes = min(int((amount *100) // (denomination *100)), self.inventory[denomination_type][denomination]) + num_notes = min(int((amount * DEVISION_MULTIPLIER) // (denomination *DEVISION_MULTIPLIER)), self.inventory[denomination_type][denomination]) if num_notes > 0: if denomination_type == "COIN": total_coins += num_notes - if total_coins > 50: + if total_coins > 50 and int(amount * DEVISION_MULTIPLIER) == 0: return None, ERR_TOO_MANY_COINS, 422 proposed_withdrawal[denomination_type][denomination] = num_notes - amount -= denomination * num_notes + amount = self.make_round(amount - self.make_round(denomination * num_notes)) if amount > 0: available_amount = { @@ -51,6 +53,9 @@ def _propose_withdrawal(self, amount): return proposed_withdrawal, None, 200 + def make_round(self, num): + return round(num, int(len(str(MULTIPLIER_FOR_DIVISION)) - 1)) + def withdraw_money(self, amount): if amount <= 0: return ERR_10_GREATER_THAN_ZERO, 422 @@ -79,7 +84,7 @@ def refill_money(self, money): if denom_value not in [200, 100, 20, 10, 1, 5, 0.1, 0.01]: return f"Unknown denomination {denomination}", 422 - denom_type = "BILL" if denom_value >= 1 else "COIN" + denom_type = "BILL" if denom_value >= 20 else "COIN" if denom_value not in self.inventory[denom_type]: self.inventory[denom_type][denom_value] = 0 diff --git a/inventory.db b/inventory.db index 41d2065..072af63 100644 Binary files a/inventory.db and b/inventory.db differ diff --git a/tests/test_atm_service.py b/tests/test_atm_service.py index 4c03f5d..7b989ac 100644 --- a/tests/test_atm_service.py +++ b/tests/test_atm_service.py @@ -9,7 +9,7 @@ def setUp(self): self.atm_service = ATMService() def test_atm_logic(self): - amount, atm_service, total_before1 = self.assert_amount(100,100,1) + amount, atm_service, total_before1 = self.assert_amount(100, 100, 1) total_after = atm_service.get_total()['total'] self.assertEqual(total_before1, total_after + amount) @@ -17,17 +17,17 @@ def test_atm_logic(self): total_before2 = atm_service.get_total()['total'] self.assertEqual(total_before1, total_before2) - #test2 + # test2 amount, atm_service, total_before1 = self.assert_amount(200, 200, 1) amount, atm_service, total_before1 = self.assert_amount(0.9, 0.1, 9, expected_type="COIN") pass - def assert_amount(self,amount, expected_bill, expected_count, expected_type='BILL'): + def assert_amount(self, amount, expected_bill, expected_count, expected_type='BILL'): atm_service = ATMService() atm_service.restart() total_before1 = atm_service.get_total()['total'] - #amount = 100 + # amount = 100 result = atm_service.withdraw_money(amount) assert result[0]['withdrawal'][expected_type][expected_bill] == expected_count return amount, atm_service, total_before1 @@ -48,14 +48,14 @@ def test_atm_logic_too_many_coins(self): # amount = 0.9 total1 = atm_service.get_total() - result = atm_service.withdraw_money(0.9) #should remain 3 of 0.1 + result = atm_service.withdraw_money(0.9) # should remain 3 of 0.1 total2 = atm_service.get_total() total = atm_service.get_inventory() result = atm_service.withdraw_money(21.61) total3 = atm_service.get_total() - assert total2 == total3 # because we did not took money + assert total2 == total3 # because we did not took money pass # total_after = atm_service.get_total()['total'] # self.assertAlmostEqual(total_before, total_after + amount, places=2) diff --git a/tests/test_atm_service_fast_api.py b/tests/test_atm_service_fast_api.py new file mode 100644 index 0000000..f93c80e --- /dev/null +++ b/tests/test_atm_service_fast_api.py @@ -0,0 +1,52 @@ +import unittest + +from atm_repository_file import FileInventoryService +from atm_service import ATMService, ERR_INSUFFICIENT_FUNDS, ERR_TOO_MANY_COINS +from fastapi.testclient import TestClient + +from main import app + + +class TestATMService(unittest.TestCase): + def setUp(self): + #self.client = TestClient(app) + #self.client.post("/atm/restart") + pass + + # def test_too_many_coins(self): + # #response = self.client.post("/atm/withdrawal", json={"amount": 0.9}) + # #response = self.client.post("/atm/withdrawal", json={"amount": 0.4}) + # + # refill_amount = {"0.01": 1000} + # initial_inventory = self.client.get("/atm/inventory").json() + # self.client.post("/atm/refill", json={"money": refill_amount}) + # updated_inventory = self.client.get("/atm/inventory").json() + # + # + # response = self.client.post("/atm/withdrawal", json={"amount": 0.9}) + # response = self.client.post("/atm/withdrawal", json={"amount": 0.1}) + # response = self.client.post("/atm/withdrawal", json={"amount": 0.1}) + # response = self.client.post("/atm/withdrawal", json={"amount": 21.61}) + # #response = self.client.post("/atm/withdrawal", json={"amount": 21.61}) + # + # assert response.status_code == 422 + # assert ERR_TOO_MANY_COINS in response.json()["detail"] + + def test_not_enough(self): + self.client = TestClient(app) + response = self.client.post("/atm/withdrawal", json={"amount": 1000}) + response = self.client.post("/atm/withdrawal", json={"amount": 1000}) + response = self.client.post("/atm/withdrawal", json={"amount": 1000}) + assert response.status_code == 409 + assert ERR_INSUFFICIENT_FUNDS in response.json()["detail"] + + def test_max(self): + self.client = TestClient(app) + response = self.client.post("/atm/withdrawal", json={"amount": 3000}) + assert response.status_code == 422 + assert response.json()["detail"] == "Amount exceeds the maximum withdrawal limit of 2000" + + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_atm_service_fast_api_refill.py b/tests/test_atm_service_fast_api_refill.py new file mode 100644 index 0000000..356112c --- /dev/null +++ b/tests/test_atm_service_fast_api_refill.py @@ -0,0 +1,38 @@ +# import unittest +# +# from atm_repository_file import FileInventoryService +# from atm_service import ATMService, ERR_INSUFFICIENT_FUNDS, ERR_TOO_MANY_COINS +# from fastapi.testclient import TestClient +# +# from main import app +# +# +# class TestATMService(unittest.TestCase): +# def setUp(self): +# #self.client = TestClient(app) +# #self.client.post("/atm/restart") +# pass +# +# def test_refill(self): +# self.client = TestClient(app) +# self.client.post("/atm/restart") +# initial_inventory = self.client.get("/atm/inventory").json() +# #self.client.post("/atm/restart") +# bill_100 = 30 +# num_5 = 30 +# num_01 = 5 +# bill_20 = 15 +# refill_amount = {"0.1": num_01, "5": num_5, "20": bill_20, "100": bill_100} +# initial_inventory = self.client.get("/atm/inventory").json() +# self.client.post("/atm/refill", json={"money": refill_amount}) +# updated_inventory = self.client.get("/atm/inventory").json() +# +# assert initial_inventory != updated_inventory +# assert initial_inventory['result']['bills']['100.0'] + bill_100 == updated_inventory['result']['bills']['100.0'] +# assert initial_inventory['result']['bills']['20.0'] + bill_20 == updated_inventory['result']['bills']['20.0'] +# assert initial_inventory['result']['coins']['0.1'] + num_01 == updated_inventory['result']['coins']['0.1'] +# assert initial_inventory['result']['coins']['5.0'] + num_5 == updated_inventory['result']['coins']['5.0'] +# +# +# if __name__ == "__main__": +# unittest.main()