11import logging
2+ from copy import deepcopy
23from itertools import chain , zip_longest
34from json import dumps
45from typing import Dict , List
78from fastapi import APIRouter , FastAPI , status
89from httpx import AsyncClient
910from pydantic import BaseModel , Field , root_validator , validator
10- from pytest import mark , param # noqa PT013
11+ from pytest import fixture , mark , param # noqa PT013
1112from sqlalchemy .ext .asyncio import AsyncSession
1213
1314from fastapi_jsonapi import RoutersJSONAPI
1415from fastapi_jsonapi .exceptions import BadRequest
16+ from fastapi_jsonapi .schema_builder import SchemaBuilder
1517from fastapi_jsonapi .views .view_base import ViewBase
1618from tests .fixtures .app import build_app_plain
1719from tests .fixtures .entities import build_workplace , create_user
@@ -2043,18 +2045,41 @@ async def test_sort(
20432045
20442046
20452047class TestValidators :
2046- async def execute_request_and_check_response (self , body : Dict , schema , expected_detail : str ):
2047- resource_type = "user"
2048- app = build_app_custom (
2048+ resource_type = "validator"
2049+
2050+ @fixture (autouse = True )
2051+ def _refresh_caches (self ) -> None :
2052+ object_schemas_cache = deepcopy (SchemaBuilder .object_schemas_cache )
2053+ relationship_schema_cache = deepcopy (SchemaBuilder .relationship_schema_cache )
2054+ base_jsonapi_object_schemas_cache = deepcopy (SchemaBuilder .base_jsonapi_object_schemas_cache )
2055+
2056+ all_jsonapi_routers = deepcopy (RoutersJSONAPI .all_jsonapi_routers )
2057+
2058+ yield
2059+
2060+ SchemaBuilder .object_schemas_cache = object_schemas_cache
2061+ SchemaBuilder .relationship_schema_cache = relationship_schema_cache
2062+ SchemaBuilder .base_jsonapi_object_schemas_cache = base_jsonapi_object_schemas_cache
2063+
2064+ RoutersJSONAPI .all_jsonapi_routers = all_jsonapi_routers
2065+
2066+ def build_app (self , schema ) -> FastAPI :
2067+ return build_app_custom (
20492068 model = User ,
20502069 schema = schema ,
20512070 schema_in_post = schema ,
20522071 schema_in_patch = schema ,
2053- resource_type = resource_type ,
2072+ resource_type = self . resource_type ,
20542073 )
20552074
2075+ async def execute_request_and_check_response (
2076+ self ,
2077+ app : FastAPI ,
2078+ body : Dict ,
2079+ expected_detail : str ,
2080+ ):
20562081 async with AsyncClient (app = app , base_url = "http://test" ) as client :
2057- url = app .url_path_for (f"get_{ resource_type } _list" )
2082+ url = app .url_path_for (f"get_{ self . resource_type } _list" )
20582083 res = await client .post (url , json = body )
20592084 assert res .status_code == status .HTTP_400_BAD_REQUEST , res .text
20602085 assert res .json () == {
@@ -2075,13 +2100,13 @@ async def test_field_validator_call(self):
20752100 Basic check to ensure that field validator called
20762101 """
20772102
2078- class UserSchemaWithValidatorCase1 (BaseModel ):
2103+ class UserSchemaWithValidator (BaseModel ):
20792104 name : str
20802105
20812106 @validator ("name" )
20822107 def validate_name (cls , v ):
20832108 # checks that cls arg is not bound to the origin class
2084- assert cls is not UserSchemaWithValidatorCase1
2109+ assert cls is not UserSchemaWithValidator
20852110
20862111 raise BadRequest (detail = "Check validator" )
20872112
@@ -2092,13 +2117,13 @@ class Config:
20922117 create_user_body = {"data" : {"attributes" : attrs }}
20932118
20942119 await self .execute_request_and_check_response (
2120+ app = self .build_app (UserSchemaWithValidator ),
20952121 body = create_user_body ,
2096- schema = UserSchemaWithValidatorCase1 ,
20972122 expected_detail = "Check validator" ,
20982123 )
20992124
21002125 async def test_field_validator_each_item_arg (self ):
2101- class UserSchemaWithValidatorCase2 (BaseModel ):
2126+ class UserSchemaWithValidator (BaseModel ):
21022127 names : List [str ]
21032128
21042129 @validator ("names" , each_item = True )
@@ -2113,13 +2138,13 @@ class Config:
21132138 create_user_body = {"data" : {"attributes" : attrs }}
21142139
21152140 await self .execute_request_and_check_response (
2141+ app = self .build_app (UserSchemaWithValidator ),
21162142 body = create_user_body ,
2117- schema = UserSchemaWithValidatorCase2 ,
21182143 expected_detail = "Bad name not allowed" ,
21192144 )
21202145
21212146 async def test_field_validator_pre_arg (self ):
2122- class UserSchemaWithValidatorCase3 (BaseModel ):
2147+ class UserSchemaWithValidator (BaseModel ):
21232148 name : List [str ]
21242149
21252150 @validator ("name" , pre = True )
@@ -2137,13 +2162,13 @@ class Config:
21372162 create_user_body = {"data" : {"attributes" : attrs }}
21382163
21392164 await self .execute_request_and_check_response (
2165+ app = self .build_app (UserSchemaWithValidator ),
21402166 body = create_user_body ,
2141- schema = UserSchemaWithValidatorCase3 ,
21422167 expected_detail = "Pre validator called" ,
21432168 )
21442169
21452170 async def test_field_validator_always_arg (self ):
2146- class UserSchemaWithValidatorCase4 (BaseModel ):
2171+ class UserSchemaWithValidator (BaseModel ):
21472172 name : str = None
21482173
21492174 @validator ("name" , always = True )
@@ -2156,13 +2181,13 @@ class Config:
21562181 create_user_body = {"data" : {"attributes" : {}}}
21572182
21582183 await self .execute_request_and_check_response (
2184+ app = self .build_app (UserSchemaWithValidator ),
21592185 body = create_user_body ,
2160- schema = UserSchemaWithValidatorCase4 ,
21612186 expected_detail = "Called always validator" ,
21622187 )
21632188
21642189 async def test_field_validator_several_validators (self ):
2165- class UserSchemaWithValidatorCase5 (BaseModel ):
2190+ class UserSchemaWithValidator (BaseModel ):
21662191 field : str
21672192
21682193 @validator ("field" )
@@ -2185,23 +2210,24 @@ class Config:
21852210 attrs = {"field" : "check_validator_1" }
21862211 create_user_body = {"data" : {"attributes" : attrs }}
21872212
2213+ app = self .build_app (UserSchemaWithValidator )
21882214 await self .execute_request_and_check_response (
2215+ app = app ,
21892216 body = create_user_body ,
2190- schema = UserSchemaWithValidatorCase5 ,
21912217 expected_detail = "Called validator 1" ,
21922218 )
21932219
21942220 attrs = {"field" : "check_validator_2" }
21952221 create_user_body = {"data" : {"attributes" : attrs }}
21962222
21972223 await self .execute_request_and_check_response (
2224+ app = app ,
21982225 body = create_user_body ,
2199- schema = UserSchemaWithValidatorCase5 ,
22002226 expected_detail = "Called validator 2" ,
22012227 )
22022228
22032229 async def test_field_validator_asterisk (self ):
2204- class UserSchemaWithValidatorCase6 (BaseModel ):
2230+ class UserSchemaWithValidator (BaseModel ):
22052231 field_1 : str
22062232 field_2 : str
22072233
@@ -2219,9 +2245,10 @@ class Config:
22192245 }
22202246 create_user_body = {"data" : {"attributes" : attrs }}
22212247
2248+ app = self .build_app (UserSchemaWithValidator )
22222249 await self .execute_request_and_check_response (
2250+ app = app ,
22232251 body = create_user_body ,
2224- schema = UserSchemaWithValidatorCase6 ,
22252252 expected_detail = "Check validator" ,
22262253 )
22272254
@@ -2232,8 +2259,8 @@ class Config:
22322259 create_user_body = {"data" : {"attributes" : attrs }}
22332260
22342261 await self .execute_request_and_check_response (
2262+ app = app ,
22352263 body = create_user_body ,
2236- schema = UserSchemaWithValidatorCase6 ,
22372264 expected_detail = "Check validator" ,
22382265 )
22392266
@@ -2243,7 +2270,7 @@ async def test_check_validator_for_id_field(self):
22432270 a different way than attributes
22442271 """
22452272
2246- class UserSchemaWithValidatorCase7 (BaseModel ):
2273+ class UserSchemaWithValidator (BaseModel ):
22472274 id : int = Field (client_can_set_id = True )
22482275
22492276 @validator ("id" )
@@ -2261,8 +2288,8 @@ class Config:
22612288 }
22622289
22632290 await self .execute_request_and_check_response (
2291+ app = self .build_app (UserSchemaWithValidator ),
22642292 body = create_user_body ,
2265- schema = UserSchemaWithValidatorCase7 ,
22662293 expected_detail = "Check validator" ,
22672294 )
22682295
@@ -2276,7 +2303,7 @@ class Config:
22762303 ],
22772304 )
22782305 async def test_root_validator (self , name : str , expected_detail : str ):
2279- class UserSchemaWithValidatorCase8 (BaseModel ):
2306+ class UserSchemaWithValidator (BaseModel ):
22802307 name : str
22812308
22822309 @root_validator (pre = True , allow_reuse = True )
@@ -2314,8 +2341,8 @@ class Config:
23142341 create_user_body = {"data" : {"attributes" : attrs }}
23152342
23162343 await self .execute_request_and_check_response (
2344+ app = self .build_app (UserSchemaWithValidator ),
23172345 body = create_user_body ,
2318- schema = UserSchemaWithValidatorCase8 ,
23192346 expected_detail = expected_detail ,
23202347 )
23212348
0 commit comments