goyave.dev/goyave/v5@v5.0.0-rc9.0.20240517145003-d3f977d0b9f3/util/testutil/testutil_test.go (about) 1 package testutil 2 3 import ( 4 "bytes" 5 "io" 6 "mime/multipart" 7 "net/http" 8 "net/http/httptest" 9 "net/textproto" 10 "path" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 "goyave.dev/goyave/v5" 16 "goyave.dev/goyave/v5/config" 17 "goyave.dev/goyave/v5/slog" 18 "goyave.dev/goyave/v5/util/fsutil" 19 "goyave.dev/goyave/v5/util/fsutil/osfs" 20 ) 21 22 type extraKey struct{} 23 24 type testMiddleware struct { 25 goyave.Component 26 procedure goyave.Handler 27 } 28 29 func (m *testMiddleware) Handle(_ goyave.Handler) goyave.Handler { 30 return m.procedure 31 } 32 33 func TestTestServer(t *testing.T) { 34 35 t.Run("NewTestServer", func(t *testing.T) { 36 server := NewTestServer(t, "resources/custom_config.json") 37 assert.Equal(t, "value", server.Config().Get("custom-entry")) 38 assert.Equal(t, slog.New(slog.NewHandler(true, &LogWriter{t: t})), server.Logger) 39 }) 40 41 t.Run("NewTestServerWithOptions", func(t *testing.T) { 42 cfg := config.LoadDefault() 43 cfg.Set("test-entry", "test-value") 44 45 server := NewTestServerWithOptions(t, goyave.Options{Config: cfg}) 46 47 assert.NotNil(t, server.Lang) 48 assert.Equal(t, "test-value", server.Config().Get("test-entry")) 49 assert.Equal(t, slog.New(slog.NewHandler(true, &LogWriter{t: t})), server.Logger) 50 }) 51 52 t.Run("NewTestServer_AutoConfig", func(t *testing.T) { 53 t.Setenv("GOYAVE_ENV", "test") 54 server := NewTestServerWithOptions(t, goyave.Options{}) 55 56 assert.NotNil(t, server.Lang) 57 assert.Equal(t, "test-value", server.Config().Get("test-entry")) 58 59 assert.Panics(t, func() { 60 // Config file not found 61 t.Setenv("GOYAVE_ENV", "") 62 NewTestServerWithOptions(t, goyave.Options{}) 63 }) 64 }) 65 66 t.Run("TestRequest", func(t *testing.T) { 67 server := NewTestServerWithOptions(t, goyave.Options{Config: config.LoadDefault()}) 68 server.RegisterRoutes(func(_ *goyave.Server, r *goyave.Router) { 69 r.Get("/route", func(resp *goyave.Response, _ *goyave.Request) { 70 resp.String(http.StatusOK, "OK") 71 }) 72 }) 73 74 resp := server.TestRequest(httptest.NewRequest(http.MethodGet, "/route", nil)) 75 assert.Equal(t, http.StatusOK, resp.StatusCode) 76 respBody, err := io.ReadAll(resp.Body) 77 require.NoError(t, resp.Body.Close()) 78 require.NoError(t, err) 79 assert.Equal(t, "OK", string(respBody)) 80 }) 81 82 t.Run("TestMiddleware", func(t *testing.T) { 83 server := NewTestServerWithOptions(t, goyave.Options{Config: config.LoadDefault()}) 84 85 request := server.NewTestRequest(http.MethodGet, "/route", nil) 86 request.Data = map[string]any{"key": "value"} 87 request.Extra = map[any]any{extraKey{}: "value"} 88 request.Query = map[string]any{"key": "value"} 89 request.RouteParams = map[string]string{"key": "value"} 90 request.User = map[string]string{"key": "value"} 91 92 middleware := &testMiddleware{ 93 procedure: func(resp *goyave.Response, req *goyave.Request) { 94 assert.Equal(t, request.Now, req.Now) 95 assert.Equal(t, request.Data, req.Data) 96 assert.Equal(t, request.Extra, req.Extra) 97 assert.Equal(t, request.Lang, req.Lang) 98 assert.Equal(t, request.Query, req.Query) 99 assert.Equal(t, request.RouteParams, req.RouteParams) 100 assert.Equal(t, request.User, req.User) 101 resp.String(http.StatusOK, "OK") 102 }, 103 } 104 105 resp := server.TestMiddleware(middleware, request, func(response *goyave.Response, _ *goyave.Request) { 106 response.Status(http.StatusBadRequest) 107 }) 108 assert.Equal(t, http.StatusOK, resp.StatusCode) 109 respBody, err := io.ReadAll(resp.Body) 110 require.NoError(t, resp.Body.Close()) 111 require.NoError(t, err) 112 assert.Equal(t, "OK", string(respBody)) 113 }) 114 115 t.Run("NewTestRequest", func(t *testing.T) { 116 server := NewTestServerWithOptions(t, goyave.Options{Config: config.LoadDefault()}) 117 body := bytes.NewBufferString("body") 118 req := server.NewTestRequest(http.MethodPost, "/uri", body) 119 120 assert.Equal(t, http.MethodPost, req.Method()) 121 assert.Equal(t, "/uri", req.URL().String()) 122 assert.NotNil(t, req.Extra) 123 124 b, err := io.ReadAll(req.Body()) 125 require.NoError(t, err) 126 assert.Equal(t, "body", string(b)) 127 assert.Equal(t, server.Lang.GetDefault(), req.Lang) 128 }) 129 130 t.Run("NewTestResponse", func(t *testing.T) { 131 server := NewTestServerWithOptions(t, goyave.Options{Config: config.LoadDefault(), Logger: slog.New(slog.NewHandler(false, &bytes.Buffer{}))}) 132 req := server.NewTestRequest(http.MethodGet, "/uri", nil) 133 resp, recorder := server.NewTestResponse(req) 134 135 resp.String(http.StatusOK, "hello") 136 result := recorder.Result() 137 b, err := io.ReadAll(result.Body) 138 require.NoError(t, result.Body.Close()) 139 require.NoError(t, err) 140 assert.Equal(t, "hello", string(b)) 141 assert.NotPanics(t, func() { 142 // No panics because the server is accessible so the ErrLogger.Println succeeds 143 resp.Error(nil) 144 }) 145 }) 146 } 147 148 func TestFindRootDirectory(t *testing.T) { 149 dir := FindRootDirectory() 150 assert.True(t, fsutil.FileExists(&osfs.FS{}, path.Join(dir, "go.mod"))) 151 } 152 153 func TestNewTestRequest(t *testing.T) { 154 body := bytes.NewBufferString("body") 155 req := NewTestRequest(http.MethodPost, "/uri", body) 156 157 assert.Equal(t, http.MethodPost, req.Method()) 158 assert.Equal(t, "/uri", req.URL().String()) 159 assert.NotNil(t, req.Extra) 160 161 b, err := io.ReadAll(req.Body()) 162 require.NoError(t, err) 163 assert.Equal(t, "body", string(b)) 164 165 } 166 167 func TestNewTestResponse(t *testing.T) { 168 req := NewTestRequest(http.MethodGet, "/uri", nil) 169 resp, recorder := NewTestResponse(req) 170 171 resp.String(http.StatusOK, "hello") 172 result := recorder.Result() 173 b, err := io.ReadAll(result.Body) 174 require.NoError(t, result.Body.Close()) 175 require.NoError(t, err) 176 assert.Equal(t, "hello", string(b)) 177 } 178 179 func TestReadJSONBody(t *testing.T) { 180 body := bytes.NewBufferString(`{"key":"value"}`) 181 jsonBody, err := ReadJSONBody[map[string]string](body) 182 require.NoError(t, err) 183 assert.Equal(t, map[string]string{"key": "value"}, jsonBody) 184 185 jsonBodyError, err := ReadJSONBody[string](body) 186 require.Error(t, err) 187 assert.Empty(t, jsonBodyError) 188 } 189 190 func TestWriteMultipartFile(t *testing.T) { 191 body := &bytes.Buffer{} 192 writer := multipart.NewWriter(body) 193 require.NoError(t, WriteMultipartFile(writer, &osfs.FS{}, "../../resources/img/logo/goyave_16.png", "profile_picture", "goyave_16.png")) 194 require.NoError(t, writer.Close()) 195 196 req := NewTestRequest(http.MethodPost, "/uri", body) 197 req.Header().Set("Content-Type", writer.FormDataContentType()) 198 require.NoError(t, req.Request().ParseMultipartForm(1024*1024*1024)) 199 200 files := req.Request().MultipartForm.File 201 require.Len(t, files, 1) 202 require.Contains(t, files, "profile_picture") 203 204 file := files["profile_picture"] 205 require.Len(t, file, 1) 206 assert.Equal(t, "goyave_16.png", file[0].Filename) 207 assert.Equal(t, int64(716), file[0].Size) 208 assert.Equal(t, textproto.MIMEHeader{"Content-Type": []string{"application/octet-stream"}, "Content-Disposition": []string{"form-data; name=\"profile_picture\"; filename=\"goyave_16.png\""}}, file[0].Header) 209 } 210 211 func TestCreateTestFiles(t *testing.T) { 212 files, err := CreateTestFiles(&osfs.FS{}, "../../resources/img/logo/goyave_16.png", "../../resources/test_file.txt") 213 require.NoError(t, err) 214 require.Len(t, files, 2) 215 216 assert.Equal(t, "goyave_16.png", files[0].Header.Filename) 217 assert.Equal(t, int64(716), files[0].Header.Size) 218 assert.Equal(t, textproto.MIMEHeader{"Content-Type": []string{"application/octet-stream"}, "Content-Disposition": []string{"form-data; name=\"file\"; filename=\"goyave_16.png\""}}, files[0].Header.Header) 219 220 assert.Equal(t, "test_file.txt", files[1].Header.Filename) 221 assert.Equal(t, int64(25), files[1].Header.Size) 222 assert.Equal(t, textproto.MIMEHeader{"Content-Type": []string{"application/octet-stream"}, "Content-Disposition": []string{"form-data; name=\"file\"; filename=\"test_file.txt\""}}, files[1].Header.Header) 223 224 } 225 226 func TestToJSON(t *testing.T) { 227 reader := ToJSON(map[string]any{"key": "value"}) 228 result, err := io.ReadAll(reader) 229 require.NoError(t, err) 230 assert.Equal(t, `{"key":"value"}`, string(result)) 231 232 assert.Panics(t, func() { 233 ToJSON(make(chan struct{})) 234 }) 235 }