2022-01-20 14:40:25 +00:00
package query
import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"regexp"
"testing"
2022-03-23 08:02:39 +00:00
sq "github.com/Masterminds/squirrel"
2022-01-20 14:40:25 +00:00
"golang.org/x/text/language"
2022-08-31 07:52:43 +00:00
"github.com/zitadel/zitadel/internal/database"
2022-04-26 23:01:45 +00:00
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
2022-01-20 14:40:25 +00:00
)
var (
2022-08-31 07:52:43 +00:00
userQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3.state, ` +
` projections.users3.type, ` +
` projections.users3.username, ` +
2022-02-02 07:21:54 +00:00
` login_names.loginnames, ` +
2022-01-20 14:40:25 +00:00
` preferred_login_name.login_name, ` +
2022-08-31 07:52:43 +00:00
` projections.users3_humans.user_id, ` +
` projections.users3_humans.first_name, ` +
` projections.users3_humans.last_name, ` +
` projections.users3_humans.nick_name, ` +
` projections.users3_humans.display_name, ` +
` projections.users3_humans.preferred_language, ` +
` projections.users3_humans.gender, ` +
` projections.users3_humans.avatar_key, ` +
` projections.users3_humans.email, ` +
` projections.users3_humans.is_email_verified, ` +
` projections.users3_humans.phone, ` +
` projections.users3_humans.is_phone_verified, ` +
` projections.users3_machines.user_id, ` +
` projections.users3_machines.name, ` +
` projections.users3_machines.description ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id ` +
` LEFT JOIN projections.users3_machines ON projections.users3.id = projections.users3_machines.user_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name)::TEXT[] AS loginnames ` +
` FROM projections.login_names AS login_names ` +
2022-03-23 08:02:39 +00:00
` WHERE login_names.instance_id = $1 ` +
2022-08-31 07:52:43 +00:00
` GROUP BY login_names.user_id) AS login_names ` +
` ON login_names.user_id = projections.users3.id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names AS preferred_login_name WHERE preferred_login_name.instance_id = $2 AND preferred_login_name.is_primary = $3) AS preferred_login_name ` +
` ON preferred_login_name.user_id = projections.users3.id `
2022-01-20 14:40:25 +00:00
userCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"state" ,
"type" ,
"username" ,
2022-02-02 07:21:54 +00:00
"loginnames" ,
2022-01-20 14:40:25 +00:00
"login_name" ,
//human
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
"email" ,
"is_email_verified" ,
"phone" ,
"is_phone_verified" ,
//machine
"user_id" ,
"name" ,
"description" ,
}
2022-08-31 07:52:43 +00:00
profileQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3_humans.user_id, ` +
` projections.users3_humans.first_name, ` +
` projections.users3_humans.last_name, ` +
` projections.users3_humans.nick_name, ` +
` projections.users3_humans.display_name, ` +
` projections.users3_humans.preferred_language, ` +
` projections.users3_humans.gender, ` +
` projections.users3_humans.avatar_key ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id `
2022-01-20 14:40:25 +00:00
profileCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
}
2022-08-31 07:52:43 +00:00
emailQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3_humans.user_id, ` +
` projections.users3_humans.email, ` +
` projections.users3_humans.is_email_verified ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id `
2022-01-20 14:40:25 +00:00
emailCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"user_id" ,
"email" ,
"is_email_verified" ,
}
2022-08-31 07:52:43 +00:00
phoneQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3_humans.user_id, ` +
` projections.users3_humans.phone, ` +
` projections.users3_humans.is_phone_verified ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id `
2022-01-20 14:40:25 +00:00
phoneCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"user_id" ,
"phone" ,
"is_phone_verified" ,
}
2022-08-31 07:52:43 +00:00
userUniqueQuery = ` SELECT projections.users3.id, ` +
` projections.users3.state, ` +
` projections.users3.username, ` +
` projections.users3_humans.user_id, ` +
` projections.users3_humans.email, ` +
` projections.users3_humans.is_email_verified ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id `
2022-01-20 14:40:25 +00:00
userUniqueCols = [ ] string {
"id" ,
"state" ,
"username" ,
"user_id" ,
"email" ,
"is_email_verified" ,
}
2022-08-31 07:52:43 +00:00
notifyUserQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3.state, ` +
` projections.users3.type, ` +
` projections.users3.username, ` +
2022-07-06 12:09:49 +00:00
` login_names.loginnames, ` +
` preferred_login_name.login_name, ` +
2022-08-31 07:52:43 +00:00
` projections.users3_humans.user_id, ` +
` projections.users3_humans.first_name, ` +
` projections.users3_humans.last_name, ` +
` projections.users3_humans.nick_name, ` +
` projections.users3_humans.display_name, ` +
` projections.users3_humans.preferred_language, ` +
` projections.users3_humans.gender, ` +
` projections.users3_humans.avatar_key, ` +
` projections.users3_notifications.user_id, ` +
` projections.users3_notifications.last_email, ` +
` projections.users3_notifications.verified_email, ` +
` projections.users3_notifications.last_phone, ` +
` projections.users3_notifications.verified_phone, ` +
` projections.users3_notifications.password_set ` +
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id ` +
` LEFT JOIN projections.users3_notifications ON projections.users3.id = projections.users3_notifications.user_id ` +
2022-07-06 12:09:49 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) AS loginnames ` +
` FROM projections.login_names AS login_names ` +
2022-07-06 12:09:49 +00:00
` WHERE login_names.instance_id = $1 ` +
2022-08-31 07:52:43 +00:00
` GROUP BY login_names.user_id) AS login_names ` +
` ON login_names.user_id = projections.users3.id ` +
2022-07-06 12:09:49 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names AS preferred_login_name WHERE preferred_login_name.instance_id = $2 AND preferred_login_name.is_primary = $3) AS preferred_login_name ` +
` ON preferred_login_name.user_id = projections.users3.id `
2022-07-06 12:09:49 +00:00
notifyUserCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"state" ,
"type" ,
"username" ,
"loginnames" ,
"login_name" ,
//human
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
//machine
"user_id" ,
"last_email" ,
"verified_email" ,
"last_phone" ,
"verified_phone" ,
"password_set" ,
}
2022-08-31 07:52:43 +00:00
usersQuery = ` SELECT projections.users3.id, ` +
` projections.users3.creation_date, ` +
` projections.users3.change_date, ` +
` projections.users3.resource_owner, ` +
` projections.users3.sequence, ` +
` projections.users3.state, ` +
` projections.users3.type, ` +
` projections.users3.username, ` +
2022-02-02 07:21:54 +00:00
` login_names.loginnames, ` +
2022-01-20 14:40:25 +00:00
` preferred_login_name.login_name, ` +
2022-08-31 07:52:43 +00:00
` projections.users3_humans.user_id, ` +
` projections.users3_humans.first_name, ` +
` projections.users3_humans.last_name, ` +
` projections.users3_humans.nick_name, ` +
` projections.users3_humans.display_name, ` +
` projections.users3_humans.preferred_language, ` +
` projections.users3_humans.gender, ` +
` projections.users3_humans.avatar_key, ` +
` projections.users3_humans.email, ` +
` projections.users3_humans.is_email_verified, ` +
` projections.users3_humans.phone, ` +
` projections.users3_humans.is_phone_verified, ` +
` projections.users3_machines.user_id, ` +
` projections.users3_machines.name, ` +
` projections.users3_machines.description, ` +
2022-01-20 14:40:25 +00:00
` COUNT(*) OVER () ` +
2022-08-31 07:52:43 +00:00
` FROM projections.users3 ` +
` LEFT JOIN projections.users3_humans ON projections.users3.id = projections.users3_humans.user_id ` +
` LEFT JOIN projections.users3_machines ON projections.users3.id = projections.users3_machines.user_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT login_names.user_id, ARRAY_AGG(login_names.login_name) AS loginnames ` +
` FROM projections.login_names AS login_names ` +
` GROUP BY login_names.user_id) AS login_names ` +
` ON login_names.user_id = projections.users3.id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-08-31 07:52:43 +00:00
` (SELECT preferred_login_name.user_id, preferred_login_name.login_name FROM projections.login_names AS preferred_login_name WHERE preferred_login_name.is_primary = $1) AS preferred_login_name ` +
` ON preferred_login_name.user_id = projections.users3.id `
2022-01-20 14:40:25 +00:00
usersCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"state" ,
"type" ,
"username" ,
2022-02-02 07:21:54 +00:00
"loginnames" ,
2022-01-20 14:40:25 +00:00
"login_name" ,
//human
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
"email" ,
"is_email_verified" ,
"phone" ,
"is_phone_verified" ,
//machine
"user_id" ,
"name" ,
"description" ,
"count" ,
}
)
func Test_UserPrepares ( t * testing . T ) {
type want struct {
sqlExpectations sqlExpectation
err checkErr
}
tests := [ ] struct {
name string
prepare interface { }
want want
object interface { }
} {
{
2022-03-23 08:02:39 +00:00
name : "prepareUserQuery no result" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * User , error ) ) {
return prepareUserQuery ( "instanceID" )
} ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userQuery ) ,
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 : ( * User ) ( nil ) ,
} ,
{
2022-03-23 08:02:39 +00:00
name : "prepareUserQuery human found" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * User , error ) ) {
return prepareUserQuery ( "instanceID" )
} ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userQuery ) ,
userCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
//human
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
//machine
nil ,
nil ,
nil ,
} ,
) ,
} ,
object : & User {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Human : & Human {
FirstName : "first_name" ,
LastName : "last_name" ,
NickName : "nick_name" ,
DisplayName : "display_name" ,
AvatarKey : "avatar_key" ,
PreferredLanguage : language . German ,
Gender : domain . GenderUnspecified ,
Email : "email" ,
IsEmailVerified : true ,
Phone : "phone" ,
IsPhoneVerified : true ,
} ,
} ,
} ,
{
2022-03-23 08:02:39 +00:00
name : "prepareUserQuery machine found" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * User , error ) ) {
return prepareUserQuery ( "instanceID" )
} ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userQuery ) ,
userCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeMachine ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
//human
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
//machine
"id" ,
"name" ,
"description" ,
} ,
) ,
} ,
object : & User {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeMachine ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Machine : & Machine {
Name : "name" ,
Description : "description" ,
} ,
} ,
} ,
{
2022-03-23 08:02:39 +00:00
name : "prepareUserQuery sql err" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * User , error ) ) {
return prepareUserQuery ( "instanceID" )
} ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( userQuery ) ,
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 : "prepareProfileQuery no result" ,
prepare : prepareProfileQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( profileQuery ) ,
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 : ( * Profile ) ( nil ) ,
} ,
{
name : "prepareProfileQuery human found" ,
prepare : prepareProfileQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( profileQuery ) ,
profileCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
} ,
) ,
} ,
object : & Profile {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
FirstName : "first_name" ,
LastName : "last_name" ,
NickName : "nick_name" ,
DisplayName : "display_name" ,
AvatarKey : "avatar_key" ,
PreferredLanguage : language . German ,
Gender : domain . GenderUnspecified ,
} ,
} ,
{
name : "prepareProfileQuery not human found (error)" ,
prepare : prepareProfileQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( profileQuery ) ,
profileCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsPreconditionFailed ( err ) {
return fmt . Errorf ( "err should be zitadel.PredconditionError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : ( * Profile ) ( nil ) ,
} ,
{
name : "prepareProfileQuery sql err" ,
prepare : prepareProfileQuery ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( profileQuery ) ,
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 : "prepareEmailQuery no result" ,
prepare : prepareEmailQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( emailQuery ) ,
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 : ( * Email ) ( nil ) ,
} ,
{
name : "prepareEmailQuery human found" ,
prepare : prepareEmailQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( emailQuery ) ,
emailCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
//domain.UserStateActive,
"id" ,
"email" ,
true ,
} ,
) ,
} ,
object : & Email {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
//State: domain.UserStateActive,
Email : "email" ,
IsVerified : true ,
} ,
} ,
{
name : "prepareEmailQuery not human found (error)" ,
prepare : prepareEmailQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( emailQuery ) ,
emailCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
//domain.UserStateActive,
nil ,
nil ,
nil ,
} ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsPreconditionFailed ( err ) {
return fmt . Errorf ( "err should be zitadel.PredconditionError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : ( * Email ) ( nil ) ,
} ,
{
name : "prepareEmailQuery sql err" ,
prepare : prepareEmailQuery ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( emailQuery ) ,
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 : "preparePhoneQuery no result" ,
prepare : preparePhoneQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( phoneQuery ) ,
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 : ( * Phone ) ( nil ) ,
} ,
{
name : "preparePhoneQuery human found" ,
prepare : preparePhoneQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( phoneQuery ) ,
phoneCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
//domain.UserStateActive,
"id" ,
"phone" ,
true ,
} ,
) ,
} ,
object : & Phone {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
//State: domain.UserStateActive,
Phone : "phone" ,
IsVerified : true ,
} ,
} ,
{
name : "preparePhoneQuery not human found (error)" ,
prepare : preparePhoneQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( phoneQuery ) ,
phoneCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
//domain.UserStateActive,
nil ,
nil ,
nil ,
} ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsPreconditionFailed ( err ) {
return fmt . Errorf ( "err should be zitadel.PredconditionError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : ( * Phone ) ( nil ) ,
} ,
{
name : "preparePhoneQuery sql err" ,
prepare : preparePhoneQuery ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( phoneQuery ) ,
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 : "prepareUserUniqueQuery no result" ,
prepare : prepareUserUniqueQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userUniqueQuery ) ,
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 : true ,
} ,
{
name : "prepareUserUniqueQuery found" ,
prepare : prepareUserUniqueQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userUniqueQuery ) ,
userUniqueCols ,
[ ] driver . Value {
"id" ,
domain . UserStateActive ,
"username" ,
"id" ,
"email" ,
true ,
} ,
) ,
} ,
object : false ,
} ,
{
name : "prepareUserUniqueQuery sql err" ,
prepare : prepareUserUniqueQuery ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( userUniqueQuery ) ,
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 ,
} ,
2022-07-06 12:09:49 +00:00
{
name : "prepareNotifyUserQuery no result" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * NotifyUser , error ) ) {
return prepareNotifyUserQuery ( "instanceID" )
} ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( notifyUserQuery ) ,
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 : ( * NotifyUser ) ( nil ) ,
} ,
{
name : "prepareNotifyUserQuery notify found" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * NotifyUser , error ) ) {
return prepareNotifyUserQuery ( "instanceID" )
} ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( notifyUserQuery ) ,
notifyUserCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-07-06 12:09:49 +00:00
"login_name1" ,
//human
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
//notify
"id" ,
"lastEmail" ,
"verifiedEmail" ,
"lastPhone" ,
"verifiedPhone" ,
true ,
} ,
) ,
} ,
object : & NotifyUser {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-07-06 12:09:49 +00:00
PreferredLoginName : "login_name1" ,
FirstName : "first_name" ,
LastName : "last_name" ,
NickName : "nick_name" ,
DisplayName : "display_name" ,
AvatarKey : "avatar_key" ,
PreferredLanguage : language . German ,
Gender : domain . GenderUnspecified ,
LastEmail : "lastEmail" ,
VerifiedEmail : "verifiedEmail" ,
LastPhone : "lastPhone" ,
VerifiedPhone : "verifiedPhone" ,
PasswordSet : true ,
} ,
} ,
{
name : "prepareNotifyUserQuery not notify found (error)" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * NotifyUser , error ) ) {
return prepareNotifyUserQuery ( "instanceID" )
} ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( notifyUserQuery ) ,
notifyUserCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-07-06 12:09:49 +00:00
"login_name1" ,
//human
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsPreconditionFailed ( err ) {
return fmt . Errorf ( "err should be zitadel.PredconditionError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : ( * NotifyUser ) ( nil ) ,
} ,
{
name : "prepareNotifyUserQuery sql err" ,
prepare : func ( ) ( sq . SelectBuilder , func ( * sql . Row ) ( * NotifyUser , error ) ) {
return prepareNotifyUserQuery ( "instanceID" )
} ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( notifyUserQuery ) ,
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 ,
} ,
2022-01-20 14:40:25 +00:00
{
name : "prepareUsersQuery no result" ,
prepare : prepareUsersQuery ,
want : want {
sqlExpectations : mockQueries (
regexp . QuoteMeta ( usersQuery ) ,
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 : & Users { Users : [ ] * User { } } ,
} ,
{
name : "prepareUsersQuery one result" ,
prepare : prepareUsersQuery ,
want : want {
sqlExpectations : mockQueries (
regexp . QuoteMeta ( usersQuery ) ,
usersCols ,
[ ] [ ] driver . Value {
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
//human
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
//machine
nil ,
nil ,
nil ,
} ,
} ,
) ,
} ,
object : & Users {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
Users : [ ] * User {
{
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Human : & Human {
FirstName : "first_name" ,
LastName : "last_name" ,
NickName : "nick_name" ,
DisplayName : "display_name" ,
AvatarKey : "avatar_key" ,
PreferredLanguage : language . German ,
Gender : domain . GenderUnspecified ,
Email : "email" ,
IsEmailVerified : true ,
Phone : "phone" ,
IsPhoneVerified : true ,
} ,
} ,
} ,
} ,
} ,
{
name : "prepareUsersQuery multiple results" ,
prepare : prepareUsersQuery ,
want : want {
sqlExpectations : mockQueries (
regexp . QuoteMeta ( usersQuery ) ,
usersCols ,
[ ] [ ] driver . Value {
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
//human
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
//machine
nil ,
nil ,
nil ,
} ,
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeMachine ,
"username" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
//human
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
//machine
"id" ,
"name" ,
"description" ,
} ,
} ,
) ,
} ,
object : & Users {
SearchResponse : SearchResponse {
Count : 2 ,
} ,
Users : [ ] * User {
{
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Human : & Human {
FirstName : "first_name" ,
LastName : "last_name" ,
NickName : "nick_name" ,
DisplayName : "display_name" ,
AvatarKey : "avatar_key" ,
PreferredLanguage : language . German ,
Gender : domain . GenderUnspecified ,
Email : "email" ,
IsEmailVerified : true ,
Phone : "phone" ,
IsPhoneVerified : true ,
} ,
} ,
{
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeMachine ,
Username : "username" ,
2022-08-31 07:52:43 +00:00
LoginNames : database . StringArray { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Machine : & Machine {
Name : "name" ,
Description : "description" ,
} ,
} ,
} ,
} ,
} ,
{
name : "prepareUsersQuery sql err" ,
prepare : prepareUsersQuery ,
want : want {
sqlExpectations : mockQueryErr (
regexp . QuoteMeta ( usersQuery ) ,
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 )
} )
}
}