2022-01-20 14:40:25 +00:00
package query
import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"regexp"
"testing"
"golang.org/x/text/language"
2023-12-05 17:01:03 +00:00
"github.com/zitadel/zitadel/internal/crypto"
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 (
2023-11-20 15:21:08 +00:00
loginNamesQuery = ` SELECT login_names.user_id, ARRAY_AGG(login_names.login_name)::TEXT[] AS loginnames, ARRAY_AGG(LOWER(login_names.login_name))::TEXT[] AS loginnames_lower, login_names.instance_id ` +
` FROM projections.login_names3 AS login_names ` +
` GROUP BY login_names.user_id, login_names.instance_id `
preferredLoginNameQuery = ` SELECT preferred_login_name.user_id, preferred_login_name.login_name, preferred_login_name.instance_id ` +
` FROM projections.login_names3 AS preferred_login_name ` +
2022-11-30 16:01:17 +00:00
` WHERE preferred_login_name.is_primary = $1 `
2023-12-05 17:01:03 +00:00
userQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10.state, ` +
` projections.users10.type, ` +
` projections.users10.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, ` +
2023-12-05 17:01:03 +00:00
` projections.users10_humans.user_id, ` +
` projections.users10_humans.first_name, ` +
` projections.users10_humans.last_name, ` +
` projections.users10_humans.nick_name, ` +
` projections.users10_humans.display_name, ` +
` projections.users10_humans.preferred_language, ` +
` projections.users10_humans.gender, ` +
` projections.users10_humans.avatar_key, ` +
` projections.users10_humans.email, ` +
` projections.users10_humans.is_email_verified, ` +
` projections.users10_humans.phone, ` +
` projections.users10_humans.is_phone_verified, ` +
` projections.users10_machines.user_id, ` +
` projections.users10_machines.name, ` +
` projections.users10_machines.description, ` +
` projections.users10_machines.secret, ` +
` projections.users10_machines.access_token_type, ` +
2022-10-17 19:19:15 +00:00
` COUNT(*) OVER () ` +
2023-12-05 17:01:03 +00:00
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
` LEFT JOIN projections.users10_machines ON projections.users10.id = projections.users10_machines.user_id AND projections.users10.instance_id = projections.users10_machines.instance_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + loginNamesQuery + ` ) AS login_names ` +
2023-12-05 17:01:03 +00:00
` ON login_names.user_id = projections.users10.id AND login_names.instance_id = projections.users10.instance_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + preferredLoginNameQuery + ` ) AS preferred_login_name ` +
2023-12-05 17:01:03 +00:00
` ON preferred_login_name.user_id = projections.users10.id AND preferred_login_name.instance_id = projections.users10.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
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" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
"email" ,
"is_email_verified" ,
"phone" ,
"is_phone_verified" ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
"user_id" ,
"name" ,
"description" ,
2023-12-05 17:01:03 +00:00
"secret" ,
2023-02-08 08:06:34 +00:00
"access_token_type" ,
2022-10-17 19:19:15 +00:00
"count" ,
2022-01-20 14:40:25 +00:00
}
2023-12-05 17:01:03 +00:00
profileQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10_humans.user_id, ` +
` projections.users10_humans.first_name, ` +
` projections.users10_humans.last_name, ` +
` projections.users10_humans.nick_name, ` +
` projections.users10_humans.display_name, ` +
` projections.users10_humans.preferred_language, ` +
` projections.users10_humans.gender, ` +
` projections.users10_humans.avatar_key ` +
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
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" ,
}
2023-12-05 17:01:03 +00:00
emailQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10_humans.user_id, ` +
` projections.users10_humans.email, ` +
` projections.users10_humans.is_email_verified ` +
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
2022-01-20 14:40:25 +00:00
emailCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"user_id" ,
"email" ,
"is_email_verified" ,
}
2023-12-05 17:01:03 +00:00
phoneQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10_humans.user_id, ` +
` projections.users10_humans.phone, ` +
` projections.users10_humans.is_phone_verified ` +
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
2022-01-20 14:40:25 +00:00
phoneCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"user_id" ,
"phone" ,
"is_phone_verified" ,
}
2023-12-05 17:01:03 +00:00
userUniqueQuery = ` SELECT projections.users10.id, ` +
` projections.users10.state, ` +
` projections.users10.username, ` +
` projections.users10_humans.user_id, ` +
` projections.users10_humans.email, ` +
` projections.users10_humans.is_email_verified ` +
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
2022-01-20 14:40:25 +00:00
userUniqueCols = [ ] string {
"id" ,
"state" ,
"username" ,
"user_id" ,
"email" ,
"is_email_verified" ,
}
2023-12-05 17:01:03 +00:00
notifyUserQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10.state, ` +
` projections.users10.type, ` +
` projections.users10.username, ` +
2022-07-06 12:09:49 +00:00
` login_names.loginnames, ` +
` preferred_login_name.login_name, ` +
2023-12-05 17:01:03 +00:00
` projections.users10_humans.user_id, ` +
` projections.users10_humans.first_name, ` +
` projections.users10_humans.last_name, ` +
` projections.users10_humans.nick_name, ` +
` projections.users10_humans.display_name, ` +
` projections.users10_humans.preferred_language, ` +
` projections.users10_humans.gender, ` +
` projections.users10_humans.avatar_key, ` +
` projections.users10_notifications.user_id, ` +
` projections.users10_notifications.last_email, ` +
` projections.users10_notifications.verified_email, ` +
` projections.users10_notifications.last_phone, ` +
` projections.users10_notifications.verified_phone, ` +
` projections.users10_notifications.password_set, ` +
2022-10-17 19:19:15 +00:00
` COUNT(*) OVER () ` +
2023-12-05 17:01:03 +00:00
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
` LEFT JOIN projections.users10_notifications ON projections.users10.id = projections.users10_notifications.user_id AND projections.users10.instance_id = projections.users10_notifications.instance_id ` +
2022-07-06 12:09:49 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + loginNamesQuery + ` ) AS login_names ` +
2023-12-05 17:01:03 +00:00
` ON login_names.user_id = projections.users10.id AND login_names.instance_id = projections.users10.instance_id ` +
2022-07-06 12:09:49 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + preferredLoginNameQuery + ` ) AS preferred_login_name ` +
2023-12-05 17:01:03 +00:00
` ON preferred_login_name.user_id = projections.users10.id AND preferred_login_name.instance_id = projections.users10.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
2022-07-06 12:09:49 +00:00
notifyUserCols = [ ] string {
"id" ,
"creation_date" ,
"change_date" ,
"resource_owner" ,
"sequence" ,
"state" ,
"type" ,
"username" ,
"loginnames" ,
"login_name" ,
2023-12-05 17:01:03 +00:00
// human
2022-07-06 12:09:49 +00:00
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
2023-12-05 17:01:03 +00:00
// machine
2022-07-06 12:09:49 +00:00
"user_id" ,
"last_email" ,
"verified_email" ,
"last_phone" ,
"verified_phone" ,
"password_set" ,
2022-10-17 19:19:15 +00:00
"count" ,
2022-07-06 12:09:49 +00:00
}
2023-12-05 17:01:03 +00:00
usersQuery = ` SELECT projections.users10.id, ` +
` projections.users10.creation_date, ` +
` projections.users10.change_date, ` +
` projections.users10.resource_owner, ` +
` projections.users10.sequence, ` +
` projections.users10.state, ` +
` projections.users10.type, ` +
` projections.users10.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, ` +
2023-12-05 17:01:03 +00:00
` projections.users10_humans.user_id, ` +
` projections.users10_humans.first_name, ` +
` projections.users10_humans.last_name, ` +
` projections.users10_humans.nick_name, ` +
` projections.users10_humans.display_name, ` +
` projections.users10_humans.preferred_language, ` +
` projections.users10_humans.gender, ` +
` projections.users10_humans.avatar_key, ` +
` projections.users10_humans.email, ` +
` projections.users10_humans.is_email_verified, ` +
` projections.users10_humans.phone, ` +
` projections.users10_humans.is_phone_verified, ` +
` projections.users10_machines.user_id, ` +
` projections.users10_machines.name, ` +
` projections.users10_machines.description, ` +
` projections.users10_machines.secret, ` +
` projections.users10_machines.access_token_type, ` +
2022-01-20 14:40:25 +00:00
` COUNT(*) OVER () ` +
2023-12-05 17:01:03 +00:00
` FROM projections.users10 ` +
` LEFT JOIN projections.users10_humans ON projections.users10.id = projections.users10_humans.user_id AND projections.users10.instance_id = projections.users10_humans.instance_id ` +
` LEFT JOIN projections.users10_machines ON projections.users10.id = projections.users10_machines.user_id AND projections.users10.instance_id = projections.users10_machines.instance_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + loginNamesQuery + ` ) AS login_names ` +
2023-12-05 17:01:03 +00:00
` ON login_names.user_id = projections.users10.id AND login_names.instance_id = projections.users10.instance_id ` +
2022-01-20 14:40:25 +00:00
` LEFT JOIN ` +
2022-11-30 16:01:17 +00:00
` ( ` + preferredLoginNameQuery + ` ) AS preferred_login_name ` +
2023-12-05 17:01:03 +00:00
` ON preferred_login_name.user_id = projections.users10.id AND preferred_login_name.instance_id = projections.users10.instance_id ` +
2023-02-27 21:36:43 +00:00
` AS OF SYSTEM TIME '-1 ms' `
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" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
"user_id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"preferred_language" ,
"gender" ,
"avatar_key" ,
"email" ,
"is_email_verified" ,
"phone" ,
"is_phone_verified" ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
"user_id" ,
"name" ,
"description" ,
2023-12-05 17:01:03 +00:00
"secret" ,
2023-02-08 08:06:34 +00:00
"access_token_type" ,
2022-01-20 14:40:25 +00:00
"count" ,
}
)
func Test_UserPrepares ( t * testing . T ) {
type want struct {
sqlExpectations sqlExpectation
err checkErr
}
tests := [ ] struct {
name string
prepare interface { }
want want
object interface { }
} {
{
2023-02-27 21:36:43 +00:00
name : "prepareUserQuery no result" ,
prepare : prepareUserQuery ,
2022-01-20 14:40:25 +00:00
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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 ) ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUserQuery human found" ,
prepare : prepareUserQuery ,
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" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
nil ,
nil ,
nil ,
2023-01-31 19:52:47 +00:00
nil ,
2023-02-08 08:06:34 +00:00
nil ,
2022-10-17 19:19:15 +00:00
1 ,
2022-01-20 14:40:25 +00:00
} ,
) ,
} ,
object : & User {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "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 ,
} ,
} ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUserQuery machine found" ,
prepare : prepareUserQuery ,
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" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
"id" ,
"name" ,
"description" ,
2023-12-05 17:01:03 +00:00
nil ,
2023-02-08 08:06:34 +00:00
domain . OIDCTokenTypeBearer ,
2022-10-17 19:19:15 +00:00
1 ,
2022-01-20 14:40:25 +00:00
} ,
) ,
} ,
object : & User {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeMachine ,
Username : "username" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Machine : & Machine {
2023-02-08 08:06:34 +00:00
Name : "name" ,
Description : "description" ,
2023-12-05 17:01:03 +00:00
Secret : nil ,
AccessTokenType : domain . OIDCTokenTypeBearer ,
} ,
} ,
} ,
{
name : "prepareUserQuery machine with secret found" ,
prepare : prepareUserQuery ,
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( userQuery ) ,
userCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeMachine ,
"username" ,
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
"login_name1" ,
// human
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// machine
"id" ,
"name" ,
"description" ,
` { "CryptoType":1,"Algorithm":"bcrypt","Crypted":"deadbeef"} ` ,
domain . OIDCTokenTypeBearer ,
1 ,
} ,
) ,
} ,
object : & User {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeMachine ,
Username : "username" ,
LoginNames : database . TextArray [ string ] { "login_name1" , "login_name2" } ,
PreferredLoginName : "login_name1" ,
Machine : & Machine {
Name : "name" ,
Description : "description" ,
Secret : & crypto . CryptoValue {
CryptoType : crypto . TypeHash ,
Algorithm : "bcrypt" ,
Crypted : [ ] byte { 117 , 230 , 157 , 109 , 231 , 159 } ,
} ,
2023-02-08 08:06:34 +00:00
AccessTokenType : domain . OIDCTokenTypeBearer ,
2022-01-20 14:40:25 +00:00
} ,
} ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUserQuery sql err" ,
prepare : prepareUserQuery ,
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * User ) ( nil ) ,
2022-01-20 14:40:25 +00:00
} ,
{
name : "prepareProfileQuery no result" ,
prepare : prepareProfileQuery ,
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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 {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * Profile ) ( nil ) ,
2022-01-20 14:40:25 +00:00
} ,
{
name : "prepareEmailQuery no result" ,
prepare : prepareEmailQuery ,
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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 {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * Email ) ( nil ) ,
2022-01-20 14:40:25 +00:00
} ,
{
name : "preparePhoneQuery no result" ,
prepare : preparePhoneQuery ,
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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 {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-01-20 14:40:25 +00:00
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * Phone ) ( nil ) ,
2022-01-20 14:40:25 +00:00
} ,
{
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : false ,
2022-01-20 14:40:25 +00:00
} ,
2022-07-06 12:09:49 +00:00
{
2023-02-27 21:36:43 +00:00
name : "prepareNotifyUserQuery no result" ,
prepare : prepareNotifyUserQuery ,
2022-07-06 12:09:49 +00:00
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-07-06 12:09:49 +00:00
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 ) ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareNotifyUserQuery notify found" ,
prepare : prepareNotifyUserQuery ,
2022-07-06 12:09:49 +00:00
want : want {
sqlExpectations : mockQuery (
regexp . QuoteMeta ( notifyUserQuery ) ,
notifyUserCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-07-06 12:09:49 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-07-06 12:09:49 +00:00
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
//notify
"id" ,
"lastEmail" ,
"verifiedEmail" ,
"lastPhone" ,
"verifiedPhone" ,
true ,
2022-10-17 19:19:15 +00:00
1 ,
2022-07-06 12:09:49 +00:00
} ,
) ,
} ,
object : & NotifyUser {
ID : "id" ,
CreationDate : testNow ,
ChangeDate : testNow ,
ResourceOwner : "resource_owner" ,
Sequence : 20211108 ,
State : domain . UserStateActive ,
Type : domain . UserTypeHuman ,
Username : "username" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "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 ,
} ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareNotifyUserQuery not notify found (error)" ,
prepare : prepareNotifyUserQuery ,
2022-07-06 12:09:49 +00:00
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQueryScanErr (
2022-07-06 12:09:49 +00:00
regexp . QuoteMeta ( notifyUserQuery ) ,
notifyUserCols ,
[ ] driver . Value {
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-07-06 12:09:49 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-07-06 12:09:49 +00:00
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
2022-10-17 19:19:15 +00:00
1 ,
2022-07-06 12:09:49 +00:00
} ,
) ,
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 ) ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareNotifyUserQuery sql err" ,
prepare : prepareNotifyUserQuery ,
2022-07-06 12:09:49 +00:00
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * NotifyUser ) ( nil ) ,
2022-07-06 12:09:49 +00:00
} ,
2022-01-20 14:40:25 +00:00
{
2023-02-27 21:36:43 +00:00
name : "prepareUsersQuery no result" ,
prepare : prepareUsersQuery ,
2022-01-20 14:40:25 +00:00
want : want {
2023-08-22 12:49:02 +00:00
sqlExpectations : mockQuery (
2022-01-20 14:40:25 +00:00
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 { } } ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUsersQuery one result" ,
prepare : prepareUsersQuery ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQueries (
regexp . QuoteMeta ( usersQuery ) ,
usersCols ,
[ ] [ ] driver . Value {
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
nil ,
nil ,
nil ,
2023-01-31 19:52:47 +00:00
nil ,
2023-02-08 08:06:34 +00:00
nil ,
2022-01-20 14:40:25 +00:00
} ,
} ,
) ,
} ,
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" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "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 ,
} ,
} ,
} ,
} ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUsersQuery multiple results" ,
prepare : prepareUsersQuery ,
2022-01-20 14:40:25 +00:00
want : want {
sqlExpectations : mockQueries (
regexp . QuoteMeta ( usersQuery ) ,
usersCols ,
[ ] [ ] driver . Value {
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeHuman ,
"username" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
"id" ,
"first_name" ,
"last_name" ,
"nick_name" ,
"display_name" ,
"de" ,
domain . GenderUnspecified ,
"avatar_key" ,
"email" ,
true ,
"phone" ,
true ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
nil ,
nil ,
nil ,
2023-01-31 19:52:47 +00:00
nil ,
2023-02-08 08:06:34 +00:00
nil ,
2022-01-20 14:40:25 +00:00
} ,
{
"id" ,
testNow ,
testNow ,
"resource_owner" ,
uint64 ( 20211108 ) ,
domain . UserStateActive ,
domain . UserTypeMachine ,
"username" ,
2023-10-19 10:19:10 +00:00
database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
"login_name1" ,
2023-12-05 17:01:03 +00:00
// human
2022-01-20 14:40:25 +00:00
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
2023-12-05 17:01:03 +00:00
// machine
2022-01-20 14:40:25 +00:00
"id" ,
"name" ,
"description" ,
2023-12-05 17:01:03 +00:00
` { "CryptoType":1,"Algorithm":"bcrypt","Crypted":"deadbeef"} ` ,
2023-02-08 08:06:34 +00:00
domain . OIDCTokenTypeBearer ,
2022-01-20 14:40:25 +00:00
} ,
} ,
) ,
} ,
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" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "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" ,
2023-10-19 10:19:10 +00:00
LoginNames : database . TextArray [ string ] { "login_name1" , "login_name2" } ,
2022-01-20 14:40:25 +00:00
PreferredLoginName : "login_name1" ,
Machine : & Machine {
2023-12-05 17:01:03 +00:00
Name : "name" ,
Description : "description" ,
Secret : & crypto . CryptoValue {
CryptoType : crypto . TypeHash ,
Algorithm : "bcrypt" ,
Crypted : [ ] byte { 117 , 230 , 157 , 109 , 231 , 159 } ,
} ,
2023-02-08 08:06:34 +00:00
AccessTokenType : domain . OIDCTokenTypeBearer ,
2022-01-20 14:40:25 +00:00
} ,
} ,
} ,
} ,
} ,
{
2023-02-27 21:36:43 +00:00
name : "prepareUsersQuery sql err" ,
prepare : prepareUsersQuery ,
2022-01-20 14:40:25 +00:00
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
} ,
} ,
2023-08-22 12:49:02 +00:00
object : ( * Users ) ( nil ) ,
2022-01-20 14:40:25 +00:00
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-02-27 21:36:43 +00:00
assertPrepare ( t , tt . prepare , tt . object , tt . want . sqlExpectations , tt . want . err , defaultPrepareArgs ... )
2022-01-20 14:40:25 +00:00
} )
}
}