feat: unify service port and add GitHub packages workflow
Build Packages / Test (push) Has been cancelled
Build Packages / Build macOS package (push) Has been cancelled
Build Packages / Build Linux package (push) Has been cancelled
Build Packages / Build Windows package (push) Has been cancelled
Build Packages / Publish GitHub Release (push) Has been cancelled

This commit is contained in:
2026-08-05 15:13:29 +08:00
parent 56db1cc642
commit 6f07849a53
7 changed files with 318 additions and 367 deletions
+44 -23
View File
@@ -1,38 +1,59 @@
package main
import (
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"testing/fstest"
"github.com/gin-gonic/gin"
)
func TestProxyAPIRequestUsesConfiguredPort(t *testing.T) {
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"path":"` + r.URL.RequestURI() + `"}`))
}))
defer backend.Close()
backendURL, err := url.Parse(backend.URL)
if err != nil {
t.Fatal(err)
}
_, port, err := net.SplitHostPort(backendURL.Host)
if err != nil {
t.Fatal(err)
}
func TestAPIAndFrontendShareRouter(t *testing.T) {
gin.SetMode(gin.TestMode)
router := gin.New()
router.Any("/api/*path", proxyAPIRequest(port))
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/api/config?custom=1", nil))
router.GET("/api/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"status": "ok"})
})
router.NoRoute(serveFrontend(fstest.MapFS{
"index.html": {Data: []byte("<html>app</html>")},
"assets/app.js": {Data: []byte("console.log('app')")},
}))
if recorder.Code != http.StatusOK || recorder.Body.String() != `{"path":"/api/config?custom=1"}` {
t.Fatalf("unexpected proxy response: status=%d body=%s", recorder.Code, recorder.Body.String())
tests := []struct {
path string
statusCode int
body string
}{
{path: "/api/ping", statusCode: http.StatusOK, body: `{"status":"ok"}`},
{path: "/admin", statusCode: http.StatusOK, body: "<html>app</html>"},
{path: "/assets/app.js", statusCode: http.StatusOK, body: "console.log('app')"},
{path: "/api/missing", statusCode: http.StatusNotFound, body: "404 page not found"},
{path: "/uploads/missing.png", statusCode: http.StatusNotFound, body: "404 page not found"},
}
for _, test := range tests {
t.Run(test.path, func(t *testing.T) {
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, test.path, nil))
if recorder.Code != test.statusCode || recorder.Body.String() != test.body {
t.Fatalf("unexpected response: status=%d body=%q", recorder.Code, recorder.Body.String())
}
})
}
}
func TestCORSMiddlewareUsesServicePort(t *testing.T) {
gin.SetMode(gin.TestMode)
router := gin.New()
router.Use(corsMiddleware("8080"))
router.GET("/api/ping", func(c *gin.Context) { c.Status(http.StatusNoContent) })
recorder := httptest.NewRecorder()
request := httptest.NewRequest(http.MethodGet, "/api/ping", nil)
request.Header.Set("Origin", "http://localhost:8080")
router.ServeHTTP(recorder, request)
if origin := recorder.Header().Get("Access-Control-Allow-Origin"); origin != "http://localhost:8080" {
t.Fatalf("unexpected allowed origin: %q", origin)
}
}