feat(friendships): create module structure and schemas

This commit is contained in:
qzl
2026-02-28 11:30:18 +08:00
parent dbd3f68dd4
commit 598c6c2ec5
8 changed files with 159 additions and 1 deletions
@@ -0,0 +1 @@
from __future__ import annotations
+1
View File
@@ -0,0 +1 @@
from __future__ import annotations
+1
View File
@@ -0,0 +1 @@
from __future__ import annotations
+38
View File
@@ -0,0 +1,38 @@
from __future__ import annotations
from datetime import datetime
from typing import Optional
from uuid import UUID
from pydantic import BaseModel, Field
class UserBasicInfo(BaseModel):
id: str
username: str
avatar_url: Optional[str] = None
class FriendRequestCreate(BaseModel):
target_user_id: UUID
content: Optional[str] = Field(None, max_length=200)
class FriendRequestResponse(BaseModel):
id: UUID
sender: UserBasicInfo
recipient: UserBasicInfo
content: Optional[str]
status: str
created_at: datetime
class FriendResponse(BaseModel):
id: UUID
friend: UserBasicInfo
status: str
created_at: datetime
accepted_at: Optional[datetime]
class FriendRequestAction(BaseModel):
pass
+1
View File
@@ -0,0 +1 @@
from __future__ import annotations
@@ -0,0 +1,116 @@
from __future__ import annotations
import pytest
from datetime import datetime
from uuid import uuid4
from v1.friendships.schemas import (
UserBasicInfo,
FriendRequestCreate,
FriendRequestResponse,
FriendResponse,
FriendRequestAction,
)
def test_user_basic_info_maps_fields() -> None:
user = UserBasicInfo(id="user-1", username="alice", avatar_url=None)
assert user.id == "user-1"
assert user.username == "alice"
assert user.avatar_url is None
def test_user_basic_info_with_avatar() -> None:
user = UserBasicInfo(
id="user-2", username="bob", avatar_url="https://example.com/avatar.png"
)
assert user.avatar_url == "https://example.com/avatar.png"
def test_friend_request_create_valid() -> None:
target_id = uuid4()
request = FriendRequestCreate(
target_user_id=target_id, content="Hi, let's be friends!"
)
assert request.target_user_id == target_id
assert request.content == "Hi, let's be friends!"
def test_friend_request_create_without_content() -> None:
target_id = uuid4()
request = FriendRequestCreate(target_user_id=target_id, content=None)
assert request.target_user_id == target_id
assert request.content is None
def test_friend_request_create_content_max_length() -> None:
target_id = uuid4()
with pytest.raises(Exception):
FriendRequestCreate(target_user_id=target_id, content="x" * 201)
def test_friend_request_response_maps_fields() -> None:
sender = UserBasicInfo(id="user-1", username="alice", avatar_url=None)
recipient = UserBasicInfo(id="user-2", username="bob", avatar_url=None)
request_id = uuid4()
created = datetime(2026, 1, 15, 10, 30, 0)
response = FriendRequestResponse(
id=request_id,
sender=sender,
recipient=recipient,
content="Hello!",
status="pending",
created_at=created,
)
assert response.id == request_id
assert response.sender.username == "alice"
assert response.recipient.username == "bob"
assert response.status == "pending"
assert response.created_at == created
def test_friend_response_maps_fields() -> None:
friend_user = UserBasicInfo(id="user-2", username="bob", avatar_url=None)
request_id = uuid4()
created = datetime(2026, 1, 15, 10, 30, 0)
accepted = datetime(2026, 1, 16, 12, 0, 0)
response = FriendResponse(
id=request_id,
friend=friend_user,
status="accepted",
created_at=created,
accepted_at=accepted,
)
assert response.id == request_id
assert response.friend.username == "bob"
assert response.status == "accepted"
assert response.accepted_at == accepted
def test_friend_response_accepted_at_optional() -> None:
friend_user = UserBasicInfo(id="user-2", username="bob", avatar_url=None)
request_id = uuid4()
created = datetime(2026, 1, 15, 10, 30, 0)
response = FriendResponse(
id=request_id,
friend=friend_user,
status="pending",
created_at=created,
accepted_at=None,
)
assert response.accepted_at is None
def test_friend_request_action_no_fields() -> None:
action = FriendRequestAction()
assert action.model_dump() == {}