From edf57b8100dd7c0f4ed222d308b81dbcd3fdf2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernd-Ren=C3=A9=20Predota?= Date: Tue, 18 May 2021 15:41:55 +0200 Subject: [PATCH] services token unit test added --- README.md | 2 +- repositories/token.go | 6 +- repositories/token_test.go | 7 +- repositories/user_test.go | 7 +- services/token.go | 8 +++ services/token_test.go | 141 +++++++++++++++++++++++++++++++++++++ services/user.go | 3 +- services/user_test.go | 1 - 8 files changed, 161 insertions(+), 14 deletions(-) create mode 100644 services/token_test.go diff --git a/README.md b/README.md index 40457dd..53c9296 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # golang API Skeleton -[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-79%25-brightgreen.svg?longCache=true&style=flat) +[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-80%25-brightgreen.svg?longCache=true&style=flat) refined skeleton future apis should be based on diff --git a/repositories/token.go b/repositories/token.go index a0d37f9..2203190 100644 --- a/repositories/token.go +++ b/repositories/token.go @@ -39,9 +39,9 @@ func (dao *TokenDAO) ReadAll() ([]*model.Token, error) { func (dao *TokenDAO) Create(token *model.Token) (*model.Token, error) { err := dao.db.Create(token).Error - if cc, ok := dao.db.Get("cache"); ok { - if c, ok := cc.(cache.Cache); ok { - username, err := c.Get("user:" + token.UserID.String()) + if c, ok := dao.db.Get("cache"); ok { + if appCache, ok := c.(cache.Cache); ok { + username, err := appCache.Get("user:" + token.UserID.String()) if err != nil { return nil, err } diff --git a/repositories/token_test.go b/repositories/token_test.go index a6b2da9..a0b38eb 100644 --- a/repositories/token_test.go +++ b/repositories/token_test.go @@ -13,7 +13,7 @@ import ( "gorm.io/gorm" ) -func tokenmock(t *testing.T) (*gorm.DB, cache.Cache, models.Token) { +func tokenmock(t *testing.T) (models.Token, *TokenDAO) { db, err := gorm.Open( sqlite.Open(":memory:"), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}, @@ -58,7 +58,7 @@ func tokenmock(t *testing.T) (*gorm.DB, cache.Cache, models.Token) { Active: true, } token.UserID = userID - return db, appCache, token + return token, NewTokenRepository(db, token.UserID.String(), username, appCache) } func validateResponse(t *testing.T, response *models.Token, token models.Token) { @@ -119,8 +119,7 @@ func validateResponse(t *testing.T, response *models.Token, token models.Token) } func TestTokenRepository(t *testing.T) { - db, appCache, token := tokenmock(t) - tokenDAO := NewTokenRepository(db, token.UserID.String(), username, appCache) + token, tokenDAO := tokenmock(t) response, err := tokenDAO.Create(&token) if err != nil { t.Errorf("tokenDAO Create failed with error: %v\n", err) diff --git a/repositories/user_test.go b/repositories/user_test.go index a148c3d..e48e701 100644 --- a/repositories/user_test.go +++ b/repositories/user_test.go @@ -14,7 +14,7 @@ import ( const username = "unittest" -func usermock(t *testing.T) (*gorm.DB, cache.Cache, models.User) { +func userRepositoryMock(t *testing.T) (models.User, *UserDAO) { db, err := gorm.Open( sqlite.Open(":memory:"), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}, @@ -50,7 +50,7 @@ func usermock(t *testing.T) (*gorm.DB, cache.Cache, models.User) { Active: true, } user.ID = userID - return db, appCache, user + return user, NewUserRepository(db, user.ID.String(), username, appCache) } func validateUserResponse(t *testing.T, response *models.User, user models.User) { @@ -115,8 +115,7 @@ func validateUserResponse(t *testing.T, response *models.User, user models.User) } func TestUserRepository(t *testing.T) { - db, appCache, user := usermock(t) - userDAO := NewUserRepository(db, user.ID.String(), username, appCache) + user, userDAO := userRepositoryMock(t) response, err := userDAO.Create(&user) if err != nil { t.Errorf("userDAO Create failed with error: %v\n", err) diff --git a/services/token.go b/services/token.go index 8a7a551..a65f20f 100644 --- a/services/token.go +++ b/services/token.go @@ -33,3 +33,11 @@ func (s *TokenService) ReadAll() ([]*model.Token, error) { func (s *TokenService) Create(token *model.Token) (*model.Token, error) { return s.repo.Create(token) } + +// NewToken returns a new created Token object +func NewToken(username string) model.Token { + return model.Token{ + Username: username, + Active: true, + } +} diff --git a/services/token_test.go b/services/token_test.go new file mode 100644 index 0000000..dfafa0c --- /dev/null +++ b/services/token_test.go @@ -0,0 +1,141 @@ +package services + +import ( + "encoding/json" + "testing" + "time" + + "git.devices.local/mawas/golang-api-skeleton/lib/cache" + "git.devices.local/mawas/golang-api-skeleton/lib/common" + "git.devices.local/mawas/golang-api-skeleton/models" + "git.devices.local/mawas/golang-api-skeleton/repositories" + "github.com/oklog/ulid" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +func tokenServiceMock(t *testing.T) (models.Token, *TokenService) { + db, err := gorm.Open( + sqlite.Open(":memory:"), + &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}, + ) + if err != nil { + t.Error(err) + } + if err := db.AutoMigrate(&models.User{}); err != nil { + t.Error(err) + } + if err := db.AutoMigrate(&models.Token{}); err != nil { + t.Error(err) + } + appCache, err := cache.Bootstrap() + if err != nil { + t.Error(err) + } + userID, err := common.NewGUID() + if err != nil { + t.Error(err) + } + if err := appCache.Set("user:"+userID.String(), username); err != nil { + t.Error(err) + } + if err := appCache.Set("user:"+username, userID.String()); err != nil { + t.Error(err) + } + userRepository := repositories.NewUserRepository(db, userID.String(), username, appCache) + userService := NewUserService(userRepository) + _, err = userService.Create(&models.User{ + ModelHiddenGUIDPK: common.ModelHiddenGUIDPK{ID: userID}, + Username: username, + Firstname: "Unit", + Lastname: "Test", + Email: "unittest@unittest.test", + Active: true, + }) + if err != nil { + t.Error(err) + } + token := NewToken(username) + token.UserID = userID + tokenRepository := repositories.NewTokenRepository(db, token.UserID.String(), username, appCache) + return token, NewTokenService(tokenRepository) +} + +func validateResponse(t *testing.T, response *models.Token, token models.Token) { + if response.Username != token.Username { + t.Errorf("Token Username must be \"%s\" but is \"%s\"\n", token.Username, response.Username) + } + if !response.Active { + t.Error("Token Active must be true") + } + if _, err := ulid.Parse(response.Token.String()); err != nil { + t.Errorf("Token Token must be a valid ULID, %v\n", err) + } + jsonString, err := json.Marshal(response) + if err != nil { + t.Error(err) + } + var j map[string]interface{} + if err := json.Unmarshal([]byte(jsonString), &j); err != nil { + t.Error(err) + } + if _, exists := j["user_id"]; exists { + t.Error("Token user_id must be hidden in json") + } + if u, exists := j["created_by"]; !exists { + t.Error("User created_by not in json") + } else if u != username { + t.Errorf("User created_by must be \"%s\" but is \"%s\"\n", username, u) + } + if u, exists := j["updated_by"]; !exists { + t.Error("User updated_by not in json") + } else if u != username { + t.Errorf("User updated_by must be \"%s\" but is \"%s\"\n", username, u) + } + if datetime, exists := j["created_at"]; !exists { + t.Error("User created_at not in json") + } else if _, err := time.Parse(time.RFC3339, datetime.(string)); err != nil { + t.Errorf("User created_at must be a valid rfc 3339 date time in json, but is \"%s\"", datetime) + } + if datetime, exists := j["updated_at"]; !exists { + t.Error("User updated_at not in json") + } else if _, err := time.Parse(time.RFC3339, datetime.(string)); err != nil { + t.Errorf("User updated_at must be a valid rfc 3339 date time in json, but is \"%s\"", datetime) + } + if datetime, exists := j["expires_at"]; !exists { + t.Error("User expires_at not in json") + } else if _, err := time.Parse(time.RFC3339, datetime.(string)); err != nil { + t.Errorf("User expires_at must be a valid rfc 3339 date time in json, but is \"%s\"", datetime) + } + if _, exists := j["deleted_by"]; exists { + t.Error("User deleted_by mustn't be set in json") + } + if _, exists := j["deleted_at"]; exists { + t.Error("User deleted_by mustn't be set in json") + } + if _, exists := j["last_used"]; exists { + t.Error("User deleted_by mustn't be set in json") + } +} + +func TestTokenRepository(t *testing.T) { + token, tokenService := tokenServiceMock(t) + response, err := tokenService.Create(&token) + if err != nil { + t.Errorf("tokenService Create failed with error: %v\n", err) + } + validateResponse(t, response, token) + response, err = tokenService.ReadByKey(token.Token.String()) + if err != nil { + t.Errorf("tokenService ReadByKey failed with error: %v\n", err) + } + validateResponse(t, response, token) + responses, err := tokenService.ReadAll() + if err != nil { + t.Errorf("tokenService ReadAll failed with error: %v\n", err) + } + if len(responses) != 1 { + t.Error("tokenService ReadAll failed with worng numer of responses") + } + validateResponse(t, responses[0], token) +} diff --git a/services/user.go b/services/user.go index fcb15bf..edd25f2 100644 --- a/services/user.go +++ b/services/user.go @@ -34,7 +34,7 @@ func (s *UserService) Create(user *model.User) (*model.User, error) { return s.repo.Create(user) } -// NewUser returns a new created user object +// NewUser returns a new created User object func NewUser(username, firstname, lastname, email string) model.User { return model.User{ Username: username, @@ -42,5 +42,6 @@ func NewUser(username, firstname, lastname, email string) model.User { Lastname: lastname, Email: email, PasswordHash: "generate_password_here", + Active: true, } } diff --git a/services/user_test.go b/services/user_test.go index aa06685..5aef930 100644 --- a/services/user_test.go +++ b/services/user_test.go @@ -44,7 +44,6 @@ func userServiceMock(t *testing.T) (models.User, *UserService) { t.Error(err) } user := NewUser(username, "Unit", "Test", "unittest@unittest.test") - user.Active = true user.ID = userID userRepository := repositories.NewUserRepository(db, user.ID.String(), username, appCache) return user, NewUserService(userRepository)