371 lines
11 KiB
Python
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}>"
|