//go:build integration package user_test import ( "context" "fmt" "os" "testing" "time" "github.com/muhlemmer/gu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/zitadel/zitadel/internal/integration" object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha" user "github.com/zitadel/zitadel/pkg/grpc/user/v2alpha" "google.golang.org/protobuf/types/known/timestamppb" ) var ( CTX context.Context ErrCTX context.Context Tester *integration.Tester Client user.UserServiceClient ) func TestMain(m *testing.M) { os.Exit(func() int { ctx, errCtx, cancel := integration.Contexts(time.Hour) defer cancel() Tester = integration.NewTester(ctx) defer Tester.Done() CTX, ErrCTX = Tester.WithSystemAuthorization(ctx, integration.OrgOwner), errCtx Client = user.NewUserServiceClient(Tester.GRPCClientConn) return m.Run() }()) } func TestServer_AddHumanUser(t *testing.T) { type args struct { ctx context.Context req *user.AddHumanUserRequest } tests := []struct { name string args args want *user.AddHumanUserResponse wantErr bool }{ { name: "default verification", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Profile: &user.SetHumanProfile{ FirstName: "Donald", LastName: "Duck", NickName: gu.Ptr("Dukkie"), DisplayName: gu.Ptr("Donald Duck"), PreferredLanguage: gu.Ptr("en"), Gender: user.Gender_GENDER_DIVERSE.Enum(), }, Email: &user.SetHumanEmail{}, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Organisation.ID, }, }, }, { name: "return verification code", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Profile: &user.SetHumanProfile{ FirstName: "Donald", LastName: "Duck", NickName: gu.Ptr("Dukkie"), DisplayName: gu.Ptr("Donald Duck"), PreferredLanguage: gu.Ptr("en"), Gender: user.Gender_GENDER_DIVERSE.Enum(), }, Email: &user.SetHumanEmail{ Verification: &user.SetHumanEmail_ReturnCode{ ReturnCode: &user.ReturnEmailVerificationCode{}, }, }, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Organisation.ID, }, EmailCode: gu.Ptr("something"), }, }, { name: "custom template", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Profile: &user.SetHumanProfile{ FirstName: "Donald", LastName: "Duck", NickName: gu.Ptr("Dukkie"), DisplayName: gu.Ptr("Donald Duck"), PreferredLanguage: gu.Ptr("en"), Gender: user.Gender_GENDER_DIVERSE.Enum(), }, Email: &user.SetHumanEmail{ Verification: &user.SetHumanEmail_SendCode{ SendCode: &user.SendEmailVerificationCode{ UrlTemplate: gu.Ptr("https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}"), }, }, }, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, want: &user.AddHumanUserResponse{ Details: &object.Details{ ChangeDate: timestamppb.Now(), ResourceOwner: Tester.Organisation.ID, }, }, }, { name: "custom template error", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Profile: &user.SetHumanProfile{ FirstName: "Donald", LastName: "Duck", NickName: gu.Ptr("Dukkie"), DisplayName: gu.Ptr("Donald Duck"), PreferredLanguage: gu.Ptr("en"), Gender: user.Gender_GENDER_DIVERSE.Enum(), }, Email: &user.SetHumanEmail{ Verification: &user.SetHumanEmail_SendCode{ SendCode: &user.SendEmailVerificationCode{ UrlTemplate: gu.Ptr("{{"), }, }, }, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, wantErr: true, }, { name: "missing REQUIRED profile", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Email: &user.SetHumanEmail{ Verification: &user.SetHumanEmail_ReturnCode{ ReturnCode: &user.ReturnEmailVerificationCode{}, }, }, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, wantErr: true, }, { name: "missing REQUIRED email", args: args{ CTX, &user.AddHumanUserRequest{ Organisation: &object.Organisation{ Org: &object.Organisation_OrgId{ OrgId: Tester.Organisation.ID, }, }, Profile: &user.SetHumanProfile{ FirstName: "Donald", LastName: "Duck", NickName: gu.Ptr("Dukkie"), DisplayName: gu.Ptr("Donald Duck"), PreferredLanguage: gu.Ptr("en"), Gender: user.Gender_GENDER_DIVERSE.Enum(), }, Metadata: []*user.SetMetadataEntry{ { Key: "somekey", Value: []byte("somevalue"), }, }, PasswordType: &user.AddHumanUserRequest_Password{ Password: &user.Password{ Password: "DifficultPW666!", ChangeRequired: true, }, }, }, }, wantErr: true, }, } for i, tt := range tests { t.Run(tt.name, func(t *testing.T) { userID := fmt.Sprint(time.Now().UnixNano() + int64(i)) tt.args.req.UserId = &userID if email := tt.args.req.GetEmail(); email != nil { email.Email = fmt.Sprintf("%s@me.now", userID) } if tt.want != nil { tt.want.UserId = userID } got, err := Client.AddHumanUser(tt.args.ctx, tt.args.req) if tt.wantErr { require.Error(t, err) } else { require.NoError(t, err) } assert.Equal(t, tt.want.GetUserId(), got.GetUserId()) if tt.want.GetEmailCode() != "" { assert.NotEmpty(t, got.GetEmailCode()) } integration.AssertDetails(t, tt.want, got) }) } }