-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrequest_decode_test.go
More file actions
101 lines (89 loc) · 3.23 KB
/
request_decode_test.go
File metadata and controls
101 lines (89 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package httpsuite
import (
"bytes"
"errors"
"net/http"
"net/http/httptest"
"testing"
)
func TestDecodeRequestBody(t *testing.T) {
t.Parallel()
t.Run("nil request", func(t *testing.T) {
_, err := DecodeRequestBody[*testRequest](nil, defaultMaxBodyBytes)
if !errors.Is(err, errNilHTTPRequest) {
t.Fatalf("expected nil request error, got %v", err)
}
})
t.Run("nil body", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", nil)
req.Body = nil
_, err := DecodeRequestBody[*testRequest](req, defaultMaxBodyBytes)
if !errors.Is(err, errNilRequestBody) {
t.Fatalf("expected nil body error, got %v", err)
}
})
t.Run("valid body", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(`{"id":42,"name":"OnlyBody"}`))
got, err := DecodeRequestBody[*testRequest](req, defaultMaxBodyBytes)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if got == nil || got.ID != 42 || got.Name != "OnlyBody" {
t.Fatalf("unexpected decoded request: %#v", got)
}
})
t.Run("invalid json", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(`{invalid-json}`))
_, err := DecodeRequestBody[*testRequest](req, defaultMaxBodyBytes)
var decodeErr *BodyDecodeError
if !errors.As(err, &decodeErr) {
t.Fatalf("expected BodyDecodeError, got %v", err)
}
if decodeErr.Kind != BodyDecodeErrorInvalidJSON {
t.Fatalf("expected invalid json error, got %s", decodeErr.Kind)
}
})
t.Run("body too large", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(`{"name":"TooLarge"}`))
_, err := DecodeRequestBody[*testRequest](req, 8)
var decodeErr *BodyDecodeError
if !errors.As(err, &decodeErr) {
t.Fatalf("expected BodyDecodeError, got %v", err)
}
if decodeErr.Kind != BodyDecodeErrorBodyTooLarge {
t.Fatalf("expected body too large error, got %s", decodeErr.Kind)
}
})
t.Run("multiple json documents", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(`{"id":1}{"id":2}`))
_, err := DecodeRequestBody[*testRequest](req, defaultMaxBodyBytes)
var decodeErr *BodyDecodeError
if !errors.As(err, &decodeErr) {
t.Fatalf("expected BodyDecodeError, got %v", err)
}
if decodeErr.Kind != BodyDecodeErrorMultipleDocuments {
t.Fatalf("expected multiple documents error, got %s", decodeErr.Kind)
}
})
t.Run("trailing decode body too large", func(t *testing.T) {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewBufferString(`{} {"name":"trailing"}`))
_, err := DecodeRequestBody[*testRequest](req, 3)
var decodeErr *BodyDecodeError
if !errors.As(err, &decodeErr) {
t.Fatalf("expected BodyDecodeError, got %v", err)
}
if decodeErr.Kind != BodyDecodeErrorBodyTooLarge {
t.Fatalf("expected body too large error, got %s", decodeErr.Kind)
}
})
}
func BenchmarkParseRequestBody(b *testing.B) {
body := []byte(`{"id":42,"name":"OnlyBody"}`)
b.ReportAllocs()
for i := 0; i < b.N; i++ {
req := httptest.NewRequest(http.MethodPost, "/test", bytes.NewReader(body))
if _, err := DecodeRequestBody[*testRequest](req, defaultMaxBodyBytes); err != nil {
b.Fatalf("unexpected error: %v", err)
}
}
}