import pytest from fastapi import status class TestStockOperations: """Test check-in and check-out operations.""" def test_check_in_item(self, test_client, test_db, user_token): """Test checking in inventory (increasing quantity).""" from backend.models import Item, User item = Item(name="Test Item", category="Electronics", type="Component", quantity=10, barcode="BC-CHECKIN", part_number="PN-CI") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() response = test_client.post( "/operations/check-in", json={"barcode": "BC-CHECKIN", "quantity": 5, "user_id": user.id}, headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["quantity"] == 15 def test_check_out_item(self, test_client, test_db, user_token): """Test checking out inventory (decreasing quantity).""" from backend.models import Item, User item = Item(name="Test Item", category="Electronics", type="Component", quantity=10, barcode="BC-CHECKOUT", part_number="PN-CO") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() response = test_client.post( "/operations/check-out", json={"barcode": "BC-CHECKOUT", "quantity": 3, "user_id": user.id}, headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_200_OK data = response.json() assert data["quantity"] == 7 def test_check_out_insufficient_quantity(self, test_client, test_db, user_token): """Test that check-out fails if quantity insufficient.""" from backend.models import Item, User item = Item(name="Test Item", category="Electronics", type="Component", quantity=5, barcode="BC-INSUFF", part_number="PN-INS") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() response = test_client.post( "/operations/check-out", json={"barcode": "BC-INSUFF", "quantity": 10, "user_id": user.id}, headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_400_BAD_REQUEST def test_audit_log_created(self, test_client, test_db, user_token): """Test that audit log entry created for each operation.""" from backend.models import Item, User item = Item(name="Test Item", category="Electronics", type="Component", quantity=10, barcode="BC-AUDIT", part_number="PN-AUD") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() response = test_client.post( "/operations/check-in", json={"barcode": "BC-AUDIT", "quantity": 5, "user_id": user.id}, headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_200_OK # Verify audit log via logs endpoint response = test_client.get( "/operations/logs", headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_200_OK logs = response.json() assert len(logs) > 0 assert any(log["action"] == "CHECK_IN" for log in logs) class TestBulkSync: """Test offline sync with UUID idempotency.""" def test_bulk_sync_offline_operations(self, test_client, test_db, user_token): """Test syncing multiple offline-generated operations.""" from backend.models import Item, User from datetime import datetime item = Item(name="Test Item", category="Electronics", type="Component", quantity=10, barcode="BC-SYNC1", part_number="PN-SYN") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() response = test_client.post( "/operations/bulk-sync", json={ "user_id": user.id, "operations": [ {"type": "CHECK_IN", "barcode": "BC-SYNC1", "quantity": 5, "uuid": "uuid-sync-1", "timestamp": datetime.utcnow().isoformat()}, {"type": "CHECK_IN", "barcode": "BC-SYNC1", "quantity": 3, "uuid": "uuid-sync-2", "timestamp": datetime.utcnow().isoformat()}, ] }, headers={"Authorization": f"Bearer {user_token}"} ) assert response.status_code == status.HTTP_200_OK data = response.json() assert "success" in data assert len(data["success"]) == 2 def test_bulk_sync_idempotent(self, test_client, test_db, user_token): """Test that syncing same UUID twice doesn't duplicate.""" from backend.models import Item, User from datetime import datetime item = Item(name="Test Item", category="Electronics", type="Component", quantity=10, barcode="BC-IDEMP", part_number="PN-IDP") test_db.add(item) test_db.commit() user = test_db.query(User).filter(User.username == "user").first() operation = { "user_id": user.id, "operations": [ {"type": "CHECK_IN", "barcode": "BC-IDEMP", "quantity": 5, "uuid": "uuid-idempotent-1", "timestamp": datetime.utcnow().isoformat()} ] } # Sync once response1 = test_client.post( "/operations/bulk-sync", json=operation, headers={"Authorization": f"Bearer {user_token}"} ) assert response1.status_code == status.HTTP_200_OK assert len(response1.json()["success"]) == 1 # Sync again with same UUID — should be idempotent (returns "Already synced") response2 = test_client.post( "/operations/bulk-sync", json=operation, headers={"Authorization": f"Bearer {user_token}"} ) assert response2.status_code == status.HTTP_200_OK # "Already synced" note in success means idempotent assert response2.json()["success"][0].get("note") == "Already synced"