refactor: make es mocks reusable

This commit is contained in:
Elio Bischof 2023-09-25 15:08:12 +02:00
parent 0b5cfbb653
commit 434ce12a6a
No known key found for this signature in database
GPG Key ID: 7B383FDE4DDBF1BD
6 changed files with 113 additions and 60 deletions

View File

@ -0,0 +1,44 @@
package command
import (
"github.com/zitadel/zitadel/internal/eventstore/mock"
)
// TODO: Delete this file and reference the mock package directly in the tests
var (
eventstoreExpect = mock.EventstoreExpect
expectEventstore = mock.ExpectEventstore
expectPush = mock.ExpectPush
expectPushFailed = mock.ExpectPushFailed
expectRandomPush = mock.ExpectRandomPush
eventFromEventPusherWithInstanceID = mock.EventFromEventPusherWithInstanceID
eventFromEventPusherWithCreationDateNow = mock.EventFromEventPusherWithCreationDateNow
eventPusherToEvents = mock.EventPusherToEvents
expectFilter = mock.ExpectFilter
expectFilterError = mock.ExpectFilterError
expectFilterOrgDomainNotFound = mock.ExpectFilterOrgDomainNotFound
expectFilterOrgMemberNotFound = mock.ExpectFilterOrgMemberNotFound
expectRandomPushFailed = mock.ExpectRandomPushFailed
newMockPermissionCheckAllowed = mock.NewMockPermissionCheckAllowed
newMockPermissionCheckNotAllowed = mock.NewMockPermissionCheckNotAllowed
uniqueConstraintsFromEventConstraint = mock.UniqueConstraintsFromEventConstraint
uniqueConstraintsFromEventConstraintWithInstanceID = mock.UniqueConstraintsFromEventConstraintWithInstanceID
eventFromEventPusher = mock.EventFromEventPusher
GetMockSecretGenerator = mock.GetMockSecretGenerator
mockPasswordHasher = mock.MockPasswordHasher
)
type mockInstance struct {
mock.MockInstance
}
type expect mock.Expecter
func toExpecters(expects ...expect) []mock.Expecter {
expecters := make([]mock.Expecter, len(expects))
for i := range expects {
expecters[i] = mock.Expecter(expects[i])
}
return expecters
}

View File

