69 lines
2.9 KiB
Go
69 lines
2.9 KiB
Go
package opsdocs
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func readPlan(t *testing.T) string {
|
|
t.Helper()
|
|
// Test laeuft aus internal/opsdocs/ heraus, Repo-Root ist zwei Ebenen hoeher.
|
|
path := filepath.Join("..", "..", IncidentResponsePlanPath)
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("incident-response-plan nicht lesbar (%s): %v", path, err)
|
|
}
|
|
return string(data)
|
|
}
|
|
|
|
func requireContains(t *testing.T, content, substr, why string) {
|
|
t.Helper()
|
|
if !strings.Contains(content, substr) {
|
|
t.Fatalf("erwartet %q im incident-response-plan (%s), nicht gefunden", substr, why)
|
|
}
|
|
}
|
|
|
|
// Akzeptanzkriterium 1: Ablaufplan dokumentiert Erkennung/Eskalation/
|
|
// Meldefristen/Verantwortlichkeiten.
|
|
func TestPlan_DocumentsDetectionEscalationAndResponsibilities(t *testing.T) {
|
|
content := readPlan(t)
|
|
requireContains(t, content, "Erkennung", "Abschnitt Erkennung fehlt")
|
|
requireContains(t, content, "Eskalationskette", "Abschnitt Eskalation fehlt")
|
|
requireContains(t, content, "Incident Commander", "Verantwortlichkeits-Rolle fehlt")
|
|
requireContains(t, content, "Datenschutzbeauftragter", "DSB-Rolle fehlt")
|
|
}
|
|
|
|
// Akzeptanzkriterium 2: DSGVO-72-Stunden-Meldefrist ist als Prozessschritt
|
|
// mit Verantwortlichem hinterlegt.
|
|
func TestPlan_Documents72HourGDPRDeadlineWithResponsibleRole(t *testing.T) {
|
|
content := readPlan(t)
|
|
requireContains(t, content, "72 Stunden", "72-Stunden-Frist fehlt")
|
|
requireContains(t, content, "Art. 33", "Verweis auf Art. 33 DSGVO fehlt")
|
|
requireContains(t, content, "Verantwortlich für die Meldung", "Zuständigkeit für die Meldung fehlt")
|
|
}
|
|
|
|
// Akzeptanzkriterium 3: Plan verweist konkret auf die Audit-Log-Quellen
|
|
// (Core AUD-01/AUD-03/AUD-05), die im Vorfall herangezogen werden.
|
|
func TestPlan_ReferencesConcreteAuditLogSources(t *testing.T) {
|
|
content := readPlan(t)
|
|
requireContains(t, content, "AUD-01", "Verweis auf AUD-01 fehlt")
|
|
requireContains(t, content, "AUD-03", "Verweis auf AUD-03 (Export) fehlt")
|
|
requireContains(t, content, "internal/audit", "konkreter Code-Pfad zum Audit-Log fehlt")
|
|
requireContains(t, content, "StreamCSV", "konkrete Export-Funktion fehlt")
|
|
}
|
|
|
|
// Zusaetzliche Absicherung: die drei geforderten Pruefungen sind im
|
|
// Dokument tatsaechlich mit einem Ergebnis (PASS/OFFEN) festgehalten,
|
|
// nicht nur als Vorhaben erwaehnt — verhindert, dass "durchgefuehrt"
|
|
// behauptet wird, ohne das Ergebnis schriftlich festzuhalten (Ticket-
|
|
// Vorgabe: "Nicht durchgefuehrte Pruefungen zaehlen als offen").
|
|
func TestPlan_RecordsAllThreeRequiredCheckResults(t *testing.T) {
|
|
content := readPlan(t)
|
|
requireContains(t, content, "Prüfung 1", "Ergebnis der Tabletop-Übung fehlt")
|
|
requireContains(t, content, "Prüfung 2", "Ergebnis der Meldefrist-Vollständigkeitsprüfung fehlt")
|
|
requireContains(t, content, "Prüfung 3", "Ergebnis der Kontaktlisten-Prüfung fehlt")
|
|
requireContains(t, content, "Status: OFFEN", "ehrlicher Offen-Status fuer die nicht durchfuehrbare Kontaktlisten-Pruefung fehlt")
|
|
}
|