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" "gorm.io/driver/sqlite" "gorm.io/gorm" ) const username = "unittest" func userServiceMock(t *testing.T) (models.User, *UserService) { 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 := NewUser(username, "Unit", "Test", "unittest@unittest.test") user.ID = userID userRepository := repositories.NewUserRepository(db, user.ID.String(), username, appCache) return user, NewUserService(userRepository) } func validateUserResponse(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) { user, userService := userServiceMock(t) if response, err := userService.Create([]*models.User{&user}); err != nil { t.Errorf("userService Create failed with error: %v\n", err) } else { if len(response) != 1 { t.Error("userService Create response must be a list with 1 result in this test") } else { validateUserResponse(t, response[0], user) } } if response, err := userService.ReadByID(username); err != nil { t.Errorf("userService ReadByID failed with error: %v\n", err) } else { validateUserResponse(t, response, user) } { response, err := userService.ReadAll() switch { case err != nil: t.Errorf("userService ReadAll failed with error: %v\n", err) case len(response) != 1: t.Error("userService ReadAll failed with worng numer of responses") default: validateUserResponse(t, response[0], user) } } }