Add and extend test coverage for models and their methods
All checks were successful
Build and Push Docker Images / changes (push) Successful in 4s
Build and Push Docker Images / build-backend (push) Successful in 49s
Build and Push Docker Images / build-frontend (push) Has been skipped

Enhanced test coverage includes `repr` methods, model functionality, and validation logic for key models like `GiftItem`, `GiftCategory`, `EventMedia`, `RSVP`, and `GiftPurchase`. Refactored and added fixtures to support comprehensive testing scenarios. Addresses validation for gift reordering and updates `EventMedia` representation format for consistency.
This commit is contained in:
2025-02-28 15:57:32 +01:00
parent c15c55d691
commit 1fd1144bc1
6 changed files with 256 additions and 6 deletions

View File

@@ -1,5 +1,8 @@
# tests/models/test_gift.py
import uuid
import pytest
from app.models.gift import GiftItem, GiftStatus, GiftPriority, GiftCategory, GiftPurchase
@@ -84,6 +87,45 @@ def test_gift_item_is_fully_received(gift_item_fixture):
# 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
@@ -147,6 +189,107 @@ def test_gift_category_total_gifts(db_session, mock_user):
# 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.
"""
# 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=gift_category_fixture.event_id, # Ensure event linkage
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.
"""
# 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=gift_category_fixture.event_id, # Required field
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=gift_category_fixture.event_id,
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=gift_category_fixture.event_id,
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
@@ -195,4 +338,11 @@ def test_link_purchase_to_gift(db_session, gift_item_fixture):
# Assert
assert len(gift_purchases) == 1
assert gift_purchases[0].quantity == 1
assert gift_purchases[0].purchase_price == 25.00
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}>"