package modulecontrol import ( "net/http/httptest" "strings" "testing" "github.com/gofiber/fiber/v2" ) func httptestJSONBody(s string) *strings.Reader { return strings.NewReader(s) } func newTestApp(h *Handler) *fiber.App { app := fiber.New() app.Use(h.Middleware()) app.Get("/health", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{"ok": true}) }) app.Get("/api/orders", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{"ok": true}) }) app.Post("/api/module-control/restart", h.Restart) app.Post("/api/module-control/maintenance", h.SetMaintenance) return app } func TestAuthRejectsEmptyConfiguredToken(t *testing.T) { h := &Handler{controlToken: ""} app := newTestApp(h) req := httptest.NewRequest("POST", "/api/module-control/restart", nil) req.Header.Set("X-Control-Token", "anything") resp, err := app.Test(req) if err != nil { t.Fatalf("app.Test: %v", err) } if resp.StatusCode != 401 { t.Errorf("status = %d, want 401 (empty configured token must never authenticate)", resp.StatusCode) } } func TestAuthRejectsWrongToken(t *testing.T) { h := &Handler{controlToken: "correct-secret"} app := newTestApp(h) req := httptest.NewRequest("POST", "/api/module-control/maintenance", httptestJSONBody(`{"enabled":true}`)) req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Control-Token", "wrong-secret") resp, err := app.Test(req) if err != nil { t.Fatalf("app.Test: %v", err) } if resp.StatusCode != 401 { t.Errorf("status = %d, want 401", resp.StatusCode) } if h.Maintenance() { t.Error("maintenance flag must not change on a rejected request") } } func TestMaintenanceMiddlewareBlocksAndExemptsHealthAndControl(t *testing.T) { h := &Handler{controlToken: "secret"} app := newTestApp(h) // Turn maintenance on via the real endpoint. req := httptest.NewRequest("POST", "/api/module-control/maintenance", httptestJSONBody(`{"enabled":true}`)) req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Control-Token", "secret") if _, err := app.Test(req); err != nil { t.Fatalf("enabling maintenance: %v", err) } if !h.Maintenance() { t.Fatal("maintenance should now be on") } // An ordinary route is blocked. resp, err := app.Test(httptest.NewRequest("GET", "/api/orders", nil)) if err != nil { t.Fatalf("app.Test: %v", err) } if resp.StatusCode != 503 { t.Errorf("ordinary route status = %d, want 503 while in maintenance", resp.StatusCode) } // /health stays reachable. resp, err = app.Test(httptest.NewRequest("GET", "/health", nil)) if err != nil { t.Fatalf("app.Test: %v", err) } if resp.StatusCode != 200 { t.Errorf("/health status = %d, want 200 even in maintenance", resp.StatusCode) } // The control route itself must stay reachable — a maintenance flag // that blocks its own toggle would be a one-way door. req = httptest.NewRequest("POST", "/api/module-control/maintenance", httptestJSONBody(`{"enabled":false}`)) req.Header.Set("Content-Type", "application/json") req.Header.Set("X-Control-Token", "secret") resp, err = app.Test(req) if err != nil { t.Fatalf("app.Test: %v", err) } if resp.StatusCode != 200 { t.Errorf("disabling maintenance status = %d, want 200", resp.StatusCode) } if h.Maintenance() { t.Error("maintenance should now be off") } }