from __future__ import annotations import json import sys import unittest from pathlib import Path from unittest.mock import patch ROOT = Path(__file__).resolve().parents[2] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) import tools.validate_platform_transition_wbs_v1 as validator class TestValidatePlatformTransitionWbs(unittest.TestCase): def test_validate_platform_transition_wbs_reports_failure_notes(self): spec = { "phase_5_platform_transition": { "P1_kis_core_api_collector": { "success_criteria": { "expected_success_value": {}, "evidence_artifacts": [], "verification_commands": [], } }, "P2_sqlite_canonical_store": { "success_criteria": { "expected_success_value": {}, "evidence_artifacts": [], "verification_commands": [], } }, "P3_ci_scheduler_cutover": { "success_criteria": { "expected_success_value": {}, "evidence_artifacts": [], "verification_commands": [], } }, "P4_gas_thin_adapter_minimize": { "success_criteria": { "expected_success_value": {}, "evidence_artifacts": [], "verification_commands": [], } }, "P5_postgresql_upgrade_path": { "success_criteria": { "expected_success_value": {}, "evidence_artifacts": [], "verification_commands": [], } }, } } with patch.object(validator, "_load_spec", return_value=spec): with patch.object(validator, "_read_text", return_value="Phase 5 데이터 플랫폼 전환 WBS 성공값 P1 KIS core collector P2 SQLite canonical store P3 CI scheduler cutover P4 GAS thin adapter minimize P5 PostgreSQL upgrade path"): with patch.object(validator, "_check_p1", return_value={ "gate": "FAIL", "expected_success_value": {}, "evidence": {"summary_path": "Temp/test_kis_data_collection.json", "db_path": "Temp/test_kis_data_collection.db"}, "errors": ["summary_status=None"], }): with patch.object(validator, "_check_p2", return_value={ "gate": "FAIL", "expected_success_value": {}, "evidence": {"db_path": "Temp/test_kis_data_collection.db"}, "errors": ["sqlite_round_trip_missing"], }): with patch.object(validator, "_check_p3", return_value={ "gate": "PASS", "expected_success_value": {}, "evidence": {"workflow_path": ".gitea/workflows/kis_data_collection.yml"}, "errors": [], }): with patch.object(validator, "_check_p4", return_value={ "gate": "FAIL", "expected_success_value": {}, "evidence": {"validation_path": "Temp/gas_thin_adapter_validation_v1.json"}, "errors": ["gate=None", "function_inventory_coverage_pct<100"], }): with patch.object(validator, "_check_p5", return_value={ "gate": "PASS", "expected_success_value": {}, "evidence": {}, "errors": [], }): rc = validator.main() payload = json.loads((ROOT / "Temp" / "platform_transition_wbs_v1.json").read_text(encoding="utf-8")) self.assertEqual(rc, 1) self.assertEqual(payload["gate"], "FAIL") self.assertTrue(payload["message"].startswith("Platform transition WBS check failed")) self.assertEqual(len(payload["failure_notes"]), 3) self.assertIn("P1 failed", payload["failure_notes"][0]) self.assertIn("P2 failed", payload["failure_notes"][1]) self.assertIn("P4 failed", payload["failure_notes"][2]) if __name__ == "__main__": unittest.main()