Files
zitadel/internal/command/user_metadata_test.go
T
247e278505 feat: delete metadata on SetUserMetadata api (#11776)
# Which Problems Are Solved

Currently, to delete metadata a key, callers must use a separate
[DeleteMetadata](https://zitadel.com/docs/reference/api/user/zitadel.user.v2.UserService.DeleteUserMetadata)
API. This increases the complexity on client-side for operations where
metadata need to be synchronized.

# How the Problems Are Solved

Introduce the behavior to
[SetUserMetadata](https://zitadel.com/docs/reference/api/user/zitadel.user.v2.UserService.SetUserMetadata):

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

- Updated [User Metadata
page](https://zitadel.com/docs/guides/manage/customize/user-metadata#manage-user-metadata-through-the-management-api)

# Additional Context

Similar behavior will be applied to
[UpdateUser](https://zitadel.com/docs/reference/api/user/zitadel.user.v2.UserService.UpdateUser)
and
[SetOrganizationMetadata](https://zitadel.com/docs/reference/api/org/zitadel.org.v2.OrganizationService.SetOrganizationMetadata)

Breaking change? 
Currently, sending an empty value returns an error — no client should be
intentionally relying on that error as part of a working workflow. The
change goes from "rejected input" to "accepted input with defined
semantics."

In other words, it relaxes a restriction rather than tightening one.
Existing valid calls continue to work exactly as before. The only
scenario where it could be "breaking" is if someone explicitly depends
on the error response for empty values (e.g., using it as a validation
check), which would be unusual.

---------

Co-authored-by: Gayathri Vijayan <[email protected]>
Co-authored-by: Copilot <[email protected]>
2026-03-06 14:57:52 +01:00

1176 lines
26 KiB
Go

package command
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/zerrors"
)
func TestCommandSide_SetUserMetadata(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore
}
type (
args struct {
ctx context.Context
orgID string
userID string
metadata *domain.Metadata
check PermissionCheck
}
)
type res struct {
want *domain.Metadata
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "user not existing, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value"),
},
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "invalid metadata, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
},
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "add metadata, no permission",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value"),
},
check: func(resourceOwner, aggregateID string) error {
return zerrors.ThrowPermissionDenied(nil, "id", "permission denied")
},
},
res: res{
err: zerrors.IsPermissionDenied,
},
},
{
name: "add metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(),
expectPush(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value"),
},
},
res: res{
want: &domain.Metadata{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Key: "key",
Value: []byte("value"),
State: domain.MetadataStateActive,
},
},
},
{
name: "add metadata, reset, invalid",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
eventFromEventPusher(
user.NewMetadataRemovedAllEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
},
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "add metadata with same key, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
expectPush(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value2"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value2"),
},
},
res: res{
want: &domain.Metadata{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Key: "key",
Value: []byte("value2"),
State: domain.MetadataStateActive,
},
},
},
{
name: "add metadata with same key and value, ok (ignore)",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value"),
},
},
res: res{
want: &domain.Metadata{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Key: "key",
Value: []byte("value"),
State: domain.MetadataStateActive,
},
},
},
{
name: "add deleted metadata with same value, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
eventFromEventPusher(
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
),
),
),
expectPush(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadata: &domain.Metadata{
Key: "key",
Value: []byte("value"),
},
},
res: res{
want: &domain.Metadata{
ObjectRoot: models.ObjectRoot{
AggregateID: "user1",
ResourceOwner: "org1",
},
Key: "key",
Value: []byte("value"),
State: domain.MetadataStateActive,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore(t),
}
got, err := r.SetUserMetadata(tt.args.ctx, tt.args.metadata, tt.args.userID, tt.args.orgID, tt.args.check)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assert.Equal(t, tt.res.want, got)
}
})
}
}
func TestCommandSide_BulkSetUserMetadata(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore
}
type (
args struct {
ctx context.Context
orgID string
userID string
check PermissionCheck
metadataList []*domain.Metadata
}
)
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "empty metadata list, pre condition error",
fields: fields{
eventstore: expectEventstore(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "user not existing, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key", Value: []byte("value")},
{Key: "key1", Value: []byte("value1")},
},
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "empty metadata value, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key"},
{Key: "key1"},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
name: "add metadata, no permission",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
check: func(resourceOwner, aggregateID string) error {
return zerrors.ThrowPermissionDenied(nil, "id", "permission-denied")
},
metadataList: []*domain.Metadata{
{Key: "key", Value: []byte("value")},
{Key: "key1", Value: []byte("value1")},
},
},
res: res{
err: zerrors.IsPermissionDenied,
},
},
{
name: "add metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
)),
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key2",
[]byte("value2"),
)),
),
expectPush(
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
),
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key2",
[]byte("update"),
),
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key3",
[]byte("add"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key1"}, // delete
{Key: "key2", Value: []byte("update")},
{Key: "key3", Value: []byte("add")},
{Key: "key4"}, // ignore
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
{
name: "re add deleted metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
)),
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
)),
eventFromEventPusher(
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
)),
),
expectPush(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key2",
[]byte("value2"),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []*domain.Metadata{
{Key: "key", Value: []byte("value")},
{Key: "key1", Value: []byte("value1")},
{Key: "key2", Value: []byte("value2")},
},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore(t),
}
got, err := r.BulkSetUserMetadata(tt.args.ctx, tt.args.userID, tt.args.orgID, tt.args.check, tt.args.metadataList...)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assertObjectDetails(t, tt.res.want, got)
}
})
}
}
func TestCommandSide_UserRemoveMetadata(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore
}
type (
args struct {
ctx context.Context
orgID string
userID string
metadataKey string
check PermissionCheck
}
)
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "user not existing, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataKey: "key",
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "invalid metadata, pre condition error",
fields: fields{
eventstore: expectEventstore(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataKey: "",
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "metadata not existing, not found error",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataKey: "key",
},
res: res{
err: zerrors.IsNotFound,
},
},
{
name: "remove metadata, no permission",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataKey: "key",
check: func(resourceOwner, aggregateID string) error {
return zerrors.ThrowPermissionDenied(nil, "id", "permission denied")
},
},
res: res{
err: zerrors.IsPermissionDenied,
},
},
{
name: "remove metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
expectPush(
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataKey: "key",
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore(t),
}
got, err := r.RemoveUserMetadata(tt.args.ctx, tt.args.metadataKey, tt.args.userID, tt.args.orgID, tt.args.check)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assertObjectDetails(t, tt.res.want, got)
}
})
}
}
func TestCommandSide_BulkRemoveUserMetadata(t *testing.T) {
type fields struct {
eventstore func(t *testing.T) *eventstore.Eventstore
}
type (
args struct {
ctx context.Context
orgID string
userID string
check PermissionCheck
metadataList []string
}
)
type res struct {
want *domain.ObjectDetails
err func(error) bool
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
name: "empty metadata list, pre condition error",
fields: fields{
eventstore: expectEventstore(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "user not existing, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []string{"key", "key1"},
},
res: res{
err: zerrors.IsPreconditionFailed,
},
},
{
name: "remove metadata keys not existing, precondition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []string{"key", "key1"},
},
res: res{
err: zerrors.IsNotFound,
},
},
{
name: "invalid metadata, pre condition error",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []string{""},
},
res: res{
err: zerrors.IsErrorInvalidArgument,
},
},
{
name: "remove metadata, no permission",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []string{"key", "key1"},
check: func(resourceOwner, aggregateID string) error {
return zerrors.ThrowPermissionDenied(nil, "id", "permission denied")
},
},
res: res{
err: zerrors.IsPermissionDenied,
},
},
{
name: "remove metadata, ok",
fields: fields{
eventstore: expectEventstore(
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"",
"firstname lastname",
language.Und,
domain.GenderUnspecified,
"[email protected]",
true,
),
),
),
expectFilter(
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
[]byte("value"),
),
),
eventFromEventPusher(
user.NewMetadataSetEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
[]byte("value1"),
),
),
),
expectPush(
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
),
user.NewMetadataRemovedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key1",
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
metadataList: []string{"key", "key1"},
},
res: res{
want: &domain.ObjectDetails{
ResourceOwner: "org1",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore(t),
}
got, err := r.BulkRemoveUserMetadata(tt.args.ctx, tt.args.userID, tt.args.orgID, tt.args.check, tt.args.metadataList...)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if tt.res.err == nil {
assertObjectDetails(t, tt.res.want, got)
}
})
}
}