@@ -204,6 +204,124 @@ def view(request):
204204
205205 assert isinstance (view .cls .schema , CustomSchema )
206206
207+ def test_incorrect_decorator_order_permission_classes (self ):
208+ """
209+ If @permission_classes is applied after @api_view, we should raise a TypeError.
210+ """
211+ with self .assertRaises (TypeError ) as cm :
212+ @permission_classes ([IsAuthenticated ])
213+ @api_view (['GET' ])
214+ def view (request ):
215+ return Response ({})
216+
217+ assert '@permission_classes must be applied before @api_view' in str (cm .exception )
218+
219+ def test_incorrect_decorator_order_renderer_classes (self ):
220+ """
221+ If @renderer_classes is applied after @api_view, we should raise a TypeError.
222+ """
223+ with self .assertRaises (TypeError ) as cm :
224+ @renderer_classes ([JSONRenderer ])
225+ @api_view (['GET' ])
226+ def view (request ):
227+ return Response ({})
228+
229+ assert '@renderer_classes must be applied before @api_view' in str (cm .exception )
230+
231+ def test_incorrect_decorator_order_parser_classes (self ):
232+ """
233+ If @parser_classes is applied after @api_view, we should raise a TypeError.
234+ """
235+ with self .assertRaises (TypeError ) as cm :
236+ @parser_classes ([JSONParser ])
237+ @api_view (['GET' ])
238+ def view (request ):
239+ return Response ({})
240+
241+ assert '@parser_classes must be applied before @api_view' in str (cm .exception )
242+
243+ def test_incorrect_decorator_order_authentication_classes (self ):
244+ """
245+ If @authentication_classes is applied after @api_view, we should raise a TypeError.
246+ """
247+ with self .assertRaises (TypeError ) as cm :
248+ @authentication_classes ([BasicAuthentication ])
249+ @api_view (['GET' ])
250+ def view (request ):
251+ return Response ({})
252+
253+ assert '@authentication_classes must be applied before @api_view' in str (cm .exception )
254+
255+ def test_incorrect_decorator_order_throttle_classes (self ):
256+ """
257+ If @throttle_classes is applied after @api_view, we should raise a TypeError.
258+ """
259+ class OncePerDayUserThrottle (UserRateThrottle ):
260+ rate = '1/day'
261+
262+ with self .assertRaises (TypeError ) as cm :
263+ @throttle_classes ([OncePerDayUserThrottle ])
264+ @api_view (['GET' ])
265+ def view (request ):
266+ return Response ({})
267+
268+ assert '@throttle_classes must be applied before @api_view' in str (cm .exception )
269+
270+ def test_incorrect_decorator_order_versioning_class (self ):
271+ """
272+ If @versioning_class is applied after @api_view, we should raise a TypeError.
273+ """
274+ with self .assertRaises (TypeError ) as cm :
275+ @versioning_class (QueryParameterVersioning )
276+ @api_view (['GET' ])
277+ def view (request ):
278+ return Response ({})
279+
280+ assert '@versioning_class must be applied before @api_view' in str (cm .exception )
281+
282+ def test_incorrect_decorator_order_metadata_class (self ):
283+ """
284+ If @metadata_class is applied after @api_view, we should raise a TypeError.
285+ """
286+ with self .assertRaises (TypeError ) as cm :
287+ @metadata_class (None )
288+ @api_view (['GET' ])
289+ def view (request ):
290+ return Response ({})
291+
292+ assert '@metadata_class must be applied before @api_view' in str (cm .exception )
293+
294+ def test_incorrect_decorator_order_content_negotiation_class (self ):
295+ """
296+ If @content_negotiation_class is applied after @api_view, we should raise a TypeError.
297+ """
298+ class CustomContentNegotiation (BaseContentNegotiation ):
299+ def select_renderer (self , request , renderers , format_suffix ):
300+ return (renderers [0 ], renderers [0 ].media_type )
301+
302+ with self .assertRaises (TypeError ) as cm :
303+ @content_negotiation_class (CustomContentNegotiation )
304+ @api_view (['GET' ])
305+ def view (request ):
306+ return Response ({})
307+
308+ assert '@content_negotiation_class must be applied before @api_view' in str (cm .exception )
309+
310+ def test_incorrect_decorator_order_schema (self ):
311+ """
312+ If @schema is applied after @api_view, we should raise a TypeError.
313+ """
314+ class CustomSchema (AutoSchema ):
315+ pass
316+
317+ with self .assertRaises (TypeError ) as cm :
318+ @schema (CustomSchema ())
319+ @api_view (['GET' ])
320+ def view (request ):
321+ return Response ({})
322+
323+ assert '@schema must be applied before @api_view' in str (cm .exception )
324+
207325
208326class ActionDecoratorTestCase (TestCase ):
209327
0 commit comments