From 0f7787d546984ecb7f85d79a339bf915eac57d3a Mon Sep 17 00:00:00 2001 From: James Tombleson Date: Sat, 23 Mar 2024 08:27:35 -0700 Subject: [PATCH] trying to create some separation between sql and user tasks. This might be too close to c# for go --- api/repositories/users.go | 24 ++++++++++++++--- api/repositories/users_test.go | 24 ++++++++++++++--- api/services/users.go | 43 +++++++++++++++++++++++++++++++ api/services/users_test.go | 47 ++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 api/services/users.go create mode 100644 api/services/users_test.go diff --git a/api/repositories/users.go b/api/repositories/users.go index 8d52e30..e5ba982 100644 --- a/api/repositories/users.go +++ b/api/repositories/users.go @@ -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, }) } diff --git a/api/repositories/users_test.go b/api/repositories/users_test.go index c86cd89..283ca75 100644 --- a/api/repositories/users_test.go +++ b/api/repositories/users_test.go @@ -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") +} \ No newline at end of file diff --git a/api/services/users.go b/api/services/users.go new file mode 100644 index 0000000..bb2d355 --- /dev/null +++ b/api/services/users.go @@ -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 +} diff --git a/api/services/users_test.go b/api/services/users_test.go new file mode 100644 index 0000000..f5cf16f --- /dev/null +++ b/api/services/users_test.go @@ -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() + } +}