import tempfile import unittest from pathlib import Path from defect_analysis.cases import ( create_root_cause_case, get_audit_logs, list_cases, update_case_status, ) from defect_analysis.database import init_database class CasesTest(unittest.TestCase): def setUp(self): self.tmpdir = tempfile.TemporaryDirectory() self.db_path = Path(self.tmpdir.name) / "cases.db" init_database(self.db_path) def tearDown(self): self.tmpdir.cleanup() def test_create_root_cause_case_records_audit_log(self): case_id = create_root_cause_case( self.db_path, title="LAM-A01 R2C3 气泡异常", candidate_type="equipment_seat", candidate_value="LAM-A01 / R2C3", defect_type="气泡", panel_zone="FPC/绑定区", owner="工程师A", created_by="tester", recommendation="检查贴合压力和吸嘴状态", ) cases = list_cases(self.db_path) logs = get_audit_logs(self.db_path, entity_type="case", entity_id=case_id) self.assertEqual(1, len(cases)) self.assertEqual("OPEN", cases.loc[0, "status"]) self.assertEqual("工程师A", cases.loc[0, "owner"]) self.assertEqual(1, len(logs)) self.assertEqual("CREATE_CASE", logs.loc[0, "action"]) def test_update_case_status_records_transition_and_audit_log(self): case_id = create_root_cause_case( self.db_path, title="治具划痕异常", candidate_type="lam_fixture_id", candidate_value="FIX-A01-03", defect_type="划痕", panel_zone="左边缘区", owner="工程师B", created_by="tester", recommendation="点检治具接触面", ) update_case_status( self.db_path, case_id=case_id, status="IN_PROGRESS", actor="工程师B", note="已安排停机点检", ) update_case_status( self.db_path, case_id=case_id, status="CLOSED", actor="工程师B", note="已更换治具,观察 3 天无复发", ) cases = list_cases(self.db_path) logs = get_audit_logs(self.db_path, entity_type="case", entity_id=case_id) self.assertEqual("CLOSED", cases.loc[0, "status"]) self.assertEqual(["CREATE_CASE", "UPDATE_STATUS", "UPDATE_STATUS"], logs["action"].tolist()) self.assertIn("已更换治具", logs.iloc[-1]["details"]) if __name__ == "__main__": unittest.main()