Files
resume-agent/backend/tests/test_builder_candidate_rewrite.py
T

87 lines
3.5 KiB
Python

"""Candidate rewrite contract: Builder presents expander results without lexical inference."""
from __future__ import annotations
from types import SimpleNamespace
from typing import Any
from app.builder_conversation import _candidate_rewrite
class _StaticExpander:
def __init__(self, optimized: str, uncovered: list[str] | None = None) -> None:
self.optimized = optimized
self.uncovered = uncovered or []
def expand(self, entry: dict[str, Any], *, context: dict[str, Any]) -> dict[str, Any]:
return {"optimized_description": self.optimized, "uncovered_facts": self.uncovered, "source": "test"}
class _Agent:
def __init__(self, optimized: str, uncovered: list[str] | None = None) -> None:
self.expander = _StaticExpander(optimized, uncovered)
def test_candidate_rewrite_does_not_inject_identity_into_education_description() -> None:
proposal = _candidate_rewrite(
_Agent("\u5728\u5b66\u6821\u4e2d\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u3002"),
{"job_type": "campus"},
{"school": "\u4e1c\u839e\u57ce\u5e02\u5b66\u9662", "description": "\u5728\u5b66\u6821\u4e2d\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u3002"},
"education",
)
assert proposal["optimized_description"] == "\u5728\u5b66\u6821\u4e2d\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u3002"
assert "\u4e1c\u839e\u57ce\u5e02\u5b66\u9662" not in proposal["optimized_description"]
def test_candidate_rewrite_uses_expander_objective_omissions_verbatim() -> None:
omitted = ["GPA: 4.3/5.0", "top10"]
proposal = _candidate_rewrite(
_Agent("\u5b8c\u6210\u6570\u636e\u5e93\u8bfe\u7a0b\u9879\u76ee\u3002", omitted),
{"job_type": "campus"},
{"description": "\u5b8c\u6210\u6570\u636e\u5e93\u8bfe\u7a0b\u9879\u76ee\u3002GPA: 4.3/5.0\u3002"},
"education",
)
assert proposal["uncovered_facts"] == omitted
def test_candidate_rewrite_does_not_lexically_flag_a_paraphrase() -> None:
proposal = _candidate_rewrite(
_Agent("\u8d1f\u8d23 AI \u7b80\u5386\u751f\u6210\u4e0e\u6587\u4ef6\u89e3\u6790\u6a21\u5757\u3002"),
{"job_type": "campus"},
{"description": "AI \u5bf9\u8bdd\u5f0f\u7b80\u5386\u751f\u6210\u52a9\u624b\uff1b\u7b80\u5386\u5bfc\u5165\u667a\u80fd\u89e3\u6790\u3002"},
"project_experience",
)
assert proposal["uncovered_facts"] == []
def test_candidate_rewrite_never_appends_raw_source_to_a_candidate() -> None:
raw = "\u5b66\u4e60\u6570\u636e\u7ed3\u6784\u3002GPA: 4.3/5.0\u3002"
proposal = _candidate_rewrite(
_Agent("\u4e3b\u4fee\u8bfe\u7a0b\uff1a\u6570\u636e\u7ed3\u6784\u3002", ["GPA: 4.3/5.0"]),
{"job_type": "campus"},
{"description": raw},
"education",
)
assert proposal["optimized_description"] == "\u4e3b\u4fee\u8bfe\u7a0b\uff1a\u6570\u636e\u7ed3\u6784\u3002"
assert "GPA: 4.3/5.0" not in proposal["optimized_description"]
def test_candidate_rewrite_does_not_present_unavailable_output_as_ai_draft() -> None:
class _UnavailableExpander:
def expand(self, entry: dict[str, Any], *, context: dict[str, Any]) -> dict[str, Any]:
raise TimeoutError("gateway timed out")
proposal = _candidate_rewrite(
SimpleNamespace(expander=_UnavailableExpander()),
{"job_type": "campus"},
{"description": "Original confirmed description."},
"project_experience",
)
assert proposal["optimized_description"] == ""
assert proposal["optimization_unavailable"] is True
assert proposal["generation_source"] == "unavailable"
assert proposal["fallback_reason"] == "timeouterror"