Testsuite für Import-Scheduler, Anhangsverarbeitung und Regelwerk, inklusive Tenant-Scoping und nicht-konformer Server. - tenant_scoping_test.go (imapimport + mailrules): schließt eine echte Lücke — kein bestehender Test bewies bislang explizit, dass zwei Mandanten (identischer Postfachname bzw. fehlende eigene Regel) sich nicht gegenseitig beeinflussen. - importtestgate/gate.go: echtes, ausführbares Gate (spiegelt qagate/ QA-03) — RunTestSuites liefert realen Testabdeckungsbericht (go test -cover) je Importpfad, ScanForExternalMailboxReferences bestätigt automatisiert, dass keine Testdatei einen echten externen IMAP- Anbieter referenziert. - Echten Bug beim eigenen Testlauf gefunden und behoben: die t.Cleanup-Löschfilter in scheduler_test.go/engine_test.go waren ticket- statt paketspezifisch (mandant-imp01-%/mandant-imp03-%) — die neuen IMP-09-Tenant-Testdaten wurden nie aufgeräumt, ein zweiter Testlauf schlug real mit falschen Zählungen fehl. Auf mandant-% verallgemeinert. Prüfungen (alle real durchgeführt, siehe mail/docs/IMP-09-PRUEFPROTOKOLL.md): 1. TestRun_RealGateAgainstImportPackages: realer Abdeckungsbericht imapimport 81.5%, attachments 94.4%, mailrules 71.2%. 2. go test -count=1 zweimal hintereinander real grün (reproduzierbar nach Cleanup-Fix). 3. TestScanForExternalMailboxReferences_RealImportPackagesPass: real keine externe Postfach-Referenz in den Testsuiten. Kein Umbau der geprüften Produktionslogik. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HhgFcLS8tYMhDJpP74C6AQ
63 lines
1.9 KiB
Go
63 lines
1.9 KiB
Go
// IMP-09: Tenant-Scoping-Nachweis für die Regelanwendung
|
|
// (Akzeptanzkriterium 2). Bekannten Fehler vermeiden (known-issues-
|
|
// archivmail.md #4): dieser Test schließt eine reale Lücke, die vor
|
|
// IMP-09 bestand — kein bestehender Test bewies bislang explizit, dass
|
|
// die Regeln eines Mandanten nicht auf die Nachrichten eines anderen
|
|
// angewendet werden.
|
|
package mailrules
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
func TestStore_TenantScopingIsolatesRuleApplication(t *testing.T) {
|
|
store := setupStore(t)
|
|
ctx := context.Background()
|
|
|
|
tenantA := "mandant-imp09-regeln-a"
|
|
tenantB := "mandant-imp09-regeln-b"
|
|
|
|
if _, err := store.Create(ctx, tenantA, Rule{Name: "a-regel", SenderPattern: "^ziel@", Category: "Kategorie-A", Priority: 10}); err != nil {
|
|
t.Fatalf("regel mandant a anlegen: %v", err)
|
|
}
|
|
// Mandant B legt bewusst KEINE eigene Regel an — sein Regelset muss
|
|
// leer bleiben, unabhängig davon, was Mandant A definiert hat.
|
|
|
|
rulesA, err := store.List(ctx, tenantA)
|
|
if err != nil {
|
|
t.Fatalf("list mandant a: %v", err)
|
|
}
|
|
if len(rulesA) != 1 {
|
|
t.Fatalf("mandant a: erwartete 1 eigene regel, habe %d", len(rulesA))
|
|
}
|
|
|
|
rulesB, err := store.List(ctx, tenantB)
|
|
if err != nil {
|
|
t.Fatalf("list mandant b: %v", err)
|
|
}
|
|
if len(rulesB) != 0 {
|
|
t.Fatalf("mandant b sieht regeln von mandant a — mandantentrennung verletzt, habe: %+v", rulesB)
|
|
}
|
|
|
|
engineA, err := NewEngine(rulesA)
|
|
if err != nil {
|
|
t.Fatalf("newengine mandant a: %v", err)
|
|
}
|
|
engineB, err := NewEngine(rulesB)
|
|
if err != nil {
|
|
t.Fatalf("newengine mandant b: %v", err)
|
|
}
|
|
|
|
msg := EmailMetadata{Sender: "ziel@lieferant.example"}
|
|
resultA := engineA.Evaluate(msg)
|
|
resultB := engineB.Evaluate(msg)
|
|
|
|
if resultA.Category != "Kategorie-A" {
|
|
t.Fatalf("mandant a: erwartete 'Kategorie-A', habe %q", resultA.Category)
|
|
}
|
|
if resultB.Category != "" {
|
|
t.Fatalf("mandant b wendet fälschlich regel von mandant a an, kategorie %q", resultB.Category)
|
|
}
|
|
}
|