// +build go1.16
package middleware
import (
"io/fs"
"net/http"
"net/http/httptest"
"os"
"testing"
"testing/fstest"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
func TestStatic_CustomFS(t *testing.T) {
var testCases = []struct {
name string
filesystem fs.FS
root string
whenURL string
expectContains string
expectCode int
}{
{
name: "ok, serve index with Echo message",
whenURL: "/",
filesystem: os.DirFS("../_fixture"),
expectCode: http.StatusOK,
expectContains: "
Echo",
},
{
name: "ok, serve index with Echo message",
whenURL: "/_fixture/",
filesystem: os.DirFS(".."),
expectCode: http.StatusOK,
expectContains: "Echo",
},
{
name: "ok, serve file from map fs",
whenURL: "/file.txt",
filesystem: fstest.MapFS{
"file.txt": &fstest.MapFile{Data: []byte("file.txt is ok")},
},
expectCode: http.StatusOK,
expectContains: "file.txt is ok",
},
{
name: "nok, missing file in map fs",
whenURL: "/file.txt",
expectCode: http.StatusNotFound,
filesystem: fstest.MapFS{
"file2.txt": &fstest.MapFile{Data: []byte("file2.txt is ok")},
},
},
{
name: "nok, file is not a subpath of root",
whenURL: `/../../secret.txt`,
root: "/nested/folder",
filesystem: fstest.MapFS{
"secret.txt": &fstest.MapFile{Data: []byte("this is a secret")},
},
expectCode: http.StatusNotFound,
},
{
name: "nok, backslash is forbidden",
whenURL: `/..\..\secret.txt`,
expectCode: http.StatusNotFound,
root: "/nested/folder",
filesystem: fstest.MapFS{
"secret.txt": &fstest.MapFile{Data: []byte("this is a secret")},
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
e := echo.New()
config := StaticConfig{
Root: ".",
Filesystem: http.FS(tc.filesystem),
}
if tc.root != "" {
config.Root = tc.root
}
middlewareFunc := StaticWithConfig(config)
e.Use(middlewareFunc)
req := httptest.NewRequest(http.MethodGet, tc.whenURL, nil)
rec := httptest.NewRecorder()
e.ServeHTTP(rec, req)
assert.Equal(t, tc.expectCode, rec.Code)
if tc.expectContains != "" {
responseBody := rec.Body.String()
assert.Contains(t, responseBody, tc.expectContains)
}
})
}
}