Fixe (partially) gift tests and api
This commit is contained in:
@@ -1,25 +1,25 @@
|
|||||||
from typing import List, Optional, Dict, Any, Union
|
from typing import List, Optional, Dict, Any
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException, Query, Path
|
from fastapi import APIRouter, Depends, HTTPException, Path
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.api.dependencies.auth import get_current_active_user, get_current_user
|
from app.api.dependencies.auth import get_current_active_user, get_current_user
|
||||||
|
from app.core.database import get_db
|
||||||
|
from app.crud.event import event_crud
|
||||||
from app.crud.gift import gift_item_crud, gift_category_crud, gift_purchase_crud, event_gift_category_crud
|
from app.crud.gift import gift_item_crud, gift_category_crud, gift_purchase_crud, event_gift_category_crud
|
||||||
from app.crud.guest import guest_crud
|
from app.crud.guest import guest_crud
|
||||||
from app.crud.event import event_crud
|
from app.models.gift import GiftStatus, EventGiftCategory, GiftItem as GiftItemModel
|
||||||
from app.models.gift import GiftStatus, GiftPriority, EventGiftCategory, GiftItem
|
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
from app.schemas.gifts import (
|
from app.schemas.gifts import (
|
||||||
GiftItem, GiftItemCreate, GiftItemUpdate,
|
GiftItem, GiftItemCreate, GiftItemUpdate,
|
||||||
GiftCategory, GiftCategoryCreate, GiftCategoryUpdate,
|
GiftCategory, GiftCategoryCreate, GiftCategoryUpdate,
|
||||||
GiftPurchase, GiftPurchaseCreate, GiftPurchaseUpdate,
|
GiftPurchase, GiftPurchaseCreate, EventGiftCategoryCreate
|
||||||
EventGiftCategoryCreate, EventGiftCategoryUpdate, EventGiftCategoryInDB
|
|
||||||
)
|
)
|
||||||
from app.core.database import get_db
|
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
# ===== GIFT CATEGORIES ===== #
|
# ===== GIFT CATEGORIES ===== #
|
||||||
|
|
||||||
@router.post("/categories/", response_model=GiftCategory)
|
@router.post("/categories/", response_model=GiftCategory)
|
||||||
@@ -51,7 +51,7 @@ def create_gift_category(
|
|||||||
event_id=event_id,
|
event_id=event_id,
|
||||||
category_id=category.id,
|
category_id=category.id,
|
||||||
display_order=0, # Default display order
|
display_order=0, # Default display order
|
||||||
is_visible=True # Default visibility
|
is_visible=True # Default visibility
|
||||||
)
|
)
|
||||||
event_gift_category_crud.create(db, obj_in=association_data)
|
event_gift_category_crud.create(db, obj_in=association_data)
|
||||||
|
|
||||||
@@ -90,37 +90,70 @@ def read_gift_categories(
|
|||||||
db, event_id=event_id, skip=skip, limit=limit, include_hidden=include_hidden
|
db, event_id=event_id, skip=skip, limit=limit, include_hidden=include_hidden
|
||||||
)
|
)
|
||||||
|
|
||||||
# Enhance categories with display information from the association
|
# Create a list to hold the enhanced category responses
|
||||||
|
enhanced_categories = []
|
||||||
|
|
||||||
for category in categories:
|
for category in categories:
|
||||||
# Get the association to access display_order and is_visible
|
# Get the association to access display_order and is_visible
|
||||||
association = event_gift_category_crud.get(
|
association = event_gift_category_crud.get(
|
||||||
db, event_id=event_id, category_id=category.id
|
db, event_id=event_id, category_id=category.id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Default values
|
||||||
|
display_order = None
|
||||||
|
is_visible = None
|
||||||
if association:
|
if association:
|
||||||
category.display_order = association.display_order
|
display_order = association.display_order
|
||||||
category.is_visible = association.is_visible
|
is_visible = association.is_visible
|
||||||
|
|
||||||
# Calculate statistics for this event
|
# Calculate statistics for this event
|
||||||
total_gifts = 0
|
total_gifts = 0
|
||||||
available_gifts = 0
|
available_gifts = 0
|
||||||
if category.gifts:
|
gifts_list = None
|
||||||
for gift in category.gifts:
|
|
||||||
|
# If include_gifts is true, fetch gift items for the category
|
||||||
|
if include_gifts:
|
||||||
|
gifts = gift_item_crud.get_multi_by_event(
|
||||||
|
db, event_id=event_id, category_id=category.id, include_hidden=include_hidden
|
||||||
|
)
|
||||||
|
gifts_list = gifts
|
||||||
|
|
||||||
|
# Calculate statistics
|
||||||
|
for gift in gifts:
|
||||||
if gift.event_id == event_id:
|
if gift.event_id == event_id:
|
||||||
total_gifts += 1
|
total_gifts += 1
|
||||||
if gift.status == GiftStatus.AVAILABLE and gift.is_visible:
|
if gift.status == GiftStatus.AVAILABLE and gift.is_visible:
|
||||||
available_gifts += 1
|
available_gifts += 1
|
||||||
|
else:
|
||||||
|
# Calculate statistics without fetching all gifts
|
||||||
|
if category.gifts:
|
||||||
|
for gift in category.gifts:
|
||||||
|
if gift.event_id == event_id:
|
||||||
|
total_gifts += 1
|
||||||
|
if gift.status == GiftStatus.AVAILABLE and gift.is_visible:
|
||||||
|
available_gifts += 1
|
||||||
|
|
||||||
category.total_gifts = total_gifts
|
# Create a new category response with the calculated values
|
||||||
category.available_gifts = available_gifts
|
category_data = {
|
||||||
|
**category.__dict__,
|
||||||
|
"display_order": display_order,
|
||||||
|
"is_visible": is_visible,
|
||||||
|
"total_gifts": total_gifts,
|
||||||
|
"available_gifts": available_gifts
|
||||||
|
}
|
||||||
|
|
||||||
# If include_gifts is true, fetch gift items for each category
|
if gifts_list is not None:
|
||||||
if include_gifts:
|
category_data["gifts"] = gifts_list
|
||||||
for category in categories:
|
|
||||||
gifts = gift_item_crud.get_multi_by_event(
|
# Remove SQLAlchemy state attributes
|
||||||
db, event_id=event_id, category_id=category.id, include_hidden=include_hidden
|
if "_sa_instance_state" in category_data:
|
||||||
)
|
del category_data["_sa_instance_state"]
|
||||||
# Set the gifts attribute which is initially None in the model
|
|
||||||
setattr(category, "gifts", gifts)
|
enhanced_category = GiftCategory(**category_data)
|
||||||
|
enhanced_categories.append(enhanced_category)
|
||||||
|
|
||||||
|
# Replace the original categories list with the enhanced one
|
||||||
|
categories = enhanced_categories
|
||||||
|
|
||||||
return categories
|
return categories
|
||||||
|
|
||||||
@@ -141,11 +174,12 @@ def read_gift_category(
|
|||||||
if not category:
|
if not category:
|
||||||
raise HTTPException(status_code=404, detail="Gift category not found")
|
raise HTTPException(status_code=404, detail="Gift category not found")
|
||||||
|
|
||||||
# Initialize event-specific properties
|
# Default values for event-specific properties
|
||||||
category.display_order = None
|
display_order = None
|
||||||
category.is_visible = None
|
is_visible = None
|
||||||
category.total_gifts = None
|
total_gifts = None
|
||||||
category.available_gifts = None
|
available_gifts = None
|
||||||
|
gifts_list = None
|
||||||
|
|
||||||
# If event_id is provided, get event-specific information
|
# If event_id is provided, get event-specific information
|
||||||
if event_id:
|
if event_id:
|
||||||
@@ -163,9 +197,9 @@ def read_gift_category(
|
|||||||
if not association:
|
if not association:
|
||||||
raise HTTPException(status_code=404, detail="Category not associated with this event")
|
raise HTTPException(status_code=404, detail="Category not associated with this event")
|
||||||
|
|
||||||
# Set event-specific display properties
|
# Get event-specific display properties
|
||||||
category.display_order = association.display_order
|
display_order = association.display_order
|
||||||
category.is_visible = association.is_visible
|
is_visible = association.is_visible
|
||||||
|
|
||||||
# Calculate statistics for this event
|
# Calculate statistics for this event
|
||||||
total_gifts = 0
|
total_gifts = 0
|
||||||
@@ -177,8 +211,7 @@ def read_gift_category(
|
|||||||
db, event_id=event_id, category_id=category.id,
|
db, event_id=event_id, category_id=category.id,
|
||||||
include_hidden=current_user is not None # Only include hidden for logged-in users
|
include_hidden=current_user is not None # Only include hidden for logged-in users
|
||||||
)
|
)
|
||||||
# Set the gifts attribute
|
gifts_list = gifts
|
||||||
setattr(category, "gifts", gifts)
|
|
||||||
|
|
||||||
# Calculate statistics
|
# Calculate statistics
|
||||||
for gift in gifts:
|
for gift in gifts:
|
||||||
@@ -187,23 +220,39 @@ def read_gift_category(
|
|||||||
available_gifts += 1
|
available_gifts += 1
|
||||||
else:
|
else:
|
||||||
# Calculate statistics without fetching all gifts
|
# Calculate statistics without fetching all gifts
|
||||||
gifts_query = db.query(GiftItem).filter(
|
gifts_query = db.query(GiftItemModel).filter(
|
||||||
GiftItem.event_id == event_id,
|
GiftItemModel.event_id == event_id,
|
||||||
GiftItem.category_id == category_id
|
GiftItemModel.category_id == category_id
|
||||||
)
|
)
|
||||||
total_gifts = gifts_query.count()
|
total_gifts = gifts_query.count()
|
||||||
available_gifts = gifts_query.filter(
|
available_gifts = gifts_query.filter(
|
||||||
GiftItem.status == GiftStatus.AVAILABLE,
|
GiftItemModel.status == GiftStatus.AVAILABLE,
|
||||||
GiftItem.is_visible == True
|
GiftItemModel.is_visible == True
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
category.total_gifts = total_gifts
|
|
||||||
category.available_gifts = available_gifts
|
|
||||||
elif include_gifts:
|
elif include_gifts:
|
||||||
# If no event_id but include_gifts is true, just get all gifts for this category
|
# If no event_id but include_gifts is true, just get all gifts for this category
|
||||||
# This is less useful without event context but included for completeness
|
# This is less useful without event context but included for completeness
|
||||||
gifts = db.query(GiftItem).filter(GiftItem.category_id == category_id).all()
|
gifts = db.query(GiftItem).filter(GiftItem.category_id == category_id).all()
|
||||||
setattr(category, "gifts", gifts)
|
gifts_list = gifts
|
||||||
|
|
||||||
|
# Create a new category response with the calculated values
|
||||||
|
category_data = {
|
||||||
|
**category.__dict__,
|
||||||
|
"display_order": display_order,
|
||||||
|
"is_visible": is_visible,
|
||||||
|
"total_gifts": total_gifts,
|
||||||
|
"available_gifts": available_gifts
|
||||||
|
}
|
||||||
|
|
||||||
|
if gifts_list is not None:
|
||||||
|
category_data["gifts"] = gifts_list
|
||||||
|
|
||||||
|
# Remove SQLAlchemy state attributes
|
||||||
|
if "_sa_instance_state" in category_data:
|
||||||
|
del category_data["_sa_instance_state"]
|
||||||
|
|
||||||
|
# Create a new category instance with the enhanced data
|
||||||
|
category = GiftCategory(**category_data)
|
||||||
|
|
||||||
return category
|
return category
|
||||||
|
|
||||||
@@ -227,11 +276,11 @@ def update_gift_category(
|
|||||||
# Update the category itself
|
# Update the category itself
|
||||||
updated_category = gift_category_crud.update(db, db_obj=category, obj_in=category_in)
|
updated_category = gift_category_crud.update(db, db_obj=category, obj_in=category_in)
|
||||||
|
|
||||||
# Initialize event-specific properties for the response
|
# Default values for event-specific properties
|
||||||
updated_category.display_order = None
|
display_order = None
|
||||||
updated_category.is_visible = None
|
is_visible = None
|
||||||
updated_category.total_gifts = None
|
total_gifts = None
|
||||||
updated_category.available_gifts = None
|
available_gifts = None
|
||||||
|
|
||||||
# If event_id is provided, update the event-specific settings
|
# If event_id is provided, update the event-specific settings
|
||||||
if event_id:
|
if event_id:
|
||||||
@@ -252,7 +301,7 @@ def update_gift_category(
|
|||||||
event_id=event_id,
|
event_id=event_id,
|
||||||
category_id=category_id,
|
category_id=category_id,
|
||||||
display_order=0, # Default display order
|
display_order=0, # Default display order
|
||||||
is_visible=True # Default visibility
|
is_visible=True # Default visibility
|
||||||
)
|
)
|
||||||
association = event_gift_category_crud.create(db, obj_in=association_data)
|
association = event_gift_category_crud.create(db, obj_in=association_data)
|
||||||
else:
|
else:
|
||||||
@@ -268,21 +317,37 @@ def update_gift_category(
|
|||||||
db, db_obj=association, obj_in=association_update
|
db, db_obj=association, obj_in=association_update
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set event-specific properties for the response
|
# Get event-specific properties for the response
|
||||||
updated_category.display_order = association.display_order
|
display_order = association.display_order
|
||||||
updated_category.is_visible = association.is_visible
|
is_visible = association.is_visible
|
||||||
|
|
||||||
# Calculate statistics for this event
|
# Calculate statistics for this event
|
||||||
gifts_query = db.query(GiftItem).filter(
|
gifts_query = db.query(GiftItem).filter(
|
||||||
GiftItem.event_id == event_id,
|
GiftItem.event_id == event_id,
|
||||||
GiftItem.category_id == category_id
|
GiftItem.category_id == category_id
|
||||||
)
|
)
|
||||||
updated_category.total_gifts = gifts_query.count()
|
total_gifts = gifts_query.count()
|
||||||
updated_category.available_gifts = gifts_query.filter(
|
available_gifts = gifts_query.filter(
|
||||||
GiftItem.status == GiftStatus.AVAILABLE,
|
GiftItem.status == GiftStatus.AVAILABLE,
|
||||||
GiftItem.is_visible == True
|
GiftItem.is_visible == True
|
||||||
).count()
|
).count()
|
||||||
|
|
||||||
|
# Create a new category response with the calculated values
|
||||||
|
category_data = {
|
||||||
|
**updated_category.__dict__,
|
||||||
|
"display_order": display_order,
|
||||||
|
"is_visible": is_visible,
|
||||||
|
"total_gifts": total_gifts,
|
||||||
|
"available_gifts": available_gifts
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove SQLAlchemy state attributes
|
||||||
|
if "_sa_instance_state" in category_data:
|
||||||
|
del category_data["_sa_instance_state"]
|
||||||
|
|
||||||
|
# Create a new category instance with the enhanced data
|
||||||
|
updated_category = GiftCategory(**category_data)
|
||||||
|
|
||||||
return updated_category
|
return updated_category
|
||||||
|
|
||||||
|
|
||||||
@@ -303,8 +368,12 @@ def delete_gift_category(
|
|||||||
if not category:
|
if not category:
|
||||||
raise HTTPException(status_code=404, detail="Gift category not found")
|
raise HTTPException(status_code=404, detail="Gift category not found")
|
||||||
|
|
||||||
# Make a copy of the category for the response
|
# Default values for event-specific properties
|
||||||
category_copy = GiftCategory.model_validate(category)
|
display_order = None
|
||||||
|
is_visible = None
|
||||||
|
total_gifts = None
|
||||||
|
available_gifts = None
|
||||||
|
gifts_list = None
|
||||||
|
|
||||||
if event_id:
|
if event_id:
|
||||||
# Check if event exists
|
# Check if event exists
|
||||||
@@ -324,13 +393,23 @@ def delete_gift_category(
|
|||||||
# Remove the association
|
# Remove the association
|
||||||
event_gift_category_crud.remove(db, event_id=event_id, category_id=category_id)
|
event_gift_category_crud.remove(db, event_id=event_id, category_id=category_id)
|
||||||
|
|
||||||
# Return the category with event-specific properties set to None
|
# Create a new category response with the calculated values
|
||||||
category_copy.display_order = None
|
category_data = {
|
||||||
category_copy.is_visible = None
|
**category.__dict__,
|
||||||
category_copy.total_gifts = None
|
"display_order": display_order,
|
||||||
category_copy.available_gifts = None
|
"is_visible": is_visible,
|
||||||
|
"total_gifts": total_gifts,
|
||||||
|
"available_gifts": available_gifts
|
||||||
|
}
|
||||||
|
|
||||||
return category_copy
|
# Remove SQLAlchemy state attributes
|
||||||
|
if "_sa_instance_state" in category_data:
|
||||||
|
del category_data["_sa_instance_state"]
|
||||||
|
|
||||||
|
# Create a new category instance with the enhanced data
|
||||||
|
category_response = GiftCategory(**category_data)
|
||||||
|
|
||||||
|
return category_response
|
||||||
elif force:
|
elif force:
|
||||||
# Check if the user has permission to delete the category
|
# Check if the user has permission to delete the category
|
||||||
# This is a more restrictive operation, so we might want to add additional checks
|
# This is a more restrictive operation, so we might want to add additional checks
|
||||||
@@ -351,7 +430,7 @@ def delete_gift_category(
|
|||||||
# If the user doesn't have permission for any of the events, deny the operation
|
# If the user doesn't have permission for any of the events, deny the operation
|
||||||
if event.created_by != current_user.id:
|
if event.created_by != current_user.id:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=403,
|
status_code=403,
|
||||||
detail="Not enough permissions. Category is used by events you don't manage."
|
detail="Not enough permissions. Category is used by events you don't manage."
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -360,11 +439,29 @@ def delete_gift_category(
|
|||||||
event_gift_category_crud.remove(db, event_id=assoc.event_id, category_id=category_id)
|
event_gift_category_crud.remove(db, event_id=assoc.event_id, category_id=category_id)
|
||||||
|
|
||||||
# Now delete the category itself
|
# Now delete the category itself
|
||||||
return gift_category_crud.remove(db, id=category_id)
|
deleted_category = gift_category_crud.remove(db, id=category_id)
|
||||||
|
|
||||||
|
# Create a new category response with the calculated values
|
||||||
|
category_data = {
|
||||||
|
**deleted_category.__dict__,
|
||||||
|
"display_order": display_order,
|
||||||
|
"is_visible": is_visible,
|
||||||
|
"total_gifts": total_gifts,
|
||||||
|
"available_gifts": available_gifts
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove SQLAlchemy state attributes
|
||||||
|
if "_sa_instance_state" in category_data:
|
||||||
|
del category_data["_sa_instance_state"]
|
||||||
|
|
||||||
|
# Create a new category instance with the enhanced data
|
||||||
|
category_response = GiftCategory(**category_data)
|
||||||
|
|
||||||
|
return category_response
|
||||||
else:
|
else:
|
||||||
# If no event_id and not force, raise an error
|
# If no event_id and not force, raise an error
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
detail="Must provide event_id to remove association or set force=True to delete category completely"
|
detail="Must provide event_id to remove association or set force=True to delete category completely"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -583,8 +680,9 @@ def create_gift_item(
|
|||||||
if not category:
|
if not category:
|
||||||
raise HTTPException(status_code=404, detail="Gift category not found")
|
raise HTTPException(status_code=404, detail="Gift category not found")
|
||||||
|
|
||||||
# Check category belongs to the same event
|
# Check category belongs to the same event by checking the association
|
||||||
if category.event_id != item_in.event_id:
|
association = event_gift_category_crud.get(db, event_id=item_in.event_id, category_id=item_in.category_id)
|
||||||
|
if not association:
|
||||||
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
||||||
|
|
||||||
return gift_item_crud.create(db, obj_in=item_in)
|
return gift_item_crud.create(db, obj_in=item_in)
|
||||||
@@ -619,8 +717,9 @@ def read_gift_items(
|
|||||||
if not category:
|
if not category:
|
||||||
raise HTTPException(status_code=404, detail="Gift category not found")
|
raise HTTPException(status_code=404, detail="Gift category not found")
|
||||||
|
|
||||||
# Check category belongs to the requested event
|
# Check category belongs to the requested event by checking the association
|
||||||
if category.event_id != event_id:
|
association = event_gift_category_crud.get(db, event_id=event_id, category_id=category_id)
|
||||||
|
if not association:
|
||||||
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
||||||
|
|
||||||
return gift_item_crud.get_multi_by_event(
|
return gift_item_crud.get_multi_by_event(
|
||||||
@@ -688,8 +787,9 @@ def update_gift_item(
|
|||||||
if not category:
|
if not category:
|
||||||
raise HTTPException(status_code=404, detail="Gift category not found")
|
raise HTTPException(status_code=404, detail="Gift category not found")
|
||||||
|
|
||||||
# Check category belongs to the same event
|
# Check category belongs to the same event by checking the association
|
||||||
if category.event_id != gift.event_id:
|
association = event_gift_category_crud.get(db, event_id=gift.event_id, category_id=item_in.category_id)
|
||||||
|
if not association:
|
||||||
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
raise HTTPException(status_code=400, detail="Category does not belong to this event")
|
||||||
|
|
||||||
return gift_item_crud.update(db, db_obj=gift, obj_in=item_in)
|
return gift_item_crud.update(db, db_obj=gift, obj_in=item_in)
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ def gift_category_data(mock_event, mock_user):
|
|||||||
"description": "Animal-themed toys for Emma",
|
"description": "Animal-themed toys for Emma",
|
||||||
"icon": "toy-icon",
|
"icon": "toy-icon",
|
||||||
"color": "#FF5733",
|
"color": "#FF5733",
|
||||||
"event_id": str(mock_event.id),
|
|
||||||
"created_by": str(mock_user.id)
|
"created_by": str(mock_user.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,13 +129,21 @@ class TestGiftsRouter:
|
|||||||
assert any(gift["event_id"] == str(mock_event.id) for gift in response.json())
|
assert any(gift["event_id"] == str(mock_event.id) for gift in response.json())
|
||||||
|
|
||||||
# Gift Category Tests
|
# Gift Category Tests
|
||||||
def test_create_gift_category_success(self, gift_category_data):
|
def test_create_gift_category_success(self, gift_category_data, mock_event):
|
||||||
response = self.client.post(f"{self.endpoint}/categories/", json=gift_category_data)
|
# 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
|
assert response.status_code == 200
|
||||||
data = response.json()
|
data = response.json()
|
||||||
assert data["name"] == gift_category_data["name"]
|
assert data["name"] == gift_category_data["name"]
|
||||||
assert data["icon"] == gift_category_data["icon"]
|
assert data["icon"] == gift_category_data["icon"]
|
||||||
assert data["color"] == gift_category_data["color"]
|
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):
|
def test_read_gift_category_success(self):
|
||||||
response = self.client.get(f"{self.endpoint}/categories/{self.gift_category.id}")
|
response = self.client.get(f"{self.endpoint}/categories/{self.gift_category.id}")
|
||||||
@@ -174,21 +181,33 @@ class TestGiftsRouter:
|
|||||||
assert response.json()["color"] == "#00FF00"
|
assert response.json()["color"] == "#00FF00"
|
||||||
|
|
||||||
def test_delete_gift_category_success(self):
|
def test_delete_gift_category_success(self):
|
||||||
response = self.client.delete(f"{self.endpoint}/categories/{self.gift_category.id}")
|
response = self.client.delete(
|
||||||
|
f"{self.endpoint}/categories/{self.gift_category.id}",
|
||||||
|
params={"force": True}
|
||||||
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json()["id"] == str(self.gift_category.id)
|
assert response.json()["id"] == str(self.gift_category.id)
|
||||||
|
|
||||||
def test_get_categories_by_event_success(self, mock_event, gift_category_data):
|
def test_get_categories_by_event_success(self, mock_event, gift_category_data):
|
||||||
# Create a new category associated with the mock event
|
# Create a new category associated with the mock event
|
||||||
gift_category_data["event_id"] = str(mock_event.id)
|
self.client.post(
|
||||||
self.client.post(f"{self.endpoint}/categories/", json=gift_category_data)
|
f"{self.endpoint}/categories/",
|
||||||
|
json=gift_category_data,
|
||||||
|
params={"event_id": str(mock_event.id)}
|
||||||
|
)
|
||||||
|
|
||||||
# Get categories for the event
|
# Get categories for the event
|
||||||
response = self.client.get(f"{self.endpoint}/categories/event/{mock_event.id}")
|
response = self.client.get(f"{self.endpoint}/categories/event/{mock_event.id}")
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert isinstance(response.json(), list)
|
assert isinstance(response.json(), list)
|
||||||
assert len(response.json()) >= 1
|
assert len(response.json()) >= 1
|
||||||
assert any(cat["event_id"] == str(mock_event.id) for cat in response.json())
|
|
||||||
|
# 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
|
# Gift Purchase Tests
|
||||||
def test_create_gift_purchase_success(self, gift_purchase_data):
|
def test_create_gift_purchase_success(self, gift_purchase_data):
|
||||||
@@ -268,4 +287,4 @@ class TestGiftsRouter:
|
|||||||
params=reservation_data
|
params=reservation_data
|
||||||
)
|
)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert response.json()["detail"] == "Gift is not available for reservation"
|
assert response.json()["detail"] == "Gift is not available for reservation"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pytest_plugins = ["pytest_asyncio"]
|
|||||||
def db_session():
|
def db_session():
|
||||||
"""
|
"""
|
||||||
Creates a fresh SQLite in-memory database for each test function.
|
Creates a fresh SQLite in-memory database for each test function.
|
||||||
|
|
||||||
Yields a SQLAlchemy session that can be used for testing.
|
Yields a SQLAlchemy session that can be used for testing.
|
||||||
"""
|
"""
|
||||||
# Set up the database
|
# Set up the database
|
||||||
@@ -340,17 +340,27 @@ def gift_category_fixture(db_session, mock_user, mock_event):
|
|||||||
"""
|
"""
|
||||||
Fixture to create and return a GiftCategory instance.
|
Fixture to create and return a GiftCategory instance.
|
||||||
"""
|
"""
|
||||||
|
# Create the category without event_id and display_order
|
||||||
gift_category = GiftCategory(
|
gift_category = GiftCategory(
|
||||||
id=uuid.uuid4(),
|
id=uuid.uuid4(),
|
||||||
name="Electronics",
|
name="Electronics",
|
||||||
description="Category for electronic gifts",
|
description="Category for electronic gifts",
|
||||||
event_id=mock_event.id,
|
created_by=mock_user.id
|
||||||
created_by=mock_user.id,
|
|
||||||
display_order=0,
|
|
||||||
is_visible=True
|
|
||||||
)
|
)
|
||||||
db_session.add(gift_category)
|
db_session.add(gift_category)
|
||||||
db_session.commit()
|
db_session.commit()
|
||||||
|
|
||||||
|
# Create the association between the category and the event
|
||||||
|
from app.models.gift import EventGiftCategory
|
||||||
|
event_gift_category = EventGiftCategory(
|
||||||
|
event_id=mock_event.id,
|
||||||
|
category_id=gift_category.id,
|
||||||
|
display_order=0,
|
||||||
|
is_visible=True
|
||||||
|
)
|
||||||
|
db_session.add(event_gift_category)
|
||||||
|
db_session.commit()
|
||||||
|
|
||||||
return gift_category
|
return gift_category
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user