diff --git a/app/schemas/api.py b/app/schemas/api.py index 42c0c0c..b87ddef 100644 --- a/app/schemas/api.py +++ b/app/schemas/api.py @@ -1,7 +1,7 @@ import datetime import uuid from collections.abc import Iterable -from typing import Any, Self +from typing import Annotated, Any, Self import pydantic from pydantic import BaseModel, PositiveInt @@ -9,6 +9,9 @@ from app.database import tables +MessageText = Annotated[str, pydantic.Field(min_length=1, max_length=4000)] + + class Base(BaseModel): model_config = pydantic.ConfigDict(from_attributes=True) @@ -66,11 +69,11 @@ class ChatDetail(Chat): class SendMessageRequest(Base): idempotency_key: uuid.UUID - text: str = pydantic.Field(min_length=1, max_length=4000) + text: MessageText class EditMessageRequest(Base): - text: str = pydantic.Field(min_length=1, max_length=4000) + text: MessageText class Message(Base): diff --git a/tests/test_schemas.py b/tests/test_schemas.py index cfb6b81..67c2a82 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -1,4 +1,9 @@ -from app.schemas.api import Collection, User +import uuid + +import pydantic +import pytest + +from app.schemas.api import Collection, EditMessageRequest, SendMessageRequest, User from tests.factories import UserFactory @@ -6,3 +11,26 @@ def test_collection_builds_from_models() -> None: user = UserFactory.build(id=1, username="alice", display_name="Alice") collection = Collection[User].from_models([user]) assert collection.items == [User(id=1, username="alice", display_name="Alice")] + + +def _build_message_request( + model: type[SendMessageRequest | EditMessageRequest], text: str +) -> SendMessageRequest | EditMessageRequest: + if model is SendMessageRequest: + return SendMessageRequest(idempotency_key=uuid.uuid4(), text=text) + return EditMessageRequest(text=text) + + +@pytest.mark.parametrize("model", [SendMessageRequest, EditMessageRequest]) +@pytest.mark.parametrize("text", ["", "x" * 4001], ids=["empty", "over_max"]) +def test_message_request_rejects_out_of_bounds_text( + model: type[SendMessageRequest | EditMessageRequest], text: str +) -> None: + with pytest.raises(pydantic.ValidationError): + _build_message_request(model, text) + + +@pytest.mark.parametrize("model", [SendMessageRequest, EditMessageRequest]) +def test_message_request_accepts_max_length_text(model: type[SendMessageRequest | EditMessageRequest]) -> None: + text = "x" * 4000 + assert _build_message_request(model, text).text == text