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