V3-1307 combine first and last name to full name (#1569)

* V3-1307 combine first and last name to full name
This commit is contained in:
Yehor Butko 2019-03-27 14:33:32 +02:00 committed by GitHub
parent bfdfebbde2
commit 86bf3dee9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 602 additions and 325 deletions

View File

@ -131,7 +131,7 @@ func addExampleProjectWithKey(key *string, createRegistrationTokenAddress, activ
}
{
createUserQuery := fmt.Sprintf(
"mutation {createUser(input:{email:\"%s\",password:\"%s\",firstName:\"%s\",lastName:\"\"}, secret:\"%s\" ){id,email,createdAt}}",
"mutation {createUser(input:{email:\"%s\",password:\"%s\",fullName:\"%s\", shortName:\"\"}, secret:\"%s\" ){id,email,createdAt}}",
"example@mail.com",
"123a123",
"Alice",

View File

@ -4,8 +4,6 @@
package consoleql
import (
"fmt"
"github.com/graphql-go/graphql"
"github.com/skyrings/skyring-common/tools/uuid"
"go.uber.org/zap"
@ -98,12 +96,16 @@ func rootMutation(log *zap.Logger, service *console.Service, mailService *mailse
rootObject := p.Info.RootValue.(map[string]interface{})
origin := rootObject["origin"].(string)
link := origin + rootObject[ActivationPath].(string) + token
userName := user.ShortName
if user.ShortName == "" {
userName = user.FullName
}
// TODO: think of a better solution
go func() {
_ = mailService.SendRendered(
p.Context,
[]post.Address{{Address: user.Email, Name: user.FirstName}},
[]post.Address{{Address: user.Email, Name: userName}},
&AccountActivationEmail{
Origin: origin,
ActivationLink: link,
@ -295,12 +297,17 @@ func rootMutation(log *zap.Logger, service *console.Service, mailService *mailse
// TODO: think of a better solution
go func() {
for _, user := range users {
userName := user.ShortName
if user.ShortName == "" {
userName = user.FullName
}
_ = mailService.SendRendered(
p.Context,
[]post.Address{{Address: user.Email, Name: fmt.Sprintf("%s %s", user.FirstName, user.LastName)}},
[]post.Address{{Address: user.Email, Name: userName}},
&ProjectInvitationEmail{
Origin: origin,
UserName: user.FirstName,
UserName: userName,
ProjectName: project.Name,
SignInLink: signIn,
},

View File

@ -73,8 +73,8 @@ func TestGrapqhlMutation(t *testing.T) {
createUser := console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "John",
LastName: "Roll",
FullName: "John Roll",
ShortName: "Roll",
Email: "test@email.com",
},
Password: "123a123",
@ -115,8 +115,8 @@ func TestGrapqhlMutation(t *testing.T) {
t.Run("Create user mutation", func(t *testing.T) {
newUser := console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "Mickey",
LastName: "Green",
FullName: "Green Mickey",
ShortName: "Green",
Email: "u1@email.com",
},
Password: "123a123",
@ -128,11 +128,11 @@ func TestGrapqhlMutation(t *testing.T) {
}
query := fmt.Sprintf(
"mutation {createUser(input:{email:\"%s\",password:\"%s\",firstName:\"%s\",lastName:\"%s\"}, secret: \"%s\"){id,lastName,firstName,email,createdAt}}",
"mutation {createUser(input:{email:\"%s\",password:\"%s\", fullName:\"%s\", shortName:\"%s\"}, secret: \"%s\"){id,shortName,fullName,email,createdAt}}",
newUser.Email,
newUser.Password,
newUser.FirstName,
newUser.LastName,
newUser.FullName,
newUser.ShortName,
regTokenTest.Secret,
)
@ -161,8 +161,8 @@ func TestGrapqhlMutation(t *testing.T) {
user, err := service.GetUser(authCtx, *uID)
assert.NoError(t, err)
assert.Equal(t, newUser.FirstName, user.FirstName)
assert.Equal(t, newUser.LastName, user.LastName)
assert.Equal(t, newUser.FullName, user.FullName)
assert.Equal(t, newUser.ShortName, user.ShortName)
})
testQuery := func(t *testing.T, query string) interface{} {
@ -187,7 +187,7 @@ func TestGrapqhlMutation(t *testing.T) {
t.Run("Update account mutation email only", func(t *testing.T) {
email := "new@email.com"
query := fmt.Sprintf(
"mutation {updateAccount(input:{email:\"%s\"}){id,email,firstName,lastName,createdAt}}",
"mutation {updateAccount(input:{email:\"%s\"}){id,email,fullName,shortName,createdAt}}",
email,
)
@ -198,15 +198,15 @@ func TestGrapqhlMutation(t *testing.T) {
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, email, user[consoleql.FieldEmail])
assert.Equal(t, rootUser.FirstName, user[consoleql.FieldFirstName])
assert.Equal(t, rootUser.LastName, user[consoleql.FieldLastName])
assert.Equal(t, rootUser.FullName, user[consoleql.FieldFullName])
assert.Equal(t, rootUser.ShortName, user[consoleql.FieldShortName])
})
t.Run("Update account mutation firstName only", func(t *testing.T) {
firstName := "George"
t.Run("Update account mutation fullName only", func(t *testing.T) {
fullName := "George"
query := fmt.Sprintf(
"mutation {updateAccount(input:{firstName:\"%s\"}){id,email,firstName,lastName,createdAt}}",
firstName,
"mutation {updateAccount(input:{fullName:\"%s\"}){id,email,fullName,shortName,createdAt}}",
fullName,
)
result := testQuery(t, query)
@ -216,15 +216,15 @@ func TestGrapqhlMutation(t *testing.T) {
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, rootUser.Email, user[consoleql.FieldEmail])
assert.Equal(t, firstName, user[consoleql.FieldFirstName])
assert.Equal(t, rootUser.LastName, user[consoleql.FieldLastName])
assert.Equal(t, fullName, user[consoleql.FieldFullName])
assert.Equal(t, rootUser.ShortName, user[consoleql.FieldShortName])
})
t.Run("Update account mutation lastName only", func(t *testing.T) {
lastName := "Yellow"
t.Run("Update account mutation shortName only", func(t *testing.T) {
shortName := "Yellow"
query := fmt.Sprintf(
"mutation {updateAccount(input:{lastName:\"%s\"}){id,email,firstName,lastName,createdAt}}",
lastName,
"mutation {updateAccount(input:{shortName:\"%s\"}){id,email,fullName,shortName,createdAt}}",
shortName,
)
result := testQuery(t, query)
@ -234,20 +234,20 @@ func TestGrapqhlMutation(t *testing.T) {
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, rootUser.Email, user[consoleql.FieldEmail])
assert.Equal(t, rootUser.FirstName, user[consoleql.FieldFirstName])
assert.Equal(t, lastName, user[consoleql.FieldLastName])
assert.Equal(t, rootUser.FullName, user[consoleql.FieldFullName])
assert.Equal(t, shortName, user[consoleql.FieldShortName])
})
t.Run("Update account mutation all info", func(t *testing.T) {
email := "test@newmail.com"
firstName := "Fill"
lastName := "Goal"
fullName := "Fill Goal"
shortName := "Goal"
query := fmt.Sprintf(
"mutation {updateAccount(input:{email:\"%s\",firstName:\"%s\",lastName:\"%s\"}){id,email,firstName,lastName,createdAt}}",
"mutation {updateAccount(input:{email:\"%s\",fullName:\"%s\",shortName:\"%s\"}){id,email,fullName,shortName,createdAt}}",
email,
firstName,
lastName,
fullName,
shortName,
)
result := testQuery(t, query)
@ -257,8 +257,8 @@ func TestGrapqhlMutation(t *testing.T) {
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, email, user[consoleql.FieldEmail])
assert.Equal(t, firstName, user[consoleql.FieldFirstName])
assert.Equal(t, lastName, user[consoleql.FieldLastName])
assert.Equal(t, fullName, user[consoleql.FieldFullName])
assert.Equal(t, shortName, user[consoleql.FieldShortName])
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(user[consoleql.FieldCreatedAt].(string)))
@ -271,7 +271,7 @@ func TestGrapqhlMutation(t *testing.T) {
newPassword := "145a145a"
query := fmt.Sprintf(
"mutation {changePassword(password:\"%s\",newPassword:\"%s\"){id,email,firstName,lastName,createdAt}}",
"mutation {changePassword(password:\"%s\",newPassword:\"%s\"){id,email,fullName,shortName,createdAt}}",
createUser.Password,
newPassword,
)
@ -283,8 +283,8 @@ func TestGrapqhlMutation(t *testing.T) {
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, rootUser.Email, user[consoleql.FieldEmail])
assert.Equal(t, rootUser.FirstName, user[consoleql.FieldFirstName])
assert.Equal(t, rootUser.LastName, user[consoleql.FieldLastName])
assert.Equal(t, rootUser.FullName, user[consoleql.FieldFullName])
assert.Equal(t, rootUser.ShortName, user[consoleql.FieldShortName])
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(user[consoleql.FieldCreatedAt].(string)))
@ -374,8 +374,8 @@ func TestGrapqhlMutation(t *testing.T) {
user1, err := service.CreateUser(authCtx, console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "User1",
Email: "u1@email.net",
FullName: "User1",
Email: "u1@email.net",
},
Password: "123a123",
}, regTokenUser1.Secret)
@ -406,8 +406,8 @@ func TestGrapqhlMutation(t *testing.T) {
user2, err := service.CreateUser(authCtx, console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "User1",
Email: "u2@email.net",
FullName: "User1",
Email: "u2@email.net",
},
Password: "123a123",
}, regTokenUser2.Secret)

View File

@ -65,8 +65,8 @@ func TestGraphqlQuery(t *testing.T) {
createUser := console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "John",
LastName: "",
FullName: "John",
ShortName: "",
Email: "mtest@email.com",
},
Password: "123a123",
@ -133,8 +133,8 @@ func TestGraphqlQuery(t *testing.T) {
testUser := func(t *testing.T, actual map[string]interface{}, expected *console.User) {
assert.Equal(t, expected.ID.String(), actual[consoleql.FieldID])
assert.Equal(t, expected.Email, actual[consoleql.FieldEmail])
assert.Equal(t, expected.FirstName, actual[consoleql.FieldFirstName])
assert.Equal(t, expected.LastName, actual[consoleql.FieldLastName])
assert.Equal(t, expected.FullName, actual[consoleql.FieldFullName])
assert.Equal(t, expected.ShortName, actual[consoleql.FieldShortName])
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
@ -145,7 +145,7 @@ func TestGraphqlQuery(t *testing.T) {
t.Run("With ID", func(t *testing.T) {
query := fmt.Sprintf(
"query {user(id:\"%s\"){id,email,firstName,lastName,createdAt}}",
"query {user(id:\"%s\"){id,email,fullName,shortName,createdAt}}",
rootUser.ID.String(),
)
@ -158,7 +158,7 @@ func TestGraphqlQuery(t *testing.T) {
})
t.Run("With AuthFallback", func(t *testing.T) {
query := "query {user{id,email,firstName,lastName,createdAt}}"
query := "query {user{id,email,fullName,shortName,createdAt}}"
result := testQuery(t, query)
@ -177,7 +177,7 @@ func TestGraphqlQuery(t *testing.T) {
t.Fatal(err)
}
// "query {project(id:\"%s\"){id,name,members(offset:0, limit:50){user{firstName,lastName,email}},apiKeys{name,id,createdAt,projectID}}}"
// "query {project(id:\"%s\"){id,name,members(offset:0, limit:50){user{fullName,shortName,email}},apiKeys{name,id,createdAt,projectID}}}"
t.Run("Project query base info", func(t *testing.T) {
query := fmt.Sprintf(
"query {project(id:\"%s\"){id,name,description,createdAt}}",
@ -207,8 +207,8 @@ func TestGraphqlQuery(t *testing.T) {
user1, err := service.CreateUser(authCtx, console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "Mickey",
LastName: "Last",
FullName: "Mickey Last",
ShortName: "Last",
Email: "muu1@email.com",
},
Password: "123a123",
@ -242,8 +242,8 @@ func TestGraphqlQuery(t *testing.T) {
user2, err := service.CreateUser(authCtx, console.CreateUser{
UserInfo: console.UserInfo{
FirstName: "Dubas",
LastName: "Name",
FullName: "Dubas Name",
ShortName: "Name",
Email: "muu2@email.com",
},
Password: "123a123",
@ -280,7 +280,7 @@ func TestGraphqlQuery(t *testing.T) {
t.Run("Project query team members", func(t *testing.T) {
query := fmt.Sprintf(
"query {project(id:\"%s\"){members(offset:0, limit:50){user{id,firstName,lastName,email,createdAt}}}}",
"query {project(id:\"%s\"){members(offset:0, limit:50){user{id,fullName,shortName,email,createdAt}}}}",
createdProject.ID.String(),
)
@ -294,8 +294,8 @@ func TestGraphqlQuery(t *testing.T) {
testUser := func(t *testing.T, actual map[string]interface{}, expected *console.User) {
assert.Equal(t, expected.Email, actual[consoleql.FieldEmail])
assert.Equal(t, expected.FirstName, actual[consoleql.FieldFirstName])
assert.Equal(t, expected.LastName, actual[consoleql.FieldLastName])
assert.Equal(t, expected.FullName, actual[consoleql.FieldFullName])
assert.Equal(t, expected.ShortName, actual[consoleql.FieldShortName])
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
@ -436,7 +436,7 @@ func TestGraphqlQuery(t *testing.T) {
t.Run("Token query", func(t *testing.T) {
query := fmt.Sprintf(
"query {token(email: \"%s\", password: \"%s\"){token,user{id,email,firstName,lastName,createdAt}}}",
"query {token(email: \"%s\", password: \"%s\"){token,user{id,email,fullName,shortName,createdAt}}}",
createUser.Email,
createUser.Password,
)
@ -457,8 +457,8 @@ func TestGraphqlQuery(t *testing.T) {
assert.Equal(t, rootUser.ID, tauth.User.ID)
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, rootUser.Email, user[consoleql.FieldEmail])
assert.Equal(t, rootUser.FirstName, user[consoleql.FieldFirstName])
assert.Equal(t, rootUser.LastName, user[consoleql.FieldLastName])
assert.Equal(t, rootUser.FullName, user[consoleql.FieldFullName])
assert.Equal(t, rootUser.ShortName, user[consoleql.FieldShortName])
createdAt := time.Time{}
err = createdAt.UnmarshalText([]byte(user[consoleql.FieldCreatedAt].(string)))

View File

@ -20,10 +20,10 @@ const (
FieldEmail = "email"
// FieldPassword is a field name for password
FieldPassword = "password"
// FieldFirstName is a field name for "first name"
FieldFirstName = "firstName"
// FieldLastName is a field name for "last name"
FieldLastName = "lastName"
// FieldFullName is a field name for "first name"
FieldFullName = "fullName"
// FieldShortName is a field name for "last name"
FieldShortName = "shortName"
// FieldCreatedAt is a field name for created at timestamp
FieldCreatedAt = "createdAt"
)
@ -39,10 +39,10 @@ func baseUserConfig() graphql.ObjectConfig {
FieldEmail: &graphql.Field{
Type: graphql.String,
},
FieldFirstName: &graphql.Field{
FieldFullName: &graphql.Field{
Type: graphql.String,
},
FieldLastName: &graphql.Field{
FieldShortName: &graphql.Field{
Type: graphql.String,
},
FieldCreatedAt: &graphql.Field{
@ -66,10 +66,10 @@ func graphqlUserInput(types Types) *graphql.InputObject {
FieldEmail: &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
FieldFirstName: &graphql.InputObjectFieldConfig{
FieldFullName: &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
FieldLastName: &graphql.InputObjectFieldConfig{
FieldShortName: &graphql.InputObjectFieldConfig{
Type: graphql.String,
},
FieldPassword: &graphql.InputObjectFieldConfig{
@ -82,8 +82,8 @@ func graphqlUserInput(types Types) *graphql.InputObject {
// fromMapUserInfo creates UserInput from input args
func fromMapUserInfo(args map[string]interface{}) (user console.UserInfo) {
user.Email, _ = args[FieldEmail].(string)
user.FirstName, _ = args[FieldFirstName].(string)
user.LastName, _ = args[FieldLastName].(string)
user.FullName, _ = args[FieldFullName].(string)
user.ShortName, _ = args[FieldShortName].(string)
return
}
@ -97,8 +97,8 @@ func fromMapCreateUser(args map[string]interface{}) (user console.CreateUser) {
func fillUserInfo(user *console.User, args map[string]interface{}) console.UserInfo {
info := console.UserInfo{
Email: user.Email,
FirstName: user.FirstName,
LastName: user.LastName,
FullName: user.FullName,
ShortName: user.ShortName,
}
for fieldName, fieldValue := range args {
@ -111,12 +111,12 @@ func fillUserInfo(user *console.User, args map[string]interface{}) console.UserI
case FieldEmail:
info.Email = value
user.Email = value
case FieldFirstName:
info.FirstName = value
user.FirstName = value
case FieldLastName:
info.LastName = value
user.LastName = value
case FieldFullName:
info.FullName = value
user.FullName = value
case FieldShortName:
info.ShortName = value
user.ShortName = value
}
}

View File

@ -107,7 +107,6 @@ func (s *Server) appHandler(w http.ResponseWriter, req *http.Request) {
}
// accountActivationHandler is web app http handler function
// TODO: add some auth token in request header to prevent unauthorized token creation
func (s *Server) createRegistrationTokenHandler(w http.ResponseWriter, req *http.Request) {
w.Header().Set(contentType, applicationJSON)

View File

@ -44,7 +44,7 @@ type Pagination struct {
type ProjectMemberOrder int8
const (
// Name indicates that we should order by first name
// Name indicates that we should order by full name
Name ProjectMemberOrder = 1
// Email indicates that we should order by email
Email ProjectMemberOrder = 2

View File

@ -158,33 +158,33 @@ func prepareUsersAndProjects(ctx context.Context, t *testing.T, users console.Us
usersList := []*console.User{{
Email: "2email2@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "Liam",
FirstName: "Jameson",
ShortName: "Liam",
FullName: "Liam Jameson",
}, {
Email: "1email1@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "William",
FirstName: "Noahson",
ShortName: "William",
FullName: "Noahson William",
}, {
Email: "email3@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "Mason",
FirstName: "Elijahson",
ShortName: "Mason",
FullName: "Mason Elijahson",
}, {
Email: "email4@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "Oliver",
FirstName: "Jacobson",
ShortName: "Oliver",
FullName: "Oliver Jacobson",
}, {
Email: "email5@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "Lucas",
FirstName: "Michaelson",
ShortName: "Lucas",
FullName: "Michaelson Lucas",
}, {
Email: "email6@ukr.net",
PasswordHash: []byte("some_readable_hash"),
LastName: "Alexander",
FirstName: "Ethanson",
ShortName: "Alexander",
FullName: "Alexander Ethanson",
},
}

View File

@ -18,10 +18,10 @@ func TestProjectsRepository(t *testing.T) {
//testing constants
const (
// for user
lastName = "lastName"
email = "email@ukr.net"
pass = "123456"
userName = "name"
shortName = "lastName"
email = "email@ukr.net"
pass = "123456"
userFullName = "name"
// for project
name = "Project"
@ -44,8 +44,8 @@ func TestProjectsRepository(t *testing.T) {
t.Run("Insert project successfully", func(t *testing.T) {
var err error
owner, err = users.Insert(ctx, &console.User{
FirstName: userName,
LastName: lastName,
FullName: userFullName,
ShortName: shortName,
Email: email,
PasswordHash: []byte(pass),
})

View File

@ -102,8 +102,8 @@ func (s *Service) CreateUser(ctx context.Context, user CreateUser, tokenSecret R
u, err = s.store.Users().Insert(ctx, &User{
Email: user.Email,
FirstName: user.FirstName,
LastName: user.LastName,
FullName: user.FullName,
ShortName: user.ShortName,
PasswordHash: hash,
})
@ -222,8 +222,8 @@ func (s *Service) UpdateAccount(ctx context.Context, info UserInfo) (err error)
return s.store.Users().Update(ctx, &User{
ID: auth.User.ID,
FirstName: info.FirstName,
LastName: info.LastName,
FullName: info.FullName,
ShortName: info.ShortName,
Email: email,
PasswordHash: nil,
})

View File

@ -27,8 +27,8 @@ type Users interface {
// UserInfo holds User updatable data.
type UserInfo struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
FullName string `json:"fullName"`
ShortName string `json:"shortName"`
Email string `json:"email"`
}
@ -40,9 +40,9 @@ func (user *UserInfo) IsValid() error {
_, err := mail.ParseAddress(user.Email)
errs.AddWrap(err)
// validate firstName
if user.FirstName == "" {
errs.Add("firstName can't be empty")
// validate fullName
if user.FullName == "" {
errs.Add("fullName can't be empty")
}
return errs.Combine()
@ -80,8 +80,8 @@ const (
type User struct {
ID uuid.UUID `json:"id"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
FullName string `json:"fullName"`
ShortName string `json:"shortName"`
Email string `json:"email"`
PasswordHash []byte `json:"passwordHash"`

View File

@ -41,8 +41,8 @@ func TestUserRepository(t *testing.T) {
user := &console.User{
ID: *id,
FirstName: name,
LastName: lastName,
FullName: name,
ShortName: lastName,
Email: email,
PasswordHash: []byte(passValid),
CreatedAt: time.Now(),
@ -59,18 +59,18 @@ func TestUserRepository(t *testing.T) {
t.Run("Get user success", func(t *testing.T) {
userByEmail, err := repository.GetByEmail(ctx, email)
assert.Equal(t, userByEmail.FirstName, name)
assert.Equal(t, userByEmail.LastName, lastName)
assert.Equal(t, userByEmail.FullName, name)
assert.Equal(t, userByEmail.ShortName, lastName)
assert.NoError(t, err)
userByID, err := repository.Get(ctx, userByEmail.ID)
assert.Equal(t, userByID.FirstName, name)
assert.Equal(t, userByID.LastName, lastName)
assert.Equal(t, userByID.FullName, name)
assert.Equal(t, userByID.ShortName, lastName)
assert.NoError(t, err)
assert.Equal(t, userByID.ID, userByEmail.ID)
assert.Equal(t, userByID.FirstName, userByEmail.FirstName)
assert.Equal(t, userByID.LastName, userByEmail.LastName)
assert.Equal(t, userByID.FullName, userByEmail.FullName)
assert.Equal(t, userByID.ShortName, userByEmail.ShortName)
assert.Equal(t, userByID.Email, userByEmail.Email)
assert.Equal(t, userByID.PasswordHash, userByEmail.PasswordHash)
assert.Equal(t, userByID.CreatedAt, userByEmail.CreatedAt)
@ -82,8 +82,8 @@ func TestUserRepository(t *testing.T) {
newUser := &console.User{
ID: oldUser.ID,
FirstName: newName,
LastName: newLastName,
FullName: newName,
ShortName: newLastName,
Email: newEmail,
Status: console.Active,
PasswordHash: []byte(newPass),
@ -95,8 +95,8 @@ func TestUserRepository(t *testing.T) {
newUser, err = repository.Get(ctx, oldUser.ID)
assert.NoError(t, err)
assert.Equal(t, newUser.ID, oldUser.ID)
assert.Equal(t, newUser.FirstName, newName)
assert.Equal(t, newUser.LastName, newLastName)
assert.Equal(t, newUser.FullName, newName)
assert.Equal(t, newUser.ShortName, newLastName)
assert.Equal(t, newUser.Email, newEmail)
assert.Equal(t, newUser.PasswordHash, []byte(newPass))
assert.Equal(t, newUser.CreatedAt, oldUser.CreatedAt)

View File

@ -225,8 +225,8 @@ model user (
key id
field id blob
field first_name text ( updatable )
field last_name text ( updatable )
field full_name text ( updatable )
field short_name text ( updatable, nullable )
field email text ( updatable )
field password_hash blob ( updatable )

View File

@ -432,8 +432,8 @@ CREATE TABLE storagenode_storage_rollups (
);
CREATE TABLE users (
id bytea NOT NULL,
first_name text NOT NULL,
last_name text NOT NULL,
full_name text NOT NULL,
short_name text,
email text NOT NULL,
password_hash bytea NOT NULL,
status integer NOT NULL,
@ -690,8 +690,8 @@ CREATE TABLE storagenode_storage_rollups (
);
CREATE TABLE users (
id BLOB NOT NULL,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
full_name TEXT NOT NULL,
short_name TEXT,
email TEXT NOT NULL,
password_hash BLOB NOT NULL,
status INTEGER NOT NULL,
@ -3094,8 +3094,8 @@ func (StoragenodeStorageRollup_Total_Field) _Column() string { return "total" }
type User struct {
Id []byte
FirstName string
LastName string
FullName string
ShortName *string
Email string
PasswordHash []byte
Status int
@ -3104,9 +3104,13 @@ type User struct {
func (User) _Table() string { return "users" }
type User_Create_Fields struct {
ShortName User_ShortName_Field
}
type User_Update_Fields struct {
FirstName User_FirstName_Field
LastName User_LastName_Field
FullName User_FullName_Field
ShortName User_ShortName_Field
Email User_Email_Field
PasswordHash User_PasswordHash_Field
Status User_Status_Field
@ -3131,43 +3135,56 @@ func (f User_Id_Field) value() interface{} {
func (User_Id_Field) _Column() string { return "id" }
type User_FirstName_Field struct {
type User_FullName_Field struct {
_set bool
_null bool
_value string
}
func User_FirstName(v string) User_FirstName_Field {
return User_FirstName_Field{_set: true, _value: v}
func User_FullName(v string) User_FullName_Field {
return User_FullName_Field{_set: true, _value: v}
}
func (f User_FirstName_Field) value() interface{} {
func (f User_FullName_Field) value() interface{} {
if !f._set || f._null {
return nil
}
return f._value
}
func (User_FirstName_Field) _Column() string { return "first_name" }
func (User_FullName_Field) _Column() string { return "full_name" }
type User_LastName_Field struct {
type User_ShortName_Field struct {
_set bool
_null bool
_value string
_value *string
}
func User_LastName(v string) User_LastName_Field {
return User_LastName_Field{_set: true, _value: v}
func User_ShortName(v string) User_ShortName_Field {
return User_ShortName_Field{_set: true, _value: &v}
}
func (f User_LastName_Field) value() interface{} {
func User_ShortName_Raw(v *string) User_ShortName_Field {
if v == nil {
return User_ShortName_Null()
}
return User_ShortName(*v)
}
func User_ShortName_Null() User_ShortName_Field {
return User_ShortName_Field{_set: true, _null: true}
}
func (f User_ShortName_Field) isnull() bool { return !f._set || f._null || f._value == nil }
func (f User_ShortName_Field) value() interface{} {
if !f._set || f._null {
return nil
}
return f._value
}
func (User_LastName_Field) _Column() string { return "last_name" }
func (User_ShortName_Field) _Column() string { return "short_name" }
type User_Email_Field struct {
_set bool
@ -3907,28 +3924,28 @@ func (obj *postgresImpl) Create_Injuredsegment(ctx context.Context,
func (obj *postgresImpl) Create_User(ctx context.Context,
user_id User_Id_Field,
user_first_name User_FirstName_Field,
user_last_name User_LastName_Field,
user_full_name User_FullName_Field,
user_email User_Email_Field,
user_password_hash User_PasswordHash_Field) (
user_password_hash User_PasswordHash_Field,
optional User_Create_Fields) (
user *User, err error) {
__now := obj.db.Hooks.Now().UTC()
__id_val := user_id.value()
__first_name_val := user_first_name.value()
__last_name_val := user_last_name.value()
__full_name_val := user_full_name.value()
__short_name_val := optional.ShortName.value()
__email_val := user_email.value()
__password_hash_val := user_password_hash.value()
__status_val := int(0)
__created_at_val := __now
var __embed_stmt = __sqlbundle_Literal("INSERT INTO users ( id, first_name, last_name, email, password_hash, status, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, ? ) RETURNING users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at")
var __embed_stmt = __sqlbundle_Literal("INSERT INTO users ( id, full_name, short_name, email, password_hash, status, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, ? ) RETURNING users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at")
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
obj.logStmt(__stmt, __id_val, __first_name_val, __last_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
obj.logStmt(__stmt, __id_val, __full_name_val, __short_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
user = &User{}
err = obj.driver.QueryRow(__stmt, __id_val, __first_name_val, __last_name_val, __email_val, __password_hash_val, __status_val, __created_at_val).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt, __id_val, __full_name_val, __short_name_val, __email_val, __password_hash_val, __status_val, __created_at_val).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -4576,7 +4593,7 @@ func (obj *postgresImpl) Get_User_By_Email_And_Status_Not_Number(ctx context.Con
user_email User_Email_Field) (
user *User, err error) {
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.email = ? AND users.status != 0 LIMIT 2")
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.email = ? AND users.status != 0 LIMIT 2")
var __values []interface{}
__values = append(__values, user_email.value())
@ -4598,7 +4615,7 @@ func (obj *postgresImpl) Get_User_By_Email_And_Status_Not_Number(ctx context.Con
}
user = &User{}
err = __rows.Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = __rows.Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -4619,7 +4636,7 @@ func (obj *postgresImpl) Get_User_By_Id(ctx context.Context,
user_id User_Id_Field) (
user *User, err error) {
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __values []interface{}
__values = append(__values, user_id.value())
@ -4628,7 +4645,7 @@ func (obj *postgresImpl) Get_User_By_Id(ctx context.Context,
obj.logStmt(__stmt, __values...)
user = &User{}
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -5353,20 +5370,20 @@ func (obj *postgresImpl) Update_User_By_Id(ctx context.Context,
user *User, err error) {
var __sets = &__sqlbundle_Hole{}
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPDATE users SET "), __sets, __sqlbundle_Literal(" WHERE users.id = ? RETURNING users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at")}}
var __embed_stmt = __sqlbundle_Literals{Join: "", SQLs: []__sqlbundle_SQL{__sqlbundle_Literal("UPDATE users SET "), __sets, __sqlbundle_Literal(" WHERE users.id = ? RETURNING users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at")}}
__sets_sql := __sqlbundle_Literals{Join: ", "}
var __values []interface{}
var __args []interface{}
if update.FirstName._set {
__values = append(__values, update.FirstName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("first_name = ?"))
if update.FullName._set {
__values = append(__values, update.FullName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("full_name = ?"))
}
if update.LastName._set {
__values = append(__values, update.LastName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("last_name = ?"))
if update.ShortName._set {
__values = append(__values, update.ShortName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("short_name = ?"))
}
if update.Email._set {
@ -5397,7 +5414,7 @@ func (obj *postgresImpl) Update_User_By_Id(ctx context.Context,
obj.logStmt(__stmt, __values...)
user = &User{}
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err == sql.ErrNoRows {
return nil, nil
}
@ -6366,27 +6383,27 @@ func (obj *sqlite3Impl) Create_Injuredsegment(ctx context.Context,
func (obj *sqlite3Impl) Create_User(ctx context.Context,
user_id User_Id_Field,
user_first_name User_FirstName_Field,
user_last_name User_LastName_Field,
user_full_name User_FullName_Field,
user_email User_Email_Field,
user_password_hash User_PasswordHash_Field) (
user_password_hash User_PasswordHash_Field,
optional User_Create_Fields) (
user *User, err error) {
__now := obj.db.Hooks.Now().UTC()
__id_val := user_id.value()
__first_name_val := user_first_name.value()
__last_name_val := user_last_name.value()
__full_name_val := user_full_name.value()
__short_name_val := optional.ShortName.value()
__email_val := user_email.value()
__password_hash_val := user_password_hash.value()
__status_val := int(0)
__created_at_val := __now
var __embed_stmt = __sqlbundle_Literal("INSERT INTO users ( id, first_name, last_name, email, password_hash, status, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, ? )")
var __embed_stmt = __sqlbundle_Literal("INSERT INTO users ( id, full_name, short_name, email, password_hash, status, created_at ) VALUES ( ?, ?, ?, ?, ?, ?, ? )")
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
obj.logStmt(__stmt, __id_val, __first_name_val, __last_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
obj.logStmt(__stmt, __id_val, __full_name_val, __short_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
__res, err := obj.driver.Exec(__stmt, __id_val, __first_name_val, __last_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
__res, err := obj.driver.Exec(__stmt, __id_val, __full_name_val, __short_name_val, __email_val, __password_hash_val, __status_val, __created_at_val)
if err != nil {
return nil, obj.makeErr(err)
}
@ -7062,7 +7079,7 @@ func (obj *sqlite3Impl) Get_User_By_Email_And_Status_Not_Number(ctx context.Cont
user_email User_Email_Field) (
user *User, err error) {
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.email = ? AND users.status != 0 LIMIT 2")
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.email = ? AND users.status != 0 LIMIT 2")
var __values []interface{}
__values = append(__values, user_email.value())
@ -7084,7 +7101,7 @@ func (obj *sqlite3Impl) Get_User_By_Email_And_Status_Not_Number(ctx context.Cont
}
user = &User{}
err = __rows.Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = __rows.Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -7105,7 +7122,7 @@ func (obj *sqlite3Impl) Get_User_By_Id(ctx context.Context,
user_id User_Id_Field) (
user *User, err error) {
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __values []interface{}
__values = append(__values, user_id.value())
@ -7114,7 +7131,7 @@ func (obj *sqlite3Impl) Get_User_By_Id(ctx context.Context,
obj.logStmt(__stmt, __values...)
user = &User{}
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt, __values...).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -7885,14 +7902,14 @@ func (obj *sqlite3Impl) Update_User_By_Id(ctx context.Context,
var __values []interface{}
var __args []interface{}
if update.FirstName._set {
__values = append(__values, update.FirstName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("first_name = ?"))
if update.FullName._set {
__values = append(__values, update.FullName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("full_name = ?"))
}
if update.LastName._set {
__values = append(__values, update.LastName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("last_name = ?"))
if update.ShortName._set {
__values = append(__values, update.ShortName.value())
__sets_sql.SQLs = append(__sets_sql.SQLs, __sqlbundle_Literal("short_name = ?"))
}
if update.Email._set {
@ -7928,12 +7945,12 @@ func (obj *sqlite3Impl) Update_User_By_Id(ctx context.Context,
return nil, obj.makeErr(err)
}
var __embed_stmt_get = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __embed_stmt_get = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE users.id = ?")
var __stmt_get = __sqlbundle_Render(obj.dialect, __embed_stmt_get)
obj.logStmt("(IMPLIED) "+__stmt_get, __args...)
err = obj.driver.QueryRow(__stmt_get, __args...).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt_get, __args...).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err == sql.ErrNoRows {
return nil, nil
}
@ -8608,13 +8625,13 @@ func (obj *sqlite3Impl) getLastUser(ctx context.Context,
pk int64) (
user *User, err error) {
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.first_name, users.last_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE _rowid_ = ?")
var __embed_stmt = __sqlbundle_Literal("SELECT users.id, users.full_name, users.short_name, users.email, users.password_hash, users.status, users.created_at FROM users WHERE _rowid_ = ?")
var __stmt = __sqlbundle_Render(obj.dialect, __embed_stmt)
obj.logStmt(__stmt, pk)
user = &User{}
err = obj.driver.QueryRow(__stmt, pk).Scan(&user.Id, &user.FirstName, &user.LastName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
err = obj.driver.QueryRow(__stmt, pk).Scan(&user.Id, &user.FullName, &user.ShortName, &user.Email, &user.PasswordHash, &user.Status, &user.CreatedAt)
if err != nil {
return nil, obj.makeErr(err)
}
@ -9346,16 +9363,16 @@ func (rx *Rx) Create_UsedSerial(ctx context.Context,
func (rx *Rx) Create_User(ctx context.Context,
user_id User_Id_Field,
user_first_name User_FirstName_Field,
user_last_name User_LastName_Field,
user_full_name User_FullName_Field,
user_email User_Email_Field,
user_password_hash User_PasswordHash_Field) (
user_password_hash User_PasswordHash_Field,
optional User_Create_Fields) (
user *User, err error) {
var tx *Tx
if tx, err = rx.getTx(ctx); err != nil {
return
}
return tx.Create_User(ctx, user_id, user_first_name, user_last_name, user_email, user_password_hash)
return tx.Create_User(ctx, user_id, user_full_name, user_email, user_password_hash, optional)
}
@ -9990,10 +10007,10 @@ type Methods interface {
Create_User(ctx context.Context,
user_id User_Id_Field,
user_first_name User_FirstName_Field,
user_last_name User_LastName_Field,
user_full_name User_FullName_Field,
user_email User_Email_Field,
user_password_hash User_PasswordHash_Field) (
user_password_hash User_PasswordHash_Field,
optional User_Create_Fields) (
user *User, err error)
Delete_AccountingRaw_By_Id(ctx context.Context,

View File

@ -161,8 +161,8 @@ CREATE TABLE storagenode_storage_rollups (
);
CREATE TABLE users (
id bytea NOT NULL,
first_name text NOT NULL,
last_name text NOT NULL,
full_name text NOT NULL,
short_name text,
email text NOT NULL,
password_hash bytea NOT NULL,
status integer NOT NULL,

View File

@ -161,8 +161,8 @@ CREATE TABLE storagenode_storage_rollups (
);
CREATE TABLE users (
id BLOB NOT NULL,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
full_name TEXT NOT NULL,
short_name TEXT,
email TEXT NOT NULL,
password_hash BLOB NOT NULL,
status INTEGER NOT NULL,

View File

@ -430,6 +430,15 @@ func (db *DB) PostgresMigration() *migrate.Migration {
rollup_end_time )`,
},
},
{
Description: "users first_name to full_name, last_name to short_name",
Version: 10,
Action: migrate.SQL{
`ALTER TABLE users RENAME COLUMN first_name TO full_name;
ALTER TABLE users ALTER COLUMN last_name DROP NOT NULL;
ALTER TABLE users RENAME COLUMN last_name TO short_name;`,
},
},
},
}
}

View File

@ -48,8 +48,8 @@ func (pm *projectMembers) GetByProjectID(ctx context.Context, projectID uuid.UUI
INNER JOIN users u ON pm.member_id = u.id
WHERE pm.project_id = ?
AND ( u.email LIKE ? OR
u.first_name || u.last_name LIKE ? OR
u.last_name || u.first_name LIKE ? )
u.full_name LIKE ? OR
u.short_name LIKE ? )
ORDER BY ` + sanitizedOrderColumnName(pagination.Order) + ` ASC
LIMIT ? OFFSET ?
`)
@ -150,7 +150,7 @@ func sanitizedOrderColumnName(pmo console.ProjectMemberOrder) string {
case 3:
return "u.created_at"
default:
return "u.first_name"
return "u.full_name"
}
}

View File

@ -16,11 +16,11 @@ func TestSanitizedOrderColumnName(t *testing.T) {
orderNumber int8
orderColumn string
}{
0: {0, "u.first_name"},
1: {1, "u.first_name"},
0: {0, "u.full_name"},
1: {1, "u.full_name"},
2: {2, "u.email"},
3: {3, "u.created_at"},
4: {4, "u.first_name"},
4: {4, "u.full_name"},
}
for _, tc := range testCases {

View File

@ -0,0 +1,235 @@
-- Copied from the corresponding version of dbx generated schema
CREATE TABLE accounting_raws (
id bigserial NOT NULL,
node_id bytea NOT NULL,
interval_end_time timestamp with time zone NOT NULL,
data_total double precision NOT NULL,
data_type integer NOT NULL,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE accounting_rollups (
id bigserial NOT NULL,
node_id bytea NOT NULL,
start_time timestamp with time zone NOT NULL,
put_total bigint NOT NULL,
get_total bigint NOT NULL,
get_audit_total bigint NOT NULL,
get_repair_total bigint NOT NULL,
put_repair_total bigint NOT NULL,
at_rest_total double precision NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE accounting_timestamps (
name text NOT NULL,
value timestamp with time zone NOT NULL,
PRIMARY KEY ( name )
);
CREATE TABLE bucket_bandwidth_rollups (
bucket_id bytea NOT NULL,
interval_start timestamp NOT NULL,
interval_seconds integer NOT NULL,
action integer NOT NULL,
inline bigint NOT NULL,
allocated bigint NOT NULL,
settled bigint NOT NULL,
PRIMARY KEY ( bucket_id, interval_start, action )
);
CREATE TABLE bucket_storage_rollups (
bucket_id bytea NOT NULL,
interval_start timestamp NOT NULL,
interval_seconds integer NOT NULL,
inline bigint NOT NULL,
remote bigint NOT NULL,
PRIMARY KEY ( bucket_id, interval_start )
);
CREATE TABLE bucket_usages (
id bytea NOT NULL,
bucket_id bytea NOT NULL,
rollup_end_time timestamp with time zone NOT NULL,
remote_stored_data bigint NOT NULL,
inline_stored_data bigint NOT NULL,
remote_segments integer NOT NULL,
inline_segments integer NOT NULL,
objects integer NOT NULL,
metadata_size bigint NOT NULL,
repair_egress bigint NOT NULL,
get_egress bigint NOT NULL,
audit_egress bigint NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE bwagreements (
serialnum text NOT NULL,
storage_node_id bytea NOT NULL,
uplink_id bytea NOT NULL,
action bigint NOT NULL,
total bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
expires_at timestamp with time zone NOT NULL,
PRIMARY KEY ( serialnum )
);
CREATE TABLE certRecords (
publickey bytea NOT NULL,
id bytea NOT NULL,
update_at timestamp with time zone NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE injuredsegments (
id bigserial NOT NULL,
info bytea NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE irreparabledbs (
segmentpath bytea NOT NULL,
segmentdetail bytea NOT NULL,
pieces_lost_count bigint NOT NULL,
seg_damaged_unix_sec bigint NOT NULL,
repair_attempt_count bigint NOT NULL,
PRIMARY KEY ( segmentpath )
);
CREATE TABLE nodes (
id bytea NOT NULL,
audit_success_count bigint NOT NULL,
total_audit_count bigint NOT NULL,
audit_success_ratio double precision NOT NULL,
uptime_success_count bigint NOT NULL,
total_uptime_count bigint NOT NULL,
uptime_ratio double precision NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
wallet text NOT NULL,
email text NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE overlay_cache_nodes (
node_id bytea NOT NULL,
node_type integer NOT NULL,
address text NOT NULL,
protocol integer NOT NULL,
operator_email text NOT NULL,
operator_wallet text NOT NULL,
free_bandwidth bigint NOT NULL,
free_disk bigint NOT NULL,
latency_90 bigint NOT NULL,
audit_success_ratio double precision NOT NULL,
audit_uptime_ratio double precision NOT NULL,
audit_count bigint NOT NULL,
audit_success_count bigint NOT NULL,
uptime_count bigint NOT NULL,
uptime_success_count bigint NOT NULL,
PRIMARY KEY ( node_id ),
UNIQUE ( node_id )
);
CREATE TABLE projects (
id bytea NOT NULL,
name text NOT NULL,
description text NOT NULL,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE registration_tokens (
secret bytea NOT NULL,
owner_id bytea,
project_limit integer NOT NULL,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( secret ),
UNIQUE ( owner_id )
);
CREATE TABLE serial_numbers (
id serial NOT NULL,
serial_number bytea NOT NULL,
bucket_id bytea NOT NULL,
expires_at timestamp NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE storagenode_bandwidth_rollups (
storagenode_id bytea NOT NULL,
interval_start timestamp NOT NULL,
interval_seconds integer NOT NULL,
action integer NOT NULL,
allocated bigint NOT NULL,
settled bigint NOT NULL,
PRIMARY KEY ( storagenode_id, interval_start, action )
);
CREATE TABLE storagenode_storage_rollups (
storagenode_id bytea NOT NULL,
interval_start timestamp NOT NULL,
interval_seconds integer NOT NULL,
total bigint NOT NULL,
PRIMARY KEY ( storagenode_id, interval_start )
);
CREATE TABLE users (
id bytea NOT NULL,
full_name text NOT NULL,
short_name text,
email text NOT NULL,
password_hash bytea NOT NULL,
status integer NOT NULL,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( id )
);
CREATE TABLE api_keys (
id bytea NOT NULL,
project_id bytea NOT NULL REFERENCES projects( id ) ON DELETE CASCADE,
key bytea NOT NULL,
name text NOT NULL,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( id ),
UNIQUE ( key ),
UNIQUE ( name, project_id )
);
CREATE TABLE project_members (
member_id bytea NOT NULL REFERENCES users( id ) ON DELETE CASCADE,
project_id bytea NOT NULL REFERENCES projects( id ) ON DELETE CASCADE,
created_at timestamp with time zone NOT NULL,
PRIMARY KEY ( member_id, project_id )
);
CREATE TABLE used_serials (
serial_number_id integer NOT NULL REFERENCES serial_numbers( id ) ON DELETE CASCADE,
storage_node_id bytea NOT NULL,
PRIMARY KEY ( serial_number_id, storage_node_id )
);
CREATE INDEX bucket_id_interval_start_interval_seconds ON bucket_bandwidth_rollups ( bucket_id, interval_start, interval_seconds );
CREATE UNIQUE INDEX bucket_id_rollup ON bucket_usages ( bucket_id, rollup_end_time );
CREATE UNIQUE INDEX serial_number ON serial_numbers ( serial_number );
CREATE INDEX serial_numbers_expires_at_index ON serial_numbers ( expires_at );
CREATE INDEX storagenode_id_interval_start_interval_seconds ON storagenode_bandwidth_rollups ( storagenode_id, interval_start, interval_seconds );
---
INSERT INTO "accounting_raws" VALUES (1, E'\\3510\\323\\225"~\\036<\\342\\330m\\0253Jhr\\246\\233K\\246#\\2303\\351\\256\\275j\\212UM\\362\\207', '2019-02-14 08:16:57.812849+00', 1000, 0, '2019-02-14 08:16:57.844849+00');
INSERT INTO "accounting_rollups"("id", "node_id", "start_time", "put_total", "get_total", "get_audit_total", "get_repair_total", "put_repair_total", "at_rest_total") VALUES (1, E'\\367M\\177\\251]t/\\022\\256\\214\\265\\025\\224\\204:\\217\\212\\0102<\\321\\374\\020&\\271Qc\\325\\261\\354\\246\\233'::bytea, '2019-02-09 00:00:00+00', 1000, 2000, 3000, 4000, 0, 5000);
INSERT INTO "accounting_timestamps" VALUES ('LastAtRestTally', '0001-01-01 00:00:00+00');
INSERT INTO "accounting_timestamps" VALUES ('LastRollup', '0001-01-01 00:00:00+00');
INSERT INTO "accounting_timestamps" VALUES ('LastBandwidthTally', '0001-01-01 00:00:00+00');
INSERT INTO "nodes" VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', 0, 0, 0, 3, 3, 1, '2019-02-14 08:07:31.028103+00', '2019-02-14 08:07:31.108963+00', '', '');
INSERT INTO "overlay_cache_nodes" VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', 4, '127.0.0.1:55518', 0, 'bootstrap@example.com', '0x0000000000000000000000000000000000000000', -1, -1, 0, 0, 1, 0, 0, 2, 2);
INSERT INTO "projects"("id", "name", "description", "created_at") VALUES (E'\\022\\217/\\014\\376!K\\023\\276\\031\\311}m\\236\\205\\300'::bytea, 'ProjectName', 'projects description', '2019-02-14 08:28:24.254934+00');
INSERT INTO "api_keys"("id", "project_id", "key", "name", "created_at") VALUES (E'\\334/\\302;\\225\\355O\\323\\276f\\247\\354/6\\241\\033'::bytea, E'\\022\\217/\\014\\376!K\\023\\276\\031\\311}m\\236\\205\\300'::bytea, E'\\000]\\326N \\343\\270L\\327\\027\\337\\242\\240\\322mOl\\0318\\251.P I'::bytea, 'key 2', '2019-02-14 08:28:24.267934+00');
INSERT INTO "users"("id", "full_name", "short_name", "email", "password_hash", "status", "created_at") VALUES (E'\\363\\311\\033w\\222\\303Ci\\265\\343U\\303\\312\\204",'::bytea, 'Noahson', 'William', '1email1@ukr.net', E'some_readable_hash'::bytea, 1, '2019-02-14 08:28:24.614594+00');
INSERT INTO "projects"("id", "name", "description", "created_at") VALUES (E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea, 'projName1', 'Test project 1', '2019-02-14 08:28:24.636949+00');
INSERT INTO "project_members"("member_id", "project_id", "created_at") VALUES (E'\\363\\311\\033w\\222\\303Ci\\265\\343U\\303\\312\\204",'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014'::bytea, '2019-02-14 08:28:24.677953+00');
INSERT INTO "bwagreements"("serialnum", "storage_node_id", "action", "total", "created_at", "expires_at", "uplink_id") VALUES ('8fc0ceaa-984c-4d52-bcf4-b5429e1e35e812FpiifDbcJkePa12jxjDEutKrfLmwzT7sz2jfVwpYqgtM8B74c', E'\\245Z[/\\333\\022\\011\\001\\036\\003\\204\\005\\032.\\206\\333E\\261\\342\\227=y,}aRaH6\\240\\370\\000'::bytea, 1, 666, '2019-02-14 15:09:54.420181+00', '2019-02-14 16:09:54+00', E'\\253Z+\\374eFm\\245$\\036\\206\\335\\247\\263\\350x\\\\\\304+\\364\\343\\364+\\276fIJQ\\361\\014\\232\\000'::bytea);
INSERT INTO "irreparabledbs" ("segmentpath", "segmentdetail", "pieces_lost_count", "seg_damaged_unix_sec", "repair_attempt_count") VALUES ('\x49616d5365676d656e746b6579696e666f30', '\x49616d5365676d656e7464657461696c696e666f30', 10, 1550159554, 10);
INSERT INTO "injuredsegments" ("id", "info") VALUES (1, '\x0a0130120100');
INSERT INTO "certrecords" VALUES (E'0Y0\\023\\006\\007*\\206H\\316=\\002\\001\\006\\010*\\206H\\316=\\003\\001\\007\\003B\\000\\004\\360\\267\\227\\377\\253u\\222\\337Y\\324C:GQ\\010\\277v\\010\\315D\\271\\333\\337.\\203\\023=C\\343\\014T%6\\027\\362?\\214\\326\\017U\\334\\000\\260\\224\\260J\\221\\304\\331F\\304\\221\\236zF,\\325\\326l\\215\\306\\365\\200\\022', E'L\\301|\\200\\247}F|1\\320\\232\\037n\\335\\241\\206\\244\\242\\207\\204.\\253\\357\\326\\352\\033Dt\\202`\\022\\325', '2019-02-14 08:07:31.335028+00');
INSERT INTO "bucket_usages" ("id", "bucket_id", "rollup_end_time", "remote_stored_data", "inline_stored_data", "remote_segments", "inline_segments", "objects", "metadata_size", "repair_egress", "get_egress", "audit_egress") VALUES (E'\\153\\313\\233\\074\\327\\177\\136\\070\\346\\001",'::bytea, E'\\366\\146\\032\\321\\316\\161\\070\\133\\302\\271",'::bytea, '2019-03-06 08:28:24.677953+00', 10, 11, 12, 13, 14, 15, 16, 17, 18);
INSERT INTO "registration_tokens" ("secret", "owner_id", "project_limit", "created_at") VALUES (E'\\070\\127\\144\\013\\332\\344\\102\\376\\306\\056\\303\\130\\106\\132\\321\\276\\321\\274\\170\\264\\054\\333\\221\\116\\154\\221\\335\\070\\220\\146\\344\\216'::bytea, null, 1, '2019-02-14 08:28:24.677953+00');
INSERT INTO "serial_numbers" ("id", "serial_number", "bucket_id", "expires_at") VALUES (1, E'0123456701234567'::bytea, E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014/testbucket'::bytea, '2019-03-06 08:28:24.677953+00');
INSERT INTO "used_serials" ("serial_number_id", "storage_node_id") VALUES (1, E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n');
INSERT INTO "storagenode_bandwidth_rollups" ("storagenode_id", "interval_start", "interval_seconds", "action", "allocated", "settled") VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', '2019-03-06 08:00:00.000000+00', 3600, 1, 1024, 2024);
INSERT INTO "storagenode_storage_rollups" ("storagenode_id", "interval_start", "interval_seconds", "total") VALUES (E'\\006\\223\\250R\\221\\005\\365\\377v>0\\266\\365\\216\\255?\\347\\244\\371?2\\264\\262\\230\\007<\\001\\262\\263\\237\\247n', '2019-03-06 08:00:00.000000+00', 3600, 4024);
INSERT INTO "bucket_bandwidth_rollups" ("bucket_id", "interval_start", "interval_seconds", "action", "inline", "allocated", "settled") VALUES (E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014/testbucket'::bytea, '2019-03-06 08:00:00.000000+00', 3600, 1, 1024, 2024, 3024);
INSERT INTO "bucket_storage_rollups" ("bucket_id", "interval_start", "interval_seconds", "inline", "remote") VALUES (E'\\363\\342\\363\\371>+F\\256\\263\\300\\273|\\342N\\347\\014/testbucket'::bytea, '2019-03-06 08:00:00.000000+00', 3600, 4024, 5024);

View File

@ -48,10 +48,12 @@ func (users *users) Insert(ctx context.Context, user *console.User) (*console.Us
createdUser, err := users.db.Create_User(ctx,
dbx.User_Id(userID[:]),
dbx.User_FirstName(user.FirstName),
dbx.User_LastName(user.LastName),
dbx.User_FullName(user.FullName),
dbx.User_Email(user.Email),
dbx.User_PasswordHash(user.PasswordHash),
dbx.User_Create_Fields{
ShortName: dbx.User_ShortName(user.ShortName),
},
)
if err != nil {
@ -82,8 +84,8 @@ func (users *users) Update(ctx context.Context, user *console.User) error {
// toUpdateUser creates dbx.User_Update_Fields with only non-empty fields as updatable
func toUpdateUser(user *console.User) dbx.User_Update_Fields {
update := dbx.User_Update_Fields{
FirstName: dbx.User_FirstName(user.FirstName),
LastName: dbx.User_LastName(user.LastName),
FullName: dbx.User_FullName(user.FullName),
ShortName: dbx.User_ShortName(user.ShortName),
Email: dbx.User_Email(user.Email),
Status: dbx.User_Status(int(user.Status)),
}
@ -109,13 +111,16 @@ func userFromDBX(user *dbx.User) (*console.User, error) {
result := console.User{
ID: id,
FirstName: user.FirstName,
LastName: user.LastName,
FullName: user.FullName,
Email: user.Email,
PasswordHash: user.PasswordHash,
Status: console.UserStatus(user.Status),
CreatedAt: user.CreatedAt,
}
if user.ShortName != nil {
result.ShortName = *user.ShortName
}
return &result, nil
}

View File

@ -22,8 +22,8 @@ func TestUserFromDbx(t *testing.T) {
t.Run("can't create dbo from dbx model with invalid ID", func(t *testing.T) {
dbxUser := dbx.User{
Id: []byte("qweqwe"),
FirstName: "FirstName",
LastName: "LastName",
FullName: "Very long full name",
ShortName: nil,
Email: "some@email.com",
PasswordHash: []byte("ihqerfgnu238723huagsd"),
CreatedAt: time.Now(),

View File

@ -97,8 +97,8 @@ export async function fetchProjectMembersRequest(projectID: string, limit: strin
members(limit: ${limit}, offset: ${offset}, order: ${sortBy}, search: "${searchQuery}") {
user {
id,
firstName,
lastName,
fullName,
shortName,
email
},
joinedAt

View File

@ -11,8 +11,8 @@ export async function updateAccountRequest(user: User): Promise<RequestResponse<
errorMessage: '',
isSuccess: false,
data: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
}
};
@ -25,13 +25,13 @@ export async function updateAccountRequest(user: User): Promise<RequestResponse<
updateAccount (
input: {
email: "${user.email}",
firstName: "${user.firstName}",
lastName: "${user.lastName}"
fullName: "${user.fullName}",
shortName: "${user.shortName}"
}
) {
email,
firstName,
lastName
fullName,
shortName
}
}`
),
@ -109,8 +109,8 @@ export async function createUserRequest(user: User, password: string, secret: st
input:{
email: "${user.email}",
password: "${password}",
firstName: "${user.firstName}",
lastName: "${user.lastName}",
fullName: "${user.fullName}",
shortName: "${user.shortName}",
},
secret: "${secret}",
){email}
@ -178,8 +178,8 @@ export async function getUserRequest(): Promise<RequestResponse<User>> {
errorMessage: '',
isSuccess: false,
data: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
}
};
@ -190,8 +190,8 @@ export async function getUserRequest(): Promise<RequestResponse<User>> {
query: gql(`
query {
user {
firstName,
lastName,
fullName,
shortName,
email,
}
}`

View File

@ -17,21 +17,21 @@
</div>
<HeaderedInput
class="full-input"
label="First name"
placeholder ="Enter First Name"
label="Full name"
placeholder="Enter Full Name"
width="100%"
ref="firstNameInput"
:error="firstNameError"
:initValue="user.firstName"
@setData="setFirstName" />
ref="fullNameInput"
:error="fullNameError"
:initValue="user.fullName"
@setData="setFullName" />
<HeaderedInput
class="full-input"
label="Last Name"
placeholder="Enter Last Name"
label="Short Name"
placeholder="Enter Short Name"
width="100%"
ref="lastNameInput"
:initValue="user.lastName"
@setData="setLastName"/>
ref="shortNameInput"
:initValue="user.shortName"
@setData="setShortName"/>
<HeaderedInput
class="full-input"
label="Email"
@ -134,15 +134,15 @@ import { validateEmail, validatePassword } from '@/utils/validation';
{
data: function () {
return {
originalFirstName: this.$store.getters.user.firstName,
originalLastName: this.$store.getters.user.lastName,
originalFullName: this.$store.getters.user.fullName,
originalShortName: this.$store.getters.user.shortName,
originalEmail: this.$store.getters.user.email,
firstName: this.$store.getters.user.firstName,
lastName: this.$store.getters.user.lastName,
fullName: this.$store.getters.user.fullName,
shortName: this.$store.getters.user.shortName,
email: this.$store.getters.user.email,
firstNameError: '',
fullNameError: '',
emailError: '',
isAccountSettingsEditing: false,
@ -158,13 +158,13 @@ import { validateEmail, validatePassword } from '@/utils/validation';
};
},
methods: {
setFirstName: function (value: string) {
this.$data.firstName = value;
this.$data.firstNameError = '';
setFullName: function (value: string) {
this.$data.fullName = value;
this.$data.fullNameError = '';
this.$data.isAccountSettingsEditing = true;
},
setLastName: function (value: string) {
this.$data.lastName = value;
setShortName: function (value: string) {
this.$data.shortName = value;
this.$data.isAccountSettingsEditing = true;
},
setEmail: function (value: string) {
@ -173,17 +173,17 @@ import { validateEmail, validatePassword } from '@/utils/validation';
this.$data.isAccountSettingsEditing = true;
},
cancelAccountSettings: function () {
this.$data.firstName = this.$data.originalFirstName;
this.$data.firstNameError = '';
this.$data.lastName = this.$data.originalLastName;
this.$data.fullName = this.$data.originalFullName;
this.$data.fullNameError = '';
this.$data.shortName = this.$data.originalShortName;
this.$data.email = this.$data.originalEmail;
this.$data.emailError = '';
let firstNameInput: any = this.$refs['firstNameInput'];
firstNameInput.setValue(this.$data.originalFirstName);
let fullNameInput: any = this.$refs['fullNameInput'];
fullNameInput.setValue(this.$data.originalFullName);
let lastNameInput: any = this.$refs['lastNameInput'];
lastNameInput.setValue(this.$data.originalLastName);
let shortNameInput: any = this.$refs['shortNameInput'];
shortNameInput.setValue(this.$data.originalShortName);
let emailInput: any = this.$refs['emailInput'];
emailInput.setValue(this.$data.originalEmail);
@ -193,8 +193,8 @@ import { validateEmail, validatePassword } from '@/utils/validation';
onSaveAccountSettingsButtonClick: async function () {
let hasError = false;
if (!this.$data.firstName) {
this.$data.firstNameError = 'First name expected';
if (!this.$data.fullName) {
this.$data.fullNameError = 'Full name expected';
hasError = true;
}
@ -209,8 +209,8 @@ import { validateEmail, validatePassword } from '@/utils/validation';
let user = {
email: this.$data.email,
firstName: this.$data.firstName,
lastName: this.$data.lastName,
fullName: this.$data.fullName,
shortName: this.$data.shortName,
};
let response = await this.$store.dispatch(USER_ACTIONS.UPDATE, user);
@ -222,8 +222,8 @@ import { validateEmail, validatePassword } from '@/utils/validation';
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Account info successfully updated!');
this.$data.originalFirstName = this.$store.getters.user.firstName;
this.$data.originalLastName = this.$store.getters.user.lastName;
this.$data.originalFullName = this.$store.getters.user.fullName;
this.$data.originalShortName = this.$store.getters.user.shortName;
this.$data.originalEmail = this.$store.getters.user.email;
this.$data.isAccountSettingsEditing = false;
@ -331,8 +331,8 @@ import { validateEmail, validatePassword } from '@/utils/validation';
computed: {
user: function() {
return {
firstName: this.$store.getters.user.firstName,
lastName: this.$store.getters.user.lastName,
fullName: this.$store.getters.user.fullName,
shortName: this.$store.getters.user.shortName,
email: this.$store.getters.user.email,
};
},
@ -341,7 +341,6 @@ import { validateEmail, validatePassword } from '@/utils/validation';
return this.$store.getters.userName.slice(0, 1).toUpperCase();
},
isPopupShown: function (): boolean {
return this.$store.state.appStateModule.appState.isDeleteAccountPopupShown;
}
},

View File

@ -32,7 +32,7 @@ import { Component, Vue } from 'vue-property-decorator';
return name;
}
return name.slice(0,12) + '...';
return name.slice(0, 12) + '...';
}
}
}

View File

@ -22,12 +22,12 @@ import { getColor } from '@/utils/avatarColorManager';
},
computed: {
userInfo: function (): object {
let fullName: string = this.$props.projectMember.user.firstName + ' ' + this.$props.projectMember.user.lastName;
let fullName = getFullName(this.$props.projectMember.user);
let email: string = this.$props.projectMember.user.email;
if (fullName.length > 16) {
fullName = this.$props.projectMember.user.firstName.slice(0, 1).toUpperCase() +
'. ' + this.$props.projectMember.user.lastName.slice(0, 1).toUpperCase() + '.';
fullName = fullName.slice(0, 13) + '...';
}
if (email.length > 16) {
@ -37,7 +37,9 @@ import { getColor } from '@/utils/avatarColorManager';
return { fullName, email };
},
avatarData: function (): object {
const letter = this.$props.projectMember.user.firstName.slice(0, 1).toLocaleUpperCase();
let fullName = getFullName(this.$props.projectMember.user);
const letter = fullName.slice(0, 1).toLocaleUpperCase();
const style = {
background: getColor(letter)
@ -53,6 +55,10 @@ import { getColor } from '@/utils/avatarColorManager';
export default class TeamMemberItem extends Vue {
}
function getFullName(user: any): string {
return user.shortName === '' ? user.fullName : user.shortName;
}
</script>
<style scoped lang="scss">

View File

@ -12,8 +12,8 @@ import {
export const usersModule = {
state: {
user: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: ''
}
},
@ -24,8 +24,8 @@ export const usersModule = {
},
[USER_MUTATIONS.REVERT_TO_DEFAULT_USER_INFO](state: any): void {
state.user.firstName = '';
state.user.lastName = '';
state.user.fullName = '';
state.user.shortName = '';
state.user.email = '';
},
@ -35,8 +35,8 @@ export const usersModule = {
[USER_MUTATIONS.CLEAR](state: any): void {
state.user = {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: ''
};
},
@ -76,6 +76,6 @@ export const usersModule = {
user: (state: any) => {
return state.user;
},
userName: (state: any) => `${state.user.firstName} ${state.user.lastName}`
userName: (state: any) => state.user.shortName == '' ? state.user.fullName : state.user.shortName
},
};

View File

@ -2,8 +2,8 @@
// See LICENSE for copying information.
declare type User = {
firstName: string,
lastName: string,
fullName: string,
shortName: string,
email: string,
};

View File

@ -22,19 +22,19 @@
</div>
<HeaderlessInput
class="full-input"
label="First name"
placeholder="Enter First Name"
:error="firstNameError"
@setData="setFirstName"
label="Full name"
placeholder="Enter Full Name"
:error="fullNameError"
@setData="setFullName"
width="100%"
height="46px"
isWhite>
</HeaderlessInput>
<HeaderlessInput
class="full-input"
label="Last Name"
label="Short Name"
placeholder="Enter Short Name"
@setData="setLastName"
@setData="setShortName"
width="100%"
height="46px"
isWhite>
@ -113,9 +113,9 @@ import { createUserRequest } from '@/api/users';
{
data: function () {
return {
firstName: '',
firstNameError: '',
lastName: '',
fullName: '',
fullNameError: '',
shortName: '',
email: '',
emailError: '',
password: '',
@ -133,12 +133,12 @@ import { createUserRequest } from '@/api/users';
this.$data.email = value;
this.$data.emailError = '';
},
setFirstName: function (value: string): void {
this.$data.firstName = value;
this.$data.firstNameError = '';
setFullName: function (value: string): void {
this.$data.fullName = value;
this.$data.fullNameError = '';
},
setLastName: function (value: string): void {
this.$data.lastName = value;
setShortName: function (value: string): void {
this.$data.shortName = value;
},
setPassword: function (value: string): void {
this.$data.password = value;
@ -150,8 +150,8 @@ import { createUserRequest } from '@/api/users';
},
validateFields: function (): boolean {
let isNoErrors = true;
if (!this.$data.firstName.trim()) {
this.$data.firstNameError = 'Invalid First Name';
if (!this.$data.fullName.trim()) {
this.$data.fullNameError = 'Invalid Name';
isNoErrors = false;
}
@ -180,8 +180,8 @@ import { createUserRequest } from '@/api/users';
createUser: async function(): Promise<any> {
let user = {
email: this.$data.email.trim(),
firstName: this.$data.firstName.trim(),
lastName: this.$data.lastName.trim(),
fullName: this.$data.fullName.trim(),
shortName: this.$data.shortName.trim(),
};
let response = await createUserRequest(user, this.$data.password, this.$data.secret);

View File

@ -17,8 +17,8 @@ describe('mutations', () => {
it('Set user info', () => {
const state = {
user: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
}
};
@ -26,23 +26,23 @@ describe('mutations', () => {
const store = new Vuex.Store({state, mutations});
const user = {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
};
store.commit(USER_MUTATIONS.SET_USER_INFO, user);
expect(state.user.email).toBe('email');
expect(state.user.firstName).toBe('firstName');
expect(state.user.lastName).toBe('lastName');
expect(state.user.fullName).toBe('fullName');
expect(state.user.shortName).toBe('shortName');
});
it('clear user info', () => {
const state = {
user: {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
}
};
@ -52,21 +52,21 @@ describe('mutations', () => {
store.commit(USER_MUTATIONS.REVERT_TO_DEFAULT_USER_INFO);
expect(state.user.email).toBe('');
expect(state.user.firstName).toBe('');
expect(state.user.lastName).toBe('');
expect(state.user.fullName).toBe('');
expect(state.user.shortName).toBe('');
});
it('Update user info', () => {
const state = {
user: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
}
};
const user = {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
};
@ -75,8 +75,8 @@ describe('mutations', () => {
store.commit(USER_MUTATIONS.UPDATE_USER_INFO, user);
expect(state.user.email).toBe('email');
expect(state.user.firstName).toBe('firstName');
expect(state.user.lastName).toBe('lastName');
expect(state.user.fullName).toBe('fullName');
expect(state.user.shortName).toBe('shortName');
});
});
@ -88,16 +88,16 @@ describe('actions', () => {
jest.spyOn(api, 'updateAccountRequest').mockReturnValue(
Promise.resolve(<RequestResponse<User>>{
isSuccess: true, data: {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
}
})
);
const commit = jest.fn();
const user = {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
};
@ -105,8 +105,8 @@ describe('actions', () => {
expect(dispatchResponse.isSuccess).toBeTruthy();
expect(commit).toHaveBeenCalledWith(USER_MUTATIONS.UPDATE_USER_INFO, {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
});
});
@ -119,8 +119,8 @@ describe('actions', () => {
);
const commit = jest.fn();
const user = {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
};
@ -164,8 +164,8 @@ describe('actions', () => {
Promise.resolve(<RequestResponse<User>>{
isSuccess: true,
data: {
firstName: '',
lastName: '',
fullName: '',
shortName: '',
email: '',
}
})
@ -195,24 +195,24 @@ describe('getters', () => {
it('user model', function () {
const state = {
user: {
firstName: 'firstName',
lastName: 'lastName',
fullName: 'fullName',
shortName: 'shortName',
email: 'email',
}
};
const retrievedUser = usersModule.getters.user(state);
expect(retrievedUser.firstName).toBe('firstName');
expect(retrievedUser.lastName).toBe('lastName');
expect(retrievedUser.fullName).toBe('fullName');
expect(retrievedUser.shortName).toBe('shortName');
expect(retrievedUser.email).toBe('email');
});
it('user name', function () {
const state = {
user: {
firstName: 'John',
lastName: 'Doe'
fullName: 'John',
shortName: 'Doe'
}
};