@ -225,7 +225,7 @@ func TestCommands_CreateSession(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &Commands{ c := &Commands{
eventstore: eventstoreExpect(t, tt.expect...), eventstore: eventstoreExpect(t, toExpecters(tt.expect...)...),
idGenerator: tt.fields.idGenerator, idGenerator: tt.fields.idGenerator,
sessionTokenCreator: tt.fields.tokenCreator, sessionTokenCreator: tt.fields.tokenCreator,
} }

View File

@ -780,7 +780,7 @@ func TestCommandSide_ChangePassword(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
r := &Commands{ r := &Commands{
eventstore: eventstoreExpect(t, tt.expect...), eventstore: eventstoreExpect(t, toExpecters(tt.expect...)...),
userPasswordHasher: tt.fields.userPasswordHasher, userPasswordHasher: tt.fields.userPasswordHasher,
} }
got, err := r.ChangePassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.oldPassword, tt.args.newPassword, tt.args.agentID) got, err := r.ChangePassword(tt.args.ctx, tt.args.resourceOwner, tt.args.userID, tt.args.oldPassword, tt.args.newPassword, tt.args.agentID)

View File

@ -438,7 +438,7 @@ func TestCommands_pushUserPasskey(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &Commands{ c := &Commands{
eventstore: eventstoreExpect(t, prep...), eventstore: eventstoreExpect(t, toExpecters(prep...)...),
webauthnConfig: webauthnConfig, webauthnConfig: webauthnConfig,
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"),
} }

View File

@ -195,7 +195,7 @@ func TestCommands_pushUserU2F(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
c := &Commands{ c := &Commands{
eventstore: eventstoreExpect(t, prep...), eventstore: eventstoreExpect(t, toExpecters(prep...)...),
webauthnConfig: webauthnConfig, webauthnConfig: webauthnConfig,
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"), idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "123"),
} }

View File

@ -1,4 +1,4 @@
package command package mock
import ( import (
"context" "context"
@ -32,12 +32,21 @@ import (
"github.com/zitadel/zitadel/internal/repository/usergrant" "github.com/zitadel/zitadel/internal/repository/usergrant"
) )
type expect func(mockRepository *mock.MockRepository) type Expecter interface {
Expect(mockRepository *mock.MockRepository)
}
func eventstoreExpect(t *testing.T, expects ...expect) *eventstore.Eventstore { // ExpectFunc implements the Expecter interface
type ExpectFunc func(mockRepository *mock.MockRepository)
func (e ExpectFunc) Expect(mockRepository *mock.MockRepository) {
e(mockRepository)
}
func EventstoreExpect(t *testing.T, expects ...Expecter) *eventstore.Eventstore {
m := mock.NewRepo(t) m := mock.NewRepo(t)
for _, e := range expects { for _, e := range expects {
e(m) e.Expect(m)
} }
es := eventstore.NewEventstore(eventstore.TestConfig(m)) es := eventstore.NewEventstore(eventstore.TestConfig(m))
iam_repo.RegisterEventMappers(es) iam_repo.RegisterEventMappers(es)
@ -55,13 +64,13 @@ func eventstoreExpect(t *testing.T, expects ...expect) *eventstore.Eventstore {
return es return es
} }
func expectEventstore(expects ...expect) func(*testing.T) *eventstore.Eventstore { func ExpectEventstore(expects ...Expecter) func(*testing.T) *eventstore.Eventstore {
return func(t *testing.T) *eventstore.Eventstore { return func(t *testing.T) *eventstore.Eventstore {
return eventstoreExpect(t, expects...) return EventstoreExpect(t, expects...)
} }
} }
func eventPusherToEvents(eventsPushes ...eventstore.Command) []*repository.Event { func EventPusherToEvents(eventsPushes ...eventstore.Command) []*repository.Event {
events := make([]*repository.Event, len(eventsPushes)) events := make([]*repository.Event, len(eventsPushes))
for i, event := range eventsPushes { for i, event := range eventsPushes {
data, err := eventstore.EventData(event) data, err := eventstore.EventData(event)
@ -82,7 +91,7 @@ func eventPusherToEvents(eventsPushes ...eventstore.Command) []*repository.Event
return events return events
} }
type testRepo struct { type TestRepo struct {
events []*repository.Event events []*repository.Event
uniqueConstraints []*repository.UniqueConstraint uniqueConstraints []*repository.UniqueConstraint
sequence uint64 sequence uint64
@ -90,17 +99,17 @@ type testRepo struct {
t *testing.T t *testing.T
} }
func (repo *testRepo) Health(ctx context.Context) error { func (repo *TestRepo) Health(ctx context.Context) error {
return nil return nil
} }
func (repo *testRepo) Push(ctx context.Context, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) error { func (repo *TestRepo) Push(ctx context.Context, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) error {
repo.events = append(repo.events, events...) repo.events = append(repo.events, events...)
repo.uniqueConstraints = append(repo.uniqueConstraints, uniqueConstraints...) repo.uniqueConstraints = append(repo.uniqueConstraints, uniqueConstraints...)
return nil return nil
} }
func (repo *testRepo) Filter(ctx context.Context, searchQuery *repository.SearchQuery) ([]*repository.Event, error) { func (repo *TestRepo) Filter(ctx context.Context, searchQuery *repository.SearchQuery) ([]*repository.Event, error) {
events := make([]*repository.Event, 0, len(repo.events)) events := make([]*repository.Event, 0, len(repo.events))
for _, event := range repo.events { for _, event := range repo.events {
for _, filter := range searchQuery.Filters { for _, filter := range searchQuery.Filters {
@ -121,61 +130,61 @@ func filterAggregateType(aggregateType string) {
} }
func (repo *testRepo) LatestSequence(ctx context.Context, queryFactory *repository.SearchQuery) (uint64, error) { func (repo *TestRepo) LatestSequence(ctx context.Context, queryFactory *repository.SearchQuery) (uint64, error) {
if repo.err != nil { if repo.err != nil {
return 0, repo.err return 0, repo.err
} }
return repo.sequence, nil return repo.sequence, nil
} }
func expectPush(events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { func ExpectPush(events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectPush(events, uniqueConstraints...) m.ExpectPush(events, uniqueConstraints...)
} })
} }
func expectPushFailed(err error, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { func ExpectPushFailed(err error, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectPushFailed(err, events, uniqueConstraints...) m.ExpectPushFailed(err, events, uniqueConstraints...)
} })
} }
func expectRandomPush(events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { func ExpectRandomPush(events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectRandomPush(events, uniqueConstraints...) m.ExpectRandomPush(events, uniqueConstraints...)
} })
} }
func expectRandomPushFailed(err error, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) expect { func ExpectRandomPushFailed(err error, events []*repository.Event, uniqueConstraints ...*repository.UniqueConstraint) Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectRandomPushFailed(err, events, uniqueConstraints...) m.ExpectRandomPushFailed(err, events, uniqueConstraints...)
} })
} }
func expectFilter(events ...*repository.Event) expect { func ExpectFilter(events ...*repository.Event) Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectFilterEvents(events...) m.ExpectFilterEvents(events...)
})
} }
} func ExpectFilterError(err error) Expecter {
func expectFilterError(err error) expect { return ExpectFunc(func(m *mock.MockRepository) {
return func(m *mock.MockRepository) {
m.ExpectFilterEventsError(err) m.ExpectFilterEventsError(err)
} })
} }
func expectFilterOrgDomainNotFound() expect { func ExpectFilterOrgDomainNotFound() Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectFilterNoEventsNoError() m.ExpectFilterNoEventsNoError()
} })
} }
func expectFilterOrgMemberNotFound() expect { func ExpectFilterOrgMemberNotFound() Expecter {
return func(m *mock.MockRepository) { return ExpectFunc(func(m *mock.MockRepository) {
m.ExpectFilterNoEventsNoError() m.ExpectFilterNoEventsNoError()
} })
} }
func eventFromEventPusher(event eventstore.Command) *repository.Event { func EventFromEventPusher(event eventstore.Command) *repository.Event {
data, _ := eventstore.EventData(event) data, _ := eventstore.EventData(event)
return &repository.Event{ return &repository.Event{
ID: "", ID: "",
@ -194,7 +203,7 @@ func eventFromEventPusher(event eventstore.Command) *repository.Event {
} }
} }
func eventFromEventPusherWithInstanceID(instanceID string, event eventstore.Command) *repository.Event { func EventFromEventPusherWithInstanceID(instanceID string, event eventstore.Command) *repository.Event {
data, _ := eventstore.EventData(event) data, _ := eventstore.EventData(event)
return &repository.Event{ return &repository.Event{
ID: "", ID: "",
@ -214,13 +223,13 @@ func eventFromEventPusherWithInstanceID(instanceID string, event eventstore.Comm
} }
} }
func eventFromEventPusherWithCreationDateNow(event eventstore.Command) *repository.Event { func EventFromEventPusherWithCreationDateNow(event eventstore.Command) *repository.Event {
e := eventFromEventPusher(event) e := EventFromEventPusher(event)
e.CreationDate = time.Now() e.CreationDate = time.Now()
return e return e
} }
func uniqueConstraintsFromEventConstraint(constraint *eventstore.EventUniqueConstraint) *repository.UniqueConstraint { func UniqueConstraintsFromEventConstraint(constraint *eventstore.EventUniqueConstraint) *repository.UniqueConstraint {
return &repository.UniqueConstraint{ return &repository.UniqueConstraint{
UniqueType: constraint.UniqueType, UniqueType: constraint.UniqueType,
UniqueField: constraint.UniqueField, UniqueField: constraint.UniqueField,
@ -228,7 +237,7 @@ func uniqueConstraintsFromEventConstraint(constraint *eventstore.EventUniqueCons
Action: repository.UniqueConstraintAction(constraint.Action)} Action: repository.UniqueConstraintAction(constraint.Action)}
} }
func uniqueConstraintsFromEventConstraintWithInstanceID(instanceID string, constraint *eventstore.EventUniqueConstraint) *repository.UniqueConstraint { func UniqueConstraintsFromEventConstraintWithInstanceID(instanceID string, constraint *eventstore.EventUniqueConstraint) *repository.UniqueConstraint {
return &repository.UniqueConstraint{ return &repository.UniqueConstraint{
InstanceID: instanceID, InstanceID: instanceID,
UniqueType: constraint.UniqueType, UniqueType: constraint.UniqueType,
@ -249,51 +258,51 @@ func GetMockSecretGenerator(t *testing.T) crypto.Generator {
return generator return generator
} }
type mockInstance struct{} type MockInstance struct{}
func (m *mockInstance) InstanceID() string { func (m *MockInstance) InstanceID() string {
return "INSTANCE" return "INSTANCE"
} }
func (m *mockInstance) ProjectID() string { func (m *MockInstance) ProjectID() string {
return "projectID" return "projectID"
} }
func (m *mockInstance) ConsoleClientID() string { func (m *MockInstance) ConsoleClientID() string {
return "consoleID" return "consoleID"
} }
func (m *mockInstance) ConsoleApplicationID() string { func (m *MockInstance) ConsoleApplicationID() string {
return "consoleApplicationID" return "consoleApplicationID"
} }
func (m *mockInstance) DefaultLanguage() language.Tag { func (m *MockInstance) DefaultLanguage() language.Tag {
return language.English return language.English
} }
func (m *mockInstance) DefaultOrganisationID() string { func (m *MockInstance) DefaultOrganisationID() string {
return "defaultOrgID" return "defaultOrgID"
} }
func (m *mockInstance) RequestedDomain() string { func (m *MockInstance) RequestedDomain() string {
return "zitadel.cloud" return "zitadel.cloud"
} }
func (m *mockInstance) RequestedHost() string { func (m *MockInstance) RequestedHost() string {
return "zitadel.cloud:443" return "zitadel.cloud:443"
} }
func (m *mockInstance) SecurityPolicyAllowedOrigins() []string { func (m *MockInstance) SecurityPolicyAllowedOrigins() []string {
return nil return nil
} }
func newMockPermissionCheckAllowed() domain.PermissionCheck { func NewMockPermissionCheckAllowed() domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) { return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return nil return nil
} }
} }
func newMockPermissionCheckNotAllowed() domain.PermissionCheck { func NewMockPermissionCheckNotAllowed() domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) { return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
return errors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied") return errors.ThrowPermissionDenied(nil, "AUTHZ-HKJD33", "Errors.PermissionDenied")
} }
@ -321,13 +330,13 @@ func (h plainHasher) Verify(encoded, password string) (verifier.Result, error) {
return verifier.OK, nil return verifier.OK, nil
} }
// mockPasswordHasher creates a swapper for plain (cleartext) password used in tests. // MockPasswordHasher creates a swapper for plain (cleartext) password used in tests.
// x can be set to arbitrary info which triggers updates when different from the // x can be set to arbitrary info which triggers updates when different from the
// setting in the encoded hashes. (normally cost parameters) // setting in the encoded hashes. (normally cost parameters)
// //
// With `x` set to "foo", the following encoded string would be produced by Hash: // With `x` set to "foo", the following encoded string would be produced by Hash:
// $plain$foo$password // $plain$foo$password
func mockPasswordHasher(x string) *crypto.PasswordHasher { func MockPasswordHasher(x string) *crypto.PasswordHasher {
return &crypto.PasswordHasher{ return &crypto.PasswordHasher{
Swapper: passwap.NewSwapper(plainHasher{x: x}), Swapper: passwap.NewSwapper(plainHasher{x: x}),
Prefixes: []string{"$plain$"}, Prefixes: []string{"$plain$"},