291 lines
12 KiB
Python
291 lines
12 KiB
Python
import uuid
|
|
|
|
import pytest
|
|
|
|
from app.api.routes.events.gifts import router as gifts_router
|
|
from app.models.gift import GiftStatus, GiftPriority
|
|
|
|
|
|
@pytest.fixture
|
|
def gift_item_data(mock_event, mock_user):
|
|
return {
|
|
"name": "Animal Plushie",
|
|
"description": "A cute animal plushie for Emma",
|
|
"price": 19.99,
|
|
"currency": "USD",
|
|
"quantity_requested": 2,
|
|
"priority": GiftPriority.HIGH.value,
|
|
"event_id": str(mock_event.id),
|
|
"added_by": str(mock_user.id)
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def gift_category_data(mock_event, mock_user):
|
|
return {
|
|
"name": "Toys",
|
|
"description": "Animal-themed toys for Emma",
|
|
"icon": "toy-icon",
|
|
"color": "#FF5733",
|
|
"created_by": str(mock_user.id)
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def gift_purchase_data(gift_item_fixture, guest_fixture):
|
|
return {
|
|
"gift_id": str(gift_item_fixture.id),
|
|
"guest_id": str(guest_fixture.id),
|
|
"quantity": 1,
|
|
"purchase_price": 19.99,
|
|
"purchase_currency": "USD",
|
|
"notes": "Purchased as a birthday gift"
|
|
}
|
|
|
|
|
|
class TestGiftsRouter:
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def setup_method(self, create_test_client, db_session, mock_user, gift_item_fixture, gift_category_fixture):
|
|
self.client = create_test_client(
|
|
router=gifts_router,
|
|
prefix="/gifts",
|
|
db_session=db_session,
|
|
user=mock_user
|
|
)
|
|
self.db_session = db_session
|
|
self.mock_user = mock_user
|
|
self.endpoint = "/gifts"
|
|
self.gift_item = gift_item_fixture
|
|
self.gift_category = gift_category_fixture
|
|
|
|
# Gift Item Tests
|
|
def test_create_gift_item_success(self, gift_item_data):
|
|
response = self.client.post(f"{self.endpoint}/items", json=gift_item_data)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["name"] == gift_item_data["name"]
|
|
assert data["price"] == gift_item_data["price"]
|
|
assert data["status"] == GiftStatus.AVAILABLE.value
|
|
|
|
def test_read_gift_item_success(self):
|
|
response = self.client.get(f"{self.endpoint}/items/{self.gift_item.id}")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["id"] == str(self.gift_item.id)
|
|
assert data["name"] == self.gift_item.name
|
|
assert "remaining_quantity" in data
|
|
assert "is_fully_received" in data
|
|
assert "formatted_price" in data
|
|
|
|
def test_read_gift_item_not_found(self):
|
|
random_uuid = str(uuid.uuid4())
|
|
response = self.client.get(f"{self.endpoint}/items/{random_uuid}")
|
|
assert response.status_code == 404
|
|
assert response.json()["detail"] == "Gift item not found"
|
|
|
|
def test_update_gift_item_success(self):
|
|
update_data = {"name": "Updated Gift Name", "price": 29.99}
|
|
response = self.client.put(f"{self.endpoint}/items/{self.gift_item.id}", json=update_data)
|
|
assert response.status_code == 200
|
|
assert response.json()["name"] == "Updated Gift Name"
|
|
assert response.json()["price"] == 29.99
|
|
|
|
def test_update_gift_item_not_found(self):
|
|
fake_uuid = str(uuid.uuid4())
|
|
update_data = {"name": "Nobody's Gift"}
|
|
response = self.client.put(f"{self.endpoint}/items/{fake_uuid}", json=update_data)
|
|
assert response.status_code == 404
|
|
|
|
def test_delete_gift_item_success(self):
|
|
response = self.client.delete(f"{self.endpoint}/items/{self.gift_item.id}")
|
|
assert response.status_code == 200
|
|
assert response.json()["id"] == str(self.gift_item.id)
|
|
|
|
def test_delete_gift_item_not_found(self):
|
|
fake_uuid = str(uuid.uuid4())
|
|
response = self.client.delete(f"{self.endpoint}/items/{fake_uuid}")
|
|
assert response.status_code == 404
|
|
assert response.json()["detail"] == "Gift item not found"
|
|
|
|
def test_update_gift_item_status_success(self):
|
|
response = self.client.put(
|
|
f"{self.endpoint}/items/{self.gift_item.id}/status",
|
|
params={"status": GiftStatus.RESERVED.value}
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == GiftStatus.RESERVED.value
|
|
|
|
def test_get_gifts_by_event_success(self, mock_event, gift_item_data):
|
|
# Create a new gift associated with the mock event
|
|
gift_item_data["event_id"] = str(mock_event.id)
|
|
self.client.post(f"{self.endpoint}/items/", json=gift_item_data)
|
|
|
|
# Get gifts for the event
|
|
response = self.client.get(f"{self.endpoint}/items/event/{mock_event.id}")
|
|
assert response.status_code == 200
|
|
assert isinstance(response.json(), list)
|
|
assert len(response.json()) >= 1
|
|
assert any(gift["event_id"] == str(mock_event.id) for gift in response.json())
|
|
|
|
# Gift Category Tests
|
|
def test_create_gift_category_success(self, gift_category_data, mock_event):
|
|
# Need to provide event_id as a query parameter
|
|
response = self.client.post(
|
|
f"{self.endpoint}/categories/",
|
|
json=gift_category_data,
|
|
params={"event_id": str(mock_event.id)}
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["name"] == gift_category_data["name"]
|
|
assert data["icon"] == gift_category_data["icon"]
|
|
assert data["color"] == gift_category_data["color"]
|
|
# Check that display_order and is_visible are set with default values
|
|
assert data["display_order"] == 0
|
|
assert data["is_visible"] == True
|
|
|
|
def test_read_gift_category_success(self):
|
|
response = self.client.get(f"{self.endpoint}/categories/{self.gift_category.id}")
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["id"] == str(self.gift_category.id)
|
|
assert data["name"] == self.gift_category.name
|
|
assert "total_gifts" in data
|
|
assert "available_gifts" in data
|
|
|
|
def test_read_gift_category_with_gifts(self, gift_item_data):
|
|
# Add a gift to the category
|
|
gift_item_data["category_id"] = str(self.gift_category.id)
|
|
self.client.post(f"{self.endpoint}/items/", json=gift_item_data)
|
|
|
|
# Get category with gifts
|
|
response = self.client.get(
|
|
f"{self.endpoint}/categories/{self.gift_category.id}",
|
|
params={"include_gifts": True}
|
|
)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert "gifts" in data
|
|
assert len(data["gifts"]) >= 1
|
|
assert all(gift["category_id"] == str(self.gift_category.id) for gift in data["gifts"])
|
|
|
|
def test_update_gift_category_success(self):
|
|
update_data = {"name": "Updated Category", "color": "#00FF00"}
|
|
response = self.client.put(
|
|
f"{self.endpoint}/categories/{self.gift_category.id}",
|
|
json=update_data
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["name"] == "Updated Category"
|
|
assert response.json()["color"] == "#00FF00"
|
|
|
|
def test_delete_gift_category_success(self):
|
|
response = self.client.delete(
|
|
f"{self.endpoint}/categories/{self.gift_category.id}",
|
|
params={"force": True}
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["id"] == str(self.gift_category.id)
|
|
|
|
def test_get_categories_by_event_success(self, mock_event, gift_category_data):
|
|
# Create a new category associated with the mock event
|
|
self.client.post(
|
|
f"{self.endpoint}/categories/",
|
|
json=gift_category_data,
|
|
params={"event_id": str(mock_event.id)}
|
|
)
|
|
|
|
# Get categories for the event
|
|
response = self.client.get(f"{self.endpoint}/categories/event/{mock_event.id}")
|
|
assert response.status_code == 200
|
|
assert isinstance(response.json(), list)
|
|
assert len(response.json()) >= 1
|
|
|
|
# Check that at least one category has display_order and is_visible set
|
|
# These properties come from the EventGiftCategory association
|
|
assert any(
|
|
cat.get("display_order") is not None and cat.get("is_visible") is not None
|
|
for cat in response.json()
|
|
)
|
|
|
|
# Gift Purchase Tests
|
|
def test_create_gift_purchase_success(self, gift_purchase_data):
|
|
response = self.client.post(f"{self.endpoint}/purchases/", json=gift_purchase_data)
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["gift_id"] == gift_purchase_data["gift_id"]
|
|
assert data["guest_id"] == gift_purchase_data["guest_id"]
|
|
assert data["quantity"] == gift_purchase_data["quantity"]
|
|
|
|
# Verify gift status was updated to PURCHASED
|
|
gift_response = self.client.get(f"{self.endpoint}/items/{gift_purchase_data['gift_id']}")
|
|
assert gift_response.status_code == 200
|
|
assert gift_response.json()["status"] == GiftStatus.PURCHASED.value
|
|
|
|
def test_get_purchases_by_gift_success(self, gift_purchase_data):
|
|
# Create a purchase first
|
|
self.client.post(f"{self.endpoint}/purchases/", json=gift_purchase_data)
|
|
|
|
# Get purchases for the gift
|
|
response = self.client.get(f"{self.endpoint}/purchases/gift/{gift_purchase_data['gift_id']}")
|
|
assert response.status_code == 200
|
|
assert isinstance(response.json(), list)
|
|
assert len(response.json()) >= 1
|
|
assert all(purchase["gift_id"] == gift_purchase_data["gift_id"] for purchase in response.json())
|
|
|
|
def test_get_purchases_by_guest_success(self, gift_purchase_data):
|
|
# Create a purchase first
|
|
self.client.post(f"{self.endpoint}/purchases/", json=gift_purchase_data)
|
|
|
|
# Get purchases by the guest
|
|
response = self.client.get(f"{self.endpoint}/purchases/guest/{gift_purchase_data['guest_id']}")
|
|
assert response.status_code == 200
|
|
assert isinstance(response.json(), list)
|
|
assert len(response.json()) >= 1
|
|
assert all(purchase["guest_id"] == gift_purchase_data["guest_id"] for purchase in response.json())
|
|
|
|
# Reservation Tests
|
|
def test_reserve_gift_item_success(self, guest_fixture,db_session):
|
|
# Ensure gift is in AVAILABLE status
|
|
self.gift_item.status = GiftStatus.AVAILABLE
|
|
self.db_session.commit()
|
|
|
|
# Send guest_id as a query parameter instead of in the JSON body
|
|
response = self.client.post(
|
|
f"{self.endpoint}/items/{self.gift_item.id}/reserve",
|
|
params={"guest_id": str(guest_fixture.id), "notes": "I'll bring this gift"}
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == GiftStatus.RESERVED.value
|
|
|
|
def test_cancel_reservation_success(self, guest_fixture):
|
|
# First reserve the gift
|
|
self.gift_item.status = GiftStatus.RESERVED
|
|
self.db_session.commit()
|
|
|
|
cancel_data = {
|
|
"guest_id": str(guest_fixture.id)
|
|
}
|
|
response = self.client.post(
|
|
f"{self.endpoint}/items/{self.gift_item.id}/cancel-reservation",
|
|
params=cancel_data
|
|
)
|
|
assert response.status_code == 200
|
|
assert response.json()["status"] == GiftStatus.AVAILABLE.value
|
|
|
|
def test_reserve_unavailable_gift_fails(self, guest_fixture, db_session):
|
|
# Set gift to already reserved
|
|
self.gift_item.status = GiftStatus.PURCHASED
|
|
self.db_session.commit()
|
|
|
|
reservation_data = {
|
|
"guest_id": str(guest_fixture.id)
|
|
}
|
|
response = self.client.post(
|
|
f"{self.endpoint}/items/{self.gift_item.id}/reserve",
|
|
params=reservation_data
|
|
)
|
|
assert response.status_code == 400
|
|
assert response.json()["detail"] == "Gift is not available for reservation"
|