adds create user func
This commit is contained in:
parent
c8e33884c0
commit
f59593e9e8
1
go.mod
1
go.mod
@ -10,4 +10,5 @@ require (
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.5.1
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899
|
||||
)
|
||||
|
@ -40,6 +40,10 @@ func (e *errorStore) SelectUserByID(id int) (*models.User, error) {
|
||||
return nil, e.error
|
||||
}
|
||||
|
||||
func (e *errorStore) InsertUser(user *models.User) (int, error) {
|
||||
return 0, e.error
|
||||
}
|
||||
|
||||
func (e *errorStore) ConnectionLive() error {
|
||||
return e.error
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ type Store interface {
|
||||
InsertPlan(plan *Plan) (int, error)
|
||||
SelectActionsByPlanID(plan *Plan) ([]*Action, error)
|
||||
SelectUserByID(id int) (*User, error)
|
||||
InsertUser(user *User) (int, error)
|
||||
}
|
||||
|
||||
// Model represents a current model item.
|
||||
|
@ -47,6 +47,10 @@ func (ms *multiStore) SelectUserByID(id int) (*models.User, error) {
|
||||
return &models.User{UserID: int64(id), Username: "test", DisplayName: "Ted Est", Password: []byte("oh no")}, nil
|
||||
}
|
||||
|
||||
func (ms *multiStore) InsertUser(user *models.User) (int, error) {
|
||||
return int(user.UserID), nil
|
||||
}
|
||||
|
||||
func (ms *multiStore) ConnectionLive() error {
|
||||
return nil
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// User represents the full DB user field, for inserts and compares.
|
||||
// No reason to return the hashed pw on the route though.
|
||||
type User struct {
|
||||
@ -34,3 +39,38 @@ func (u *User) NoPassword() *UserNoPassword {
|
||||
DisplayName: u.DisplayName,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateUserRequest represents a desired user creation.
|
||||
type CreateUserRequest struct {
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// CreateUser takes in a create user request and returns the ID of the newly created user.
|
||||
func (m *Model) CreateUser(req *CreateUserRequest) (int, error) {
|
||||
if req.Username == "" {
|
||||
return -1, fmt.Errorf("No username provided")
|
||||
}
|
||||
if req.Password == "" {
|
||||
return -1, fmt.Errorf("No password provided")
|
||||
}
|
||||
hash, err := hashPassword(req.Password)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
desiredUser := &User{
|
||||
Username: req.Username,
|
||||
DisplayName: req.DisplayName,
|
||||
Password: hash,
|
||||
}
|
||||
|
||||
return m.InsertUser(desiredUser)
|
||||
}
|
||||
|
||||
// hashPassword hashes a password
|
||||
func hashPassword(password string) ([]byte, error) {
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 11)
|
||||
return bytes, err
|
||||
}
|
||||
|
@ -31,16 +31,49 @@ func TestErrorUsers(t *testing.T) {
|
||||
assert.NotNil(err)
|
||||
}
|
||||
|
||||
func TestUserNoPassword(t *testing.T) {
|
||||
func TestCreateUser(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
id := int64(3)
|
||||
username := "test"
|
||||
displayName := "Ted Est"
|
||||
pass := []byte("abc")
|
||||
u := &models.User{UserID: id, Username: username, DisplayName: displayName, Password: pass}
|
||||
pass := "abc"
|
||||
u := &models.CreateUserRequest{Username: username, DisplayName: displayName, Password: pass}
|
||||
|
||||
unp := u.NoPassword()
|
||||
assert.EqualValues(id, unp.UserID)
|
||||
assert.Equal(username, unp.Username)
|
||||
assert.Equal(displayName, unp.DisplayName)
|
||||
ss := &multiStore{
|
||||
[]*models.Action{},
|
||||
[]*models.Plan{}}
|
||||
m := models.New(ss)
|
||||
|
||||
_, err := m.CreateUser(u)
|
||||
assert.Nil(err)
|
||||
}
|
||||
func TestCreateUserFailValidation(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
username := ""
|
||||
displayName := "Ted Est"
|
||||
pass := "abc"
|
||||
u := &models.CreateUserRequest{Username: username, DisplayName: displayName, Password: pass}
|
||||
|
||||
ss := &multiStore{
|
||||
[]*models.Action{},
|
||||
[]*models.Plan{}}
|
||||
m := models.New(ss)
|
||||
|
||||
_, err := m.CreateUser(u)
|
||||
assert.NotNil(err)
|
||||
}
|
||||
|
||||
func TestCreateUserFailValidationPassword(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
username := "aoeu"
|
||||
displayName := "Ted Est"
|
||||
pass := ""
|
||||
u := &models.CreateUserRequest{Username: username, DisplayName: displayName, Password: pass}
|
||||
|
||||
ss := &multiStore{
|
||||
[]*models.Action{},
|
||||
[]*models.Plan{}}
|
||||
m := models.New(ss)
|
||||
|
||||
_, err := m.CreateUser(u)
|
||||
assert.NotNil(err)
|
||||
}
|
||||
|
@ -62,6 +62,10 @@ func (ms *multiStore) SelectUserByID(id int) (*models.User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (ms *multiStore) InsertUser(user *models.User) (int, error) {
|
||||
return int(user.UserID), nil
|
||||
}
|
||||
|
||||
func (ms *multiStore) ConnectionLive() error {
|
||||
return nil
|
||||
}
|
||||
@ -119,6 +123,10 @@ func (e *errorStore) SelectUserByID(id int) (*models.User, error) {
|
||||
return nil, e.error
|
||||
}
|
||||
|
||||
func (e *errorStore) InsertUser(user *models.User) (int, error) {
|
||||
return 0, e.error
|
||||
}
|
||||
|
||||
func (e *errorStore) ConnectionLive() error {
|
||||
return e.error
|
||||
}
|
||||
@ -168,6 +176,10 @@ func (e *onlyCreateStore) SelectUserByID(id int) (*models.User, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (e *onlyCreateStore) InsertUser(user *models.User) (int, error) {
|
||||
return 0, e.error
|
||||
}
|
||||
|
||||
func (e *onlyCreateStore) ConnectionLive() error {
|
||||
return e.error
|
||||
}
|
||||
|
@ -143,3 +143,19 @@ func (store *postgresStore) SelectUserByID(id int) (*models.User, error) {
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (store *postgresStore) InsertUser(user *models.User) (int, error) {
|
||||
queryString := store.db.Rebind("INSERT INTO users (username, display_name, password) VALUES (?, ?, ?) RETURNING user_id")
|
||||
tx := store.db.MustBegin()
|
||||
var id int
|
||||
err := tx.Get(&id, queryString, user.Username, user.DisplayName, user.Password)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
return -1, err
|
||||
}
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package store_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gitea.deepak.science/deepak/gogmagog/models"
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
@ -62,3 +63,90 @@ func TestErrUserByID(t *testing.T) {
|
||||
t.Errorf("unfulfilled expectations: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInsertUser(t *testing.T) {
|
||||
// setup
|
||||
assert := assert.New(t)
|
||||
|
||||
str, mock := getDbMock(t)
|
||||
username := "test"
|
||||
displayName := "Tom Est"
|
||||
password := []byte("ABC€")
|
||||
usr := &models.User{Username: username, DisplayName: displayName, Password: password}
|
||||
|
||||
idToUse := 8
|
||||
|
||||
rows := sqlmock.NewRows([]string{"user_id"}).AddRow(8)
|
||||
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`^INSERT INTO users \(username, display_name, password\) VALUES \(\$1, \$2, \$3\) RETURNING user_id$`).
|
||||
WithArgs(username, displayName, password).
|
||||
WillReturnRows(rows)
|
||||
mock.ExpectCommit()
|
||||
|
||||
// function under test
|
||||
insertedId, err := str.InsertUser(usr)
|
||||
// check results
|
||||
assert.Nil(err)
|
||||
assert.EqualValues(idToUse, insertedId)
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Errorf("unfulfilled expectations: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestInsertUserErr(t *testing.T) {
|
||||
// setup
|
||||
assert := assert.New(t)
|
||||
|
||||
str, mock := getDbMock(t)
|
||||
username := "test"
|
||||
displayName := "Tom Est"
|
||||
password := []byte("ABC€")
|
||||
usr := &models.User{Username: username, DisplayName: displayName, Password: password}
|
||||
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`^INSERT INTO users \(username, display_name, password\) VALUES \(\$1, \$2, \$3\) RETURNING user_id$`).
|
||||
WithArgs(username, displayName, password).
|
||||
WillReturnError(fmt.Errorf("example error"))
|
||||
mock.ExpectRollback()
|
||||
|
||||
// function under test
|
||||
_, err := str.InsertUser(usr)
|
||||
// check results
|
||||
assert.NotNil(err)
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Errorf("unfulfilled expectations: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestInsertUserCommitErr(t *testing.T) {
|
||||
// setup
|
||||
assert := assert.New(t)
|
||||
|
||||
str, mock := getDbMock(t)
|
||||
username := "test"
|
||||
displayName := "Tom Est"
|
||||
password := []byte("ABC€")
|
||||
usr := &models.User{Username: username, DisplayName: displayName, Password: password}
|
||||
|
||||
idToUse := 8
|
||||
|
||||
rows := sqlmock.NewRows([]string{"user_id"}).AddRow(idToUse)
|
||||
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`^INSERT INTO users \(username, display_name, password\) VALUES \(\$1, \$2, \$3\) RETURNING user_id$`).
|
||||
WithArgs(username, displayName, password).
|
||||
WillReturnRows(rows)
|
||||
mock.ExpectCommit().WillReturnError(fmt.Errorf("another error example"))
|
||||
|
||||
// function under test
|
||||
_, err := str.InsertUser(usr)
|
||||
// check results
|
||||
assert.NotNil(err)
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Errorf("unfulfilled expectations: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user