trying to create some separation between sql and user tasks. This might be too close to c# for go

This commit is contained in:
James Tombleson 2024-03-23 08:27:35 -07:00
parent b5791cd64e
commit 0f7787d546
4 changed files with 131 additions and 7 deletions

View File

@ -10,6 +10,10 @@ import (
"golang.org/x/crypto/bcrypt"
)
const (
TableName string = "users"
)
// Creates a new instance of UserRepository with the bound sql
func NewUserRepository(conn *sql.DB) UserRepository {
return UserRepository{
@ -58,6 +62,18 @@ func (ur UserRepository) NewUser(name, password string) (int64, error) {
return 1, nil
}
func (ur UserRepository) UpdatePassword(name, password string) error {
_, err := ur.GetByName(name)
if err != nil {
return nil
}
queryBuilder := sqlbuilder.NewUpdateBuilder()
queryBuilder.Update(TableName)
//queryBuilder.Set
return nil
}
// If the hash matches what we have in the database, an error will not be returned.
// If the user does not exist or the hash does not match, an error will be returned
func (ur UserRepository) CheckUserHash(name, password string) error {
@ -89,10 +105,10 @@ func (ur UserRepository) processRows(rows *sql.Rows) []models.UserModel {
}
items = append(items, models.UserModel{
Id: id,
Name: name,
Hash: hash,
CreatedAt: createdAt,
Id: id,
Name: name,
Hash: hash,
CreatedAt: createdAt,
LastUpdated: lastUpdated,
})
}

View File

@ -6,11 +6,13 @@ import (
"log"
"testing"
"github.com/DATA-DOG/go-sqlmock"
_ "github.com/glebarez/go-sqlite"
)
func TestCanCreateNewUser(t *testing.T) {
db, err := sql.Open("sqlite", "../../gocook.db")
db, _, err := sqlmock.New()
//db, err := sql.Open("sqlite", "../../gocook.db")
if err != nil {
log.Println("unable to open connection")
t.FailNow()
@ -35,6 +37,22 @@ func TestCanFindUserInTable(t *testing.T) {
defer db.Close()
repo := repositories.NewUserRepository(db)
repo.GetByName("testing")
user, err := repo.GetByName("testing")
if err != nil {
log.Println(err)
t.FailNow()
}
log.Println(user)
}
func TestCheckUserHash (t *testing.T) {
db, err := sql.Open("sqlite", "../../gocook.db")
if err != nil {
log.Println("unable to open connection")
t.FailNow()
}
defer db.Close()
repo := repositories.NewUserRepository(db)
repo.CheckUserHash("testing", "NotSecure")
}

43
api/services/users.go Normal file
View File

@ -0,0 +1,43 @@
package services
import (
"database/sql"
"errors"
"go-cook/api/models"
"go-cook/api/repositories"
)
const (
ErrPasswordNotLongEnough = "password needs to be 8 character or longer"
)
// This will handle operations that are user related, but one layer higher then the repository
type UserService struct {
repo repositories.UserRepository
}
func NewUserService(conn *sql.DB) UserService {
return UserService{
repo: repositories.NewUserRepository(conn),
}
}
func (us UserService) DoesUserExist(username string) error {
_, err := us.repo.GetByName(username)
if err != nil {
return err
}
return nil
}
func (us UserService) CreateNewUser(name, password string) (models.UserModel, error) {
us.repo.NewUser(name, password)
return models.UserModel{}, nil
}
func (us UserService) CheckPasswordForRequirements(password string) error {
if len(password) <= 8 {
return errors.New(ErrPasswordNotLongEnough)
}
return nil
}

View File

@ -0,0 +1,47 @@
package services_test
import (
"go-cook/api/services"
"testing"
"github.com/DATA-DOG/go-sqlmock"
)
func TestPasswordIsLongEnough(t *testing.T) {
db, _, err := sqlmock.New()
if err != nil {
t.Log(err.Error())
t.FailNow()
}
defer db.Close()
client := services.NewUserService(db)
err = client.CheckPasswordForRequirements("IsThisLongEnough")
if err != nil {
t.Logf(err.Error())
t.FailNow()
}
}
func TestPasswordIsToShort(t *testing.T){
db, _, err := sqlmock.New()
if err != nil {
t.Log(err.Error())
t.FailNow()
}
defer db.Close()
client := services.NewUserService(db)
err = client.CheckPasswordForRequirements("short")
if err != nil {
msg := err.Error()
if (msg != services.ErrPasswordNotLongEnough) {
t.Log("wrong error")
t.FailNow()
}
} else {
t.Logf("expected a err")
t.FailNow()
}
}