package cabana import ( "context" "errors" "testing" "git.golem15.com/golem15/summercms/modules/backpack" "git.golem15.com/golem15/summercms/modules/lagoon" "git.golem15.com/golem15/summercms/modules/pact" "gorm.io/gorm" ) // subjectListener records every *pact.MCPSubjectChanged the bus delivers, // the type pier listens for. func subjectListener(app *backpack.App) *[]pact.MCPSubjectChanged { got := &[]pact.MCPSubjectChanged{} app.Events.Listen("test", func(_ context.Context, ev *pact.MCPSubjectChanged) error { *got = append(*got, *ev) return nil }) return got } func TestFireSubjectChangedReachesPointerListener(t *testing.T) { app := backpack.New(nil) got := subjectListener(app) fireSubjectChanged(context.Background(), app, pact.MCPSubjectPermissions, 7, 0, 9) if len(*got) != 2 { t.Fatalf("delivered %d events, want 2: %+v", len(*got), *got) } for i, id := range []uint{7, 9} { ev := (*got)[i] if ev.Guard != backendSubjectGuard || ev.UserID != id || ev.Kind != pact.MCPSubjectPermissions { t.Fatalf("event %d = %+v", i, ev) } } } func TestFireSubjectChangedWaitsForCommit(t *testing.T) { _, db := newListService(t) app := backpack.New(nil) got := subjectListener(app) err := lagoon.Transaction(context.Background(), db, func(ctx context.Context, tx *gorm.DB) error { fireSubjectChanged(withTx(ctx, tx), app, pact.MCPSubjectDeleted, 3) if len(*got) != 0 { t.Fatalf("fired inside the transaction: %+v", *got) } return nil }) if err != nil { t.Fatal(err) } if len(*got) != 1 || (*got)[0].UserID != 3 || (*got)[0].Kind != pact.MCPSubjectDeleted { t.Fatalf("after commit got %+v, want one deleted event for 3", *got) } *got = nil rollback := errors.New("rollback") err = lagoon.Transaction(context.Background(), db, func(ctx context.Context, tx *gorm.DB) error { fireSubjectChanged(withTx(ctx, tx), app, pact.MCPSubjectDeleted, 4) return rollback }) if !errors.Is(err, rollback) { t.Fatalf("err = %v, want rollback", err) } if len(*got) != 0 { t.Fatalf("a rolled-back transaction fired %+v", *got) } }