"""``IdentitySyncService._resolve_hrbp_emails`` — resolves a person's ``hris_hrbp_person_id`` (SF EmpJobRelationships 2448) to (email, name). This feeds the Feishu contact runner's HRBP GENERIC_USER custom attribute (via the ``hrbp_email`` render-context field → ``hrbp_user_id_email`` mapping rule). Mirrors the manager-email resolver; both delegate to the shared ``_resolve_related_emails`` helper. """ from __future__ import annotations import uuid import pytest from app.domains.identity_sync.service import IdentitySyncService from app.identity.person_models import IdentityPerson async def _person(db, *, email: str, hrbp_id: uuid.UUID | None = None, status: str = "active") -> IdentityPerson: p = IdentityPerson( id=uuid.uuid4(), work_email=email, display_name=email.split("@")[0].replace(".", " ").title(), employment_status=status, source_system="successfactors", hris_person_id=f"sf-{email}", hris_hrbp_person_id=hrbp_id, ) db.add(p) await db.flush() return p @pytest.mark.asyncio async def test_resolves_hrbp_email_and_name(db_session): hrbp = await _person(db_session, email="claire.zhu@pingcap.com") person = await _person( db_session, email="alice@pingcap.com", hrbp_id=hrbp.id, ) svc = IdentitySyncService(db_session) out = await svc._resolve_hrbp_emails([person.id]) assert out[person.id] == ( hrbp.work_email, hrbp.name_pinyin or hrbp.display_name or hrbp.work_email, ) @pytest.mark.asyncio async def test_no_hrbp_returns_none_pair(db_session): person = await _person(db_session, email="bob@pingcap.com", hrbp_id=None) svc = IdentitySyncService(db_session) out = await svc._resolve_hrbp_emails([person.id]) assert out[person.id] == (None, None) @pytest.mark.asyncio async def test_dangling_hrbp_pointer_to_deleted_person_is_none(db_session): """An HRBP pointer to a soft-deleted person resolves to (None, None) rather than leaking a tombstoned row's email.""" from datetime import UTC, datetime hrbp = await _person(db_session, email="gone.hrbp@pingcap.com") hrbp.deleted_at = datetime.now(UTC) person = await _person( db_session, email="carol@pingcap.com", hrbp_id=hrbp.id, ) await db_session.flush() svc = IdentitySyncService(db_session) out = await svc._resolve_hrbp_emails([person.id]) assert out[person.id] == (None, None) @pytest.mark.asyncio async def test_empty_input_returns_empty(db_session): svc = IdentitySyncService(db_session) assert await svc._resolve_hrbp_emails([]) == {}