package command import ( "io" "testing" "time" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/debug_events" "github.com/zitadel/zitadel/internal/zerrors" ) func TestCommands_CreateDebugEvents(t *testing.T) { ctx := authz.NewMockContextWithPermissions("instance1", "org1", "user1", nil) type fields struct { eventstore func(*testing.T) *eventstore.Eventstore } type args struct { dbe *DebugEvents } tests := []struct { name string fields fields args args want *domain.ObjectDetails wantErr error }{ { name: "filter error", fields: fields{ eventstore: expectEventstore( expectFilterError(io.ErrClosedPipe), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, wantErr: io.ErrClosedPipe, }, { name: "already exists", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, wantErr: zerrors.ThrowAlreadyExists(nil, "COMMAND-Aex6j", "debug aggregate already exists"), }, { name: "double added event, already exists", fields: fields{ eventstore: expectEventstore( expectFilter(), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, wantErr: zerrors.ThrowAlreadyExists(nil, "COMMAND-Aex6j", "debug aggregate already exists"), }, { name: "changed event, not found", fields: fields{ eventstore: expectEventstore( expectFilter(), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventChanged{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, wantErr: zerrors.ThrowNotFound(nil, "COMMAND-Thie6", "debug aggregate not found"), }, { name: "removed event, not found", fields: fields{ eventstore: expectEventstore( expectFilter(), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, }, }}, wantErr: zerrors.ThrowNotFound(nil, "COMMAND-Ohna9", "debug aggregate not found"), }, { name: "changed after removed event, not found", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, DebugEventChanged{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, wantErr: zerrors.ThrowNotFound(nil, "COMMAND-Thie6", "debug aggregate not found"), }, { name: "double removed event, not found", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, }, }}, wantErr: zerrors.ThrowNotFound(nil, "COMMAND-Ohna9", "debug aggregate not found"), }, { name: "added, ok", fields: fields{ eventstore: expectEventstore( expectFilter(), expectPush( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, }, }}, want: &domain.ObjectDetails{ ResourceOwner: "instance1", }, }, { name: "changed, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), expectPush( debug_events.NewChangedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("b"), ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventChanged{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("b"), }, }, }}, want: &domain.ObjectDetails{ ResourceOwner: "instance1", }, }, { name: "removed, ok", fields: fields{ eventstore: expectEventstore( expectFilter( eventFromEventPusher( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), ), ), expectPush( debug_events.NewRemovedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, }, }}, want: &domain.ObjectDetails{ ResourceOwner: "instance1", }, }, { name: "added, changed, changed, removed ok", fields: fields{ eventstore: expectEventstore( expectFilter(), expectPush( debug_events.NewAddedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("a"), ), debug_events.NewChangedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("b"), ), debug_events.NewChangedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, gu.Ptr("c"), ), debug_events.NewRemovedEvent( ctx, debug_events.NewAggregate("dbg1", "instance1"), time.Millisecond, ), ), ), }, args: args{&DebugEvents{ AggregateID: "dbg1", Events: []DebugEvent{ DebugEventAdded{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("a"), }, DebugEventChanged{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("b"), }, DebugEventChanged{ ProjectionSleep: time.Millisecond, Blob: gu.Ptr("c"), }, DebugEventRemoved{ ProjectionSleep: time.Millisecond, }, }, }}, want: &domain.ObjectDetails{ ResourceOwner: "instance1", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { c := &Commands{ eventstore: tt.fields.eventstore(t), } got, err := c.CreateDebugEvents(ctx, tt.args.dbe) require.ErrorIs(t, err, tt.wantErr) assert.Equal(t, tt.want, got) }) } }