munin/internal/hilfe/hilfe_test.go
Thomas Adamek 466f1e40af Workspaces, Änderungshistorie, Papierkorb, Nutzungsübersicht, Hilfe
Umsetzung der Ausbaustufen 2.1, 3.6, 3.8, 3.9, 4.1, 4.2, 4.4, 4.6,
5.1–5.4 (Details in AUSBAUSTUFEN.md).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:44:52 +02:00

110 lines
3 KiB
Go

package hilfe
import (
"io/fs"
"regexp"
"strings"
"testing"
)
// TestJedeSeiteHatEineDatei stellt sicher, dass die Liste in hilfe.go und die
// Dateien in seiten/ zusammenpassen — in beide Richtungen. Eine Seite ohne
// Datei gäbe einen Fehler beim Aufruf, eine Datei ohne Listeneintrag wäre
// unerreichbar und würde unbemerkt veralten.
func TestJedeSeiteHatEineDatei(t *testing.T) {
gelistet := map[string]bool{}
for _, s := range Alle() {
gelistet[s.Slug] = true
if _, err := s.Markdown(); err != nil {
t.Errorf("Seite %q: %v", s.Slug, err)
}
}
dateien, err := fs.Glob(seitenFS, "seiten/*.md")
if err != nil {
t.Fatal(err)
}
for _, d := range dateien {
slug := strings.TrimSuffix(strings.TrimPrefix(d, "seiten/"), ".md")
if !gelistet[slug] {
t.Errorf("Datei %s steht nicht in der Seitenliste", d)
}
}
}
// TestInterneLinksFuehrenZuSeiten prüft jeden Link der Form (/hilfe/…) in
// allen Seiten. Wird eine Seite umbenannt, fällt ein vergessener Verweis hier
// auf statt erst als 404 beim Lesen.
func TestInterneLinksFuehrenZuSeiten(t *testing.T) {
link := regexp.MustCompile(`\(/hilfe/([a-z0-9-]+)\)`)
for _, s := range Alle() {
md, err := s.Markdown()
if err != nil {
t.Fatal(err)
}
for _, treffer := range link.FindAllStringSubmatch(md, -1) {
if _, ok := Finde(treffer[1]); !ok {
t.Errorf("Seite %q verlinkt auf unbekannte Hilfeseite %q", s.Slug, treffer[1])
}
}
}
}
func TestFindeUnbekannteSeite(t *testing.T) {
if _, ok := Finde("gibt-es-nicht"); ok {
t.Error("Finde meldet eine Seite, die es nicht gibt")
}
}
func TestRenderTabellenUndKeinRohHTML(t *testing.T) {
html, err := Render("| a | b |\n|---|---|\n| 1 | 2 |\n\n<script>alert(1)</script>")
if err != nil {
t.Fatal(err)
}
if !strings.Contains(html, "<table>") {
t.Error("Tabellen werden nicht als Tabelle dargestellt")
}
if strings.Contains(html, "<script>") {
t.Error("Roh-HTML wird durchgelassen")
}
}
// TestAlleGibtKopie stellt sicher, dass ein Aufrufer die Navigation nicht
// für alle anderen verändern kann.
func TestAlleGibtKopie(t *testing.T) {
a := Alle()
a[0].Titel = "verändert"
if Alle()[0].Titel == "verändert" {
t.Error("Alle gibt die interne Liste statt einer Kopie heraus")
}
}
func TestSichtbarBlendetAdminSeitenAus(t *testing.T) {
for _, s := range Sichtbar(false) {
if s.NurAdmin {
t.Errorf("Seite %q ist nur für Admins, wird aber allen gezeigt", s.Slug)
}
}
if len(Sichtbar(true)) != len(Alle()) {
t.Error("ein Admin sieht nicht alle Seiten")
}
}
// TestAllgemeineSeitenVerlinkenKeineAdminSeiten: Ein Link auf eine Admin-Seite
// liefe für alle anderen ins Leere (404).
func TestAllgemeineSeitenVerlinkenKeineAdminSeiten(t *testing.T) {
link := regexp.MustCompile(`\(/hilfe/([a-z0-9-]+)\)`)
for _, s := range Sichtbar(false) {
md, err := s.Markdown()
if err != nil {
t.Fatal(err)
}
for _, treffer := range link.FindAllStringSubmatch(md, -1) {
if ziel, ok := Finde(treffer[1]); ok && ziel.NurAdmin {
t.Errorf("Seite %q verlinkt auf die Admin-Seite %q", s.Slug, ziel.Slug)
}
}
}
}