main
1package test
2
3import (
4 "fmt"
5 "io"
6 "net/http"
7 "strings"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12 "github.com/xlgmokha/x/pkg/context"
13 "github.com/xlgmokha/x/pkg/serde"
14 "github.com/xlgmokha/x/pkg/x"
15)
16
17var exampleHeader x.Option[*http.Request] = x.Option[*http.Request](func(r *http.Request) *http.Request {
18 r.Header.Add("X-Example", "example")
19 return r
20})
21
22var withHost x.Option[*http.Request] = x.Option[*http.Request](func(r *http.Request) *http.Request {
23 r.Host = "example.com"
24 return r
25})
26
27func TestRequest(t *testing.T) {
28 t.Run("without options", func(t *testing.T) {
29 r := Request("GET", "/example")
30
31 require.NotNil(t, r)
32 assert.Equal(t, "GET", r.Method)
33 assert.Equal(t, "/example", r.URL.Path)
34 assert.Zero(t, r.Body)
35 })
36
37 t.Run("with an option", func(t *testing.T) {
38 r := Request("GET", "/example", exampleHeader)
39
40 require.NotNil(t, r)
41 assert.Equal(t, "GET", r.Method)
42 assert.Equal(t, "/example", r.URL.Path)
43 assert.Zero(t, r.Body)
44 assert.Equal(t, "example", r.Header.Get("X-Example"))
45 })
46
47 t.Run("with options", func(t *testing.T) {
48 r := Request("GET", "/example", exampleHeader, withHost)
49
50 require.NotNil(t, r)
51 assert.Equal(t, "GET", r.Method)
52 assert.Equal(t, "/example", r.URL.Path)
53 assert.Zero(t, r.Body)
54 assert.Equal(t, "example", r.Header.Get("X-Example"))
55 assert.Equal(t, "example.com", r.Host)
56 })
57}
58
59func TestRequestResponse(t *testing.T) {
60 t.Run("without options", func(t *testing.T) {
61 r, w := RequestResponse("GET", "/health")
62
63 require.NotNil(t, r)
64 assert.Equal(t, "GET", r.Method)
65 assert.Equal(t, "/health", r.URL.Path)
66
67 require.NotNil(t, w)
68 })
69
70 t.Run("with options", func(t *testing.T) {
71 r, w := RequestResponse("GET", "/example", exampleHeader, withHost)
72
73 require.NotNil(t, r)
74 assert.Equal(t, "GET", r.Method)
75 assert.Equal(t, "/example", r.URL.Path)
76 assert.Zero(t, r.Body)
77 assert.Equal(t, "example", r.Header.Get("X-Example"))
78 assert.Equal(t, "example.com", r.Host)
79
80 require.NotNil(t, w)
81 })
82}
83
84func TestWithAcceptHeader(t *testing.T) {
85 t.Run("applies the Accept header", func(t *testing.T) {
86 r := Request("GET", "/example", WithAcceptHeader(serde.JSON))
87
88 require.NotNil(t, r)
89 assert.Equal(t, serde.JSON.String(), r.Header.Get("Accept"))
90 })
91}
92
93func TestWithRequestHeader(t *testing.T) {
94 t.Run("applies a header to the request", func(t *testing.T) {
95 r := Request("GET", "/example", WithRequestHeader("Via", "gtwy"))
96
97 require.NotNil(t, r)
98 assert.Equal(t, "gtwy", r.Header.Get("Via"))
99 })
100}
101
102func TestWithContentType(t *testing.T) {
103 type example struct {
104 ID int `json: "id" jsonapi:"primary,examples"`
105 Name string `json: "name" jsonapi:"attr,name"`
106 }
107 item := &example{ID: 1, Name: "example"}
108
109 tt := []serde.MediaType{serde.JSON, serde.YAML}
110 for _, mediaType := range tt {
111 t.Run(fmt.Sprintf("generates a %v request body", mediaType), func(t *testing.T) {
112 r := Request("GET", "/example", WithContentType(item, mediaType))
113 require.NotNil(t, r)
114
115 result, err := serde.From[example](r.Body, mediaType)
116 require.NoError(t, err)
117 assert.Equal(t, 1, result.ID)
118 assert.Equal(t, "example", result.Name)
119 })
120 }
121}
122
123func TestWithRequestBody(t *testing.T) {
124 t.Run("applies the io to the request body", func(t *testing.T) {
125 body := io.NopCloser(strings.NewReader("example"))
126 r := Request("GET", "/example", WithRequestBody(body))
127
128 require.NotNil(t, r)
129
130 b, err := io.ReadAll(r.Body)
131 require.NoError(t, err)
132 assert.Equal(t, "example", string(b))
133 })
134}
135
136func TestWithContext(t *testing.T) {
137 t.Run("returns a request with a new context", func(t *testing.T) {
138 key := context.Key[string]("x")
139
140 ctx := key.With(t.Context(), "example")
141 r := Request("GET", "/example", WithContext(ctx))
142
143 require.NotNil(t, r)
144 assert.Equal(t, "example", key.From(r.Context()))
145 })
146}
147
148func TestWithContextKeyValue(t *testing.T) {
149 t.Run("returns a request with a new context", func(t *testing.T) {
150 key := context.Key[string]("x")
151
152 r := Request("GET", "/example", WithContextKeyValue(t.Context(), key, "example"))
153
154 require.NotNil(t, r)
155 assert.Equal(t, "example", key.From(r.Context()))
156 })
157}
158
159func TestWithCookie(t *testing.T) {
160 t.Run("adds a cookie to the request", func(t *testing.T) {
161 r := Request("GET", "/example", WithCookie(&http.Cookie{Name: "example", Value: "value"}))
162
163 require.NotNil(t, r)
164 result, err := r.Cookie("example")
165 require.NoError(t, err)
166
167 assert.Equal(t, "example", result.Name)
168 assert.Equal(t, "value", result.Value)
169 })
170}