HR-ATS-Portal/backend/tests/test_employment_agent.py

116 lines
3.8 KiB
Python

"""employment_agent parse_employment_response — linkedin_url is an agent key.
parse_employment_response returns a DICT. These tests used to unpack it
positionally, which silently read dict KEYS instead of values and asserted
against whatever the last key happened to be.
"""
from __future__ import annotations
from employment_agent.decorators import parse_employment_response
from employment_agent.prompt import EDUCATION, NO_COMPANY, NO_LINKEDIN
def test_parses_linkedin_url_key_separately():
# The resume must actually contain the slug: _clean_linkedin keeps a URL
# only when the CV evidences it, so a resume that never mentions LinkedIn
# correctly yields None however confident the model was.
fields = parse_employment_response(
{
"current_employment": "Acme",
"education": "BS CS",
"current_title": "Engineer",
"linkedin_url": "https://www.linkedin.com/in/jane-doe",
},
"Acme BS CS Engineer https://www.linkedin.com/in/jane-doe",
)
assert fields["current_employment"] == "Acme"
assert fields["education"] == "BS CS"
assert fields["current_title"] == "Engineer"
assert fields["linkedin_url"] == "https://www.linkedin.com/in/jane-doe"
def test_url_absent_from_the_resume_is_not_trusted():
fields = parse_employment_response(
{
"current_employment": "Acme",
"education": "BS CS",
"current_title": "Engineer",
"linkedin_url": "https://www.linkedin.com/in/jane-doe",
},
"Acme BS CS Engineer",
)
assert fields["linkedin_url"] is None
def test_sentinel_and_non_linkedin_are_dropped():
sentinel = parse_employment_response(
{
"current_employment": NO_COMPANY,
"education": EDUCATION,
"current_title": "x",
"linkedin_url": NO_LINKEDIN,
},
"",
)
assert sentinel["linkedin_url"] is None
github = parse_employment_response(
{
"current_employment": NO_COMPANY,
"education": EDUCATION,
"current_title": "x",
"linkedin_url": "https://github.com/jane",
},
"",
)
assert github["linkedin_url"] is None
def test_adds_scheme_and_rejects_company_page():
bare = parse_employment_response(
{
"current_employment": NO_COMPANY,
"education": EDUCATION,
"current_title": "x",
"linkedin_url": "www.linkedin.com/in/jane-doe",
},
"",
)
assert bare["linkedin_url"] == "https://www.linkedin.com/in/jane-doe"
company_page = parse_employment_response(
{
"current_employment": NO_COMPANY,
"education": EDUCATION,
"current_title": "x",
"linkedin_url": "https://www.linkedin.com/company/acme",
},
"",
)
assert company_page["linkedin_url"] is None
def test_city_prompt_asks_openai_for_a_proper_city_name():
from employment_agent.prompt import city_list_prompt, prompt
text = prompt()
assert "Karachi(Malir)" in text
assert 'JSON city must be "Karachi"' in text
assert "Return ONE proper city name only" in text
listed = city_list_prompt()
assert "Karachi(Malir)" in listed
assert '"cities"' in listed
def test_parse_normalized_cities_keeps_agent_names():
from employment_agent.execute_agent import parse_normalized_cities
assert parse_normalized_cities(
{"cities": ["Karachi", "Karachi", "Lahore", "no city mentioned"]},
fallback=["Karachi(Malir)"],
) == ["Karachi", "Lahore"]
def test_parse_normalized_cities_falls_back_when_the_model_shape_is_wrong():
from employment_agent.execute_agent import parse_normalized_cities
assert parse_normalized_cities({"oops": True}, fallback=["Karachi(Malir)"]) == ["Karachi(Malir)"]