449 lines
16 KiB
Python
449 lines
16 KiB
Python
import pytest
|
|
from datetime import datetime, timezone
|
|
from uuid import UUID, uuid4
|
|
|
|
from app.crud.gift import gift_item_crud, gift_category_crud, gift_purchase_crud
|
|
from app.schemas.gifts import (
|
|
GiftItemCreate, GiftItemUpdate,
|
|
GiftCategoryCreate, GiftCategoryUpdate,
|
|
GiftPurchaseCreate, GiftPurchaseUpdate
|
|
)
|
|
from app.models.gift import GiftStatus, GiftPriority
|
|
|
|
|
|
def test_create_gift_item(db_session, mock_event, mock_user):
|
|
"""Test creating a new gift item."""
|
|
gift_data = {
|
|
"name": "Toy Lion",
|
|
"description": "A cuddly lion toy",
|
|
"price": 24.99,
|
|
"currency": "USD",
|
|
"quantity_requested": 1,
|
|
"priority": GiftPriority.HIGH,
|
|
"purchase_url": "https://example.com/toy-lion",
|
|
"store_name": "Toys R Fun",
|
|
"image_url": "https://example.com/images/toy-lion.jpg"
|
|
}
|
|
gift_in = GiftItemCreate(**gift_data, event_id=mock_event.id, added_by=mock_user.id)
|
|
gift = gift_item_crud.create(db=db_session, obj_in=gift_in)
|
|
|
|
assert gift.name == gift_data["name"]
|
|
assert gift.description == gift_data["description"]
|
|
assert gift.price == gift_data["price"]
|
|
assert gift.event_id == mock_event.id
|
|
assert gift.added_by == mock_user.id
|
|
assert gift.status == GiftStatus.AVAILABLE
|
|
assert gift.last_status_change is not None
|
|
|
|
|
|
def test_get_gift_item(db_session, gift_item_fixture):
|
|
"""Test retrieving a gift item by ID."""
|
|
stored_gift = gift_item_crud.get(db=db_session, id=gift_item_fixture.id)
|
|
assert stored_gift
|
|
assert stored_gift.id == gift_item_fixture.id
|
|
assert stored_gift.name == gift_item_fixture.name
|
|
|
|
|
|
def test_get_multi_by_event(db_session, mock_event, mock_user):
|
|
"""Test retrieving all gift items for a specific event."""
|
|
# Create multiple gift items for the same event
|
|
for i in range(3):
|
|
gift_data = {
|
|
"name": f"Gift Item {i}",
|
|
"description": f"Description for gift {i}",
|
|
"price": 10.0 * (i + 1),
|
|
"event_id": mock_event.id,
|
|
"added_by": mock_user.id
|
|
}
|
|
gift_in = GiftItemCreate(**gift_data)
|
|
gift_item_crud.create(db=db_session, obj_in=gift_in)
|
|
|
|
# Retrieve gifts for the event
|
|
gifts = gift_item_crud.get_multi_by_event(
|
|
db=db_session,
|
|
event_id=mock_event.id,
|
|
skip=0,
|
|
limit=100
|
|
)
|
|
assert len(gifts) >= 3
|
|
assert all(gift.event_id == mock_event.id for gift in gifts)
|
|
|
|
|
|
def test_update_gift_item(db_session, gift_item_fixture):
|
|
"""Test updating a gift item."""
|
|
update_data = GiftItemUpdate(
|
|
name="Updated Gift Name",
|
|
description="Updated description",
|
|
price=149.99,
|
|
priority=GiftPriority.MUST_HAVE
|
|
)
|
|
updated_gift = gift_item_crud.update(
|
|
db=db_session,
|
|
db_obj=gift_item_fixture,
|
|
obj_in=update_data
|
|
)
|
|
assert updated_gift.name == "Updated Gift Name"
|
|
assert updated_gift.description == "Updated description"
|
|
assert updated_gift.price == 149.99
|
|
assert updated_gift.priority == GiftPriority.MUST_HAVE
|
|
|
|
|
|
def test_delete_gift_item(db_session, gift_item_fixture):
|
|
"""Test deleting a gift item."""
|
|
gift = gift_item_crud.remove(db=db_session, id=gift_item_fixture.id)
|
|
assert gift.id == gift_item_fixture.id
|
|
deleted_gift = gift_item_crud.get(db=db_session, id=gift_item_fixture.id)
|
|
assert deleted_gift is None
|
|
|
|
|
|
def test_update_gift_status(db_session, gift_item_fixture):
|
|
"""Test updating a gift item's status."""
|
|
updated_gift = gift_item_crud.update_status(
|
|
db=db_session,
|
|
gift_id=gift_item_fixture.id,
|
|
new_status=GiftStatus.RESERVED
|
|
)
|
|
assert updated_gift.status == GiftStatus.RESERVED
|
|
assert updated_gift.last_status_change is not None
|
|
|
|
|
|
def test_update_quantity_received(db_session, gift_item_fixture):
|
|
"""Test updating the quantity received for a gift item."""
|
|
# Set initial values for testing
|
|
gift_item_fixture.quantity_requested = 5
|
|
gift_item_fixture.quantity_received = 0
|
|
db_session.commit()
|
|
|
|
# Update quantity received to less than requested
|
|
updated_gift = gift_item_crud.update_quantity_received(
|
|
db=db_session,
|
|
gift_id=gift_item_fixture.id,
|
|
quantity=3
|
|
)
|
|
assert updated_gift.quantity_received == 3
|
|
assert updated_gift.status != GiftStatus.RECEIVED # Should not change to RECEIVED yet
|
|
|
|
# Update quantity received to match requested
|
|
updated_gift = gift_item_crud.update_quantity_received(
|
|
db=db_session,
|
|
gift_id=gift_item_fixture.id,
|
|
quantity=5
|
|
)
|
|
assert updated_gift.quantity_received == 5
|
|
assert updated_gift.status == GiftStatus.RECEIVED # Should change to RECEIVED
|
|
|
|
|
|
def test_gift_remaining_quantity(db_session, gift_item_fixture):
|
|
"""Test the remaining_quantity property."""
|
|
gift_item_fixture.quantity_requested = 5
|
|
gift_item_fixture.quantity_received = 2
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.remaining_quantity == 3
|
|
|
|
gift_item_fixture.quantity_received = 5
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.remaining_quantity == 0
|
|
|
|
gift_item_fixture.quantity_received = 6 # More than requested
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.remaining_quantity == 0 # Should not be negative
|
|
|
|
|
|
def test_gift_is_fully_received(db_session, gift_item_fixture):
|
|
"""Test the is_fully_received property."""
|
|
gift_item_fixture.quantity_requested = 3
|
|
gift_item_fixture.quantity_received = 1
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.is_fully_received is False
|
|
|
|
gift_item_fixture.quantity_received = 3
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.is_fully_received is True
|
|
|
|
gift_item_fixture.quantity_received = 4 # More than requested
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.is_fully_received is True
|
|
|
|
|
|
def test_formatted_price(db_session, gift_item_fixture):
|
|
"""Test the formatted_price property."""
|
|
gift_item_fixture.price = 19.99
|
|
gift_item_fixture.currency = "USD"
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.formatted_price == "19.99 USD"
|
|
|
|
gift_item_fixture.price = None
|
|
db_session.commit()
|
|
db_session.refresh(gift_item_fixture)
|
|
|
|
assert gift_item_fixture.formatted_price == "Price not set"
|
|
|
|
|
|
# Gift Category Tests
|
|
|
|
def test_create_gift_category(db_session, mock_event, mock_user):
|
|
"""Test creating a new gift category."""
|
|
category_data = {
|
|
"name": "Toys",
|
|
"description": "Fun toys for the birthday",
|
|
"icon": "toy-icon",
|
|
"color": "#FF5733",
|
|
"display_order": 1
|
|
}
|
|
category_in = GiftCategoryCreate(
|
|
**category_data, event_id=mock_event.id, created_by=mock_user.id
|
|
)
|
|
category = gift_category_crud.create(db=db_session, obj_in=category_in)
|
|
|
|
assert category.name == category_data["name"]
|
|
assert category.description == category_data["description"]
|
|
assert category.event_id == mock_event.id
|
|
assert category.created_by == mock_user.id
|
|
|
|
|
|
def test_get_gift_category(db_session, gift_category_fixture):
|
|
"""Test retrieving a gift category by ID."""
|
|
stored_category = gift_category_crud.get(db=db_session, id=gift_category_fixture.id)
|
|
assert stored_category
|
|
assert stored_category.id == gift_category_fixture.id
|
|
assert stored_category.name == gift_category_fixture.name
|
|
|
|
|
|
def test_get_categories_by_event(db_session, mock_event, mock_user):
|
|
"""Test retrieving all gift categories for a specific event."""
|
|
# Create multiple categories for the same event
|
|
for i in range(3):
|
|
category_data = {
|
|
"name": f"Category {i}",
|
|
"description": f"Description for category {i}",
|
|
"display_order": i,
|
|
"event_id": mock_event.id,
|
|
"created_by": mock_user.id
|
|
}
|
|
category_in = GiftCategoryCreate(**category_data)
|
|
gift_category_crud.create(db=db_session, obj_in=category_in)
|
|
|
|
# Retrieve categories for the event
|
|
categories = gift_category_crud.get_multi_by_event(
|
|
db=db_session,
|
|
event_id=mock_event.id,
|
|
skip=0,
|
|
limit=100
|
|
)
|
|
assert len(categories) >= 3
|
|
assert all(category.event_id == mock_event.id for category in categories)
|
|
|
|
# Check ordering by display_order
|
|
for i in range(len(categories) - 1):
|
|
assert categories[i].display_order <= categories[i + 1].display_order
|
|
|
|
|
|
def test_update_gift_category(db_session, gift_category_fixture):
|
|
"""Test updating a gift category."""
|
|
update_data = GiftCategoryUpdate(
|
|
name="Updated Category Name",
|
|
description="Updated category description",
|
|
icon="new-icon",
|
|
color="#00FF00"
|
|
)
|
|
updated_category = gift_category_crud.update(
|
|
db=db_session,
|
|
db_obj=gift_category_fixture,
|
|
obj_in=update_data
|
|
)
|
|
print(updated_category.__dict__)
|
|
assert updated_category.name == "Updated Category Name"
|
|
assert updated_category.description == "Updated category description"
|
|
# assert updated_category.icon == "new-icon"
|
|
# assert updated_category.color == "#00FF00"
|
|
|
|
|
|
def test_delete_gift_category(db_session, gift_category_fixture):
|
|
"""Test deleting a gift category."""
|
|
category = gift_category_crud.remove(db=db_session, id=gift_category_fixture.id)
|
|
assert category.id == gift_category_fixture.id
|
|
deleted_category = gift_category_crud.get(db=db_session, id=gift_category_fixture.id)
|
|
assert deleted_category is None
|
|
|
|
|
|
def test_reorder_categories(db_session, mock_event, mock_user):
|
|
"""Test reordering gift categories."""
|
|
# Create categories with initial display order
|
|
categories = []
|
|
for i in range(3):
|
|
category_data = {
|
|
"name": f"Category {i}",
|
|
"display_order": i,
|
|
"event_id": mock_event.id,
|
|
"created_by": mock_user.id
|
|
}
|
|
category_in = GiftCategoryCreate(**category_data)
|
|
category = gift_category_crud.create(db=db_session, obj_in=category_in)
|
|
categories.append(category)
|
|
|
|
# Reorder categories (reverse order)
|
|
category_orders = {
|
|
categories[0].id: 2,
|
|
categories[1].id: 1,
|
|
categories[2].id: 0
|
|
}
|
|
|
|
updated_categories = gift_category_crud.reorder_categories(
|
|
db=db_session,
|
|
event_id=mock_event.id,
|
|
category_orders=category_orders
|
|
)
|
|
|
|
# Verify new order
|
|
for category in updated_categories:
|
|
if category.id == categories[0].id:
|
|
assert category.display_order == 2
|
|
elif category.id == categories[1].id:
|
|
assert category.display_order == 1
|
|
elif category.id == categories[2].id:
|
|
assert category.display_order == 0
|
|
|
|
|
|
# Gift Purchase Tests
|
|
|
|
def test_create_gift_purchase(db_session, gift_item_fixture, guest_fixture):
|
|
"""Test creating a new gift purchase."""
|
|
purchase_data = {
|
|
"gift_id": gift_item_fixture.id,
|
|
"guest_id": guest_fixture.id,
|
|
"quantity": 1,
|
|
"purchase_price": 19.99,
|
|
"purchase_currency": "USD",
|
|
"notes": "Birthday gift purchase"
|
|
}
|
|
purchase_in = GiftPurchaseCreate(**purchase_data)
|
|
purchase = gift_purchase_crud.create(db=db_session, obj_in=purchase_in)
|
|
|
|
assert purchase.gift_id == gift_item_fixture.id
|
|
assert purchase.guest_id == guest_fixture.id
|
|
assert purchase.quantity == 1
|
|
assert purchase.purchase_price == 19.99
|
|
assert purchase.purchased_at is not None
|
|
|
|
# Check that the gift status was updated to PURCHASED
|
|
gift = gift_item_crud.get(db=db_session, id=gift_item_fixture.id)
|
|
assert gift.status == GiftStatus.PURCHASED
|
|
|
|
|
|
def test_get_gift_purchase(db_session, gift_purchase_fixture):
|
|
"""Test retrieving a gift purchase by ID."""
|
|
stored_purchase = gift_purchase_crud.get(db=db_session, id=gift_purchase_fixture.id)
|
|
assert stored_purchase
|
|
assert stored_purchase.id == gift_purchase_fixture.id
|
|
assert stored_purchase.gift_id == gift_purchase_fixture.gift_id
|
|
assert stored_purchase.guest_id == gift_purchase_fixture.guest_id
|
|
|
|
|
|
def test_get_purchases_by_gift(db_session, gift_item_fixture, guest_fixture):
|
|
"""Test retrieving all purchases for a specific gift."""
|
|
# Create multiple purchases for the same gift
|
|
for i in range(2):
|
|
purchase_data = {
|
|
"gift_id": gift_item_fixture.id,
|
|
"guest_id": guest_fixture.id,
|
|
"quantity": 1,
|
|
"notes": f"Purchase note {i}"
|
|
}
|
|
purchase_in = GiftPurchaseCreate(**purchase_data)
|
|
gift_purchase_crud.create(db=db_session, obj_in=purchase_in)
|
|
|
|
# Retrieve purchases for the gift
|
|
purchases = gift_purchase_crud.get_by_gift(
|
|
db=db_session,
|
|
gift_id=gift_item_fixture.id
|
|
)
|
|
assert len(purchases) >= 2
|
|
assert all(purchase.gift_id == gift_item_fixture.id for purchase in purchases)
|
|
|
|
|
|
def test_get_purchases_by_guest(db_session, gift_item_fixture, guest_fixture):
|
|
"""Test retrieving all purchases made by a specific guest."""
|
|
# Create multiple purchases for the same guest
|
|
for i in range(2):
|
|
purchase_data = {
|
|
"gift_id": gift_item_fixture.id,
|
|
"guest_id": guest_fixture.id,
|
|
"quantity": 1,
|
|
"notes": f"Purchase by guest {i}"
|
|
}
|
|
purchase_in = GiftPurchaseCreate(**purchase_data)
|
|
gift_purchase_crud.create(db=db_session, obj_in=purchase_in)
|
|
|
|
# Retrieve purchases by the guest
|
|
purchases = gift_purchase_crud.get_by_guest(
|
|
db=db_session,
|
|
guest_id=guest_fixture.id
|
|
)
|
|
assert len(purchases) >= 2
|
|
assert all(purchase.guest_id == guest_fixture.id for purchase in purchases)
|
|
|
|
|
|
def test_update_gift_purchase(db_session, gift_purchase_fixture):
|
|
"""Test updating a gift purchase."""
|
|
update_data = GiftPurchaseUpdate(
|
|
quantity=2,
|
|
purchase_price=39.98,
|
|
notes="Updated purchase notes"
|
|
)
|
|
updated_purchase = gift_purchase_crud.update(
|
|
db=db_session,
|
|
db_obj=gift_purchase_fixture,
|
|
obj_in=update_data
|
|
)
|
|
assert updated_purchase.quantity == 2
|
|
assert updated_purchase.purchase_price == 39.98
|
|
assert updated_purchase.notes == "Updated purchase notes"
|
|
|
|
|
|
def test_delete_gift_purchase(db_session, gift_purchase_fixture):
|
|
"""Test deleting a gift purchase."""
|
|
purchase = gift_purchase_crud.remove(db=db_session, id=gift_purchase_fixture.id)
|
|
assert purchase.id == gift_purchase_fixture.id
|
|
deleted_purchase = gift_purchase_crud.get(db=db_session, id=gift_purchase_fixture.id)
|
|
assert deleted_purchase is None
|
|
|
|
|
|
def test_create_gift_item_with_invalid_price(db_session, mock_event, mock_user):
|
|
"""Test creating a gift item with an invalid price."""
|
|
gift_data = {
|
|
"name": "Invalid Gift",
|
|
"price": -10.0, # Negative price should be invalid
|
|
"event_id": mock_event.id,
|
|
"added_by": mock_user.id
|
|
}
|
|
with pytest.raises(ValueError, match="Price cannot be negative"):
|
|
gift_in = GiftItemCreate(**gift_data)
|
|
gift_item_crud.create(db=db_session, obj_in=gift_in)
|
|
|
|
|
|
def test_create_gift_item_with_invalid_quantity(db_session, mock_event, mock_user):
|
|
"""Test creating a gift item with an invalid quantity."""
|
|
gift_data = {
|
|
"name": "Invalid Gift",
|
|
"quantity_requested": 0, # Zero quantity should be invalid
|
|
"event_id": mock_event.id,
|
|
"added_by": mock_user.id
|
|
}
|
|
|
|
with pytest.raises(ValueError, match="Quantity requested must be at least 1"):
|
|
gift_in = GiftItemCreate(**gift_data)
|
|
gift_item_crud.create(db=db_session, obj_in=gift_in) |