Skip to content

Commit 821865f

Browse files
committed
feat(urls): path for testing CSRF error handler
BaseErrorView needs to implement post to avoid a 405 Method Not Allowed and actually trigger the CSRF error handler
1 parent d167221 commit 821865f

3 files changed

Lines changed: 22 additions & 0 deletions

File tree

benefits/urls.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,19 @@ def trigger_404(request):
6565
def trigger_500(request):
6666
raise Exception("Test 500")
6767

68+
def trigger_csrf(request):
69+
if request.method == "POST":
70+
return HttpResponse("Should not reach here")
71+
return HttpResponse(
72+
"<html><body><form method='post' action='/testcsrf/'>"
73+
"<button type='submit'>Submit CSRF failure</button></form></body></html>"
74+
)
75+
6876
urlpatterns.append(path("test400/", trigger_400))
6977
urlpatterns.append(path("test403/", trigger_403))
7078
urlpatterns.append(path("test404/", trigger_404))
7179
urlpatterns.append(path("test500/", trigger_500))
80+
urlpatterns.append(path("testcsrf/", trigger_csrf))
7281

7382
if settings.RUNTIME_ENVIRONMENT() in (settings.RUNTIME_ENVS.LOCAL, settings.RUNTIME_ENVS.DEV):
7483
# simple route to read a pre-defined "secret"

benefits/views.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ def render_to_response(self, context, **response_kwargs):
3030
response_kwargs.setdefault("status", self.status_code)
3131
return super().render_to_response(context, **response_kwargs)
3232

33+
def post(self, request, *args, **kwargs):
34+
"""
35+
Handle POST requests by treating them as GET requests.
36+
This prevents 405 errors when error handlers are triggered
37+
by failed POST submissions (common with CSRF failures).
38+
"""
39+
return self.get(request, *args, **kwargs)
40+
3341

3442
class BadRequestView(BaseErrorView):
3543
"""View handler for HTTP 400 Bad Request responses."""

tests/pytest/test_views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ def test_render_to_response__injects_status(self, view):
6363
response = view.render_to_response({})
6464
assert response.status_code == 420
6565

66+
def test_post_is_get(self, view, app_request_post, mocker):
67+
spy = mocker.patch.object(view, "get")
68+
view.post(app_request_post)
69+
spy.assert_called_once()
70+
6671

6772
@pytest.mark.django_db
6873
class TestBadRequestView:

0 commit comments

Comments
 (0)