Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added tests/__init__.py
Empty file.
27 changes: 27 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os
import pytest

os.environ["DATABASE_URL"] = "sqlite:///:memory:"

from app import create_app, db as _db


@pytest.fixture()
def app():
app = create_app()
app.config["TESTING"] = True
with app.app_context():
_db.create_all()
yield app
_db.session.remove()
_db.drop_all()


@pytest.fixture()
def client(app):
return app.test_client()


@pytest.fixture()
def db(app):
return _db
4 changes: 4 additions & 0 deletions tests/test_health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
def test_health(client):
resp = client.get("/health")
assert resp.status_code == 200
assert resp.get_json() == {"status": "healthy"}
85 changes: 85 additions & 0 deletions tests/test_inventory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
ITEM = {"sku": "SKU-001", "name": "Widget", "price": 9.99}


def _create(client, data=None):
return client.post("/api/inventory/", json=data or ITEM)


class TestCreateItem:
def test_success(self, client):
resp = _create(client)
assert resp.status_code == 201
body = resp.get_json()
assert body["sku"] == ITEM["sku"]
assert body["name"] == ITEM["name"]
assert body["quantity"] == 0

def test_with_optional_fields(self, client):
resp = _create(client, {**ITEM, "quantity": 5, "category": "tools"})
body = resp.get_json()
assert body["quantity"] == 5
assert body["category"] == "tools"

def test_missing_fields(self, client):
assert client.post("/api/inventory/", json={}).status_code == 400
assert client.post("/api/inventory/", json={"sku": "X", "name": "Y"}).status_code == 400

def test_duplicate_sku(self, client):
_create(client)
assert _create(client).status_code == 409


class TestListItems:
def test_empty(self, client):
assert client.get("/api/inventory/").get_json() == []

def test_returns_all(self, client):
_create(client, {"sku": "A", "name": "A", "price": 1})
_create(client, {"sku": "B", "name": "B", "price": 2})
assert len(client.get("/api/inventory/").get_json()) == 2

def test_filter_by_category(self, client):
_create(client, {"sku": "A", "name": "A", "price": 1, "category": "tools"})
_create(client, {"sku": "B", "name": "B", "price": 2, "category": "parts"})
_create(client, {"sku": "C", "name": "C", "price": 3, "category": "tools"})
result = client.get("/api/inventory/?category=tools").get_json()
assert len(result) == 2
assert all(i["category"] == "tools" for i in result)

def test_filter_no_match(self, client):
_create(client)
assert client.get("/api/inventory/?category=nope").get_json() == []


class TestGetItem:
def test_found(self, client):
iid = _create(client).get_json()["id"]
resp = client.get(f"/api/inventory/{iid}")
assert resp.status_code == 200
assert resp.get_json()["sku"] == ITEM["sku"]

def test_not_found(self, client):
assert client.get("/api/inventory/999").status_code == 404


class TestUpdateItem:
def test_update_fields(self, client):
iid = _create(client).get_json()["id"]
resp = client.put(f"/api/inventory/{iid}", json={"quantity": 10, "price": 19.99})
assert resp.status_code == 200
body = resp.get_json()
assert body["quantity"] == 10
assert body["price"] == "19.99"

def test_not_found(self, client):
assert client.put("/api/inventory/999", json={"quantity": 1}).status_code == 404


class TestDeleteItem:
def test_success(self, client):
iid = _create(client).get_json()["id"]
assert client.delete(f"/api/inventory/{iid}").status_code == 204
assert client.get(f"/api/inventory/{iid}").status_code == 404

def test_not_found(self, client):
assert client.delete("/api/inventory/999").status_code == 404
76 changes: 76 additions & 0 deletions tests/test_members.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import pytest


MEMBER = {"email": "[email protected]", "name": "Alice"}


def _create(client, data=None):
return client.post("/api/members/", json=data or MEMBER)


class TestCreateMember:
def test_success(self, client):
resp = _create(client)
assert resp.status_code == 201
body = resp.get_json()
assert body["email"] == MEMBER["email"]
assert body["name"] == MEMBER["name"]
assert body["tier"] == "basic"
assert body["active"] is True

def test_custom_tier(self, client):
resp = _create(client, {**MEMBER, "tier": "vip"})
assert resp.get_json()["tier"] == "vip"

def test_missing_fields(self, client):
assert client.post("/api/members/", json={}).status_code == 400
assert client.post("/api/members/", json={"email": "x"}).status_code == 400
assert client.post("/api/members/", json={"name": "x"}).status_code == 400

def test_duplicate_email(self, client):
_create(client)
assert _create(client).status_code == 409


class TestListMembers:
def test_empty(self, client):
assert client.get("/api/members/").get_json() == []

def test_returns_all(self, client):
_create(client, {"email": "[email protected]", "name": "A"})
_create(client, {"email": "[email protected]", "name": "B"})
assert len(client.get("/api/members/").get_json()) == 2


class TestGetMember:
def test_found(self, client):
mid = _create(client).get_json()["id"]
resp = client.get(f"/api/members/{mid}")
assert resp.status_code == 200
assert resp.get_json()["email"] == MEMBER["email"]

def test_not_found(self, client):
assert client.get("/api/members/999").status_code == 404


class TestUpdateMember:
def test_update_fields(self, client):
mid = _create(client).get_json()["id"]
resp = client.put(f"/api/members/{mid}", json={"name": "Bob", "tier": "premium"})
assert resp.status_code == 200
body = resp.get_json()
assert body["name"] == "Bob"
assert body["tier"] == "premium"

def test_not_found(self, client):
assert client.put("/api/members/999", json={"name": "X"}).status_code == 404


class TestDeleteMember:
def test_success(self, client):
mid = _create(client).get_json()["id"]
assert client.delete(f"/api/members/{mid}").status_code == 204
assert client.get(f"/api/members/{mid}").status_code == 404

def test_not_found(self, client):
assert client.delete("/api/members/999").status_code == 404
57 changes: 57 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from app.models.member import Member
from app.models.inventory import InventoryItem


class TestMemberModel:
def test_create_and_defaults(self, db, app):
m = Member(email="[email protected]", name="Alice")
db.session.add(m)
db.session.commit()
assert m.id is not None
assert m.tier == "basic"
assert m.active is True
assert m.created_at is not None

def test_to_dict(self, db, app):
m = Member(email="[email protected]", name="Alice", tier="vip")
db.session.add(m)
db.session.commit()
d = m.to_dict()
assert d["email"] == "[email protected]"
assert d["tier"] == "vip"
assert "created_at" in d

def test_unique_email(self, db, app):
import pytest
db.session.add(Member(email="[email protected]", name="A"))
db.session.commit()
db.session.add(Member(email="[email protected]", name="B"))
with pytest.raises(Exception):
db.session.commit()


class TestInventoryItemModel:
def test_create_and_defaults(self, db, app):
i = InventoryItem(sku="SKU-1", name="Widget", price=9.99)
db.session.add(i)
db.session.commit()
assert i.id is not None
assert i.quantity == 0
assert i.created_at is not None

def test_to_dict(self, db, app):
i = InventoryItem(sku="SKU-1", name="Widget", price=9.99, category="tools")
db.session.add(i)
db.session.commit()
d = i.to_dict()
assert d["sku"] == "SKU-1"
assert d["price"] == "9.99"
assert d["category"] == "tools"

def test_unique_sku(self, db, app):
import pytest
db.session.add(InventoryItem(sku="DUP", name="A", price=1))
db.session.commit()
db.session.add(InventoryItem(sku="DUP", name="B", price=2))
with pytest.raises(Exception):
db.session.commit()