86 lines
3.2 KiB
Go
86 lines
3.2 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestSourceAuditPersistsOperations(t *testing.T) {
|
|
url := isolatedIntegrationDatabaseURL(t, os.Getenv("TEST_DATABASE_URL"))
|
|
if url == "" {
|
|
t.Skip("TEST_DATABASE_URL is not set")
|
|
}
|
|
ctx := context.Background()
|
|
pool, err := pgxpool.New(ctx, url)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer pool.Close()
|
|
if err := ApplyMigrations(ctx, pool); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var exists bool
|
|
if err := pool.QueryRow(ctx, `SELECT to_regclass('source_configuration_events') IS NOT NULL`).Scan(&exists); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !exists {
|
|
t.Fatal("configuration operations have no persistent audit log")
|
|
}
|
|
_, err = pool.Exec(ctx, `INSERT INTO source_connections(id,source_type,name,enabled,updated_by) VALUES ('audit-test','dingtalk','测试知识库',true,'tester');
|
|
UPDATE source_connections SET enabled=false,updated_by='tester',updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET enabled=true,updated_by='tester',updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET schedule='{"refresh_interval_seconds":3600}',updated_by='tester',updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET archived_at=now(),archived_by='tester',enabled=false,updated_by='tester',updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET archived_at=archived_at,updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET archived_at=NULL,archived_by='',updated_by='tester',updated_at=now() WHERE id='audit-test';
|
|
UPDATE source_connections SET last_scheduled_at=now(),next_refresh_at=now(),updated_at=now() WHERE id='audit-test';`)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var actions []string
|
|
if err := pool.QueryRow(ctx, `SELECT array_agg(action ORDER BY id) FROM source_configuration_events WHERE connection_id='audit-test'`).Scan(&actions); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
store := NewStore(pool)
|
|
page, err := store.ListSourceAudit(ctx, 2, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(page.Items) != 2 || page.Total < 6 || page.Items[0].Action != "restored" {
|
|
t.Fatalf("bad audit page %+v", page)
|
|
}
|
|
next, err := store.ListSourceAudit(ctx, 2, 2)
|
|
if err != nil || len(next.Items) != 2 || next.Items[0].ID == page.Items[0].ID {
|
|
t.Fatalf("bad second page %+v %v", next, err)
|
|
}
|
|
tx, err := pool.Begin(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err = tx.Exec(ctx, `UPDATE source_connections SET enabled=true WHERE id='audit-test'`); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err = tx.Rollback(ctx); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
after, err := store.ListSourceAudit(ctx, 100, 0)
|
|
if err != nil || after.Total != page.Total {
|
|
t.Fatalf("rolled back changes must not appear %+v %v", after, err)
|
|
}
|
|
want := []string{"created", "paused", "resumed", "settings_updated", "archived", "restored"}
|
|
if len(actions) != len(want) {
|
|
t.Fatalf("audit actions=%v want=%v", actions, want)
|
|
}
|
|
for i := range want {
|
|
if actions[i] != want[i] {
|
|
t.Fatalf("actions=%v", actions)
|
|
}
|
|
}
|
|
var wrong int
|
|
if err := pool.QueryRow(ctx, `SELECT count(*) FROM source_configuration_events WHERE connection_id='audit-test' AND actor<>'tester'`).Scan(&wrong); err != nil || wrong != 0 {
|
|
t.Fatalf("incorrect actors %d %v", wrong, err)
|
|
}
|
|
}
|