mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 12:07:37 +00:00
fix: make user creation errors helpful (#5382)
* fix: make user creation errors helpful * fix linting and unit testing errors * fix linting * make zitadel config reusable * fix human validations * translate ssr errors * make zitadel config reusable * cover more translations for ssr * handle email validation message centrally * fix unit tests * fix linting * align signatures * use more precise wording * handle phone validation message centrally * fix: return specific profile errors * docs: edit comments * fix unit tests --------- Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
||||
)
|
||||
@@ -120,13 +121,13 @@ func newConfig(tenant TenantType, clientID, secret, callbackURL string, scopes [
|
||||
// AzureAD does not return an `email_verified` claim.
|
||||
// The verification can be automatically activated on the provider ([WithEmailVerified])
|
||||
type User struct {
|
||||
Sub string `json:"sub"`
|
||||
FamilyName string `json:"family_name"`
|
||||
GivenName string `json:"given_name"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferred_username"`
|
||||
Email string `json:"email"`
|
||||
Picture string `json:"picture"`
|
||||
Sub string `json:"sub"`
|
||||
FamilyName string `json:"family_name"`
|
||||
GivenName string `json:"given_name"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferred_username"`
|
||||
Email domain.EmailAddress `json:"email"`
|
||||
Picture string `json:"picture"`
|
||||
isEmailVerified bool
|
||||
}
|
||||
|
||||
@@ -162,7 +163,7 @@ func (u *User) GetPreferredUsername() string {
|
||||
}
|
||||
|
||||
// GetEmail is an implementation of the [idp.User] interface.
|
||||
func (u *User) GetEmail() string {
|
||||
func (u *User) GetEmail() domain.EmailAddress {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
@@ -176,7 +177,7 @@ func (u *User) IsEmailVerified() bool {
|
||||
|
||||
// GetPhone is an implementation of the [idp.User] interface.
|
||||
// It returns an empty string because AzureAD does not provide the user's phone.
|
||||
func (u *User) GetPhone() string {
|
||||
func (u *User) GetPhone() domain.PhoneNumber {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
||||
)
|
||||
@@ -259,9 +260,9 @@ func TestSession_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -4,6 +4,8 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
@@ -68,44 +70,44 @@ func newConfig(clientID, secret, callbackURL, authURL, tokenURL string, scopes [
|
||||
// User is a representation of the authenticated GitHub user and implements the [idp.User] interface
|
||||
// https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user
|
||||
type User struct {
|
||||
Login string `json:"login"`
|
||||
ID int `json:"id"`
|
||||
NodeId string `json:"node_id"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
GravatarId string `json:"gravatar_id"`
|
||||
Url string `json:"url"`
|
||||
HtmlUrl string `json:"html_url"`
|
||||
FollowersUrl string `json:"followers_url"`
|
||||
FollowingUrl string `json:"following_url"`
|
||||
GistsUrl string `json:"gists_url"`
|
||||
StarredUrl string `json:"starred_url"`
|
||||
SubscriptionsUrl string `json:"subscriptions_url"`
|
||||
OrganizationsUrl string `json:"organizations_url"`
|
||||
ReposUrl string `json:"repos_url"`
|
||||
EventsUrl string `json:"events_url"`
|
||||
ReceivedEventsUrl string `json:"received_events_url"`
|
||||
Type string `json:"type"`
|
||||
SiteAdmin bool `json:"site_admin"`
|
||||
Name string `json:"name"`
|
||||
Company string `json:"company"`
|
||||
Blog string `json:"blog"`
|
||||
Location string `json:"location"`
|
||||
Email string `json:"email"`
|
||||
Hireable bool `json:"hireable"`
|
||||
Bio string `json:"bio"`
|
||||
TwitterUsername string `json:"twitter_username"`
|
||||
PublicRepos int `json:"public_repos"`
|
||||
PublicGists int `json:"public_gists"`
|
||||
Followers int `json:"followers"`
|
||||
Following int `json:"following"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
PrivateGists int `json:"private_gists"`
|
||||
TotalPrivateRepos int `json:"total_private_repos"`
|
||||
OwnedPrivateRepos int `json:"owned_private_repos"`
|
||||
DiskUsage int `json:"disk_usage"`
|
||||
Collaborators int `json:"collaborators"`
|
||||
TwoFactorAuthentication bool `json:"two_factor_authentication"`
|
||||
Login string `json:"login"`
|
||||
ID int `json:"id"`
|
||||
NodeId string `json:"node_id"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
GravatarId string `json:"gravatar_id"`
|
||||
Url string `json:"url"`
|
||||
HtmlUrl string `json:"html_url"`
|
||||
FollowersUrl string `json:"followers_url"`
|
||||
FollowingUrl string `json:"following_url"`
|
||||
GistsUrl string `json:"gists_url"`
|
||||
StarredUrl string `json:"starred_url"`
|
||||
SubscriptionsUrl string `json:"subscriptions_url"`
|
||||
OrganizationsUrl string `json:"organizations_url"`
|
||||
ReposUrl string `json:"repos_url"`
|
||||
EventsUrl string `json:"events_url"`
|
||||
ReceivedEventsUrl string `json:"received_events_url"`
|
||||
Type string `json:"type"`
|
||||
SiteAdmin bool `json:"site_admin"`
|
||||
Name string `json:"name"`
|
||||
Company string `json:"company"`
|
||||
Blog string `json:"blog"`
|
||||
Location string `json:"location"`
|
||||
Email domain.EmailAddress `json:"email"`
|
||||
Hireable bool `json:"hireable"`
|
||||
Bio string `json:"bio"`
|
||||
TwitterUsername string `json:"twitter_username"`
|
||||
PublicRepos int `json:"public_repos"`
|
||||
PublicGists int `json:"public_gists"`
|
||||
Followers int `json:"followers"`
|
||||
Following int `json:"following"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
PrivateGists int `json:"private_gists"`
|
||||
TotalPrivateRepos int `json:"total_private_repos"`
|
||||
OwnedPrivateRepos int `json:"owned_private_repos"`
|
||||
DiskUsage int `json:"disk_usage"`
|
||||
Collaborators int `json:"collaborators"`
|
||||
TwoFactorAuthentication bool `json:"two_factor_authentication"`
|
||||
Plan struct {
|
||||
Name string `json:"name"`
|
||||
Space int `json:"space"`
|
||||
@@ -150,7 +152,7 @@ func (u *User) GetPreferredUsername() string {
|
||||
}
|
||||
|
||||
// GetEmail is an implementation of the [idp.User] interface.
|
||||
func (u *User) GetEmail() string {
|
||||
func (u *User) GetEmail() domain.EmailAddress {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ func (u *User) IsEmailVerified() bool {
|
||||
|
||||
// GetPhone is an implementation of the [idp.User] interface.
|
||||
// It returns an empty string because GitHub does not provide the user's phone.
|
||||
func (u *User) GetPhone() string {
|
||||
func (u *User) GetPhone() domain.PhoneNumber {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
||||
)
|
||||
@@ -188,9 +189,9 @@ func TestSession_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||
)
|
||||
|
||||
@@ -187,9 +188,9 @@ func TestProvider_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -43,5 +43,5 @@ type User struct {
|
||||
// GetPreferredUsername implements the [idp.User] interface.
|
||||
// It returns the email, because Google does not return a username.
|
||||
func (u *User) GetPreferredUsername() string {
|
||||
return u.GetEmail()
|
||||
return string(u.GetEmail())
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||
)
|
||||
|
||||
@@ -188,9 +189,9 @@ func TestSession_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -106,8 +107,8 @@ func (u *User) GetNickname() string {
|
||||
return u.IDTokenClaims.GetNickname()
|
||||
}
|
||||
|
||||
func (u *User) GetPhone() string {
|
||||
return u.IDTokenClaims.GetPhoneNumber()
|
||||
func (u *User) GetPhone() domain.PhoneNumber {
|
||||
return domain.PhoneNumber(u.IDTokenClaims.GetPhoneNumber())
|
||||
}
|
||||
|
||||
func (u *User) IsPhoneVerified() bool {
|
||||
@@ -121,3 +122,7 @@ func (u *User) GetPreferredLanguage() language.Tag {
|
||||
func (u *User) GetAvatarURL() string {
|
||||
return u.IDTokenClaims.GetPicture()
|
||||
}
|
||||
|
||||
func (u *User) GetEmail() domain.EmailAddress {
|
||||
return domain.EmailAddress(u.IDTokenClaims.GetEmail())
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ import (
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
)
|
||||
|
||||
func TestSession_FetchUser(t *testing.T) {
|
||||
@@ -193,9 +194,9 @@ func TestSession_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -87,9 +88,9 @@ func (s *Session) FetchUser(_ context.Context) (idp.User, error) {
|
||||
user.GetAttributeValue(s.Provider.displayNameAttribute),
|
||||
user.GetAttributeValue(s.Provider.nickNameAttribute),
|
||||
user.GetAttributeValue(s.Provider.preferredUsernameAttribute),
|
||||
user.GetAttributeValue(s.Provider.emailAttribute),
|
||||
domain.EmailAddress(user.GetAttributeValue(s.Provider.emailAttribute)),
|
||||
emailVerified,
|
||||
user.GetAttributeValue(s.Provider.phoneAttribute),
|
||||
domain.PhoneNumber(user.GetAttributeValue(s.Provider.phoneAttribute)),
|
||||
phoneVerified,
|
||||
language.Make(user.GetAttributeValue(s.Provider.preferredLanguageAttribute)),
|
||||
user.GetAttributeValue(s.Provider.avatarURLAttribute),
|
||||
|
@@ -1,6 +1,10 @@
|
||||
package ldap
|
||||
|
||||
import "golang.org/x/text/language"
|
||||
import (
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
id string
|
||||
@@ -9,9 +13,9 @@ type User struct {
|
||||
displayName string
|
||||
nickName string
|
||||
preferredUsername string
|
||||
email string
|
||||
email domain.EmailAddress
|
||||
emailVerified bool
|
||||
phone string
|
||||
phone domain.PhoneNumber
|
||||
phoneVerified bool
|
||||
preferredLanguage language.Tag
|
||||
avatarURL string
|
||||
@@ -25,9 +29,9 @@ func NewUser(
|
||||
displayName string,
|
||||
nickName string,
|
||||
preferredUsername string,
|
||||
email string,
|
||||
email domain.EmailAddress,
|
||||
emailVerified bool,
|
||||
phone string,
|
||||
phone domain.PhoneNumber,
|
||||
phoneVerified bool,
|
||||
preferredLanguage language.Tag,
|
||||
avatarURL string,
|
||||
@@ -68,13 +72,13 @@ func (u *User) GetNickname() string {
|
||||
func (u *User) GetPreferredUsername() string {
|
||||
return u.preferredUsername
|
||||
}
|
||||
func (u *User) GetEmail() string {
|
||||
func (u *User) GetEmail() domain.EmailAddress {
|
||||
return u.email
|
||||
}
|
||||
func (u *User) IsEmailVerified() bool {
|
||||
return u.emailVerified
|
||||
}
|
||||
func (u *User) GetPhone() string {
|
||||
func (u *User) GetPhone() domain.PhoneNumber {
|
||||
return u.phone
|
||||
}
|
||||
func (u *User) IsPhoneVerified() bool {
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -74,7 +75,7 @@ func (u *UserMapper) GetPreferredUsername() string {
|
||||
}
|
||||
|
||||
// GetEmail is an implementation of the [idp.User] interface.
|
||||
func (u *UserMapper) GetEmail() string {
|
||||
func (u *UserMapper) GetEmail() domain.EmailAddress {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -84,7 +85,7 @@ func (u *UserMapper) IsEmailVerified() bool {
|
||||
}
|
||||
|
||||
// GetPhone is an implementation of the [idp.User] interface.
|
||||
func (u *UserMapper) GetPhone() string {
|
||||
func (u *UserMapper) GetPhone() domain.PhoneNumber {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -260,9 +261,9 @@ func TestProvider_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -82,8 +83,8 @@ func (u *User) GetDisplayName() string {
|
||||
return u.GetName()
|
||||
}
|
||||
|
||||
func (u *User) GetPhone() string {
|
||||
return u.GetPhoneNumber()
|
||||
func (u *User) GetPhone() domain.PhoneNumber {
|
||||
return domain.PhoneNumber(u.GetPhoneNumber())
|
||||
}
|
||||
|
||||
func (u *User) IsPhoneVerified() bool {
|
||||
@@ -97,3 +98,7 @@ func (u *User) GetPreferredLanguage() language.Tag {
|
||||
func (u *User) GetAvatarURL() string {
|
||||
return u.GetPicture()
|
||||
}
|
||||
|
||||
func (u *User) GetEmail() domain.EmailAddress {
|
||||
return domain.EmailAddress(u.UserInfo.GetEmail())
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ import (
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/idp"
|
||||
)
|
||||
|
||||
@@ -281,9 +282,9 @@ func TestSession_FetchUser(t *testing.T) {
|
||||
a.Equal(tt.want.displayName, user.GetDisplayName())
|
||||
a.Equal(tt.want.nickName, user.GetNickname())
|
||||
a.Equal(tt.want.preferredUsername, user.GetPreferredUsername())
|
||||
a.Equal(tt.want.email, user.GetEmail())
|
||||
a.Equal(domain.EmailAddress(tt.want.email), user.GetEmail())
|
||||
a.Equal(tt.want.isEmailVerified, user.IsEmailVerified())
|
||||
a.Equal(tt.want.phone, user.GetPhone())
|
||||
a.Equal(domain.PhoneNumber(tt.want.phone), user.GetPhone())
|
||||
a.Equal(tt.want.isPhoneVerified, user.IsPhoneVerified())
|
||||
a.Equal(tt.want.preferredLanguage, user.GetPreferredLanguage())
|
||||
a.Equal(tt.want.avatarURL, user.GetAvatarURL())
|
||||
|
Reference in New Issue
Block a user