精简后的项目:仅保留 api/ui 源码、文档、构建依赖
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewSpaHandler(t *testing.T) {
|
||||
t.Run("valid paths", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("index content"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
assert.NoError(t, err)
|
||||
assert.NotEmpty(t, handler.staticPath)
|
||||
assert.NotEmpty(t, handler.indexPath)
|
||||
})
|
||||
|
||||
t.Run("invalid static path", func(t *testing.T) {
|
||||
handler, err := NewSpaHandler("/nonexistent/path", "index.html")
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, handler.staticPath)
|
||||
assert.Empty(t, handler.indexPath)
|
||||
})
|
||||
|
||||
t.Run("static path is not a directory", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
filePath := filepath.Join(tempDir, "file.txt")
|
||||
require.NoError(t, os.WriteFile(filePath, []byte("content"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(filePath, "index.html")
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, handler.staticPath)
|
||||
assert.Empty(t, handler.indexPath)
|
||||
})
|
||||
|
||||
t.Run("index path does not exist", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
handler, err := NewSpaHandler(tempDir, "nonexistent.html")
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, handler.staticPath)
|
||||
assert.Empty(t, handler.indexPath)
|
||||
})
|
||||
|
||||
t.Run("index path is a directory", func(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
indexDir := filepath.Join(tempDir, "indexdir")
|
||||
require.NoError(t, os.Mkdir(indexDir, 0755))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "indexdir")
|
||||
assert.Error(t, err)
|
||||
assert.Empty(t, handler.staticPath)
|
||||
assert.Empty(t, handler.indexPath)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSpaHandler_ServeHTTP(t *testing.T) {
|
||||
// Setup test directory structure
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create index.html
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("<!DOCTYPE html><html>index</html>"), 0644))
|
||||
|
||||
// Create assets directory
|
||||
assetsDir := filepath.Join(tempDir, "assets")
|
||||
require.NoError(t, os.Mkdir(assetsDir, 0755))
|
||||
|
||||
// Create test files
|
||||
jsFile := filepath.Join(assetsDir, "app.js")
|
||||
require.NoError(t, os.WriteFile(jsFile, []byte("console.log('app');"), 0644))
|
||||
|
||||
// Create pre-compressed variants
|
||||
require.NoError(t, os.WriteFile(jsFile+".br", []byte("compressed-br"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".zst", []byte("compressed-zst"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".gz", []byte("compressed-gz"), 0644))
|
||||
|
||||
// Create an image file (should not be compressed)
|
||||
imgFile := filepath.Join(assetsDir, "logo.png")
|
||||
require.NoError(t, os.WriteFile(imgFile, []byte("PNG data"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, handler.staticPath)
|
||||
|
||||
t.Run("serve root returns index.html", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Contains(t, rec.Body.String(), "index")
|
||||
})
|
||||
|
||||
t.Run("serve existing file", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Contains(t, rec.Body.String(), "console.log")
|
||||
})
|
||||
|
||||
t.Run("serve non-existent file returns index.html (SPA routing)", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/some/spa/route", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Contains(t, rec.Body.String(), "index")
|
||||
})
|
||||
|
||||
t.Run("path traversal attack prevented", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/../../../etc/passwd", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("in-tree traversal redirected", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/../index.html", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusMovedPermanently, rec.Code)
|
||||
})
|
||||
|
||||
t.Run("empty handler configuration returns 500", func(t *testing.T) {
|
||||
emptyHandler := SpaHandler{}
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
emptyHandler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, rec.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestSpaHandler_PrecompressedFiles(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
// Create index.html
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("index"), 0644))
|
||||
|
||||
// Create assets directory
|
||||
assetsDir := filepath.Join(tempDir, "assets")
|
||||
require.NoError(t, os.Mkdir(assetsDir, 0755))
|
||||
|
||||
// Create test file with all compression variants
|
||||
jsFile := filepath.Join(assetsDir, "app.js")
|
||||
jsContent := []byte("console.log('original');")
|
||||
require.NoError(t, os.WriteFile(jsFile, jsContent, 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".br", []byte("br-compressed"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".zst", []byte("zst-compressed"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".gz", []byte("gz-compressed"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("serve brotli when accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip, deflate, br")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "br", rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Header().Get("Vary"), "Accept-Encoding")
|
||||
assert.Contains(t, rec.Header().Get("Content-Type"), "javascript")
|
||||
assert.Equal(t, "br-compressed", rec.Body.String())
|
||||
})
|
||||
|
||||
t.Run("serve zstd when br not accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip, zstd")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "zstd", rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Header().Get("Vary"), "Accept-Encoding")
|
||||
assert.Contains(t, rec.Header().Get("Content-Type"), "javascript")
|
||||
assert.Equal(t, "zst-compressed", rec.Body.String())
|
||||
})
|
||||
|
||||
t.Run("serve gzip when only gzip accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "gzip", rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Header().Get("Vary"), "Accept-Encoding")
|
||||
assert.Contains(t, rec.Header().Get("Content-Type"), "javascript")
|
||||
assert.Equal(t, "gz-compressed", rec.Body.String())
|
||||
})
|
||||
|
||||
t.Run("serve uncompressed when no encoding accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Empty(t, rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Body.String(), "original")
|
||||
})
|
||||
|
||||
t.Run("serve original when pre-compressed file missing", func(t *testing.T) {
|
||||
// Create file without pre-compressed variants
|
||||
cssFile := filepath.Join(assetsDir, "style.css")
|
||||
require.NoError(t, os.WriteFile(cssFile, []byte("body { margin: 0; }"), 0644))
|
||||
|
||||
req := httptest.NewRequest("GET", "/assets/style.css", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip, br")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Empty(t, rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Body.String(), "margin")
|
||||
})
|
||||
|
||||
t.Run("do not compress already-compressed formats", func(t *testing.T) {
|
||||
pngFile := filepath.Join(assetsDir, "logo.png")
|
||||
require.NoError(t, os.WriteFile(pngFile, []byte("PNG data"), 0644))
|
||||
require.NoError(t, os.WriteFile(pngFile+".br", []byte("should-not-serve"), 0644))
|
||||
|
||||
req := httptest.NewRequest("GET", "/assets/logo.png", nil)
|
||||
req.Header.Set("Accept-Encoding", "br")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Empty(t, rec.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "PNG data", rec.Body.String())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSpaHandler_CacheHeaders(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("index"), 0644))
|
||||
|
||||
assetsDir := filepath.Join(tempDir, "assets")
|
||||
require.NoError(t, os.Mkdir(assetsDir, 0755))
|
||||
|
||||
jsFile := filepath.Join(assetsDir, "app.js")
|
||||
require.NoError(t, os.WriteFile(jsFile, []byte("console.log('app');"), 0644))
|
||||
|
||||
otherFile := filepath.Join(tempDir, "manifest.json")
|
||||
require.NoError(t, os.WriteFile(otherFile, []byte("{}"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("long-term cache for assets", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "public, max-age=31536000, immutable", rec.Header().Get("Cache-Control"))
|
||||
})
|
||||
|
||||
t.Run("short cache with revalidation for non-assets", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/manifest.json", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "public, max-age=3600, must-revalidate", rec.Header().Get("Cache-Control"))
|
||||
})
|
||||
|
||||
t.Run("cache headers for index.html", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "public, max-age=3600, must-revalidate", rec.Header().Get("Cache-Control"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSpaHandler_IndexHTML(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
indexContent := []byte("<!DOCTYPE html><html>index</html>")
|
||||
require.NoError(t, os.WriteFile(indexPath, indexContent, 0644))
|
||||
|
||||
// Create pre-compressed index.html
|
||||
require.NoError(t, os.WriteFile(indexPath+".br", []byte("index-br-compressed"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("serve pre-compressed index.html when accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Set("Accept-Encoding", "br")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "br", rec.Header().Get("Content-Encoding"))
|
||||
assert.Equal(t, "index-br-compressed", rec.Body.String())
|
||||
})
|
||||
|
||||
t.Run("serve uncompressed index.html when encoding not accepted", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Empty(t, rec.Header().Get("Content-Encoding"))
|
||||
assert.Contains(t, rec.Body.String(), "index")
|
||||
})
|
||||
|
||||
t.Run("SPA routing serves index.html for non-existent paths", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/app/users/123", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Contains(t, rec.Body.String(), "index")
|
||||
})
|
||||
}
|
||||
|
||||
func TestIsCompressedFormat(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ext string
|
||||
expected bool
|
||||
}{
|
||||
{"png", ".png", true},
|
||||
{"jpg", ".jpg", true},
|
||||
{"jpeg", ".jpeg", true},
|
||||
{"gif", ".gif", true},
|
||||
{"webp", ".webp", true},
|
||||
{"ico", ".ico", true},
|
||||
{"zip", ".zip", true},
|
||||
{"gz", ".gz", true},
|
||||
{"br", ".br", true},
|
||||
{"zst", ".zst", true},
|
||||
{"woff", ".woff", true},
|
||||
{"woff2", ".woff2", true},
|
||||
{"js", ".js", false},
|
||||
{"css", ".css", false},
|
||||
{"html", ".html", false},
|
||||
{"json", ".json", false},
|
||||
{"txt", ".txt", false},
|
||||
{"uppercase PNG", ".PNG", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := isCompressedFormat(tt.ext)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFilterZeroQuality(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "no q params (fast path)",
|
||||
input: "gzip, deflate, br",
|
||||
expected: "gzip, deflate, br",
|
||||
},
|
||||
{
|
||||
name: "filter q=0",
|
||||
input: "gzip;q=1.0, deflate;q=0, br;q=0.8",
|
||||
expected: "gzip;q=1.0,br;q=0.8",
|
||||
},
|
||||
{
|
||||
name: "filter q=0.0",
|
||||
input: "gzip;q=0.0, br;q=1",
|
||||
expected: "br;q=1",
|
||||
},
|
||||
{
|
||||
name: "filter with spaces",
|
||||
input: "gzip; q=0.0, deflate; q=1.0, br",
|
||||
expected: "deflate; q=1.0,br",
|
||||
},
|
||||
{
|
||||
name: "all encodings filtered",
|
||||
input: "gzip;q=0, deflate;q=0.0",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "empty input",
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "q=0 but others present",
|
||||
input: "identity;q=0, gzip, br",
|
||||
expected: "gzip,br",
|
||||
},
|
||||
{
|
||||
name: "multiple spaces",
|
||||
input: "gzip; q=0, br; q=1",
|
||||
expected: "br; q=1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := filterZeroQuality(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpaHandler_AcceptEncodingEdgeCases(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("index"), 0644))
|
||||
|
||||
assetsDir := filepath.Join(tempDir, "assets")
|
||||
require.NoError(t, os.Mkdir(assetsDir, 0755))
|
||||
|
||||
jsFile := filepath.Join(assetsDir, "app.js")
|
||||
require.NoError(t, os.WriteFile(jsFile, []byte("original"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".br", []byte("br-compressed"), 0644))
|
||||
require.NoError(t, os.WriteFile(jsFile+".gz", []byte("gz-compressed"), 0644))
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("reject encoding with q=0", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "br;q=0, gzip")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
// Should serve gzip since br is rejected with q=0
|
||||
assert.Equal(t, "gzip", rec.Header().Get("Content-Encoding"))
|
||||
})
|
||||
|
||||
t.Run("case insensitive encoding names", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "BR, GZIP")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "br", rec.Header().Get("Content-Encoding"))
|
||||
})
|
||||
|
||||
t.Run("wildcard encoding", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "*")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
// Wildcard doesn't match our specific encodings
|
||||
assert.Empty(t, rec.Header().Get("Content-Encoding"))
|
||||
})
|
||||
|
||||
t.Run("complex Accept-Encoding with quality values", func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/app.js", nil)
|
||||
req.Header.Set("Accept-Encoding", "gzip;q=0.8, br;q=1.0, deflate;q=0.5")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
// br has highest quality and should be preferred
|
||||
assert.Equal(t, "br", rec.Header().Get("Content-Encoding"))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSpaHandler_ContentType(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
|
||||
indexPath := filepath.Join(tempDir, "index.html")
|
||||
require.NoError(t, os.WriteFile(indexPath, []byte("index"), 0644))
|
||||
|
||||
assetsDir := filepath.Join(tempDir, "assets")
|
||||
require.NoError(t, os.Mkdir(assetsDir, 0755))
|
||||
|
||||
// Create files with various extensions
|
||||
files := map[string]string{
|
||||
"app.js": "text/javascript",
|
||||
"style.css": "text/css",
|
||||
"data.json": "application/json",
|
||||
"image.svg": "image/svg+xml",
|
||||
"unknown.xyz": "", // Unknown extension
|
||||
}
|
||||
|
||||
for filename := range files {
|
||||
filePath := filepath.Join(assetsDir, filename)
|
||||
require.NoError(t, os.WriteFile(filePath, []byte("content"), 0644))
|
||||
require.NoError(t, os.WriteFile(filePath+".br", []byte("compressed"), 0644))
|
||||
}
|
||||
|
||||
handler, err := NewSpaHandler(tempDir, "index.html")
|
||||
require.NoError(t, err)
|
||||
|
||||
for filename, expectedType := range files {
|
||||
t.Run(filename, func(t *testing.T) {
|
||||
req := httptest.NewRequest("GET", "/assets/"+filename, nil)
|
||||
req.Header.Set("Accept-Encoding", "br")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
handler.ServeHTTP(rec, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
assert.Equal(t, "br", rec.Header().Get("Content-Encoding"))
|
||||
|
||||
if expectedType != "" {
|
||||
assert.Contains(t, rec.Header().Get("Content-Type"), expectedType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user