222 lines
8.4 KiB
Python
222 lines
8.4 KiB
Python
"""Shared test fixtures for Resume Matcher backend tests."""
|
|
|
|
import copy
|
|
import importlib
|
|
|
|
import pytest
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sample resume data — full ResumeData-compatible dict
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.fixture
|
|
def sample_resume() -> dict:
|
|
"""A realistic resume dict matching the ResumeData schema."""
|
|
return {
|
|
"personalInfo": {
|
|
"name": "Jane Doe",
|
|
"title": "Senior Backend Engineer",
|
|
"email": "jane@example.com",
|
|
"phone": "+1-555-0100",
|
|
"location": "San Francisco, CA",
|
|
"website": "https://janedoe.dev",
|
|
"linkedin": "linkedin.com/in/janedoe",
|
|
"github": "github.com/janedoe",
|
|
},
|
|
"summary": "Backend engineer with 6 years of experience building scalable Python APIs and microservices.",
|
|
"workExperience": [
|
|
{
|
|
"id": 1,
|
|
"title": "Senior Backend Engineer",
|
|
"company": "Acme Corp",
|
|
"location": "San Francisco, CA",
|
|
"years": "Jan 2021 - Present",
|
|
"description": [
|
|
"Built REST APIs serving 50K requests/day using Python and FastAPI",
|
|
"Led migration from monolith to microservices architecture",
|
|
"Mentored 3 junior developers on backend best practices",
|
|
],
|
|
},
|
|
{
|
|
"id": 2,
|
|
"title": "Software Engineer",
|
|
"company": "StartupCo",
|
|
"location": "New York, NY",
|
|
"years": "Jun 2018 - Dec 2020",
|
|
"description": [
|
|
"Developed payment processing system handling $2M monthly",
|
|
"Wrote unit and integration tests improving coverage from 40% to 85%",
|
|
],
|
|
},
|
|
],
|
|
"education": [
|
|
{
|
|
"id": 1,
|
|
"institution": "MIT",
|
|
"degree": "B.S. Computer Science",
|
|
"years": "2014 - 2018",
|
|
"description": "Graduated with honors, Dean's List",
|
|
}
|
|
],
|
|
"personalProjects": [
|
|
{
|
|
"id": 1,
|
|
"name": "OpenAPI Generator",
|
|
"role": "Creator & Maintainer",
|
|
"years": "Mar 2021 - Present",
|
|
"description": [
|
|
"CLI tool generating API clients from OpenAPI specs",
|
|
"500+ GitHub stars, used by 30+ companies",
|
|
],
|
|
}
|
|
],
|
|
"additional": {
|
|
"technicalSkills": ["Python", "FastAPI", "Docker", "AWS", "PostgreSQL", "Redis"],
|
|
"languages": ["English (Native)", "Spanish (Conversational)"],
|
|
"certificationsTraining": ["AWS Solutions Architect Associate"],
|
|
"awards": ["Employee of the Year 2022"],
|
|
},
|
|
"customSections": {},
|
|
"sectionMeta": [],
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_resume_copy(sample_resume) -> dict:
|
|
"""Deep copy of sample_resume for mutation-safe tests."""
|
|
return copy.deepcopy(sample_resume)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Job-related fixtures
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.fixture
|
|
def sample_job_keywords() -> dict:
|
|
"""Extracted job keywords matching the LLM output format."""
|
|
return {
|
|
"required_skills": ["Python", "FastAPI", "Docker", "Kubernetes"],
|
|
"preferred_skills": ["AWS", "Terraform", "GraphQL"],
|
|
"experience_requirements": ["5+ years backend development"],
|
|
"education_requirements": ["Bachelor's in CS or equivalent"],
|
|
"key_responsibilities": [
|
|
"Design and build scalable APIs",
|
|
"Lead technical architecture decisions",
|
|
],
|
|
"keywords": ["microservices", "CI/CD", "agile", "REST API"],
|
|
"experience_years": 5,
|
|
"seniority_level": "senior",
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_job_description() -> str:
|
|
"""A realistic job description text."""
|
|
return (
|
|
"Senior Backend Engineer at TechCorp\n\n"
|
|
"We are looking for a Senior Backend Engineer to join our platform team. "
|
|
"You will design and build scalable APIs using Python and FastAPI. "
|
|
"Experience with Docker, Kubernetes, and AWS is required. "
|
|
"Terraform and GraphQL experience is a plus.\n\n"
|
|
"Requirements:\n"
|
|
"- 5+ years backend development experience\n"
|
|
"- Strong Python skills with FastAPI or similar frameworks\n"
|
|
"- Experience with microservices architecture\n"
|
|
"- Familiarity with CI/CD pipelines and agile methodologies\n"
|
|
"- Bachelor's degree in CS or equivalent\n"
|
|
)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Master resume — used for alignment validation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.fixture
|
|
def master_resume(sample_resume) -> dict:
|
|
"""Master resume (source of truth) — same as sample_resume by default."""
|
|
return copy.deepcopy(sample_resume)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# ResumeChange fixtures for diff-based tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.fixture
|
|
def sample_changes():
|
|
"""A set of ResumeChange dicts covering all action types."""
|
|
from app.schemas.models import ResumeChange
|
|
|
|
return [
|
|
ResumeChange(
|
|
path="summary",
|
|
action="replace",
|
|
original="Backend engineer with 6 years of experience building scalable Python APIs and microservices.",
|
|
value="Senior backend engineer with 6 years building scalable Python APIs, microservices, and cloud infrastructure on AWS.",
|
|
reason="Added cloud/AWS keywords from JD",
|
|
),
|
|
ResumeChange(
|
|
path="workExperience[0].description[0]",
|
|
action="replace",
|
|
original="Built REST APIs serving 50K requests/day using Python and FastAPI",
|
|
value="Designed and built REST APIs serving 50K requests/day using Python, FastAPI, and Docker",
|
|
reason="Added Docker keyword from JD",
|
|
),
|
|
ResumeChange(
|
|
path="workExperience[0].description",
|
|
action="append",
|
|
original=None,
|
|
value="Implemented CI/CD pipelines with GitHub Actions reducing deploy time by 40%",
|
|
reason="Added CI/CD keyword from JD",
|
|
),
|
|
ResumeChange(
|
|
path="additional.technicalSkills",
|
|
action="reorder",
|
|
original=None,
|
|
value=["Python", "FastAPI", "Docker", "AWS", "PostgreSQL", "Redis"],
|
|
reason="Already in good order, no change needed",
|
|
),
|
|
]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Isolated database — swap the global TinyDB singleton for a temp-file DB
|
|
# ---------------------------------------------------------------------------
|
|
|
|
@pytest.fixture
|
|
async def isolated_db(tmp_path, monkeypatch):
|
|
"""Replace the global ``db`` singleton with a disposable temp-file SQLite DB
|
|
across ``app.database`` and every router module that imported it.
|
|
|
|
Lets endpoint / e2e tests run against a REAL (but isolated) database instead
|
|
of a MagicMock, so persistence, the master-resume invariant, and CRUD are
|
|
actually exercised — without touching the developer's real database. A
|
|
temp **file** (not ``:memory:``) is required: SQLite's connection pool gives
|
|
each connection its own in-memory DB, so the async + sync engines would not
|
|
share state.
|
|
"""
|
|
import app.database as database_module
|
|
from app.database import Database
|
|
|
|
test_db = Database(db_path=tmp_path / "isolated_db.db")
|
|
monkeypatch.setattr(database_module, "db", test_db)
|
|
for router_name in (
|
|
"resumes",
|
|
"jobs",
|
|
"enrichment",
|
|
"config",
|
|
"health",
|
|
"applications",
|
|
"resume_wizard",
|
|
):
|
|
try:
|
|
module = importlib.import_module(f"app.routers.{router_name}")
|
|
except ModuleNotFoundError:
|
|
continue
|
|
if hasattr(module, "db"):
|
|
monkeypatch.setattr(module, "db", test_db)
|
|
try:
|
|
yield test_db
|
|
finally:
|
|
await test_db.close()
|