diff --git a/README.md b/README.md
index 9e55ca6..ff1c22c 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/user.go b/repositories/user.go
index 81b935a..f8ca52b 100644
--- a/repositories/user.go
+++ b/repositories/user.go
@@ -25,9 +25,7 @@ func NewUserRepository(db *gorm.DB, userID string, username string, cache cache.
func (dao *UserDAO) ReadByUsername(username string) (*model.User, error) {
result := model.User{}
- // err := dao.db.Joins("TokensRef").Where(&model.User{Username: username}).First(&result).Error
err := dao.db.Preload("TokensRef").Where(&model.User{Username: username}).First(&result).Error
- // err := dao.db.Where(&model.User{Username: username}).First(&result).Error
return &result, err
}
diff --git a/repositories/user_test.go b/repositories/user_test.go
new file mode 100644
index 0000000..13702d2
--- /dev/null
+++ b/repositories/user_test.go
@@ -0,0 +1,138 @@
+package repositories
+
+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"
+ "gorm.io/driver/sqlite"
+ "gorm.io/gorm"
+)
+
+const username = "unittest"
+
+func usermock(t *testing.T) (*gorm.DB, cache.Cache, models.User) {
+ 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)
+ }
+ user := models.User{
+ Username: username,
+ Firstname: "Unit",
+ Lastname: "Test",
+ Email: "unittest@unittest.test",
+ Active: true,
+ }
+ user.ID = userID
+ return db, appCache, user
+}
+
+func validateResponse(t *testing.T, response *models.User, user models.User) {
+ if response.Username != user.Username {
+ t.Errorf("User Username must be \"%s\" but is \"%s\"\n", user.Username, response.Username)
+ }
+ if response.Firstname != user.Firstname {
+ t.Errorf("User Firstname must be \"%s\" but is \"%s\"\n", user.Firstname, response.Firstname)
+ }
+ if response.Lastname != user.Lastname {
+ t.Errorf("User Lastname must be \"%s\" but is \"%s\"\n", user.Lastname, response.Lastname)
+ }
+ if response.Email != user.Email {
+ t.Errorf("User Email must be \"%s\" but is \"%s\"\n", user.Email, response.Email)
+ }
+ if !response.Active {
+ t.Error("User active must be true")
+ }
+ if len(response.TokensRef) > 0 {
+ t.Error("User TokensRef must be empty")
+ }
+ if len(response.Tokens) > 0 {
+ t.Error("User Tokens must be empty")
+ }
+ 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["id"]; exists {
+ t.Error("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 _, 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")
+ }
+}
+
+func TestUserRepository(t *testing.T) {
+ db, appCache, user := usermock(t)
+ userDAO := NewUserRepository(db, user.ID.String(), username, appCache)
+ response, err := userDAO.Create(&user)
+ if err != nil {
+ t.Errorf("userDAO Create failed with error: %v\n", err)
+ }
+ validateResponse(t, response, user)
+ response, err = userDAO.ReadByUsername(username)
+ if err != nil {
+ t.Errorf("userDAO ReadByUsername failed with error: %v\n", err)
+ }
+ validateResponse(t, response, user)
+ responses, err := userDAO.ReadAll()
+ if err != nil {
+ t.Errorf("userDAO ReadAll failed with error: %v\n", err)
+ }
+ if len(responses) != 1 {
+ t.Error("userDAO ReadAll failed with worng numer of responses")
+ }
+ validateResponse(t, responses[0], user)
+}