import unittest from unittest.mock import MagicMock from src.models import Gate, Status from src.repository import GatesRepository from src.services import AVConnectService, GatesService, UsersService class TestGatesService(unittest.TestCase): def setUp(self): self.gates_repo = MagicMock(spec=GatesRepository) self.avconnect_service = MagicMock(spec=AVConnectService) self.users_service = MagicMock(spec=UsersService) self.service = GatesService(self.gates_repo, self.avconnect_service, self.users_service) def test_open_gate_returns_false_when_gate_does_not_exist(self): gate_key = "missing_gate" uid = "user-1" self.gates_repo.get_by_key.return_value = None result = self.service.open_gate(gate_key, uid) self.assertFalse(result) self.gates_repo.get_by_key.assert_called_once_with(gate_key) self.users_service.get_credentials.assert_not_called() self.avconnect_service.open_gate_by_id.assert_not_called() def test_open_gate_returns_false_when_gate_is_disabled(self): gate_key = "gate-disabled" uid = "user-2" gate = Gate(gid="G-1", name="Disabled Gate", status=Status.DISABLED) self.gates_repo.get_by_key.return_value = gate result = self.service.open_gate(gate_key, uid) self.assertFalse(result) self.gates_repo.get_by_key.assert_called_once_with(gate_key) self.users_service.get_credentials.assert_not_called() self.avconnect_service.open_gate_by_id.assert_not_called() def test_open_gate_calls_services_and_returns_true_when_avconnect_succeeds(self): gate_key = "gate-enabled" uid = "user-3" credentials = {"u": "name", "p": "pwd"} gate = Gate(gid="G-2", name="Enabled Gate", status=Status.ENABLED) self.gates_repo.get_by_key.return_value = gate self.users_service.get_credentials.return_value = credentials self.avconnect_service.open_gate_by_id.return_value = True result = self.service.open_gate(gate_key, uid) self.assertTrue(result) self.gates_repo.get_by_key.assert_called_once_with(gate_key) self.users_service.get_credentials.assert_called_once_with(uid, gate_key) self.avconnect_service.open_gate_by_id.assert_called_once_with(gate.gid, credentials) def test_open_gate_calls_services_and_returns_false_when_avconnect_fails(self): gate_key = "gate-enabled" uid = "user-4" credentials = {"u": "name", "p": "pwd"} gate = Gate(gid="G-3", name="Enabled Gate", status=Status.ENABLED) self.gates_repo.get_by_key.return_value = gate self.users_service.get_credentials.return_value = credentials self.avconnect_service.open_gate_by_id.return_value = False result = self.service.open_gate(gate_key, uid) self.assertFalse(result) self.gates_repo.get_by_key.assert_called_once_with(gate_key) self.users_service.get_credentials.assert_called_once_with(uid, gate_key) self.avconnect_service.open_gate_by_id.assert_called_once_with(gate.gid, credentials) def test_open_gate_propagates_exception_from_avconnect(self): gate_key = "gate-exception" uid = "user-5" credentials = {"u": "name", "p": "pwd"} gate = Gate(gid="G-4", name="Enabled Gate", status=Status.ENABLED) self.gates_repo.get_by_key.return_value = gate self.users_service.get_credentials.return_value = credentials self.avconnect_service.open_gate_by_id.side_effect = RuntimeError("boom") with self.assertRaises(RuntimeError): self.service.open_gate(gate_key, uid) self.gates_repo.get_by_key.assert_called_once_with(gate_key) self.users_service.get_credentials.assert_called_once_with(uid, gate_key) self.avconnect_service.open_gate_by_id.assert_called_once_with(gate.gid, credentials) def test_get_name_returns_gate_name_when_gate_exists(self): gate_key = "gate-name" gate = Gate(gid="G-5", name="Main Entrance", status=Status.ENABLED) self.gates_repo.get_by_key.return_value = gate name = self.service.get_name(gate_key) self.assertEqual("Main Entrance", name) self.gates_repo.get_by_key.assert_called_once_with(gate_key) def test_get_name_returns_none_when_gate_missing(self): gate_key = "missing" self.gates_repo.get_by_key.return_value = None name = self.service.get_name(gate_key) self.assertIsNone(name) self.gates_repo.get_by_key.assert_called_once_with(gate_key) def test_get_all_enabled_delegates_to_repository(self): gates = [ Gate(gid="G-6", name="G1", status=Status.ENABLED), Gate(gid="G-7", name="G2", status=Status.ENABLED), ] self.gates_repo.get_all_enabled.return_value = gates result = self.service.get_all_enabled() self.assertEqual(gates, result) self.gates_repo.get_all_enabled.assert_called_once() if __name__ == "__main__": unittest.main()