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.
82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
"""Unit testy parsera StashDB."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from datetime import date
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from app.connectors.stashdb import _parse_scene
|
|
|
|
|
|
@pytest.fixture
|
|
def stashdb_raw() -> dict:
|
|
return json.loads(
|
|
(Path(__file__).parent / "fixtures" / "stashdb_scene.json").read_text()
|
|
)
|
|
|
|
|
|
def test_parses_basic_fields(stashdb_raw: dict) -> None:
|
|
s = _parse_scene(stashdb_raw)
|
|
assert s is not None
|
|
assert s.external_id == "99999999-9999-4999-8999-999999999999"
|
|
assert s.title == "The Great Heist"
|
|
assert s.release_date == date(2024, 8, 15)
|
|
assert s.duration_sec == 1820
|
|
assert s.code == "BRZ-12345"
|
|
assert s.description.startswith("A clever caper")
|
|
|
|
|
|
def test_extracts_tpdb_cross_ref_from_urls(stashdb_raw: dict) -> None:
|
|
s = _parse_scene(stashdb_raw)
|
|
assert s is not None
|
|
assert s.cross_source_refs == {
|
|
"tpdb": "11111111-1111-4111-8111-111111111111"
|
|
}
|
|
|
|
|
|
def test_studio_with_parent(stashdb_raw: dict) -> None:
|
|
s = _parse_scene(stashdb_raw)
|
|
assert s is not None
|
|
assert s.studio is not None
|
|
assert s.studio.name == "Brazzers Exxtra"
|
|
assert s.studio.parent_external_id == "stashdb-brz-parent"
|
|
assert s.studio.parent_name == "Brazzers"
|
|
|
|
|
|
def test_performers_use_as_alias_when_different(stashdb_raw: dict) -> None:
|
|
s = _parse_scene(stashdb_raw)
|
|
assert s is not None
|
|
mia = s.performers[0]
|
|
assert mia.external_id == "perf-mia"
|
|
assert mia.name == "Mia Malkova"
|
|
assert mia.as_alias_in_scene == "Mia M."
|
|
assert "Madison Clover" in mia.aliases
|
|
assert mia.gender == "female"
|
|
assert mia.birth_date == date(1992, 7, 1)
|
|
|
|
johnny = s.performers[1]
|
|
assert johnny.as_alias_in_scene is None # `as` is null in fixture
|
|
|
|
|
|
def test_fingerprints_are_lowercased_and_typed(stashdb_raw: dict) -> None:
|
|
s = _parse_scene(stashdb_raw)
|
|
assert s is not None
|
|
kinds = sorted(fp.kind for fp in s.fingerprints)
|
|
assert kinds == ["oshash", "phash"]
|
|
phash = next(fp for fp in s.fingerprints if fp.kind == "phash")
|
|
assert phash.value == "0123456789abcdef"
|
|
|
|
|
|
def test_skips_unknown_fingerprint_algorithm() -> None:
|
|
raw = {
|
|
"id": "x",
|
|
"title": "t",
|
|
"performers": [],
|
|
"tags": [],
|
|
"fingerprints": [{"hash": "abc", "algorithm": "FOOHASH"}],
|
|
}
|
|
s = _parse_scene(raw)
|
|
assert s is not None
|
|
assert s.fingerprints == []
|