Skip to content

Commit

Permalink
AddHumanUser tests
Browse files Browse the repository at this point in the history
  • Loading branch information
muhlemmer committed Apr 28, 2023
1 parent 11ab645 commit 4b7f5ae
Show file tree
Hide file tree
Showing 8 changed files with 463 additions and 5 deletions.
2 changes: 1 addition & 1 deletion build/zitadel/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ RUN rm -r cockroach-${COCKROACH_VERSION}.linux-amd64

# Migrations for cockroach-secure
RUN go install github.com/rakyll/statik \
&& go test -race -v -coverprofile=profile.cov -coverpkg=./... $(go list ./... | grep -v /operator/)
&& go test -race -v -coverprofile=profile.cov $(go list ./... | grep -v /operator/)

#######################
## Go test results
Expand Down
2 changes: 1 addition & 1 deletion internal/api/grpc/admin/information_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (

func TestMain(m *testing.M) {
os.Exit(func() int {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
ctx, _, cancel := integration.Contexts(time.Minute)
defer cancel()
Tester = integration.NewTester(ctx)
defer Tester.Done()
Expand Down
317 changes: 317 additions & 0 deletions internal/api/grpc/user/v2/user_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
//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: "211137963315232910",
},
},
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: "211137963315232910",
},
},
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: "211137963315232910",
},
},
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: "211137963315232910",
},
},
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: "211137963315232910",
},
},
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: "211137963315232910",
},
},
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)
})
}
}
25 changes: 25 additions & 0 deletions internal/integration/assert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package integration

import (
"testing"
"time"

"github.com/stretchr/testify/assert"

object "github.com/zitadel/zitadel/pkg/grpc/object/v2alpha"
)

type DetailsMsg interface {
GetDetails() *object.Details
}

func AssertDetails[D DetailsMsg](t testing.TB, exptected, actual D) {
wantDetails, gotDetails := exptected.GetDetails(), actual.GetDetails()

if wantDetails != nil {
assert.NotZero(t, gotDetails.GetSequence())
}
wantCD, gotCD := wantDetails.GetChangeDate().AsTime(), gotDetails.GetChangeDate().AsTime()
assert.WithinRange(t, gotCD, wantCD, wantCD.Add(time.Minute))
assert.Equal(t, wantDetails.GetResourceOwner(), gotDetails.GetResourceOwner())
}
1 change: 0 additions & 1 deletion internal/integration/config/zitadel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,3 @@ Projections:
DefaultInstance:
LoginPolicy:
MfaInitSkipLifetime: "0"

0 comments on commit 4b7f5ae

Please sign in to comment.