test: integration tests for resume library<->profile sync endpoints
This commit is contained in:
parent
22bc57242e
commit
1c9bfc9fb6
1 changed files with 134 additions and 0 deletions
134
tests/test_resume_sync_integration.py
Normal file
134
tests/test_resume_sync_integration.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
"""Integration tests for resume library<->profile sync endpoints."""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from scripts.db import create_resume, get_resume, list_resumes
|
||||
from scripts.db_migrate import migrate_db
|
||||
|
||||
STRUCT_JSON = {
|
||||
"name": "Alex Rivera",
|
||||
"email": "alex@example.com",
|
||||
"phone": "555-0100",
|
||||
"career_summary": "Senior UX Designer.",
|
||||
"experience": [{"title": "Designer", "company": "Acme", "start_date": "2022",
|
||||
"end_date": "present", "location": "Remote", "bullets": ["Led redesign"]}],
|
||||
"education": [{"institution": "State U", "degree": "B.A.", "field": "Design",
|
||||
"start_date": "2016", "end_date": "2020"}],
|
||||
"skills": ["Figma"],
|
||||
"achievements": ["Design award"],
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fresh_db(tmp_path, monkeypatch):
|
||||
"""Set up a fresh isolated DB + config dir, wired to dev_api._request_db."""
|
||||
db = tmp_path / "test.db"
|
||||
cfg = tmp_path / "config"
|
||||
cfg.mkdir()
|
||||
# STAGING_DB drives _user_yaml_path() -> dirname(db)/config/user.yaml
|
||||
monkeypatch.setenv("STAGING_DB", str(db))
|
||||
migrate_db(db)
|
||||
import dev_api
|
||||
monkeypatch.setattr(
|
||||
dev_api,
|
||||
"_request_db",
|
||||
type("CV", (), {"get": lambda self: str(db), "set": lambda *a: None})(),
|
||||
)
|
||||
return db, cfg
|
||||
|
||||
|
||||
def test_apply_to_profile_updates_yaml(fresh_db, monkeypatch):
|
||||
db, cfg = fresh_db
|
||||
import dev_api
|
||||
client = TestClient(dev_api.app)
|
||||
entry = create_resume(db, name="Test Resume",
|
||||
text="Alex Rivera\n", source="uploaded",
|
||||
struct_json=json.dumps(STRUCT_JSON))
|
||||
resp = client.post(f"/api/resumes/{entry['id']}/apply-to-profile")
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["ok"] is True
|
||||
assert "backup_id" in data
|
||||
assert "Auto-backup before Test Resume" in data["backup_name"]
|
||||
profile_yaml = cfg / "plain_text_resume.yaml"
|
||||
assert profile_yaml.exists()
|
||||
profile = yaml.safe_load(profile_yaml.read_text())
|
||||
assert profile["career_summary"] == "Senior UX Designer."
|
||||
# Name split: "Alex Rivera" -> name="Alex", surname="Rivera"
|
||||
assert profile["name"] == "Alex"
|
||||
assert profile["surname"] == "Rivera"
|
||||
assert profile["education"][0]["institution"] == "State U"
|
||||
|
||||
|
||||
def test_apply_to_profile_creates_backup(fresh_db, monkeypatch):
|
||||
db, cfg = fresh_db
|
||||
profile_path = cfg / "plain_text_resume.yaml"
|
||||
profile_path.write_text(yaml.dump({"name": "Old Name", "career_summary": "Old summary"}))
|
||||
entry = create_resume(db, name="New Resume",
|
||||
text="Alex Rivera\n", source="uploaded",
|
||||
struct_json=json.dumps(STRUCT_JSON))
|
||||
import dev_api
|
||||
client = TestClient(dev_api.app)
|
||||
client.post(f"/api/resumes/{entry['id']}/apply-to-profile")
|
||||
resumes = list_resumes(db_path=db)
|
||||
backup = next((r for r in resumes if r["source"] == "auto_backup"), None)
|
||||
assert backup is not None
|
||||
|
||||
|
||||
def test_apply_to_profile_preserves_metadata(fresh_db, monkeypatch):
|
||||
db, cfg = fresh_db
|
||||
profile_path = cfg / "plain_text_resume.yaml"
|
||||
profile_path.write_text(yaml.dump({
|
||||
"name": "Old", "salary_min": 80000, "salary_max": 120000,
|
||||
"remote": True, "gender": "non-binary",
|
||||
}))
|
||||
entry = create_resume(db, name="New",
|
||||
text="Alex\n", source="uploaded",
|
||||
struct_json=json.dumps(STRUCT_JSON))
|
||||
import dev_api
|
||||
client = TestClient(dev_api.app)
|
||||
client.post(f"/api/resumes/{entry['id']}/apply-to-profile")
|
||||
profile = yaml.safe_load(profile_path.read_text())
|
||||
assert profile["salary_min"] == 80000
|
||||
assert profile["remote"] is True
|
||||
assert profile["gender"] == "non-binary"
|
||||
|
||||
|
||||
def test_save_resume_syncs_to_default_library_entry(fresh_db, monkeypatch):
|
||||
db, cfg = fresh_db
|
||||
entry = create_resume(db, name="My Resume",
|
||||
text="Original", source="manual")
|
||||
user_yaml = cfg / "user.yaml"
|
||||
user_yaml.write_text(yaml.dump({"default_resume_id": entry["id"], "wizard_complete": True}))
|
||||
import dev_api
|
||||
client = TestClient(dev_api.app)
|
||||
resp = client.put("/api/settings/resume", json={
|
||||
"name": "Alex", "career_summary": "Updated summary",
|
||||
"experience": [], "education": [], "achievements": [], "skills": [],
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["synced_library_entry_id"] == entry["id"]
|
||||
updated = get_resume(db_path=db, resume_id=entry["id"])
|
||||
assert updated["synced_at"] is not None
|
||||
struct = json.loads(updated["struct_json"])
|
||||
assert struct["career_summary"] == "Updated summary"
|
||||
|
||||
|
||||
def test_save_resume_no_default_no_crash(fresh_db, monkeypatch):
|
||||
db, cfg = fresh_db
|
||||
user_yaml = cfg / "user.yaml"
|
||||
user_yaml.write_text(yaml.dump({"wizard_complete": True}))
|
||||
import dev_api
|
||||
client = TestClient(dev_api.app)
|
||||
resp = client.put("/api/settings/resume", json={
|
||||
"name": "Alex", "career_summary": "", "experience": [],
|
||||
"education": [], "achievements": [], "skills": [],
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["synced_library_entry_id"] is None
|
||||
Loading…
Reference in a new issue