"""特殊批次定向培养计划模块测试。""" from __future__ import annotations from pathlib import Path from data.crowd_db.special_programs_loader import SpecialProgramsLoader _DATA_PATH = Path(__file__).resolve().parent.parent / "special_programs.json" _RULES_PATH = ( Path(__file__).resolve().parents[3] / "data" / "rules" / "special_programs_rules.json" ) class TestSpecialProgramsLoader: def setup_method(self): self.loader = SpecialProgramsLoader( data_path=_DATA_PATH, rules_path=_RULES_PATH ) def test_loads_8_program_types(self): programs = self.loader.list_programs() types = {p["program_type"] for p in programs} expected = { "rural_medical", "public_agriculture", "fire_rescue", "railway_directed", "judicial_directed", "military_nco", "public_teacher", "enterprise_order", "minority_prep", "targeted_poverty", "tibet_directed", } for t in expected: assert t in types, f"缺少项目类型: {t}" def test_get_program(self): p = self.loader.get_program("rural_medical") assert p is not None assert p["program_name"] == "农村订单定向免费医学生" assert p["key_features"]["service_years"] == 6 def test_get_program_not_found(self): assert self.loader.get_program("nonexistent") is None def test_list_programs_for_hunan(self): programs = self.loader.list_programs_for_province("湖南") types = {p["program_type"] for p in programs} # 湖南应该有 rural_medical(applicable_provinces 含"湖南") # fire_rescue/railway_directed/judicial_directed 是"全国" assert "rural_medical" in types assert "fire_rescue" in types # 全国 assert "railway_directed" in types # 全国 def test_find_matching_schools_for_hunan_578(self): """湖南 578 分应该能匹配到铁路/消防/医疗等院校。""" results = self.loader.find_matching_schools("湖南", 578) assert len(results) > 0 # 应包含铁路(湖南铁道职业技术学院 340 分) types = {r["program_type"] for r in results} assert "railway_directed" in types def test_find_matching_schools_low_score(self): """低分考生(250)应该匹配到铁路专科。""" results = self.loader.find_matching_schools("湖北", 250) # 武汉铁路职业技术学院 223 分 railway = [r for r in results if r["program_type"] == "railway_directed"] assert len(railway) > 0 assert any("武汉铁路" in r["school"] for r in railway) def test_find_matching_schools_high_score_excludes_far(self): """高分考生不应匹配到分数差距过大的院校。""" results = self.loader.find_matching_schools("湖南", 650) # 650 分不应匹配到 223 分的武汉铁路(差距 427 分,223*0.85=189.55) # 但仍然匹配(因为 650 >= 189.55),只是 gap 很大 # 验证至少不报错 assert isinstance(results, list) def test_get_applicable_rules(self): rules = self.loader.get_applicable_rules("rural_medical") rule_ids = {r["rule_id"] for r in rules} assert "special.rural_medical.hukou_requirement" in rule_ids assert "special.rural_medical.service_commitment" in rule_ids assert "special.general.tuition_free" in rule_ids def test_build_recommendation_for_review(self): """审核场景推荐摘要。""" recs = self.loader.build_recommendation_for_review("湖南", 450) assert len(recs) > 0 # 450 分应该能匹配到定向医疗(444/441分) types = {r["program_type"] for r in recs} assert "rural_medical" in types # 每条都有 match_score for r in recs: assert "match_score" in r assert 0 <= r["match_score"] <= 100 def test_build_recommendation_no_match(self): """不存在的省份只返回全国性项目(fire/railway/judicial),不报错。""" recs = self.loader.build_recommendation_for_review("火星", 500) # 全国性项目仍可能返回,但不应报错 assert isinstance(recs, list) def test_rules_loaded(self): rules = self.loader.rules assert "rules" in rules assert len(rules["rules"]) >= 9