fix(account): isolate destructive PostgreSQL tests

This commit is contained in:
2026-10-06 00:08:19 +08:00
parent fa558d9a64
commit d0b95ba236
2 changed files with 84 additions and 15 deletions
+66
View File
@@ -0,0 +1,66 @@
package account_test
import (
"context"
"crypto/rand"
"database/sql"
"encoding/hex"
"fmt"
"net/url"
"os"
"testing"
hub "git.ipao.vip/rogee/creator-hub/internal/environment"
)
// Account tests truncate their fixtures. They must never run in the configured
// database schema; always initialize and destroy a separate schema first.
func TestMain(m *testing.M) { os.Exit(runAccountTests(m)) }
func runAccountTests(m *testing.M) (result int) {
databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
if databaseURL == "" {
return m.Run()
}
fail := func(err error) int {
fmt.Fprintln(os.Stderr, "initialize isolated account test schema:", err)
return 1
}
parsed, err := url.Parse(databaseURL)
if err != nil {
return fail(err)
}
bytes := make([]byte, 8)
if _, err := rand.Read(bytes); err != nil {
return fail(err)
}
schema := "account_test_" + hex.EncodeToString(bytes)
db, err := sql.Open("pgx", databaseURL)
if err != nil {
return fail(err)
}
defer db.Close()
if _, err := db.Exec(`CREATE SCHEMA "` + schema + `"`); err != nil {
return fail(err)
}
defer func() {
if _, err := db.Exec(`DROP SCHEMA "` + schema + `" CASCADE`); err != nil {
fmt.Fprintln(os.Stderr, "cleanup isolated account test schema:", err)
result = 1
}
}()
query := parsed.Query()
query.Set("search_path", schema)
parsed.RawQuery = query.Encode()
store, err := hub.Open(context.Background(), parsed.String())
if err != nil {
return fail(err)
}
if err := store.Close(); err != nil {
return fail(err)
}
if err := os.Setenv("CREATORHUB_POSTGRES_TEST_URL", parsed.String()); err != nil {
return fail(err)
}
return m.Run()
}
+18 -15
View File
@@ -7,6 +7,7 @@ import (
"io"
"os"
"path/filepath"
"strings"
"testing"
"github.com/jackc/pgx/v5"
@@ -126,6 +127,20 @@ func applyHubMigrationsForPhaseATest(t *testing.T, store *Store) {
}
}
func resetAccountTestFixtures(t *testing.T, store *Store) {
t.Helper()
var schema string
if err := store.db.QueryRow(`SELECT current_schema()`).Scan(&schema); err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(schema, "account_test_") {
t.Fatalf("refusing to clear non-test schema %q", schema)
}
if _, err := store.db.Exec(`TRUNCATE audit_event, network_exit, social_account, browser_env, gateway RESTART IDENTITY CASCADE`); err != nil {
t.Fatal(err)
}
}
func TestCreateAccountWithoutCookiesSkipsCredentialStore(t *testing.T) {
databaseURL := os.Getenv("CREATORHUB_POSTGRES_TEST_URL")
if databaseURL == "" {
@@ -138,11 +153,7 @@ func TestCreateAccountWithoutCookiesSkipsCredentialStore(t *testing.T) {
}
t.Cleanup(func() { _ = store.Close() })
applyHubMigrationsForPhaseATest(t, store)
if _, err := store.db.ExecContext(ctx, `
TRUNCATE audit_event, network_exit, social_account, browser_env,
gateway RESTART IDENTITY CASCADE`); err != nil {
t.Fatal(err)
}
resetAccountTestFixtures(t, store)
credentials := &testCredentialBridge{values: map[string]string{}}
account := Account{ID: "account-no-cookies", Name: "扫码账号", Platform: "douyin", PlatformAccountKey: "qr-login",
Tags: []string{}, Cookies: "",
@@ -168,11 +179,7 @@ func TestAccountCredentialCommitResult(t *testing.T) {
t.Fatal(err)
}
applyHubMigrationsForPhaseATest(t, store)
if _, err := store.db.ExecContext(ctx, `
TRUNCATE audit_event, network_exit, social_account, browser_env,
gateway RESTART IDENTITY CASCADE`); err != nil {
t.Fatal(err)
}
resetAccountTestFixtures(t, store)
credentials := &testCredentialBridge{values: map[string]string{}}
account := func(id, platformKey string) Account {
return Account{ID: id, Name: id, Platform: "douyin", PlatformAccountKey: platformKey, Tags: []string{}, Cookies: "sessionid=" + id,
@@ -240,11 +247,7 @@ func TestAccountStoreLifecycleAgainstPostgres(t *testing.T) {
t.Fatal(err)
}
t.Cleanup(func() { _ = store.Close() })
if _, err := store.db.ExecContext(ctx, `
TRUNCATE audit_event, network_exit, social_account, browser_env,
gateway RESTART IDENTITY CASCADE`); err != nil {
t.Fatal(err)
}
resetAccountTestFixtures(t, store)
credentials := &testCredentialBridge{values: map[string]string{}}
mustCreate := func(id, platformKey string) {
t.Helper()