check / check (push) Successful in 3m25s
MAINTENANCE_MODE did nothing but make the healthcheck JSON report maintenanceMode: true; no request was ever served differently, so an operator who set it expecting requests to be refused got nothing. It is removed from the configuration, the startup configuration log line, the healthcheck JSON, the README and the Settings page, together with the uncalled Server.MaintenanceMode method and the healthcheck's dependency on the configuration. A leftover value in an environment is ignored like any other unknown variable. Model: opus-5-5
149 lines
3.9 KiB
Go
149 lines
3.9 KiB
Go
package handlers_test
|
|
|
|
import (
|
|
"context"
|
|
"html"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/netip"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"sneak.berlin/go/webhooker/internal/config"
|
|
"sneak.berlin/go/webhooker/internal/handlers"
|
|
"sneak.berlin/go/webhooker/internal/session"
|
|
)
|
|
|
|
// settingsShown renders the Settings page over cfg as a logged-in user
|
|
// and returns the value it shows for each variable name, plus the
|
|
// whole page.
|
|
func settingsShown(
|
|
t *testing.T, cfg *config.Config,
|
|
) (map[string]string, string) {
|
|
t.Helper()
|
|
|
|
var h *handlers.Handlers
|
|
|
|
var sess *session.Session
|
|
|
|
app := newTestAppWithConfig(t, cfg, &h, &sess)
|
|
app.RequireStart()
|
|
|
|
t.Cleanup(app.RequireStop)
|
|
|
|
req := httptest.NewRequestWithContext(
|
|
context.Background(), http.MethodGet, "/settings", nil,
|
|
)
|
|
for _, c := range authenticatedCookies(t, sess, "id", "admin") {
|
|
req.AddCookie(c)
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
h.HandleSettings().ServeHTTP(w, req)
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
|
|
body := w.Body.String()
|
|
|
|
row := regexp.MustCompile(
|
|
`<code[^>]*>([A-Z_]+)</code>\s*<code[^>]*>([^<]*)</code>`,
|
|
)
|
|
|
|
shown := map[string]string{}
|
|
for _, match := range row.FindAllStringSubmatch(body, -1) {
|
|
shown[match[1]] = html.UnescapeString(match[2])
|
|
}
|
|
|
|
return shown, body
|
|
}
|
|
|
|
func TestSettingsPageShowsLoadedConfiguration(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Each of METRICS_USERNAME, METRICS_PASSWORD and SENTRY_DSN is the
|
|
// only one of the three set in one of the content tests, so each
|
|
// row is checked against its own field.
|
|
cfg := &config.Config{
|
|
DataDir: t.TempDir(),
|
|
Debug: true,
|
|
Environment: config.EnvironmentDev,
|
|
MetricsUsername: "scraper",
|
|
MetricsPassword: "",
|
|
Port: 9123,
|
|
SentryDSN: "",
|
|
BindAddress: "192.0.2.10",
|
|
RetentionSweepInterval: 17 * time.Minute,
|
|
SessionIdleTimeout: 3 * time.Hour,
|
|
ReceiverRateLimit: 77,
|
|
TrustedProxies: []netip.Prefix{
|
|
netip.MustParsePrefix("10.1.0.0/16"),
|
|
},
|
|
AllowedEgressCIDRs: []netip.Prefix{
|
|
netip.MustParsePrefix("192.168.5.0/24"),
|
|
netip.MustParsePrefix("fd00::/8"),
|
|
},
|
|
}
|
|
|
|
shown, body := settingsShown(t, cfg)
|
|
|
|
assert.Equal(t, map[string]string{
|
|
"WEBHOOKER_ENVIRONMENT": "dev",
|
|
"PORT": "9123",
|
|
"BIND_ADDRESS": "192.0.2.10",
|
|
"DATA_DIR": cfg.DataDir,
|
|
"DEBUG": "true",
|
|
"METRICS_USERNAME": "scraper",
|
|
"METRICS_PASSWORD": "not set",
|
|
"SENTRY_DSN": "not set",
|
|
"RETENTION_SWEEP_INTERVAL": "17m0s",
|
|
"SESSION_IDLE_TIMEOUT": "3h0m0s",
|
|
"RECEIVER_RATE_LIMIT": "77",
|
|
"TRUSTED_PROXIES": "10.1.0.0/16",
|
|
"ALLOWED_EGRESS_CIDRS": "192.168.5.0/24, fd00::/8",
|
|
}, shown)
|
|
|
|
assert.Contains(
|
|
t, body, `href="/settings"`,
|
|
"the navigation bar links to the page",
|
|
)
|
|
}
|
|
|
|
func TestSettingsPageShowsUnsetValues(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const metricsPassword = "metrics-password-1f9a"
|
|
|
|
shown, body := settingsShown(t, &config.Config{
|
|
DataDir: t.TempDir(),
|
|
MetricsPassword: metricsPassword,
|
|
})
|
|
|
|
assert.Equal(t, "not set", shown["METRICS_USERNAME"])
|
|
assert.Equal(t, "set", shown["METRICS_PASSWORD"])
|
|
assert.Equal(t, "not set", shown["SENTRY_DSN"])
|
|
assert.NotContains(t, body, metricsPassword)
|
|
assert.Equal(t, "none", shown["TRUSTED_PROXIES"])
|
|
assert.Equal(t, "none", shown["ALLOWED_EGRESS_CIDRS"])
|
|
}
|
|
|
|
func TestSettingsPageShowsSentryDSNOnlyAsSet(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
const (
|
|
sentryKey = "dsnkey7c2e"
|
|
sentryDSN = "https://" + sentryKey + "@errors.example.com/42"
|
|
)
|
|
|
|
shown, body := settingsShown(t, &config.Config{
|
|
DataDir: t.TempDir(),
|
|
SentryDSN: sentryDSN,
|
|
})
|
|
|
|
assert.Equal(t, "not set", shown["METRICS_USERNAME"])
|
|
assert.Equal(t, "not set", shown["METRICS_PASSWORD"])
|
|
assert.Equal(t, "set", shown["SENTRY_DSN"])
|
|
assert.NotContains(t, body, sentryKey)
|
|
}
|