Files
pulse/internal/api/multi_tenant_setters_additional_test.go
T
rcourtman 0622169be8 Harden multi-tenant GA readiness
Revalidate and harden the Pulse multi-tenant GA surface across org ownership transfer, MSP invite lifecycle, tenant state fallback, registry workspace limits, and the embedded Pulse Account portal bundle.
2026-04-23 23:04:03 +01:00

134 lines
4.5 KiB
Go

package api
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/internal/monitoring"
)
func TestConfigHandlersSetMultiTenantMonitor(t *testing.T) {
handler := &ConfigHandlers{}
handler.SetMultiTenantMonitor(nil)
if handler.mtMonitor != nil {
t.Fatalf("mtMonitor should be nil after SetMultiTenantMonitor(nil)")
}
}
func TestRouterSetMultiTenantMonitor(t *testing.T) {
router := &Router{
alertHandlers: &AlertHandlers{},
notificationHandlers: &NotificationHandlers{},
configHandlers: &ConfigHandlers{},
dockerAgentHandlers: &DockerAgentHandlers{},
unifiedAgentHandlers: &UnifiedAgentHandlers{},
kubernetesAgentHandlers: &KubernetesAgentHandlers{},
systemSettingsHandler: &SystemSettingsHandler{},
resourceHandlers: NewResourceHandlers(nil),
}
router.SetMultiTenantMonitor(nil)
if router.mtMonitor != nil {
t.Fatalf("mtMonitor should be nil after SetMultiTenantMonitor(nil)")
}
if router.resourceHandlers.tenantStateProvider == nil {
t.Fatalf("tenantStateProvider should be set on resource handlers")
}
}
func TestRouterSetMultiTenantMonitorRefreshesConfigHandlerMonitorSource(t *testing.T) {
oldMonitor, _, _ := newTestMonitor(t)
newMonitor, _, _ := newTestMonitor(t)
oldConfig := &config.Config{DataPath: t.TempDir(), ConfigPath: t.TempDir()}
newConfig := &config.Config{DataPath: t.TempDir(), ConfigPath: t.TempDir()}
setUnexportedField(t, oldMonitor, "config", oldConfig)
setUnexportedField(t, newMonitor, "config", newConfig)
oldMTM := &monitoring.MultiTenantMonitor{}
setUnexportedField(t, oldMTM, "monitors", map[string]*monitoring.Monitor{
"default": oldMonitor,
})
newMTM := &monitoring.MultiTenantMonitor{}
setUnexportedField(t, newMTM, "monitors", map[string]*monitoring.Monitor{
"default": newMonitor,
})
router := &Router{
configHandlers: &ConfigHandlers{},
}
router.configHandlers.SetMultiTenantMonitor(oldMTM)
if got := router.configHandlers.getMonitor(context.Background()); got != oldMonitor {
t.Fatalf("precondition monitor = %#v, want old monitor %#v", got, oldMonitor)
}
router.SetMultiTenantMonitor(newMTM)
if got := router.configHandlers.getMonitor(context.Background()); got != newMonitor {
t.Fatalf("config handler monitor = %#v, want reloaded monitor %#v", got, newMonitor)
}
if got := router.configHandlers.getConfig(context.Background()); got != newConfig {
t.Fatalf("config handler config = %#v, want reloaded config %#v", got, newConfig)
}
}
func TestConfigHandlersNonDefaultMissingTenantMonitorFailsClosed(t *testing.T) {
defaultConfig := &config.Config{DataPath: t.TempDir(), ConfigPath: t.TempDir()}
defaultMonitor, _, _ := newTestMonitor(t)
mtp := config.NewMultiTenantPersistence(t.TempDir())
mtm := monitoring.NewMultiTenantMonitor(defaultConfig, mtp, nil)
defer mtm.Stop()
handler := &ConfigHandlers{
defaultConfig: defaultConfig,
defaultPersistence: config.NewConfigPersistence(defaultConfig.ConfigPath),
defaultMonitor: defaultMonitor,
}
handler.SetMultiTenantMonitor(mtm)
ctx := context.WithValue(context.Background(), OrgIDContextKey, "tenant-missing")
cfg, persistence, monitor := handler.getContextState(ctx)
if cfg != nil || persistence != nil || monitor != nil {
t.Fatalf("expected missing non-default tenant state to fail closed, got cfg=%#v persistence=%#v monitor=%#v", cfg, persistence, monitor)
}
}
func TestNewRouterWiresTenantResourceStateProvider(t *testing.T) {
cfg := &config.Config{
DataPath: t.TempDir(),
ConfigPath: t.TempDir(),
}
mtm := &monitoring.MultiTenantMonitor{}
router := NewRouter(cfg, nil, mtm, nil, nil, "1.0.0")
if router.resourceHandlers == nil {
t.Fatal("expected resource handlers to be initialized")
}
if router.resourceHandlers.tenantStateProvider == nil {
t.Fatal("expected NewRouter to wire the tenant resource state provider when a multi-tenant monitor is provided")
}
}
func TestNewRouterServesTenantResourceListWithMultiTenantMonitor(t *testing.T) {
cfg := &config.Config{
DataPath: t.TempDir(),
ConfigPath: t.TempDir(),
}
mtm := &monitoring.MultiTenantMonitor{}
router := NewRouter(cfg, nil, mtm, nil, nil, "1.0.0")
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/api/resources?page=1&limit=100", nil)
req = req.WithContext(context.WithValue(req.Context(), OrgIDContextKey, "tenant-a"))
router.resourceHandlers.HandleListResources(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d, body=%s", rec.Code, rec.Body.String())
}
}