151 lines
4.8 KiB
Python
151 lines
4.8 KiB
Python
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__])
|