diff --git a/go.mod b/go.mod index a7f44ab4f3..8445a86055 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/muesli/gamut v0.2.0 github.com/nicksnyder/go-i18n/v2 v2.1.2 - github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 // indirect + github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 github.com/pkg/errors v0.9.1 github.com/pquerna/otp v1.3.0 github.com/rakyll/statik v0.1.7 @@ -81,7 +81,7 @@ require ( golang.org/x/text v0.3.7 golang.org/x/tools v0.1.7 google.golang.org/api v0.60.0 - google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca // indirect + google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca google.golang.org/grpc v1.42.0 google.golang.org/protobuf v1.27.1 gopkg.in/square/go-jose.v2 v2.6.0 diff --git a/internal/query/action_flow.go b/internal/query/action_flow.go index 9961697b44..7409a1c185 100644 --- a/internal/query/action_flow.go +++ b/internal/query/action_flow.go @@ -5,7 +5,6 @@ import ( "database/sql" "time" - "github.com/Masterminds/squirrel" sq "github.com/Masterminds/squirrel" "github.com/caos/zitadel/internal/domain" @@ -89,13 +88,13 @@ func (q *Queries) GetActionsByFlowAndTriggerType(ctx context.Context, flowType d } func (q *Queries) GetFlowTypesOfActionID(ctx context.Context, actionID string) ([]domain.FlowType, error) { - stmt, args, err := squirrel.StatementBuilder. + stmt, args, err := sq.StatementBuilder. Select(FlowsTriggersColumnFlowType.identifier()). From(flowsTriggersTable.identifier()). Where(sq.Eq{ FlowsTriggersColumnActionID.identifier(): actionID, }). - PlaceholderFormat(squirrel.Dollar). + PlaceholderFormat(sq.Dollar). ToSql() if err != nil { return nil, errors.ThrowInvalidArgument(err, "QUERY-Dh311", "Errors.Query.InvalidRequest") diff --git a/internal/query/org_test.go b/internal/query/org_test.go new file mode 100644 index 0000000000..e208e9a48a --- /dev/null +++ b/internal/query/org_test.go @@ -0,0 +1,367 @@ +package query + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "regexp" + "testing" + + "github.com/caos/zitadel/internal/domain" + errs "github.com/caos/zitadel/internal/errors" +) + +func Test_OrgPrepares(t *testing.T) { + type want struct { + sqlExpectations sqlExpectation + err checkErr + } + tests := []struct { + name string + prepare interface{} + want want + object interface{} + }{ + { + name: "prepareOrgsQuery no result", + prepare: prepareOrgsQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain,`+ + ` COUNT(*) OVER ()`+ + ` FROM zitadel.projections.orgs`), + nil, + nil, + ), + }, + object: &Orgs{Orgs: []*Org{}}, + }, + { + name: "prepareOrgsQuery one result", + prepare: prepareOrgsQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain,`+ + ` COUNT(*) OVER ()`+ + ` FROM zitadel.projections.orgs`), + []string{ + "id", + "creation_date", + "change_date", + "resource_owner", + "org_state", + "sequence", + "name", + "primary_domain", + "count", + }, + [][]driver.Value{ + { + "id", + testNow, + testNow, + "ro", + domain.OrgStateActive, + uint64(20211109), + "org-name", + "zitadel.ch", + }, + }, + ), + }, + object: &Orgs{ + SearchResponse: SearchResponse{ + Count: 1, + }, + Orgs: []*Org{ + { + ID: "id", + CreationDate: testNow, + ChangeDate: testNow, + ResourceOwner: "ro", + State: domain.OrgStateActive, + Sequence: 20211109, + Name: "org-name", + Domain: "zitadel.ch", + }, + }, + }, + }, + { + name: "prepareOrgsQuery multiple result", + prepare: prepareOrgsQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain,`+ + ` COUNT(*) OVER ()`+ + ` FROM zitadel.projections.orgs`), + []string{ + "id", + "creation_date", + "change_date", + "resource_owner", + "org_state", + "sequence", + "name", + "primary_domain", + "count", + }, + [][]driver.Value{ + { + "id-1", + testNow, + testNow, + "ro", + domain.OrgStateActive, + uint64(20211108), + "org-name-1", + "zitadel.ch", + }, + { + "id-2", + testNow, + testNow, + "ro", + domain.OrgStateActive, + uint64(20211108), + "org-name-2", + "caos.ch", + }, + }, + ), + }, + object: &Orgs{ + SearchResponse: SearchResponse{ + Count: 2, + }, + Orgs: []*Org{ + { + ID: "id-1", + CreationDate: testNow, + ChangeDate: testNow, + ResourceOwner: "ro", + State: domain.OrgStateActive, + Sequence: 20211108, + Name: "org-name-1", + Domain: "zitadel.ch", + }, + { + ID: "id-2", + CreationDate: testNow, + ChangeDate: testNow, + ResourceOwner: "ro", + State: domain.OrgStateActive, + Sequence: 20211108, + Name: "org-name-2", + Domain: "caos.ch", + }, + }, + }, + }, + { + name: "prepareOrgsQuery sql err", + prepare: prepareOrgsQuery, + want: want{ + sqlExpectations: mockQueryErr( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain,`+ + ` COUNT(*) OVER ()`+ + ` FROM zitadel.projections.orgs`), + sql.ErrConnDone, + ), + err: func(err error) (error, bool) { + if !errors.Is(err, sql.ErrConnDone) { + return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false + } + return nil, true + }, + }, + object: nil, + }, + { + name: "prepareOrgQuery no result", + prepare: prepareOrgQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain`+ + ` FROM zitadel.projections.orgs`), + nil, + nil, + ), + err: func(err error) (error, bool) { + if !errs.IsNotFound(err) { + return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false + } + return nil, true + }, + }, + object: (*Org)(nil), + }, + { + name: "prepareOrgQuery found", + prepare: prepareOrgQuery, + want: want{ + sqlExpectations: mockQuery( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain`+ + ` FROM zitadel.projections.orgs`), + []string{ + "id", + "creation_date", + "change_date", + "resource_owner", + "org_state", + "sequence", + "name", + "primary_domain", + }, + []driver.Value{ + "id", + testNow, + testNow, + "ro", + domain.OrgStateActive, + uint64(20211108), + "org-name", + "zitadel.ch", + }, + ), + }, + object: &Org{ + ID: "id", + CreationDate: testNow, + ChangeDate: testNow, + ResourceOwner: "ro", + State: domain.OrgStateActive, + Sequence: 20211108, + Name: "org-name", + Domain: "zitadel.ch", + }, + }, + { + name: "prepareOrgQuery sql err", + prepare: prepareOrgQuery, + want: want{ + sqlExpectations: mockQueryErr( + regexp.QuoteMeta(`SELECT zitadel.projections.orgs.id,`+ + ` zitadel.projections.orgs.creation_date,`+ + ` zitadel.projections.orgs.change_date,`+ + ` zitadel.projections.orgs.resource_owner,`+ + ` zitadel.projections.orgs.org_state,`+ + ` zitadel.projections.orgs.sequence,`+ + ` zitadel.projections.orgs.name,`+ + ` zitadel.projections.orgs.primary_domain`+ + ` FROM zitadel.projections.orgs`), + sql.ErrConnDone, + ), + err: func(err error) (error, bool) { + if !errors.Is(err, sql.ErrConnDone) { + return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false + } + return nil, true + }, + }, + object: nil, + }, + { + name: "prepareOrgUniqueQuery no result", + prepare: prepareOrgUniqueQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ + ` FROM zitadel.projections.orgs`), + nil, + nil, + ), + err: func(err error) (error, bool) { + if !errs.IsInternal(err) { + return fmt.Errorf("err should be zitadel.Internal got: %w", err), false + } + return nil, true + }, + }, + object: false, + }, + { + name: "prepareOrgUniqueQuery found", + prepare: prepareOrgUniqueQuery, + want: want{ + sqlExpectations: mockQuery( + regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ + ` FROM zitadel.projections.orgs`), + []string{ + "count", + }, + []driver.Value{ + 1, + }, + ), + }, + object: true, + }, + { + name: "prepareOrgUniqueQuery sql err", + prepare: prepareOrgUniqueQuery, + want: want{ + sqlExpectations: mockQueryErr( + regexp.QuoteMeta(`SELECT COUNT(*) = 0`+ + ` FROM zitadel.projections.orgs`), + sql.ErrConnDone, + ), + err: func(err error) (error, bool) { + if !errors.Is(err, sql.ErrConnDone) { + return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false + } + return nil, true + }, + }, + object: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err) + }) + } +} diff --git a/internal/query/prepare_test.go b/internal/query/prepare_test.go index fa97424a49..bcb0bf6e09 100644 --- a/internal/query/prepare_test.go +++ b/internal/query/prepare_test.go @@ -9,12 +9,17 @@ import ( "log" "reflect" "testing" + "time" "github.com/DATA-DOG/go-sqlmock" sq "github.com/Masterminds/squirrel" "github.com/nsf/jsondiff" ) +var ( + testNow = time.Now() +) + //assertPrepare checks if the prepare func executes the correct sql query and returns the correct object //prepareFunc must be of type // func() (sq.SelectBuilder, func(*sql.Rows) (*struct, error)) diff --git a/internal/query/project_test.go b/internal/query/project_test.go index 00a86148a6..94810c983f 100644 --- a/internal/query/project_test.go +++ b/internal/query/project_test.go @@ -7,17 +7,12 @@ import ( "fmt" "regexp" "testing" - "time" "github.com/caos/zitadel/internal/domain" errs "github.com/caos/zitadel/internal/errors" ) -var ( - now = time.Now() -) - -func Test_prepareProjectsQuery(t *testing.T) { +func Test_ProjectPrepares(t *testing.T) { type want struct { sqlExpectations sqlExpectation err checkErr @@ -87,8 +82,8 @@ func Test_prepareProjectsQuery(t *testing.T) { [][]driver.Value{ { "id", - now, - now, + testNow, + testNow, "ro", domain.ProjectStateActive, uint64(20211108), @@ -108,8 +103,8 @@ func Test_prepareProjectsQuery(t *testing.T) { Projects: []*Project{ { ID: "id", - CreationDate: now, - ChangeDate: now, + CreationDate: testNow, + ChangeDate: testNow, ResourceOwner: "ro", State: domain.ProjectStateActive, Sequence: 20211108, @@ -157,8 +152,8 @@ func Test_prepareProjectsQuery(t *testing.T) { [][]driver.Value{ { "id-1", - now, - now, + testNow, + testNow, "ro", domain.ProjectStateActive, uint64(20211108), @@ -170,8 +165,8 @@ func Test_prepareProjectsQuery(t *testing.T) { }, { "id-2", - now, - now, + testNow, + testNow, "ro", domain.ProjectStateActive, uint64(20211108), @@ -191,8 +186,8 @@ func Test_prepareProjectsQuery(t *testing.T) { Projects: []*Project{ { ID: "id-1", - CreationDate: now, - ChangeDate: now, + CreationDate: testNow, + ChangeDate: testNow, ResourceOwner: "ro", State: domain.ProjectStateActive, Sequence: 20211108, @@ -204,8 +199,8 @@ func Test_prepareProjectsQuery(t *testing.T) { }, { ID: "id-2", - CreationDate: now, - ChangeDate: now, + CreationDate: testNow, + ChangeDate: testNow, ResourceOwner: "ro", State: domain.ProjectStateActive, Sequence: 20211108, @@ -308,8 +303,8 @@ func Test_prepareProjectsQuery(t *testing.T) { }, []driver.Value{ "id", - now, - now, + testNow, + testNow, "ro", domain.ProjectStateActive, uint64(20211108), @@ -323,8 +318,8 @@ func Test_prepareProjectsQuery(t *testing.T) { }, object: &Project{ ID: "id", - CreationDate: now, - ChangeDate: now, + CreationDate: testNow, + ChangeDate: testNow, ResourceOwner: "ro", State: domain.ProjectStateActive, Sequence: 20211108,