CI / lint (push) Canceled after 0s
CI / typecheck (push) Canceled after 0s
CI / unit-tests (push) Canceled after 0s
CI / integration-tests (push) Canceled after 0s
CI / container-build (push) Canceled after 0s
CI / dependency-audit (push) Canceled after 0s
Production-grade media metadata backend per docs/aurora-core-spec.md: Aurora-owned UUIDv7 identity system, normalized movie/TV/people/credits schema, provider abstraction with a TMDb adapter, an idempotent async ingestion pipeline (normalize -> match -> upsert -> provenance), a Postgres FTS/trigram search layer, a stateless FastAPI v1 API with Redis caching/rate-limiting, arq workers, dev/prod Docker Compose topologies, unit + integration + load tests, CI, and architecture/ database/API/ERD documentation. Co-Authored-By: Claude Sonnet 5 <[email protected]>
74 lines
2.1 KiB
Python
74 lines
2.1 KiB
Python
"""Unit tests for the Aurora ID system (app/core/ids.py) — section 3."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from app.core.ids import (
|
|
ENTITY_PREFIXES,
|
|
aurora_id,
|
|
is_valid_aurora_id,
|
|
new_uuid7,
|
|
parse_aurora_id,
|
|
)
|
|
|
|
|
|
def test_new_uuid7_is_unique_and_well_formed():
|
|
ids = {new_uuid7() for _ in range(1000)}
|
|
assert len(ids) == 1000
|
|
for value in list(ids)[:5]:
|
|
assert len(value) == 36 # canonical hyphenated form
|
|
|
|
|
|
def test_aurora_id_roundtrips_through_parse():
|
|
u = new_uuid7()
|
|
aid = aurora_id("movie", u)
|
|
assert aid.startswith("aur_movie_")
|
|
assert parse_aurora_id(aid, expected_type="movie") == u
|
|
|
|
|
|
def test_aurora_id_never_leaks_provider_identity():
|
|
# Aurora IDs must not be derived from or embed provider IDs (section 3).
|
|
u = new_uuid7()
|
|
aid = aurora_id("movie", u)
|
|
assert "550" not in aid # a plausible TMDb id, just shouldn't appear
|
|
assert "tmdb" not in aid
|
|
|
|
|
|
def test_every_entity_prefix_produces_a_parseable_id():
|
|
for entity_type in ENTITY_PREFIXES:
|
|
aid = aurora_id(entity_type, new_uuid7())
|
|
assert is_valid_aurora_id(aid, expected_type=entity_type)
|
|
|
|
|
|
def test_parse_rejects_wrong_entity_type():
|
|
aid = aurora_id("movie", new_uuid7())
|
|
with pytest.raises(ValueError):
|
|
parse_aurora_id(aid, expected_type="person")
|
|
assert is_valid_aurora_id(aid, expected_type="person") is False
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"malformed",
|
|
[
|
|
"",
|
|
"not-an-aurora-id",
|
|
"aur_movie_",
|
|
"aur_movie_tooshort",
|
|
"aur_unknownprefix_" + "0" * 26,
|
|
"aur_movie_" + "!" * 26,
|
|
],
|
|
)
|
|
def test_parse_rejects_malformed_ids(malformed: str):
|
|
with pytest.raises(ValueError):
|
|
parse_aurora_id(malformed)
|
|
assert is_valid_aurora_id(malformed) is False
|
|
|
|
|
|
def test_aurora_ids_sort_in_creation_order():
|
|
# UUIDv7 is time-ordered, and the Crockford base32 encoding preserves
|
|
# byte order, so IDs generated later should sort later.
|
|
first = aurora_id("movie", new_uuid7())
|
|
second = aurora_id("movie", new_uuid7())
|
|
assert first < second
|