Skip to content

Commit 8138f0a

Browse files
authored
feat: use HTTP 405 responses for existing routes that don’t support a method (#74)
1 parent 027fa2e commit 8138f0a

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

internal/controllers/main_list_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,23 @@ func TestGetOverview(t *testing.T) {
2525
assert.JSONEq(t, tt.expected, recorder.Body.String())
2626
}
2727
}
28+
29+
var methodNotAllowedTests = []struct {
30+
path string
31+
method string
32+
}{
33+
{"/", "POST"},
34+
{"/", "DELETE"},
35+
{"/v1", "POST"},
36+
{"/v1", "DELETE"},
37+
{"/v1/budgets", "HEAD"},
38+
{"/v1/budgets", "PUT"},
39+
}
40+
41+
func TestMethodNotAllowed(t *testing.T) {
42+
for _, tt := range methodNotAllowedTests {
43+
recorder := test.Request(t, tt.method, tt.path, "")
44+
45+
test.AssertHTTPStatus(t, http.StatusMethodNotAllowed, &recorder, tt.path, tt.method)
46+
}
47+
}

internal/controllers/routing.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ func Router() (*gin.Engine, error) {
2626
// client IPs
2727
r.ForwardedByClientIP = false
2828

29+
// Send a HTTP 405 (Method not allowed) for all paths where there is
30+
// a handler, but not for the specific method used
31+
r.HandleMethodNotAllowed = true
32+
2933
r.Use(gin.Recovery())
3034
r.Use(requestid.New())
3135
r.Use(logger.SetLogger(

internal/test/helpers.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"net/http"
66
"net/http/httptest"
7+
"strings"
78
"testing"
89
"time"
910

@@ -45,6 +46,6 @@ func Request(t *testing.T, method, url, body string, headers ...map[string]strin
4546
return *recorder
4647
}
4748

48-
func AssertHTTPStatus(t *testing.T, expected int, r *httptest.ResponseRecorder) {
49-
assert.Equal(t, expected, r.Code, "Status is '%v', body is '%v'", r.Code, r.Body.String())
49+
func AssertHTTPStatus(t *testing.T, expected int, r *httptest.ResponseRecorder, args ...string) {
50+
assert.Equal(t, expected, r.Code, "Status is '%v', body is '%v'. Additional context: %v", r.Code, r.Body.String(), strings.Join(args, " "))
5051
}

0 commit comments

Comments
 (0)