190 lines
5.6 KiB
Python
190 lines
5.6 KiB
Python
import pytest
|
|
from fastapi import status
|
|
from datetime import datetime
|
|
|
|
|
|
class TestStockOperations:
|
|
"""Test check-in and check-out operations."""
|
|
|
|
def test_check_in_item(self, test_client, test_db):
|
|
"""Test checking in inventory (increasing quantity)."""
|
|
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.post(
|
|
"/api/operations/check-in",
|
|
json={"item_id": item.id, "quantity": 5}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["new_quantity"] == 15
|
|
|
|
def test_check_out_item(self, test_client, test_db):
|
|
"""Test checking out inventory (decreasing quantity)."""
|
|
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.post(
|
|
"/api/operations/check-out",
|
|
json={"item_id": item.id, "quantity": 3}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["new_quantity"] == 7
|
|
|
|
def test_check_out_insufficient_quantity(self, test_client, test_db):
|
|
"""Test that check-out fails if quantity insufficient."""
|
|
from backend.models import Item
|
|
|
|
item = Item(
|
|
name="Test Item",
|
|
category="Electronics",
|
|
item_type="Component",
|
|
quantity=5,
|
|
barcode="123456789",
|
|
part_number="PN-12345"
|
|
)
|
|
test_db.add(item)
|
|
test_db.commit()
|
|
|
|
response = test_client.post(
|
|
"/api/operations/check-out",
|
|
json={"item_id": item.id, "quantity": 10}
|
|
)
|
|
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
|
|
|
def test_audit_log_created(self, test_client, test_db):
|
|
"""Test that audit log entry created for each operation."""
|
|
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()
|
|
|
|
# Perform operation
|
|
response = test_client.post(
|
|
"/api/operations/check-in",
|
|
json={"item_id": item.id, "quantity": 5}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
# Verify audit log
|
|
response = test_client.get(f"/api/audit-logs?item_id={item.id}")
|
|
assert response.status_code == status.HTTP_200_OK
|
|
logs = response.json()
|
|
assert len(logs) > 0
|
|
assert logs[-1]["operation"] == "CHECK_IN"
|
|
assert logs[-1]["quantity_change"] == 5
|
|
|
|
|
|
class TestBulkSync:
|
|
"""Test offline sync with UUID idempotency."""
|
|
|
|
def test_bulk_sync_offline_operations(self, test_client, test_db):
|
|
"""Test syncing multiple offline-generated operations."""
|
|
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()
|
|
|
|
# Simulate offline operations with UUIDs
|
|
response = test_client.post(
|
|
"/api/bulk-sync",
|
|
json={
|
|
"operations": [
|
|
{
|
|
"id": "uuid-1",
|
|
"type": "CHECK_IN",
|
|
"item_id": item.id,
|
|
"quantity": 5
|
|
},
|
|
{
|
|
"id": "uuid-2",
|
|
"type": "CHECK_IN",
|
|
"item_id": item.id,
|
|
"quantity": 3
|
|
}
|
|
]
|
|
}
|
|
)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
data = response.json()
|
|
assert data["synced"] == 2
|
|
assert data["final_quantity"] == 18
|
|
|
|
def test_bulk_sync_idempotent(self, test_client, test_db):
|
|
"""Test that syncing same UUID twice doesn't duplicate."""
|
|
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()
|
|
|
|
operation = {
|
|
"id": "uuid-1",
|
|
"type": "CHECK_IN",
|
|
"item_id": item.id,
|
|
"quantity": 5
|
|
}
|
|
|
|
# Sync once
|
|
response1 = test_client.post(
|
|
"/api/bulk-sync",
|
|
json={"operations": [operation]}
|
|
)
|
|
assert response1.status_code == status.HTTP_200_OK
|
|
q1 = response1.json()["final_quantity"]
|
|
|
|
# Sync again (same UUID)
|
|
response2 = test_client.post(
|
|
"/api/bulk-sync",
|
|
json={"operations": [operation]}
|
|
)
|
|
assert response2.status_code == status.HTTP_200_OK
|
|
q2 = response2.json()["final_quantity"]
|
|
|
|
# Quantity should not increase twice
|
|
assert q1 == q2 == 15
|