Files
OpenFlare/backend/plugins/domain/system/public_config_test.go
T
ryan 455e2f8be5 fix(config): serve public settings and enforce login CAP
Public config now comes from admin as a flat visibility=1 map instead of
a cross-plugin query that compared an integer column to "visible". Login
and register resolve CaptchaService per request so CAP is not skipped
when user applies before cap.
2026-09-02 17:07:07 +08:00

160 lines
4.2 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package system
import (
"context"
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"strings"
"testing"
"Wavelet/core"
"Wavelet/core/contracts"
"github.com/gin-gonic/gin"
)
type stubPublic struct{ payload map[string]string }
func (s stubPublic) PublicConfig(context.Context) (map[string]string, error) {
return s.payload, nil
}
type errPublic struct{ err error }
func (s errPublic) PublicConfig(context.Context) (map[string]string, error) {
return nil, s.err
}
func TestPublicConfigUsesProviderWhenPresent(t *testing.T) {
gin.SetMode(gin.TestMode)
ctx := core.NewContext(context.Background())
core.Provide[contracts.PublicConfigProvider](ctx, stubPublic{payload: map[string]string{"k": "v"}})
if err := New().Apply(ctx); err != nil {
t.Fatal(err)
}
body := invokePublicConfig(t, publicConfigHandler(t, ctx))
assertFlatKV(t, body)
}
func TestPublicConfigUsesProviderRegisteredAfterApply(t *testing.T) {
gin.SetMode(gin.TestMode)
ctx := core.NewContext(context.Background())
if err := New().Apply(ctx); err != nil {
t.Fatal(err)
}
core.Provide[contracts.PublicConfigProvider](ctx, stubPublic{payload: map[string]string{"k": "v"}})
body := invokePublicConfig(t, publicConfigHandler(t, ctx))
assertFlatKV(t, body)
}
func TestPublicConfigDefaultWithoutProvider(t *testing.T) {
gin.SetMode(gin.TestMode)
ctx := core.NewContext(context.Background())
if err := New().Apply(ctx); err != nil {
t.Fatal(err)
}
if !ctx.Router().IsWhitelisted("/api/v1/config/public") {
t.Fatal("GET /api/v1/config/public not whitelisted")
}
raw := invokePublicConfig(t, publicConfigHandler(t, ctx))
var data map[string]any
if err := json.Unmarshal(raw, &data); err != nil {
t.Fatal(err)
}
if len(data) != 0 {
t.Fatalf("data = %s, want empty flat map", raw)
}
if _, ok := data["configs"]; ok {
t.Fatalf("data = %s, default payload must not wrap configs", raw)
}
if _, ok := data["app"]; ok {
t.Fatalf("data = %s, default payload must not wrap app", raw)
}
}
func TestPublicConfigProviderErrorAbortsInternal(t *testing.T) {
gin.SetMode(gin.TestMode)
ctx := core.NewContext(context.Background())
core.Provide[contracts.PublicConfigProvider](ctx, errPublic{err: errors.New("secret boom")})
if err := New().Apply(ctx); err != nil {
t.Fatal(err)
}
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, "/api/v1/config/public", nil)
publicConfigHandler(t, ctx)(c)
if !c.IsAborted() {
t.Fatal("want request aborted on provider error")
}
if len(c.Errors) == 0 {
t.Fatal("want gin error on provider failure")
}
if got := c.Errors.Last().Error(); got != "public config unavailable" {
t.Fatalf("error = %q, want generic message", got)
}
if strings.Contains(w.Body.String(), "secret boom") {
t.Fatalf("leaked provider error: %s", w.Body.String())
}
}
func publicConfigHandler(t *testing.T, ctx *core.Context) gin.HandlerFunc {
t.Helper()
for _, rd := range ctx.Router().Routes() {
if rd.Method != "GET" || rd.Path != "/api/v1/config/public" {
continue
}
if len(rd.Handlers) == 0 {
break
}
switch h := rd.Handlers[0].(type) {
case gin.HandlerFunc:
return h
case func(*gin.Context):
return h
default:
t.Fatalf("unexpected handler type %T", rd.Handlers[0])
}
}
t.Fatal("public config route missing")
return nil
}
func invokePublicConfig(t *testing.T, handler gin.HandlerFunc) json.RawMessage {
t.Helper()
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Request = httptest.NewRequest(http.MethodGet, "/api/v1/config/public", nil)
handler(c)
var body struct {
Data json.RawMessage `json:"data"`
}
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
return body.Data
}
func assertFlatKV(t *testing.T, raw json.RawMessage) {
t.Helper()
var data map[string]any
if err := json.Unmarshal(raw, &data); err != nil {
t.Fatal(err)
}
if data["k"] != "v" {
t.Fatalf("data = %s, want flat map", raw)
}
if _, ok := data["configs"]; ok {
t.Fatalf("data = %s, want provider payload without default configs", raw)
}
if _, ok := data["app"]; ok {
t.Fatalf("data = %s, want provider payload without default app", raw)
}
}