munin/main_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

123 lines
3.4 KiB
Go

package main
import (
"context"
"errors"
"os"
"path/filepath"
"strings"
"testing"
"munin/internal/export"
"munin/internal/store"
"munin/internal/workspace"
)
// aufbauZweiWorkspaces legt eine Kontroll-Datenbank mit zwei Workspaces an,
// jeder mit einem Projekt "plattform" und einem Eintrag.
func aufbauZweiWorkspaces(t *testing.T) (*store.ControlStore, *workspace.Manager, []store.Workspace) {
t.Helper()
ctx := context.Background()
dir := t.TempDir()
control, err := store.OpenControl(filepath.Join(dir, "control.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { control.Close() })
workspaces := workspace.NewManager(dir)
t.Cleanup(func() { workspaces.Close() })
var alle []store.Workspace
for _, name := range []string{"Intern", "Vertrieb"} {
w, err := control.CreateWorkspace(ctx, name)
if err != nil {
t.Fatal(err)
}
offen, err := workspaces.Get(w.ID)
if err != nil {
t.Fatal(err)
}
projekt, err := offen.Store.CreateProject(ctx, w.ID, "plattform", "Plattform", "")
if err != nil {
t.Fatal(err)
}
if _, err := offen.Store.PutEntry(ctx, store.EntryWrite{
ProjectID: projekt.ID, Slug: "wissen", Title: "Wissen",
Content: "aus " + name, Source: store.SourceHuman,
}); err != nil {
t.Fatal(err)
}
alle = append(alle, w)
}
return control, workspaces, alle
}
// TestFuerJedenWorkspaceErreichtAlle: Die wiederkehrenden Aufgaben liefen
// früher nur für den ältesten Workspace. Jetzt muss jeder drankommen.
func TestFuerJedenWorkspaceErreichtAlle(t *testing.T) {
control, workspaces, alle := aufbauZweiWorkspaces(t)
gesehen := map[string]bool{}
err := fuerJedenWorkspace(context.Background(), control, workspaces,
func(w store.Workspace, _ *workspace.Workspace) error {
gesehen[w.ID] = true
return nil
})
if err != nil {
t.Fatal(err)
}
for _, w := range alle {
if !gesehen[w.ID] {
t.Errorf("Workspace %q wurde übersprungen", w.Name)
}
}
}
// TestFuerJedenWorkspaceMachtNachFehlerWeiter: Ein kaputter Workspace darf die
// übrigen nicht aufhalten, der Fehler muss aber beim Aufrufer ankommen.
func TestFuerJedenWorkspaceMachtNachFehlerWeiter(t *testing.T) {
control, workspaces, alle := aufbauZweiWorkspaces(t)
kaputt := errors.New("kaputt")
var aufrufe int
err := fuerJedenWorkspace(context.Background(), control, workspaces,
func(w store.Workspace, _ *workspace.Workspace) error {
aufrufe++
if w.ID == alle[0].ID {
return kaputt
}
return nil
})
if aufrufe != len(alle) {
t.Errorf("%d Aufrufe, erwartet %d — nach dem Fehler wurde abgebrochen", aufrufe, len(alle))
}
if !errors.Is(err, kaputt) {
t.Errorf("Fehler ging verloren: %v", err)
}
}
// TestExportiereAlleSchreibtJedenWorkspace prüft den Weg von -export und dem
// täglichen Lauf: jeder Workspace in seinem eigenen Ordner, obwohl beide ein
// Projekt "plattform" haben.
func TestExportiereAlleSchreibtJedenWorkspace(t *testing.T) {
control, workspaces, alle := aufbauZweiWorkspaces(t)
ziel := t.TempDir()
if _, err := exportiereAlle(context.Background(), export.New(ziel), control, workspaces); err != nil {
t.Fatal(err)
}
for _, w := range alle {
inhalt, err := os.ReadFile(filepath.Join(ziel, w.ID, "plattform", "wissen.md"))
if err != nil {
t.Errorf("Workspace %q fehlt im Export: %v", w.Name, err)
continue
}
if want := "aus " + w.Name; !strings.Contains(string(inhalt), want) {
t.Errorf("Workspace %q: %q fehlt im Inhalt", w.Name, want)
}
}
}