from app.services import RuleBasedExperienceExtractor, RuleBasedResumeRewriter from app.validators import anchor_missing_fields, can_create_resume def test_rule_based_services_are_deterministic() -> None: extractor = RuleBasedExperienceExtractor() result = extractor.extract("在星河科技担任后端工程师,接口耗时降低30%。") assert result.organization == "星河科技" assert result.metrics == ["30%"] assert result.confidence >= 0.5 rewriter = RuleBasedResumeRewriter() resume = rewriter.rewrite( { "name": "张三", "phone": "13800138000", "phone_source": "manual", "job_type": "campus", "anchor_type": "education", "anchor": {"school": "示例大学"}, "experiences": [result.to_dict()], } ) assert resume["basics"]["masked_phone"] == "138****8000" assert resume["sections"][0]["kind"] == "education" assert resume == rewriter.rewrite( { "name": "张三", "phone": "13800138000", "phone_source": "manual", "job_type": "campus", "anchor_type": "education", "anchor": {"school": "示例大学"}, "experiences": [result.to_dict()], } ) def test_creation_gate_requires_confirmation_and_valid_date_order() -> None: profile = { "privacy_accepted": True, "phone": "13800138000", "name": "张三", "job_type": "social", "anchor_type": "work_experience", "anchor": { "company": "星河科技", "position": "产品经理", "start_date": "2024-06", "end_date_or_present": "2023-06", }, } required = ["company", "position", "start_date", "end_date_or_present"] missing = anchor_missing_fields(profile, required) assert missing == ["end_date_or_present"] assert can_create_resume(profile, missing) is False profile["anchor"]["end_date_or_present"] = "present" assert can_create_resume(profile, anchor_missing_fields(profile, required)) is False profile["anchor_confirmed"] = True assert can_create_resume(profile, anchor_missing_fields(profile, required)) is True def test_creation_gate_allows_a_basic_resume_after_core_experience_skip() -> None: profile = { "privacy_accepted": True, "phone": "13800138000", "name": "Zhang San", "job_type": "social", "core_experience_skipped": True, } assert can_create_resume(profile, []) is True