1+ import pickle
2+
13import pytest
24from common_library .json_serialization import json_dumps
35from models_library .basic_types import IDStr
46from models_library .rest_ordering import (
57 OrderBy ,
68 OrderDirection ,
7- create_ordering_query_model_classes ,
9+ create_ordering_query_model_class ,
810)
911from pydantic import (
1012 BaseModel ,
1113 ConfigDict ,
1214 Field ,
1315 Json ,
16+ TypeAdapter ,
1417 ValidationError ,
1518 field_validator ,
1619)
@@ -47,8 +50,72 @@ def _validate_order_by_field(cls, v):
4750 )
4851
4952
53+ @pytest .mark .xfail (
54+ reason = "create_ordering_query_model_class.<locals>._OrderBy is still not pickable"
55+ )
56+ def test_pickle_ordering_query_model_class ():
57+ OrderQueryParamsModel = create_ordering_query_model_class (
58+ ordering_fields = {"name" , "description" },
59+ default = OrderBy (field = IDStr ("name" ), direction = OrderDirection .DESC ),
60+ )
61+
62+ data = {"order_by" : {"field" : "name" , "direction" : "asc" }}
63+ query_model = OrderQueryParamsModel .model_validate (data )
64+
65+ # https://docs.pydantic.dev/latest/concepts/serialization/#pickledumpsmodel
66+ expected = query_model .order_by
67+
68+ # see https://github.com/ITISFoundation/osparc-simcore/pull/6828
69+ # FAILURE: raises `AttributeError: Can't pickle local object 'create_ordering_query_model_class.<locals>._OrderBy'`
70+ data = pickle .dumps (expected )
71+
72+ loaded = pickle .loads (data )
73+ assert loaded == expected
74+
75+
76+ def test_conversion_order_by_from_query_to_domain_model ():
77+ OrderQueryParamsModel = create_ordering_query_model_class (
78+ ordering_fields = {"modified_at" , "name" , "description" },
79+ default = OrderBy (field = IDStr ("modified_at" ), direction = OrderDirection .DESC ),
80+ )
81+
82+ # normal
83+ data = {"order_by" : {"field" : "modified_at" , "direction" : "asc" }}
84+ query_model = OrderQueryParamsModel .model_validate (data )
85+
86+ expected_data = data ["order_by" ]
87+
88+ assert type (query_model .order_by ) is not OrderBy
89+ assert isinstance (query_model .order_by , OrderBy )
90+
91+ # NOTE: This does NOT convert to OrderBy but has correct data
92+ order_by = TypeAdapter (OrderBy ).validate_python (
93+ query_model .order_by , from_attributes = True
94+ )
95+ assert type (order_by ) is not OrderBy
96+ assert order_by .model_dump (mode = "json" ) == expected_data
97+
98+ order_by = OrderBy .model_validate (query_model .order_by .model_dump ())
99+ assert type (order_by ) is OrderBy
100+ assert order_by .model_dump (mode = "json" ) == expected_data
101+
102+ # NOTE: This does NOT convert to OrderBy but has correct data
103+ order_by = OrderBy .model_validate (query_model .order_by , from_attributes = True )
104+ assert type (order_by ) is not OrderBy
105+ assert order_by .model_dump (mode = "json" ) == expected_data
106+
107+ order_by = OrderBy (** query_model .order_by .model_dump ())
108+ assert type (order_by ) is OrderBy
109+ assert order_by .model_dump (mode = "json" ) == expected_data
110+
111+ # we should use this !!!
112+ order_by = OrderBy .model_construct (** query_model .order_by .model_dump ())
113+ assert type (order_by ) is OrderBy
114+ assert order_by .model_dump (mode = "json" ) == expected_data
115+
116+
50117def test_ordering_query_model_class_factory ():
51- BaseOrderingQueryModel = create_ordering_query_model_classes (
118+ BaseOrderingQueryModel = create_ordering_query_model_class (
52119 ordering_fields = {"modified_at" , "name" , "description" },
53120 default = OrderBy (field = IDStr ("modified_at" ), direction = OrderDirection .DESC ),
54121 ordering_fields_api_to_column_map = {"modified_at" : "modified_column" },
@@ -77,7 +144,7 @@ class OrderQueryParamsModel(BaseOrderingQueryModel):
77144
78145def test_ordering_query_model_class__fails_with_invalid_fields ():
79146
80- OrderQueryParamsModel = create_ordering_query_model_classes (
147+ OrderQueryParamsModel = create_ordering_query_model_class (
81148 ordering_fields = {"modified" , "name" , "description" },
82149 default = OrderBy (field = IDStr ("modified" ), direction = OrderDirection .DESC ),
83150 )
@@ -94,7 +161,7 @@ def test_ordering_query_model_class__fails_with_invalid_fields():
94161
95162
96163def test_ordering_query_model_class__fails_with_invalid_direction ():
97- OrderQueryParamsModel = create_ordering_query_model_classes (
164+ OrderQueryParamsModel = create_ordering_query_model_class (
98165 ordering_fields = {"modified" , "name" , "description" },
99166 default = OrderBy (field = IDStr ("modified" ), direction = OrderDirection .DESC ),
100167 )
@@ -112,7 +179,7 @@ def test_ordering_query_model_class__fails_with_invalid_direction():
112179
113180def test_ordering_query_model_class__defaults ():
114181
115- OrderQueryParamsModel = create_ordering_query_model_classes (
182+ OrderQueryParamsModel = create_ordering_query_model_class (
116183 ordering_fields = {"modified" , "name" , "description" },
117184 default = OrderBy (field = IDStr ("modified" ), direction = OrderDirection .DESC ),
118185 ordering_fields_api_to_column_map = {"modified" : "modified_at" },
@@ -142,7 +209,7 @@ def test_ordering_query_model_class__defaults():
142209
143210
144211def test_ordering_query_model_with_map ():
145- OrderQueryParamsModel = create_ordering_query_model_classes (
212+ OrderQueryParamsModel = create_ordering_query_model_class (
146213 ordering_fields = {"modified" , "name" , "description" },
147214 default = OrderBy (field = IDStr ("modified" ), direction = OrderDirection .DESC ),
148215 ordering_fields_api_to_column_map = {"modified" : "some_db_column_name" },
@@ -155,7 +222,7 @@ def test_ordering_query_model_with_map():
155222
156223def test_ordering_query_parse_json_pre_validator ():
157224
158- OrderQueryParamsModel = create_ordering_query_model_classes (
225+ OrderQueryParamsModel = create_ordering_query_model_class (
159226 ordering_fields = {"modified" , "name" },
160227 default = OrderBy (field = IDStr ("modified" ), direction = OrderDirection .DESC ),
161228 )
0 commit comments