[release-11.4.6]: Add static tests (#106132)

pull/106182/head
Sofia Papagiannaki 1 month ago committed by GitHub
parent 316ea68268
commit 2edf712e9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 179
      pkg/api/static/static_test.go

@ -0,0 +1,179 @@
package httpstatic
import (
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"github.com/grafana/authlib/claims"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/models/usertoken"
"github.com/grafana/grafana/pkg/services/authn"
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestStatic(t *testing.T) {
// Create a temporary directory for test files
tmpDir, err := os.MkdirTemp("", "static-test")
require.NoError(t, err)
defer func() {
err := os.RemoveAll(tmpDir)
require.NoError(t, err)
}()
// Create test files
testFiles := map[string]string{
"test.txt": "Test content",
"subdir/test.txt": "Subdir content",
}
for path, content := range testFiles {
fullPath := filepath.Join(tmpDir, path)
err := os.MkdirAll(filepath.Dir(fullPath), 0o750)
require.NoError(t, err)
err = os.WriteFile(fullPath, []byte(content), 0o644)
require.NoError(t, err)
}
tests := []struct {
dir string
name string
path string
options StaticOptions
expectedStatus int
expectedBody string
expectedLocation string
}{
{
name: "should serve existing file",
path: "/test.txt",
expectedStatus: http.StatusOK,
expectedBody: "Test content",
dir: tmpDir,
},
{
name: "should serve file from subdirectory",
path: "/subdir/test.txt",
expectedStatus: http.StatusOK,
expectedBody: "Subdir content",
dir: tmpDir,
},
{
name: "should redirect directory without trailing slash",
path: "/subdir",
expectedStatus: http.StatusFound,
expectedLocation: "/subdir/",
dir: tmpDir,
},
{
name: "should handle prefix",
path: "/static/test.txt",
options: StaticOptions{Prefix: "/static"},
expectedStatus: http.StatusOK,
expectedBody: "Test content",
dir: tmpDir,
},
{
name: "should handle excluded path",
path: "/test.txt",
options: StaticOptions{Exclude: []string{"/test.txt"}},
expectedStatus: http.StatusNotFound,
dir: tmpDir,
},
{
name: "should add custom headers",
path: "/test.txt",
options: StaticOptions{AddHeaders: func(ctx *web.Context) { ctx.Resp.Header().Set("X-Test", "test") }},
expectedStatus: http.StatusOK,
expectedBody: "Test content",
dir: tmpDir,
},
{
name: "should clean up path before redirecting",
path: "/subdir/..%2F%5C127.0.0.1:80%2F%3F%2F..%2F..",
options: StaticOptions{Prefix: "subdir"},
expectedStatus: http.StatusFound,
expectedLocation: "/",
dir: tmpDir,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sc := setupScenarioContext(t, "")
sc.m.Use(Static(tt.dir, tt.options))
// Create a test request
req := httptest.NewRequest("GET", tt.path, nil)
w := httptest.NewRecorder()
// Execute the handler
sc.m.ServeHTTP(w, req)
// Verify the response
resp := w.Result()
require.Equal(t, tt.expectedStatus, resp.StatusCode)
if tt.expectedBody != "" {
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.Equal(t, tt.expectedBody, string(body))
}
if tt.options.AddHeaders != nil {
assert.Equal(t, "test", resp.Header.Get("X-Test"))
}
if tt.expectedLocation != "" {
assert.Equal(t, tt.expectedLocation, resp.Header.Get("Location"))
}
})
}
}
type scenarioContext struct {
t *testing.T
cfg *setting.Cfg
m *web.Mux
ctxHdlr *contexthandler.ContextHandler
}
func getContextHandler(t *testing.T, cfg *setting.Cfg) *contexthandler.ContextHandler {
t.Helper()
if cfg == nil {
cfg = setting.NewCfg()
}
return contexthandler.ProvideService(
cfg,
tracing.InitializeTracerForTest(),
&authntest.FakeService{ExpectedIdentity: &authn.Identity{ID: "0", Type: claims.TypeAnonymous, SessionToken: &usertoken.UserToken{}}},
featuremgmt.WithFeatures(),
)
}
func setupScenarioContext(t *testing.T, url string) *scenarioContext {
cfg := setting.NewCfg()
ctxHdlr := getContextHandler(t, cfg)
sc := &scenarioContext{
t: t,
cfg: cfg,
ctxHdlr: ctxHdlr,
}
sc.m = web.New()
sc.m.Use(ctxHdlr.Middleware)
return sc
}
Loading…
Cancel
Save