diff --git a/backend/v3/api/instance/v2/convert/instance.go b/backend/v3/api/instance/v2/convert/instance.go new file mode 100644 index 000000000..81047c190 --- /dev/null +++ b/backend/v3/api/instance/v2/convert/instance.go @@ -0,0 +1,52 @@ +package convert + +import ( + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/backend/v3/domain" + "github.com/zitadel/zitadel/cmd/build" + instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" +) + +/* + * Domain Model to GRPC v2 + */ + +func DomainInstanceListModelToGRPCResponse(instances []*domain.Instance) []*instance.Instance { + toReturn := make([]*instance.Instance, len(instances)) + + for i, inst := range instances { + toReturn[i] = DomainInstanceModelToGRPCResponse(inst) + } + + return toReturn +} + +func DomainInstanceModelToGRPCResponse(inst *domain.Instance) *instance.Instance { + return &instance.Instance{ + Id: inst.ID, + ChangeDate: timestamppb.New(inst.UpdatedAt), + CreationDate: timestamppb.New(inst.CreatedAt), + State: instance.State_STATE_RUNNING, // TODO(IAM-Marco): Not sure what to put here + Name: inst.Name, + Version: build.Version(), + Domains: domainInstanceDomainListModelToGRPCResponse(inst.Domains), + } +} + +func domainInstanceDomainListModelToGRPCResponse(dms []*domain.InstanceDomain) []*instance.Domain { + toReturn := make([]*instance.Domain, len(dms)) + for i, domain := range dms { + isGenerated := domain.IsGenerated != nil && *domain.IsGenerated + isPrimary := domain.IsPrimary != nil && *domain.IsPrimary + toReturn[i] = &instance.Domain{ + InstanceId: domain.InstanceID, + CreationDate: timestamppb.New(domain.CreatedAt), + Domain: domain.Domain, + Primary: isPrimary, + Generated: isGenerated, + } + } + + return toReturn +} diff --git a/backend/v3/api/instance/v2/convert/instance_test.go b/backend/v3/api/instance/v2/convert/instance_test.go new file mode 100644 index 000000000..134ba0e6d --- /dev/null +++ b/backend/v3/api/instance/v2/convert/instance_test.go @@ -0,0 +1,204 @@ +package convert + +import ( + "testing" + "time" + + "github.com/muhlemmer/gu" + "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/backend/v3/domain" + instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" +) + +func TestDomainInstanceModelToGRPCResponse(t *testing.T) { + // Given + t.Parallel() + + now := time.Now().UTC() + yesterday := now.AddDate(0, 0, -1) + + inputInstance := &domain.Instance{ + ID: "instance-1", + Name: "Instance One", + CreatedAt: yesterday, + UpdatedAt: now, + Domains: []*domain.InstanceDomain{ + { + InstanceID: "instance-1", + Domain: "d1.example.com", + IsPrimary: gu.Ptr(true), + CreatedAt: yesterday, + }, + { + InstanceID: "instance-1", + Domain: "d2.example.com", + IsGenerated: gu.Ptr(true), + CreatedAt: yesterday, + }, + { + InstanceID: "instance-1", + Domain: "d3.example.com", + IsPrimary: gu.Ptr(true), + IsGenerated: gu.Ptr(false), + CreatedAt: yesterday, + }, + { + InstanceID: "instance-1", + Domain: "d4.example.com", + IsPrimary: gu.Ptr(false), + IsGenerated: gu.Ptr(true), + CreatedAt: yesterday, + }, + }, + } + + expectedInstance := &instance.Instance{ + Id: "instance-1", + ChangeDate: timestamppb.New(now), + CreationDate: timestamppb.New(yesterday), + State: instance.State_STATE_RUNNING, + Name: "Instance One", + Version: "", + Domains: []*instance.Domain{ + { + InstanceId: "instance-1", + CreationDate: timestamppb.New(yesterday), + Domain: "d1.example.com", + Primary: true, + Generated: false, + }, + { + InstanceId: "instance-1", + CreationDate: timestamppb.New(yesterday), + Domain: "d2.example.com", + Primary: false, + Generated: true, + }, + { + InstanceId: "instance-1", + CreationDate: timestamppb.New(yesterday), + Domain: "d3.example.com", + Primary: true, + Generated: false, + }, + { + InstanceId: "instance-1", + CreationDate: timestamppb.New(yesterday), + Domain: "d4.example.com", + Primary: false, + Generated: true, + }, + }, + } + + // Test + res := DomainInstanceModelToGRPCResponse(inputInstance) + + // Verify + assert.Equal(t, expectedInstance, res) +} + +func TestDomainInstanceListModelToGRPCResponse(t *testing.T) { + t.Parallel() + now := time.Now() + + tt := []struct { + testName string + inputResult []*domain.Instance + expectedResult []*instance.Instance + }{ + { + testName: "empty result", + inputResult: []*domain.Instance{}, + expectedResult: []*instance.Instance{}, + }, + { + testName: "single instance without domains", + inputResult: []*domain.Instance{ + { + ID: "instance1", + Name: "test-instance", + CreatedAt: now, + UpdatedAt: now, + Domains: nil, + }, + }, + expectedResult: []*instance.Instance{ + { + Id: "instance1", + Name: "test-instance", + CreationDate: timestamppb.New(now), + ChangeDate: timestamppb.New(now), + State: instance.State_STATE_RUNNING, + Domains: []*instance.Domain{}, + }, + }, + }, + { + testName: "multiple instances with domains", + inputResult: []*domain.Instance{ + { + ID: "instance1", + Name: "test-instance-1", + CreatedAt: now, + UpdatedAt: now, + Domains: []*domain.InstanceDomain{ + { + InstanceID: "instance1", + Domain: "domain1.com", + CreatedAt: now, + IsPrimary: gu.Ptr(true), + IsGenerated: gu.Ptr(false), + }, + }, + }, + { + ID: "instance2", + Name: "test-instance-2", + CreatedAt: now, + UpdatedAt: now, + Domains: nil, + }, + }, + expectedResult: []*instance.Instance{ + { + Id: "instance1", + Name: "test-instance-1", + CreationDate: timestamppb.New(now), + ChangeDate: timestamppb.New(now), + State: instance.State_STATE_RUNNING, + Domains: []*instance.Domain{ + { + InstanceId: "instance1", + Domain: "domain1.com", + CreationDate: timestamppb.New(now), + Primary: true, + Generated: false, + }, + }, + }, + { + Id: "instance2", + Name: "test-instance-2", + CreationDate: timestamppb.New(now), + ChangeDate: timestamppb.New(now), + State: instance.State_STATE_RUNNING, + Domains: []*instance.Domain{}, + }, + }, + }, + } + + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Test + result := DomainInstanceListModelToGRPCResponse(tc.inputResult) + + // Verify + assert.Equal(t, tc.expectedResult, result) + }) + } +} diff --git a/backend/v3/api/instance/v2/instance.go b/backend/v3/api/instance/v2/instance.go new file mode 100644 index 000000000..0716529b9 --- /dev/null +++ b/backend/v3/api/instance/v2/instance.go @@ -0,0 +1,101 @@ +package instancev2 + +import ( + "context" + "errors" + + "connectrpc.com/connect" + "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/zitadel/zitadel/backend/v3/api/instance/v2/convert" + "github.com/zitadel/zitadel/backend/v3/domain" + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/repository" + "github.com/zitadel/zitadel/internal/zerrors" + filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta" + instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" +) + +func DeleteInstance(ctx context.Context, request *connect.Request[instance.DeleteInstanceRequest]) (*connect.Response[instance.DeleteInstanceResponse], error) { + instanceDeleteCmd := domain.NewDeleteInstanceCommand(request.Msg.GetInstanceId()) + + err := domain.Invoke(ctx, instanceDeleteCmd, domain.WithInstanceRepo(repository.InstanceRepository())) + + if err != nil { + if errors.Is(err, &database.NoRowFoundError{}) { + return nil, zerrors.ThrowNotFound(err, "INST-QVrUwc", "instance not found") + } + return nil, err + } + + return &connect.Response[instance.DeleteInstanceResponse]{ + Msg: &instance.DeleteInstanceResponse{ + // TODO(IAM-Marco): Change this with the real update date when OrganizationRepo.Update() + // returns the timestamp + DeletionDate: timestamppb.Now(), + }, + }, nil +} + +func GetInstance(ctx context.Context, request *connect.Request[instance.GetInstanceRequest]) (*connect.Response[instance.GetInstanceResponse], error) { + instanceGetCmd := domain.NewGetInstanceCommand(request.Msg.GetInstanceId()) + + err := domain.Invoke(ctx, instanceGetCmd, domain.WithInstanceRepo(repository.InstanceRepository())) + + if err != nil { + if errors.Is(err, &database.NoRowFoundError{}) { + return nil, zerrors.ThrowNotFound(err, "INST-QVrUwc", "instance not found") + } + return nil, err + } + + return &connect.Response[instance.GetInstanceResponse]{ + Msg: &instance.GetInstanceResponse{ + Instance: convert.DomainInstanceModelToGRPCResponse(instanceGetCmd.Result()), + }, + }, nil +} + +func UpdateInstance(ctx context.Context, request *connect.Request[instance.UpdateInstanceRequest]) (*connect.Response[instance.UpdateInstanceResponse], error) { + instanceUpdateCmd := domain.NewUpdateInstanceCommand(request.Msg.GetInstanceId(), request.Msg.GetInstanceName()) + + err := domain.Invoke(ctx, instanceUpdateCmd, domain.WithInstanceRepo(repository.InstanceRepository())) + + if err != nil { + return nil, err + } + + return &connect.Response[instance.UpdateInstanceResponse]{ + Msg: &instance.UpdateInstanceResponse{ + // TODO(IAM-Marco): Change this with the real update date when InstanceRepo.Update() + // returns the timestamp + ChangeDate: timestamppb.Now(), + }, + }, nil +} + +func ListInstances(ctx context.Context, request *connect.Request[instance.ListInstancesRequest]) (*connect.Response[instance.ListInstancesResponse], error) { + instancesListCmd := domain.NewListInstancesCommand(request.Msg) + + err := domain.Invoke( + ctx, + instancesListCmd, + domain.WithInstanceRepo(repository.InstanceRepository()), + domain.WithInstanceDomainRepo(repository.InstanceDomainRepository()), + ) + if err != nil { + return nil, err + } + + instances := instancesListCmd.Result() + return &connect.Response[instance.ListInstancesResponse]{ + Msg: &instance.ListInstancesResponse{ + Instances: convert.DomainInstanceListModelToGRPCResponse(instances), + Pagination: &filter.PaginationResponse{ + // TODO(IAM-Marco): return correct value. Tracked in https://github.com/zitadel/zitadel/issues/10955 + TotalResult: uint64(len(instances)), + AppliedLimit: uint64(request.Msg.GetPagination().GetLimit()), + }, + }, + }, nil +} diff --git a/backend/v3/api/instance/v2/server.go b/backend/v3/api/instance/v2/server.go deleted file mode 100644 index f50eed8dd..000000000 --- a/backend/v3/api/instance/v2/server.go +++ /dev/null @@ -1,21 +0,0 @@ -package v2 - -// this file has been commented out to pass the linter - -// import ( -// "github.com/zitadel/zitadel/backend/v3/telemetry/logging" -// "github.com/zitadel/zitadel/backend/v3/telemetry/tracing" -// ) - -// var ( -// logger logging.Logger -// tracer tracing.Tracer -// ) - -// func SetLogger(l logging.Logger) { -// logger = l -// } - -// func SetTracer(t tracing.Tracer) { -// tracer = t -// } diff --git a/backend/v3/api/org/v2/server.go b/backend/v3/api/org/v2/server.go deleted file mode 100644 index fdfc45a2b..000000000 --- a/backend/v3/api/org/v2/server.go +++ /dev/null @@ -1,21 +0,0 @@ -package orgv2 - -// this file has been commented out to pass the linter - -// import ( -// "github.com/zitadel/zitadel/backend/v3/telemetry/logging" -// "github.com/zitadel/zitadel/backend/v3/telemetry/tracing" -// ) - -// var ( -// logger logging.Logger -// tracer tracing.Tracer -// ) - -// func SetLogger(l logging.Logger) { -// logger = l -// } - -// func SetTracer(t tracing.Tracer) { -// tracer = t -// } diff --git a/backend/v3/domain/instance.go b/backend/v3/domain/instance.go index 60c6381ba..e0717c44b 100644 --- a/backend/v3/domain/instance.go +++ b/backend/v3/domain/instance.go @@ -94,6 +94,8 @@ type instanceChanges interface { } // InstanceRepository is the interface for the instance repository. +// +//go:generate mockgen -typed -package domainmock -destination ./mock/instance.mock.go . InstanceRepository type InstanceRepository interface { Repository diff --git a/backend/v3/domain/instance_delete.go b/backend/v3/domain/instance_delete.go new file mode 100644 index 000000000..4df3279a7 --- /dev/null +++ b/backend/v3/domain/instance_delete.go @@ -0,0 +1,97 @@ +package domain + +import ( + "context" + "strings" + + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/instance" + "github.com/zitadel/zitadel/internal/repository/milestone" + "github.com/zitadel/zitadel/internal/zerrors" +) + +type DeleteInstanceCommand struct { + ID string `json:"id"` + + // InstanceDomains is public for testing purposes + // do not use this field + InstanceDomains []string + // InstanceName is public for testing purposes + // do not use this field + InstanceName string +} + +// RequiresTransaction implements [Transactional]. +func (d *DeleteInstanceCommand) RequiresTransaction() {} + +func NewDeleteInstanceCommand(instanceID string) *DeleteInstanceCommand { + return &DeleteInstanceCommand{ID: instanceID} +} + +// Events implements [Commander]. +func (d *DeleteInstanceCommand) Events(ctx context.Context, opts *InvokeOpts) ([]eventstore.Command, error) { + milestoneAggregate := milestone.NewInstanceAggregate(d.ID) + instanceAggregate := instance.NewAggregate(d.ID) + + return []eventstore.Command{ + instance.NewInstanceRemovedEvent(ctx, &instanceAggregate.Aggregate, d.InstanceName, d.InstanceDomains), + milestone.NewReachedEvent(ctx, milestoneAggregate, milestone.InstanceDeleted), + }, nil +} + +// Execute implements [Commander]. +func (d *DeleteInstanceCommand) Execute(ctx context.Context, opts *InvokeOpts) (err error) { + instanceRepo := opts.instanceRepo.LoadDomains() + + instanceToDelete, err := instanceRepo.Get(ctx, opts.DB(), database.WithCondition(instanceRepo.IDCondition(d.ID))) + if err != nil { + return err + } + + d.InstanceDomains = make([]string, len(instanceToDelete.Domains)) + for i, domain := range instanceToDelete.Domains { + d.InstanceDomains[i] = domain.Domain + } + + d.InstanceName = instanceToDelete.Name + + deletedRows, err := instanceRepo.Delete(ctx, opts.DB(), instanceToDelete.ID) + if err != nil { + return err + } + + if deletedRows > 1 { + err = zerrors.ThrowInternalf(nil, "DOM-Od04Jx", "expecting 1 row deleted, got %d", deletedRows) + return err + } + + if deletedRows < 1 { + err = zerrors.ThrowNotFound(nil, "DOM-daglwD", "instance not found") + } + + return err +} + +// String implements [Commander]. +func (d *DeleteInstanceCommand) String() string { + return "DeleteInstanceCommand" +} + +// Validate implements [Commander]. +func (d *DeleteInstanceCommand) Validate(ctx context.Context, opts *InvokeOpts) (err error) { + if d.ID = strings.TrimSpace(d.ID); d.ID == "" { + return zerrors.ThrowInvalidArgument(nil, "DOM-VpQ9lF", "Errors.Invalid.Argument") + } + + if authZErr := opts.Permissions.CheckInstancePermission(ctx, InstanceWritePermission); authZErr != nil { + return zerrors.ThrowPermissionDenied(authZErr, "DOM-Yz8f1X", "permission denied") + } + + return nil +} + +var ( + _ Commander = (*DeleteInstanceCommand)(nil) + _ Transactional = (*DeleteInstanceCommand)(nil) +) diff --git a/backend/v3/domain/instance_delete_test.go b/backend/v3/domain/instance_delete_test.go new file mode 100644 index 000000000..0a660da20 --- /dev/null +++ b/backend/v3/domain/instance_delete_test.go @@ -0,0 +1,340 @@ +package domain_test + +import ( + "context" + "errors" + "testing" + + "github.com/brianvoe/gofakeit/v6" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/zitadel/zitadel/backend/v3/domain" + domainmock "github.com/zitadel/zitadel/backend/v3/domain/mock" + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dbmock" + noopdb "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/noop" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/instance" + "github.com/zitadel/zitadel/internal/repository/milestone" + "github.com/zitadel/zitadel/internal/zerrors" +) + +func TestDeleteInstanceCommand_Validate(t *testing.T) { + t.Parallel() + permissionErr := errors.New("permission error") + tt := []struct { + name string + permissionChecker func(ctrl *gomock.Controller) domain.PermissionChecker + inputID string + expectedError error + }{ + { + name: "empty id", + inputID: "", + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-VpQ9lF", "Errors.Invalid.Argument"), + }, + { + name: "whitespace id", + inputID: " ", + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-VpQ9lF", "Errors.Invalid.Argument"), + }, + { + name: "when user is missing permission should return permission denied", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(permissionErr) + + return permChecker + }, + expectedError: zerrors.ThrowPermissionDenied(permissionErr, "DOM-Yz8f1X", "permission denied"), + inputID: "instance-1", + }, + { + name: "valid id", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(nil) + + return permChecker + }, + inputID: "instance-1", + }, + } + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + // Given + d := &domain.DeleteInstanceCommand{ID: tc.inputID} + + cmdOpts := &domain.InvokeOpts{} + if tc.permissionChecker != nil { + ctrl := gomock.NewController(t) + cmdOpts.Permissions = tc.permissionChecker(ctrl) + } + + // Test + err := d.Validate(context.Background(), cmdOpts) + + // Verify + assert.Equal(t, tc.expectedError, err) + }) + } +} + +func TestDeleteInstanceCommand_Events(t *testing.T) { + t.Parallel() + // Given + cmd := domain.NewDeleteInstanceCommand("instance-1") + expectedEvents := []eventstore.Command{ + instance.NewInstanceRemovedEvent(context.Background(), &instance.NewAggregate("instance-1").Aggregate, "instance-1", []string{}), + milestone.NewReachedEvent(context.Background(), milestone.NewInstanceAggregate("instance-1"), milestone.InstanceDeleted), + } + + // Test + events, err := cmd.Events(context.Background(), nil) + + // Verify + assert.NoError(t, err) + assert.Len(t, events, len(expectedEvents)) + assert.IsType(t, &instance.InstanceRemovedEvent{}, events[0]) + assert.IsType(t, &milestone.ReachedEvent{}, events[1]) +} + +func TestDeleteInstanceCommand_Execute(t *testing.T) { + t.Parallel() + + ctx := authz.NewMockContext("inst-1", "org-1", gofakeit.UUID()) + deleteErr := errors.New("delete error") + getErr := errors.New("get error") + + tests := []struct { + testName string + instanceRepo func(ctrl *gomock.Controller) domain.InstanceRepository + + inputInstanceID string + + expectedError error + expectedInstanceName string + expectedInstanceDomains []string + }{ + { + testName: "when retrieving instance fails should return error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(nil, getErr) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedError: getErr, + }, + { + testName: "when delete instance fails should return error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, nil) + + instanceRepo.EXPECT(). + Delete(gomock.Any(), gomock.Any(), "instance-1"). + Times(1). + Return(int64(0), deleteErr) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedError: deleteErr, + expectedInstanceName: "My instance 1", + expectedInstanceDomains: []string{"d1.example.com", "d2.example.com", "d3.example.com"}, + }, + { + testName: "when more than one row deleted should return internal error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, nil) + + instanceRepo.EXPECT(). + Delete(gomock.Any(), gomock.Any(), "instance-1"). + Times(1). + Return(int64(2), nil) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedError: zerrors.ThrowInternalf(nil, "DOM-Od04Jx", "expecting 1 row deleted, got %d", 2), + expectedInstanceName: "My instance 1", + expectedInstanceDomains: []string{"d1.example.com", "d2.example.com", "d3.example.com"}, + }, + { + testName: "when no rows deleted should return not found error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, nil) + + instanceRepo.EXPECT(). + Delete(gomock.Any(), gomock.Any(), "instance-1"). + Times(1). + Return(int64(0), nil) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedError: zerrors.ThrowNotFound(nil, "DOM-daglwD", "instance not found"), + expectedInstanceName: "My instance 1", + expectedInstanceDomains: []string{"d1.example.com", "d2.example.com", "d3.example.com"}, + }, + { + testName: "when one row deleted should execute successfully", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, nil) + + instanceRepo.EXPECT(). + Delete(gomock.Any(), gomock.Any(), "instance-1"). + Times(1). + Return(int64(1), nil) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedInstanceName: "My instance 1", + expectedInstanceDomains: []string{"d1.example.com", "d2.example.com", "d3.example.com"}, + }, + } + + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Given + d := domain.NewDeleteInstanceCommand(tc.inputInstanceID) + ctrl := gomock.NewController(t) + opts := &domain.InvokeOpts{ + Invoker: domain.NewTransactionInvoker(nil), + } + domain.WithQueryExecutor(new(noopdb.Pool))(opts) + + if tc.instanceRepo != nil { + domain.WithInstanceRepo(tc.instanceRepo(ctrl))(opts) + } + + // Test + err := d.Execute(ctx, opts) + + // Verify + assert.Equal(t, tc.expectedError, err) + assert.Equal(t, tc.expectedInstanceName, d.InstanceName) + assert.ElementsMatch(t, tc.expectedInstanceDomains, d.InstanceDomains) + }) + } +} diff --git a/backend/v3/domain/instance_domain.go b/backend/v3/domain/instance_domain.go index 5a9499f33..7ca01ae66 100644 --- a/backend/v3/domain/instance_domain.go +++ b/backend/v3/domain/instance_domain.go @@ -59,6 +59,7 @@ type instanceDomainChanges interface { SetType(typ DomainType) database.Change } +//go:generate mockgen -typed -package domainmock -destination ./mock/instance_domain.mock.go . InstanceDomainRepository type InstanceDomainRepository interface { Repository diff --git a/backend/v3/domain/instance_get.go b/backend/v3/domain/instance_get.go new file mode 100644 index 000000000..3b8bbe1a4 --- /dev/null +++ b/backend/v3/domain/instance_get.go @@ -0,0 +1,61 @@ +package domain + +import ( + "context" + "strings" + + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/zerrors" +) + +type GetInstanceQuery struct { + ID string `json:"id"` + returnedInstance *Instance +} + +// Result implements [Querier]. +func (g *GetInstanceQuery) Result() *Instance { + return g.returnedInstance +} + +func NewGetInstanceCommand(instanceID string) *GetInstanceQuery { + return &GetInstanceQuery{ID: instanceID} +} + +// Execute implements [Executor]. +func (g *GetInstanceQuery) Execute(ctx context.Context, opts *InvokeOpts) (err error) { + instanceRepo := opts.instanceRepo.LoadDomains() + + instance, err := instanceRepo.Get(ctx, opts.DB(), database.WithCondition(instanceRepo.IDCondition(g.ID))) + if err != nil { + return err + } + + g.returnedInstance = instance + return nil +} + +// String implements [Executor]. +func (g *GetInstanceQuery) String() string { + return "GetInstanceCommand" +} + +// Validate implements [Validator]. +func (g *GetInstanceQuery) Validate(ctx context.Context, opts *InvokeOpts) (err error) { + g.ID = strings.TrimSpace(g.ID) + if g.ID == "" { + return zerrors.ThrowInvalidArgument(nil, "DOM-32a0o2", "invalid instance ID") + } + if g.ID != authz.GetInstance(ctx).InstanceID() { + return zerrors.ThrowPermissionDenied(nil, "DOM-n0SvVB", "input instance ID doesn't match context instance") + } + + if authZErr := opts.Permissions.CheckInstancePermission(ctx, InstanceReadPermission); authZErr != nil { + return zerrors.ThrowPermissionDenied(authZErr, "DOM-Uq6b00", "permission denied") + } + + return nil +} + +var _ Querier[*Instance] = (*GetInstanceQuery)(nil) diff --git a/backend/v3/domain/instance_get_test.go b/backend/v3/domain/instance_get_test.go new file mode 100644 index 000000000..4d70cf445 --- /dev/null +++ b/backend/v3/domain/instance_get_test.go @@ -0,0 +1,213 @@ +package domain_test + +import ( + "context" + "errors" + "testing" + + "github.com/brianvoe/gofakeit/v6" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/zitadel/zitadel/backend/v3/domain" + domainmock "github.com/zitadel/zitadel/backend/v3/domain/mock" + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dbmock" + noopdb "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/noop" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/zerrors" +) + +func TestGetInstanceCommand_Validate(t *testing.T) { + t.Parallel() + + permissionErr := errors.New("permission error") + + tests := []struct { + name string + permissionChecker func(ctrl *gomock.Controller) domain.PermissionChecker + inputInstanceID string + ctx context.Context + expectedError error + }{ + { + name: "empty instance id, error", + inputInstanceID: "", + ctx: context.Background(), + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-32a0o2", "invalid instance ID"), + }, + { + name: "whitespace instance id, error", + inputInstanceID: " ", + ctx: context.Background(), + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-32a0o2", "invalid instance ID"), + }, + { + name: "instance id mismatch, error", + inputInstanceID: "instance1", + ctx: authz.NewMockContext("instance2", "", ""), + expectedError: zerrors.ThrowPermissionDenied(nil, "DOM-n0SvVB", "input instance ID doesn't match context instance"), + }, + { + name: "when user is missing permission should return permission denied", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceReadPermission). + Times(1). + Return(permissionErr) + + return permChecker + }, + inputInstanceID: "instance1", + ctx: authz.NewMockContext("instance1", "", ""), + expectedError: zerrors.ThrowPermissionDenied(permissionErr, "DOM-Uq6b00", "permission denied"), + }, + { + name: "valid instance id, success", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceReadPermission). + Times(1). + Return(nil) + + return permChecker + }, + inputInstanceID: "instance1", + ctx: authz.NewMockContext("instance1", "", ""), + expectedError: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + // Given + cmd := domain.NewGetInstanceCommand(tt.inputInstanceID) + + cmdOpts := &domain.InvokeOpts{} + if tt.permissionChecker != nil { + ctrl := gomock.NewController(t) + cmdOpts.Permissions = tt.permissionChecker(ctrl) + } + + // Test + err := cmd.Validate(tt.ctx, cmdOpts) + + // Verify + assert.Equal(t, tt.expectedError, err) + }) + } +} + +func TestGetInstanceCommand_Execute(t *testing.T) { + t.Parallel() + + ctx := authz.NewMockContext("inst-1", "org-1", gofakeit.UUID()) + getErr := errors.New("get error") + + tt := []struct { + testName string + + instanceRepo func(ctrl *gomock.Controller) domain.InstanceRepository + + inputInstanceID string + + expectedError error + expectedInstance *domain.Instance + }{ + { + testName: "when retrieving instance fails should return error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(nil, getErr) + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedError: getErr, + }, + { + testName: "when retrieving instance succeeds should set instance on struct and return no error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + instanceRepo.EXPECT(). + Get( + gomock.Any(), + gomock.Any(), + dbmock.QueryOptions(database.WithCondition( + instanceRepo.IDCondition("instance-1"), + )), + ). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, nil) + + return instanceRepo + }, + inputInstanceID: "instance-1", + expectedInstance: &domain.Instance{ + ID: "instance-1", + Name: "My instance 1", + Domains: []*domain.InstanceDomain{ + {Domain: "d1.example.com"}, + {Domain: "d2.example.com"}, + {Domain: "d3.example.com"}, + }, + }, + }, + } + + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Given + g := domain.NewGetInstanceCommand(tc.inputInstanceID) + ctrl := gomock.NewController(t) + opts := &domain.InvokeOpts{ + Invoker: domain.NewTransactionInvoker(nil), + } + domain.WithQueryExecutor(new(noopdb.Pool))(opts) + + if tc.instanceRepo != nil { + domain.WithInstanceRepo(tc.instanceRepo(ctrl))(opts) + } + + // Test + err := g.Execute(ctx, opts) + + // Verify + assert.Equal(t, tc.expectedError, err) + assert.Equal(t, tc.expectedInstance, g.Result()) + }) + } +} diff --git a/backend/v3/domain/instance_list.go b/backend/v3/domain/instance_list.go new file mode 100644 index 000000000..7580f6428 --- /dev/null +++ b/backend/v3/domain/instance_list.go @@ -0,0 +1,122 @@ +package domain + +import ( + "context" + + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/internal/zerrors" + instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" +) + +type ListInstancesQuery struct { + Request *instance.ListInstancesRequest + + toReturn []*Instance +} + +// Result implements Querier. +func (l *ListInstancesQuery) Result() []*Instance { + return l.toReturn +} + +var _ Querier[[]*Instance] = (*ListInstancesQuery)(nil) + +func NewListInstancesCommand(inputRequest *instance.ListInstancesRequest) *ListInstancesQuery { + return &ListInstancesQuery{ + Request: inputRequest, + } +} + +// Execute implements [Querier]. +func (l *ListInstancesQuery) Execute(ctx context.Context, opts *InvokeOpts) (err error) { + instanceRepo := opts.instanceRepo.LoadDomains() + domainRepo := opts.instanceDomainRepo + + sorting := l.Sorting(instanceRepo) + limit, offset := l.Pagination() + conds, err := l.conditions(instanceRepo, domainRepo) + if err != nil { + return err + } + + instances, err := instanceRepo.List(ctx, opts.DB(), conds, sorting, limit, offset) + if err != nil { + return err + } + + l.toReturn = instances + + return nil +} + +func (l *ListInstancesQuery) Pagination() (database.QueryOption, database.QueryOption) { + return database.WithLimit(l.Request.GetPagination().GetLimit()), + database.WithOffset(uint32(l.Request.GetPagination().GetOffset())) +} + +func (l *ListInstancesQuery) conditions(instanceRepo InstanceRepository, domainRepo InstanceDomainRepository) (database.QueryOption, error) { + conditions := make([]database.Condition, len(l.Request.GetQueries())) + for i, query := range l.Request.GetQueries() { + switch assertedType := query.GetQuery().(type) { + case *instance.Query_DomainQuery: + domainConditions := make([]database.Condition, len(assertedType.DomainQuery.GetDomains())) + for j, domain := range assertedType.DomainQuery.GetDomains() { + domainConditions[j] = domainRepo.DomainCondition(database.TextOperationEqual, domain) + } + conditions[i] = instanceRepo.ExistsDomain( + database.Or(domainConditions...), + ) + case *instance.Query_IdQuery: + idConditions := make([]database.Condition, len(assertedType.IdQuery.GetIds())) + for j, id := range assertedType.IdQuery.GetIds() { + idConditions[j] = instanceRepo.IDCondition(id) + } + conditions[i] = database.Or(idConditions...) + default: + return nil, zerrors.ThrowInvalidArgument(NewUnexpectedQueryTypeError(assertedType), "DOM-AU99kR", "List.Query.Invalid") + } + } + + return database.WithCondition(database.And(conditions...)), nil +} + +func (l *ListInstancesQuery) Sorting(instanceRepo InstanceRepository) database.QueryOption { + var sortingCol database.Column + + switch l.Request.GetSortingColumn() { + case instance.FieldName_FIELD_NAME_CREATION_DATE: + sortingCol = instanceRepo.CreatedAtColumn() + case instance.FieldName_FIELD_NAME_ID: + sortingCol = instanceRepo.IDColumn() + case instance.FieldName_FIELD_NAME_NAME: + sortingCol = instanceRepo.NameColumn() + case instance.FieldName_FIELD_NAME_UNSPECIFIED: + fallthrough + default: + return func(opts *database.QueryOpts) {} + } + + orderDirection := database.OrderDirectionDesc + if l.Request.GetPagination().GetAsc() { + orderDirection = database.OrderDirectionAsc + } + + return database.WithOrderBy(orderDirection, sortingCol) +} + +// String implements [Querier]. +func (l *ListInstancesQuery) String() string { + return "ListInstancesCommand" +} + +// Validate implements [Querier]. +func (l *ListInstancesQuery) Validate(ctx context.Context, opts *InvokeOpts) (err error) { + // TODO(IAM-Marco): This is likely wrong, because it's checking the read permission of + // the instance in context. In here, instead we should probably loop through all retrieved + // instances and check their permissions. + if authZErr := opts.Permissions.CheckInstancePermission(ctx, InstanceReadPermission); authZErr != nil { + return zerrors.ThrowPermissionDenied(authZErr, "DOM-cuT6Ws", "permission denied") + } + + return nil +} diff --git a/backend/v3/domain/instance_list_test.go b/backend/v3/domain/instance_list_test.go new file mode 100644 index 000000000..1cf43fc98 --- /dev/null +++ b/backend/v3/domain/instance_list_test.go @@ -0,0 +1,328 @@ +package domain_test + +import ( + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + + "github.com/zitadel/zitadel/backend/v3/domain" + domainmock "github.com/zitadel/zitadel/backend/v3/domain/mock" + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dbmock" + noopdb "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/noop" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/zerrors" + filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta" + instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" +) + +func TestListInstancesCommand_Sorting(t *testing.T) { + t.Parallel() + tt := []struct { + name string + request *instance.ListInstancesRequest + + expectedSortingDirection database.OrderDirection + expectedOrderBy database.Columns + }{ + { + name: "sort by creation date DESC", + request: &instance.ListInstancesRequest{ + SortingColumn: instance.FieldName_FIELD_NAME_CREATION_DATE.Enum(), + }, + + expectedSortingDirection: database.OrderDirectionDesc, + expectedOrderBy: database.Columns{database.NewColumn("instances", "created_at")}, + }, + { + name: "sort by creation date ASC", + request: &instance.ListInstancesRequest{ + SortingColumn: instance.FieldName_FIELD_NAME_CREATION_DATE.Enum(), + Pagination: &filter.PaginationRequest{Asc: true}, + }, + + expectedSortingDirection: database.OrderDirectionAsc, + expectedOrderBy: database.Columns{database.NewColumn("instances", "created_at")}, + }, + { + name: "sort by id DESC", + request: &instance.ListInstancesRequest{ + SortingColumn: instance.FieldName_FIELD_NAME_ID.Enum(), + }, + expectedSortingDirection: database.OrderDirectionDesc, + expectedOrderBy: database.Columns{database.NewColumn("instances", "id")}, + }, + { + name: "sort by id ASC", + request: &instance.ListInstancesRequest{ + SortingColumn: instance.FieldName_FIELD_NAME_ID.Enum(), + Pagination: &filter.PaginationRequest{Asc: true}, + }, + expectedSortingDirection: database.OrderDirectionAsc, + expectedOrderBy: database.Columns{database.NewColumn("instances", "id")}, + }, + { + name: "unspecified field", + request: &instance.ListInstancesRequest{ + SortingColumn: instance.FieldName_FIELD_NAME_UNSPECIFIED.Enum(), + }, + expectedSortingDirection: database.OrderDirectionAsc, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + // Given + mockCtrl := gomock.NewController(t) + mockRepo := domainmock.NewInstanceRepo(mockCtrl) + + cmd := domain.NewListInstancesCommand(tc.request) + opts := &database.QueryOpts{} + + // Test + queryOpt := cmd.Sorting(mockRepo) + queryOpt(opts) + + // Verify + assert.Equal(t, tc.expectedOrderBy, opts.OrderBy) + assert.Equal(t, tc.expectedSortingDirection, opts.Ordering) + }) + } +} + +func TestListInstancesCommand_Execute(t *testing.T) { + t.Parallel() + listErr := errors.New("list mock error") + + tt := []struct { + testName string + + repos func(ctrl *gomock.Controller, queryParams ...database.QueryOption) (domain.InstanceRepository, domain.InstanceDomainRepository) + + queryParams []database.QueryOption + inputRequest *instance.ListInstancesRequest + + expectedInstances []*domain.Instance + expectedError error + }{ + { + testName: "when listing instances fails should return error", + repos: func(ctrl *gomock.Controller, _ ...database.QueryOption) (domain.InstanceRepository, domain.InstanceDomainRepository) { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + domainRepo := domainmock.NewInstancesDomainRepo(ctrl) + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + domainExistsORedConditions := instanceRepo.ExistsDomain( + database.Or([]database.Condition{ + domainRepo.DomainCondition(database.TextOperationEqual, "domain1.example.com"), + domainRepo.DomainCondition(database.TextOperationEqual, "domain2.example.com"), + }...), + ) + + idConditions := database.Or( + []database.Condition{ + instanceRepo.IDCondition("instance-1"), + instanceRepo.IDCondition("instance-2"), + }..., + ) + + instanceRepo.EXPECT(). + List(gomock.Any(), gomock.Any(), + dbmock.QueryOptions( + database.WithCondition(database.And( + idConditions, domainExistsORedConditions, + )), + ), + dbmock.QueryOptions(database.WithOrderBy(database.OrderDirectionDesc, instanceRepo.NameColumn())), + dbmock.QueryOptions(database.WithLimit(2)), + dbmock.QueryOptions(database.WithOffset(1)), + ). + Times(1). + Return(nil, listErr) + + return instanceRepo, domainRepo + }, + inputRequest: &instance.ListInstancesRequest{ + Pagination: &filter.PaginationRequest{Limit: 2, Offset: 1, Asc: false}, + SortingColumn: instance.FieldName_FIELD_NAME_NAME.Enum(), + Queries: []*instance.Query{ + {Query: &instance.Query_IdQuery{IdQuery: &instance.IdsQuery{ + Ids: []string{"instance-1", "instance-2"}, + }}}, + {Query: &instance.Query_DomainQuery{DomainQuery: &instance.DomainsQuery{ + Domains: []string{"domain1.example.com", "domain2.example.com"}, + }}}, + }, + }, + expectedError: listErr, + }, + { + testName: "when listing instances succeeds should save into result and return nil", + repos: func(ctrl *gomock.Controller, _ ...database.QueryOption) (domain.InstanceRepository, domain.InstanceDomainRepository) { + instanceRepo := domainmock.NewInstanceRepo(ctrl) + domainRepo := domainmock.NewInstancesDomainRepo(ctrl) + instanceRepo.EXPECT(). + LoadDomains(). + Times(1). + Return(instanceRepo) + + domainExistsORedConditions := instanceRepo.ExistsDomain( + database.Or([]database.Condition{ + domainRepo.DomainCondition(database.TextOperationEqual, "domain1.example.com"), + domainRepo.DomainCondition(database.TextOperationEqual, "domain2.example.com"), + }...), + ) + + idConditions := database.Or( + []database.Condition{ + instanceRepo.IDCondition("instance-1"), + instanceRepo.IDCondition("instance-2"), + }..., + ) + + instanceRepo.EXPECT(). + List(gomock.Any(), gomock.Any(), + dbmock.QueryOptions( + database.WithCondition(database.And( + idConditions, domainExistsORedConditions, + )), + ), + dbmock.QueryOptions(database.WithOrderBy(database.OrderDirectionDesc, instanceRepo.NameColumn())), + dbmock.QueryOptions(database.WithLimit(2)), + dbmock.QueryOptions(database.WithOffset(1)), + ). + Times(1). + Return([]*domain.Instance{ + { + ID: "instance-2", + Name: "Instance Two", + Domains: []*domain.InstanceDomain{{Domain: "domain1.example.com"}}, + }, + { + ID: "instance-1", + Name: "Instance One", + Domains: []*domain.InstanceDomain{{Domain: "domain2.example.com"}}, + }, + }, nil) + + return instanceRepo, domainRepo + }, + inputRequest: &instance.ListInstancesRequest{ + Pagination: &filter.PaginationRequest{Limit: 2, Offset: 1, Asc: false}, + SortingColumn: instance.FieldName_FIELD_NAME_NAME.Enum(), + Queries: []*instance.Query{ + {Query: &instance.Query_IdQuery{IdQuery: &instance.IdsQuery{ + Ids: []string{"instance-1", "instance-2"}, + }}}, + {Query: &instance.Query_DomainQuery{DomainQuery: &instance.DomainsQuery{ + Domains: []string{"domain1.example.com", "domain2.example.com"}, + }}}, + }, + }, + expectedInstances: []*domain.Instance{ + { + ID: "instance-2", + Name: "Instance Two", + Domains: []*domain.InstanceDomain{{Domain: "domain1.example.com"}}, + }, + { + ID: "instance-1", + Name: "Instance One", + Domains: []*domain.InstanceDomain{{Domain: "domain2.example.com"}}, + }, + }, + }, + } + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Given + ctx := authz.NewMockContext("instance-1", "org-1", "") + ctrl := gomock.NewController(t) + cmd := domain.NewListInstancesCommand(tc.inputRequest) + opts := &domain.InvokeOpts{ + Invoker: domain.NewTransactionInvoker(nil), + } + domain.WithQueryExecutor(new(noopdb.Pool))(opts) + if tc.repos != nil { + inst, instDomain := tc.repos(ctrl, tc.queryParams...) + domain.WithInstanceRepo(inst)(opts) + domain.WithInstanceDomainRepo(instDomain)(opts) + } + + // Test + err := cmd.Execute(ctx, opts) + + // Verify + assert.Equal(t, tc.expectedError, err) + assert.ElementsMatch(t, tc.expectedInstances, cmd.Result()) + + }) + } +} + +func TestListInstancesCommand_Validate(t *testing.T) { + t.Parallel() + permissionErr := errors.New("permission error") + tt := []struct { + name string + permissionChecker func(ctrl *gomock.Controller) domain.PermissionChecker + expectedError error + }{ + { + name: "when user is missing permission should return permission denied", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceReadPermission). + Times(1). + Return(permissionErr) + + return permChecker + }, + expectedError: zerrors.ThrowPermissionDenied(permissionErr, "DOM-cuT6Ws", "permission denied"), + }, + { + name: "when valid permission should return no error", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceReadPermission). + Times(1). + Return(nil) + + return permChecker + }, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + // Given + l := &domain.ListInstancesQuery{} + + cmdOpts := &domain.InvokeOpts{} + if tc.permissionChecker != nil { + ctrl := gomock.NewController(t) + cmdOpts.Permissions = tc.permissionChecker(ctrl) + } + + // Test + err := l.Validate(context.Background(), cmdOpts) + + // Verify + assert.Equal(t, tc.expectedError, err) + + }) + } +} diff --git a/backend/v3/domain/instance_update.go b/backend/v3/domain/instance_update.go new file mode 100644 index 000000000..8054cc73b --- /dev/null +++ b/backend/v3/domain/instance_update.go @@ -0,0 +1,96 @@ +package domain + +import ( + "context" + "strings" + + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/internal/eventstore" + "github.com/zitadel/zitadel/internal/repository/instance" + "github.com/zitadel/zitadel/internal/zerrors" +) + +type UpdateInstanceCommand struct { + ID string `json:"id"` + Name string `json:"name"` +} + +// RequiresTransaction implements [Transactional]. +func (u *UpdateInstanceCommand) RequiresTransaction() {} + +// Events implements Commander. +func (u *UpdateInstanceCommand) Events(ctx context.Context, _ *InvokeOpts) ([]eventstore.Command, error) { + return []eventstore.Command{ + instance.NewInstanceChangedEvent(ctx, &instance.NewAggregate(u.ID).Aggregate, u.Name), + }, nil +} + +var ( + _ Commander = (*UpdateInstanceCommand)(nil) + _ Transactional = (*UpdateInstanceCommand)(nil) +) + +func NewUpdateInstanceCommand(id, name string) *UpdateInstanceCommand { + return &UpdateInstanceCommand{ + ID: id, + Name: name, + } +} + +// Execute implements [Commander] +func (u *UpdateInstanceCommand) Execute(ctx context.Context, opts *InvokeOpts) (err error) { + instanceRepo := opts.instanceRepo + + updateCount, err := instanceRepo.Update( + ctx, + opts.DB(), + u.ID, + database.NewChange(instanceRepo.NameColumn(), u.Name), + ) + if err != nil { + return err + } + + if updateCount == 0 { + err = zerrors.ThrowNotFound(nil, "DOM-ghfov1", "Errors.Instance.NotFound") + return err + } + if updateCount > 1 { + err = zerrors.ThrowInternal(NewMultipleObjectsUpdatedError(1, updateCount), "DOM-HlrNmD", "unexpected number of rows updated") + return err + } + + return err +} + +// String implements [Commander] +func (u *UpdateInstanceCommand) String() string { + return "UpdateInstanceCommand" +} + +// Validate implements [Commander] +func (u *UpdateInstanceCommand) Validate(ctx context.Context, opts *InvokeOpts) error { + if u.ID = strings.TrimSpace(u.ID); u.ID == "" { + return zerrors.ThrowInvalidArgument(nil, "DOM-wSs6kG", "invalid instance ID") + } + if u.Name = strings.TrimSpace(u.Name); u.Name == "" { + return zerrors.ThrowInvalidArgument(nil, "DOM-FPJcLC", "invalid instance name") + } + + if authZErr := opts.Permissions.CheckInstancePermission(ctx, InstanceWritePermission); authZErr != nil { + return zerrors.ThrowPermissionDenied(authZErr, "DOM-M5ObLP", "permission denied") + } + + instanceRepo := opts.instanceRepo + + instance, err := instanceRepo.Get(ctx, opts.DB(), database.WithCondition(instanceRepo.IDCondition(u.ID))) + if err != nil { + return err + } + + if instance.Name == u.Name { + err = zerrors.ThrowPreconditionFailed(nil, "DOM-5MrT21", "Errors.Instance.NotChanged") + return err + } + return nil +} diff --git a/backend/v3/domain/instance_update_test.go b/backend/v3/domain/instance_update_test.go new file mode 100644 index 000000000..d8f82447b --- /dev/null +++ b/backend/v3/domain/instance_update_test.go @@ -0,0 +1,300 @@ +package domain_test + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" + + "github.com/zitadel/zitadel/backend/v3/domain" + domainmock "github.com/zitadel/zitadel/backend/v3/domain/mock" + "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/dbmock" + noopdb "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/noop" + "github.com/zitadel/zitadel/internal/api/authz" + "github.com/zitadel/zitadel/internal/repository/instance" + "github.com/zitadel/zitadel/internal/zerrors" +) + +func TestUpdateInstanceCommand_Validate(t *testing.T) { + t.Parallel() + getErr := errors.New("get error") + permissionErr := errors.New("permission error") + + tt := []struct { + testName string + instanceRepo func(ctrl *gomock.Controller) domain.InstanceRepository + permissionChecker func(ctrl *gomock.Controller) domain.PermissionChecker + inputInstanceID string + inputInstanceName string + expectedError error + }{ + { + testName: "when no ID should return invalid argument error", + inputInstanceID: "", + inputInstanceName: "test-name", + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-wSs6kG", "invalid instance ID"), + }, + { + testName: "when no name shuld return invalid argument error", + inputInstanceID: "test-id", + inputInstanceName: "", + expectedError: zerrors.ThrowInvalidArgument(nil, "DOM-FPJcLC", "invalid instance name"), + }, + { + testName: "when user is missing permission should return permission denied", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(permissionErr) + + return permChecker + }, + inputInstanceID: "instance-1", + inputInstanceName: "test instance update", + expectedError: zerrors.ThrowPermissionDenied(permissionErr, "DOM-M5ObLP", "permission denied"), + }, + { + testName: "when retrieving instance fails should return error", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(nil) + + return permChecker + }, + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions( + database.WithCondition( + repo.IDCondition("instance-1"), + ), + )). + Times(1). + Return(nil, getErr) + return repo + }, + inputInstanceID: "instance-1", + inputInstanceName: "test instance update", + expectedError: getErr, + }, + { + testName: "when instance name is not changed should return name not changed error", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(nil) + + return permChecker + }, + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition( + repo.IDCondition("instance-1"), + ))). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "test instance update", + }, nil) + return repo + }, + inputInstanceID: "instance-1", + inputInstanceName: "test instance update", + expectedError: zerrors.ThrowPreconditionFailed(nil, "DOM-5MrT21", "Errors.Instance.NotChanged"), + }, + { + testName: "when instance name is changed should validate successfully and return no error", + permissionChecker: func(ctrl *gomock.Controller) domain.PermissionChecker { + permChecker := domainmock.NewMockPermissionChecker(ctrl) + + permChecker.EXPECT(). + CheckInstancePermission(gomock.Any(), domain.InstanceWritePermission). + Times(1). + Return(nil) + + return permChecker + }, + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Get(gomock.Any(), gomock.Any(), dbmock.QueryOptions(database.WithCondition( + repo.IDCondition("instance-1"), + ))). + Times(1). + Return(&domain.Instance{ + ID: "instance-1", + Name: "old instance name", + }, nil) + return repo + }, + inputInstanceID: "instance-1", + inputInstanceName: "test instance update", + }, + } + + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Given + ctx := authz.NewMockContext("instance-1", "", "") + ctrl := gomock.NewController(t) + cmd := domain.NewUpdateInstanceCommand(tc.inputInstanceID, tc.inputInstanceName) + + opts := &domain.InvokeOpts{ + Invoker: domain.NewTransactionInvoker(nil), + } + domain.WithQueryExecutor(new(noopdb.Pool))(opts) + if tc.instanceRepo != nil { + domain.WithInstanceRepo(tc.instanceRepo(ctrl))(opts) + } + if tc.permissionChecker != nil { + opts.Permissions = tc.permissionChecker(ctrl) + } + + err := cmd.Validate(ctx, opts) + assert.Equal(t, tc.expectedError, err) + }) + } +} + +func TestUpdateInstanceCommand_Execute(t *testing.T) { + t.Parallel() + + updateErr := errors.New("update error") + + tt := []struct { + testName string + + instanceRepo func(ctrl *gomock.Controller) domain.InstanceRepository + + inputID string + inputName string + + expectedError error + }{ + { + testName: "when instance update fails should return error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Update(gomock.Any(), gomock.Any(), + "instance-1", + repo.SetName("test instance update"), + ). + Times(1). + Return(int64(0), updateErr) + return repo + }, + inputID: "instance-1", + inputName: "test instance update", + expectedError: updateErr, + }, + { + testName: "when instance update returns 0 rows updated should return not found error", + inputID: "instance-1", + inputName: "test instance update", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Update(gomock.Any(), gomock.Any(), + "instance-1", + repo.SetName("test instance update"), + ). + Times(1). + Return(int64(0), nil) + return repo + }, + expectedError: zerrors.ThrowNotFound(nil, "DOM-ghfov1", "Errors.Instance.NotFound"), + }, + { + testName: "when instance update returns more than 1 row updated should return internal error", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + repo.EXPECT(). + Update(gomock.Any(), gomock.Any(), + "instance-1", + repo.SetName("test instance update"), + ). + Times(1). + Return(int64(2), nil) + return repo + }, + inputID: "instance-1", + inputName: "test instance update", + expectedError: zerrors.ThrowInternal(domain.NewMultipleObjectsUpdatedError(1, 2), "DOM-HlrNmD", "unexpected number of rows updated"), + }, + { + testName: "when instance update returns 1 row updated should return no error and set non-primary verified domain", + instanceRepo: func(ctrl *gomock.Controller) domain.InstanceRepository { + repo := domainmock.NewInstanceRepo(ctrl) + + repo.EXPECT(). + Update(gomock.Any(), gomock.Any(), + "instance-1", + repo.SetName("test instance update"), + ). + Times(1). + Return(int64(1), nil) + return repo + }, + inputID: "instance-1", + inputName: "test instance update", + }, + } + + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + t.Parallel() + // Given + ctx := authz.NewMockContext("instance-1", "", "") + ctrl := gomock.NewController(t) + cmd := domain.NewUpdateInstanceCommand(tc.inputID, tc.inputName) + + opts := &domain.InvokeOpts{ + Invoker: domain.NewTransactionInvoker(nil), + } + domain.WithQueryExecutor(new(noopdb.Pool))(opts) + if tc.instanceRepo != nil { + domain.WithInstanceRepo(tc.instanceRepo(ctrl))(opts) + } + + // Test + err := cmd.Execute(ctx, opts) + + // Verify + assert.Equal(t, tc.expectedError, err) + }) + } +} +func TestUpdateInstanceCommand_Events(t *testing.T) { + t.Parallel() + + // Given + ctx := authz.NewMockContext("instance-1", "", "") + cmd := domain.NewUpdateInstanceCommand("instance-1", "test-name") + + // Test + events, err := cmd.Events(ctx, &domain.InvokeOpts{}) + + // Verify + assert.NoError(t, err) + require.Len(t, events, 1) + + event := events[0].(*instance.InstanceChangedEvent) + assert.Equal(t, "instance-1", event.Aggregate().ID) + assert.Equal(t, "test-name", event.Name) +} diff --git a/backend/v3/domain/invoke_option.go b/backend/v3/domain/invoke_option.go index b23989225..feff12eaa 100644 --- a/backend/v3/domain/invoke_option.go +++ b/backend/v3/domain/invoke_option.go @@ -27,6 +27,18 @@ func WithProjectRepo(repo ProjectRepository) InvokeOpt { } } +func WithInstanceRepo(repo InstanceRepository) InvokeOpt { + return func(opts *InvokeOpts) { + opts.instanceRepo = repo + } +} + +func WithInstanceDomainRepo(repo InstanceDomainRepository) InvokeOpt { + return func(opts *InvokeOpts) { + opts.instanceDomainRepo = repo + } +} + // WithQueryExecutor sets the database client to be used by the command. // If not set, the default pool will be used. // This is mainly used for testing. @@ -59,6 +71,8 @@ type InvokeOpts struct { organizationRepo OrganizationRepository organizationDomainRepo OrganizationDomainRepository projectRepo ProjectRepository + instanceRepo InstanceRepository + instanceDomainRepo InstanceDomainRepository } func (o *InvokeOpts) DB() database.QueryExecutor { diff --git a/backend/v3/domain/mock/instance.mock.go b/backend/v3/domain/mock/instance.mock.go new file mode 100644 index 000000000..c178e0fef --- /dev/null +++ b/backend/v3/domain/mock/instance.mock.go @@ -0,0 +1,1089 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/zitadel/zitadel/backend/v3/domain (interfaces: InstanceRepository) +// +// Generated by this command: +// +// mockgen -typed -package domainmock -destination ./mock/instance.mock.go . InstanceRepository +// + +// Package domainmock is a generated GoMock package. +package domainmock + +import ( + context "context" + reflect "reflect" + time "time" + + domain "github.com/zitadel/zitadel/backend/v3/domain" + database "github.com/zitadel/zitadel/backend/v3/storage/database" + gomock "go.uber.org/mock/gomock" + language "golang.org/x/text/language" +) + +// MockInstanceRepository is a mock of InstanceRepository interface. +type MockInstanceRepository struct { + ctrl *gomock.Controller + recorder *MockInstanceRepositoryMockRecorder +} + +// MockInstanceRepositoryMockRecorder is the mock recorder for MockInstanceRepository. +type MockInstanceRepositoryMockRecorder struct { + mock *MockInstanceRepository +} + +// NewMockInstanceRepository creates a new mock instance. +func NewMockInstanceRepository(ctrl *gomock.Controller) *MockInstanceRepository { + mock := &MockInstanceRepository{ctrl: ctrl} + mock.recorder = &MockInstanceRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockInstanceRepository) EXPECT() *MockInstanceRepositoryMockRecorder { + return m.recorder +} + +// ConsoleAppIDColumn mocks base method. +func (m *MockInstanceRepository) ConsoleAppIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConsoleAppIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// ConsoleAppIDColumn indicates an expected call of ConsoleAppIDColumn. +func (mr *MockInstanceRepositoryMockRecorder) ConsoleAppIDColumn() *MockInstanceRepositoryConsoleAppIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsoleAppIDColumn", reflect.TypeOf((*MockInstanceRepository)(nil).ConsoleAppIDColumn)) + return &MockInstanceRepositoryConsoleAppIDColumnCall{Call: call} +} + +// MockInstanceRepositoryConsoleAppIDColumnCall wrap *gomock.Call +type MockInstanceRepositoryConsoleAppIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryConsoleAppIDColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryConsoleAppIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryConsoleAppIDColumnCall) Do(f func() database.Column) *MockInstanceRepositoryConsoleAppIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryConsoleAppIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryConsoleAppIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ConsoleClientIDColumn mocks base method. +func (m *MockInstanceRepository) ConsoleClientIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ConsoleClientIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// ConsoleClientIDColumn indicates an expected call of ConsoleClientIDColumn. +func (mr *MockInstanceRepositoryMockRecorder) ConsoleClientIDColumn() *MockInstanceRepositoryConsoleClientIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsoleClientIDColumn", reflect.TypeOf((*MockInstanceRepository)(nil).ConsoleClientIDColumn)) + return &MockInstanceRepositoryConsoleClientIDColumnCall{Call: call} +} + +// MockInstanceRepositoryConsoleClientIDColumnCall wrap *gomock.Call +type MockInstanceRepositoryConsoleClientIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryConsoleClientIDColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryConsoleClientIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryConsoleClientIDColumnCall) Do(f func() database.Column) *MockInstanceRepositoryConsoleClientIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryConsoleClientIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryConsoleClientIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Create mocks base method. +func (m *MockInstanceRepository) Create(arg0 context.Context, arg1 database.QueryExecutor, arg2 *domain.Instance) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockInstanceRepositoryMockRecorder) Create(arg0, arg1, arg2 any) *MockInstanceRepositoryCreateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockInstanceRepository)(nil).Create), arg0, arg1, arg2) + return &MockInstanceRepositoryCreateCall{Call: call} +} + +// MockInstanceRepositoryCreateCall wrap *gomock.Call +type MockInstanceRepositoryCreateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryCreateCall) Return(arg0 error) *MockInstanceRepositoryCreateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryCreateCall) Do(f func(context.Context, database.QueryExecutor, *domain.Instance) error) *MockInstanceRepositoryCreateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryCreateCall) DoAndReturn(f func(context.Context, database.QueryExecutor, *domain.Instance) error) *MockInstanceRepositoryCreateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CreatedAtColumn mocks base method. +func (m *MockInstanceRepository) CreatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// CreatedAtColumn indicates an expected call of CreatedAtColumn. +func (mr *MockInstanceRepositoryMockRecorder) CreatedAtColumn() *MockInstanceRepositoryCreatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatedAtColumn", reflect.TypeOf((*MockInstanceRepository)(nil).CreatedAtColumn)) + return &MockInstanceRepositoryCreatedAtColumnCall{Call: call} +} + +// MockInstanceRepositoryCreatedAtColumnCall wrap *gomock.Call +type MockInstanceRepositoryCreatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryCreatedAtColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryCreatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryCreatedAtColumnCall) Do(f func() database.Column) *MockInstanceRepositoryCreatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryCreatedAtColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryCreatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DefaultLanguageColumn mocks base method. +func (m *MockInstanceRepository) DefaultLanguageColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DefaultLanguageColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// DefaultLanguageColumn indicates an expected call of DefaultLanguageColumn. +func (mr *MockInstanceRepositoryMockRecorder) DefaultLanguageColumn() *MockInstanceRepositoryDefaultLanguageColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultLanguageColumn", reflect.TypeOf((*MockInstanceRepository)(nil).DefaultLanguageColumn)) + return &MockInstanceRepositoryDefaultLanguageColumnCall{Call: call} +} + +// MockInstanceRepositoryDefaultLanguageColumnCall wrap *gomock.Call +type MockInstanceRepositoryDefaultLanguageColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryDefaultLanguageColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryDefaultLanguageColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryDefaultLanguageColumnCall) Do(f func() database.Column) *MockInstanceRepositoryDefaultLanguageColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryDefaultLanguageColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryDefaultLanguageColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DefaultOrgIDColumn mocks base method. +func (m *MockInstanceRepository) DefaultOrgIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DefaultOrgIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// DefaultOrgIDColumn indicates an expected call of DefaultOrgIDColumn. +func (mr *MockInstanceRepositoryMockRecorder) DefaultOrgIDColumn() *MockInstanceRepositoryDefaultOrgIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DefaultOrgIDColumn", reflect.TypeOf((*MockInstanceRepository)(nil).DefaultOrgIDColumn)) + return &MockInstanceRepositoryDefaultOrgIDColumnCall{Call: call} +} + +// MockInstanceRepositoryDefaultOrgIDColumnCall wrap *gomock.Call +type MockInstanceRepositoryDefaultOrgIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryDefaultOrgIDColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryDefaultOrgIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryDefaultOrgIDColumnCall) Do(f func() database.Column) *MockInstanceRepositoryDefaultOrgIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryDefaultOrgIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryDefaultOrgIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Delete mocks base method. +func (m *MockInstanceRepository) Delete(arg0 context.Context, arg1 database.QueryExecutor, arg2 string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Delete indicates an expected call of Delete. +func (mr *MockInstanceRepositoryMockRecorder) Delete(arg0, arg1, arg2 any) *MockInstanceRepositoryDeleteCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockInstanceRepository)(nil).Delete), arg0, arg1, arg2) + return &MockInstanceRepositoryDeleteCall{Call: call} +} + +// MockInstanceRepositoryDeleteCall wrap *gomock.Call +type MockInstanceRepositoryDeleteCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryDeleteCall) Return(arg0 int64, arg1 error) *MockInstanceRepositoryDeleteCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryDeleteCall) Do(f func(context.Context, database.QueryExecutor, string) (int64, error)) *MockInstanceRepositoryDeleteCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryDeleteCall) DoAndReturn(f func(context.Context, database.QueryExecutor, string) (int64, error)) *MockInstanceRepositoryDeleteCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ExistsDomain mocks base method. +func (m *MockInstanceRepository) ExistsDomain(arg0 database.Condition) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExistsDomain", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// ExistsDomain indicates an expected call of ExistsDomain. +func (mr *MockInstanceRepositoryMockRecorder) ExistsDomain(arg0 any) *MockInstanceRepositoryExistsDomainCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExistsDomain", reflect.TypeOf((*MockInstanceRepository)(nil).ExistsDomain), arg0) + return &MockInstanceRepositoryExistsDomainCall{Call: call} +} + +// MockInstanceRepositoryExistsDomainCall wrap *gomock.Call +type MockInstanceRepositoryExistsDomainCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryExistsDomainCall) Return(arg0 database.Condition) *MockInstanceRepositoryExistsDomainCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryExistsDomainCall) Do(f func(database.Condition) database.Condition) *MockInstanceRepositoryExistsDomainCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryExistsDomainCall) DoAndReturn(f func(database.Condition) database.Condition) *MockInstanceRepositoryExistsDomainCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Get mocks base method. +func (m *MockInstanceRepository) Get(arg0 context.Context, arg1 database.QueryExecutor, arg2 ...database.QueryOption) (*domain.Instance, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Get", varargs...) + ret0, _ := ret[0].(*domain.Instance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockInstanceRepositoryMockRecorder) Get(arg0, arg1 any, arg2 ...any) *MockInstanceRepositoryGetCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInstanceRepository)(nil).Get), varargs...) + return &MockInstanceRepositoryGetCall{Call: call} +} + +// MockInstanceRepositoryGetCall wrap *gomock.Call +type MockInstanceRepositoryGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryGetCall) Return(arg0 *domain.Instance, arg1 error) *MockInstanceRepositoryGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryGetCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.Instance, error)) *MockInstanceRepositoryGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryGetCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.Instance, error)) *MockInstanceRepositoryGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IAMProjectIDColumn mocks base method. +func (m *MockInstanceRepository) IAMProjectIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IAMProjectIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// IAMProjectIDColumn indicates an expected call of IAMProjectIDColumn. +func (mr *MockInstanceRepositoryMockRecorder) IAMProjectIDColumn() *MockInstanceRepositoryIAMProjectIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IAMProjectIDColumn", reflect.TypeOf((*MockInstanceRepository)(nil).IAMProjectIDColumn)) + return &MockInstanceRepositoryIAMProjectIDColumnCall{Call: call} +} + +// MockInstanceRepositoryIAMProjectIDColumnCall wrap *gomock.Call +type MockInstanceRepositoryIAMProjectIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryIAMProjectIDColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryIAMProjectIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryIAMProjectIDColumnCall) Do(f func() database.Column) *MockInstanceRepositoryIAMProjectIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryIAMProjectIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryIAMProjectIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IDColumn mocks base method. +func (m *MockInstanceRepository) IDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// IDColumn indicates an expected call of IDColumn. +func (mr *MockInstanceRepositoryMockRecorder) IDColumn() *MockInstanceRepositoryIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDColumn", reflect.TypeOf((*MockInstanceRepository)(nil).IDColumn)) + return &MockInstanceRepositoryIDColumnCall{Call: call} +} + +// MockInstanceRepositoryIDColumnCall wrap *gomock.Call +type MockInstanceRepositoryIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryIDColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryIDColumnCall) Do(f func() database.Column) *MockInstanceRepositoryIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IDCondition mocks base method. +func (m *MockInstanceRepository) IDCondition(arg0 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IDCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// IDCondition indicates an expected call of IDCondition. +func (mr *MockInstanceRepositoryMockRecorder) IDCondition(arg0 any) *MockInstanceRepositoryIDConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IDCondition", reflect.TypeOf((*MockInstanceRepository)(nil).IDCondition), arg0) + return &MockInstanceRepositoryIDConditionCall{Call: call} +} + +// MockInstanceRepositoryIDConditionCall wrap *gomock.Call +type MockInstanceRepositoryIDConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryIDConditionCall) Return(arg0 database.Condition) *MockInstanceRepositoryIDConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryIDConditionCall) Do(f func(string) database.Condition) *MockInstanceRepositoryIDConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryIDConditionCall) DoAndReturn(f func(string) database.Condition) *MockInstanceRepositoryIDConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// List mocks base method. +func (m *MockInstanceRepository) List(arg0 context.Context, arg1 database.QueryExecutor, arg2 ...database.QueryOption) ([]*domain.Instance, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) + ret0, _ := ret[0].([]*domain.Instance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockInstanceRepositoryMockRecorder) List(arg0, arg1 any, arg2 ...any) *MockInstanceRepositoryListCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInstanceRepository)(nil).List), varargs...) + return &MockInstanceRepositoryListCall{Call: call} +} + +// MockInstanceRepositoryListCall wrap *gomock.Call +type MockInstanceRepositoryListCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryListCall) Return(arg0 []*domain.Instance, arg1 error) *MockInstanceRepositoryListCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryListCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.Instance, error)) *MockInstanceRepositoryListCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryListCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.Instance, error)) *MockInstanceRepositoryListCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// LoadDomains mocks base method. +func (m *MockInstanceRepository) LoadDomains() domain.InstanceRepository { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LoadDomains") + ret0, _ := ret[0].(domain.InstanceRepository) + return ret0 +} + +// LoadDomains indicates an expected call of LoadDomains. +func (mr *MockInstanceRepositoryMockRecorder) LoadDomains() *MockInstanceRepositoryLoadDomainsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadDomains", reflect.TypeOf((*MockInstanceRepository)(nil).LoadDomains)) + return &MockInstanceRepositoryLoadDomainsCall{Call: call} +} + +// MockInstanceRepositoryLoadDomainsCall wrap *gomock.Call +type MockInstanceRepositoryLoadDomainsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryLoadDomainsCall) Return(arg0 domain.InstanceRepository) *MockInstanceRepositoryLoadDomainsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryLoadDomainsCall) Do(f func() domain.InstanceRepository) *MockInstanceRepositoryLoadDomainsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryLoadDomainsCall) DoAndReturn(f func() domain.InstanceRepository) *MockInstanceRepositoryLoadDomainsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// NameColumn mocks base method. +func (m *MockInstanceRepository) NameColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NameColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// NameColumn indicates an expected call of NameColumn. +func (mr *MockInstanceRepositoryMockRecorder) NameColumn() *MockInstanceRepositoryNameColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NameColumn", reflect.TypeOf((*MockInstanceRepository)(nil).NameColumn)) + return &MockInstanceRepositoryNameColumnCall{Call: call} +} + +// MockInstanceRepositoryNameColumnCall wrap *gomock.Call +type MockInstanceRepositoryNameColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryNameColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryNameColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryNameColumnCall) Do(f func() database.Column) *MockInstanceRepositoryNameColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryNameColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryNameColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// NameCondition mocks base method. +func (m *MockInstanceRepository) NameCondition(arg0 database.TextOperation, arg1 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NameCondition", arg0, arg1) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// NameCondition indicates an expected call of NameCondition. +func (mr *MockInstanceRepositoryMockRecorder) NameCondition(arg0, arg1 any) *MockInstanceRepositoryNameConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NameCondition", reflect.TypeOf((*MockInstanceRepository)(nil).NameCondition), arg0, arg1) + return &MockInstanceRepositoryNameConditionCall{Call: call} +} + +// MockInstanceRepositoryNameConditionCall wrap *gomock.Call +type MockInstanceRepositoryNameConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryNameConditionCall) Return(arg0 database.Condition) *MockInstanceRepositoryNameConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryNameConditionCall) Do(f func(database.TextOperation, string) database.Condition) *MockInstanceRepositoryNameConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryNameConditionCall) DoAndReturn(f func(database.TextOperation, string) database.Condition) *MockInstanceRepositoryNameConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyColumns mocks base method. +func (m *MockInstanceRepository) PrimaryKeyColumns() []database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyColumns") + ret0, _ := ret[0].([]database.Column) + return ret0 +} + +// PrimaryKeyColumns indicates an expected call of PrimaryKeyColumns. +func (mr *MockInstanceRepositoryMockRecorder) PrimaryKeyColumns() *MockInstanceRepositoryPrimaryKeyColumnsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyColumns", reflect.TypeOf((*MockInstanceRepository)(nil).PrimaryKeyColumns)) + return &MockInstanceRepositoryPrimaryKeyColumnsCall{Call: call} +} + +// MockInstanceRepositoryPrimaryKeyColumnsCall wrap *gomock.Call +type MockInstanceRepositoryPrimaryKeyColumnsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryPrimaryKeyColumnsCall) Return(arg0 []database.Column) *MockInstanceRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryPrimaryKeyColumnsCall) Do(f func() []database.Column) *MockInstanceRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryPrimaryKeyColumnsCall) DoAndReturn(f func() []database.Column) *MockInstanceRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyCondition mocks base method. +func (m *MockInstanceRepository) PrimaryKeyCondition(arg0 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// PrimaryKeyCondition indicates an expected call of PrimaryKeyCondition. +func (mr *MockInstanceRepositoryMockRecorder) PrimaryKeyCondition(arg0 any) *MockInstanceRepositoryPrimaryKeyConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyCondition", reflect.TypeOf((*MockInstanceRepository)(nil).PrimaryKeyCondition), arg0) + return &MockInstanceRepositoryPrimaryKeyConditionCall{Call: call} +} + +// MockInstanceRepositoryPrimaryKeyConditionCall wrap *gomock.Call +type MockInstanceRepositoryPrimaryKeyConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryPrimaryKeyConditionCall) Return(arg0 database.Condition) *MockInstanceRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryPrimaryKeyConditionCall) Do(f func(string) database.Condition) *MockInstanceRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryPrimaryKeyConditionCall) DoAndReturn(f func(string) database.Condition) *MockInstanceRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetConsoleAppID mocks base method. +func (m *MockInstanceRepository) SetConsoleAppID(arg0 string) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetConsoleAppID", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetConsoleAppID indicates an expected call of SetConsoleAppID. +func (mr *MockInstanceRepositoryMockRecorder) SetConsoleAppID(arg0 any) *MockInstanceRepositorySetConsoleAppIDCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetConsoleAppID", reflect.TypeOf((*MockInstanceRepository)(nil).SetConsoleAppID), arg0) + return &MockInstanceRepositorySetConsoleAppIDCall{Call: call} +} + +// MockInstanceRepositorySetConsoleAppIDCall wrap *gomock.Call +type MockInstanceRepositorySetConsoleAppIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetConsoleAppIDCall) Return(arg0 database.Change) *MockInstanceRepositorySetConsoleAppIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetConsoleAppIDCall) Do(f func(string) database.Change) *MockInstanceRepositorySetConsoleAppIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetConsoleAppIDCall) DoAndReturn(f func(string) database.Change) *MockInstanceRepositorySetConsoleAppIDCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetConsoleClientID mocks base method. +func (m *MockInstanceRepository) SetConsoleClientID(arg0 string) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetConsoleClientID", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetConsoleClientID indicates an expected call of SetConsoleClientID. +func (mr *MockInstanceRepositoryMockRecorder) SetConsoleClientID(arg0 any) *MockInstanceRepositorySetConsoleClientIDCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetConsoleClientID", reflect.TypeOf((*MockInstanceRepository)(nil).SetConsoleClientID), arg0) + return &MockInstanceRepositorySetConsoleClientIDCall{Call: call} +} + +// MockInstanceRepositorySetConsoleClientIDCall wrap *gomock.Call +type MockInstanceRepositorySetConsoleClientIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetConsoleClientIDCall) Return(arg0 database.Change) *MockInstanceRepositorySetConsoleClientIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetConsoleClientIDCall) Do(f func(string) database.Change) *MockInstanceRepositorySetConsoleClientIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetConsoleClientIDCall) DoAndReturn(f func(string) database.Change) *MockInstanceRepositorySetConsoleClientIDCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetDefaultLanguage mocks base method. +func (m *MockInstanceRepository) SetDefaultLanguage(arg0 language.Tag) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDefaultLanguage", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetDefaultLanguage indicates an expected call of SetDefaultLanguage. +func (mr *MockInstanceRepositoryMockRecorder) SetDefaultLanguage(arg0 any) *MockInstanceRepositorySetDefaultLanguageCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDefaultLanguage", reflect.TypeOf((*MockInstanceRepository)(nil).SetDefaultLanguage), arg0) + return &MockInstanceRepositorySetDefaultLanguageCall{Call: call} +} + +// MockInstanceRepositorySetDefaultLanguageCall wrap *gomock.Call +type MockInstanceRepositorySetDefaultLanguageCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetDefaultLanguageCall) Return(arg0 database.Change) *MockInstanceRepositorySetDefaultLanguageCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetDefaultLanguageCall) Do(f func(language.Tag) database.Change) *MockInstanceRepositorySetDefaultLanguageCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetDefaultLanguageCall) DoAndReturn(f func(language.Tag) database.Change) *MockInstanceRepositorySetDefaultLanguageCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetDefaultOrg mocks base method. +func (m *MockInstanceRepository) SetDefaultOrg(arg0 string) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetDefaultOrg", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetDefaultOrg indicates an expected call of SetDefaultOrg. +func (mr *MockInstanceRepositoryMockRecorder) SetDefaultOrg(arg0 any) *MockInstanceRepositorySetDefaultOrgCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDefaultOrg", reflect.TypeOf((*MockInstanceRepository)(nil).SetDefaultOrg), arg0) + return &MockInstanceRepositorySetDefaultOrgCall{Call: call} +} + +// MockInstanceRepositorySetDefaultOrgCall wrap *gomock.Call +type MockInstanceRepositorySetDefaultOrgCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetDefaultOrgCall) Return(arg0 database.Change) *MockInstanceRepositorySetDefaultOrgCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetDefaultOrgCall) Do(f func(string) database.Change) *MockInstanceRepositorySetDefaultOrgCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetDefaultOrgCall) DoAndReturn(f func(string) database.Change) *MockInstanceRepositorySetDefaultOrgCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetIAMProject mocks base method. +func (m *MockInstanceRepository) SetIAMProject(arg0 string) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetIAMProject", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetIAMProject indicates an expected call of SetIAMProject. +func (mr *MockInstanceRepositoryMockRecorder) SetIAMProject(arg0 any) *MockInstanceRepositorySetIAMProjectCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetIAMProject", reflect.TypeOf((*MockInstanceRepository)(nil).SetIAMProject), arg0) + return &MockInstanceRepositorySetIAMProjectCall{Call: call} +} + +// MockInstanceRepositorySetIAMProjectCall wrap *gomock.Call +type MockInstanceRepositorySetIAMProjectCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetIAMProjectCall) Return(arg0 database.Change) *MockInstanceRepositorySetIAMProjectCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetIAMProjectCall) Do(f func(string) database.Change) *MockInstanceRepositorySetIAMProjectCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetIAMProjectCall) DoAndReturn(f func(string) database.Change) *MockInstanceRepositorySetIAMProjectCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetName mocks base method. +func (m *MockInstanceRepository) SetName(arg0 string) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetName", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetName indicates an expected call of SetName. +func (mr *MockInstanceRepositoryMockRecorder) SetName(arg0 any) *MockInstanceRepositorySetNameCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetName", reflect.TypeOf((*MockInstanceRepository)(nil).SetName), arg0) + return &MockInstanceRepositorySetNameCall{Call: call} +} + +// MockInstanceRepositorySetNameCall wrap *gomock.Call +type MockInstanceRepositorySetNameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetNameCall) Return(arg0 database.Change) *MockInstanceRepositorySetNameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetNameCall) Do(f func(string) database.Change) *MockInstanceRepositorySetNameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetNameCall) DoAndReturn(f func(string) database.Change) *MockInstanceRepositorySetNameCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetUpdatedAt mocks base method. +func (m *MockInstanceRepository) SetUpdatedAt(arg0 time.Time) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetUpdatedAt", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetUpdatedAt indicates an expected call of SetUpdatedAt. +func (mr *MockInstanceRepositoryMockRecorder) SetUpdatedAt(arg0 any) *MockInstanceRepositorySetUpdatedAtCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUpdatedAt", reflect.TypeOf((*MockInstanceRepository)(nil).SetUpdatedAt), arg0) + return &MockInstanceRepositorySetUpdatedAtCall{Call: call} +} + +// MockInstanceRepositorySetUpdatedAtCall wrap *gomock.Call +type MockInstanceRepositorySetUpdatedAtCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositorySetUpdatedAtCall) Return(arg0 database.Change) *MockInstanceRepositorySetUpdatedAtCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositorySetUpdatedAtCall) Do(f func(time.Time) database.Change) *MockInstanceRepositorySetUpdatedAtCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositorySetUpdatedAtCall) DoAndReturn(f func(time.Time) database.Change) *MockInstanceRepositorySetUpdatedAtCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Update mocks base method. +func (m *MockInstanceRepository) Update(arg0 context.Context, arg1 database.QueryExecutor, arg2 string, arg3 ...database.Change) (int64, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Update", varargs...) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockInstanceRepositoryMockRecorder) Update(arg0, arg1, arg2 any, arg3 ...any) *MockInstanceRepositoryUpdateCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1, arg2}, arg3...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockInstanceRepository)(nil).Update), varargs...) + return &MockInstanceRepositoryUpdateCall{Call: call} +} + +// MockInstanceRepositoryUpdateCall wrap *gomock.Call +type MockInstanceRepositoryUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryUpdateCall) Return(arg0 int64, arg1 error) *MockInstanceRepositoryUpdateCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryUpdateCall) Do(f func(context.Context, database.QueryExecutor, string, ...database.Change) (int64, error)) *MockInstanceRepositoryUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryUpdateCall) DoAndReturn(f func(context.Context, database.QueryExecutor, string, ...database.Change) (int64, error)) *MockInstanceRepositoryUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdatedAtColumn mocks base method. +func (m *MockInstanceRepository) UpdatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// UpdatedAtColumn indicates an expected call of UpdatedAtColumn. +func (mr *MockInstanceRepositoryMockRecorder) UpdatedAtColumn() *MockInstanceRepositoryUpdatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedAtColumn", reflect.TypeOf((*MockInstanceRepository)(nil).UpdatedAtColumn)) + return &MockInstanceRepositoryUpdatedAtColumnCall{Call: call} +} + +// MockInstanceRepositoryUpdatedAtColumnCall wrap *gomock.Call +type MockInstanceRepositoryUpdatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceRepositoryUpdatedAtColumnCall) Return(arg0 database.Column) *MockInstanceRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceRepositoryUpdatedAtColumnCall) Do(f func() database.Column) *MockInstanceRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceRepositoryUpdatedAtColumnCall) DoAndReturn(f func() database.Column) *MockInstanceRepositoryUpdatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/backend/v3/domain/mock/instance_domain.mock.go b/backend/v3/domain/mock/instance_domain.mock.go new file mode 100644 index 000000000..cea899f7d --- /dev/null +++ b/backend/v3/domain/mock/instance_domain.mock.go @@ -0,0 +1,860 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/zitadel/zitadel/backend/v3/domain (interfaces: InstanceDomainRepository) +// +// Generated by this command: +// +// mockgen -typed -package domainmock -destination ./mock/instance_domain.mock.go . InstanceDomainRepository +// + +// Package domainmock is a generated GoMock package. +package domainmock + +import ( + context "context" + reflect "reflect" + time "time" + + domain "github.com/zitadel/zitadel/backend/v3/domain" + database "github.com/zitadel/zitadel/backend/v3/storage/database" + gomock "go.uber.org/mock/gomock" +) + +// MockInstanceDomainRepository is a mock of InstanceDomainRepository interface. +type MockInstanceDomainRepository struct { + ctrl *gomock.Controller + recorder *MockInstanceDomainRepositoryMockRecorder +} + +// MockInstanceDomainRepositoryMockRecorder is the mock recorder for MockInstanceDomainRepository. +type MockInstanceDomainRepositoryMockRecorder struct { + mock *MockInstanceDomainRepository +} + +// NewMockInstanceDomainRepository creates a new mock instance. +func NewMockInstanceDomainRepository(ctrl *gomock.Controller) *MockInstanceDomainRepository { + mock := &MockInstanceDomainRepository{ctrl: ctrl} + mock.recorder = &MockInstanceDomainRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockInstanceDomainRepository) EXPECT() *MockInstanceDomainRepositoryMockRecorder { + return m.recorder +} + +// Add mocks base method. +func (m *MockInstanceDomainRepository) Add(arg0 context.Context, arg1 database.QueryExecutor, arg2 *domain.AddInstanceDomain) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Add", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// Add indicates an expected call of Add. +func (mr *MockInstanceDomainRepositoryMockRecorder) Add(arg0, arg1, arg2 any) *MockInstanceDomainRepositoryAddCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockInstanceDomainRepository)(nil).Add), arg0, arg1, arg2) + return &MockInstanceDomainRepositoryAddCall{Call: call} +} + +// MockInstanceDomainRepositoryAddCall wrap *gomock.Call +type MockInstanceDomainRepositoryAddCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryAddCall) Return(arg0 error) *MockInstanceDomainRepositoryAddCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryAddCall) Do(f func(context.Context, database.QueryExecutor, *domain.AddInstanceDomain) error) *MockInstanceDomainRepositoryAddCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryAddCall) DoAndReturn(f func(context.Context, database.QueryExecutor, *domain.AddInstanceDomain) error) *MockInstanceDomainRepositoryAddCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CreatedAtColumn mocks base method. +func (m *MockInstanceDomainRepository) CreatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// CreatedAtColumn indicates an expected call of CreatedAtColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) CreatedAtColumn() *MockInstanceDomainRepositoryCreatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreatedAtColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).CreatedAtColumn)) + return &MockInstanceDomainRepositoryCreatedAtColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryCreatedAtColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryCreatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryCreatedAtColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryCreatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryCreatedAtColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryCreatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryCreatedAtColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryCreatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DomainColumn mocks base method. +func (m *MockInstanceDomainRepository) DomainColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DomainColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// DomainColumn indicates an expected call of DomainColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) DomainColumn() *MockInstanceDomainRepositoryDomainColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DomainColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).DomainColumn)) + return &MockInstanceDomainRepositoryDomainColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryDomainColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryDomainColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryDomainColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryDomainColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryDomainColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryDomainColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryDomainColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryDomainColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DomainCondition mocks base method. +func (m *MockInstanceDomainRepository) DomainCondition(arg0 database.TextOperation, arg1 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DomainCondition", arg0, arg1) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// DomainCondition indicates an expected call of DomainCondition. +func (mr *MockInstanceDomainRepositoryMockRecorder) DomainCondition(arg0, arg1 any) *MockInstanceDomainRepositoryDomainConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DomainCondition", reflect.TypeOf((*MockInstanceDomainRepository)(nil).DomainCondition), arg0, arg1) + return &MockInstanceDomainRepositoryDomainConditionCall{Call: call} +} + +// MockInstanceDomainRepositoryDomainConditionCall wrap *gomock.Call +type MockInstanceDomainRepositoryDomainConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryDomainConditionCall) Return(arg0 database.Condition) *MockInstanceDomainRepositoryDomainConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryDomainConditionCall) Do(f func(database.TextOperation, string) database.Condition) *MockInstanceDomainRepositoryDomainConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryDomainConditionCall) DoAndReturn(f func(database.TextOperation, string) database.Condition) *MockInstanceDomainRepositoryDomainConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Get mocks base method. +func (m *MockInstanceDomainRepository) Get(arg0 context.Context, arg1 database.QueryExecutor, arg2 ...database.QueryOption) (*domain.InstanceDomain, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Get", varargs...) + ret0, _ := ret[0].(*domain.InstanceDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockInstanceDomainRepositoryMockRecorder) Get(arg0, arg1 any, arg2 ...any) *MockInstanceDomainRepositoryGetCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockInstanceDomainRepository)(nil).Get), varargs...) + return &MockInstanceDomainRepositoryGetCall{Call: call} +} + +// MockInstanceDomainRepositoryGetCall wrap *gomock.Call +type MockInstanceDomainRepositoryGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryGetCall) Return(arg0 *domain.InstanceDomain, arg1 error) *MockInstanceDomainRepositoryGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryGetCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.InstanceDomain, error)) *MockInstanceDomainRepositoryGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryGetCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) (*domain.InstanceDomain, error)) *MockInstanceDomainRepositoryGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// InstanceIDColumn mocks base method. +func (m *MockInstanceDomainRepository) InstanceIDColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InstanceIDColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// InstanceIDColumn indicates an expected call of InstanceIDColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) InstanceIDColumn() *MockInstanceDomainRepositoryInstanceIDColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).InstanceIDColumn)) + return &MockInstanceDomainRepositoryInstanceIDColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryInstanceIDColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryInstanceIDColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryInstanceIDColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryInstanceIDColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryInstanceIDColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryInstanceIDColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryInstanceIDColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryInstanceIDColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// InstanceIDCondition mocks base method. +func (m *MockInstanceDomainRepository) InstanceIDCondition(arg0 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InstanceIDCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// InstanceIDCondition indicates an expected call of InstanceIDCondition. +func (mr *MockInstanceDomainRepositoryMockRecorder) InstanceIDCondition(arg0 any) *MockInstanceDomainRepositoryInstanceIDConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceIDCondition", reflect.TypeOf((*MockInstanceDomainRepository)(nil).InstanceIDCondition), arg0) + return &MockInstanceDomainRepositoryInstanceIDConditionCall{Call: call} +} + +// MockInstanceDomainRepositoryInstanceIDConditionCall wrap *gomock.Call +type MockInstanceDomainRepositoryInstanceIDConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryInstanceIDConditionCall) Return(arg0 database.Condition) *MockInstanceDomainRepositoryInstanceIDConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryInstanceIDConditionCall) Do(f func(string) database.Condition) *MockInstanceDomainRepositoryInstanceIDConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryInstanceIDConditionCall) DoAndReturn(f func(string) database.Condition) *MockInstanceDomainRepositoryInstanceIDConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IsGeneratedColumn mocks base method. +func (m *MockInstanceDomainRepository) IsGeneratedColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsGeneratedColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// IsGeneratedColumn indicates an expected call of IsGeneratedColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) IsGeneratedColumn() *MockInstanceDomainRepositoryIsGeneratedColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsGeneratedColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).IsGeneratedColumn)) + return &MockInstanceDomainRepositoryIsGeneratedColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryIsGeneratedColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryIsGeneratedColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryIsGeneratedColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryIsGeneratedColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryIsGeneratedColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryIsGeneratedColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryIsGeneratedColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryIsGeneratedColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IsPrimaryColumn mocks base method. +func (m *MockInstanceDomainRepository) IsPrimaryColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsPrimaryColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// IsPrimaryColumn indicates an expected call of IsPrimaryColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) IsPrimaryColumn() *MockInstanceDomainRepositoryIsPrimaryColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPrimaryColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).IsPrimaryColumn)) + return &MockInstanceDomainRepositoryIsPrimaryColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryIsPrimaryColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryIsPrimaryColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryIsPrimaryColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryIsPrimaryColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryIsPrimaryColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryIsPrimaryColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryIsPrimaryColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryIsPrimaryColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// IsPrimaryCondition mocks base method. +func (m *MockInstanceDomainRepository) IsPrimaryCondition(arg0 bool) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsPrimaryCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// IsPrimaryCondition indicates an expected call of IsPrimaryCondition. +func (mr *MockInstanceDomainRepositoryMockRecorder) IsPrimaryCondition(arg0 any) *MockInstanceDomainRepositoryIsPrimaryConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsPrimaryCondition", reflect.TypeOf((*MockInstanceDomainRepository)(nil).IsPrimaryCondition), arg0) + return &MockInstanceDomainRepositoryIsPrimaryConditionCall{Call: call} +} + +// MockInstanceDomainRepositoryIsPrimaryConditionCall wrap *gomock.Call +type MockInstanceDomainRepositoryIsPrimaryConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryIsPrimaryConditionCall) Return(arg0 database.Condition) *MockInstanceDomainRepositoryIsPrimaryConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryIsPrimaryConditionCall) Do(f func(bool) database.Condition) *MockInstanceDomainRepositoryIsPrimaryConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryIsPrimaryConditionCall) DoAndReturn(f func(bool) database.Condition) *MockInstanceDomainRepositoryIsPrimaryConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// List mocks base method. +func (m *MockInstanceDomainRepository) List(arg0 context.Context, arg1 database.QueryExecutor, arg2 ...database.QueryOption) ([]*domain.InstanceDomain, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) + ret0, _ := ret[0].([]*domain.InstanceDomain) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockInstanceDomainRepositoryMockRecorder) List(arg0, arg1 any, arg2 ...any) *MockInstanceDomainRepositoryListCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockInstanceDomainRepository)(nil).List), varargs...) + return &MockInstanceDomainRepositoryListCall{Call: call} +} + +// MockInstanceDomainRepositoryListCall wrap *gomock.Call +type MockInstanceDomainRepositoryListCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryListCall) Return(arg0 []*domain.InstanceDomain, arg1 error) *MockInstanceDomainRepositoryListCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryListCall) Do(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.InstanceDomain, error)) *MockInstanceDomainRepositoryListCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryListCall) DoAndReturn(f func(context.Context, database.QueryExecutor, ...database.QueryOption) ([]*domain.InstanceDomain, error)) *MockInstanceDomainRepositoryListCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyColumns mocks base method. +func (m *MockInstanceDomainRepository) PrimaryKeyColumns() []database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyColumns") + ret0, _ := ret[0].([]database.Column) + return ret0 +} + +// PrimaryKeyColumns indicates an expected call of PrimaryKeyColumns. +func (mr *MockInstanceDomainRepositoryMockRecorder) PrimaryKeyColumns() *MockInstanceDomainRepositoryPrimaryKeyColumnsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyColumns", reflect.TypeOf((*MockInstanceDomainRepository)(nil).PrimaryKeyColumns)) + return &MockInstanceDomainRepositoryPrimaryKeyColumnsCall{Call: call} +} + +// MockInstanceDomainRepositoryPrimaryKeyColumnsCall wrap *gomock.Call +type MockInstanceDomainRepositoryPrimaryKeyColumnsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryPrimaryKeyColumnsCall) Return(arg0 []database.Column) *MockInstanceDomainRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryPrimaryKeyColumnsCall) Do(f func() []database.Column) *MockInstanceDomainRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryPrimaryKeyColumnsCall) DoAndReturn(f func() []database.Column) *MockInstanceDomainRepositoryPrimaryKeyColumnsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// PrimaryKeyCondition mocks base method. +func (m *MockInstanceDomainRepository) PrimaryKeyCondition(arg0 string) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PrimaryKeyCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// PrimaryKeyCondition indicates an expected call of PrimaryKeyCondition. +func (mr *MockInstanceDomainRepositoryMockRecorder) PrimaryKeyCondition(arg0 any) *MockInstanceDomainRepositoryPrimaryKeyConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrimaryKeyCondition", reflect.TypeOf((*MockInstanceDomainRepository)(nil).PrimaryKeyCondition), arg0) + return &MockInstanceDomainRepositoryPrimaryKeyConditionCall{Call: call} +} + +// MockInstanceDomainRepositoryPrimaryKeyConditionCall wrap *gomock.Call +type MockInstanceDomainRepositoryPrimaryKeyConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryPrimaryKeyConditionCall) Return(arg0 database.Condition) *MockInstanceDomainRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryPrimaryKeyConditionCall) Do(f func(string) database.Condition) *MockInstanceDomainRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryPrimaryKeyConditionCall) DoAndReturn(f func(string) database.Condition) *MockInstanceDomainRepositoryPrimaryKeyConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Remove mocks base method. +func (m *MockInstanceDomainRepository) Remove(arg0 context.Context, arg1 database.QueryExecutor, arg2 database.Condition) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remove", arg0, arg1, arg2) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Remove indicates an expected call of Remove. +func (mr *MockInstanceDomainRepositoryMockRecorder) Remove(arg0, arg1, arg2 any) *MockInstanceDomainRepositoryRemoveCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remove", reflect.TypeOf((*MockInstanceDomainRepository)(nil).Remove), arg0, arg1, arg2) + return &MockInstanceDomainRepositoryRemoveCall{Call: call} +} + +// MockInstanceDomainRepositoryRemoveCall wrap *gomock.Call +type MockInstanceDomainRepositoryRemoveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryRemoveCall) Return(arg0 int64, arg1 error) *MockInstanceDomainRepositoryRemoveCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryRemoveCall) Do(f func(context.Context, database.QueryExecutor, database.Condition) (int64, error)) *MockInstanceDomainRepositoryRemoveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryRemoveCall) DoAndReturn(f func(context.Context, database.QueryExecutor, database.Condition) (int64, error)) *MockInstanceDomainRepositoryRemoveCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetPrimary mocks base method. +func (m *MockInstanceDomainRepository) SetPrimary() database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetPrimary") + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetPrimary indicates an expected call of SetPrimary. +func (mr *MockInstanceDomainRepositoryMockRecorder) SetPrimary() *MockInstanceDomainRepositorySetPrimaryCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPrimary", reflect.TypeOf((*MockInstanceDomainRepository)(nil).SetPrimary)) + return &MockInstanceDomainRepositorySetPrimaryCall{Call: call} +} + +// MockInstanceDomainRepositorySetPrimaryCall wrap *gomock.Call +type MockInstanceDomainRepositorySetPrimaryCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositorySetPrimaryCall) Return(arg0 database.Change) *MockInstanceDomainRepositorySetPrimaryCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositorySetPrimaryCall) Do(f func() database.Change) *MockInstanceDomainRepositorySetPrimaryCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositorySetPrimaryCall) DoAndReturn(f func() database.Change) *MockInstanceDomainRepositorySetPrimaryCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetType mocks base method. +func (m *MockInstanceDomainRepository) SetType(arg0 domain.DomainType) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetType", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetType indicates an expected call of SetType. +func (mr *MockInstanceDomainRepositoryMockRecorder) SetType(arg0 any) *MockInstanceDomainRepositorySetTypeCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetType", reflect.TypeOf((*MockInstanceDomainRepository)(nil).SetType), arg0) + return &MockInstanceDomainRepositorySetTypeCall{Call: call} +} + +// MockInstanceDomainRepositorySetTypeCall wrap *gomock.Call +type MockInstanceDomainRepositorySetTypeCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositorySetTypeCall) Return(arg0 database.Change) *MockInstanceDomainRepositorySetTypeCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositorySetTypeCall) Do(f func(domain.DomainType) database.Change) *MockInstanceDomainRepositorySetTypeCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositorySetTypeCall) DoAndReturn(f func(domain.DomainType) database.Change) *MockInstanceDomainRepositorySetTypeCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SetUpdatedAt mocks base method. +func (m *MockInstanceDomainRepository) SetUpdatedAt(arg0 time.Time) database.Change { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetUpdatedAt", arg0) + ret0, _ := ret[0].(database.Change) + return ret0 +} + +// SetUpdatedAt indicates an expected call of SetUpdatedAt. +func (mr *MockInstanceDomainRepositoryMockRecorder) SetUpdatedAt(arg0 any) *MockInstanceDomainRepositorySetUpdatedAtCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetUpdatedAt", reflect.TypeOf((*MockInstanceDomainRepository)(nil).SetUpdatedAt), arg0) + return &MockInstanceDomainRepositorySetUpdatedAtCall{Call: call} +} + +// MockInstanceDomainRepositorySetUpdatedAtCall wrap *gomock.Call +type MockInstanceDomainRepositorySetUpdatedAtCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositorySetUpdatedAtCall) Return(arg0 database.Change) *MockInstanceDomainRepositorySetUpdatedAtCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositorySetUpdatedAtCall) Do(f func(time.Time) database.Change) *MockInstanceDomainRepositorySetUpdatedAtCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositorySetUpdatedAtCall) DoAndReturn(f func(time.Time) database.Change) *MockInstanceDomainRepositorySetUpdatedAtCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TypeColumn mocks base method. +func (m *MockInstanceDomainRepository) TypeColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TypeColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// TypeColumn indicates an expected call of TypeColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) TypeColumn() *MockInstanceDomainRepositoryTypeColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TypeColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).TypeColumn)) + return &MockInstanceDomainRepositoryTypeColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryTypeColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryTypeColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryTypeColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryTypeColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryTypeColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryTypeColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryTypeColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryTypeColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TypeCondition mocks base method. +func (m *MockInstanceDomainRepository) TypeCondition(arg0 domain.DomainType) database.Condition { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TypeCondition", arg0) + ret0, _ := ret[0].(database.Condition) + return ret0 +} + +// TypeCondition indicates an expected call of TypeCondition. +func (mr *MockInstanceDomainRepositoryMockRecorder) TypeCondition(arg0 any) *MockInstanceDomainRepositoryTypeConditionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TypeCondition", reflect.TypeOf((*MockInstanceDomainRepository)(nil).TypeCondition), arg0) + return &MockInstanceDomainRepositoryTypeConditionCall{Call: call} +} + +// MockInstanceDomainRepositoryTypeConditionCall wrap *gomock.Call +type MockInstanceDomainRepositoryTypeConditionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryTypeConditionCall) Return(arg0 database.Condition) *MockInstanceDomainRepositoryTypeConditionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryTypeConditionCall) Do(f func(domain.DomainType) database.Condition) *MockInstanceDomainRepositoryTypeConditionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryTypeConditionCall) DoAndReturn(f func(domain.DomainType) database.Condition) *MockInstanceDomainRepositoryTypeConditionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Update mocks base method. +func (m *MockInstanceDomainRepository) Update(arg0 context.Context, arg1 database.QueryExecutor, arg2 database.Condition, arg3 ...database.Change) (int64, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1, arg2} + for _, a := range arg3 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Update", varargs...) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Update indicates an expected call of Update. +func (mr *MockInstanceDomainRepositoryMockRecorder) Update(arg0, arg1, arg2 any, arg3 ...any) *MockInstanceDomainRepositoryUpdateCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1, arg2}, arg3...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockInstanceDomainRepository)(nil).Update), varargs...) + return &MockInstanceDomainRepositoryUpdateCall{Call: call} +} + +// MockInstanceDomainRepositoryUpdateCall wrap *gomock.Call +type MockInstanceDomainRepositoryUpdateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryUpdateCall) Return(arg0 int64, arg1 error) *MockInstanceDomainRepositoryUpdateCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryUpdateCall) Do(f func(context.Context, database.QueryExecutor, database.Condition, ...database.Change) (int64, error)) *MockInstanceDomainRepositoryUpdateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryUpdateCall) DoAndReturn(f func(context.Context, database.QueryExecutor, database.Condition, ...database.Change) (int64, error)) *MockInstanceDomainRepositoryUpdateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdatedAtColumn mocks base method. +func (m *MockInstanceDomainRepository) UpdatedAtColumn() database.Column { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdatedAtColumn") + ret0, _ := ret[0].(database.Column) + return ret0 +} + +// UpdatedAtColumn indicates an expected call of UpdatedAtColumn. +func (mr *MockInstanceDomainRepositoryMockRecorder) UpdatedAtColumn() *MockInstanceDomainRepositoryUpdatedAtColumnCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatedAtColumn", reflect.TypeOf((*MockInstanceDomainRepository)(nil).UpdatedAtColumn)) + return &MockInstanceDomainRepositoryUpdatedAtColumnCall{Call: call} +} + +// MockInstanceDomainRepositoryUpdatedAtColumnCall wrap *gomock.Call +type MockInstanceDomainRepositoryUpdatedAtColumnCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockInstanceDomainRepositoryUpdatedAtColumnCall) Return(arg0 database.Column) *MockInstanceDomainRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockInstanceDomainRepositoryUpdatedAtColumnCall) Do(f func() database.Column) *MockInstanceDomainRepositoryUpdatedAtColumnCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockInstanceDomainRepositoryUpdatedAtColumnCall) DoAndReturn(f func() database.Column) *MockInstanceDomainRepositoryUpdatedAtColumnCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/backend/v3/domain/mock/instance_domain_repo.go b/backend/v3/domain/mock/instance_domain_repo.go new file mode 100644 index 000000000..6a8c6f237 --- /dev/null +++ b/backend/v3/domain/mock/instance_domain_repo.go @@ -0,0 +1,52 @@ +package domainmock + +import ( + context "context" + + gomock "go.uber.org/mock/gomock" + + domain "github.com/zitadel/zitadel/backend/v3/domain" + database "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/repository" +) + +type InstancesDomainRepo struct { + domain.InstanceDomainRepository + mock *MockInstanceDomainRepository +} + +func NewInstancesDomainRepo(ctrl *gomock.Controller) *InstancesDomainRepo { + return &InstancesDomainRepo{ + mock: NewMockInstanceDomainRepository(ctrl), + InstanceDomainRepository: repository.InstanceDomainRepository(), + } +} + +func (r *InstancesDomainRepo) EXPECT() *MockInstanceDomainRepositoryMockRecorder { + return r.mock.EXPECT() +} + +func (r *InstancesDomainRepo) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.InstanceDomain, error) { + return r.mock.Get(ctx, client, opts...) + +} + +func (r *InstancesDomainRepo) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.InstanceDomain, error) { + return r.mock.List(ctx, client, opts...) + +} + +func (r *InstancesDomainRepo) Add(ctx context.Context, client database.QueryExecutor, domain *domain.AddInstanceDomain) error { + return r.mock.Add(ctx, client, domain) + +} + +func (r *InstancesDomainRepo) Update(ctx context.Context, client database.QueryExecutor, condition database.Condition, changes ...database.Change) (int64, error) { + return r.mock.Update(ctx, client, condition, changes...) + +} + +func (r *InstancesDomainRepo) Remove(ctx context.Context, client database.QueryExecutor, condition database.Condition) (int64, error) { + return r.mock.Remove(ctx, client, condition) + +} diff --git a/backend/v3/domain/mock/instance_repo.go b/backend/v3/domain/mock/instance_repo.go new file mode 100644 index 000000000..9f96dd80c --- /dev/null +++ b/backend/v3/domain/mock/instance_repo.go @@ -0,0 +1,56 @@ +package domainmock + +import ( + context "context" + + gomock "go.uber.org/mock/gomock" + + domain "github.com/zitadel/zitadel/backend/v3/domain" + database "github.com/zitadel/zitadel/backend/v3/storage/database" + "github.com/zitadel/zitadel/backend/v3/storage/database/repository" +) + +type InstanceRepo struct { + domain.InstanceRepository + mock *MockInstanceRepository +} + +func NewInstanceRepo(ctrl *gomock.Controller) *InstanceRepo { + return &InstanceRepo{ + mock: NewMockInstanceRepository(ctrl), + InstanceRepository: repository.InstanceRepository(), + } +} + +func (r *InstanceRepo) EXPECT() *MockInstanceRepositoryMockRecorder { + return r.mock.EXPECT() +} + +func (r *InstanceRepo) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.Instance, error) { + return r.mock.Get(ctx, client, opts...) + +} + +func (r *InstanceRepo) List(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) ([]*domain.Instance, error) { + return r.mock.List(ctx, client, opts...) + +} + +func (r *InstanceRepo) Create(ctx context.Context, client database.QueryExecutor, instance *domain.Instance) error { + return r.mock.Create(ctx, client, instance) + +} + +func (r *InstanceRepo) Update(ctx context.Context, client database.QueryExecutor, instanceID string, changes ...database.Change) (int64, error) { + return r.mock.Update(ctx, client, instanceID, changes...) + +} + +func (r *InstanceRepo) Delete(ctx context.Context, client database.QueryExecutor, instanceID string) (int64, error) { + return r.mock.Delete(ctx, client, instanceID) + +} + +func (r *InstanceRepo) LoadDomains() domain.InstanceRepository { + return r.mock.LoadDomains() +} diff --git a/backend/v3/domain/mock/org_domain_repo.go b/backend/v3/domain/mock/org_domain_repo.go index 0b29f4d98..1385deed2 100644 --- a/backend/v3/domain/mock/org_domain_repo.go +++ b/backend/v3/domain/mock/org_domain_repo.go @@ -22,6 +22,10 @@ func NewOrgDomainRepo(ctrl *gomock.Controller) *OrgDomainRepo { } } +func (r *OrgDomainRepo) EXPECT() *MockOrganizationDomainRepositoryMockRecorder { + return r.mock.EXPECT() +} + func (r *OrgDomainRepo) Get(ctx context.Context, client database.QueryExecutor, opts ...database.QueryOption) (*domain.OrganizationDomain, error) { return r.mock.Get(ctx, client, opts...) diff --git a/backend/v3/domain/mock/permission.mock.go b/backend/v3/domain/mock/permission.mock.go new file mode 100644 index 000000000..5d0f21150 --- /dev/null +++ b/backend/v3/domain/mock/permission.mock.go @@ -0,0 +1,192 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/zitadel/zitadel/backend/v3/domain (interfaces: PermissionChecker) +// +// Generated by this command: +// +// mockgen -typed -package domainmock -destination ./mock/permission.mock.go . PermissionChecker +// + +// Package domainmock is a generated GoMock package. +package domainmock + +import ( + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockPermissionChecker is a mock of PermissionChecker interface. +type MockPermissionChecker struct { + ctrl *gomock.Controller + recorder *MockPermissionCheckerMockRecorder +} + +// MockPermissionCheckerMockRecorder is the mock recorder for MockPermissionChecker. +type MockPermissionCheckerMockRecorder struct { + mock *MockPermissionChecker +} + +// NewMockPermissionChecker creates a new mock instance. +func NewMockPermissionChecker(ctrl *gomock.Controller) *MockPermissionChecker { + mock := &MockPermissionChecker{ctrl: ctrl} + mock.recorder = &MockPermissionCheckerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPermissionChecker) EXPECT() *MockPermissionCheckerMockRecorder { + return m.recorder +} + +// CheckInstancePermission mocks base method. +func (m *MockPermissionChecker) CheckInstancePermission(arg0 context.Context, arg1 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckInstancePermission", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckInstancePermission indicates an expected call of CheckInstancePermission. +func (mr *MockPermissionCheckerMockRecorder) CheckInstancePermission(arg0, arg1 any) *MockPermissionCheckerCheckInstancePermissionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckInstancePermission", reflect.TypeOf((*MockPermissionChecker)(nil).CheckInstancePermission), arg0, arg1) + return &MockPermissionCheckerCheckInstancePermissionCall{Call: call} +} + +// MockPermissionCheckerCheckInstancePermissionCall wrap *gomock.Call +type MockPermissionCheckerCheckInstancePermissionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockPermissionCheckerCheckInstancePermissionCall) Return(arg0 error) *MockPermissionCheckerCheckInstancePermissionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockPermissionCheckerCheckInstancePermissionCall) Do(f func(context.Context, string) error) *MockPermissionCheckerCheckInstancePermissionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockPermissionCheckerCheckInstancePermissionCall) DoAndReturn(f func(context.Context, string) error) *MockPermissionCheckerCheckInstancePermissionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CheckOrganizationPermission mocks base method. +func (m *MockPermissionChecker) CheckOrganizationPermission(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckOrganizationPermission", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckOrganizationPermission indicates an expected call of CheckOrganizationPermission. +func (mr *MockPermissionCheckerMockRecorder) CheckOrganizationPermission(arg0, arg1, arg2 any) *MockPermissionCheckerCheckOrganizationPermissionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckOrganizationPermission", reflect.TypeOf((*MockPermissionChecker)(nil).CheckOrganizationPermission), arg0, arg1, arg2) + return &MockPermissionCheckerCheckOrganizationPermissionCall{Call: call} +} + +// MockPermissionCheckerCheckOrganizationPermissionCall wrap *gomock.Call +type MockPermissionCheckerCheckOrganizationPermissionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockPermissionCheckerCheckOrganizationPermissionCall) Return(arg0 error) *MockPermissionCheckerCheckOrganizationPermissionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockPermissionCheckerCheckOrganizationPermissionCall) Do(f func(context.Context, string, string) error) *MockPermissionCheckerCheckOrganizationPermissionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockPermissionCheckerCheckOrganizationPermissionCall) DoAndReturn(f func(context.Context, string, string) error) *MockPermissionCheckerCheckOrganizationPermissionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CheckProjectGrantPermission mocks base method. +func (m *MockPermissionChecker) CheckProjectGrantPermission(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckProjectGrantPermission", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckProjectGrantPermission indicates an expected call of CheckProjectGrantPermission. +func (mr *MockPermissionCheckerMockRecorder) CheckProjectGrantPermission(arg0, arg1, arg2 any) *MockPermissionCheckerCheckProjectGrantPermissionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckProjectGrantPermission", reflect.TypeOf((*MockPermissionChecker)(nil).CheckProjectGrantPermission), arg0, arg1, arg2) + return &MockPermissionCheckerCheckProjectGrantPermissionCall{Call: call} +} + +// MockPermissionCheckerCheckProjectGrantPermissionCall wrap *gomock.Call +type MockPermissionCheckerCheckProjectGrantPermissionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockPermissionCheckerCheckProjectGrantPermissionCall) Return(arg0 error) *MockPermissionCheckerCheckProjectGrantPermissionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockPermissionCheckerCheckProjectGrantPermissionCall) Do(f func(context.Context, string, string) error) *MockPermissionCheckerCheckProjectGrantPermissionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockPermissionCheckerCheckProjectGrantPermissionCall) DoAndReturn(f func(context.Context, string, string) error) *MockPermissionCheckerCheckProjectGrantPermissionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// CheckProjectPermission mocks base method. +func (m *MockPermissionChecker) CheckProjectPermission(arg0 context.Context, arg1, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CheckProjectPermission", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// CheckProjectPermission indicates an expected call of CheckProjectPermission. +func (mr *MockPermissionCheckerMockRecorder) CheckProjectPermission(arg0, arg1, arg2 any) *MockPermissionCheckerCheckProjectPermissionCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckProjectPermission", reflect.TypeOf((*MockPermissionChecker)(nil).CheckProjectPermission), arg0, arg1, arg2) + return &MockPermissionCheckerCheckProjectPermissionCall{Call: call} +} + +// MockPermissionCheckerCheckProjectPermissionCall wrap *gomock.Call +type MockPermissionCheckerCheckProjectPermissionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *MockPermissionCheckerCheckProjectPermissionCall) Return(arg0 error) *MockPermissionCheckerCheckProjectPermissionCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *MockPermissionCheckerCheckProjectPermissionCall) Do(f func(context.Context, string, string) error) *MockPermissionCheckerCheckProjectPermissionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *MockPermissionCheckerCheckProjectPermissionCall) DoAndReturn(f func(context.Context, string, string) error) *MockPermissionCheckerCheckProjectPermissionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/backend/v3/domain/permission.go b/backend/v3/domain/permission.go index 3484085fe..0ccb0f84c 100644 --- a/backend/v3/domain/permission.go +++ b/backend/v3/domain/permission.go @@ -2,6 +2,13 @@ package domain import "context" +const ( + InstanceReadPermission = "instance.read" + InstanceWritePermission = "instance.write" + OrganizationReadPermission = "organization.read" + OrganizationWritePermission = "organization.write" +) + // PermissionRepository is the interface that manages and checks Zitadel permissions. // // TODO(muhlemmer): This just defines the checker methods, rest to be done later. @@ -10,6 +17,8 @@ type PermissionRepository interface { } // PermissionChecker defines the methods needed to check permissions. +// +//go:generate mockgen -typed -package domainmock -destination ./mock/permission.mock.go . PermissionChecker type PermissionChecker interface { // Check if the authenticated user has the given permission on instance level. CheckInstancePermission(ctx context.Context, permission string) error diff --git a/internal/api/grpc/instance/v2beta/instance.go b/internal/api/grpc/instance/v2beta/instance.go index b3f2d6e47..a90876d1d 100644 --- a/internal/api/grpc/instance/v2beta/instance.go +++ b/internal/api/grpc/instance/v2beta/instance.go @@ -6,10 +6,16 @@ import ( "connectrpc.com/connect" "google.golang.org/protobuf/types/known/timestamppb" + instancev2 "github.com/zitadel/zitadel/backend/v3/api/instance/v2" + "github.com/zitadel/zitadel/internal/api/authz" instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" ) func (s *Server) DeleteInstance(ctx context.Context, request *connect.Request[instance.DeleteInstanceRequest]) (*connect.Response[instance.DeleteInstanceResponse], error) { + if authz.GetFeatures(ctx).EnableRelationalTables { + return instancev2.DeleteInstance(ctx, request) + } + obj, err := s.command.RemoveInstance(ctx, request.Msg.GetInstanceId()) if err != nil { return nil, err @@ -22,6 +28,10 @@ func (s *Server) DeleteInstance(ctx context.Context, request *connect.Request[in } func (s *Server) UpdateInstance(ctx context.Context, request *connect.Request[instance.UpdateInstanceRequest]) (*connect.Response[instance.UpdateInstanceResponse], error) { + if authz.GetFeatures(ctx).EnableRelationalTables { + return instancev2.UpdateInstance(ctx, request) + } + obj, err := s.command.UpdateInstance(ctx, request.Msg.GetInstanceName()) if err != nil { return nil, err diff --git a/internal/api/grpc/instance/v2beta/integration_test/instance_test.go b/internal/api/grpc/instance/v2beta/integration_test/instance_test.go index cdc34dd93..576d2f5f5 100644 --- a/internal/api/grpc/instance/v2beta/integration_test/instance_test.go +++ b/internal/api/grpc/instance/v2beta/integration_test/instance_test.go @@ -4,15 +4,18 @@ package instance_test import ( "context" + "fmt" "testing" "time" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/pkg/grpc/feature/v2" instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" ) @@ -20,66 +23,77 @@ func TestDeleteInstace(t *testing.T) { t.Parallel() // Given - ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() ctxWithSysAuthZ := integration.WithSystemAuthorization(ctx) - inst := integration.NewInstance(ctxWithSysAuthZ) + instEventStore := integration.NewInstance(ctxWithSysAuthZ) - t.Cleanup(func() { - inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst.ID()}) + instRelational := integration.NewInstance(ctxWithSysAuthZ) + integration.EnsureInstanceFeature(t, ctxWithSysAuthZ, instRelational, &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) { + assert.True(tCollect, got.EnableRelationalTables.GetEnabled()) }) - tt := []struct { - testName string - inputRequest *instance.DeleteInstanceRequest - inputContext context.Context - expectedErrorMsg string - expectedErrorCode codes.Code - expectedInstanceID string - }{ - { - testName: "when invalid context should return unauthN error", - inputRequest: &instance.DeleteInstanceRequest{ - InstanceId: " ", - }, - inputContext: context.Background(), - expectedErrorCode: codes.Unauthenticated, - expectedErrorMsg: "auth header missing", - }, - { - testName: "when invalid input should return invalid argument error", - inputRequest: &instance.DeleteInstanceRequest{ - InstanceId: inst.ID() + "invalid", - }, - inputContext: ctxWithSysAuthZ, - expectedErrorCode: codes.NotFound, - expectedErrorMsg: "Instance not found (COMMA-AE3GS)", - }, - { - testName: "when delete succeeds should return deletion date", - inputRequest: &instance.DeleteInstanceRequest{ - InstanceId: inst.ID(), - }, - inputContext: ctxWithSysAuthZ, - expectedInstanceID: inst.ID(), - }, + instances := []*integration.Instance{ + instEventStore, + instRelational, } + t.Cleanup(func() { + instRelational.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instRelational.ID()}) + instEventStore.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instEventStore.ID()}) + }) - for _, tc := range tt { - t.Run(tc.testName, func(t *testing.T) { - // Test - res, err := inst.Client.InstanceV2Beta.DeleteInstance(tc.inputContext, tc.inputRequest) + for _, inst := range instances { + tt := []struct { + testName string + inputRequest *instance.DeleteInstanceRequest + inputContext context.Context + expectedErrorMsg string + expectedErrorCode codes.Code + expectedInstanceID string + }{ + { + testName: "when invalid context should return unauthN error", + inputRequest: &instance.DeleteInstanceRequest{ + InstanceId: " ", + }, + inputContext: context.Background(), + expectedErrorCode: codes.Unauthenticated, + expectedErrorMsg: "auth header missing", + }, + { + testName: "when invalid input should return invalid argument error", + inputRequest: &instance.DeleteInstanceRequest{ + InstanceId: inst.ID() + "invalid", + }, + inputContext: ctxWithSysAuthZ, + expectedErrorCode: codes.NotFound, + expectedErrorMsg: "not found", + }, + { + testName: "when delete succeeds should return deletion date", + inputRequest: &instance.DeleteInstanceRequest{ + InstanceId: inst.ID(), + }, + inputContext: ctxWithSysAuthZ, + expectedInstanceID: inst.ID(), + }, + } + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + // Test + res, err := inst.Client.InstanceV2Beta.DeleteInstance(tc.inputContext, tc.inputRequest) - // Verify - assert.Equal(t, tc.expectedErrorCode, status.Code(err)) - assert.Equal(t, tc.expectedErrorMsg, status.Convert(err).Message()) - if tc.expectedErrorMsg == "" { - require.NotNil(t, res) - require.NotEmpty(t, res.GetDeletionDate()) - } - }) + // Verify + assert.Equal(t, tc.expectedErrorCode, status.Code(err)) + assert.Contains(t, status.Convert(err).Message(), tc.expectedErrorMsg) + if tc.expectedErrorMsg == "" { + require.NotNil(t, res) + require.NotEmpty(t, res.GetDeletionDate()) + } + }) + } } } @@ -92,72 +106,90 @@ func TestUpdateInstace(t *testing.T) { ctxWithSysAuthZ := integration.WithSystemAuthorization(ctx) - inst := integration.NewInstance(ctxWithSysAuthZ) - orgOwnerCtx := inst.WithAuthorization(context.Background(), integration.UserTypeOrgOwner) + instEventStore := integration.NewInstance(ctxWithSysAuthZ) + orgOwnerESCtx := instEventStore.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner) + + instRelational := integration.NewInstance(ctxWithSysAuthZ) + integration.EnsureInstanceFeature(t, ctxWithSysAuthZ, instRelational, &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) { + assert.True(tCollect, got.EnableRelationalTables.GetEnabled()) + }) + orgOwnerRelationalCtx := instRelational.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner) + + instances := []struct { + instance *integration.Instance + ctx context.Context + }{ + {instance: instEventStore, ctx: orgOwnerESCtx}, + {instance: instRelational, ctx: orgOwnerRelationalCtx}, + } t.Cleanup(func() { - inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst.ID()}) + instEventStore.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instEventStore.ID()}) + instRelational.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instRelational.ID()}) }) - tt := []struct { - testName string - inputRequest *instance.UpdateInstanceRequest - inputContext context.Context - expectedErrorMsg string - expectedErrorCode codes.Code - expectedNewName string - }{ - { - testName: "when invalid context should return unauthN error", - inputRequest: &instance.UpdateInstanceRequest{ - InstanceId: inst.ID(), - InstanceName: " ", + for i, inst := range instances { + tt := []struct { + testName string + inputRequest *instance.UpdateInstanceRequest + inputContext context.Context + expectedErrorMsg string + expectedErrorCode codes.Code + expectedNewName string + }{ + { + testName: "when invalid context should return unauthN error", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceId: inst.instance.ID(), + InstanceName: " ", + }, + inputContext: context.Background(), + expectedErrorCode: codes.Unauthenticated, + expectedErrorMsg: "auth header missing", }, - inputContext: context.Background(), - expectedErrorCode: codes.Unauthenticated, - expectedErrorMsg: "auth header missing", - }, - { - testName: "when unauthZ context should return unauthZ error", - inputRequest: &instance.UpdateInstanceRequest{ - InstanceId: inst.ID(), - InstanceName: " ", + { + testName: "when unauthZ context should return unauthZ error", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceId: inst.instance.ID(), + InstanceName: " ", + }, + inputContext: inst.ctx, + expectedErrorCode: codes.PermissionDenied, + expectedErrorMsg: "No matching permissions found (AUTH-5mWD2)", }, - inputContext: orgOwnerCtx, - expectedErrorCode: codes.PermissionDenied, - expectedErrorMsg: "No matching permissions found (AUTH-5mWD2)", - }, - { - testName: "when update succeeds should change instance name", - inputRequest: &instance.UpdateInstanceRequest{ - InstanceId: inst.ID(), - InstanceName: "an-updated-name", + { + testName: "when update succeeds should change instance name", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceId: inst.instance.ID(), + InstanceName: fmt.Sprintf("an-updated-name %d", i), + }, + inputContext: ctxWithSysAuthZ, + expectedNewName: fmt.Sprintf("an-updated-name %d", i), }, - inputContext: ctxWithSysAuthZ, - expectedNewName: "an-updated-name", - }, - } + } - for _, tc := range tt { - t.Run(tc.testName, func(t *testing.T) { - // Test - res, err := inst.Client.InstanceV2Beta.UpdateInstance(tc.inputContext, tc.inputRequest) + for _, tc := range tt { + t.Run(tc.testName, func(t *testing.T) { + // Test + res, err := inst.instance.Client.InstanceV2Beta.UpdateInstance(tc.inputContext, tc.inputRequest) - // Verify - assert.Equal(t, tc.expectedErrorCode, status.Code(err)) - assert.Equal(t, tc.expectedErrorMsg, status.Convert(err).Message()) - if tc.expectedErrorMsg == "" { + // Verify + assert.Equal(t, tc.expectedErrorCode, status.Code(err)) + assert.Equal(t, tc.expectedErrorMsg, status.Convert(err).Message()) + if tc.expectedErrorMsg == "" { - require.NotNil(t, res) - assert.NotEmpty(t, res.GetChangeDate()) + require.NotNil(t, res) + assert.NotEmpty(t, res.GetChangeDate()) + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tc.inputContext, time.Minute) + require.EventuallyWithT(t, func(tt *assert.CollectT) { + retrievedInstance, err := inst.instance.Client.InstanceV2Beta.GetInstance(tc.inputContext, &instance.GetInstanceRequest{InstanceId: inst.instance.ID()}) + require.Nil(tt, err) + assert.Equal(tt, tc.expectedNewName, retrievedInstance.GetInstance().GetName()) + }, retryDuration, tick, "timeout waiting for expected execution result") + } + }) + } - retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tc.inputContext, time.Minute) - require.EventuallyWithT(t, func(tt *assert.CollectT) { - retrievedInstance, err := inst.Client.InstanceV2Beta.GetInstance(tc.inputContext, &instance.GetInstanceRequest{InstanceId: inst.ID()}) - require.Nil(tt, err) - assert.Equal(tt, tc.expectedNewName, retrievedInstance.GetInstance().GetName()) - }, retryDuration, tick, "timeout waiting for expected execution result") - } - }) } } diff --git a/internal/api/grpc/instance/v2beta/integration_test/query_test.go b/internal/api/grpc/instance/v2beta/integration_test/query_test.go index 90c23dfd8..5eded645d 100644 --- a/internal/api/grpc/instance/v2beta/integration_test/query_test.go +++ b/internal/api/grpc/instance/v2beta/integration_test/query_test.go @@ -4,16 +4,18 @@ package instance_test import ( "context" - "slices" + "fmt" "testing" "time" + "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "github.com/zitadel/zitadel/internal/integration" + "github.com/zitadel/zitadel/pkg/grpc/feature/v2" filter "github.com/zitadel/zitadel/pkg/grpc/filter/v2beta" instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" "github.com/zitadel/zitadel/pkg/grpc/object/v2" @@ -27,43 +29,76 @@ func TestGetInstance(t *testing.T) { defer cancel() ctxWithSysAuthZ := integration.WithSystemAuthorization(ctx) - inst := integration.NewInstance(ctxWithSysAuthZ) - orgOwnerCtx := inst.WithAuthorization(context.Background(), integration.UserTypeOrgOwner) + instEventStore := integration.NewInstance(ctxWithSysAuthZ) + orgOwnerCtxES := instEventStore.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner) + + instRelational := integration.NewInstance(ctxWithSysAuthZ) + orgOwnerCtxREL := instRelational.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner) + integration.EnsureInstanceFeature(t, ctxWithSysAuthZ, instRelational, &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) { + assert.True(tCollect, got.GetEnableRelationalTables().GetEnabled()) + }) t.Cleanup(func() { - inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst.ID()}) + instRelational.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instRelational.ID()}) + instEventStore.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: instEventStore.ID()}) }) tt := []struct { testName string + instance *integration.Instance inputContext context.Context expectedInstanceID string expectedErrorMsg string expectedErrorCode codes.Code }{ { - testName: "when unauthN context should return unauthN error", + testName: "eventstore instance - when unauthN context should return unauthN error", inputContext: context.Background(), + instance: instEventStore, expectedErrorCode: codes.Unauthenticated, expectedErrorMsg: "auth header missing", }, { - testName: "when unauthZ context should return unauthZ error", - inputContext: orgOwnerCtx, + testName: "eventstore instance - when unauthZ context should return unauthZ error", + inputContext: orgOwnerCtxES, + instance: instEventStore, expectedErrorCode: codes.PermissionDenied, expectedErrorMsg: "No matching permissions found (AUTH-5mWD2)", }, { - testName: "when request succeeds should return matching instance", + testName: "eventstore instance - when request succeeds should return matching instance", inputContext: ctxWithSysAuthZ, - expectedInstanceID: inst.ID(), + instance: instEventStore, + expectedInstanceID: instEventStore.ID(), + }, + + // Relational + { + testName: "relational instance - when unauthN context should return unauthN error", + inputContext: context.Background(), + instance: instRelational, + expectedErrorCode: codes.Unauthenticated, + expectedErrorMsg: "auth header missing", + }, + { + testName: "relational instance - when unauthZ context should return unauthZ error", + inputContext: orgOwnerCtxREL, + instance: instRelational, + expectedErrorCode: codes.PermissionDenied, + expectedErrorMsg: "No matching permissions found (AUTH-5mWD2)", + }, + { + testName: "relational instance - when request succeeds should return matching instance", + inputContext: ctxWithSysAuthZ, + instance: instRelational, + expectedInstanceID: instRelational.ID(), }, } for _, tc := range tt { t.Run(tc.testName, func(t *testing.T) { // Test - res, err := inst.Client.InstanceV2Beta.GetInstance(tc.inputContext, &instance.GetInstanceRequest{InstanceId: inst.ID()}) + res, err := tc.instance.Client.InstanceV2Beta.GetInstance(tc.inputContext, &instance.GetInstanceRequest{InstanceId: tc.instance.ID()}) // Verify assert.Equal(t, tc.expectedErrorCode, status.Code(err)) @@ -86,26 +121,26 @@ func TestListInstances(t *testing.T) { ctxWithSysAuthZ := integration.WithSystemAuthorization(ctx) - instances := make([]*integration.Instance, 2) + instances := make([]*integration.Instance, 5) inst := integration.NewInstance(ctxWithSysAuthZ) inst2 := integration.NewInstance(ctxWithSysAuthZ) - instances[0], instances[1] = inst, inst2 + inst3 := integration.NewInstance(ctxWithSysAuthZ) + inst4 := integration.NewInstance(ctxWithSysAuthZ) + inst5 := integration.NewInstance(ctxWithSysAuthZ) + instances[0], instances[1], instances[2], instances[3], instances[4] = inst, inst2, inst3, inst4, inst5 t.Cleanup(func() { + inst.Client.FeatureV2.ResetInstanceFeatures(ctxWithSysAuthZ, &feature.ResetInstanceFeaturesRequest{}) inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst.ID()}) - inst.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst2.ID()}) + inst2.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst2.ID()}) + inst3.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst3.ID()}) + inst4.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst4.ID()}) + inst5.Client.InstanceV2Beta.DeleteInstance(ctxWithSysAuthZ, &instance.DeleteInstanceRequest{InstanceId: inst5.ID()}) }) - // Sort in descending order - slices.SortFunc(instances, func(i1, i2 *integration.Instance) int { - res := i1.Instance.Details.CreationDate.AsTime().Compare(i2.Instance.Details.CreationDate.AsTime()) - if res == 0 { - return res - } - return -res - }) + orgOwnerCtx := inst.WithAuthorizationToken(context.Background(), integration.UserTypeOrgOwner) - orgOwnerCtx := inst.WithAuthorization(context.Background(), integration.UserTypeOrgOwner) + relTableState := integration.RelationalTablesEnableMatrix() tt := []struct { testName string @@ -136,43 +171,57 @@ func TestListInstances(t *testing.T) { { testName: "when valid request with filter should return paginated response", inputRequest: &instance.ListInstancesRequest{ - Pagination: &filter.PaginationRequest{Offset: 0, Limit: 10}, + Pagination: &filter.PaginationRequest{Offset: 1, Limit: 3}, SortingColumn: instance.FieldName_FIELD_NAME_CREATION_DATE.Enum(), Queries: []*instance.Query{ { Query: &instance.Query_IdQuery{ IdQuery: &instance.IdsQuery{ - Ids: []string{inst.ID(), inst2.ID()}, + Ids: []string{inst.ID(), inst2.ID(), inst3.ID(), inst4.ID(), inst5.ID()}, + }, + }, + }, + { + Query: &instance.Query_DomainQuery{ + DomainQuery: &instance.DomainsQuery{ + Domains: []string{inst4.Domain, inst3.Domain, inst2.Domain, inst.Domain}, }, }, }, }, }, inputContext: ctxWithSysAuthZ, - expectedInstances: []string{inst2.ID(), inst.ID()}, + expectedInstances: []string{inst3.ID(), inst2.ID(), inst.ID()}, }, } - for _, tc := range tt { - t.Run(tc.testName, func(t *testing.T) { - // Test - res, err := inst.Client.InstanceV2Beta.ListInstances(tc.inputContext, tc.inputRequest) - - // Verify - assert.Equal(t, tc.expectedErrorCode, status.Code(err)) - assert.Equal(t, tc.expectedErrorMsg, status.Convert(err).Message()) - - if tc.expectedErrorMsg == "" { - require.NotNil(t, res) - - require.Len(t, res.GetInstances(), len(tc.expectedInstances)) - - for i, ins := range res.GetInstances() { - assert.Equal(t, tc.expectedInstances[i], ins.GetId()) - } - } + for _, stateCase := range relTableState { + integration.EnsureInstanceFeature(t, ctx, inst, stateCase.FeatureSet, func(tCollect *assert.CollectT, got *feature.GetInstanceFeaturesResponse) { + assert.Equal(tCollect, stateCase.FeatureSet.GetEnableRelationalTables(), got.EnableRelationalTables.GetEnabled()) }) + + for _, tc := range tt { + t.Run(fmt.Sprintf("%s - %s", stateCase.State, tc.testName), func(t *testing.T) { + // Test + res, err := inst.Client.InstanceV2Beta.ListInstances(tc.inputContext, tc.inputRequest) + + // Verify + assert.Equal(t, tc.expectedErrorCode, status.Code(err)) + assert.Equal(t, tc.expectedErrorMsg, status.Convert(err).Message()) + + if tc.expectedErrorMsg == "" { + require.NotNil(t, res) + + require.Len(t, res.GetInstances(), len(tc.expectedInstances)) + + for i, ins := range res.GetInstances() { + assert.Equal(t, tc.expectedInstances[i], ins.GetId()) + } + } + }) + } } + } func TestListCustomDomains(t *testing.T) { diff --git a/internal/api/grpc/instance/v2beta/query.go b/internal/api/grpc/instance/v2beta/query.go index 10716ffda..bda2ea46c 100644 --- a/internal/api/grpc/instance/v2beta/query.go +++ b/internal/api/grpc/instance/v2beta/query.go @@ -5,11 +5,17 @@ import ( "connectrpc.com/connect" + instancev2 "github.com/zitadel/zitadel/backend/v3/api/instance/v2" + "github.com/zitadel/zitadel/internal/api/authz" filter "github.com/zitadel/zitadel/internal/api/grpc/filter/v2beta" instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" ) -func (s *Server) GetInstance(ctx context.Context, _ *connect.Request[instance.GetInstanceRequest]) (*connect.Response[instance.GetInstanceResponse], error) { +func (s *Server) GetInstance(ctx context.Context, request *connect.Request[instance.GetInstanceRequest]) (*connect.Response[instance.GetInstanceResponse], error) { + if authz.GetFeatures(ctx).EnableRelationalTables { + return instancev2.GetInstance(ctx, request) + } + inst, err := s.query.Instance(ctx, true) if err != nil { return nil, err @@ -21,6 +27,10 @@ func (s *Server) GetInstance(ctx context.Context, _ *connect.Request[instance.Ge } func (s *Server) ListInstances(ctx context.Context, req *connect.Request[instance.ListInstancesRequest]) (*connect.Response[instance.ListInstancesResponse], error) { + if authz.GetFeatures(ctx).EnableRelationalTables { + return instancev2.ListInstances(ctx, req) + } + queries, err := ListInstancesRequestToModel(req.Msg, s.systemDefaults) if err != nil { return nil, err diff --git a/internal/integration/feature.go b/internal/integration/feature.go index 41b9eaba8..f27173b2c 100644 --- a/internal/integration/feature.go +++ b/internal/integration/feature.go @@ -38,13 +38,13 @@ type RelationalTableFeatureMatrix struct { // TODO(IAM-Marco): Once we have gotten rid of eventstore, this can be removed func RelationalTablesEnableMatrix() []RelationalTableFeatureMatrix { return []RelationalTableFeatureMatrix{ - { - State: "when relational tables are enabled", - FeatureSet: &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, - }, { State: "when relational tables are disabled", FeatureSet: &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(false)}, }, + { + State: "when relational tables are enabled", + FeatureSet: &feature.SetInstanceFeaturesRequest{EnableRelationalTables: gu.Ptr(true)}, + }, } }