mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-20 14:34:25 +00:00
# Which Problems Are Solved Currently, to delete an Organization metadata key, callers must use a separate [DeleteMetadata](https://zitadel.com/docs/reference/api/org/zitadel.org.v2.OrganizationService.DeleteOrganizationMetadata) API. This increases the complexity on client-side for operations where metadata need to be synchronized. # How the Problems Are Solved Introduce deletion behavior to [SetOrganizationMetadata](https://zitadel.com/docs/reference/api/org/zitadel.org.v2.OrganizationService.SetOrganizationMetadata): When a metadata entry is passed with an empty value ("" / empty bytes): - If the key exists → delete the key - If the key does not exist → no-op (idempotent, no error) # Additional Changes n/a # Additional Context Relates to #11776 --------- Co-authored-by: Gayathri Vijayan <[email protected]> Co-authored-by: Gayathri Vijayan <[email protected]>
624 lines
23 KiB
Go
624 lines
23 KiB
Go
//go:build integration
|
|
|
|
package user_test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/zitadel/zitadel/internal/integration"
|
|
"github.com/zitadel/zitadel/pkg/grpc/filter/v2"
|
|
metadata "github.com/zitadel/zitadel/pkg/grpc/metadata/v2"
|
|
"github.com/zitadel/zitadel/pkg/grpc/user/v2"
|
|
)
|
|
|
|
func TestServer_SetUserMetadata(t *testing.T) {
|
|
iamOwnerCTX := Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
dep func(request *user.SetUserMetadataRequest)
|
|
req *user.SetUserMetadataRequest
|
|
assert func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse)
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "missing permission",
|
|
ctx: Instance.WithAuthorizationToken(context.Background(), integration.UserTypeNoPermission),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(OrgCTX, integration.Email()).GetId()
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))}},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "set user metadata",
|
|
ctx: iamOwnerCTX,
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(OrgCTX, integration.Email()).GetId()
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))}},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
assert.WithinRange(t, setResponse.GetSetDate().AsTime(), testStartTime, time.Now().UTC())
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
{
|
|
name: "set user metadata, multiple",
|
|
ctx: iamOwnerCTX,
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(OrgCTX, integration.Email()).GetId()
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))},
|
|
{Key: "key2", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value2")))},
|
|
{Key: "key3", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value3")))},
|
|
},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
assert.WithinRange(t, setResponse.GetSetDate().AsTime(), testStartTime, time.Now().UTC())
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))},
|
|
{Key: "key2", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value2")))},
|
|
{Key: "key3", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value3")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
{
|
|
name: "set user metadata on non existent user",
|
|
ctx: iamOwnerCTX,
|
|
req: &user.SetUserMetadataRequest{
|
|
UserId: "notexisting",
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))}},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "update user metadata",
|
|
ctx: Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key1", "value1")
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value2")))}},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
assert.WithinRange(t, setResponse.GetSetDate().AsTime(), testStartTime, time.Now().UTC())
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value2")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
{
|
|
name: "update user metadata with same value",
|
|
ctx: Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key1", "value1")
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))}},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
// assert that the set date is not updated, i.e., it is before testStartTime, because no change to the metadata should be made
|
|
assert.True(t, setResponse.GetSetDate().AsTime().Before(testStartTime))
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
{
|
|
name: "delete user metadata",
|
|
ctx: Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key1", "value1")
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{{Key: "key1", Value: nil}},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
assert.WithinRange(t, setResponse.GetSetDate().AsTime(), testStartTime, time.Now().UTC())
|
|
|
|
assert.Len(t, getResponse.GetMetadata(), 0)
|
|
},
|
|
},
|
|
{
|
|
name: "delete non-existent user metadata key is noop",
|
|
ctx: Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key1", "value1")
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{
|
|
{Key: "key2", Value: nil}, // delete non-existent key; should be a no-op
|
|
},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
// assert that the set date is not updated, i.e., it is before testStartTime, because no change to the metadata should be made
|
|
assert.True(t, setResponse.GetSetDate().AsTime().Before(testStartTime))
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key1", Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
{
|
|
name: "update and delete user metadata",
|
|
ctx: Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner),
|
|
dep: func(req *user.SetUserMetadataRequest) {
|
|
req.UserId = Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key1", "value1")
|
|
Instance.SetUserMetadata(iamOwnerCTX, req.UserId, "key2", "value2")
|
|
},
|
|
req: &user.SetUserMetadataRequest{
|
|
Metadata: []*user.Metadata{
|
|
{Key: "key1", Value: nil}, // delete
|
|
{Key: "key2", Value: []byte(base64.StdEncoding.EncodeToString([]byte("updated")))},
|
|
},
|
|
},
|
|
assert: func(t *testing.T, setResponse *user.SetUserMetadataResponse, testStartTime time.Time, getResponse *user.ListUserMetadataResponse) {
|
|
assert.WithinRange(t, setResponse.GetSetDate().AsTime(), testStartTime, time.Now().UTC())
|
|
|
|
expectedMetadata := []*metadata.Metadata{
|
|
{Key: "key2", Value: []byte(base64.StdEncoding.EncodeToString([]byte("updated")))},
|
|
}
|
|
integration.AssertMetadataEquals(t, expectedMetadata, getResponse.GetMetadata())
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.dep != nil {
|
|
tt.dep(tt.req)
|
|
}
|
|
testStartTime := time.Now().UTC()
|
|
got, err := Client.SetUserMetadata(tt.ctx, tt.req)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
|
|
Instance.TriggerUserByID(tt.ctx, tt.req.GetUserId())
|
|
|
|
gotMetadataResponse, err := Client.ListUserMetadata(tt.ctx, &user.ListUserMetadataRequest{
|
|
UserId: tt.req.GetUserId(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
tt.assert(t, got, testStartTime, gotMetadataResponse)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestServer_ListUserMetadata(t *testing.T) {
|
|
iamOwnerCTX := Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner)
|
|
|
|
type args struct {
|
|
ctx context.Context
|
|
dep func(context.Context, *user.ListUserMetadataRequest, *user.ListUserMetadataResponse)
|
|
req *user.ListUserMetadataRequest
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *user.ListUserMetadataResponse
|
|
}{
|
|
{
|
|
name: "missing permission, actual TotalResult count returned",
|
|
args: args{
|
|
ctx: Instance.WithAuthorizationToken(context.Background(), integration.UserTypeNoPermission),
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, "key1", "value1")
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list request",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
metadataResp := Instance.SetUserMetadata(iamOwnerCTX, userID, "key1", "value1")
|
|
|
|
response.Metadata[0] = &metadata.Metadata{
|
|
CreationDate: metadataResp.GetSetDate(),
|
|
ChangeDate: metadataResp.GetSetDate(),
|
|
Key: "key1",
|
|
Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1"))),
|
|
}
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list request single key",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key := "key1"
|
|
response.Metadata[0] = setUserMetadata(iamOwnerCTX, Instance, userID, key, "value1")
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, "key2", "value2")
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, "key3", "value3")
|
|
request.Filters[0] = &metadata.MetadataSearchFilter{
|
|
Filter: &metadata.MetadataSearchFilter_KeyFilter{KeyFilter: &metadata.MetadataKeyFilter{Key: key}},
|
|
}
|
|
},
|
|
req: &user.ListUserMetadataRequest{
|
|
Filters: []*metadata.MetadataSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple keys",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
|
|
response.Metadata[2] = setUserMetadata(iamOwnerCTX, Instance, userID, "key1", "value1")
|
|
response.Metadata[1] = setUserMetadata(iamOwnerCTX, Instance, userID, "key2", "value2")
|
|
response.Metadata[0] = setUserMetadata(iamOwnerCTX, Instance, userID, "key3", "value3")
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 3,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{}, {}, {},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.args.dep != nil {
|
|
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
|
}
|
|
|
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(iamOwnerCTX, time.Minute)
|
|
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
|
got, listErr := Instance.Client.UserV2.ListUserMetadata(tt.args.ctx, tt.args.req)
|
|
require.NoError(ttt, listErr)
|
|
// always first check length, otherwise its failed anyway
|
|
if assert.Len(ttt, got.Metadata, len(tt.want.Metadata)) {
|
|
assert.EqualExportedValues(ttt, got.Metadata, tt.want.Metadata)
|
|
}
|
|
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
|
}, retryDuration, tick, "timeout waiting for expected execution result")
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestServer_ListUserMetadata_WithPermissionV2(t *testing.T) {
|
|
ensureFeaturePermissionV2Enabled(t, InstancePermissionV2)
|
|
iamOwnerCTX := InstancePermissionV2.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner)
|
|
|
|
type args struct {
|
|
ctx context.Context
|
|
dep func(context.Context, *user.ListUserMetadataRequest, *user.ListUserMetadataResponse)
|
|
req *user.ListUserMetadataRequest
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *user.ListUserMetadataResponse
|
|
}{
|
|
{
|
|
name: "missing permission, TotalResult set to 0",
|
|
args: args{
|
|
ctx: InstancePermissionV2.WithAuthorizationToken(context.Background(), integration.UserTypeNoPermission),
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := InstancePermissionV2.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
InstancePermissionV2.SetUserMetadata(iamOwnerCTX, userID, "key1", "value1")
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 0,
|
|
AppliedLimit: 100,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list request",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := InstancePermissionV2.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
metadataResp := InstancePermissionV2.SetUserMetadata(iamOwnerCTX, userID, "key1", "value1")
|
|
|
|
response.Metadata[0] = &metadata.Metadata{
|
|
CreationDate: metadataResp.GetSetDate(),
|
|
ChangeDate: metadataResp.GetSetDate(),
|
|
Key: "key1",
|
|
Value: []byte(base64.StdEncoding.EncodeToString([]byte("value1"))),
|
|
}
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list request single key",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := InstancePermissionV2.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key := "key1"
|
|
response.Metadata[0] = setUserMetadata(iamOwnerCTX, InstancePermissionV2, userID, key, "value1")
|
|
InstancePermissionV2.SetUserMetadata(iamOwnerCTX, userID, "key2", "value2")
|
|
InstancePermissionV2.SetUserMetadata(iamOwnerCTX, userID, "key3", "value3")
|
|
request.Filters[0] = &metadata.MetadataSearchFilter{
|
|
Filter: &metadata.MetadataSearchFilter_KeyFilter{KeyFilter: &metadata.MetadataKeyFilter{Key: key}},
|
|
}
|
|
},
|
|
req: &user.ListUserMetadataRequest{
|
|
Filters: []*metadata.MetadataSearchFilter{{}},
|
|
},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 1,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "list multiple keys",
|
|
args: args{
|
|
ctx: iamOwnerCTX,
|
|
dep: func(ctx context.Context, request *user.ListUserMetadataRequest, response *user.ListUserMetadataResponse) {
|
|
userID := InstancePermissionV2.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
|
|
response.Metadata[2] = setUserMetadata(iamOwnerCTX, InstancePermissionV2, userID, "key1", "value1")
|
|
response.Metadata[1] = setUserMetadata(iamOwnerCTX, InstancePermissionV2, userID, "key2", "value2")
|
|
response.Metadata[0] = setUserMetadata(iamOwnerCTX, InstancePermissionV2, userID, "key3", "value3")
|
|
},
|
|
req: &user.ListUserMetadataRequest{},
|
|
},
|
|
want: &user.ListUserMetadataResponse{
|
|
Pagination: &filter.PaginationResponse{
|
|
TotalResult: 3,
|
|
AppliedLimit: 100,
|
|
},
|
|
Metadata: []*metadata.Metadata{
|
|
{}, {}, {},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.args.dep != nil {
|
|
tt.args.dep(tt.args.ctx, tt.args.req, tt.want)
|
|
}
|
|
|
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(iamOwnerCTX, time.Minute)
|
|
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
|
got, listErr := InstancePermissionV2.Client.UserV2.ListUserMetadata(tt.args.ctx, tt.args.req)
|
|
require.NoError(ttt, listErr)
|
|
// always first check length, otherwise its failed anyway
|
|
if assert.Len(ttt, got.Metadata, len(tt.want.Metadata)) {
|
|
assert.EqualExportedValues(ttt, got.Metadata, tt.want.Metadata)
|
|
}
|
|
assertPaginationResponse(ttt, tt.want.Pagination, got.Pagination)
|
|
}, retryDuration, tick, "timeout waiting for expected execution result")
|
|
})
|
|
}
|
|
}
|
|
|
|
func setUserMetadata(ctx context.Context, instance *integration.Instance, userID, key, value string) *metadata.Metadata {
|
|
metadataResp := instance.SetUserMetadata(ctx, userID, key, value)
|
|
return &metadata.Metadata{
|
|
CreationDate: metadataResp.GetSetDate(),
|
|
ChangeDate: metadataResp.GetSetDate(),
|
|
Key: key,
|
|
Value: []byte(base64.StdEncoding.EncodeToString([]byte(value))),
|
|
}
|
|
}
|
|
|
|
func assertPaginationResponse(t *assert.CollectT, expected *filter.PaginationResponse, actual *filter.PaginationResponse) {
|
|
assert.Equal(t, expected.AppliedLimit, actual.AppliedLimit)
|
|
assert.Equal(t, expected.TotalResult, actual.TotalResult)
|
|
}
|
|
|
|
func TestServer_DeleteUserMetadata(t *testing.T) {
|
|
iamOwnerCTX := Instance.WithAuthorizationToken(OrgCTX, integration.UserTypeIAMOwner)
|
|
|
|
tests := []struct {
|
|
name string
|
|
ctx context.Context
|
|
prepare func(request *user.DeleteUserMetadataRequest) (time.Time, time.Time)
|
|
req *user.DeleteUserMetadataRequest
|
|
wantDeletionDate bool
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "empty id",
|
|
ctx: iamOwnerCTX,
|
|
req: &user.DeleteUserMetadataRequest{
|
|
UserId: "",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "delete, user not existing",
|
|
ctx: iamOwnerCTX,
|
|
req: &user.DeleteUserMetadataRequest{
|
|
UserId: "notexisting",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "delete",
|
|
ctx: iamOwnerCTX,
|
|
prepare: func(request *user.DeleteUserMetadataRequest) (time.Time, time.Time) {
|
|
testStartTime := time.Now().UTC()
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key := "key1"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key, "value1")
|
|
request.Keys = []string{key}
|
|
return testStartTime, time.Time{}
|
|
},
|
|
req: &user.DeleteUserMetadataRequest{},
|
|
wantDeletionDate: true,
|
|
},
|
|
{
|
|
name: "delete, empty list",
|
|
ctx: iamOwnerCTX,
|
|
prepare: func(request *user.DeleteUserMetadataRequest) (time.Time, time.Time) {
|
|
testStartTime := time.Now().UTC()
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key := "key1"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key, "value1")
|
|
Instance.DeleteUserMetadata(iamOwnerCTX, userID, key)
|
|
return testStartTime, time.Now().UTC()
|
|
},
|
|
req: &user.DeleteUserMetadataRequest{},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "delete, already removed",
|
|
ctx: iamOwnerCTX,
|
|
prepare: func(request *user.DeleteUserMetadataRequest) (time.Time, time.Time) {
|
|
testStartTime := time.Now().UTC()
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key := "key1"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key, "value1")
|
|
Instance.DeleteUserMetadata(iamOwnerCTX, userID, key)
|
|
request.Keys = []string{key}
|
|
return testStartTime, time.Now().UTC()
|
|
},
|
|
req: &user.DeleteUserMetadataRequest{},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "delete, multiple",
|
|
ctx: iamOwnerCTX,
|
|
prepare: func(request *user.DeleteUserMetadataRequest) (time.Time, time.Time) {
|
|
testStartTime := time.Now().UTC()
|
|
userID := Instance.CreateUserTypeHuman(iamOwnerCTX, integration.Email()).GetId()
|
|
request.UserId = userID
|
|
key1 := "key1"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key1, "value1")
|
|
key2 := "key2"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key2, "value1")
|
|
key3 := "key3"
|
|
Instance.SetUserMetadata(iamOwnerCTX, userID, key3, "value1")
|
|
request.Keys = []string{key1, key2, key3}
|
|
return testStartTime, time.Time{}
|
|
},
|
|
req: &user.DeleteUserMetadataRequest{},
|
|
wantDeletionDate: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
var testStartTime, deletionDate time.Time
|
|
if tt.prepare != nil {
|
|
testStartTime, deletionDate = tt.prepare(tt.req)
|
|
}
|
|
got, err := Instance.Client.UserV2.DeleteUserMetadata(tt.ctx, tt.req)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assertDeleteProjectResponse(t, testStartTime, deletionDate, tt.wantDeletionDate, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func assertDeleteProjectResponse(t *testing.T, testStartTime, deletionDate time.Time, expectedDeletionDate bool, actualResp *user.DeleteUserMetadataResponse) {
|
|
if expectedDeletionDate {
|
|
if !deletionDate.IsZero() {
|
|
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), testStartTime, deletionDate)
|
|
} else {
|
|
assert.WithinRange(t, actualResp.GetDeletionDate().AsTime(), testStartTime, time.Now().UTC())
|
|
}
|
|
} else {
|
|
assert.Nil(t, actualResp.DeletionDate)
|
|
}
|
|
}
|