"""Artikel löschen – und wann der Server sich weigert. Ohne Sperre reisst ein Klick Chargen, Einzelstücke, Barcodes, Bilder und den gesamten Bewegungsverlauf per Kaskade mit. Geprüft wird deshalb der heutige Bestand. Bewegungen allein halten bewusst NICHT auf, sonst waere jeder je benutzte Artikel fuer immer unloeschbar. Geprüft wird nur die Sperre selbst – die Kaskade nicht: Die Tests laufen auf SQLite ohne ``PRAGMA foreign_keys=ON``, eine Kaskaden-Zusicherung waere dort ohne Aussagekraft. """ import pytest from fastapi import HTTPException from app.models import BaseUnit, Item, Lot, Product, Role, User from app.routers.products import delete_product @pytest.fixture() def admin(db): person = User(username="chef", password_hash="x", role=Role.admin) db.add(person) db.commit() db.refresh(person) return person def _artikel(db, name="Hammer"): product = Product(name=name, base_unit=BaseUnit.piece, package_size=1, source="manual") db.add(product) db.commit() db.refresh(product) return product def test_loeschen_ohne_bestand_geht_durch(db, admin): product = _artikel(db) delete_product(product_id=product.id, db=db, _=admin) assert db.get(Product, product.id) is None def test_loeschen_mit_einzelstuecken_wird_abgelehnt(db, admin): product = _artikel(db) db.add(Item(uid="ABC12345", product_id=product.id)) db.commit() with pytest.raises(HTTPException) as fehler: delete_product(product_id=product.id, db=db, _=admin) assert fehler.value.status_code == 409 assert "Einzelstücke" in fehler.value.detail assert db.get(Product, product.id) is not None def test_loeschen_mit_chargen_wird_abgelehnt(db, admin): product = _artikel(db) db.add(Lot(product_id=product.id, quantity=5)) db.commit() with pytest.raises(HTTPException) as fehler: delete_product(product_id=product.id, db=db, _=admin) assert fehler.value.status_code == 409 assert "Bestand" in fehler.value.detail assert db.get(Product, product.id) is not None def test_loeschen_nach_leergeraeumter_charge_geht_durch(db, admin): """Wer alles auslagert, muss den Artikel loswerden können. Haelt fest, dass die Sperre am heutigen Bestand haengt und nicht zu einer Verlaufspruefung ausgebaut wird – sonst waere ein einmal benutzter Artikel nie wieder loeschbar. """ product = _artikel(db) lot = Lot(product_id=product.id, quantity=5) db.add(lot) db.commit() db.delete(lot) # wie beim vollstaendigen Auslagern db.commit() delete_product(product_id=product.id, db=db, _=admin) assert db.get(Product, product.id) is None def test_unbekannter_artikel_bleibt_ein_404(db, admin): with pytest.raises(HTTPException) as fehler: delete_product(product_id=9999, db=db, _=admin) assert fehler.value.status_code == 404