77from furl import furl
88from rest_framework import status
99from rest_framework .test import APITestCase
10+ from vng_api_common .tests import get_validation_errors
1011
1112from objects .core .tests .factories import (
1213 ObjectFactory ,
@@ -66,7 +67,11 @@ def test_filter_invalid_objecttype(self):
6667 response = self .client .get (self .url , {"type" : "invalid-objecttype-url" })
6768
6869 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
69- self .assertEqual (response .json ()["type" ], ["Invalid value." ])
70+
71+ error = get_validation_errors (response , "type" )
72+
73+ self .assertEqual (error ["reason" ], "Invalid value." )
74+ self .assertEqual (error ["code" ], "invalid" )
7075
7176 def test_filter_unknown_objecttype (self ):
7277 objecttype_url = (
@@ -75,19 +80,30 @@ def test_filter_unknown_objecttype(self):
7580 response = self .client .get (self .url , {"type" : objecttype_url })
7681
7782 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
83+
84+ error = get_validation_errors (response , "type" )
85+
7886 self .assertEqual (
79- response .json ()["type" ],
80- [
81- f"Select a valid object type. { objecttype_url } is not one of the available choices."
82- ],
87+ error ,
88+ {
89+ "name" : "type" ,
90+ "code" : "invalid_choice" ,
91+ "reason" : (
92+ f"Select a valid object type. { objecttype_url } is not one of the available choices."
93+ ),
94+ },
8395 )
8496
8597 def test_filter_too_long_object_type (self ):
8698 object_type_long = f"{ OBJECT_TYPES_API } { 'a' * 1000 } /{ self .object_type .uuid } "
8799 response = self .client .get (self .url , {"type" : object_type_long })
88100
89101 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
90- self .assertEqual (response .json ()["type" ], ["The value has too many characters" ])
102+
103+ error = get_validation_errors (response , "type" )
104+
105+ self .assertEqual (error ["code" ], "max_length" )
106+ self .assertEqual (error ["reason" ], "The value has too many characters" )
91107
92108
93109class FilterDataAttrsTests (TokenAuthMixin , APITestCase ):
@@ -218,8 +234,12 @@ def test_filter_lte_not_numerical(self):
218234 response = self .client .get (self .url , {"data_attrs" : "diameter__lt__value" })
219235
220236 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
237+
238+ error = get_validation_errors (response , "" )
239+
221240 self .assertEqual (
222- response .json (), ["Operator `lt` supports only dates and/or numeric values" ]
241+ error ["reason" ],
242+ "Operator `lt` supports only dates and/or numeric values" ,
223243 )
224244
225245 def test_filter_lte_date (self ):
@@ -255,20 +275,27 @@ def test_filter_lte_date(self):
255275
256276 def test_filter_invalid_operator (self ):
257277 response = self .client .get (self .url , {"data_attrs" : "diameter__not__value" })
258-
259278 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
260- self .assertEqual (response .json (), ["Comparison operator `not` is unknown" ])
279+
280+ error = get_validation_errors (response , "" )
281+
282+ self .assertEqual (
283+ error ["reason" ],
284+ "Comparison operator `not` is unknown" ,
285+ )
286+ self .assertEqual (error ["code" ], "invalid-data-attrs-query" )
261287
262288 def test_filter_invalid_param (self ):
263289 response = self .client .get (self .url , {"data_attrs" : "diameter__exact" })
264-
265290 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
291+
292+ error = get_validation_errors (response , "" )
293+
266294 self .assertEqual (
267- response .json (),
268- [
269- "Filter expression 'diameter__exact' doesn't have the shape 'key__operator__value'"
270- ],
295+ error ["reason" ],
296+ "Filter expression 'diameter__exact' doesn't have the shape 'key__operator__value'" ,
271297 )
298+ self .assertEqual (error ["code" ], "invalid-data-attrs-query" )
272299
273300 def test_filter_nested_attr (self ):
274301 record = ObjectRecordFactory .create (
@@ -570,8 +597,11 @@ def test_filter_lte_not_numerical(self):
570597 response = self .client .get (self .url , {"data_attr" : "diameter__lt__value" })
571598
572599 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
573- self .assertEqual (
574- response .json (), ["Operator `lt` supports only dates and/or numeric values" ]
600+
601+ error = get_validation_errors (response , "" )
602+
603+ self .assertIn (
604+ "Operator `lt` supports only dates and/or numeric values" , error ["reason" ]
575605 )
576606
577607 def test_filter_lte_date (self ):
@@ -609,17 +639,24 @@ def test_filter_invalid_operator(self):
609639 response = self .client .get (self .url , {"data_attr" : "diameter__not__value" })
610640
611641 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
612- self .assertEqual (response .json (), ["Comparison operator `not` is unknown" ])
642+
643+ error = get_validation_errors (response , "" )
644+
645+ self .assertEqual (
646+ error ["reason" ],
647+ "Comparison operator `not` is unknown" ,
648+ )
613649
614650 def test_filter_invalid_param (self ):
615651 response = self .client .get (self .url , {"data_attr" : "diameter__exact" })
616652
617653 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
654+
655+ error = get_validation_errors (response , "" )
656+
618657 self .assertEqual (
619- response .json (),
620- [
621- "Filter expression 'diameter__exact' doesn't have the shape 'key__operator__value'"
622- ],
658+ error ["reason" ],
659+ "Filter expression 'diameter__exact' doesn't have the shape 'key__operator__value'" ,
623660 )
624661
625662 def test_filter_nested_attr (self ):
@@ -819,18 +856,21 @@ def test_filter_two_icontains_with_comma(self):
819856
820857 def test_filter_comma_separated_invalid (self ):
821858 response = self .client .get (
822- self .url , {"data_attr" : "dimensions__diameter__exact__4,name__exact__demo" }
859+ self .url ,
860+ {"data_attr" : "dimensions__diameter__exact__4,name__exact__demo" },
823861 )
824862
825863 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
864+
865+ error = get_validation_errors (response , "" )
866+
826867 self .assertEqual (
827- response .json (),
828- [
829- "Filter expression 'dimensions__diameter__exact__4,name__exact__demo' "
830- "must have the shape 'key__operator__value', commas can only be present in "
831- "the 'value'"
832- ],
868+ error ["reason" ],
869+ "Filter expression 'dimensions__diameter__exact__4,name__exact__demo' "
870+ "must have the shape 'key__operator__value', commas can only be present in "
871+ "the 'value'" ,
833872 )
873+ self .assertEqual (error ["code" ], "invalid-data-attr-query" )
834874
835875
836876class FilterDateTests (TokenAuthMixin , APITestCase ):
@@ -941,6 +981,8 @@ def test_filter_registration_date_list(self):
941981
942982 response = self .client .get (url , {"registrationDate" : "2020-07-01" })
943983
984+ self .assertEqual (response .status_code , status .HTTP_200_OK )
985+
944986 data = response .json ()["results" ]
945987
946988 self .assertEqual (len (data ), 1 )
@@ -952,17 +994,18 @@ def test_filter_registration_date_list(self):
952994
953995 def test_filter_on_both_date_and_registration_date (self ):
954996 url = reverse_lazy ("object-list" )
955-
956997 response = self .client .get (
957- url , {"date" : "2020-07-01" , "registrationDate" : "2020-08-01" }
998+ url ,
999+ {"date" : "2020-07-01" , "registrationDate" : "2020-08-01" },
9581000 )
9591001
9601002 self .assertEqual (response .status_code , status .HTTP_400_BAD_REQUEST )
1003+
1004+ data = response .json ()
1005+
9611006 self .assertEqual (
962- response .json (),
963- [
964- "'date' and 'registrationDate' parameters can't be used in the same request"
965- ],
1007+ data ["invalid_params" ][0 ]["reason" ],
1008+ "'date' and 'registrationDate' parameters can't be used in the same request" ,
9661009 )
9671010
9681011
@@ -1033,13 +1076,19 @@ def test_filter_db_error(self, mock_query):
10331076 response = self .client .get (self .url , {"data_icontains" : "some" })
10341077
10351078 self .assertEqual (response .status_code , status .HTTP_500_INTERNAL_SERVER_ERROR )
1079+
1080+ data = response .json ()
1081+
1082+ data .pop ("instance" , None )
1083+
10361084 self .assertEqual (
1037- response . json () ,
1085+ data ,
10381086 {
1039- "code" : "error " ,
1087+ "code" : "search-not-supported " ,
10401088 "title" : "Internal Server Error" ,
10411089 "status" : 500 ,
10421090 "detail" : "This search operation is not supported by the underlying data store." ,
1091+ "type" : "http://testserver/ref/fouten/ProgrammingError/" ,
10431092 },
10441093 )
10451094
0 commit comments