Neuer Endpoint GET /items liefert alle Einzelstuecke ueber alle Produkte, angereichert mit Produkt-, Kategorie-, Lagerort- und Shop-Angaben (Beziehungen vorgeladen). ItemOut bekommt category_id/category_name. ProductOut bekommt image_version (Epoch der letzten Bildaenderung, None ohne Bild) - identisch zum ETag der Bild-Route, damit Clients Bilder cachen und nur bei Aenderung neu laden. Grundlage fuer die neue Einzelstueck-Liste (Web+iOS) und den iOS-Bild-Cache. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
"""Einzelstücke: Kaufpreis und Belege (Metadaten in der Ausgabe, Dateinamen-Härtung)."""
|
|
|
|
import pytest
|
|
|
|
from app.models import (
|
|
Category,
|
|
CategoryTracking,
|
|
Item,
|
|
ItemDocument,
|
|
Location,
|
|
Product,
|
|
Role,
|
|
User,
|
|
)
|
|
from app.routers.items import _safe_filename, create_items, get_item, list_all_items
|
|
from app.schemas import ItemCreate
|
|
|
|
|
|
@pytest.fixture()
|
|
def admin(db):
|
|
person = User(username="admin", password_hash="x", role=Role.admin)
|
|
db.add(person)
|
|
db.commit()
|
|
db.refresh(person)
|
|
return person
|
|
|
|
|
|
def _product(db):
|
|
cat = Category(name="Elektronik", tracking=CategoryTracking.object.value)
|
|
db.add(cat)
|
|
db.flush()
|
|
product = Product(name="Kamera", category_id=cat.id, individual=True)
|
|
db.add(product)
|
|
db.commit()
|
|
db.refresh(product)
|
|
return product
|
|
|
|
|
|
def test_item_kaufpreis_round_trip(db, admin):
|
|
product = _product(db)
|
|
out = create_items(
|
|
product.id, ItemCreate(count=1, price_cents=49900, currency="CHF"), db=db, _=admin
|
|
)
|
|
assert out[0].price_cents == 49900
|
|
assert out[0].currency == "CHF"
|
|
|
|
|
|
def test_item_out_listet_belege(db, admin):
|
|
product = _product(db)
|
|
item_id = create_items(product.id, ItemCreate(count=1), db=db, _=admin)[0].id
|
|
db.add(ItemDocument(item_id=item_id, filename="rechnung.pdf",
|
|
content_type="application/pdf", data=b"%PDF-1.4 x"))
|
|
db.commit()
|
|
|
|
fresh = get_item(item_id, db=db, _=admin)
|
|
assert len(fresh.documents) == 1
|
|
assert fresh.documents[0].filename == "rechnung.pdf"
|
|
assert fresh.documents[0].content_type == "application/pdf"
|
|
|
|
|
|
def test_list_all_items_angereichert(db, admin):
|
|
cat = Category(name="Elektronik", tracking=CategoryTracking.object.value)
|
|
db.add(cat)
|
|
db.flush()
|
|
product = Product(name="Kamera", brand="Sony", category_id=cat.id, individual=True)
|
|
db.add(product)
|
|
db.flush()
|
|
ort = Location(name="Keller")
|
|
db.add(ort)
|
|
db.commit()
|
|
create_items(product.id, ItemCreate(count=2, location_id=ort.id), db=db, _=admin)
|
|
|
|
alle = list_all_items(db=db, _=admin)
|
|
assert len(alle) == 2
|
|
e = alle[0]
|
|
assert e.product_name == "Kamera"
|
|
assert e.product_brand == "Sony"
|
|
assert e.category_name == "Elektronik"
|
|
assert e.location_id == ort.id
|
|
assert e.location_name == "Keller"
|
|
|
|
|
|
def test_safe_filename_entfernt_header_zeichen():
|
|
assert _safe_filename('a"b\r\nc.pdf') == "abc.pdf"
|
|
assert _safe_filename(" ") == "beleg"
|
|
assert _safe_filename(None) == "beleg"
|