Skip to content

Commit

Permalink
refactor tests for validators and mark as xfail
Browse files Browse the repository at this point in the history
  • Loading branch information
mahenzon committed Jun 9, 2024
1 parent 954e927 commit 1f77549
Showing 1 changed file with 37 additions and 35 deletions.
72 changes: 37 additions & 35 deletions tests/test_api/test_validators.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
from copy import deepcopy
from typing import Dict, List, Optional, Set, Type
from typing import (
Type,
Annotated,
)

import pytest
from fastapi import FastAPI, status
from httpx import AsyncClient
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator

from fastapi_jsonapi.types_metadata import ClientCanSetId
from fastapi_jsonapi.views.view_base import ViewBase
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
from pytest import mark, param # noqa: PT013
from pytest_asyncio import fixture
from sqlalchemy.ext.asyncio import AsyncSession
Expand All @@ -24,6 +30,9 @@
pytestmark = pytest.mark.asyncio


# TODO: Support Annotated validators (Before/After)


@fixture()
async def task_with_none_ids(
async_session: AsyncSession,
Expand All @@ -40,6 +49,7 @@ def resource_type():
return "task"


@pytest.mark.xfail(reason="validators passthrough not supported yet")
class TestTaskValidators:
async def test_base_model_validator_pre_true_get_one(
self,
Expand All @@ -56,7 +66,7 @@ async def test_base_model_validator_pre_true_get_one(
attributes = response_data["data"].pop("attributes")
assert response_data == {
"data": {
"id": str(task_with_none_ids.id),
"id": ViewBase.get_db_item_id(task_with_none_ids),
"type": resource_type,
},
"jsonapi": {"version": "1.0"},
Expand All @@ -81,26 +91,18 @@ async def test_base_model_root_validator_get_list(
res = await client.get(url)
assert res.status_code == status.HTTP_200_OK, res.text
response_data = res.json()
assert response_data == {
"data": [
{
"id": str(task_with_none_ids.id),
"type": resource_type,
"attributes": {
# not `None`! schema validator returns empty list `[]`
# "task_ids": None,
"task_ids": [],
},
expected_data = [
{
"id": ViewBase.get_db_item_id(task_with_none_ids),
"type": resource_type,
"attributes": {
# not `None`! schema validator returns empty list `[]`
# "task_ids": None,
"task_ids": [],
},
],
"jsonapi": {
"version": "1.0",
},
"meta": {
"count": 1,
"totalPages": 1,
},
}
]
assert response_data["data"] == expected_data

async def test_base_model_root_validator_create(
self,
Expand All @@ -126,7 +128,6 @@ async def test_base_model_root_validator_create(
task_id = response_data["data"].pop("id")
task = await async_session.get(Task, int(task_id))
assert isinstance(task, Task)
assert task.task_ids == []
# we sent request with `None`, but value in db is `[]`
# because validator converted data before object creation
assert task.task_ids == []
Expand All @@ -143,6 +144,7 @@ async def test_base_model_root_validator_create(
}


@pytest.mark.xfail(reason="validators passthrough not supported yet")
class TestValidators:
resource_type = "validator"

Expand All @@ -162,12 +164,10 @@ def _refresh_caches(self) -> None:

RoutersJSONAPI.all_jsonapi_routers = all_jsonapi_routers

def build_app(self, schema, resource_type: Optional[str] = None) -> FastAPI:
def build_app(self, schema, resource_type: str | None = None) -> FastAPI:
return build_app_custom(
model=User,
schema=schema,
# schema_in_post=schema,
# schema_in_patch=schema,
resource_type=resource_type or self.resource_type,
)

Expand All @@ -180,9 +180,9 @@ class InheritedSchema(schema):
async def execute_request_and_check_response(
self,
app: FastAPI,
body: Dict,
body: dict,
expected_detail: str,
resource_type: Optional[str] = None,
resource_type: str | None = None,
):
resource_type = resource_type or self.resource_type
async with AsyncClient(app=app, base_url="http://test") as client:
Expand All @@ -203,7 +203,7 @@ async def execute_request_and_check_response(
async def execute_request_twice_and_check_response(
self,
schema: Type[BaseModel],
body: Dict,
body: dict,
expected_detail: str,
):
"""
Expand Down Expand Up @@ -251,7 +251,7 @@ def validate_name(cls, v):

async def test_field_validator_each_item_arg(self):
class UserSchemaWithValidator(BaseModel):
names: List[str]
names: list[str]

@field_validator("names")
@classmethod
Expand All @@ -273,7 +273,7 @@ def validate_name(cls, v):

async def test_field_validator_pre_arg(self):
class UserSchemaWithValidator(BaseModel):
name: List[str]
name: list[str]

@field_validator("name", mode="before")
@classmethod
Expand Down Expand Up @@ -400,7 +400,8 @@ async def test_check_validator_for_id_field(self):
"""

class UserSchemaWithValidator(BaseModel):
id: int = Field(json_schema_extra={"client_can_set_id": True})
# TODO
id: Annotated[int, ClientCanSetId()]

@field_validator("id")
@classmethod
Expand All @@ -412,7 +413,7 @@ def validate_id(cls, v):
create_user_body = {
"data": {
"attributes": {},
"id": 42,
"id": str(42),
},
}

Expand Down Expand Up @@ -653,6 +654,7 @@ def validator_post_2(cls, values):
)


@pytest.mark.xfail(reason="validators passthrough not supported yet")
class TestValidationUtils:
@mark.parametrize(
("include", "exclude", "expected"),
Expand All @@ -665,9 +667,9 @@ class TestValidationUtils:
)
def test_extract_field_validators_args(
self,
include: Set[str],
exclude: Set[str],
expected: Set[str],
exclude: set[str],
include: set[str],
expected: set[str],
):
class ValidationSchema(BaseModel):
item_1: str
Expand Down

0 comments on commit 1f77549

Please sign in to comment.