package eventcatalog import ( "context" "errors" "reflect" "testing" ) func TestBootstrapCatalogTransitionsToActive(t *testing.T) { t.Parallel() store := &bootstrapStoreFake{} createdJobs := 7 result, err := BootstrapCatalog(t.Context(), store, validCoveredImport(), 1405, "reviewer", "operator", func(context.Context) (int, error) { return createdJobs, nil }) if err != nil { t.Fatal(err) } if want := []string{"IMPORTED", "APPROVED", "ACTIVATED"}; !reflect.DeepEqual(result.Transitions, want) { t.Fatalf("transitions=%v, want %v", result.Transitions, want) } if result.Status != CatalogStatusActive || result.NoOp || result.CreatedJobs != createdJobs { t.Fatalf("result=%+v", result) } } func TestBootstrapCatalogResumesAndNoOps(t *testing.T) { t.Parallel() tests := []struct { name string status CatalogStatus transitions []string }{ {name: "draft", status: CatalogStatusDraft, transitions: []string{"APPROVED", "ACTIVATED"}}, {name: "approved", status: CatalogStatusApproved, transitions: []string{"ACTIVATED"}}, {name: "active", status: CatalogStatusActive}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Parallel() input := validCoveredImport() store := &bootstrapStoreFake{state: stateFromImport(input, test.status), active: stateFromImport(input, CatalogStatusActive)} if test.status != CatalogStatusActive { store.active = CatalogState{} } result, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil }) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(result.Transitions, test.transitions) { t.Fatalf("transitions=%v, want %v", result.Transitions, test.transitions) } if result.NoOp != (test.status == CatalogStatusActive) { t.Fatalf("no_op=%t", result.NoOp) } }) } } func TestBootstrapCatalogFailsClosed(t *testing.T) { t.Parallel() input := validCoveredImport() tests := []struct { name string state CatalogState active CatalogState mutate func(*Import) }{ {name: "retired version", state: stateFromImport(input, CatalogStatusRetired)}, {name: "different active version", active: CatalogState{Version: "newer", Status: CatalogStatusActive}}, {name: "checksum mismatch", state: stateFromImport(input, CatalogStatusDraft), mutate: func(input *Import) { input.SourceChecksum = "different" }}, {name: "metadata mismatch", state: stateFromImport(input, CatalogStatusDraft), mutate: func(input *Import) { input.SourceVersion = "different" }}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { t.Parallel() candidate := input if test.mutate != nil { test.mutate(&candidate) } store := &bootstrapStoreFake{state: test.state, active: test.active} _, err := BootstrapCatalog(t.Context(), store, candidate, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil }) if !errors.Is(err, ErrCatalogConflict) { t.Fatalf("error=%v, want ErrCatalogConflict", err) } if len(store.transitions) != 0 { t.Fatalf("unexpected transitions=%v", store.transitions) } }) } } func TestBootstrapCatalogRejectsInvalidReviewAndRetriesScheduling(t *testing.T) { t.Parallel() input := validCoveredImport() input.SourceChecksum = "review-required-before-activation" store := &bootstrapStoreFake{} if _, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil }); err == nil { t.Fatal("expected placeholder checksum error") } input = validCoveredImport() store = &bootstrapStoreFake{state: stateFromImport(input, CatalogStatusActive), active: stateFromImport(input, CatalogStatusActive)} wantErr := errors.New("scheduling failed") if _, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, wantErr }); !errors.Is(err, wantErr) { t.Fatalf("error=%v, want scheduling error", err) } result, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 2, nil }) if err != nil || result.CreatedJobs != 2 || result.NoOp { t.Fatalf("result=%+v error=%v", result, err) } } type bootstrapStoreFake struct { state CatalogState active CatalogState transitions []string } func (f *bootstrapStoreFake) CatalogState(context.Context, string) (CatalogState, error) { if f.state.Version == "" { return CatalogState{}, ErrCatalogNotFound } return f.state, nil } func (f *bootstrapStoreFake) ActiveCatalogState(context.Context) (CatalogState, error) { if f.active.Version == "" { return CatalogState{}, ErrCatalogNotFound } return f.active, nil } func (f *bootstrapStoreFake) ImportDraft(_ context.Context, input Import) error { f.state = stateFromImport(input, CatalogStatusDraft) f.transitions = append(f.transitions, "IMPORTED") return nil } func (f *bootstrapStoreFake) Approve(_ context.Context, _ string, _ string) error { f.state.Status = CatalogStatusApproved f.transitions = append(f.transitions, "APPROVED") return nil } func (f *bootstrapStoreFake) ActivateInitial(_ context.Context, _ string, _ string) error { f.state.Status = CatalogStatusActive f.active = f.state f.transitions = append(f.transitions, "ACTIVATED") return nil }