// Integrationstest (ARC-03): echte Postgres-Instanz, folgt derselben // Testhost-Konvention wie mail/internal/example (QA-01) — TEST_TENANT_DSN. package dedup import ( "context" "os" "testing" "github.com/jackc/pgx/v5/pgxpool" ) func setupStore(t *testing.T, tenantSlug string) *Store { t.Helper() dsn := os.Getenv("TEST_TENANT_DSN") if dsn == "" { t.Skip("TEST_TENANT_DSN nicht gesetzt, Integrationstest übersprungen") } ctx := context.Background() pool, err := pgxpool.New(ctx, dsn) if err != nil { t.Fatalf("pool: %v", err) } t.Cleanup(func() { pool.Close() }) store := NewStore(pool, tenantSlug) if err := store.EnsureSchema(ctx); err != nil { t.Fatalf("schema: %v", err) } t.Cleanup(func() { _, _ = pool.Exec(context.Background(), `DELETE FROM mail_content_hashes WHERE tenant_slug = $1`, tenantSlug) }) return store } // TestRegister_SameMessageFromTwoSourcesIsDuplicate ist die geforderte // Pflichtprüfung 1: dieselbe Nachricht aus zwei Quellen wird als // Duplikat erkannt. func TestRegister_SameMessageFromTwoSourcesIsDuplicate(t *testing.T) { store := setupStore(t, "mandant-arc03-a") ctx := context.Background() hash := "fixierter-inhalts-hash-fuer-test-1" isDup, _, err := store.Register(ctx, hash, "quelle-1/objekt") if err != nil { t.Fatalf("erste registrierung: %v", err) } if isDup { t.Fatal("erste registrierung eines hashes darf kein duplikat sein") } isDup, existing, err := store.Register(ctx, hash, "quelle-2/objekt") if err != nil { t.Fatalf("zweite registrierung: %v", err) } if !isDup { t.Fatal("erwartet: dieselbe nachricht aus zweiter quelle wird als duplikat erkannt") } if existing != "quelle-1/objekt" { t.Fatalf("erwartet referenz auf das original quelle-1/objekt, habe %q", existing) } } // TestRegister_SameContentTwoTenantsNotLinked ist die geforderte // Pflichtprüfung 2: zwei Mandanten mit identischem Mailinhalt werden // nicht fälschlich verknüpft. func TestRegister_SameContentTwoTenantsNotLinked(t *testing.T) { dsn := os.Getenv("TEST_TENANT_DSN") if dsn == "" { t.Skip("TEST_TENANT_DSN nicht gesetzt, Integrationstest übersprungen") } storeA := setupStore(t, "mandant-arc03-x") storeB := setupStore(t, "mandant-arc03-y") ctx := context.Background() hash := "identischer-inhalt-ueber-zwei-mandanten-hinweg" isDupA, _, err := storeA.Register(ctx, hash, "mandant-x/objekt") if err != nil { t.Fatalf("mandant a: %v", err) } if isDupA { t.Fatal("erste registrierung bei mandant a darf kein duplikat sein") } isDupB, existingB, err := storeB.Register(ctx, hash, "mandant-y/objekt") if err != nil { t.Fatalf("mandant b: %v", err) } if isDupB { t.Fatalf("mandant b wurde fälschlich mit mandant a verknüpft, existing=%q", existingB) } }