Files
member-console/internal/lint/rawerror_test.go
T
cgalo5758 88db730fcc Add dual licensing and SPDX headers
Introduce a commercial license option alongside AGPL-3.0-only, require a
CLA for contributors, and document the terms in COMMERCIAL.md and
NOTICE. Add a script to stamp SPDX headers on Go files and apply it
across the tree.
2026-09-06 02:29:42 -05:00

90 lines
2.9 KiB
Go

// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
package lint
import (
"os"
"path/filepath"
"testing"
)
// writeFixture drops src at name under dir, creating parents.
func writeFixture(t *testing.T, dir, name, src string) string {
t.Helper()
path := filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(path, []byte(src), 0o644); err != nil {
t.Fatal(err)
}
return path
}
func TestRuleRawErrorRender(t *testing.T) {
dir := t.TempDir()
leaky := writeFixture(t, dir, "handlers.go", `package server
func (h *H) bad(err error, attErr error) {
h.renderFooPage(w, r, "", "Failed to save: "+err.Error()) // line 4: flag
fireErrorToast(w, attErr.Error()) // line 5: flag (suffixed identifier)
http.Error(w, err.Error(), 500) // line 6: flag
h.Logger.Error("failed", slog.Any("error", err)) // line 7: ok — slog only
slog.Error("failed to save: " + err.Error()) // line 8: ok — slog carve-out
return fmt.Errorf("wrap: %w", err) // line 9: ok — no UI sink
msg := err.Error() // line 10: ok — no UI sink on this line
h.renderFooPage(w, r, "", "Failed to save. See the logs.") // line 11: ok — generic text only
fireSuccessToast(w, "saved "+err.Error()) // line 12: flag (success toast is a sink too)
}
`)
writeFixture(t, dir, "handlers_test.go", `package server
func TestX(t *testing.T) {
h.renderFooPage(w, r, "", "boom: "+err.Error()) // tests are exempt
}
`)
got := ruleRawErrorRender(dir)
wantLines := map[int]bool{4: true, 5: true, 6: true, 12: true}
if len(got) != len(wantLines) {
t.Fatalf("got %d violations, want %d: %+v", len(got), len(wantLines), got)
}
for _, viol := range got {
if viol.File != leaky {
t.Errorf("violation in %s, want only %s", viol.File, leaky)
}
if viol.Rule != "raw-error-render" {
t.Errorf("rule = %q, want raw-error-render", viol.Rule)
}
if !wantLines[viol.Line] {
t.Errorf("unexpected violation at line %d", viol.Line)
}
delete(wantLines, viol.Line)
}
for line := range wantLines {
t.Errorf("missing violation at line %d", line)
}
}
func TestRuleRawErrorRender_CleanDir(t *testing.T) {
dir := t.TempDir()
writeFixture(t, dir, "clean.go", `package server
func (h *H) good(err error) {
if fe, ok := web.FieldErrorsFromDB(err, nil); ok {
h.renderFooFormErrors(w, r, fe)
return
}
h.Logger.Error("failed to save", slog.Any("error", err))
h.renderFooPage(w, r, "", "Failed to save. Details are in the server logs.")
}
`)
if got := ruleRawErrorRender(dir); len(got) != 0 {
t.Fatalf("got %d violations on clean fixture, want 0: %+v", len(got), got)
}
}