166 lines
5.1 KiB
Python
166 lines
5.1 KiB
Python
import pytest
|
|
from fastapi import status
|
|
|
|
|
|
class TestItemCRUD:
|
|
"""Test item creation, read, update, delete."""
|
|
|
|
def test_create_item(self, test_client, test_db):
|
|
"""Test creating an inventory item."""
|
|
response = test_client.post(
|
|
"/api/items",
|
|
json={
|
|
"name": "Test Item",
|
|
"category": "Electronics",
|
|
"type": "Component",
|
|
"quantity": 10,
|
|
"barcode": "123456789",
|
|
"part_number": "PN-12345"
|
|
}
|
|
)
|
|
assert response.status_code == status.HTTP_201_CREATED
|
|
data = response.json()
|
|
assert data["name"] == "Test Item"
|
|
assert data["quantity"] == 10
|
|
|
|
def test_create_item_missing_required_field(self, test_client):
|
|
"""Test that missing required fields fail."""
|
|
response = test_client.post(
|
|
"/api/items",
|
|
json={"name": "Test Item"}
|
|
)
|
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
|
|
|
def test_get_item_by_id(self, test_client, test_db):
|
|
"""Test retrieving an item by ID."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
item_type="Component",
|
|
quantity=10,
|
|
barcode="123456789",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
|
|
response = test_client.get(f"/api/items/{item.id}")
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["name"] == "Test Item"
|
|
assert data["barcode"] == "123456789"
|
|
|
|
def test_list_items(self, test_client, test_db):
|
|
"""Test listing all items."""
|
|
from backend.models import Item
|
|
|
|
item1 = Item(name="Item1", category="A", item_type="Type", quantity=5, barcode="111", part_number="PN1")
|
|
item2 = Item(name="Item2", category="B", item_type="Type", quantity=3, barcode="222", part_number="PN2")
|
|
test_db.add_all([item1, item2])
|
|
test_db.commit()
|
|
|
|
response = test_client.get("/api/items")
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert len(data) >= 2
|
|
|
|
def test_update_item(self, test_client, test_db):
|
|
"""Test updating an item."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
item_type="Component",
|
|
quantity=10,
|
|
barcode="123456789",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
|
|
response = test_client.put(
|
|
f"/api/items/{item.id}",
|
|
json={"quantity": 20, "part_number": "PN-99999"}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["quantity"] == 20
|
|
assert data["part_number"] == "PN-99999"
|
|
|
|
def test_delete_item_admin_only(self, test_client, test_db, admin_token):
|
|
"""Test deleting an item (admin only)."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
item_type="Component",
|
|
quantity=10,
|
|
barcode="123456789",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
item_id = item.id
|
|
|
|
response = test_client.delete(
|
|
f"/api/items/{item_id}",
|
|
headers={"Authorization": f"Bearer {admin_token}"}
|
|
)
|
|
assert response.status_code == status.HTTP_204_NO_CONTENT
|
|
|
|
# Verify audit log persists
|
|
response = test_client.get(f"/api/audit-logs?item_id={item_id}")
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
|
|
class TestItemValidation:
|
|
"""Test item field validation."""
|
|
|
|
def test_barcode_unique(self, test_client, test_db):
|
|
"""Test that barcodes must be unique."""
|
|
from backend.models import Item
|
|
|
|
item1 = Item(
|
|
name="Item1",
|
|
category="A",
|
|
item_type="Type",
|
|
quantity=5,
|
|
barcode="UNIQUE123",
|
|
part_number="PN1"
|
|
)
|
|
test_db.add(item1)
|
|
test_db.commit()
|
|
|
|
# Try to create duplicate barcode
|
|
response = test_client.post(
|
|
"/api/items",
|
|
json={
|
|
"name": "Item2",
|
|
"category": "B",
|
|
"type": "Type",
|
|
"quantity": 5,
|
|
"barcode": "UNIQUE123",
|
|
"part_number": "PN2"
|
|
}
|
|
)
|
|
assert response.status_code == status.HTTP_409_CONFLICT
|
|
|
|
def test_quantity_non_negative(self, test_client):
|
|
"""Test that quantity must be non-negative."""
|
|
response = test_client.post(
|
|
"/api/items",
|
|
json={
|
|
"name": "Test",
|
|
"category": "A",
|
|
"type": "Type",
|
|
"quantity": -5,
|
|
"barcode": "123",
|
|
"part_number": "PN"
|
|
}
|
|
)
|
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|