diff --git a/go.mod b/go.mod index 5d34af91ac1a2..61fb3b0e83cee 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,6 @@ require ( github.com/pion/transport v0.13.0 github.com/pion/webrtc/v3 v3.1.23 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 - github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef github.com/quasilyte/go-ruleguard/dsl v0.3.17 github.com/spf13/cobra v1.3.0 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index ef0487b1afb51..5db435337eecd 100644 --- a/go.sum +++ b/go.sum @@ -1104,8 +1104,6 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef h1:NKxTG6GVGbfMXc2mIk+KphcH6hagbVXhcFkbTgYleTI= -github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef/go.mod h1:tcaRap0jS3eifrEEllL6ZMd9dg8IlDpi2S1oARrQ+NI= github.com/quasilyte/go-ruleguard/dsl v0.3.17 h1:L5xf3nifnRIdYe9vyMuY2sDnZHIgQol/fDq74FQz7ZY= github.com/quasilyte/go-ruleguard/dsl v0.3.17/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= diff --git a/site/nextrouter/nextrouter_test.go b/site/nextrouter/nextrouter_test.go index 96ebf3d7ef40b..8e0a807fe1bd2 100644 --- a/site/nextrouter/nextrouter_test.go +++ b/site/nextrouter/nextrouter_test.go @@ -6,8 +6,9 @@ import ( "net/http" "net/http/httptest" "testing" + "testing/fstest" + "time" - "github.com/psanford/memfs" "github.com/stretchr/testify/require" "cdr.dev/slog" @@ -20,311 +21,369 @@ func TestNextRouter(t *testing.T) { t.Run("Serves file at root", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.html", []byte("test123"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "test.html": &fstest.MapFile{ + Data: []byte("test123"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test.html") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test123") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.EqualValues(t, "test123", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) // This is a test case for the issue we hit in V1 w/ NextJS migration t.Run("Prefer file over folder w/ trailing slash", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("folder", 0777) - require.NoError(t, err) - err = rootFS.WriteFile("folder.html", []byte("folderFile"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "folder/test.html": &fstest.MapFile{}, + "folder.html": &fstest.MapFile{ + Data: []byte("folderFile"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/folder/") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "folderFile") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.EqualValues(t, "folderFile", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Serves non-html files at root", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.png", []byte("png-bytes"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "test.png": &fstest.MapFile{ + Data: []byte("png-bytes"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test.png") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, res.Header.Get("Content-Type"), "image/png") - require.Equal(t, string(body), "png-bytes") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.Equal(t, "image/png", res.Header.Get("Content-Type")) + require.EqualValues(t, "png-bytes", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Serves html file without extension", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.html", []byte("test-no-extension"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "test.html": &fstest.MapFile{ + Data: []byte("test-no-extension"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-no-extension") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.EqualValues(t, "test-no-extension", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Defaults to index.html at root", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("index.html", []byte("test-root-index"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "index.html": &fstest.MapFile{ + Data: []byte("test-root-index"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, res.Header.Get("Content-Type"), "text/html; charset=utf-8") - require.Equal(t, string(body), "test-root-index") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.Equal(t, "text/html; charset=utf-8", res.Header.Get("Content-Type")) + require.EqualValues(t, "test-root-index", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Serves nested file", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("test/a/b", 0777) - require.NoError(t, err) - - rootFS.WriteFile("test/a/b/c.html", []byte("test123"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "test/a/b/c.html": &fstest.MapFile{ + Data: []byte("test123"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test/a/b/c.html") require.NoError(t, err) - defer res.Body.Close() + require.NoError(t, res.Body.Close()) res, err = request(server, "/test/a/b/c.html") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test123") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.EqualValues(t, "test123", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("Uses index.html in nested path", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("test/a/b/c", 0777) - require.NoError(t, err) - - rootFS.WriteFile("test/a/b/c/index.html", []byte("test-abc-index"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "test/a/b/c/index.html": &fstest.MapFile{ + Data: []byte("test-abc-index"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test/a/b/c") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-abc-index") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + require.EqualValues(t, "test-abc-index", body) + require.Equal(t, http.StatusOK, res.StatusCode) }) t.Run("404 if file at root is not found", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.html", []byte("test123"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "test.html": &fstest.MapFile{ + Data: []byte("test123"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test-non-existent.html") require.NoError(t, err) - defer res.Body.Close() - require.Equal(t, res.StatusCode, 404) + require.NoError(t, res.Body.Close()) + require.Equal(t, http.StatusNotFound, res.StatusCode) }) t.Run("404 if file at root is not found", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.html", []byte("test123"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "test.html": &fstest.MapFile{ + Data: []byte("test123"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test-non-existent.html") require.NoError(t, err) - defer res.Body.Close() - require.Equal(t, res.StatusCode, 404) + require.NoError(t, res.Body.Close()) + require.Equal(t, http.StatusNotFound, res.StatusCode) }) t.Run("Serve custom 404.html if available", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("404.html", []byte("404 custom content"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "404.html": &fstest.MapFile{ + Data: []byte("404 custom content"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test-non-existent.html") require.NoError(t, err) - defer res.Body.Close() + body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, res.StatusCode, 404) - require.Equal(t, string(body), "404 custom content") + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusNotFound, res.StatusCode) + require.EqualValues(t, "404 custom content", body) }) t.Run("Serves dynamic-routed file", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("folder", 0777) - require.NoError(t, err) - err = rootFS.WriteFile("folder/[orgs].html", []byte("test-dynamic-path"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "folder/[orgs].html": &fstest.MapFile{ + Data: []byte("test-dynamic-path"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/folder/org-1") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-dynamic-path") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusOK, res.StatusCode) + require.EqualValues(t, "test-dynamic-path", body) }) t.Run("Handles dynamic-routed folders", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("folder/[org]/[project]", 0777) - require.NoError(t, err) - err = rootFS.WriteFile("folder/[org]/[project]/create.html", []byte("test-create"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "folder/[org]/[project]/create.html": &fstest.MapFile{ + Data: []byte("test-create"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/folder/org-1/project-1/create") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-create") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusOK, res.StatusCode) + require.EqualValues(t, "test-create", body) }) t.Run("Handles catch-all routes", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("folder", 0777) - require.NoError(t, err) - err = rootFS.WriteFile("folder/[[...any]].html", []byte("test-catch-all"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "folder/[[...any]].html": &fstest.MapFile{ + Data: []byte("test-catch-all"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/folder/org-1/project-1/random") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-catch-all") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusOK, res.StatusCode) + require.EqualValues(t, "test-catch-all", body) }) t.Run("Static routes should be preferred to dynamic routes", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.MkdirAll("folder", 0777) - require.NoError(t, err) - err = rootFS.WriteFile("folder/[orgs].html", []byte("test-dynamic-path"), 0755) - require.NoError(t, err) - err = rootFS.WriteFile("folder/create.html", []byte("test-create"), 0755) - require.NoError(t, err) + + rootFS := fstest.MapFS{ + "folder/[orgs].html": &fstest.MapFile{ + Data: []byte("test-dynamic-path"), + }, + "folder/create.html": &fstest.MapFile{ + Data: []byte("test-create"), + }, + } router, err := nextrouter.Handler(rootFS, nil) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/folder/create") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "test-create") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusOK, res.StatusCode) + require.EqualValues(t, "test-create", body) }) t.Run("Injects template parameters", func(t *testing.T) { t.Parallel() - rootFS := memfs.New() - err := rootFS.WriteFile("test.html", []byte("{{ .CSRF.Token }}"), 0755) - require.NoError(t, err) + rootFS := fstest.MapFS{ + "test.html": &fstest.MapFile{ + Data: []byte("{{ .CSRF.Token }}"), + }, + } type csrfState struct { Token string @@ -348,25 +407,32 @@ func TestNextRouter(t *testing.T) { TemplateDataFunc: templateFunc, }) require.NoError(t, err) + server := httptest.NewServer(router) + t.Cleanup(server.Close) res, err := request(server, "/test.html") require.NoError(t, err) - defer res.Body.Close() body, err := io.ReadAll(res.Body) require.NoError(t, err) - require.Equal(t, string(body), "hello-csrf") - require.Equal(t, res.StatusCode, 200) + require.NoError(t, res.Body.Close()) + + require.Equal(t, http.StatusOK, res.StatusCode) + require.EqualValues(t, "hello-csrf", body) }) } func request(server *httptest.Server, path string) (*http.Response, error) { - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, server.URL+path, nil) + ctx, cancelFunc := context.WithTimeout(context.Background(), 1*time.Second) + defer cancelFunc() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, server.URL+path, nil) if err != nil { return nil, err } - res, err := http.DefaultClient.Do(req) + + res, err := server.Client().Do(req) if err != nil { return nil, err }