Files
eventspace/backend/tests/models/test_gift.py

371 lines
11 KiB
Python

# tests/models/test_gift.py
import uuid
import pytest
from app.models.gift import GiftItem, GiftStatus, GiftPriority, GiftCategory, GiftPurchase
# ================================
# GiftItem Test Cases
# ================================
def test_create_gift_item(db_session, mock_user):
# Arrange
gift = GiftItem(
id=uuid.uuid4(),
event_id=uuid.uuid4(),
added_by=mock_user.id,
name="Baby Stroller",
description="High-quality baby stroller.",
price=150.00,
currency="USD",
quantity_requested=2,
quantity_received=0,
status=GiftStatus.AVAILABLE,
priority=GiftPriority.MUST_HAVE,
is_visible=True,
)
db_session.add(gift)
# Act
db_session.commit()
created_gift = db_session.query(GiftItem).filter_by(name="Baby Stroller").first()
# Assert
assert created_gift is not None
assert created_gift.name == "Baby Stroller"
assert created_gift.status == GiftStatus.AVAILABLE
assert created_gift.priority == GiftPriority.MUST_HAVE
assert created_gift.price == 150.00
assert created_gift.currency == "USD"
def test_update_gift_item(gift_item_fixture, db_session):
# Act
gift_item_fixture.quantity_requested = 3
gift_item_fixture.status = GiftStatus.RESERVED
gift_item_fixture.description = "Updated description for the gift."
db_session.commit()
# Assert
assert gift_item_fixture.quantity_requested == 3
assert gift_item_fixture.status == GiftStatus.RESERVED
assert gift_item_fixture.description == "Updated description for the gift."
def test_delete_gift_item(gift_item_fixture, db_session):
# Act
db_session.delete(gift_item_fixture)
db_session.commit()
# Assert
deleted_gift = db_session.query(GiftItem).filter_by(id=gift_item_fixture.id).first()
assert deleted_gift is None
def test_gift_item_remaining_quantity(gift_item_fixture):
# Arrange
gift_item_fixture.quantity_requested = 5
gift_item_fixture.quantity_received = 2
# Act
remaining_quantity = gift_item_fixture.remaining_quantity
# Assert
assert remaining_quantity == 3 # 5 requested - 2 received
def test_gift_item_is_fully_received(gift_item_fixture):
# Arrange
gift_item_fixture.quantity_requested = 4
gift_item_fixture.quantity_received = 4
# Act
is_fully_received = gift_item_fixture.is_fully_received
# Assert
assert is_fully_received is True
def test_gift_item_repr(db_session, gift_item_fixture):
# Act
repr_output = repr(gift_item_fixture)
# Assert
assert repr_output == f"<GiftItem {gift_item_fixture.name} ({gift_item_fixture.status.value})>"
from datetime import datetime, timezone
def test_update_status(db_session, gift_item_fixture):
# Arrange
gift_item_fixture.status = 'available'
# Act
gift_item_fixture.update_status('reserved')
# Assert
assert gift_item_fixture.status == 'reserved'
assert gift_item_fixture.last_status_change is not None
assert gift_item_fixture.last_status_change <= datetime.now(timezone.utc)
def test_gift_item_formatted_price(db_session, gift_item_fixture):
# Act: Case when price and currency are set
gift_item_fixture.price = 25.0
gift_item_fixture.currency = "USD"
formatted_price = gift_item_fixture.formatted_price
# Assert
assert formatted_price == "25.00 USD"
# Act: Case when price is `None`
gift_item_fixture.price = None
formatted_price_no_price = gift_item_fixture.formatted_price
# Assert
assert formatted_price_no_price == "Price not set"
# ================================
# GiftCategory Test Cases
# ================================
def test_create_gift_category(db_session, mock_user):
# Arrange
category = GiftCategory(
id=uuid.uuid4(),
created_by=mock_user.id,
name="Toys",
description="All kinds of educational toys."
)
db_session.add(category)
# Act
db_session.commit()
created_category = db_session.query(GiftCategory).filter_by(name="Toys").first()
# Assert
assert created_category is not None
assert created_category.description == "All kinds of educational toys."
def test_gift_category_total_gifts(db_session, mock_user):
# Arrange
event_id = uuid.uuid4()
category = GiftCategory(
id=uuid.uuid4(),
created_by=mock_user.id,
name="Baby Essentials",
)
db_session.add(category)
db_session.commit()
# Create the association between the category and the event
from app.models.gift import EventGiftCategory
event_gift_category = EventGiftCategory(
event_id=event_id,
category_id=category.id,
display_order=0,
is_visible=True
)
db_session.add(event_gift_category)
db_session.commit()
gift1 = GiftItem(
id=uuid.uuid4(),
event_id=event_id,
category_id=category.id,
name="Bottle Set",
quantity_requested=2,
added_by=mock_user.id,
status=GiftStatus.AVAILABLE,
)
gift2 = GiftItem(
id=uuid.uuid4(),
event_id=event_id,
category_id=category.id,
name="Diaper Bag",
quantity_requested=1,
added_by=mock_user.id,
status=GiftStatus.AVAILABLE,
)
db_session.add_all([gift1, gift2])
db_session.commit()
# Act
total_gifts = category.total_gifts
# Assert
assert total_gifts == 3 # 2 from gift1 + 1 from gift2
def test_gift_category_repr(db_session, gift_category_fixture):
# Act
repr_output = repr(gift_category_fixture)
# Assert
assert repr_output == f"<GiftCategory {gift_category_fixture.name}>"
def test_gift_category_available_gifts(db_session, gift_category_fixture, gift_item_fixture):
"""
Test that the available_gifts method correctly counts the available gifts.
"""
# Get the event_id from the EventGiftCategory association
from app.models.gift import EventGiftCategory
event_gift_category = db_session.query(EventGiftCategory).filter_by(
category_id=gift_category_fixture.id
).first()
# Update gift_item_fixture to match the gift_category_fixture
gift_item = GiftItem(
name="Toy Car",
description="A toy for kids",
price=10.0,
currency="USD",
quantity_requested=1,
quantity_received=0,
status=GiftStatus.AVAILABLE,
is_visible=True,
category_id=gift_category_fixture.id,
event_id=event_gift_category.event_id, # Get event_id from association
added_by=gift_category_fixture.created_by # Link to a user
)
db_session.add(gift_item)
db_session.commit()
# Assert that exactly one gift is available
assert gift_category_fixture.available_gifts == 1
def test_gift_category_reorder_gifts(db_session, gift_category_fixture, mock_user):
"""
Test that the reorder_gifts method correctly updates gift display_order
based on the provided order of gift IDs.
"""
# Get the event_id from the EventGiftCategory association
from app.models.gift import EventGiftCategory
event_gift_category = db_session.query(EventGiftCategory).filter_by(
category_id=gift_category_fixture.id
).first()
# Create GiftItems with proper required fields and UUID objects (not strings)
gift1_id = uuid.uuid4()
gift2_id = uuid.uuid4()
gift3_id = uuid.uuid4()
gift1 = GiftItem(
id=gift1_id,
name="Gift 1",
display_order=0,
category_id=gift_category_fixture.id,
event_id=event_gift_category.event_id, # Get event_id from association
added_by=gift_category_fixture.created_by, # Required field
status=GiftStatus.AVAILABLE # Required field
)
gift2 = GiftItem(
id=gift2_id,
name="Gift 2",
display_order=1,
category_id=gift_category_fixture.id,
event_id=event_gift_category.event_id, # Get event_id from association
added_by=gift_category_fixture.created_by,
status=GiftStatus.AVAILABLE
)
gift3 = GiftItem(
id=gift3_id,
name="Gift 3",
display_order=2,
category_id=gift_category_fixture.id,
event_id=event_gift_category.event_id, # Get event_id from association
added_by=gift_category_fixture.created_by,
status=GiftStatus.AVAILABLE
)
# Add gifts and refresh category to ensure the relationship is established
db_session.add_all([gift1, gift2, gift3])
db_session.commit()
db_session.refresh(gift_category_fixture)
# Act: Reorder gifts using the gift IDs (as UUID objects, not strings)
new_order = [gift3.id, gift1.id, gift2.id]
gift_category_fixture.reorder_gifts(new_order)
db_session.commit() # Make sure to commit the changes
# Refresh everything to ensure we get the latest data
db_session.refresh(gift1)
db_session.refresh(gift2)
db_session.refresh(gift3)
# Assert: Verify the display orders are updated correctly
assert gift1.display_order == 1
assert gift2.display_order == 2
assert gift3.display_order == 0
def test_reorder_gifts_invalid_id(gift_category_fixture, db_session):
"""
Test that reorder_gifts raises a ValueError when an invalid gift ID is provided.
"""
# Arrange: Ensure the category and database session are ready
db_session.add(gift_category_fixture)
db_session.commit()
# Act and Assert: Pass an invalid gift ID and assert it raises the correct exception
invalid_gift_id = "nonexistent-id"
with pytest.raises(ValueError, match=f"Gift ID {invalid_gift_id} not found in category"):
gift_category_fixture.reorder_gifts([invalid_gift_id])
# ================================
# GiftPurchase Test Cases
# ================================
def test_create_gift_purchase(db_session, mock_user, gift_item_fixture):
# Arrange
purchase = GiftPurchase(
id=uuid.uuid4(),
gift_id=gift_item_fixture.id,
guest_id=mock_user.id,
quantity=2,
purchase_price=50.00,
purchase_currency="USD",
notes="Gift purchased for the event."
)
db_session.add(purchase)
# Act
db_session.commit()
created_purchase = db_session.query(GiftPurchase).filter_by(gift_id=gift_item_fixture.id).first()
# Assert
assert created_purchase is not None
assert created_purchase.quantity == 2
assert created_purchase.purchase_currency == "USD"
assert created_purchase.notes == "Gift purchased for the event."
def test_link_purchase_to_gift(db_session, gift_item_fixture):
# Arrange
purchase = GiftPurchase(
id=uuid.uuid4(),
gift_id=gift_item_fixture.id,
guest_id=uuid.uuid4(),
quantity=1,
purchase_price=25.00,
purchase_currency="USD"
)
db_session.add(purchase)
db_session.commit()
# Act
gift_purchases = gift_item_fixture.purchase_history
# Assert
assert len(gift_purchases) == 1
assert gift_purchases[0].quantity == 1
assert gift_purchases[0].purchase_price == 25.00
def test_gift_purchase_repr(db_session, gift_purchase_fixture):
# Act
repr_output = repr(gift_purchase_fixture)
# Assert
assert repr_output == f"<GiftPurchase gift_id={gift_purchase_fixture.gift_id} guest_id={gift_purchase_fixture.guest_id}>"