Skip to content

Commit f99137e

Browse files
committed
feat(printers): add slug lookup + unified slug/uuid resolver
resolve_by_slug_or_uuid akzeptiert beides für menschen-lesbare API-Pfade. Refs strausmann/hangar#78
1 parent e8de35b commit f99137e

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

backend/app/repositories/printers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,23 @@ async def create(session: AsyncSession, printer: Printer) -> Printer:
3434
await session.commit()
3535
await session.refresh(printer)
3636
return printer
37+
38+
39+
async def get_by_slug(session: AsyncSession, slug: str) -> Printer | None:
40+
"""Lookup nach slug. None wenn nicht vorhanden."""
41+
result = await session.execute(
42+
select(Printer).where(col(Printer.slug) == slug)
43+
)
44+
return result.scalar_one_or_none()
45+
46+
47+
async def resolve_by_slug_or_uuid(session: AsyncSession, key: str) -> Printer | None:
48+
"""Akzeptiert Slug-String ODER UUID-String. UUID hat Vorrang (Performance)."""
49+
try:
50+
uuid_obj = UUID(key)
51+
printer = await get(session, uuid_obj)
52+
if printer is not None:
53+
return printer
54+
except ValueError:
55+
pass
56+
return await get_by_slug(session, key)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
"""Repository-Tests für slug-Lookup und Slug-oder-UUID-Resolution."""
2+
from __future__ import annotations
3+
4+
from uuid import uuid4
5+
6+
import pytest
7+
from sqlalchemy.ext.asyncio import AsyncSession
8+
9+
from app.models.printer import Printer
10+
from app.repositories import printers as printers_repo
11+
12+
13+
@pytest.mark.asyncio
14+
async def test_get_by_slug_returns_printer(db_session: AsyncSession):
15+
p = Printer(name="Brother PT-P750W", slug="brother-p750w",
16+
model="PT-P750W", backend="ptouch")
17+
await printers_repo.create(db_session, p)
18+
19+
found = await printers_repo.get_by_slug(db_session, "brother-p750w")
20+
assert found is not None
21+
assert found.id == p.id
22+
23+
24+
@pytest.mark.asyncio
25+
async def test_get_by_slug_returns_none_when_missing(db_session: AsyncSession):
26+
found = await printers_repo.get_by_slug(db_session, "does-not-exist")
27+
assert found is None
28+
29+
30+
@pytest.mark.asyncio
31+
async def test_resolve_by_slug_or_uuid_with_uuid(db_session: AsyncSession):
32+
p = Printer(name="X", slug="x", model="X", backend="mock")
33+
await printers_repo.create(db_session, p)
34+
35+
found = await printers_repo.resolve_by_slug_or_uuid(db_session, str(p.id))
36+
assert found is not None
37+
assert found.id == p.id
38+
39+
40+
@pytest.mark.asyncio
41+
async def test_resolve_by_slug_or_uuid_with_slug(db_session: AsyncSession):
42+
p = Printer(name="Y", slug="my-printer", model="Y", backend="mock")
43+
await printers_repo.create(db_session, p)
44+
45+
found = await printers_repo.resolve_by_slug_or_uuid(db_session, "my-printer")
46+
assert found is not None
47+
assert found.id == p.id
48+
49+
50+
@pytest.mark.asyncio
51+
async def test_resolve_by_slug_or_uuid_with_garbage(db_session: AsyncSession):
52+
found = await printers_repo.resolve_by_slug_or_uuid(db_session, "nonexistent")
53+
assert found is None

0 commit comments

Comments
 (0)