"""Tests for schema classes."""
from __future__ import annotations

import pytest
from pydantic import ValidationError

from repo_core import BaseRequestSchema, BaseResponseSchema, BasePatchSchema


class CreateArticleRequest(BaseRequestSchema):
    title: str
    body: str
    tags: list[str] = []


class ArticleResponse(BaseResponseSchema):
    id: int
    title: str
    body: str


class PatchArticleRequest(BasePatchSchema):
    title: str | None = None
    body: str | None = None


# ---------------------------------------------------------------------------

def test_request_schema_valid():
    req = CreateArticleRequest(title="Hello", body="World")
    assert req.title == "Hello"
    assert req.tags == []


def test_request_schema_rejects_extra_fields():
    with pytest.raises(ValidationError):
        CreateArticleRequest(title="Hello", body="World", unknown_field="x")


def test_request_schema_validates_required_fields():
    with pytest.raises(ValidationError):
        CreateArticleRequest(body="World")  # missing title


def test_response_schema_from_dict():
    resp = ArticleResponse.model_validate({"id": 1, "title": "Hello", "body": "World"})
    assert resp.id == 1


def test_response_schema_from_orm():
    class FakeORM:
        id = 5
        title = "ORM"
        body = "body"

    resp = ArticleResponse.model_validate(FakeORM(), from_attributes=True)
    assert resp.id == 5
    assert resp.title == "ORM"


def test_response_schema_to_dict():
    resp = ArticleResponse(id=1, title="Hello", body="World")
    d = resp.to_dict()
    assert d == {"id": 1, "title": "Hello", "body": "World"}


def test_patch_schema_partial_update():
    patch = PatchArticleRequest(title="New Title")
    d = patch.to_patch_dict()
    assert d == {"title": "New Title"}
    assert "body" not in d


def test_patch_schema_empty_patch():
    patch = PatchArticleRequest()
    d = patch.to_patch_dict()
    assert d == {}


def test_patch_schema_rejects_extra_fields():
    with pytest.raises(ValidationError):
        PatchArticleRequest(unknown="x")
