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
-[](https://drone.devices.local/mawas/golang-api-skeleton)
+[](https://drone.devices.local/mawas/golang-api-skeleton)
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)