fix deployment and frontend build regressions

This commit is contained in:
2026-05-21 15:30:24 +08:00
parent 31f1b510c3
commit b430fb9301
6 changed files with 276 additions and 99 deletions

View File

@@ -6,6 +6,9 @@ import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
@@ -20,7 +23,7 @@ func TestSubscriptionPlansHandlerReturnsEnvelope(t *testing.T) {
{
PlanFamily: "token_plan",
PlanCode: "token-plan-lite",
PlanName: "通用 Token Plan Lite",
PlanName: "General Token Plan Lite",
Tier: "Lite",
Provider: "Tencent",
ProviderCN: "腾讯",
@@ -38,6 +41,7 @@ func TestSubscriptionPlansHandlerReturnsEnvelope(t *testing.T) {
},
}, nil
},
"",
)
req := httptest.NewRequest(http.MethodGet, "/api/v1/subscription-plans", nil)
@@ -76,3 +80,89 @@ func TestSubscriptionPlansHandlerReturnsEnvelope(t *testing.T) {
t.Fatalf("unexpected model scope length: %d", len(got.ModelScope))
}
}
func TestFrontendHandlerServesIndexAssetsAndSpaFallback(t *testing.T) {
distDir := t.TempDir()
writeTestFile(t, filepath.Join(distDir, "index.html"), "<html>dashboard</html>")
writeTestFile(t, filepath.Join(distDir, "assets", "app.js"), "console.log('ok');")
mux := newMux(&sql.DB{}, noOpModelsFetcher, noOpPlansFetcher, distDir)
t.Run("root serves index", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/", nil)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status 200, got %d", rec.Code)
}
if !strings.Contains(rec.Body.String(), "dashboard") {
t.Fatalf("expected index response, got %q", rec.Body.String())
}
})
t.Run("asset serves file", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/assets/app.js", nil)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status 200, got %d", rec.Code)
}
if !strings.Contains(rec.Body.String(), "console.log") {
t.Fatalf("expected asset response, got %q", rec.Body.String())
}
})
t.Run("spa route falls back to index", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/explorer/detail", nil)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status 200, got %d", rec.Code)
}
if !strings.Contains(rec.Body.String(), "dashboard") {
t.Fatalf("expected SPA fallback, got %q", rec.Body.String())
}
})
t.Run("missing asset returns not found", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/assets/missing.js", nil)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusNotFound {
t.Fatalf("expected status 404, got %d", rec.Code)
}
})
t.Run("api routes keep precedence", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/api/v1/models", nil)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected status 200, got %d", rec.Code)
}
})
}
func noOpModelsFetcher(context.Context, *sql.DB) ([]modelResponse, error) {
return []modelResponse{}, nil
}
func noOpPlansFetcher(context.Context, *sql.DB) ([]subscriptionPlanResponse, error) {
return []subscriptionPlanResponse{}, nil
}
func writeTestFile(t *testing.T, path string, contents string) {
t.Helper()
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
t.Fatalf("mkdir %s: %v", path, err)
}
if err := os.WriteFile(path, []byte(contents), 0o644); err != nil {
t.Fatalf("write %s: %v", path, err)
}
}