generated from kgod/ai-review-template
feat: initialize resume agent with OfferPai sync
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from app.import_parser import ImportParseOutput, OpenAIResumeImportParser
|
||||
from app.resume_import_service import RuleBasedResumeImportParser
|
||||
|
||||
|
||||
class FakeCompletion:
|
||||
def __init__(self, result: ImportParseOutput | Exception) -> None:
|
||||
self.result = result
|
||||
self.payload: dict[str, Any] | None = None
|
||||
|
||||
def complete(self, **kwargs: Any) -> ImportParseOutput:
|
||||
self.payload = kwargs["payload"]
|
||||
if isinstance(self.result, Exception):
|
||||
raise self.result
|
||||
return self.result
|
||||
|
||||
|
||||
def test_llm_parser_redacts_sensitive_content_and_builds_reviewable_sections() -> None:
|
||||
completion = FakeCompletion(
|
||||
ImportParseOutput.model_validate(
|
||||
{
|
||||
"basics": {"name": "张三", "city": "广州"},
|
||||
"target": {"job_type": "校招", "position": "后端开发工程师"},
|
||||
"sections": [
|
||||
{
|
||||
"kind": "education",
|
||||
"heading": "教育经历",
|
||||
"items": [
|
||||
{
|
||||
"fields": {
|
||||
"school": "示例大学",
|
||||
"major": "软件工程",
|
||||
"start_date": "2022-09",
|
||||
"end_date_or_present": "2026-06",
|
||||
},
|
||||
"evidence": ["示例大学 软件工程 2022-09 至 2026-06"],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
"kind": "project_experience",
|
||||
"heading": "项目经历",
|
||||
"items": [
|
||||
{
|
||||
"fields": {
|
||||
"project_name": "简历助手",
|
||||
"project_role": "后端开发",
|
||||
"description": "使用 FastAPI 开发简历解析接口",
|
||||
},
|
||||
"evidence": ["简历助手 后端开发 使用 FastAPI 开发简历解析接口"],
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"skill_groups": [
|
||||
{
|
||||
"category": "编程语言",
|
||||
"skills": ["Python", "SQL"],
|
||||
"evidence": ["Python SQL"],
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
)
|
||||
parser = OpenAIResumeImportParser(completion=completion)
|
||||
|
||||
draft = parser.parse(
|
||||
source_name="resume.docx",
|
||||
text=(
|
||||
"张三 13800138000 zhang@example.com 微信: zhangsan88\n"
|
||||
"示例大学 软件工程 2022-09 至 2026-06\n"
|
||||
"简历助手 后端开发 使用 FastAPI 开发简历解析接口\nPython SQL"
|
||||
),
|
||||
)
|
||||
|
||||
assert completion.payload is not None
|
||||
sent = completion.payload["resume_text"]
|
||||
assert "13800138000" not in sent
|
||||
assert "zhang@example.com" not in sent
|
||||
assert "zhangsan88" not in sent
|
||||
assert draft.document["basics"] == {"name": "张三", "city": "广州"}
|
||||
assert [section["heading"] for section in draft.document["sections"]] == [
|
||||
"教育经历",
|
||||
"项目经历",
|
||||
]
|
||||
assert draft.document["sections"][1]["items"][0]["project_name"] == "简历助手"
|
||||
assert draft.document["skill_groups"] == [{"category": "编程语言", "skills": ["Python", "SQL"]}]
|
||||
assert all(review.status == "needs_review" for review in draft.field_reviews)
|
||||
assert any(review.field_path == "sections[1].items[0].project_name" for review in draft.field_reviews)
|
||||
assert all(review.evidence for review in draft.field_reviews)
|
||||
|
||||
|
||||
def test_llm_parser_falls_back_to_rule_parser_when_model_is_unavailable() -> None:
|
||||
parser = OpenAIResumeImportParser(
|
||||
completion=FakeCompletion(RuntimeError("model gateway unavailable")),
|
||||
fallback=RuleBasedResumeImportParser(),
|
||||
)
|
||||
|
||||
draft = parser.parse(source_name="resume.docx", text="这是导入的简历正文")
|
||||
|
||||
assert draft.document["sections"][0]["heading"] == "导入内容"
|
||||
assert draft.field_reviews[0].status == "needs_review"
|
||||
Reference in New Issue
Block a user