- 新增 backend/.golangci.yml 配置 12 个 linter(forbidigo、errorlint、errcheck、staticcheck、revive、gocritic、gosec、bodyclose、noctx、nilerr、goimports、gocyclo) - 新增 lefthook.yml 配置 pre-commit hook 自动运行 lint - 修复存量代码违规:errors.Is/As 替换、zap.Error 替换、import 排序、errcheck 修复 - 更新 README 补充编码规范说明 - 归档 backend-code-lint 变更
124 lines
2.8 KiB
Go
124 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"io/fs"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"nex/embedfs"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestSetupStaticFiles(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
distFS, err := fs.Sub(embedfs.FrontendDist, "frontend-dist")
|
|
if err != nil {
|
|
t.Skipf("跳过测试: 前端资源未构建: %v", err)
|
|
return
|
|
}
|
|
|
|
getContentType := func(path string) string {
|
|
if strings.HasSuffix(path, ".js") {
|
|
return "application/javascript"
|
|
}
|
|
if strings.HasSuffix(path, ".css") {
|
|
return "text/css"
|
|
}
|
|
if strings.HasSuffix(path, ".svg") {
|
|
return "image/svg+xml"
|
|
}
|
|
return "application/octet-stream"
|
|
}
|
|
|
|
r := gin.New()
|
|
r.GET("/assets/*filepath", func(c *gin.Context) {
|
|
filepath := c.Param("filepath")
|
|
data, err := fs.ReadFile(distFS, "assets"+filepath)
|
|
if err != nil {
|
|
c.Status(404)
|
|
return
|
|
}
|
|
c.Data(200, getContentType(filepath), data)
|
|
})
|
|
|
|
r.GET("/favicon.svg", func(c *gin.Context) {
|
|
data, err := fs.ReadFile(distFS, "favicon.svg")
|
|
if err != nil {
|
|
c.Status(404)
|
|
return
|
|
}
|
|
c.Data(200, "image/svg+xml", data)
|
|
})
|
|
|
|
r.NoRoute(func(c *gin.Context) {
|
|
path := c.Request.URL.Path
|
|
if strings.HasPrefix(path, "/api/") ||
|
|
strings.HasPrefix(path, "/v1/") ||
|
|
strings.HasPrefix(path, "/health") {
|
|
c.JSON(404, gin.H{"error": "not found"})
|
|
return
|
|
}
|
|
data, err := fs.ReadFile(distFS, "index.html")
|
|
if err != nil {
|
|
c.Status(500)
|
|
return
|
|
}
|
|
c.Data(200, "text/html; charset=utf-8", data)
|
|
})
|
|
|
|
t.Run("API 404", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/api/test", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != 404 {
|
|
t.Errorf("期望状态码 404, 实际 %d", w.Code)
|
|
}
|
|
})
|
|
|
|
t.Run("SPA fallback", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/providers", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != 200 {
|
|
t.Errorf("期望状态码 200, 实际 %d", w.Code)
|
|
}
|
|
})
|
|
|
|
t.Run("MIME type for JS", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/assets/test.js", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code == 200 {
|
|
expected := "application/javascript"
|
|
if w.Header().Get("Content-Type") != expected {
|
|
t.Errorf("期望 Content-Type %s, 实际 %s", expected, w.Header().Get("Content-Type"))
|
|
}
|
|
} else {
|
|
t.Log("文件不存在,跳过 MIME 类型验证")
|
|
}
|
|
})
|
|
|
|
t.Run("MIME type for CSS", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/assets/test.css", nil)
|
|
w := httptest.NewRecorder()
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code == 200 {
|
|
expected := "text/css"
|
|
if w.Header().Get("Content-Type") != expected {
|
|
t.Errorf("期望 Content-Type %s, 实际 %s", expected, w.Header().Get("Content-Type"))
|
|
}
|
|
} else {
|
|
t.Log("文件不存在,跳过 MIME 类型验证")
|
|
}
|
|
})
|
|
|
|
t.Log("静态文件服务测试通过")
|
|
}
|