- isPublicRoute exempts site-status (anonymous banner polling) - httptest coverage: anonymous 200 + site_notice payload; route table guards - test report + playwright evidence (docker mcr playwright v1.63 noble vs real dev stack, 1 passed)
74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
package server
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"testing"
|
||
|
||
"chat-agent-system/internal/maintenance"
|
||
)
|
||
|
||
// P9:site-status 为公开端点(登录页横幅轮询),匿名可达且不落鉴权错误。
|
||
func TestMaintenanceSiteStatusPublic(t *testing.T) {
|
||
svc := maintenance.NewService(&fakeSiteStore{})
|
||
svc.SetSiteSettings(func(ctx context.Context) (string, bool) {
|
||
return "公告内容", true
|
||
})
|
||
s := &Server{}
|
||
s.setOverrideMaintenance(svc)
|
||
|
||
mux := http.NewServeMux()
|
||
mux.HandleFunc("GET /api/v1/maintenance/site-status", s.handleMaintenanceSiteStatus)
|
||
ts := httptest.NewServer(mux)
|
||
defer ts.Close()
|
||
|
||
resp, err := http.Get(ts.URL + "/api/v1/maintenance/site-status")
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
defer resp.Body.Close()
|
||
if resp.StatusCode != http.StatusOK {
|
||
t.Fatalf("status = %d", resp.StatusCode)
|
||
}
|
||
var view maintenance.StatusView
|
||
if err := json.NewDecoder(resp.Body).Decode(&view); err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
if view.Notice != "公告内容" || !view.ReadOnly || view.Status != "site_notice" {
|
||
t.Fatalf("site view = %+v", view)
|
||
}
|
||
}
|
||
|
||
// isPublicRoute 必须豁免 site-status(匿名横幅)。
|
||
func TestIsPublicRouteMaintenanceSiteStatus(t *testing.T) {
|
||
if !isPublicRoute(http.MethodGet, "/api/v1/maintenance/site-status") {
|
||
t.Fatal("site-status must be public")
|
||
}
|
||
if !isPublicRoute(http.MethodGet, "/api/v1/maintenance/status") {
|
||
t.Fatal("status must stay public")
|
||
}
|
||
if isPublicRoute(http.MethodGet, "/api/v1/admin/maintenance") {
|
||
t.Fatal("admin maintenance must not be public")
|
||
}
|
||
}
|
||
|
||
type fakeSiteStore struct{}
|
||
|
||
func (f *fakeSiteStore) GetOpen(ctx context.Context) (*maintenance.Window, error) {
|
||
return nil, maintenance.ErrNotFound
|
||
}
|
||
func (f *fakeSiteStore) GetByID(ctx context.Context, id int64) (*maintenance.Window, error) {
|
||
return nil, maintenance.ErrNotFound
|
||
}
|
||
func (f *fakeSiteStore) Insert(ctx context.Context, w maintenance.Window) (maintenance.Window, error) {
|
||
return w, nil
|
||
}
|
||
func (f *fakeSiteStore) UpdateStatus(ctx context.Context, id int64, from, to string) (maintenance.Window, error) {
|
||
return maintenance.Window{}, nil
|
||
}
|
||
func (f *fakeSiteStore) ListRecent(ctx context.Context, limit int) ([]maintenance.Window, error) {
|
||
return nil, nil
|
||
}
|