1227 lines
43 KiB
Go
1227 lines
43 KiB
Go
package controllers
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"GoMembership/internal/config"
|
|
"GoMembership/internal/constants"
|
|
"GoMembership/internal/middlewares"
|
|
"GoMembership/internal/models"
|
|
"GoMembership/internal/repositories"
|
|
"GoMembership/internal/utils"
|
|
"GoMembership/pkg/logger"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
type RegisterUserTest struct {
|
|
WantDBData map[string]interface{}
|
|
Name string
|
|
Input string
|
|
WantResponse int
|
|
Assert bool
|
|
}
|
|
|
|
var jwtSigningMethod = jwt.SigningMethodHS256
|
|
|
|
func (rt *RegisterUserTest) SetupContext() (*gin.Context, *httptest.ResponseRecorder, *gin.Engine) {
|
|
return GetMockedJSONContext([]byte(rt.Input), "register")
|
|
}
|
|
|
|
func (rt *RegisterUserTest) RunHandler(c *gin.Context, router *gin.Engine) {
|
|
Uc.RegisterUser(c)
|
|
}
|
|
|
|
func (rt *RegisterUserTest) ValidateResponse(w *httptest.ResponseRecorder) error {
|
|
if w.Code != rt.WantResponse {
|
|
responseBody, _ := io.ReadAll(w.Body)
|
|
return fmt.Errorf("Register User: Didn't get the expected response code: got: %v; expected: %v. Context: %#v", w.Code, rt.WantResponse, string(responseBody))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (rt *RegisterUserTest) ValidateResult() error {
|
|
return validateUser(rt.Assert, rt.WantDBData)
|
|
}
|
|
|
|
func testUserController(t *testing.T) {
|
|
|
|
tests := getTestUsers()
|
|
for _, tt := range tests {
|
|
logger.Error.Print("==============================================================")
|
|
logger.Error.Printf("Register User Testing : %v", tt.Name)
|
|
logger.Error.Print("==============================================================")
|
|
t.Run(tt.Name, func(t *testing.T) {
|
|
if err := runSingleTest(&tt); err != nil {
|
|
t.Fatalf("Test failed: %v", err.Error())
|
|
}
|
|
})
|
|
}
|
|
|
|
loginEmail, loginCookie := testLoginHandler(t)
|
|
logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie)
|
|
|
|
// creating a admin cookie
|
|
c, w, _ := GetMockedJSONContext([]byte(`{
|
|
"email": "admin@example.com",
|
|
"password": "securepassword"
|
|
}`), "/login")
|
|
|
|
Uc.LoginHandler(c)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, "Login successful", response["message"])
|
|
var adminCookie http.Cookie
|
|
for _, cookie := range w.Result().Cookies() {
|
|
if cookie.Name == "jwt" {
|
|
adminCookie = *cookie
|
|
|
|
tokenString := adminCookie.Value
|
|
_, claims, err := middlewares.ExtractContentFrom(tokenString)
|
|
assert.NoError(t, err, "FAiled getting cookie string")
|
|
jwtUserID := uint((*claims)["user_id"].(float64))
|
|
user, err := Uc.Service.GetUserByID(jwtUserID)
|
|
assert.NoError(t, err, "FAiled getting cookie string")
|
|
logger.Error.Printf("ADMIN USER: %#v", user)
|
|
break
|
|
}
|
|
}
|
|
assert.NotEmpty(t, adminCookie)
|
|
testUpdateUser(t, loginCookie, adminCookie)
|
|
testLogoutHandler(t, logoutCookie)
|
|
}
|
|
|
|
func testLogoutHandler(t *testing.T, loginCookie http.Cookie) {
|
|
|
|
tests := []struct {
|
|
name string
|
|
setupCookie func(*http.Request)
|
|
expectedStatus int
|
|
}{
|
|
{
|
|
name: "Logout with valid cookie",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "Logout without cookie",
|
|
setupCookie: func(req *http.Request) {},
|
|
expectedStatus: http.StatusOK, // Logout should still succeed even without a cookie
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
logger.Error.Print("==============================================================")
|
|
logger.Error.Printf("Logout User Testing : %v", tt.name)
|
|
logger.Error.Print("==============================================================")
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.POST("/logout", Uc.LogoutHandler)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/logout", nil)
|
|
tt.setupCookie(req)
|
|
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, tt.expectedStatus, w.Code)
|
|
|
|
var response map[string]string
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "Logged out successfully", response["message"])
|
|
|
|
// Check if the cookie has been cleared
|
|
var logoutCookie *http.Cookie
|
|
for _, cookie := range w.Result().Cookies() {
|
|
if cookie.Name == "jwt" {
|
|
logoutCookie = cookie
|
|
break
|
|
}
|
|
}
|
|
assert.NotNil(t, logoutCookie, "Logout should set a clearing cookie")
|
|
assert.Equal(t, "", logoutCookie.Value, "Logout cookie should have empty value")
|
|
assert.True(t, logoutCookie.Expires.Before(time.Now()), "Logout cookie should be expired")
|
|
|
|
// Verify that the user can no longer access protected routes
|
|
w = httptest.NewRecorder()
|
|
req, _ = http.NewRequest("GET", "/current", nil)
|
|
if logoutCookie != nil {
|
|
req.AddCookie(logoutCookie)
|
|
}
|
|
router.GET("/current", middlewares.AuthMiddleware(), Uc.CurrentUserHandler)
|
|
router.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusUnauthorized, w.Code, "User should not be able to access protected routes after logout")
|
|
})
|
|
}
|
|
}
|
|
|
|
func testLoginHandler(t *testing.T) (string, http.Cookie) {
|
|
// This test should run after the user registration test
|
|
var loginCookie http.Cookie
|
|
var loginInput loginInput
|
|
t.Run("LoginHandler", func(t *testing.T) {
|
|
// Test cases
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantStatusCode int
|
|
wantToken bool
|
|
}{
|
|
{
|
|
name: "Valid login",
|
|
input: `{
|
|
"email": "john.doe@example.com",
|
|
"password": "password123"
|
|
}`,
|
|
wantStatusCode: http.StatusOK,
|
|
wantToken: true,
|
|
},
|
|
{
|
|
name: "Invalid email",
|
|
input: `{
|
|
"email": "nonexistent@example.com",
|
|
"password": "password123"
|
|
}`,
|
|
wantStatusCode: http.StatusNotFound,
|
|
wantToken: false,
|
|
},
|
|
{
|
|
name: "Invalid password",
|
|
input: `{
|
|
"email": "john.doe@example.com",
|
|
"password": "wrongpassword"
|
|
}`,
|
|
wantStatusCode: http.StatusNotAcceptable,
|
|
wantToken: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
logger.Error.Print("==============================================================")
|
|
logger.Error.Printf("Login Testing : %v", tt.name)
|
|
logger.Error.Print("==============================================================")
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Setup
|
|
c, w, _ := GetMockedJSONContext([]byte(tt.input), "/login")
|
|
|
|
// Execute
|
|
Uc.LoginHandler(c)
|
|
|
|
// Assert
|
|
assert.Equal(t, tt.wantStatusCode, w.Code)
|
|
|
|
var response map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
|
|
if tt.wantToken {
|
|
assert.Contains(t, response, "message")
|
|
assert.Equal(t, "Login successful", response["message"])
|
|
for _, cookie := range w.Result().Cookies() {
|
|
if cookie.Name == "jwt" {
|
|
loginCookie = *cookie
|
|
|
|
// tokenString := loginCookie.Value
|
|
// _, claims, err := middlewares.ExtractContentFrom(tokenString)
|
|
// assert.NoError(t, err, "FAiled getting cookie string")
|
|
// jwtUserID := uint((*claims)["user_id"].(float64))
|
|
// user, err := Uc.Service.GetUserByID(jwtUserID)
|
|
// assert.NoError(t, err, "FAiled getting cookie string")
|
|
|
|
// logger.Error.Printf("cookie user: %#v", user)
|
|
err = json.Unmarshal([]byte(tt.input), &loginInput)
|
|
assert.NoError(t, err, "Failed to unmarshal input JSON")
|
|
|
|
break
|
|
}
|
|
}
|
|
assert.NotEmpty(t, loginCookie)
|
|
} else {
|
|
assert.Contains(t, response, "errors")
|
|
assert.NotEmpty(t, response["errors"])
|
|
}
|
|
})
|
|
|
|
}
|
|
})
|
|
return loginInput.Email, loginCookie
|
|
}
|
|
|
|
func testCurrentUserHandler(t *testing.T, loginEmail string, loginCookie http.Cookie) http.Cookie {
|
|
// This test should run after the user login test
|
|
invalidCookie := http.Cookie{
|
|
Name: "jwt",
|
|
Value: "invalid.token.here",
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
setupCookie func(*http.Request)
|
|
expectedUserMail string
|
|
expectedStatus int
|
|
expectNewCookie bool
|
|
expectedErrors []map[string]string
|
|
}{
|
|
{
|
|
name: "With valid cookie",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
expectedUserMail: loginEmail,
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "With valid expired cookie",
|
|
setupCookie: func(req *http.Request) {
|
|
sessionID := "test-session"
|
|
token := jwt.NewWithClaims(jwtSigningMethod, jwt.MapClaims{
|
|
"user_id": 1,
|
|
"role_id": 0,
|
|
"session_id": sessionID,
|
|
"exp": time.Now().Add(-time.Hour).Unix(), // Expired 1 hour ago
|
|
})
|
|
tokenString, _ := token.SignedString([]byte(config.Auth.JWTSecret))
|
|
req.AddCookie(&http.Cookie{Name: "jwt", Value: tokenString})
|
|
middlewares.UpdateSession(sessionID, 1) // Add a valid session
|
|
},
|
|
expectedUserMail: config.Recipients.AdminEmail,
|
|
expectedStatus: http.StatusOK,
|
|
expectNewCookie: true,
|
|
},
|
|
{
|
|
name: "Without cookie",
|
|
setupCookie: func(req *http.Request) {},
|
|
expectedStatus: http.StatusUnauthorized,
|
|
expectedErrors: []map[string]string{
|
|
{"field": "general", "key": "server.error.no_auth_token"},
|
|
},
|
|
},
|
|
{
|
|
name: "With invalid cookie",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&invalidCookie)
|
|
},
|
|
expectedStatus: http.StatusUnauthorized,
|
|
expectedErrors: []map[string]string{
|
|
{"field": "general", "key": "server.error.no_auth_token"},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
logger.Error.Print("==============================================================")
|
|
logger.Error.Printf("CurrentUser Testing : %v", tt.name)
|
|
logger.Error.Print("==============================================================")
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.Use(middlewares.AuthMiddleware())
|
|
router.GET("/current", Uc.CurrentUserHandler)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/current", nil)
|
|
tt.setupCookie(req)
|
|
|
|
router.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, tt.expectedStatus, w.Code)
|
|
|
|
if tt.expectedStatus == http.StatusOK {
|
|
var response struct {
|
|
User models.User `json:"user"`
|
|
Subscriptions []models.SubscriptionModel `json:"subscriptions"`
|
|
}
|
|
err := json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NoError(t, err)
|
|
// logger.Error.Printf("response: %#v", response)
|
|
assert.Equal(t, tt.expectedUserMail, response.User.Email)
|
|
var newCookie *http.Cookie
|
|
for _, cookie := range w.Result().Cookies() {
|
|
if cookie.Name == "jwt" {
|
|
newCookie = cookie
|
|
break
|
|
}
|
|
}
|
|
if tt.expectNewCookie {
|
|
assert.NotNil(t, newCookie, "New cookie should be set for expired token")
|
|
assert.NotEqual(t, loginCookie.Value, newCookie.Value, "Cookie value should be different")
|
|
assert.True(t, newCookie.MaxAge > 0, "New cookie should not be expired")
|
|
} else {
|
|
assert.Nil(t, newCookie, "No new cookie should be set for non-expired token")
|
|
}
|
|
} else {
|
|
// For unauthorized requests, check for the new error structure
|
|
var errorResponse map[string]interface{}
|
|
err := json.Unmarshal(w.Body.Bytes(), &errorResponse)
|
|
assert.NoError(t, err)
|
|
|
|
errors, ok := errorResponse["errors"].([]interface{})
|
|
assert.True(t, ok, "Expected 'errors' field in response")
|
|
assert.Len(t, errors, len(tt.expectedErrors), "Unexpected number of errors")
|
|
|
|
for i, expectedError := range tt.expectedErrors {
|
|
if i < len(errors) {
|
|
actualError := errors[i].(map[string]interface{})
|
|
assert.Equal(t, expectedError["field"], actualError["field"], "Mismatched error field")
|
|
assert.Equal(t, expectedError["key"], actualError["key"], "Mismatched error key")
|
|
}
|
|
}
|
|
}
|
|
|
|
})
|
|
}
|
|
return loginCookie
|
|
}
|
|
|
|
func validateUser(assert bool, wantDBData map[string]interface{}) error {
|
|
users, err := Uc.Service.GetUsers(wantDBData)
|
|
if err != nil {
|
|
return fmt.Errorf("Error in database ops: %#v", err)
|
|
}
|
|
|
|
if assert != (len(*users) != 0) {
|
|
return fmt.Errorf("User entry query didn't met expectation: %v != %#v", assert, *users)
|
|
}
|
|
if assert {
|
|
user := (*users)[0]
|
|
// Check for mandate reference
|
|
if user.BankAccount.MandateReference == "" {
|
|
return fmt.Errorf("Mandate reference not generated for user: %s", user.Email)
|
|
}
|
|
|
|
// Validate mandate reference format
|
|
expected := user.GenerateMandateReference()
|
|
if !strings.HasPrefix(user.BankAccount.MandateReference, expected) {
|
|
return fmt.Errorf("Mandate reference is invalid. Expected: %s, Got: %s", expected, user.BankAccount.MandateReference)
|
|
}
|
|
|
|
//check for email delivery
|
|
messages := utils.SMTPGetMessages()
|
|
for _, message := range messages {
|
|
mail, err := utils.DecodeMail(message.MsgRequest())
|
|
if err != nil {
|
|
logger.Error.Printf("Error in validateUser: %#v", err)
|
|
return err
|
|
}
|
|
if strings.Contains(mail.Subject, constants.MailRegistrationSubject) {
|
|
if err := checkRegistrationMail(mail, &user); err != nil {
|
|
logger.Error.Printf("Error in checkRegistrationMail: %#v", err)
|
|
return err
|
|
}
|
|
} else if strings.Contains(mail.Subject, constants.MailVerificationSubject) {
|
|
if err := checkVerificationMail(mail, &user); err != nil {
|
|
logger.Error.Printf("Error in checkVerificationMail: %#v", err)
|
|
return err
|
|
}
|
|
verifiedUsers, err := Uc.Service.GetUsers(wantDBData)
|
|
if err != nil {
|
|
logger.Error.Printf("Error in GetUsers: %#v", err)
|
|
return err
|
|
}
|
|
if (*verifiedUsers)[0].Status != constants.VerifiedStatus {
|
|
return fmt.Errorf("Users(%v) status isn't verified after email verification. Status is: %v", (*verifiedUsers)[0].Email, (*verifiedUsers)[0].Status)
|
|
}
|
|
} else {
|
|
return fmt.Errorf("Subject not expected: %v", mail.Subject)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func testUpdateUser(t *testing.T, loginCookie http.Cookie, adminCookie http.Cookie) {
|
|
|
|
invalidCookie := http.Cookie{
|
|
Name: "jwt",
|
|
Value: "invalid.token.here",
|
|
}
|
|
// Get the user we just created
|
|
users, err := Uc.Service.GetUsers(map[string]interface{}{"email": "john.doe@example.com"})
|
|
if err != nil || len(*users) == 0 {
|
|
t.Fatalf("Failed to get test user: %v", err)
|
|
}
|
|
user := (*users)[0]
|
|
if user.Licence == nil {
|
|
user.Licence = &models.Licence{
|
|
Number: "Z021AB37X13",
|
|
ExpirationDate: time.Now().UTC().AddDate(1, 0, 0),
|
|
IssuedDate: time.Now().UTC().AddDate(-1, 0, 0),
|
|
IssuingCountry: "Deutschland",
|
|
}
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
setupCookie func(*http.Request)
|
|
updateFunc func(*models.User)
|
|
expectedReturn func(*models.User)
|
|
expectedStatus int
|
|
expectedErrors []map[string]string
|
|
}{
|
|
{
|
|
name: "Valid Admin Update",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&adminCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Valid Update, invalid cookie",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&invalidCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
},
|
|
expectedStatus: http.StatusUnauthorized,
|
|
expectedErrors: []map[string]string{
|
|
{"field": "general", "key": "server.error.no_auth_token"},
|
|
},
|
|
},
|
|
{
|
|
name: "Invalid Email Update",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Email = "invalid-email"
|
|
},
|
|
expectedStatus: http.StatusBadRequest,
|
|
expectedErrors: []map[string]string{
|
|
{"field": "Email", "key": "server.validation.email"},
|
|
},
|
|
},
|
|
|
|
{
|
|
name: "admin may change licence number",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&adminCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Change phone number",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Add category",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
|
category, err := licenceRepo.FindCategoryByName("B")
|
|
assert.NoError(t, err)
|
|
u.Licence.Categories = []models.Category{category}
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Delete 1 and add 1 category",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
|
category, err := licenceRepo.FindCategoryByName("A")
|
|
category2, err := licenceRepo.FindCategoryByName("BE")
|
|
assert.NoError(t, err)
|
|
u.Licence.Categories = []models.Category{category, category2}
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Delete 1 category",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
|
|
category, err := licenceRepo.FindCategoryByName("A")
|
|
assert.NoError(t, err)
|
|
u.Licence.Categories = []models.Category{category}
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Delete all categories",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
u.Licence.Categories = []models.Category{}
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "User ID mismatch while not admin",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.ID = 1
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
u.FirstName = "John Missing ID"
|
|
},
|
|
expectedStatus: http.StatusUnauthorized,
|
|
expectedErrors: []map[string]string{
|
|
{"field": "user.user", "key": "server.error.unauthorized"},
|
|
},
|
|
},
|
|
{
|
|
name: "Password Update",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
u.Password = "NewPassword"
|
|
},
|
|
expectedReturn: func(u *models.User) {
|
|
u.Password = ""
|
|
u.FirstName = "John Updated"
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Admin Password Update",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&adminCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.LastName = "Doe Updated"
|
|
u.Phone = "01738484994"
|
|
u.Licence.Number = "B072RRE2I50"
|
|
u.Password = "NewPassword"
|
|
},
|
|
expectedStatus: http.StatusAccepted,
|
|
},
|
|
{
|
|
name: "Non-existent User",
|
|
setupCookie: func(req *http.Request) {
|
|
req.AddCookie(&loginCookie)
|
|
},
|
|
updateFunc: func(u *models.User) {
|
|
u.Password = ""
|
|
u.ID = 99999
|
|
u.FirstName = "Non-existent"
|
|
},
|
|
expectedErrors: []map[string]string{
|
|
{"field": "user.user", "key": "server.error.unauthorized"},
|
|
},
|
|
expectedStatus: http.StatusUnauthorized,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
logger.Error.Print("==============================================================")
|
|
logger.Error.Printf("Update Testing : %v", tt.name)
|
|
logger.Error.Print("==============================================================")
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Create a copy of the user and apply the updates
|
|
updatedUser := user
|
|
// logger.Error.Printf("users licence to be updated: %+v", user.Licence)
|
|
tt.updateFunc(&updatedUser)
|
|
|
|
updateData := &RegistrationData{User: updatedUser}
|
|
jsonData, err := json.Marshal(updateData)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal user data: %v", err)
|
|
}
|
|
|
|
logger.Error.Printf("Updated User: %#v", updatedUser.Safe())
|
|
if tt.expectedReturn != nil {
|
|
tt.expectedReturn(&updatedUser)
|
|
}
|
|
|
|
// Create request
|
|
req, _ := http.NewRequest("PUT", "/users/"+strconv.FormatUint(uint64(user.ID), 10), bytes.NewBuffer(jsonData))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
tt.setupCookie(req)
|
|
// Create response recorder
|
|
w := httptest.NewRecorder()
|
|
|
|
// Set up router and add middleware
|
|
router := gin.New()
|
|
router.Use(middlewares.AuthMiddleware())
|
|
router.PUT("/users/:id", Uc.UpdateHandler)
|
|
|
|
// Perform request
|
|
router.ServeHTTP(w, req)
|
|
|
|
bodyBytes, _ := io.ReadAll(w.Body)
|
|
t.Logf("Response Body: %s", string(bodyBytes))
|
|
// Check status code
|
|
assert.Equal(t, tt.expectedStatus, w.Code)
|
|
|
|
// Parse response
|
|
var response map[string]interface{}
|
|
err = json.Unmarshal(bodyBytes, &response)
|
|
if err != nil {
|
|
t.Fatalf("Failed to unmarshal response body: %v", err)
|
|
}
|
|
|
|
if tt.expectedErrors != nil {
|
|
errors, ok := response["errors"].([]interface{})
|
|
if !ok {
|
|
t.Fatalf("Expected 'errors' field in response, got: %v", response)
|
|
}
|
|
assert.Len(t, errors, len(tt.expectedErrors), "Unexpected number of errors")
|
|
for i, expectedError := range tt.expectedErrors {
|
|
if i < len(errors) {
|
|
actualError := errors[i].(map[string]interface{})
|
|
assert.Equal(t, expectedError["field"], actualError["field"], "Mismatched error field")
|
|
assert.Equal(t, expectedError["key"], actualError["key"], "Mismatched error key")
|
|
}
|
|
}
|
|
} else {
|
|
// Check for success message
|
|
message, ok := response["message"].(string)
|
|
if !ok {
|
|
t.Fatalf("Expected 'message' field in response, got: %v", response)
|
|
}
|
|
assert.Equal(t, "User updated successfully", message)
|
|
|
|
// Verify the update in the database
|
|
updatedUserFromDB, err := Uc.Service.GetUserByID(user.ID)
|
|
assert.NoError(t, err)
|
|
|
|
if updatedUser.Password == "" {
|
|
assert.Equal(t, user.Password, (*updatedUserFromDB).Password)
|
|
} else {
|
|
assert.NotEqual(t, user.Password, (*updatedUserFromDB).Password)
|
|
}
|
|
|
|
updatedUserFromDB.Password = ""
|
|
updatedUser.Password = ""
|
|
assert.Equal(t, updatedUser.FirstName, updatedUserFromDB.FirstName, "FirstName mismatch")
|
|
assert.Equal(t, updatedUser.LastName, updatedUserFromDB.LastName, "LastName mismatch")
|
|
assert.Equal(t, updatedUser.Email, updatedUserFromDB.Email, "Email mismatch")
|
|
assert.Equal(t, updatedUser.DateOfBirth, updatedUserFromDB.DateOfBirth, "DateOfBirth mismatch")
|
|
assert.Equal(t, updatedUser.Company, updatedUserFromDB.Company, "Company mismatch")
|
|
assert.Equal(t, updatedUser.Phone, updatedUserFromDB.Phone, "Phone mismatch")
|
|
assert.Equal(t, updatedUser.Notes, updatedUserFromDB.Notes, "Notes mismatch")
|
|
assert.Equal(t, updatedUser.ProfilePicture, updatedUserFromDB.ProfilePicture, "ProfilePicture mismatch")
|
|
assert.Equal(t, updatedUser.Address, updatedUserFromDB.Address, "Address mismatch")
|
|
assert.Equal(t, updatedUser.ZipCode, updatedUserFromDB.ZipCode, "ZipCode mismatch")
|
|
assert.Equal(t, updatedUser.City, updatedUserFromDB.City, "City mismatch")
|
|
assert.Equal(t, updatedUser.PaymentStatus, updatedUserFromDB.PaymentStatus, "PaymentStatus mismatch")
|
|
assert.Equal(t, updatedUser.Status, updatedUserFromDB.Status, "Status mismatch")
|
|
assert.Equal(t, updatedUser.RoleID, updatedUserFromDB.RoleID, "RoleID mismatch")
|
|
|
|
// For nested structs, you might want to compare individual fields
|
|
assert.Equal(t, updatedUser.BankAccount.Bank, updatedUserFromDB.BankAccount.Bank, "BankAccount.Bank mismatch")
|
|
assert.Equal(t, updatedUser.BankAccount.AccountHolderName, updatedUserFromDB.BankAccount.AccountHolderName, "BankAccount.AccountHolderName mismatch")
|
|
assert.Equal(t, updatedUser.BankAccount.IBAN, updatedUserFromDB.BankAccount.IBAN, "BankAccount.IBAN mismatch")
|
|
assert.Equal(t, updatedUser.BankAccount.BIC, updatedUserFromDB.BankAccount.BIC, "BankAccount.BIC mismatch")
|
|
assert.Equal(t, updatedUser.BankAccount.MandateReference, updatedUserFromDB.BankAccount.MandateReference, "BankAccount.MandateReference mismatch")
|
|
|
|
assert.Equal(t, updatedUser.Membership.StartDate, updatedUserFromDB.Membership.StartDate, "Membership.StartDate mismatch")
|
|
assert.Equal(t, updatedUser.Membership.EndDate, updatedUserFromDB.Membership.EndDate, "Membership.EndDate mismatch")
|
|
assert.Equal(t, updatedUser.Membership.Status, updatedUserFromDB.Membership.Status, "Membership.Status mismatch")
|
|
assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch")
|
|
assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch")
|
|
|
|
assert.Equal(t, updatedUser.Licence.Status, updatedUserFromDB.Licence.Status, "Licence.Status mismatch")
|
|
assert.Equal(t, updatedUser.Licence.Number, updatedUserFromDB.Licence.Number, "Licence.Number mismatch")
|
|
assert.Equal(t, updatedUser.Licence.IssuedDate, updatedUserFromDB.Licence.IssuedDate, "Licence.IssuedDate mismatch")
|
|
assert.Equal(t, updatedUser.Licence.ExpirationDate, updatedUserFromDB.Licence.ExpirationDate, "Licence.ExpirationDate mismatch")
|
|
assert.Equal(t, updatedUser.Licence.IssuingCountry, updatedUserFromDB.Licence.IssuingCountry, "Licence.IssuingCountry mismatch")
|
|
|
|
// For slices or more complex nested structures, you might want to use deep equality checks
|
|
assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch")
|
|
if len(updatedUser.Licence.Categories) > 0 {
|
|
for i := range updatedUser.Licence.Categories {
|
|
assert.Equal(t, updatedUser.Licence.Categories[i].Name, updatedUserFromDB.Licence.Categories[i].Name, "Category Category mismatch at index %d", i)
|
|
}
|
|
} else {
|
|
assert.Emptyf(t, updatedUserFromDB.Licence.Categories, "Categories aren't empty when they should")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func checkWelcomeMail(message *utils.Email, user *models.User) error {
|
|
|
|
if !strings.Contains(message.To, user.Email) {
|
|
return fmt.Errorf("Registration Information didn't reach the user! Recipient was: %v instead of %v", message.To, user.Email)
|
|
}
|
|
if !strings.Contains(message.From, config.SMTP.User) {
|
|
return fmt.Errorf("Registration Information was sent from unexpected address! Sender was: %v instead of %v", message.From, config.SMTP.User)
|
|
}
|
|
|
|
//Check if all the relevant data has been passed to the mail.
|
|
if !strings.Contains(message.Body, user.FirstName) {
|
|
return fmt.Errorf("User first name(%v) has not been rendered in registration mail.", user.FirstName)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Preis/Monat</strong>: %v", user.Membership.SubscriptionModel.MonthlyFee)) {
|
|
return fmt.Errorf("Users monthly subscription fee(%v) has not been rendered in registration mail.", user.Membership.SubscriptionModel.MonthlyFee)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Preis/h</strong>: %v", user.Membership.SubscriptionModel.HourlyRate)) {
|
|
return fmt.Errorf("Users hourly subscription fee(%v) has not been rendered in registration mail.", user.Membership.SubscriptionModel.HourlyRate)
|
|
}
|
|
if user.Company != "" && !strings.Contains(message.Body, user.Company) {
|
|
return fmt.Errorf("Users Company(%v) has not been rendered in registration mail.", user.Company)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Mitgliedsnummer</strong>: %v", user.Membership.ID)) {
|
|
return fmt.Errorf("Users membership Id(%v) has not been rendered in registration mail.", user.Membership.ID)
|
|
}
|
|
if !strings.Contains(message.Body, config.Site.BaseURL) {
|
|
return fmt.Errorf("Base Url (%v) has not been rendered in registration mail.", config.Site.BaseURL)
|
|
}
|
|
if !strings.Contains(message.Body, config.Site.BaseURL+config.Templates.LogoURI) {
|
|
return fmt.Errorf("Logo Url (%v) has not been rendered in registration mail.", config.Site.BaseURL+config.Site.WebsiteTitle)
|
|
}
|
|
if !strings.Contains(message.Body, config.Site.WebsiteTitle) {
|
|
return fmt.Errorf("Website title (%v) has not been rendered in registration mail.", config.Site.WebsiteTitle)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func checkRegistrationMail(message *utils.Email, user *models.User) error {
|
|
|
|
if !strings.Contains(message.To, config.Recipients.UserRegistration) {
|
|
return fmt.Errorf("Registration Information didn't reach admin! Recipient was: %v instead of %v", message.To, config.Recipients.UserRegistration)
|
|
}
|
|
if !strings.Contains(message.From, config.SMTP.User) {
|
|
return fmt.Errorf("Registration Information was sent from unexpected address! Sender was: %v instead of %v", message.From, config.SMTP.User)
|
|
}
|
|
//Check if all the relevant data has been passed to the mail.
|
|
if !strings.Contains(message.Body, user.FirstName+" "+user.LastName) {
|
|
return fmt.Errorf("User first and last name(%v) has not been rendered in registration mail.", user.FirstName+" "+user.LastName)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Preis/Monat</strong>: %v", user.Membership.SubscriptionModel.MonthlyFee)) {
|
|
return fmt.Errorf("Users monthly subscription fee(%v) has not been rendered in registration mail.", user.Membership.SubscriptionModel.MonthlyFee)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Preis/h</strong>: %v", user.Membership.SubscriptionModel.HourlyRate)) {
|
|
return fmt.Errorf("Users hourly subscription fee(%v) has not been rendered in registration mail.", user.Membership.SubscriptionModel.HourlyRate)
|
|
}
|
|
if user.Company != "" && !strings.Contains(message.Body, user.Company) {
|
|
return fmt.Errorf("Users Company(%v) has not been rendered in registration mail.", user.Company)
|
|
}
|
|
if !strings.Contains(message.Body, fmt.Sprintf("Mitgliedsnr:</strong> %v", user.Membership.ID)) {
|
|
return fmt.Errorf("Users membership Id(%v) has not been rendered in registration mail.", user.Membership.ID)
|
|
}
|
|
if !strings.Contains(message.Body, user.Address+","+user.ZipCode) {
|
|
return fmt.Errorf("Users address(%v) has not been rendered in registration mail.", user.Address+" sv,"+user.ZipCode)
|
|
}
|
|
if !strings.Contains(message.Body, user.City) {
|
|
return fmt.Errorf("Users city(%v) has not been rendered in registration mail.", user.City)
|
|
}
|
|
if !strings.Contains(message.Body, user.DateOfBirth.Format("20060102")) {
|
|
return fmt.Errorf("Users birthday(%v) has not been rendered in registration mail.", user.DateOfBirth.Format("20060102"))
|
|
}
|
|
if !strings.Contains(message.Body, "Email:</strong> "+user.Email) {
|
|
return fmt.Errorf("Users email(%v) has not been rendered in registration mail.", user.Email)
|
|
}
|
|
if !strings.Contains(message.Body, user.Phone) {
|
|
return fmt.Errorf("Users phone(%v) has not been rendered in registration mail.", user.Phone)
|
|
}
|
|
if !strings.Contains(message.Body, user.BankAccount.IBAN) {
|
|
return fmt.Errorf("Users IBAN(%v) has not been rendered in registration mail.", user.BankAccount.IBAN)
|
|
}
|
|
if !strings.Contains(message.Body, config.Site.BaseURL) {
|
|
return fmt.Errorf("Base Url (%v) has not been rendered in registration mail.", config.Site.BaseURL)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func checkVerificationMail(message *utils.Email, user *models.User) error {
|
|
if !strings.Contains(message.To, user.Email) {
|
|
return fmt.Errorf("Registration Information didn't reach client! Recipient was: %v instead of %v", message.To, user.Email)
|
|
}
|
|
verificationURL, err := getVerificationURL(message.Body)
|
|
if err != nil {
|
|
return fmt.Errorf("Error parsing verification URL: %#v", err.Error())
|
|
}
|
|
if !strings.Contains(verificationURL, user.Verification.VerificationToken) {
|
|
return fmt.Errorf("Users Verification link token(%v) has not been rendered in email verification mail. %v", user.Verification.VerificationToken, verificationURL)
|
|
}
|
|
|
|
if !strings.Contains(message.Body, config.Site.BaseURL) {
|
|
return fmt.Errorf("Base Url (%v) has not been rendered in email verification mail.", config.Site.BaseURL)
|
|
}
|
|
// open the provided link:
|
|
if err := verifyMail(verificationURL); err != nil {
|
|
return err
|
|
}
|
|
messages := utils.SMTPGetMessages()
|
|
for _, message := range messages {
|
|
mail, err := utils.DecodeMail(message.MsgRequest())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := checkWelcomeMail(mail, user); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
|
|
}
|
|
|
|
func verifyMail(verificationURL string) error {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
router.LoadHTMLGlob(filepath.Join(config.Templates.HTMLPath, "*"))
|
|
|
|
router.GET("/users/verify", Uc.VerifyMailHandler)
|
|
wv := httptest.NewRecorder()
|
|
cv, _ := gin.CreateTestContext(wv)
|
|
var err error
|
|
cv.Request, err = http.NewRequest("GET", verificationURL, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to create new GET Request: %v", err.Error())
|
|
}
|
|
router.ServeHTTP(wv, cv.Request)
|
|
if wv.Code != 200 {
|
|
|
|
responseBody, _ := io.ReadAll(wv.Body)
|
|
|
|
return fmt.Errorf("VerifyMail: Didn't get the expected response code: got: %v; expected: %v Context: %#v", wv.Code, 200, string(responseBody))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getVerificationURL(mailBody string) (string, error) {
|
|
re := regexp.MustCompile(`"([^"]*verify[^"]*)"`)
|
|
|
|
// Find the matching URL in the email content
|
|
match := re.FindStringSubmatch(mailBody)
|
|
if len(match) == 0 {
|
|
return "", fmt.Errorf("No mail verification link found in email body: %#v", mailBody)
|
|
}
|
|
verificationURL, err := url.QueryUnescape(match[1])
|
|
if err != nil {
|
|
return "", fmt.Errorf("Error decoding URL: %v", err)
|
|
}
|
|
logger.Info.Printf("VerificationURL: %#v", verificationURL)
|
|
return verificationURL, nil
|
|
}
|
|
|
|
// TEST DATA:
|
|
|
|
func customizeInput(customize func(models.User) models.User) *RegistrationData {
|
|
user := getBaseUser()
|
|
user = customize(user) // Apply the customization
|
|
return &RegistrationData{User: user}
|
|
}
|
|
|
|
func getTestUsers() []RegisterUserTest {
|
|
return []RegisterUserTest{
|
|
{
|
|
Name: "birthday < 18 should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.DateOfBirth = time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "FirstName empty, should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.FirstName = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "LastName Empty should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.LastName = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "EMail wrong format should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "johnexample.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "johnexample.com"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Missing Zip Code should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.ZipCode = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Missing Address should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Address = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Missing City should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.City = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Missing IBAN should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.BankAccount.IBAN = ""
|
|
user.RoleID = 0
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Invalid IBAN should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.BankAccount.IBAN = "DE1234234123134"
|
|
user.RoleID = 0
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Missing subscription plan should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Membership.SubscriptionModel.Name = ""
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Invalid subscription plan should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Membership.SubscriptionModel.Name = "NOTEXISTENTPLAN"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Correct Entry should pass",
|
|
WantResponse: http.StatusCreated,
|
|
WantDBData: map[string]interface{}{"email": "john.doe@example.com"},
|
|
Assert: true,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User { return user })),
|
|
},
|
|
{
|
|
Name: "Email duplicate should fail",
|
|
WantResponse: http.StatusConflict,
|
|
WantDBData: map[string]interface{}{"first_name": "Jane"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.FirstName = "Jane"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Company present should pass",
|
|
WantResponse: http.StatusCreated,
|
|
WantDBData: map[string]interface{}{"email": "john.doe2@example.com"},
|
|
Assert: true,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "john.doe2@example.com"
|
|
user.Company = "ACME"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Subscription constraints not entered; should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "john.junior.doe@example.com"
|
|
user.Membership.SubscriptionModel.Name = "additional"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Subscription constraints wrong; should fail",
|
|
WantResponse: http.StatusBadRequest,
|
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
|
Assert: false,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "john.junior.doe@example.com"
|
|
user.Membership.ParentMembershipID = 200
|
|
user.Membership.SubscriptionModel.Name = "additional"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Subscription constraints correct, should pass",
|
|
WantResponse: http.StatusCreated,
|
|
WantDBData: map[string]interface{}{"email": "john.junior.doe@example.com"},
|
|
Assert: true,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "john.junior.doe@example.com"
|
|
user.Membership.ParentMembershipID = 1
|
|
user.Membership.SubscriptionModel.Name = "additional"
|
|
return user
|
|
})),
|
|
},
|
|
{
|
|
Name: "Correct Entry with Mandate Reference",
|
|
WantResponse: http.StatusCreated,
|
|
WantDBData: map[string]interface{}{"email": "john.mandate@example.com"},
|
|
Assert: true,
|
|
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
user.Email = "john.mandate@example.com"
|
|
user.BankAccount.IBAN = "DE89370400440532013000"
|
|
return user
|
|
})),
|
|
},
|
|
// Currently unsupported. My number wouldn't match, though it should.
|
|
// {
|
|
// Name: "wrong driverslicence number, should fail",
|
|
// WantResponse: http.StatusBadRequest,
|
|
// WantDBData: map[string]interface{}{"email": "john.wronglicence.doe@example.com"},
|
|
// Assert: false,
|
|
// Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
// user.Email = "john.wronglicence.doe@example.com"
|
|
// user.Licence = &models.Licence{
|
|
// Number: "AAAA12345AA",
|
|
// ExpirationDate: time.Now().AddDate(1, 0, 0),
|
|
// IssuedDate: time.Now().AddDate(-1, 0, 0),
|
|
// }
|
|
// return user
|
|
// })),
|
|
// },
|
|
// {
|
|
// Name: "empty driverslicence number, should fail",
|
|
// WantResponse: http.StatusBadRequest,
|
|
// WantDBData: map[string]interface{}{"email": "john.wronglicence.doe@example.com"},
|
|
// Assert: false,
|
|
// Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
// user.Email = "john.wronglicence.doe@example.com"
|
|
// user.Licence = &models.Licence{
|
|
// Number: "",
|
|
// ExpirationDate: time.Now().AddDate(1, 0, 0),
|
|
// IssuedDate: time.Now().AddDate(-1, 0, 0),
|
|
// }
|
|
// return user
|
|
// })),
|
|
// },
|
|
// {
|
|
// Name: "Correct Licence number, should pass",
|
|
// WantResponse: http.StatusCreated,
|
|
// WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
|
|
// Assert: true,
|
|
// Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
|
|
// user.Email = "john.correctLicenceNumber@example.com"
|
|
// user.Licence = &models.Licence{
|
|
// Number: "B072RRE2I55",
|
|
// ExpirationDate: time.Now().AddDate(1, 0, 0),
|
|
// IssuedDate: time.Now().AddDate(-1, 0, 0),
|
|
// }
|
|
// return user
|
|
// })),
|
|
// },
|
|
}
|
|
}
|