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
2.2 KiB
Go
63 lines
2.2 KiB
Go
// IMP-09: Tenant-Scoping-Nachweis für den Postfach-Abruf
|
|
// (Akzeptanzkriterium 2). Bekannten Fehler vermeiden (known-issues-
|
|
// archivmail.md #4): Import-nahe Module waren praktisch ungetestet —
|
|
// dieser Test schließt eine reale Lücke, die vor IMP-09 bestand: kein
|
|
// bestehender Test bewies bislang, dass zwei Mandanten mit DEMSELBEN
|
|
// Postfachnamen sich nicht gegenseitig beeinflussen.
|
|
package imapimport
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
)
|
|
|
|
func TestScheduler_TenantScopingIsolatesSyncState(t *testing.T) {
|
|
store := setupStore(t)
|
|
scheduler := NewScheduler(store)
|
|
ctx := context.Background()
|
|
|
|
tenantA := "mandant-imp09-tenant-a"
|
|
tenantB := "mandant-imp09-tenant-b"
|
|
const mailbox = "INBOX" // BEWUSST derselbe Postfachname bei beiden Mandanten
|
|
|
|
clientA := &fakeIMAPClient{uidvalidity: 1, messages: []RemoteMessage{{UID: 1}, {UID: 2}}}
|
|
clientB := &fakeIMAPClient{uidvalidity: 1, messages: []RemoteMessage{{UID: 1}, {UID: 2}, {UID: 3}}}
|
|
|
|
handlerA := &recordingHandler{}
|
|
resultA, err := scheduler.RunOnce(ctx, tenantA, mailbox, clientA, handlerA)
|
|
if err != nil {
|
|
t.Fatalf("mandant a: %v", err)
|
|
}
|
|
if resultA.NewMessages != 2 {
|
|
t.Fatalf("mandant a: erwartete 2 neue nachrichten, habe %d", resultA.NewMessages)
|
|
}
|
|
|
|
handlerB := &recordingHandler{}
|
|
resultB, err := scheduler.RunOnce(ctx, tenantB, mailbox, clientB, handlerB)
|
|
if err != nil {
|
|
t.Fatalf("mandant b: %v", err)
|
|
}
|
|
// Entscheidender Nachweis: Mandant B startet trotz identischem
|
|
// Postfachnamen bei UID 0 — sähe er fälschlich den Zustand von
|
|
// Mandant A (UID 2 bereits synchronisiert), würden hier nur 1 statt
|
|
// 3 neue Nachrichten gezählt.
|
|
if resultB.NewMessages != 3 {
|
|
t.Fatalf("mandant b: erwartete 3 neue nachrichten (kein zustand von mandant a übernommen), habe %d", resultB.NewMessages)
|
|
}
|
|
|
|
stateA, err := store.Get(ctx, tenantA, mailbox)
|
|
if err != nil {
|
|
t.Fatalf("zustand mandant a: %v", err)
|
|
}
|
|
stateB, err := store.Get(ctx, tenantB, mailbox)
|
|
if err != nil {
|
|
t.Fatalf("zustand mandant b: %v", err)
|
|
}
|
|
if stateA.LastSyncedUID != 2 {
|
|
t.Fatalf("mandant a: erwartete last_synced_uid=2, habe %d", stateA.LastSyncedUID)
|
|
}
|
|
if stateB.LastSyncedUID != 3 {
|
|
t.Fatalf("mandant b: erwartete last_synced_uid=3, habe %d", stateB.LastSyncedUID)
|
|
}
|
|
}
|