187 lines
6.0 KiB
Python
187 lines
6.0 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, user_token):
|
|
"""Test creating an inventory item."""
|
|
response = test_client.post(
|
|
"/items",
|
|
json={
|
|
"name": "Test Item",
|
|
"category": "Electronics",
|
|
"type": "Component",
|
|
"quantity": 10,
|
|
"barcode": "123456789",
|
|
"part_number": "PN-12345"
|
|
},
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
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, user_token):
|
|
"""Test that missing required fields fail."""
|
|
response = test_client.post(
|
|
"/items",
|
|
json={"name": "Test Item"},
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
|
|
|
def test_get_item_by_id(self, test_client, test_db, user_token):
|
|
"""Test retrieving an item by ID."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
type="Component",
|
|
quantity=10,
|
|
barcode="123456789",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
|
|
response = test_client.get(
|
|
f"/items/{item.id}",
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
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, user_token):
|
|
"""Test listing all items."""
|
|
from backend.models import Item
|
|
|
|
item1 = Item(name="Item1", category="A", type="Type", quantity=5, barcode="111", part_number="PN1")
|
|
item2 = Item(name="Item2", category="B", type="Type", quantity=3, barcode="222", part_number="PN2")
|
|
test_db.add_all([item1, item2])
|
|
test_db.commit()
|
|
|
|
response = test_client.get(
|
|
"/items",
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert len(data) >= 2
|
|
|
|
def test_update_item(self, test_client, test_db, user_token):
|
|
"""Test updating an item."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
type="Component",
|
|
quantity=10,
|
|
barcode="UPD-123",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
|
|
response = test_client.put(
|
|
f"/items/{item.id}",
|
|
json={
|
|
"name": "Test Item",
|
|
"category": "Electronics",
|
|
"barcode": "UPD-123",
|
|
"quantity": 20,
|
|
"part_number": "PN-99999"
|
|
},
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
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, user_token):
|
|
"""Test deleting an item (admin only)."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
type="Component",
|
|
quantity=10,
|
|
barcode="DEL-123",
|
|
part_number="PN-DEL"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
item_id = item.id
|
|
|
|
response = test_client.delete(
|
|
f"/items/{item_id}",
|
|
headers={"Authorization": f"Bearer {admin_token}"}
|
|
)
|
|
assert response.status_code in (status.HTTP_200_OK, status.HTTP_204_NO_CONTENT)
|
|
|
|
# Verify item is gone
|
|
response = test_client.get(
|
|
f"/items/{item_id}",
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
assert response.status_code == status.HTTP_404_NOT_FOUND
|
|
|
|
|
|
class TestItemValidation:
|
|
"""Test item field validation."""
|
|
|
|
def test_barcode_unique(self, test_client, test_db, user_token):
|
|
"""Test that barcodes must be unique."""
|
|
from backend.models import Item
|
|
|
|
item1 = Item(
|
|
name="Item1",
|
|
category="A",
|
|
type="Type",
|
|
quantity=5,
|
|
barcode="UNIQUE123",
|
|
part_number="PN1"
|
|
)
|
|
test_db.add(item1)
|
|
test_db.commit()
|
|
|
|
# Try to create duplicate barcode via API
|
|
response = test_client.post(
|
|
"/items",
|
|
json={
|
|
"name": "Item2",
|
|
"category": "B",
|
|
"type": "Type",
|
|
"quantity": 5,
|
|
"barcode": "UNIQUE123",
|
|
"part_number": "PN2"
|
|
},
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
assert response.status_code in (status.HTTP_409_CONFLICT, status.HTTP_400_BAD_REQUEST)
|
|
|
|
def test_quantity_stored_correctly(self, test_client, user_token):
|
|
"""Test that quantity is stored as provided (API accepts any float)."""
|
|
response = test_client.post(
|
|
"/items",
|
|
json={
|
|
"name": "QtyTest",
|
|
"category": "A",
|
|
"type": "Type",
|
|
"quantity": 42.5,
|
|
"barcode": "QTY-TEST-123",
|
|
"part_number": "PN-QTY"
|
|
},
|
|
headers={"Authorization": f"Bearer {user_token}"}
|
|
)
|
|
assert response.status_code == status.HTTP_201_CREATED
|
|
assert response.json()["quantity"] == 42.5
|