143 lines
4.0 KiB
Python
143 lines
4.0 KiB
Python
"""Integration tests for GET /api/v1/people (browse/discover, section 17 --
|
|||
|
|
additive beyond the spec's minimum endpoint list): sorting, filtering, and
|
||
|
|
pagination against real PostgreSQL, exercised through
|
||
|
|
person_service.list_people directly rather than over HTTP. Mirrors
|
||
|
|
test_movie_browse.py; people have no genre/year/status equivalent, just
|
||
|
|
known_for_department, so there's no invalid-filter case to test here (no
|
||
|
|
parsing/enum lookup happens, unlike movies/series filters)."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
|
|
||
|
|
from app.repositories.provider_repository import get_or_create_provider
|
||
|
|
from app.repositories.reference_repository import get_or_create_person
|
||
|
|
from app.services import person_service
|
||
|
|
|
||
|
|
|
||
|
|
async def _seed_people(db_session: AsyncSession) -> None:
|
||
|
|
provider = await get_or_create_provider(db_session, "tmdb", "TMDB")
|
||
|
|
people = [
|
||
|
|
("1001", "Alice Actor", 10.0, "Acting"),
|
||
|
|
("1002", "Bob Actor", 90.0, "Acting"),
|
||
|
|
("1003", "Cara Director", 50.0, "Directing"),
|
||
|
|
("1004", "Dana Writer", 20.0, "Writing"),
|
||
|
|
]
|
||
|
|
for external_id, name, popularity, department in people:
|
||
|
|
await get_or_create_person(
|
||
|
|
db_session,
|
||
|
|
provider_id=provider.id,
|
||
|
|
external_id=external_id,
|
||
|
|
name=name,
|
||
|
|
popularity=popularity,
|
||
|
|
known_for_department=department,
|
||
|
|
)
|
||
|
|
await db_session.commit()
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_people_defaults_to_popularity_descending(db_session: AsyncSession):
|
||
|
|
await _seed_people(db_session)
|
||
|
|
|
||
|
|
out = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department=None,
|
||
|
|
sort_by="popularity",
|
||
|
|
sort_dir="desc",
|
||
|
|
page=1,
|
||
|
|
page_size=20,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert out.total_results == 4
|
||
|
|
assert out.total_pages == 1
|
||
|
|
assert [p.name for p in out.results] == [
|
||
|
|
"Bob Actor",
|
||
|
|
"Cara Director",
|
||
|
|
"Dana Writer",
|
||
|
|
"Alice Actor",
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_people_filters_by_known_for_department(db_session: AsyncSession):
|
||
|
|
await _seed_people(db_session)
|
||
|
|
|
||
|
|
out = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department="Acting",
|
||
|
|
sort_by="popularity",
|
||
|
|
sort_dir="desc",
|
||
|
|
page=1,
|
||
|
|
page_size=20,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert out.total_results == 2
|
||
|
|
assert [p.name for p in out.results] == ["Bob Actor", "Alice Actor"]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_people_sorts_by_name_ascending(db_session: AsyncSession):
|
||
|
|
await _seed_people(db_session)
|
||
|
|
|
||
|
|
out = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department=None,
|
||
|
|
sort_by="name",
|
||
|
|
sort_dir="asc",
|
||
|
|
page=1,
|
||
|
|
page_size=20,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert [p.name for p in out.results] == [
|
||
|
|
"Alice Actor",
|
||
|
|
"Bob Actor",
|
||
|
|
"Cara Director",
|
||
|
|
"Dana Writer",
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_people_paginates(db_session: AsyncSession):
|
||
|
|
await _seed_people(db_session)
|
||
|
|
|
||
|
|
page1 = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department=None,
|
||
|
|
sort_by="popularity",
|
||
|
|
sort_dir="desc",
|
||
|
|
page=1,
|
||
|
|
page_size=2,
|
||
|
|
)
|
||
|
|
page2 = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department=None,
|
||
|
|
sort_by="popularity",
|
||
|
|
sort_dir="desc",
|
||
|
|
page=2,
|
||
|
|
page_size=2,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert page1.total_results == 4
|
||
|
|
assert page1.total_pages == 2
|
||
|
|
assert [p.name for p in page1.results] == ["Bob Actor", "Cara Director"]
|
||
|
|
assert [p.name for p in page2.results] == ["Dana Writer", "Alice Actor"]
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.asyncio
|
||
|
|
async def test_list_people_returns_empty_page_when_nothing_matches(db_session: AsyncSession):
|
||
|
|
await _seed_people(db_session)
|
||
|
|
|
||
|
|
out = await person_service.list_people(
|
||
|
|
db_session,
|
||
|
|
known_for_department="Editing",
|
||
|
|
sort_by="popularity",
|
||
|
|
sort_dir="desc",
|
||
|
|
page=1,
|
||
|
|
page_size=20,
|
||
|
|
)
|
||
|
|
|
||
|
|
assert out.results == []
|
||
|
|
assert out.total_results == 0
|
||
|
|
assert out.total_pages == 0
|