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}