From a27b879accb191b6a6c6e76a6251ed751967f73a Mon Sep 17 00:00:00 2001 From: tjpcc Date: Thu, 26 Jan 2023 16:22:58 -0700 Subject: test coverage and resulting bugfixes --- contrib/fs/dir_test.go | 130 ++++++++++++++++++++++++++++++ contrib/fs/file.go | 2 +- contrib/fs/file_test.go | 80 ++++++++++++++++++ contrib/fs/testdata/a/b | 1 + contrib/fs/testdata/a/c.html | 0 contrib/fs/testdata/d/index.gmi | 1 + gemini/gemtext/internal/templates_test.go | 15 ++++ logging/middleware.go | 1 + logging/middleware_test.go | 47 +++++++++++ 9 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 contrib/fs/dir_test.go create mode 100644 contrib/fs/file_test.go create mode 100644 contrib/fs/testdata/a/b create mode 100644 contrib/fs/testdata/a/c.html create mode 100644 contrib/fs/testdata/d/index.gmi create mode 100644 gemini/gemtext/internal/templates_test.go create mode 100644 logging/middleware_test.go diff --git a/contrib/fs/dir_test.go b/contrib/fs/dir_test.go new file mode 100644 index 0000000..c7492ff --- /dev/null +++ b/contrib/fs/dir_test.go @@ -0,0 +1,130 @@ +package fs_test + +import ( + "context" + "io" + "net/url" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "tildegit.org/tjp/gus" + "tildegit.org/tjp/gus/contrib/fs" + "tildegit.org/tjp/gus/gemini" +) + +func TestDirectoryDefault(t *testing.T) { + handler := fs.DirectoryDefault(os.DirFS("testdata"), "index.gmi") + + tests := []struct { + url string + status gus.Status + meta string + body string + }{ + { + url: "gemini://localhost/d", + status: gemini.StatusTemporaryRedirect, + meta: "gemini://localhost/d/", + }, + { + url: "gemini://localhost/d/", + status: gemini.StatusSuccess, + meta: "text/gemini", + body: "# This is d\n", + }, + { + url: "gemini://localhost/a/", + status: gemini.StatusNotFound, + }, + } + + for _, test := range tests { + t.Run(test.url, func(t *testing.T) { + u, err := url.Parse(test.url) + require.Nil(t, err) + + request := &gus.Request{URL: u} + response := handler(context.Background(), request) + + if response == nil { + assert.Equal(t, test.status, gemini.StatusNotFound) + return + } else { + assert.Equal(t, test.status, response.Status) + } + + if test.meta != "" { + assert.Equal(t, test.meta, response.Meta) + } + if test.body != "" { + body, err := io.ReadAll(response.Body) + require.Nil(t, err) + assert.Equal(t, test.body, string(body)) + } + }) + } +} + +func TestDirectoryListing(t *testing.T) { + handler := fs.DirectoryListing(os.DirFS("testdata"), nil) + + tests := []struct { + url string + status gus.Status + meta string + body string + }{ + { + url: "gemini://localhost/", + status: gemini.StatusSuccess, + meta: "text/gemini", + body: "# (root)\n\n=> a/\n=> d/\n=> ../\n", + }, + { + url: "gemini://localhost/d", + status: gemini.StatusTemporaryRedirect, + meta: "gemini://localhost/d/", + }, + { + url: "gemini://localhost/d/", + status: gemini.StatusSuccess, + meta: "text/gemini", + body: "# d\n\n=> index.gmi\n=> ../\n", + }, + { + url: "gemini://localhost/a/", + status: gemini.StatusSuccess, + meta: "text/gemini", + body: "# a\n\n=> b\n=> c.html\n=> ../\n", + }, + } + + for _, test := range tests { + t.Run(test.url, func(t *testing.T) { + u, err := url.Parse(test.url) + require.Nil(t, err) + + request := &gus.Request{URL: u} + response := handler(context.Background(), request) + + if response == nil { + assert.Equal(t, test.status, gemini.StatusNotFound) + return + } else { + assert.Equal(t, test.status, response.Status) + } + + if test.meta != "" { + assert.Equal(t, test.meta, response.Meta) + } + if test.body != "" { + body, err := io.ReadAll(response.Body) + require.Nil(t, err) + assert.Equal(t, test.body, string(body)) + } + }) + } +} diff --git a/contrib/fs/file.go b/contrib/fs/file.go index 8cb1aeb..71428ed 100644 --- a/contrib/fs/file.go +++ b/contrib/fs/file.go @@ -46,7 +46,7 @@ func mediaType(filePath string) string { if dotIdx == -1 { return "application/octet-stream" } - ext := filePath[slashIdx+dotIdx:] + ext := filePath[slashIdx+1+dotIdx:] mtype := mime.TypeByExtension(ext) if mtype == "" { diff --git a/contrib/fs/file_test.go b/contrib/fs/file_test.go new file mode 100644 index 0000000..4f371c7 --- /dev/null +++ b/contrib/fs/file_test.go @@ -0,0 +1,80 @@ +package fs_test + +import ( + "context" + "io" + "net/url" + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "tildegit.org/tjp/gus" + "tildegit.org/tjp/gus/contrib/fs" + "tildegit.org/tjp/gus/gemini" +) + +func TestFileHandler(t *testing.T) { + handler := fs.FileHandler(os.DirFS("testdata")) + + tests := []struct { + url string + status gus.Status + meta string + body string + }{ + { + url: "gemini://localhost/d", + status: gemini.StatusNotFound, + }, + { + url: "gemini://localhost/d/", + status: gemini.StatusNotFound, + }, + { + url: "gemini://localhost/d/index.gmi", + status: gemini.StatusSuccess, + meta: "text/gemini", + body: "# This is d\n", + }, + { + url: "gemini://localhost/a/b", + status: gemini.StatusSuccess, + meta: "application/octet-stream", + body: "this is file b\n", + }, + { + url: "gemini://localhost/a/c.html", + status: gemini.StatusSuccess, + meta: "text/html; charset=utf-8", + body: "", + }, + } + + for _, test := range tests { + t.Run(test.url, func(t *testing.T) { + u, err := url.Parse(test.url) + require.Nil(t, err) + + request := &gus.Request{URL: u} + response := handler(context.Background(), request) + + if response == nil { + assert.Equal(t, test.status, gemini.StatusNotFound) + return + } else { + assert.Equal(t, test.status, response.Status) + } + + if test.meta != "" { + assert.Equal(t, test.meta, response.Meta) + } + if test.body != "" { + body, err := io.ReadAll(response.Body) + require.Nil(t, err) + assert.Equal(t, test.body, string(body)) + } + }) + } +} diff --git a/contrib/fs/testdata/a/b b/contrib/fs/testdata/a/b new file mode 100644 index 0000000..77486f7 --- /dev/null +++ b/contrib/fs/testdata/a/b @@ -0,0 +1 @@ +this is file b diff --git a/contrib/fs/testdata/a/c.html b/contrib/fs/testdata/a/c.html new file mode 100644 index 0000000..e69de29 diff --git a/contrib/fs/testdata/d/index.gmi b/contrib/fs/testdata/d/index.gmi new file mode 100644 index 0000000..faf50cf --- /dev/null +++ b/contrib/fs/testdata/d/index.gmi @@ -0,0 +1 @@ +# This is d diff --git a/gemini/gemtext/internal/templates_test.go b/gemini/gemtext/internal/templates_test.go new file mode 100644 index 0000000..a5722fb --- /dev/null +++ b/gemini/gemtext/internal/templates_test.go @@ -0,0 +1,15 @@ +package internal_test + +import "testing" + +func TestAddAllTemplates(t *testing.T) { +} + +func TestAddHTMLTemplates(t *testing.T) { +} + +func TestValidateLinks(t *testing.T) { +} + +func TestRenderItems(t *testing.T) { +} diff --git a/logging/middleware.go b/logging/middleware.go index 01278e1..5527ce7 100644 --- a/logging/middleware.go +++ b/logging/middleware.go @@ -48,6 +48,7 @@ func (lr *loggedResponseBody) log() { func (lr *loggedResponseBody) Read(b []byte) (int, error) { if lr.body == nil { + lr.log() return 0, io.EOF } diff --git a/logging/middleware_test.go b/logging/middleware_test.go new file mode 100644 index 0000000..288c960 --- /dev/null +++ b/logging/middleware_test.go @@ -0,0 +1,47 @@ +package logging_test + +import ( + "context" + "io" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "tildegit.org/tjp/gus" + "tildegit.org/tjp/gus/logging" +) + +func TestLogRequests(t *testing.T) { + logger := logRecorder{} + handler := logging.LogRequests(&logger)(func(_ context.Context, _ *gus.Request) *gus.Response { + return &gus.Response{} + }) + + response := handler(context.Background(), &gus.Request{}) + _, err := io.ReadAll(response.Body) + assert.Nil(t, err) + + require.Equal(t, 1, len(logger)) + + keyvals := map[string]any{} + for i := 0; i < len(logger[0])-1; i += 2 { + keyvals[logger[0][i].(string)] = logger[0][i+1] + } + + if assert.Contains(t, keyvals, "msg") { + assert.Equal(t, keyvals["msg"], "request") + } + assert.Contains(t, keyvals, "ts") + assert.Contains(t, keyvals, "dur") + assert.Contains(t, keyvals, "url") + assert.Contains(t, keyvals, "status") + assert.Contains(t, keyvals, "bodylen") +} + +type logRecorder [][]any + +func (lr *logRecorder) Log(keyvals ...any) error { + *lr = append(*lr, keyvals) + return nil +} -- cgit v1.2.3