245 lines
7.7 KiB
Python
245 lines
7.7 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
|
|
from datetime import datetime
|
|
|
|
client = TestClient(app)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def clear_db():
|
|
db = get_db()
|
|
db.orders.delete_many({})
|
|
db.items.delete_many({})
|
|
db.users.delete_many({})
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def run_around_tests():
|
|
clear_db()
|
|
yield
|
|
clear_db()
|
|
|
|
|
|
def create_test_user():
|
|
user_data = {
|
|
"username": "testuser",
|
|
"email": "testuser@example.com",
|
|
"password": "testpassword",
|
|
"full_name": "Test User",
|
|
"is_active": True,
|
|
"is_superuser": False
|
|
}
|
|
response = client.post("/users/register", json=user_data)
|
|
assert response.status_code == 200, f"Failed to create user: {response.text}"
|
|
return response.json()
|
|
|
|
|
|
def login_test_user():
|
|
login_data = {
|
|
"username": "testuser",
|
|
"password": "testpassword"
|
|
}
|
|
response = client.post("/token", data=login_data)
|
|
assert response.status_code == 200
|
|
return response.json()["access_token"]
|
|
|
|
|
|
def create_test_item(token):
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
response = client.post(
|
|
"/items/",
|
|
headers=headers,
|
|
json={"name": "Test Item", "price": 10.99,
|
|
"quantity": 100, "unit": "piece"}
|
|
)
|
|
assert response.status_code == 200
|
|
return response.json()["_id"]
|
|
|
|
|
|
@pytest.fixture
|
|
def auth_headers():
|
|
create_test_user()
|
|
token = login_test_user()
|
|
return {"Authorization": f"Bearer {token}"}
|
|
|
|
|
|
def test_create_order(auth_headers):
|
|
logger.info("Testing create order")
|
|
item_id = create_test_item(auth_headers["Authorization"].split()[1])
|
|
order_data = {
|
|
"items": [{"item_id": item_id, "quantity": 2}],
|
|
"total_amount": 21.98,
|
|
"payment_method": "credit_card"
|
|
}
|
|
response = client.post("/orders/", json=order_data, headers=auth_headers)
|
|
assert response.status_code == 200
|
|
assert "_id" in response.json()
|
|
logger.info(f"Created order with ID: {response.json()['_id']}")
|
|
|
|
|
|
def test_read_orders(auth_headers):
|
|
logger.info("Testing read orders")
|
|
item_id = create_test_item(auth_headers["Authorization"].split()[1])
|
|
order_data = {
|
|
"items": [{"item_id": item_id, "quantity": 2}],
|
|
"total_amount": 21.98,
|
|
"payment_method": "credit_card"
|
|
}
|
|
client.post("/orders/", json=order_data, headers=auth_headers)
|
|
response = client.get("/orders/", headers=auth_headers)
|
|
assert response.status_code == 200
|
|
orders = response.json()
|
|
assert len(orders) == 1
|
|
assert orders[0]["total_amount"] == 21.98
|
|
logger.info(f"Retrieved {len(orders)} orders")
|
|
|
|
|
|
def test_read_order(auth_headers):
|
|
logger.info("Testing read single order")
|
|
item_id = create_test_item(auth_headers["Authorization"].split()[1])
|
|
order_data = {
|
|
"items": [{"item_id": item_id, "quantity": 2}],
|
|
"total_amount": 21.98,
|
|
"payment_method": "credit_card"
|
|
}
|
|
create_response = client.post(
|
|
"/orders/", json=order_data, headers=auth_headers)
|
|
order_id = create_response.json()["_id"]
|
|
response = client.get(f"/orders/{order_id}", headers=auth_headers)
|
|
assert response.status_code == 200
|
|
assert response.json()["total_amount"] == 21.98
|
|
logger.info(f"Retrieved order with ID: {order_id}")
|
|
|
|
|
|
def test_update_order(auth_headers):
|
|
logger.info("Testing update order")
|
|
item_id = create_test_item(auth_headers["Authorization"].split()[1])
|
|
order_data = {
|
|
"items": [{"item_id": item_id, "quantity": 2}],
|
|
"total_amount": 21.98,
|
|
"payment_method": "credit_card"
|
|
}
|
|
create_response = client.post(
|
|
"/orders/", json=order_data, headers=auth_headers)
|
|
order_id = create_response.json()["_id"]
|
|
update_data = {
|
|
"items": [{"item_id": item_id, "quantity": 3}],
|
|
"total_amount": 32.97,
|
|
"payment_method": "cash"
|
|
}
|
|
response = client.put(f"/orders/{order_id}",
|
|
json=update_data, headers=auth_headers)
|
|
assert response.status_code == 200
|
|
assert response.json()["total_amount"] == 32.97
|
|
assert response.json()["payment_method"] == "cash"
|
|
logger.info(f"Updated order with ID: {order_id}")
|
|
|
|
|
|
def test_delete_order(auth_headers):
|
|
logger.info("Testing delete order")
|
|
item_id = create_test_item(auth_headers["Authorization"].split()[1])
|
|
order_data = {
|
|
"items": [{"item_id": item_id, "quantity": 2}],
|
|
"total_amount": 21.98,
|
|
"payment_method": "credit_card"
|
|
}
|
|
create_response = client.post(
|
|
"/orders/", json=order_data, headers=auth_headers)
|
|
order_id = create_response.json()["_id"]
|
|
response = client.delete(f"/orders/{order_id}", headers=auth_headers)
|
|
assert response.status_code == 200
|
|
assert response.json()["message"] == "Order deleted successfully"
|
|
get_response = client.get(f"/orders/{order_id}", headers=auth_headers)
|
|
assert get_response.status_code == 404
|
|
logger.info(f"Deleted order with ID: {order_id}")
|
|
|
|
|
|
# @given(
|
|
# st.lists(
|
|
# st.fixed_dictionaries({
|
|
# "quantity": st.integers(min_value=1, max_value=10)
|
|
# }),
|
|
# min_size=1,
|
|
# max_size=5
|
|
# ),
|
|
# st.floats(min_value=0.01, max_value=1000,
|
|
# allow_nan=False, allow_infinity=False),
|
|
# st.sampled_from(["credit_card", "cash", "paypal"])
|
|
# )
|
|
# @settings(max_examples=50)
|
|
# def test_create_order_property(auth_headers, items, total_amount, payment_method):
|
|
# clear_db()
|
|
# create_test_user()
|
|
# token = login_test_user()
|
|
# auth_headers = {"Authorization": f"Bearer {token}"}
|
|
# item_id = create_test_item(token)
|
|
# for item in items:
|
|
# item["item_id"] = item_id # Use the same item_id for all items
|
|
# order_data = {
|
|
# "items": items,
|
|
# "total_amount": total_amount,
|
|
# "payment_method": payment_method
|
|
# }
|
|
# response = client.post("/orders/", json=order_data, headers=auth_headers)
|
|
# assert response.status_code == 200
|
|
# assert "_id" in response.json()
|
|
# order_id = response.json()["_id"]
|
|
# get_response = client.get(f"/orders/{order_id}", headers=auth_headers)
|
|
# assert get_response.status_code == 200
|
|
# retrieved_order = get_response.json()
|
|
# assert retrieved_order["total_amount"] == total_amount
|
|
# assert retrieved_order["payment_method"] == payment_method
|
|
# assert len(retrieved_order["items"]) == len(items)
|
|
|
|
|
|
# @given(
|
|
# st.lists(
|
|
# st.fixed_dictionaries({
|
|
# "total_amount": st.floats(min_value=0.01, max_value=1000, allow_nan=False, allow_infinity=False),
|
|
# "payment_method": st.sampled_from(["credit_card", "cash", "paypal"])
|
|
# }),
|
|
# min_size=1,
|
|
# max_size=10
|
|
# )
|
|
# )
|
|
# @settings(max_examples=20)
|
|
# def test_read_orders_property(auth_headers, orders):
|
|
# clear_db()
|
|
# create_test_user()
|
|
# token = login_test_user()
|
|
# auth_headers = {"Authorization": f"Bearer {token}"}
|
|
# item_id = create_test_item(token)
|
|
# for order in orders:
|
|
# order_data = {
|
|
# "items": [{"item_id": item_id, "quantity": 1}],
|
|
# "total_amount": order["total_amount"],
|
|
# "payment_method": order["payment_method"]
|
|
# }
|
|
# client.post("/orders/", json=order_data, headers=auth_headers)
|
|
# response = client.get("/orders/", headers=auth_headers)
|
|
# assert response.status_code == 200
|
|
# retrieved_orders = response.json()
|
|
# assert len(retrieved_orders) == len(orders)
|
|
# for retrieved_order in retrieved_orders:
|
|
# assert "total_amount" in retrieved_order
|
|
# assert "payment_method" in retrieved_order
|
|
|
|
|
|
@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__])
|