from __future__ import annotations from collections.abc import Mapping from pathlib import Path from typing import Any from pydantic import BaseModel from resume_harness.io import load_model from resume_harness.models import ( CandidateProfile, ContentPlan, EvidenceMap, GenerationConfig, JobAnalysis, JobPosting, QualityReport, ResumeDraft, ) from resume_harness.pipeline import PipelineStatus, ResumePipeline from resume_harness.renderer import render_markdown ROOT = Path(__file__).resolve().parents[1] class GoldenFixtureBackend: def __init__(self, responses: list[tuple[str, BaseModel]]) -> None: self._responses = list(responses) def complete_json( self, *, stage: str, system_prompt: str, task_prompt: str, user_payload: Mapping[str, Any], output_model: type[BaseModel], ) -> BaseModel: assert system_prompt and task_prompt and user_payload expected_stage, response = self._responses.pop(0) assert stage == expected_stage assert isinstance(response, output_model) return response def test_professional_golden_fixture_passes_full_pipeline_and_renders() -> None: profile = load_model(ROOT / "examples/candidate.sample.yaml", CandidateProfile) posting = load_model(ROOT / "examples/job.sample.yaml", JobPosting) config = load_model(ROOT / "examples/config.sample.yaml", GenerationConfig) analysis = load_model(ROOT / "examples/job-analysis.sample.yaml", JobAnalysis) evidence_map = load_model(ROOT / "examples/evidence-map.sample.yaml", EvidenceMap) plan = load_model(ROOT / "examples/content-plan.sample.yaml", ContentPlan) draft = load_model(ROOT / "examples/draft.sample.yaml", ResumeDraft) report = load_model(ROOT / "examples/quality-report.sample.yaml", QualityReport) backend = GoldenFixtureBackend( [ ("analyze-job", analysis), ("map-evidence", evidence_map), ("plan-content", plan), ("draft-resume", draft), ("evaluate-resume", report), ] ) result = ResumePipeline(backend).run(profile, posting, config) assert result.status is PipelineStatus.PASSED assert result.deterministic_findings == [] assert result.quality_report is not None assert result.quality_report.evidence_coverage == 1.0 assert result.quality_report.requirement_coverage == 1.0 markdown = render_markdown(result.draft, profile, config, analysis=analysis) assert "## 핵심 역량" in markdown assert "## 경력" in markdown assert "## 주요 프로젝트" in markdown assert "## 자격" in markdown assert markdown.count("\n- ") >= 16