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

86 lines
3.3 KiB
Python

"""linkedin_utils: the slug vocabulary Find Talent matches applicants on.
Pure functions only — the DB annotation path in talent/matching.py reuses
exactly these, so the extraction cases here are the matching cases there.
"""
from __future__ import annotations
from linkedin_utils import (
NO_SLUG,
primary_slug_from_text,
slug_from_url,
slugs_from_text,
)
# ---------------------------------------------------------------- from URLs
def test_slug_from_normalized_profile_url():
assert slug_from_url("https://www.linkedin.com/in/jane-doe-123") == "jane-doe-123"
assert slug_from_url("https://linkedin.com/in/JaneDoe") == "janedoe"
def test_slug_ignores_subpaths_and_non_linkedin():
assert slug_from_url("https://www.linkedin.com/in/jane-doe/details/experience") == "jane-doe"
assert slug_from_url("https://github.com/in/jane-doe") is None
assert slug_from_url(None) is None
# ---------------------------------------------------------------- from CV text
def test_extracts_bare_and_schemed_links():
text = "Contact: linkedin.com/in/ali-raza-8a1b2c | ali@example.com"
assert slugs_from_text(text) == ["ali-raza-8a1b2c"]
text2 = "Profile: https://www.linkedin.com/in/Ali-Raza-8A1B2C/"
assert slugs_from_text(text2) == ["ali-raza-8a1b2c"]
def test_wrapped_and_spaced_pdf_urls():
# pypdf wraps the path; glyph-padded CVs insert spaces around slashes.
assert slugs_from_text("linkedin.com/in/\njane-doe") == ["jane-doe"]
assert slugs_from_text("linkedin.com / in / jane-doe") == ["jane-doe"]
assert slugs_from_text("https://pk.linkedin.com/in/jane-doe") == ["jane-doe"]
def test_html_href_and_mobile_path():
html = '<a href="https://www.linkedin.com/in/jane-doe">LinkedIn</a>'
assert slugs_from_text(html) == ["jane-doe"]
assert slugs_from_text("See linkedin.com/mwlite/in/jane-doe") == ["jane-doe"]
def test_profile_url_from_text_prefers_slug_then_short_link():
from linkedin_utils import profile_url_from_text
assert profile_url_from_text("linkedin.com/in/jane-doe") == (
"https://www.linkedin.com/in/jane-doe"
)
assert profile_url_from_text("Contact: lnkd.in/abc12XY") == "https://lnkd.in/abc12XY"
assert profile_url_from_text("no profile here") is None
def test_percent_encoding_and_trailing_punctuation():
# PDF extraction often percent-encodes hyphens and glues sentence dots on.
assert slugs_from_text("see linkedin.com/in/jane%2Ddoe.") == ["jane-doe"]
def test_legacy_pub_path_and_dedup():
text = "linkedin.com/pub/jane-doe and again https://linkedin.com/in/jane-doe"
assert slugs_from_text(text) == ["jane-doe"]
def test_primary_slug_sentinel_contract():
# "" (scanned, none found) must be distinct from None (never scanned):
# the lazy backfill filters on IS NULL and would otherwise rescan forever.
assert primary_slug_from_text("no links here") == NO_SLUG
assert primary_slug_from_text("") == NO_SLUG
assert primary_slug_from_text("linkedin.com/in/x-y") == "x-y"
def test_cv_and_profile_url_agree_on_the_key():
# The whole feature: a CV mention and the actor's normalized URL must
# produce the same key for the same person.
cv = "Portfolio — www.LinkedIn.com/in/Muhammad%2DTalha%2DAhmed."
profile_url = "https://www.linkedin.com/in/muhammad-talha-ahmed"
assert primary_slug_from_text(cv) == slug_from_url(profile_url)