Files
nexarch/internal/testdb/testdb_test.go
patrick 8b7e0427ba
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
QA-14: Isolationstest fuer testdb (Core, Mail), Testdatenbank-Strategie in TESTSTRATEGIE-CORE.md aktualisiert
2026-09-22 01:14:32 +02:00

86 lines
2.3 KiB
Go

package testdb
import (
"context"
"os"
"regexp"
"testing"
"github.com/jackc/pgx/v5/pgxpool"
)
func TestPool_SchemasAreIsolatedSiblingsShareAndCleanupRemoves(t *testing.T) {
dsn := os.Getenv("TEST_ADMIN_DSN")
if dsn == "" {
t.Skip("TEST_ADMIN_DSN nicht gesetzt, Integrationstest uebersprungen")
}
ctx := context.Background()
var schemas []string
t.Run("nutzung", func(t *testing.T) {
a, schemaA := PoolWithSchema(t, dsn, nil)
b, schemaB := PoolWithSchema(t, dsn, nil)
schemas = []string{schemaA, schemaB}
if schemaA == schemaB {
t.Fatalf("zwei Aufrufe lieferten dasselbe Schema %q", schemaA)
}
for _, p := range []*pgxpool.Pool{a, b} {
if _, err := p.Exec(ctx, `CREATE TABLE probe (v INT)`); err != nil {
t.Fatalf("gleicher tabellenname darf nicht kollidieren: %v", err)
}
}
if _, err := a.Exec(ctx, `INSERT INTO probe VALUES (1)`); err != nil {
t.Fatalf("insert: %v", err)
}
count := func(p *pgxpool.Pool) int {
var n int
if err := p.QueryRow(ctx, `SELECT count(*) FROM probe`).Scan(&n); err != nil {
t.Fatalf("count: %v", err)
}
return n
}
if got := count(b); got != 0 {
t.Fatalf("pool b sieht %d zeilen aus dem schema von pool a", got)
}
if got := count(Sibling(t, a, dsn)); got != 1 {
t.Fatalf("sibling sieht %d zeilen, want 1 (gleiches schema)", got)
}
open, err := Open(ctx, dsn, schemaA)
if err != nil {
t.Fatalf("open: %v", err)
}
defer open.Close()
if got := count(open); got != 1 {
t.Fatalf("open sieht %d zeilen, want 1", got)
}
})
admin, err := pgxpool.New(ctx, dsn)
if err != nil {
t.Fatalf("pool: %v", err)
}
defer admin.Close()
var left int
if err := admin.QueryRow(ctx, `SELECT count(*) FROM pg_namespace WHERE nspname = ANY($1)`, schemas).Scan(&left); err != nil {
t.Fatalf("schemas pruefen: %v", err)
}
if left != 0 {
t.Fatalf("nach dem cleanup existieren noch %d test-schemas", left)
}
}
func TestSlug_IsUniqueAndMatchesTenantSlugPattern(t *testing.T) {
pattern := regexp.MustCompile(`^[a-z][a-z0-9_]{1,48}$`)
seen := map[string]bool{}
for i := 0; i < 50; i++ {
s := Slug("ten09_isolation_very_long_prefix")
if !pattern.MatchString(s) {
t.Fatalf("slug %q passt nicht zum mandanten-slug-muster", s)
}
if seen[s] {
t.Fatalf("slug %q doppelt vergeben", s)
}
seen[s] = true
}
}