Tests: Membership controller

This commit is contained in:
Alex
2025-02-12 10:12:30 +01:00
parent 2fdb484451
commit 861d029ce5
7 changed files with 110 additions and 30 deletions

View File

@@ -106,7 +106,7 @@ func TestSuite(t *testing.T) {
licenceService := &services.LicenceService{Repo: licenceRepo} licenceService := &services.LicenceService{Repo: licenceRepo}
Uc = &UserController{Service: userService, LicenceService: licenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService} Uc = &UserController{Service: userService, LicenceService: licenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
Mc = &MembershipController{Service: *membershipService} Mc = &MembershipController{UserController: &MockUserController{}, Service: *membershipService}
Cc = &ContactController{EmailService: emailService} Cc = &ContactController{EmailService: emailService}
if err := initSubscriptionPlans(); err != nil { if err := initSubscriptionPlans(); err != nil {

View File

@@ -1,36 +1,54 @@
package controllers package controllers
import ( import (
"GoMembership/internal/constants"
"GoMembership/internal/models" "GoMembership/internal/models"
"GoMembership/internal/services" "GoMembership/internal/services"
"GoMembership/internal/utils"
"strings" "strings"
"net/http" "net/http"
// "strconv"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"GoMembership/pkg/errors"
"GoMembership/pkg/logger" "GoMembership/pkg/logger"
) )
type MembershipController struct { type MembershipController struct {
Service services.MembershipService Service services.MembershipService
UserController interface {
ExtractUserFromContext(*gin.Context) (*models.User, error)
}
} }
type MembershipData struct { type MembershipData struct {
APIKey string `json:"api_key"` // APIKey string `json:"api_key"`
Model models.SubscriptionModel `json:"model"` Subscription models.SubscriptionModel `json:"subscription"`
} }
func (mc *MembershipController) RegisterSubscription(c *gin.Context) { func (mc *MembershipController) RegisterSubscription(c *gin.Context) {
var regData MembershipData var regData MembershipData
requestUser, err := mc.UserController.ExtractUserFromContext(c)
if err != nil {
utils.RespondWithError(c, err, "Error extracting user from context in subscription registrationHandler", http.StatusBadRequest, "general", "server.validation.invalid_user_data")
return
}
if !utils.HasPrivilige(requestUser, constants.Priviliges.Update) {
utils.RespondWithError(c, errors.ErrNotAuthorized, "Not allowed to register subscription", http.StatusForbidden, "user", "server.error.unauthorized")
return
}
if err := c.ShouldBindJSON(&regData); err != nil { if err := c.ShouldBindJSON(&regData); err != nil {
logger.Error.Printf("Couln't decode subscription data: %v", err) utils.HandleValidationError(c, err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Couldn't decode subscription data"})
return return
} }
// Register Subscription // Register Subscription
id, err := mc.Service.RegisterSubscription(&regData.Model) logger.Info.Printf("Registering subscription %v", regData.Subscription.Name)
id, err := mc.Service.RegisterSubscription(&regData.Subscription)
if err != nil { if err != nil {
logger.Error.Printf("Couldn't register Membershipmodel: %v", err) logger.Error.Printf("Couldn't register Membershipmodel: %v", err)
if strings.Contains(err.Error(), "UNIQUE constraint failed") { if strings.Contains(err.Error(), "UNIQUE constraint failed") {
@@ -47,6 +65,44 @@ func (mc *MembershipController) RegisterSubscription(c *gin.Context) {
}) })
} }
func (mc *MembershipController) UpdateHandler(c *gin.Context) {
var regData MembershipData
requestUser, err := mc.UserController.ExtractUserFromContext(c)
if err != nil {
utils.RespondWithError(c, err, "Error extracting user from context in subscription UpdateHandler", http.StatusBadRequest, "general", "server.validation.no_auth_tokenw")
return
}
if !utils.HasPrivilige(requestUser, constants.Priviliges.Update) {
utils.RespondWithError(c, errors.ErrNotAuthorized, "Not allowed to update subscription", http.StatusForbidden, "user", "server.error.unauthorized")
return
}
if err := c.ShouldBindJSON(&regData); err != nil {
utils.HandleValidationError(c, err)
return
}
// Register Subscription
logger.Info.Printf("Registering subscription %v", regData.Subscription.Name)
// id, err := mc.Service.UpdateSubscription(&regData.Subscription)
id := 1
if err != nil {
logger.Error.Printf("Couldn't update Membershipmodel: %v", err)
if strings.Contains(err.Error(), "UNIQUE constraint failed") {
c.JSON(http.StatusConflict, "Duplicate subscription name")
return
}
c.JSON(http.StatusNotAcceptable, "Couldn't update Membershipmodel")
return
}
logger.Info.Printf("updating subscription: %+v", regData)
c.JSON(http.StatusAccepted, gin.H{
"status": "success",
"id": id,
})
}
func (mc *MembershipController) GetSubscriptions(c *gin.Context) { func (mc *MembershipController) GetSubscriptions(c *gin.Context) {
subscriptions, err := mc.Service.GetSubscriptions(nil) subscriptions, err := mc.Service.GetSubscriptions(nil)
if err != nil { if err != nil {

View File

@@ -6,7 +6,7 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"GoMembership/internal/config" "GoMembership/internal/constants"
"GoMembership/internal/models" "GoMembership/internal/models"
"GoMembership/pkg/logger" "GoMembership/pkg/logger"
@@ -21,8 +21,29 @@ type RegisterSubscriptionTest struct {
Assert bool Assert bool
} }
type MockUserController struct {
UserController // Embed the UserController
}
func (m *MockUserController) ExtractUserFromContext(c *gin.Context) (*models.User, error) {
return &models.User{
ID: 1,
FirstName: "Admin",
LastName: "User",
Email: "admin@test.com",
RoleID: constants.Roles.Admin,
}, nil
}
func setupMockAuth() {
// Create and assign the mock controller
mockController := &MockUserController{}
Mc.UserController = mockController
}
func testMembershipController(t *testing.T) { func testMembershipController(t *testing.T) {
setupMockAuth()
tests := getSubscriptionData() tests := getSubscriptionData()
for _, tt := range tests { for _, tt := range tests {
logger.Error.Print("==============================================================") logger.Error.Print("==============================================================")
@@ -68,8 +89,8 @@ func validateSubscription(assert bool, wantDBData map[string]interface{}) error
func getBaseSubscription() MembershipData { func getBaseSubscription() MembershipData {
return MembershipData{ return MembershipData{
APIKey: config.Auth.APIKEY, // APIKey: config.Auth.APIKEY,
Model: models.SubscriptionModel{ Subscription: models.SubscriptionModel{
Name: "Premium", Name: "Premium",
Details: "A subscription detail", Details: "A subscription detail",
MonthlyFee: 12.0, MonthlyFee: 12.0,
@@ -91,7 +112,7 @@ func getSubscriptionData() []RegisterSubscriptionTest {
Assert: false, Assert: false,
Input: GenerateInputJSON( Input: GenerateInputJSON(
customizeSubscription(func(subscription MembershipData) MembershipData { customizeSubscription(func(subscription MembershipData) MembershipData {
subscription.Model.Details = "" subscription.Subscription.Details = ""
return subscription return subscription
})), })),
}, },
@@ -102,7 +123,7 @@ func getSubscriptionData() []RegisterSubscriptionTest {
Assert: false, Assert: false,
Input: GenerateInputJSON( Input: GenerateInputJSON(
customizeSubscription(func(subscription MembershipData) MembershipData { customizeSubscription(func(subscription MembershipData) MembershipData {
subscription.Model.Name = "" subscription.Subscription.Name = ""
return subscription return subscription
})), })),
}, },
@@ -112,7 +133,7 @@ func getSubscriptionData() []RegisterSubscriptionTest {
WantDBData: map[string]interface{}{"name": "Premium"}, WantDBData: map[string]interface{}{"name": "Premium"},
Assert: false, Assert: false,
Input: GenerateInputJSON(customizeSubscription(func(sub MembershipData) MembershipData { Input: GenerateInputJSON(customizeSubscription(func(sub MembershipData) MembershipData {
sub.Model.MonthlyFee = -10.0 sub.Subscription.MonthlyFee = -10.0
return sub return sub
})), })),
}, },
@@ -122,7 +143,7 @@ func getSubscriptionData() []RegisterSubscriptionTest {
WantDBData: map[string]interface{}{"name": "Premium"}, WantDBData: map[string]interface{}{"name": "Premium"},
Assert: false, Assert: false,
Input: GenerateInputJSON(customizeSubscription(func(sub MembershipData) MembershipData { Input: GenerateInputJSON(customizeSubscription(func(sub MembershipData) MembershipData {
sub.Model.HourlyRate = -1.0 sub.Subscription.HourlyRate = -1.0
return sub return sub
})), })),
}, },
@@ -133,9 +154,9 @@ func getSubscriptionData() []RegisterSubscriptionTest {
Assert: true, Assert: true,
Input: GenerateInputJSON( Input: GenerateInputJSON(
customizeSubscription(func(subscription MembershipData) MembershipData { customizeSubscription(func(subscription MembershipData) MembershipData {
subscription.Model.Conditions = "Some Condition" subscription.Subscription.Conditions = "Some Condition"
subscription.Model.IncludedPerYear = 0 subscription.Subscription.IncludedPerYear = 0
subscription.Model.IncludedPerMonth = 1 subscription.Subscription.IncludedPerMonth = 1
return subscription return subscription
})), })),
}, },

View File

@@ -33,7 +33,7 @@ type RegistrationData struct {
} }
func (uc *UserController) CurrentUserHandler(c *gin.Context) { func (uc *UserController) CurrentUserHandler(c *gin.Context) {
requestUser, err := uc.extractUserFromContext(c) requestUser, err := uc.ExtractUserFromContext(c)
if err != nil { if err != nil {
utils.RespondWithError(c, err, "Error extracting user from context in CurrentUserHandler", http.StatusBadRequest, "general", "server.error.internal_server_error") utils.RespondWithError(c, err, "Error extracting user from context in CurrentUserHandler", http.StatusBadRequest, "general", "server.error.internal_server_error")
return return
@@ -65,7 +65,7 @@ func (uc *UserController) GetAllUsers(c *gin.Context) {
func (uc *UserController) UpdateHandler(c *gin.Context) { func (uc *UserController) UpdateHandler(c *gin.Context) {
// 1. Extract and validate the user ID from the route // 1. Extract and validate the user ID from the route
requestUser, err := uc.extractUserFromContext(c) requestUser, err := uc.ExtractUserFromContext(c)
if err != nil { if err != nil {
utils.RespondWithError(c, err, "Error extracting user from context in UpdateHandler", http.StatusBadRequest, "general", "server.validation.no_auth_tokenw") utils.RespondWithError(c, err, "Error extracting user from context in UpdateHandler", http.StatusBadRequest, "general", "server.validation.no_auth_tokenw")
return return
@@ -86,7 +86,7 @@ func (uc *UserController) UpdateHandler(c *gin.Context) {
updatedUser, err := uc.Service.UpdateUser(&user) updatedUser, err := uc.Service.UpdateUser(&user)
if err != nil { if err != nil {
utils.HandleUpdateError(c, err) utils.HandleUserUpdateError(c, err)
return return
} }
@@ -97,7 +97,7 @@ func (uc *UserController) UpdateHandler(c *gin.Context) {
func (uc *UserController) DeleteUser(c *gin.Context) { func (uc *UserController) DeleteUser(c *gin.Context) {
requestUser, err := uc.extractUserFromContext(c) requestUser, err := uc.ExtractUserFromContext(c)
if err != nil { if err != nil {
utils.RespondWithError(c, err, "Error extracting user from context in UpdateHandler", http.StatusBadRequest, "general", "server.validation.no_auth_tokenw") utils.RespondWithError(c, err, "Error extracting user from context in UpdateHandler", http.StatusBadRequest, "general", "server.validation.no_auth_tokenw")
return return
@@ -125,7 +125,7 @@ func (uc *UserController) DeleteUser(c *gin.Context) {
} }
} }
func (uc *UserController) extractUserFromContext(c *gin.Context) (*models.User, error) { func (uc *UserController) ExtractUserFromContext(c *gin.Context) (*models.User, error) {
tokenString, err := c.Cookie("jwt") tokenString, err := c.Cookie("jwt")
if err != nil { if err != nil {

View File

@@ -15,11 +15,11 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll
router.POST("/users/login", userController.LoginHandler) router.POST("/users/login", userController.LoginHandler)
router.POST("/csp-report", middlewares.CSPReportHandling) router.POST("/csp-report", middlewares.CSPReportHandling)
apiRouter := router.Group("/api") // apiRouter := router.Group("/api")
apiRouter.Use(middlewares.APIKeyMiddleware()) // apiRouter.Use(middlewares.APIKeyMiddleware())
{ // {
apiRouter.POST("/v1/subscription", membershipcontroller.RegisterSubscription) // apiRouter.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
} // }
userRouter := router.Group("/backend/users") userRouter := router.Group("/backend/users")
userRouter.Use(middlewares.AuthMiddleware()) userRouter.Use(middlewares.AuthMiddleware())
@@ -36,6 +36,9 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll
membershipRouter.Use(middlewares.AuthMiddleware()) membershipRouter.Use(middlewares.AuthMiddleware())
{ {
membershipRouter.GET("/subscriptions", membershipcontroller.GetSubscriptions) membershipRouter.GET("/subscriptions", membershipcontroller.GetSubscriptions)
membershipRouter.PATCH("/subscriptions", membershipcontroller.UpdateHandler)
membershipRouter.POST("/subscriptions", membershipcontroller.RegisterSubscription)
} }
licenceRouter := router.Group("/backend/licence") licenceRouter := router.Group("/backend/licence")

View File

@@ -46,7 +46,7 @@ func Run() {
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo} userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, LicenceService: licenceService, BankAccountService: bankAccountService, MembershipService: membershipService} userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, LicenceService: licenceService, BankAccountService: bankAccountService, MembershipService: membershipService}
membershipController := &controllers.MembershipController{Service: *membershipService} membershipController := &controllers.MembershipController{Service: *membershipService, UserController: userController}
licenceController := &controllers.LicenceController{Service: *licenceService} licenceController := &controllers.LicenceController{Service: *licenceService}
contactController := &controllers.ContactController{EmailService: emailService} contactController := &controllers.ContactController{EmailService: emailService}

View File

@@ -36,7 +36,7 @@ func HandleValidationError(c *gin.Context, err error) {
c.JSON(http.StatusBadRequest, gin.H{"errors": validationErrors}) c.JSON(http.StatusBadRequest, gin.H{"errors": validationErrors})
} }
func HandleUpdateError(c *gin.Context, err error) { func HandleUserUpdateError(c *gin.Context, err error) {
switch err { switch err {
case errors.ErrUserNotFound: case errors.ErrUserNotFound:
RespondWithError(c, err, "Error while updating user", http.StatusNotFound, "user", "server.validation.user_not_found") RespondWithError(c, err, "Error while updating user", http.StatusNotFound, "user", "server.validation.user_not_found")