import unittest from unittest.mock import MagicMock, patch import obd from modules import app_obd class CarConnectedFlagTest(unittest.TestCase): def setUp(self): app_obd._car_ever_connected = False def tearDown(self): app_obd._car_ever_connected = False def test_was_ever_connected_reads_persisted_flag(self): with patch("modules.app_sql.get_setting", return_value="1"): self.assertTrue(app_obd.was_car_ever_connected()) self.assertTrue(app_obd._car_ever_connected) def test_was_ever_connected_defaults_false(self): with patch("modules.app_sql.get_setting", return_value="0"): self.assertFalse(app_obd.was_car_ever_connected()) def test_persist_car_connected_writes_setting(self): with patch("modules.app_sql.set_setting") as mock_set: app_obd._persist_car_connected() mock_set.assert_called_once_with("car_ever_connected", "1") class ClearDtcCodesTest(unittest.TestCase): def setUp(self): self.original_connection = app_obd.connection self.original_dtc_codes = app_obd.dtc_codes self.original_mil_on = app_obd.mil_on def tearDown(self): app_obd.connection = self.original_connection app_obd.dtc_codes = self.original_dtc_codes app_obd.mil_on = self.original_mil_on def test_not_connected_returns_not_connected(self): app_obd.connection = None result = app_obd.clear_dtc_codes() self.assertEqual(result["status"], "not_connected") def test_connected_clears_ecu_and_resets_state(self): fake_conn = MagicMock() app_obd.connection = fake_conn app_obd.dtc_codes = [{"code": "P0300", "description": "Misfire"}] app_obd.mil_on = True with patch.object(app_obd, "_is_car_connected", return_value=True), \ patch("modules.app_sql.clear_dtc_state") as mock_clear, \ patch("modules.app_events.socketio.emit") as mock_emit: result = app_obd.clear_dtc_codes() self.assertEqual(result["status"], "cleared") fake_conn.query.assert_called_once_with(obd.commands.CLEAR_DTC) self.assertEqual(app_obd.dtc_codes, []) self.assertFalse(app_obd.mil_on) mock_clear.assert_called_once_with() self.assertTrue(mock_emit.called) def test_query_error_returns_error(self): fake_conn = MagicMock() fake_conn.query.side_effect = RuntimeError("boom") app_obd.connection = fake_conn with patch.object(app_obd, "_is_car_connected", return_value=True), \ patch.object(app_obd, "_mark_connection_lost") as mock_mark: result = app_obd.clear_dtc_codes() self.assertEqual(result["status"], "error") self.assertIn("boom", result["error"]) mock_mark.assert_called_once() class EmitCurrentStateTest(unittest.TestCase): def setUp(self): self._saved = { name: getattr(app_obd, name) for name in ( "speed", "rpm", "coolant_temp", "fuel_level", "throttle_position", "mil_on", "dtc_codes", ) } def tearDown(self): for name, value in self._saved.items(): setattr(app_obd, name, value) def _emitted(self, mock_emit): return {call.args[0]: call.args[1] for call in mock_emit.call_args_list} def test_connected_emits_current_values(self): app_obd.speed = 42.5 app_obd.rpm = 1200 app_obd.coolant_temp = 88.0 app_obd.fuel_level = 60.0 app_obd.throttle_position = 12.0 app_obd.mil_on = False app_obd.dtc_codes = [] with patch.object(app_obd, "_is_car_connected", return_value=True), \ patch("modules.app_events.socketio.emit") as mock_emit: app_obd.emit_current_state() emitted = self._emitted(mock_emit) self.assertEqual(emitted["obd_status"], "Connected") self.assertEqual(emitted["obd_rpm"], 1200) self.assertEqual(emitted["obd_coolant_temp"], 88.0) self.assertEqual(emitted["obd_fuel_level"], 60.0) self.assertEqual(emitted["obd_throttle"], 12.0) # speed is emitted as [time, speed] self.assertEqual(emitted["obd_speed"][1], 42.5) def test_disconnected_emits_dashes(self): app_obd.rpm = None app_obd.coolant_temp = None app_obd.fuel_level = None app_obd.throttle_position = None with patch.object(app_obd, "_is_car_connected", return_value=False), \ patch("modules.app_events.socketio.emit") as mock_emit: app_obd.emit_current_state() emitted = self._emitted(mock_emit) self.assertEqual(emitted["obd_status"], "Disconnected") self.assertEqual(emitted["obd_speed"], "-") self.assertEqual(emitted["obd_rpm"], "-") self.assertEqual(emitted["obd_coolant_temp"], "-") self.assertEqual(emitted["obd_fuel_level"], "-") self.assertEqual(emitted["obd_throttle"], "-") if __name__ == "__main__": unittest.main()