from __future__ import annotations from datetime import datetime, timezone from typing import cast from unittest.mock import AsyncMock, MagicMock from uuid import UUID, uuid4 import pytest from fastapi import HTTPException from core.auth.models import CurrentUser from models.schedule_items import ScheduleItem from v1.auth.schemas import UserByEmailResponse from v1.schedule_items.repository import ScheduleItemRepository from v1.schedule_items.schemas import ScheduleItemShareRequest from v1.schedule_items.service import ScheduleItemService def test_share_request_schema() -> None: request = ScheduleItemShareRequest( email="friend@example.com", permission_view=True, permission_edit=True, permission_invite=False, ) assert request.email == "friend@example.com" assert request.permission_view is True def test_permission_bits_calculation() -> None: request = ScheduleItemShareRequest( email="friend@example.com", permission_view=True, permission_edit=True, permission_invite=False, ) assert request._permission_value() == 5 def _build_item(item_id: UUID, owner_id: UUID) -> ScheduleItem: item = MagicMock(spec=ScheduleItem) item.id = item_id item.owner_id = owner_id item.title = "test" item.description = None item.start_at = datetime(2026, 2, 28, 16, 0, 0, tzinfo=timezone.utc) item.end_at = None item.timezone = "UTC" item.extra_metadata = {} item.created_at = datetime(2026, 2, 28, 10, 0, 0, tzinfo=timezone.utc) item.updated_at = datetime(2026, 2, 28, 10, 0, 0, tzinfo=timezone.utc) return item class ShareRepo: def __init__(self, item: ScheduleItem | None) -> None: self._item = item async def get_by_id(self, item_id: UUID) -> ScheduleItem | None: if self._item and self._item.id == item_id: return self._item return None class AuthGatewayStub: async def get_user_by_email(self, email: str) -> UserByEmailResponse: return UserByEmailResponse( id="00000000-0000-0000-0000-000000000222", email=email, created_at="2026-02-28T10:00:00Z", email_confirmed_at=None, ) @pytest.mark.asyncio async def test_share_forbidden_when_not_owner() -> None: owner_id = UUID("00000000-0000-0000-0000-000000000001") requester_id = UUID("00000000-0000-0000-0000-000000000002") item_id = uuid4() service = ScheduleItemService( repository=cast( ScheduleItemRepository, ShareRepo(_build_item(item_id=item_id, owner_id=owner_id)), ), session=AsyncMock(), current_user=CurrentUser(id=requester_id), auth_gateway=AuthGatewayStub(), ) with pytest.raises(HTTPException) as exc_info: await service.share( item_id, ScheduleItemShareRequest( email="friend@example.com", permission_view=True, permission_edit=False, permission_invite=False, ), ) assert exc_info.value.status_code == 403