diff --git a/internal/api/grpc/instance/v2/integration_test/instance_test.go b/internal/api/grpc/instance/v2/integration_test/instance_test.go index 549765b51dd..2c00eb374a4 100644 --- a/internal/api/grpc/instance/v2/integration_test/instance_test.go +++ b/internal/api/grpc/instance/v2/integration_test/instance_test.go @@ -5,6 +5,7 @@ package instance_test import ( "context" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -12,6 +13,7 @@ import ( instance "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/emptypb" ) func TestCreateInstance(t *testing.T) { @@ -168,3 +170,79 @@ func TestDeleteInstace(t *testing.T) { }) } } + +func TestUpdateInstace(t *testing.T) { + // Given + inst := integration.NewInstance(CTXWithSysAuthZ) + orgOwnerCtx := inst.WithAuthorization(context.Background(), integration.UserTypeOrgOwner) + + 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{ + InstanceName: " ", + }, + inputContext: context.Background(), + expectedErrorCode: codes.Unauthenticated, + expectedErrorMsg: "auth header missing", + }, + { + testName: "when unauthZ context should return unauthZ error", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceName: " ", + }, + inputContext: orgOwnerCtx, + expectedErrorCode: codes.PermissionDenied, + expectedErrorMsg: "No matching permissions found (AUTH-5mWD2)", + }, + { + testName: "when invalid input should return invalid argument error", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceName: " ", + }, + inputContext: CTXWithSysAuthZ, + expectedErrorCode: codes.InvalidArgument, + expectedErrorMsg: "instance_name must not be empty (instance_name)", + }, + { + testName: "when update succeeds should change instance name", + inputRequest: &instance.UpdateInstanceRequest{ + InstanceName: "an-updated-name", + }, + 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) + + // 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.NotNil(t, res.GetDetails()) + assert.NotEmpty(t, res.GetDetails().GetChangeDate()) + assert.NotEmpty(t, res.GetDetails().GetResourceOwner()) + + retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tc.inputContext, 20*time.Second) + require.EventuallyWithT(t, func(tt *assert.CollectT) { + retrievedInstance, err := inst.Client.InstanceV2Beta.GetInstance(tc.inputContext, &emptypb.Empty{}) + require.Nil(tt, err) + assert.Equal(tt, tc.expectedNewName, retrievedInstance.GetInstance().GetName()) + }, retryDuration, tick, "timeout waiting for expected execution result") + } + }) + } +}