Goon — self-hosted aggregator for adult-content scene metadata. Indexes scenes from TPDB, StashDB, and 30+ public adult tube sites. Cross-source deduplication via perceptual hash + Levenshtein distance. FastAPI backend + APScheduler worker + React Native (Expo) mobile client. FOSS, ad-free, donation-funded. See README for details.
86 lines
3 KiB
Python
86 lines
3 KiB
Python
"""Unit testy parsera TPDB — `_parse_scene` i pochodne."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import date
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.connectors.tpdb import _parse_scene
|
|
|
|
|
|
@pytest.fixture
|
|
def tpdb_scene_raw() -> dict:
|
|
path = Path(__file__).parent / "fixtures" / "tpdb_scene.json"
|
|
return json.loads(path.read_text())
|
|
|
|
|
|
def test_parse_scene_basic_fields(tpdb_scene_raw: dict) -> None:
|
|
scene = _parse_scene(tpdb_scene_raw)
|
|
assert scene is not None
|
|
assert scene.external_id == "11111111-1111-4111-8111-111111111111"
|
|
assert scene.title == "The Great Heist"
|
|
assert scene.release_date == date(2024, 8, 15)
|
|
assert scene.duration_sec == 1820
|
|
assert scene.code == "BRZ-12345"
|
|
assert scene.director == "Jane Doe"
|
|
|
|
|
|
def test_parse_scene_studio(tpdb_scene_raw: dict) -> None:
|
|
scene = _parse_scene(tpdb_scene_raw)
|
|
assert scene is not None
|
|
assert scene.studio is not None
|
|
assert scene.studio.name == "Brazzers Exxtra"
|
|
assert scene.studio.slug == "brazzers-exxtra"
|
|
assert scene.studio.parent_external_id == "33333333-3333-4333-8333-333333333333"
|
|
assert scene.studio.parent_name == "Brazzers"
|
|
assert scene.studio.network == "MindGeek"
|
|
|
|
|
|
def test_parse_scene_performers_use_canonical_id_from_parent(tpdb_scene_raw: dict) -> None:
|
|
scene = _parse_scene(tpdb_scene_raw)
|
|
assert scene is not None
|
|
assert len(scene.performers) == 2
|
|
|
|
mia = scene.performers[0]
|
|
# canonical UUID = parent.id, NOT the scene-local performer.id
|
|
assert mia.external_id == "66666666-6666-4666-8666-666666666666"
|
|
assert mia.name == "Mia Malkova"
|
|
# alias used in this scene must be exposed
|
|
assert mia.as_alias_in_scene == "Mia M."
|
|
# aliases parsed from "Mia M., Madison Clover" string
|
|
assert "Mia M." in mia.aliases
|
|
assert "Madison Clover" in mia.aliases
|
|
assert mia.gender == "female"
|
|
assert mia.birth_date == date(1992, 7, 1)
|
|
|
|
johnny = scene.performers[1]
|
|
assert johnny.external_id == "88888888-8888-4888-8888-888888888888"
|
|
assert johnny.name == "Johnny Sins"
|
|
# Same name in scene as canonical → as_alias_in_scene is None
|
|
assert johnny.as_alias_in_scene is None
|
|
|
|
|
|
def test_parse_scene_tags(tpdb_scene_raw: dict) -> None:
|
|
scene = _parse_scene(tpdb_scene_raw)
|
|
assert scene is not None
|
|
tags_by_slug = {t.slug: t for t in scene.tags}
|
|
assert "heist" in tags_by_slug
|
|
assert tags_by_slug["big-tits"].name == "Big Tits"
|
|
|
|
|
|
def test_parse_scene_skips_when_missing_id() -> None:
|
|
assert _parse_scene({"title": "no id"}) is None
|
|
|
|
|
|
def test_parse_scene_skips_when_missing_title() -> None:
|
|
assert _parse_scene({"id": "deadbeef"}) is None
|
|
|
|
|
|
def test_parse_scene_raw_payload_preserved(tpdb_scene_raw: dict) -> None:
|
|
scene = _parse_scene(tpdb_scene_raw)
|
|
assert scene is not None
|
|
# Pydantic v2 makes a shallow copy of dict[str, Any] during validation,
|
|
# but the value must be equal (used as external_records.raw payload).
|
|
assert scene.raw == tpdb_scene_raw
|