import pytest import logging from fastapi.testclient import TestClient from hypothesis import given, strategies as st, settings from bson import ObjectId from pos_system.server import app from pos_system.database import get_db client = TestClient(app) logger = logging.getLogger(__name__) @pytest.fixture(autouse=True) def clear_db(): db = get_db() db.items.delete_many({}) yield db.items.delete_many({}) def test_create_item(): logger.info("Testing create item") response = client.post( "/items/", json={"name": "Test Item", "price": 10.99, "quantity": 5, "unit": "piece"} ) assert response.status_code == 200 assert "_id" in response.json() logger.info(f"Created item with ID: {response.json()['_id']}") def test_read_items(): logger.info("Testing read items") client.post("/items/", json={"name": "Test Item", "price": 10.99, "quantity": 5, "unit": "piece"}) response = client.get("/items/") assert response.status_code == 200 items = response.json() assert len(items) == 1 assert items[0]["name"] == "Test Item" logger.info(f"Retrieved {len(items)} items") def test_read_item(): logger.info("Testing read single item") create_response = client.post( "/items/", json={"name": "Test Item", "price": 10.99, "quantity": 5, "unit": "piece"}) item_id = create_response.json()["_id"] response = client.get(f"/items/{item_id}") assert response.status_code == 200 assert response.json()["name"] == "Test Item" logger.info(f"Retrieved item with ID: {item_id}") def test_update_item(): logger.info("Testing update item") create_response = client.post( "/items/", json={"name": "Test Item", "price": 10.99, "quantity": 5, "unit": "piece"}) item_id = create_response.json()["_id"] update_data = {"name": "Updated Item", "price": 15.99, "quantity": 10, "unit": "piece"} response = client.put(f"/items/{item_id}", json=update_data) assert response.status_code == 200 assert response.json()["name"] == "Updated Item" logger.info(f"Updated item with ID: {item_id}") def test_delete_item(): logger.info("Testing delete item") create_response = client.post( "/items/", json={"name": "Test Item", "price": 10.99, "quantity": 5, "unit": "piece"}) item_id = create_response.json()["_id"] response = client.delete(f"/items/{item_id}") assert response.status_code == 200 assert response.json()["message"] == "Item deleted successfully" get_response = client.get(f"/items/{item_id}") assert get_response.status_code == 404 logger.info(f"Deleted item with ID: {item_id}") @given( name=st.text(min_size=1, max_size=20), price=st.floats(min_value=0.01, max_value=100, allow_nan=False, allow_infinity=False), quantity=st.integers(min_value=0, max_value=100), unit=st.text(min_size=1, max_size=10) ) @settings(max_examples=50) # Limit the number of examples to 50 def test_create_item_property(name, price, quantity, unit): response = client.post( "/items/", json={"name": name, "price": price, "quantity": quantity, "unit": unit} ) assert response.status_code == 200 assert "_id" in response.json() item_id = response.json()["_id"] get_response = client.get(f"/items/{item_id}") assert get_response.status_code == 200 item = get_response.json() assert item["name"] == name assert pytest.approx(item["price"], 0.01) == price assert item["quantity"] == quantity assert item["unit"] == unit @given( st.lists( st.fixed_dictionaries({ "name": st.text(min_size=1, max_size=20), "price": st.floats(min_value=0.01, max_value=100, allow_nan=False, allow_infinity=False), "quantity": st.integers(min_value=0, max_value=100), "unit": st.text(min_size=1, max_size=10) }), min_size=1, max_size=10 ) ) @settings(max_examples=20) # Limit the number of examples to 20 def test_read_items_property(items): for item in items: client.post("/items/", json=item) response = client.get("/items/") assert response.status_code == 200 retrieved_items = response.json() assert len(retrieved_items) == len(items) for retrieved_item in retrieved_items: assert "name" in retrieved_item assert "price" in retrieved_item assert "quantity" in retrieved_item assert "unit" in retrieved_item # Add this function to log only failed property tests @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): outcome = yield report = outcome.get_result() if report.when == "call" and report.failed: if "hypothesis" in item.keywords: logger.error(f"Property test failed: {item.name}") logger.error(f"Falsifying example: {call.excinfo.value}") if __name__ == "__main__": pytest.main([__file__]) def test(): pytest.main([__file__])