11import logging
2- from itertools import chain
2+ from itertools import chain , zip_longest
33from json import dumps
44from typing import Dict , List
55from uuid import uuid4
2626 Workplace ,
2727)
2828from tests .schemas import (
29+ CustomUserAttributesSchema ,
2930 IdCastSchema ,
3031 PostAttributesBaseSchema ,
3132 PostCommentAttributesBaseSchema ,
@@ -47,10 +48,10 @@ def association_key(data: dict):
4748
4849
4950def build_app_custom (
50- schema ,
51- schema_in_patch ,
52- schema_in_post ,
5351 model ,
52+ schema ,
53+ schema_in_patch = None ,
54+ schema_in_post = None ,
5455 resource_type : str = "misc" ,
5556) -> FastAPI :
5657 router : APIRouter = APIRouter ()
@@ -922,10 +923,10 @@ async def test_create_user_and_fetch_data(self, app: FastAPI, client: AsyncClien
922923 async def test_create_id_by_client (self ):
923924 resource_type = "user"
924925 app = build_app_custom (
925- UserSchema ,
926- UserPatchSchema ,
927- UserInSchemaAllowIdOnPost ,
928- User ,
926+ model = User ,
927+ schema = UserSchema ,
928+ schema_in_post = UserInSchemaAllowIdOnPost ,
929+ schema_in_patch = UserPatchSchema ,
929930 resource_type = resource_type ,
930931 )
931932
@@ -957,7 +958,12 @@ async def test_create_id_by_client(self):
957958 }
958959
959960 async def test_create_id_by_client_uuid_type (self ):
960- app = build_app_custom (IdCastSchema , IdCastSchema , IdCastSchema , IdCast )
961+ resource_type = fake .word ()
962+ app = build_app_custom (
963+ model = IdCast ,
964+ schema = IdCastSchema ,
965+ resource_type = resource_type ,
966+ )
961967
962968 new_id = str (uuid4 ())
963969 create_body = {
@@ -968,14 +974,14 @@ async def test_create_id_by_client_uuid_type(self):
968974 }
969975
970976 async with AsyncClient (app = app , base_url = "http://test" ) as client :
971- url = app .url_path_for ("get_misc_list " )
977+ url = app .url_path_for (f"get_ { resource_type } _list " )
972978 res = await client .post (url , json = create_body )
973979 assert res .status_code == status .HTTP_201_CREATED , res .text
974980 assert res .json () == {
975981 "data" : {
976982 "attributes" : {},
977983 "id" : new_id ,
978- "type" : "misc" ,
984+ "type" : resource_type ,
979985 },
980986 "jsonapi" : {"version" : "1.0" },
981987 "meta" : None ,
@@ -984,10 +990,8 @@ async def test_create_id_by_client_uuid_type(self):
984990 async def test_create_with_relationship_to_the_same_table (self ):
985991 resource_type = "self_relationship"
986992 app = build_app_custom (
987- SelfRelationshipSchema ,
988- SelfRelationshipSchema ,
989- SelfRelationshipSchema ,
990- SelfRelationship ,
993+ model = SelfRelationship ,
994+ schema = SelfRelationshipSchema ,
991995 resource_type = resource_type ,
992996 )
993997
@@ -1108,10 +1112,10 @@ class UserPatchSchemaWithExtraAttribute(UserPatchSchema):
11081112
11091113 resource_type = "user"
11101114 app = build_app_custom (
1111- UserSchema ,
1112- UserPatchSchemaWithExtraAttribute ,
1113- UserPatchSchemaWithExtraAttribute ,
1114- User ,
1115+ model = User ,
1116+ schema = UserSchema ,
1117+ schema_in_post = UserPatchSchemaWithExtraAttribute ,
1118+ schema_in_patch = UserPatchSchemaWithExtraAttribute ,
11151119 resource_type = resource_type ,
11161120 )
11171121 new_attrs = UserPatchSchemaWithExtraAttribute (
@@ -1132,6 +1136,51 @@ class UserPatchSchemaWithExtraAttribute(UserPatchSchema):
11321136 res = await client .patch (url , json = patch_user_body )
11331137 assert res .status_code == status .HTTP_200_OK , res .text
11341138
1139+ async def test_update_schema_has_extra_fields (self , user_1 : User , caplog ):
1140+ resource_type = "user_extra_fields"
1141+ app = build_app_custom (
1142+ model = User ,
1143+ schema = UserAttributesBaseSchema ,
1144+ schema_in_patch = CustomUserAttributesSchema ,
1145+ resource_type = resource_type ,
1146+ )
1147+
1148+ new_attributes = CustomUserAttributesSchema (
1149+ age = fake .pyint (),
1150+ name = fake .user_name (),
1151+ spam = fake .word (),
1152+ eggs = fake .word (),
1153+ )
1154+ create_body = {
1155+ "data" : {
1156+ "attributes" : new_attributes .dict (),
1157+ "id" : user_1 .id ,
1158+ },
1159+ }
1160+
1161+ async with AsyncClient (app = app , base_url = "http://test" ) as client :
1162+ url = app .url_path_for (f"update_{ resource_type } _detail" , obj_id = user_1 .id )
1163+ res = await client .patch (url , json = create_body )
1164+
1165+ assert res .status_code == status .HTTP_200_OK , res .text
1166+ assert res .json () == {
1167+ "data" : {
1168+ "attributes" : UserAttributesBaseSchema (** new_attributes .dict ()).dict (),
1169+ "id" : str (user_1 .id ),
1170+ "type" : resource_type ,
1171+ },
1172+ "jsonapi" : {"version" : "1.0" },
1173+ "meta" : None ,
1174+ }
1175+
1176+ messages = [x .message for x in caplog .get_records ("call" ) if x .levelno == logging .WARNING ]
1177+ messages .sort ()
1178+ for log_message , expected in zip_longest (
1179+ messages ,
1180+ sorted ([f"No field { name !r} " for name in ("spam" , "eggs" )]),
1181+ ):
1182+ assert expected in log_message
1183+
11351184
11361185class TestPatchObjectRelationshipsToOne :
11371186 async def test_ok_when_foreign_key_of_related_object_is_nullable (
0 commit comments