package eventcatalog import ( "context" "errors" "fmt" "os" "testing" "time" "github.com/jackc/pgx/v5/pgxpool" ) func TestRepositoryBootstrapStateAndInitialActivation(t *testing.T) { pool := eventCatalogTestPool(t) repository := NewRepository(pool) ctx := t.Context() prefix := fmt.Sprintf("bootstrap-%d", time.Now().UnixNano()) first := catalogImportForIntegration(prefix + "-first") second := catalogImportForIntegration(prefix + "-second") t.Cleanup(func() { _, _ = pool.Exec(context.Background(), `DELETE FROM calendar_catalog_versions WHERE version IN ($1,$2)`, first.Version, second.Version) }) if err := repository.ImportDraft(ctx, first); err != nil { t.Fatal(err) } state, err := repository.CatalogState(ctx, first.Version) if err != nil || state.Status != CatalogStatusDraft || !state.matches(first) { t.Fatalf("draft state=%+v error=%v", state, err) } if err := repository.Approve(ctx, first.Version, "reviewer"); err != nil { t.Fatal(err) } if err := repository.ActivateInitial(ctx, first.Version, "operator"); err != nil { t.Fatal(err) } active, err := repository.ActiveCatalogState(ctx) if err != nil || active.Version != first.Version || active.Status != CatalogStatusActive { t.Fatalf("active state=%+v error=%v", active, err) } var auditCount int if err := pool.QueryRow(ctx, `SELECT count(*) FROM calendar_catalog_audit a JOIN calendar_catalog_versions v ON v.id=a.catalog_version_id WHERE v.version=$1`, first.Version).Scan(&auditCount); err != nil || auditCount != 3 { t.Fatalf("first audit count=%d error=%v", auditCount, err) } if err := repository.ImportDraft(ctx, second); err != nil { t.Fatal(err) } if err := repository.Approve(ctx, second.Version, "reviewer"); err != nil { t.Fatal(err) } if err := repository.ActivateInitial(ctx, second.Version, "operator"); !errors.Is(err, ErrCatalogConflict) { t.Fatalf("activation error=%v, want ErrCatalogConflict", err) } state, err = repository.CatalogState(ctx, second.Version) if err != nil || state.Status != CatalogStatusApproved { t.Fatalf("conflicting state=%+v error=%v", state, err) } if err := pool.QueryRow(ctx, `SELECT count(*) FROM calendar_catalog_audit a JOIN calendar_catalog_versions v ON v.id=a.catalog_version_id WHERE v.version=$1`, second.Version).Scan(&auditCount); err != nil || auditCount != 2 { t.Fatalf("second audit count=%d error=%v", auditCount, err) } } func eventCatalogTestPool(t *testing.T) *pgxpool.Pool { t.Helper() databaseURL := os.Getenv("TEST_DATABASE_URL") if databaseURL == "" { t.Skip("TEST_DATABASE_URL is not configured") } pool, err := pgxpool.New(context.Background(), databaseURL) if err != nil { t.Fatal(err) } t.Cleanup(pool.Close) return pool } func catalogImportForIntegration(version string) Import { input := validCoveredImport() input.Version = version input.SourceChecksum = "sha256:" + fmt.Sprintf("%064x", len(version)) for index := range input.Events { input.Events[index].ID = fmt.Sprintf("%s-event-%d", version, index) } return input }