33from django .conf import settings
44from django .core .cache import cache
55from django .test import TestCase , override_settings
6- from rest_framework .test import APIClient
6+ from rest_framework .response import Response
7+ from rest_framework .test import APIClient , APIRequestFactory
8+ from rest_framework .views import APIView
79
10+ from core .throttling import PostOnlyScopedRateThrottle
811from tests .constants import USER_CREATE_DATA
912from users .tests .helpers import build_user
1013
@@ -18,10 +21,22 @@ def throttle_settings(**rates):
1821 return rest_framework
1922
2023
24+ class DummyPostOnlyThrottleView (APIView ):
25+ throttle_classes = [PostOnlyScopedRateThrottle ]
26+ throttle_scope = "auth_register"
27+
28+ def get (self , _request ):
29+ return Response ({"ok" : True })
30+
31+ def post (self , _request ):
32+ return Response ({"ok" : True })
33+
34+
2135class AuthThrottleTests (TestCase ):
2236 def setUp (self ):
2337 cache .clear ()
2438 self .client = APIClient ()
39+ self .factory = APIRequestFactory ()
2540
2641 @override_settings (
2742 REST_FRAMEWORK = throttle_settings (auth_register = "1/min" )
@@ -118,3 +133,39 @@ def test_password_reset_request_post_is_scoped_throttled(self, _email_message):
118133
119134 self .assertNotEqual (first_response .status_code , 429 )
120135 self .assertEqual (second_response .status_code , 429 )
136+
137+ @override_settings (
138+ REST_FRAMEWORK = throttle_settings (auth_register = "1/min" )
139+ )
140+ def test_post_only_throttle_allows_get_and_options (self ):
141+ view = DummyPostOnlyThrottleView .as_view ()
142+
143+ for method in ("get" , "options" ):
144+ for _ in range (2 ):
145+ response = view (
146+ getattr (self .factory , method )(
147+ "/unused/" ,
148+ REMOTE_ADDR = "203.0.113.14" ,
149+ )
150+ )
151+ self .assertNotEqual (response .status_code , 429 )
152+
153+ first_response = view (
154+ self .factory .post (
155+ "/unused/" ,
156+ {},
157+ format = "json" ,
158+ REMOTE_ADDR = "203.0.113.14" ,
159+ )
160+ )
161+ second_response = view (
162+ self .factory .post (
163+ "/unused/" ,
164+ {},
165+ format = "json" ,
166+ REMOTE_ADDR = "203.0.113.14" ,
167+ )
168+ )
169+
170+ self .assertEqual (first_response .status_code , 200 )
171+ self .assertEqual (second_response .status_code , 429 )
0 commit comments