mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-11 20:22:22 +00:00
249 lines
7.5 KiB
Go
249 lines
7.5 KiB
Go
//go:build integration
|
|
|
|
package instance_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/zitadel/zitadel/internal/integration"
|
|
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) {
|
|
tt := []struct {
|
|
testName string
|
|
inputRequest *instance.CreateInstanceRequest
|
|
inputContext context.Context
|
|
expectedErrorMsg string
|
|
expectedErrorCode codes.Code
|
|
}{
|
|
{
|
|
testName: "when invalid context should return unauthN error",
|
|
inputRequest: &instance.CreateInstanceRequest{
|
|
InstanceName: " ",
|
|
FirstOrgName: " ",
|
|
CustomDomain: " ",
|
|
Owner: &instance.CreateInstanceRequest_Machine_{
|
|
Machine: &instance.CreateInstanceRequest_Machine{
|
|
UserName: "owner",
|
|
Name: "owner",
|
|
PersonalAccessToken: &instance.CreateInstanceRequest_PersonalAccessToken{},
|
|
},
|
|
},
|
|
DefaultLanguage: "",
|
|
},
|
|
inputContext: context.Background(),
|
|
expectedErrorCode: codes.Unauthenticated,
|
|
expectedErrorMsg: "auth header missing",
|
|
},
|
|
{
|
|
testName: "when invalid input should return no admin error",
|
|
inputRequest: &instance.CreateInstanceRequest{
|
|
InstanceName: " ",
|
|
FirstOrgName: " ",
|
|
CustomDomain: " ",
|
|
DefaultLanguage: "",
|
|
Owner: &instance.CreateInstanceRequest_Human_{
|
|
Human: &instance.CreateInstanceRequest_Human{
|
|
Email: &instance.CreateInstanceRequest_Email{
|
|
Email: " user@example.com ",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
inputContext: CTXWithSysAuthZ,
|
|
expectedErrorCode: codes.InvalidArgument,
|
|
expectedErrorMsg: "Given name in profile is empty (USER-UCej2)",
|
|
},
|
|
{
|
|
testName: "when input and context are valid should return expected response and no error",
|
|
inputRequest: &instance.CreateInstanceRequest{
|
|
InstanceName: " ",
|
|
FirstOrgName: " ",
|
|
CustomDomain: " ",
|
|
Owner: &instance.CreateInstanceRequest_Machine_{
|
|
Machine: &instance.CreateInstanceRequest_Machine{
|
|
UserName: "owner",
|
|
Name: "owner",
|
|
PersonalAccessToken: &instance.CreateInstanceRequest_PersonalAccessToken{},
|
|
},
|
|
},
|
|
DefaultLanguage: "",
|
|
},
|
|
inputContext: CTXWithSysAuthZ,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
// Given
|
|
cli, err := integration.NewDefaultClient(CTXWithSysAuthZ)
|
|
require.Nil(t, err)
|
|
|
|
// Test
|
|
res, err := cli.InstanceV2Beta.CreateInstance(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.NotEmpty(t, res.GetInstanceId())
|
|
assert.NotEmpty(t, res.GetPat())
|
|
|
|
require.NotNil(t, res.GetDetails())
|
|
assert.NotEmpty(t, res.GetDetails().GetResourceOwner())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteInstace(t *testing.T) {
|
|
// Given
|
|
inst := integration.NewInstance(CTXWithSysAuthZ)
|
|
|
|
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: " ",
|
|
},
|
|
inputContext: CTXWithSysAuthZ,
|
|
expectedErrorCode: codes.InvalidArgument,
|
|
expectedErrorMsg: "instance_id must not be empty (instance_id)",
|
|
},
|
|
{
|
|
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 invalid input should return invalid argument error",
|
|
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.NotNil(t, res.GetDetails())
|
|
assert.Equal(t, tc.expectedInstanceID, res.GetDetails().GetResourceOwner())
|
|
assert.NotEmpty(t, res.GetDetails().GetChangeDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
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")
|
|
}
|
|
})
|
|
}
|
|
}
|