feat: add share calendar API
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
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
|
||||
Reference in New Issue
Block a user