diff --git a/internal/handlers/active_area.go b/internal/handlers/active_area.go index 671db1c7..332151b1 100644 --- a/internal/handlers/active_area.go +++ b/internal/handlers/active_area.go @@ -12,6 +12,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/active_areas" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" @@ -42,17 +43,17 @@ func (area ActiveArea) GetActiveAreasFunc(repository domain.ActiveAreaRepository orderColumn := utils.GetValueByPointerOrDefaultValue(a.OrderColumn, order.FieldID) total, err := repository.TotalActiveAreas(ctx) if err != nil { - area.logger.Error("failed to query total active areas", zap.Error(err)) + area.logger.Error(messages.ErrQueryTotalAreas, zap.Error(err)) return active_areas.NewGetAllActiveAreasDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalAreas, err.Error())) } var e []*ent.ActiveArea if total > 0 { e, err = repository.AllActiveAreas(ctx, int(limit), int(offset), orderBy, orderColumn) if err != nil { - area.logger.Error("failed to query active areas", zap.Error(err)) + area.logger.Error(messages.ErrQueryAreas, zap.Error(err)) return active_areas.NewGetAllActiveAreasDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrQueryAreas, err.Error())) } } totalAreas := int64(total) diff --git a/internal/handlers/category.go b/internal/handlers/category.go index 124690ae..a51fabc9 100644 --- a/internal/handlers/category.go +++ b/internal/handlers/category.go @@ -12,6 +12,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/categories" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" @@ -43,9 +44,9 @@ func (c *Category) CreateNewCategoryFunc(repository domain.CategoryRepository) c ctx := s.HTTPRequest.Context() createdCategory, err := repository.CreateCategory(ctx, *s.NewCategory) if err != nil { - c.logger.Error("cant create new category", zap.Error(err)) + c.logger.Error(messages.ErrCreateCategory, zap.Error(err)) return categories.NewCreateNewCategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant create new category")) + WithPayload(buildInternalErrorPayload(messages.ErrCreateCategory, err.Error())) } return categories.NewCreateNewCategoryCreated().WithPayload(&models.CreateNewCategoryResponse{ Data: mapCategory(createdCategory), @@ -63,9 +64,9 @@ func (c *Category) GetAllCategoriesFunc(repository domain.CategoryRepository) ca total, err := repository.AllCategoriesTotal(ctx) if err != nil { - c.logger.Error("query total categories error", zap.Error(err)) + c.logger.Error(messages.ErrQueryTotalCategories, zap.Error(err)) return categories.NewGetAllCategoriesDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant get total amount of categories")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalCategories, err.Error())) } var allCategories []*ent.Category if total > 0 { @@ -82,9 +83,9 @@ func (c *Category) GetAllCategoriesFunc(repository domain.CategoryRepository) ca } allCategories, err = repository.AllCategories(ctx, filter) if err != nil { - c.logger.Error("query all category error", zap.Error(err)) + c.logger.Error(messages.ErrQueryCategories, zap.Error(err)) return categories.NewGetAllCategoriesDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant get all categories")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryCategories, err.Error())) } } mappedCategories := make([]*models.Category, len(allCategories)) @@ -105,9 +106,9 @@ func (c *Category) GetCategoryByIDFunc(repository domain.CategoryRepository) cat ctx := s.HTTPRequest.Context() category, err := repository.CategoryByID(ctx, int(s.CategoryID)) if err != nil { - c.logger.Error("failed to get category", zap.Error(err)) + c.logger.Error(messages.ErrGetCategory, zap.Error(err)) return categories.NewGetCategoryByIDDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to get category")) + WithPayload(buildInternalErrorPayload(messages.ErrGetCategory, err.Error())) } return categories.NewGetCategoryByIDOK().WithPayload(&models.GetCategoryByIDResponse{ Data: mapCategory(category), @@ -120,11 +121,11 @@ func (c *Category) DeleteCategoryFunc(repository domain.CategoryRepository) cate ctx := s.HTTPRequest.Context() err := repository.DeleteCategoryByID(ctx, int(s.CategoryID)) if err != nil { - c.logger.Error("delete category failed", zap.Error(err)) + c.logger.Error(messages.ErrDeleteCategory, zap.Error(err)) return categories.NewDeleteCategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("delete category failed")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteCategory, err.Error())) } - return categories.NewDeleteCategoryOK().WithPayload("category deleted") + return categories.NewDeleteCategoryOK().WithPayload(messages.MsgCategoryDeleted) } } @@ -133,9 +134,9 @@ func (c *Category) UpdateCategoryFunc(repository domain.CategoryRepository) cate ctx := s.HTTPRequest.Context() updatedCategory, err := repository.UpdateCategory(ctx, int(s.CategoryID), *s.UpdateCategory) if err != nil { - c.logger.Error("cant update category", zap.Error(err)) + c.logger.Error(messages.ErrUpdateCategory, zap.Error(err)) return categories.NewUpdateCategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant update category")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateCategory, err.Error())) } return categories.NewUpdateCategoryOK().WithPayload(&models.UpdateCategoryResponse{ diff --git a/internal/handlers/common.go b/internal/handlers/common.go index 666294cc..bbb92cff 100644 --- a/internal/handlers/common.go +++ b/internal/handlers/common.go @@ -1,19 +1,39 @@ package handlers -import "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" +import ( + "net/http" -func buildErrorPayload(err error) *models.Error { - return &models.Error{ - Data: &models.ErrorData{ - Message: err.Error(), - }, + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" +) + +func buildErrorPayload(code int32, msg string, details string) *models.SwaggerError { + return &models.SwaggerError{ + Code: &code, + Message: &msg, + Details: details, // optional field for raw err messages } } -func buildStringPayload(msg string) *models.Error { - return &models.Error{ - Data: &models.ErrorData{ - Message: msg, - }, - } +func buildInternalErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusInternalServerError, msg, details) +} + +func buildExFailedErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusExpectationFailed, msg, details) +} + +func buildConflictErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusConflict, msg, details) +} + +func buildNotFoundErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusNotFound, msg, details) +} + +func buildForbiddenErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusForbidden, msg, details) +} + +func buildBadRequestErrorPayload(msg string, details string) *models.SwaggerError { + return buildErrorPayload(http.StatusBadRequest, msg, details) } diff --git a/internal/handlers/email_confirm.go b/internal/handlers/email_confirm.go index 9a342ec2..515d0539 100644 --- a/internal/handlers/email_confirm.go +++ b/internal/handlers/email_confirm.go @@ -3,8 +3,10 @@ package handlers import ( "net/http" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/email_confirm" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" "github.com/go-openapi/runtime/middleware" "go.uber.org/zap" @@ -33,11 +35,12 @@ func (e emailConfirmHandler) VerifyEmailConfirmTokenFunc() email_confirm.VerifyE token := s.Token err := e.emailConfirm.VerifyTokenAndChangeEmail(ctx, token) if err != nil { - e.logger.Error("Failed to verify email confirmation token", zap.Error(err)) + e.logger.Error(messages.ErrEmailConfirm, zap.Error(err)) return email_confirm.NewVerifyEmailConfirmTokenDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Failed to verify email confirmation token. Please try again later")) + WithPayload(buildInternalErrorPayload(messages.ErrEmailConfirm, err.Error())) } - return email_confirm.NewVerifyEmailConfirmTokenOK().WithPayload("You have successfully confirmed new email") + return email_confirm.NewVerifyEmailConfirmTokenOK().WithPayload( + models.EmailConfirmResponse(messages.MsgEmailConfirmed)) } } diff --git a/internal/handlers/equipment.go b/internal/handlers/equipment.go index fbb7b351..6043ff67 100644 --- a/internal/handlers/equipment.go +++ b/internal/handlers/equipment.go @@ -14,6 +14,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/equipment" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/roles" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" @@ -52,21 +53,21 @@ func (c Equipment) PostEquipmentFunc(eqRepo domain.EquipmentRepository, eqStatus ctx := s.HTTPRequest.Context() status, err := eqStatusNameRepo.GetByName(ctx, domain.EquipmentStatusAvailable) if err != nil { - c.logger.Error("Error while getting status", zap.Error(err)) + c.logger.Error(messages.ErrGetEqStatus, zap.Error(err)) return equipment.NewCreateNewEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while creating equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrCreateEquipment, err.Error())) } eq, err := eqRepo.CreateEquipment(ctx, *s.NewEquipment, status) if err != nil { - c.logger.Error("Error while creating equipment", zap.Error(err)) + c.logger.Error(messages.ErrCreateEquipment, zap.Error(err)) return equipment.NewCreateNewEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while creating equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrCreateEquipment, err.Error())) } returnEq, err := mapEquipmentResponse(eq) if err != nil { - c.logger.Error("Error while mapping equipment", zap.Error(err)) + c.logger.Error(messages.ErrMapEquipment, zap.Error(err)) return equipment.NewCreateNewEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while mapping equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrMapEquipment, err.Error())) } return equipment.NewCreateNewEquipmentCreated().WithPayload(returnEq) @@ -78,15 +79,15 @@ func (c Equipment) GetEquipmentFunc(repository domain.EquipmentRepository) equip ctx := s.HTTPRequest.Context() eq, err := repository.EquipmentByID(ctx, int(s.EquipmentID)) if err != nil { - c.logger.Error("Error while getting equipment", zap.Error(err)) + c.logger.Error(messages.ErrGetEquipment, zap.Error(err)) return equipment.NewGetEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEquipment, err.Error())) } returnEq, err := mapEquipmentResponse(eq) if err != nil { - c.logger.Error("Error while mapping equipment", zap.Error(err)) + c.logger.Error(messages.ErrMapEquipment, zap.Error(err)) return equipment.NewGetEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while mapping equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrMapEquipment, err.Error())) } return equipment.NewGetEquipmentOK().WithPayload(returnEq) } @@ -99,11 +100,11 @@ func (c Equipment) ArchiveEquipmentFunc(repository domain.EquipmentRepository) e if err != nil { if ent.IsNotFound(err) { return equipment.NewArchiveEquipmentNotFound(). - WithPayload(buildStringPayload(EquipmentNotFoundMsg)) + WithPayload(buildNotFoundErrorPayload(messages.ErrEquipmentNotFound, "")) } - c.logger.Error("Error while archiving equipment", zap.Error(err)) + c.logger.Error(messages.ErrEquipmentArchive, zap.Error(err)) return equipment.NewArchiveEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while archiving equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrEquipmentArchive, err.Error())) } return equipment.NewArchiveEquipmentNoContent() } @@ -114,25 +115,22 @@ func (c Equipment) DeleteEquipmentFunc(repository domain.EquipmentRepository) eq ctx := s.HTTPRequest.Context() eq, err := repository.EquipmentByID(ctx, int(s.EquipmentID)) if err != nil { - c.logger.Error("Error while getting equipment", zap.Error(err)) - return equipment.NewDeleteEquipmentDefault(http.StatusInternalServerError).WithPayload(&models.Error{ - Data: &models.ErrorData{ - Message: "Error while getting equipment", - }, - }) + c.logger.Error(messages.ErrGetEquipment, zap.Error(err)) + return equipment.NewDeleteEquipmentDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrDeleteEquipment, err.Error())) } err = repository.DeleteEquipmentByID(ctx, int(s.EquipmentID)) if err != nil { - c.logger.Error("Error while deleting equipment", zap.Error(err)) + c.logger.Error(messages.ErrDeleteEquipment, zap.Error(err)) return equipment.NewDeleteEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while deleting equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteEquipment, err.Error())) } if err := repository.DeleteEquipmentPhoto(ctx, eq.Edges.Photo.ID); err != nil { c.logger.Error("Error while deleting photo from db", zap.Error(err)) } - return equipment.NewDeleteEquipmentOK().WithPayload("Equipment deleted") + return equipment.NewDeleteEquipmentOK().WithPayload(messages.MsgEquipmentDeleted) } } @@ -145,17 +143,17 @@ func (c Equipment) ListEquipmentFunc(repository domain.EquipmentRepository) equi orderColumn := utils.GetValueByPointerOrDefaultValue(s.OrderColumn, order.FieldID) total, err := repository.AllEquipmentsTotal(ctx) if err != nil { - c.logger.Error("Error while getting total of all equipments", zap.Error(err)) + c.logger.Error(messages.ErrQueryTotalEquipments, zap.Error(err)) return equipment.NewGetAllEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting total of all equipments")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalEquipments, err.Error())) } var equipments []*ent.Equipment if total > 0 { equipments, err = repository.AllEquipments(ctx, int(limit), int(offset), orderBy, orderColumn) if err != nil { - c.logger.Error("Error while getting all equipments", zap.Error(err)) + c.logger.Error(messages.ErrQueryEquipments, zap.Error(err)) return equipment.NewGetAllEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting all equipments")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryEquipments, err.Error())) } } totalEquipments := int64(total) @@ -166,9 +164,9 @@ func (c Equipment) ListEquipmentFunc(repository domain.EquipmentRepository) equi for i, eq := range equipments { tmpEq, errMap := mapEquipmentResponse(eq) if errMap != nil { - c.logger.Error("Error while mapping equipment", zap.Error(errMap)) + c.logger.Error(messages.ErrMapEquipment, zap.Error(errMap)) return equipment.NewGetAllEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while mapping equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrMapEquipment, errMap.Error())) } listEquipment.Items[i] = tmpEq } @@ -181,15 +179,15 @@ func (c Equipment) EditEquipmentFunc(repository domain.EquipmentRepository) equi ctx := s.HTTPRequest.Context() eq, err := repository.UpdateEquipmentByID(ctx, int(s.EquipmentID), s.EditEquipment) if err != nil { - c.logger.Error("Error while updating equipment", zap.Error(err)) + c.logger.Error(messages.ErrUpdateEquipment, zap.Error(err)) return equipment.NewEditEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while updating equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEquipment, err.Error())) } returnEq, err := mapEquipmentResponse(eq) if err != nil { - c.logger.Error("Error while mapping equipment", zap.Error(err)) + c.logger.Error(messages.ErrMapEquipment, zap.Error(err)) return equipment.NewEditEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while mapping equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrMapEquipment, err.Error())) } return equipment.NewEditEquipmentOK().WithPayload(returnEq) @@ -206,17 +204,17 @@ func (c Equipment) FindEquipmentFunc(repository domain.EquipmentRepository) equi equipmentFilter := *s.FindEquipment total, err := repository.EquipmentsByFilterTotal(ctx, equipmentFilter) if err != nil { - c.logger.Error("Error while getting total of all equipments", zap.Error(err)) + c.logger.Error(messages.ErrQueryTotalEquipments, zap.Error(err)) return equipment.NewGetAllEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting total of all equipments")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalEquipments, err.Error())) } var foundEquipment []*ent.Equipment if total > 0 { foundEquipment, err = repository.EquipmentsByFilter(ctx, equipmentFilter, int(limit), int(offset), orderBy, orderColumn) if err != nil { - c.logger.Error("Error while finding equipment", zap.Error(err)) + c.logger.Error(messages.ErrFindEquipment, zap.Error(err)) return equipment.NewFindEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while finding equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrFindEquipment, err.Error())) } } totalEquipments := int64(total) @@ -227,9 +225,9 @@ func (c Equipment) FindEquipmentFunc(repository domain.EquipmentRepository) equi for i, eq := range foundEquipment { tmpEq, errMap := mapEquipmentResponse(eq) if errMap != nil { - c.logger.Error("Error while mapping equipment", zap.Error(errMap)) + c.logger.Error(messages.ErrMapEquipment, zap.Error(errMap)) return equipment.NewFindEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while mapping equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrMapEquipment, errMap.Error())) } returnEquipment.Items[i] = tmpEq } @@ -314,21 +312,25 @@ func (c Equipment) BlockEquipmentFunc(repository domain.EquipmentRepository) equ c.logger.Warn("User have no right to block the equipment", zap.Any("principal", principal)) return equipment. NewBlockEquipmentDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{ - Message: "You don't have rights to block the equipment"}}) + WithPayload(buildForbiddenErrorPayload(messages.ErrEquipmentBlockForbidden, "")) + } + + startDate := time.Time(s.Data.StartDate) + endDate := time.Time(s.Data.EndDate) + if startDate.After(endDate) { + return equipment.NewBlockEquipmentDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrStartDateAfterEnd, "")) } - err := repository.BlockEquipment( - ctx, int(s.EquipmentID), time.Time(s.Data.StartDate), time.Time(s.Data.EndDate), userID, - ) + err := repository.BlockEquipment(ctx, int(s.EquipmentID), startDate, endDate, userID) if err != nil { if ent.IsNotFound(err) { return equipment.NewBlockEquipmentNotFound(). - WithPayload(buildStringPayload(EquipmentNotFoundMsg)) + WithPayload(buildNotFoundErrorPayload(messages.ErrEquipmentNotFound, "")) } - c.logger.Error("Error while blocking equipment", zap.Error(err)) + c.logger.Error(messages.ErrEquipmentBlock, zap.Error(err)) return equipment.NewBlockEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while blocking equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrEquipmentBlock, err.Error())) } return equipment.NewBlockEquipmentNoContent() } @@ -340,21 +342,21 @@ func (c Equipment) UnblockEquipmentFunc(repository domain.EquipmentRepository) e role := principal.Role if role != roles.Manager { - c.logger.Warn("User have no right to unblock the equipment", zap.Any("principal", principal)) + c.logger.Warn(messages.ErrEquipmentUnblockForbidden, zap.Any("principal", principal)) return equipment. NewUnblockEquipmentDefault(http.StatusForbidden). - WithPayload(buildStringPayload("You don't have rights to unblock the equipment")) + WithPayload(buildForbiddenErrorPayload(messages.ErrEquipmentUnblockForbidden, "")) } err := repository.UnblockEquipment(ctx, int(s.EquipmentID)) if err != nil { if ent.IsNotFound(err) { return equipment.NewUnblockEquipmentNotFound(). - WithPayload(buildStringPayload(EquipmentNotFoundMsg)) + WithPayload(buildNotFoundErrorPayload(messages.ErrEquipmentNotFound, "")) } - c.logger.Error("Error while unblocking equipment", zap.Error(err)) + c.logger.Error(messages.ErrEquipmentUnblock, zap.Error(err)) return equipment.NewUnblockEquipmentDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while unblocking equipment")) + WithPayload(buildInternalErrorPayload(messages.ErrEquipmentUnblock, err.Error())) } return equipment.NewUnblockEquipmentNoContent() } diff --git a/internal/handlers/equipment_periods.go b/internal/handlers/equipment_periods.go index 4d7b9520..51281a8f 100644 --- a/internal/handlers/equipment_periods.go +++ b/internal/handlers/equipment_periods.go @@ -7,6 +7,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" eqPeriods "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/equipment" eqStatus "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/equipment_status" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" "github.com/go-openapi/runtime/middleware" @@ -44,12 +45,9 @@ func (c EquipmentPeriods) GetEquipmentUnavailableDatesFunc( equipmentStatuses, err := eqStatusRepository.GetUnavailableEquipmentStatusByEquipmentID(ctx, id) if err != nil { - c.logger.Error( - "error during the search for unavailable equipment status dates", - zap.Error(err), - ) + c.logger.Error(messages.ErrGetUnavailableEqStatus, zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't find unavailable equipment status dates")) + WithPayload(buildInternalErrorPayload(messages.ErrGetUnavailableEqStatus, err.Error())) } var result []*models.EquipmentUnavailabilityPeriods diff --git a/internal/handlers/equipment_status.go b/internal/handlers/equipment_status.go index 49543713..c6e4eddd 100644 --- a/internal/handlers/equipment_status.go +++ b/internal/handlers/equipment_status.go @@ -8,6 +8,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" eqStatus "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/equipment_status" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/orders" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" "github.com/go-openapi/runtime/middleware" @@ -51,9 +52,9 @@ func (c EquipmentStatus) GetEquipmentStatusCheckDatesFunc( newStatus := s.Name.StatusName if !newStatusIsUnavailable(*newStatus) { - c.logger.Error("Wrong new equipment status, status should be only 'not available'", zap.Any("principal", principal)) - return orders.NewAddNewOrderStatusDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Wrong new equipment status, status should be only 'not available'"}}) + c.logger.Error(messages.ErrWrongEqStatus, zap.Any("principal", principal)) + return orders.NewAddNewOrderStatusDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrWrongEqStatus, "")) } data := models.EquipmentStatus{ @@ -68,7 +69,7 @@ func (c EquipmentStatus) GetEquipmentStatusCheckDatesFunc( if err != nil { c.logger.Error("receiving equipment status by id failed during checking start/end dates", zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't find equipment status by provided id")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatusByID, err.Error())) } if !eqStatusResult.EndDate.After(time.Time(*data.StartDate)) && @@ -81,9 +82,9 @@ func (c EquipmentStatus) GetEquipmentStatusCheckDatesFunc( orderResult, userResult, err := eqStatusRepository.GetOrderAndUserByEquipmentStatusID( ctx, int(*data.ID)) if err != nil { - c.logger.Error("receiving order and user data failed", zap.Error(err)) + c.logger.Error(messages.ErrOrderAndUserByEqStatusID, zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't receive order and user data during checking equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrOrderAndUserByEqStatusID, err.Error())) } if orderResult == nil && userResult == nil { @@ -116,9 +117,9 @@ func (c EquipmentStatus) PutEquipmentStatusInRepairFunc( newStatus := s.Name.StatusName if !newStatusIsUnavailable(*newStatus) { - c.logger.Error("Wrong new equipment status, status should be only 'not available'", zap.Any("principal", principal)) - return orders.NewAddNewOrderStatusDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Wrong new equipment status, status should be only 'not available'"}}) + c.logger.Error(messages.ErrWrongEqStatus, zap.Any("principal", principal)) + return orders.NewAddNewOrderStatusDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrWrongEqStatus, "")) } reduceOneDayFromCurrentStartDate := strfmt.DateTime( @@ -139,16 +140,16 @@ func (c EquipmentStatus) PutEquipmentStatusInRepairFunc( orderResult, userResult, err := eqStatusRepository.GetOrderAndUserByEquipmentStatusID( ctx, int(*data.ID)) if err != nil { - c.logger.Error("receiving user and order status failed", zap.Error(err)) + c.logger.Error(messages.ErrOrderAndUserByEqStatusID, zap.Error(err)) return eqStatus.NewUpdateEquipmentStatusOnUnavailableDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't receive order and user for updating equipment status on unavailable")) + WithPayload(buildInternalErrorPayload(messages.ErrOrderAndUserByEqStatusID, err.Error())) } updatedEqStatus, err := eqStatusRepository.Update(ctx, &data) if err != nil { - c.logger.Error("update equipment status failed", zap.Error(err)) + c.logger.Error(messages.ErrUpdateEqStatus, zap.Error(err)) return eqStatus.NewUpdateEquipmentStatusOnUnavailableDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't update equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } comment := EQUIPMENT_UNDER_REPAIR_COMMENT_FOR_ORDER @@ -163,9 +164,9 @@ func (c EquipmentStatus) PutEquipmentStatusInRepairFunc( err = orderStatusRepo.UpdateStatus(ctx, userResult.ID, model) if err != nil { - c.logger.Error("Update order status error", zap.Error(err)) + c.logger.Error(messages.ErrUpdateOrderStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't update order status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateOrderStatus, err.Error())) } eqStatusResult, err := eqStatusRepository.GetEquipmentStatusByID( @@ -173,7 +174,7 @@ func (c EquipmentStatus) PutEquipmentStatusInRepairFunc( if err != nil { c.logger.Error("receiving equipment status by id failed during changing status to unavailable", zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't find equipment status by provided id")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatusByID, err.Error())) } equipmentStatusID := int64(updatedEqStatus.ID) @@ -200,9 +201,9 @@ func (c EquipmentStatus) DeleteEquipmentStatusFromRepairFunc( newStatus := s.Name.StatusName if !newStatusIsAvailable(*newStatus) { - c.logger.Error("Wrong new equipment status, status should be only 'available'", zap.Any("principal", principal)) - return orders.NewAddNewOrderStatusDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Wrong new equipment status, status should be only 'not available'"}}) + c.logger.Error(messages.ErrWrongEqStatus, zap.Any("principal", principal)) + return orders.NewAddNewOrderStatusDefault(http.StatusBadGateway). + WithPayload(buildBadRequestErrorPayload(messages.ErrWrongEqStatus, "")) } timeNow := timeNowEquipmentStatus() @@ -219,7 +220,7 @@ func (c EquipmentStatus) DeleteEquipmentStatusFromRepairFunc( if err != nil { c.logger.Error("update equipment on available status failed", zap.Error(err)) return eqStatus.NewUpdateEquipmentStatusOnAvailableDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't update equipment status on available status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } eqStatusResult, err := eqStatusRepository.GetEquipmentStatusByID( @@ -227,7 +228,7 @@ func (c EquipmentStatus) DeleteEquipmentStatusFromRepairFunc( if err != nil { c.logger.Error("receiving equipment status by id failed during changing status to available", zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't find equipment status by provided id")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatusByID, err.Error())) } equipmentStatusID := int64(updatedEqStatus.ID) @@ -257,7 +258,7 @@ func (c EquipmentStatus) PatchEquipmentStatusEditDatesFunc( if err != nil { c.logger.Error("receiving equipment status by id failed during editing dates", zap.Error(err)) return eqStatus.NewCheckEquipmentStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't find equipment status by provided id")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatusByID, err.Error())) } if !time.Time(s.Name.StartDate).IsZero() { @@ -278,7 +279,7 @@ func (c EquipmentStatus) PatchEquipmentStatusEditDatesFunc( if err != nil { c.logger.Error("update equipment on available status failed during editing dates", zap.Error(err)) return eqStatus.NewUpdateRepairedEquipmentStatusDatesDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't update equipment status on available status during editing dates")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } equipmentStatusID := int64(updatedEqStatus.ID) diff --git a/internal/handlers/equipment_status_name.go b/internal/handlers/equipment_status_name.go index 1fd80adb..bd859228 100644 --- a/internal/handlers/equipment_status_name.go +++ b/internal/handlers/equipment_status_name.go @@ -10,6 +10,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" eqStatusName "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/equipment_status_name" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -40,9 +41,9 @@ func (c EquipmentStatusName) PostEquipmentStatusNameFunc(repository domain.Equip name := s.Name.Name createdStatus, err := repository.Create(ctx, *name) if err != nil { - c.logger.Error("create status failed", zap.Error(err)) + c.logger.Error(messages.ErrCreateEqStatus, zap.Error(err)) return eqStatusName.NewPostEquipmentStatusNameDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't create status")) + WithPayload(buildInternalErrorPayload(messages.ErrCreateEqStatus, err.Error())) } return eqStatusName.NewPostEquipmentStatusNameCreated().WithPayload(&models.SuccessEquipmentStatusNameOperationResponse{ @@ -56,9 +57,9 @@ func (c EquipmentStatusName) ListEquipmentStatusNamesFunc(repository domain.Equi ctx := s.HTTPRequest.Context() statuses, err := repository.GetAll(ctx) if err != nil { - c.logger.Error("get statuses failed", zap.Error(err)) + c.logger.Error(messages.ErrQueryEqStatuses, zap.Error(err)) return eqStatusName.NewListEquipmentStatusNamesDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't get statuses")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryEqStatuses, err.Error())) } listStatuses := models.ListEquipmentStatusNames{} for _, element := range statuses { @@ -73,9 +74,9 @@ func (c EquipmentStatusName) GetEquipmentStatusNameFunc(repository domain.Equipm ctx := s.HTTPRequest.Context() foundStatus, err := repository.Get(ctx, int(s.StatusID)) if err != nil { - c.logger.Error("get status failed", zap.Error(err)) + c.logger.Error(messages.ErrGetEqStatus, zap.Error(err)) return eqStatusName.NewGetEquipmentStatusNameDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't get status")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatus, err.Error())) } return eqStatusName.NewGetEquipmentStatusNameOK().WithPayload(&models.SuccessEquipmentStatusNameOperationResponse{ @@ -89,9 +90,9 @@ func (c EquipmentStatusName) DeleteEquipmentStatusNameFunc(repository domain.Equ ctx := s.HTTPRequest.Context() deletedStatus, err := repository.Delete(ctx, int(s.StatusID)) if err != nil { - c.logger.Error("delete status failed", zap.Error(err)) + c.logger.Error(messages.ErrDeleteEqStatus, zap.Error(err)) return eqStatusName.NewDeleteEquipmentStatusNameDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't delete status")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteEqStatus, err.Error())) } return eqStatusName.NewDeleteEquipmentStatusNameOK().WithPayload( &models.SuccessEquipmentStatusNameOperationResponse{ diff --git a/internal/handlers/order.go b/internal/handlers/order.go index d721249c..516e6827 100644 --- a/internal/handlers/order.go +++ b/internal/handlers/order.go @@ -16,6 +16,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/orders" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" @@ -221,30 +222,32 @@ func (o Order) ListUserOrdersFunc(repository domain.OrderRepository) orders.GetU _, ok := domain.AllOrderStatuses[*p.Status] if !ok { return orders.NewGetUserOrdersDefault(http.StatusBadRequest). - WithPayload(buildStringPayload(fmt.Sprintf("Invalid order status '%v'", *p.Status))) + WithPayload(buildBadRequestErrorPayload(messages.ErrQueryOrders, fmt.Sprintf("invalid order status '%v'", *p.Status))) } } total, err := repository.OrdersTotal(ctx, &userID) if err != nil { - o.logger.Error("Error while getting total of all user's orders", zap.Error(err)) + o.logger.Error(messages.ErrQueryTotalOrders, zap.Error(err)) return orders.NewGetUserOrdersDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildBadRequestErrorPayload(messages.ErrQueryTotalOrders, err.Error())) } var items []*ent.Order if total > 0 { items, err = repository.List(ctx, &userID, orderFilter) if err != nil { - o.logger.Error("list items failed", zap.Error(err)) - return orders.NewGetUserOrdersDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrQueryOrders, zap.Error(err)) + return orders.NewGetUserOrdersDefault(http.StatusInternalServerError). + WithPayload(buildBadRequestErrorPayload(messages.ErrQueryOrders, err.Error())) } } mappedOrders, err := mapUserOrdersToResponse(items, o.logger) if err != nil { - o.logger.Error("map orders to response failed", zap.Error(err)) - return orders.NewGetUserOrdersDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrMapOrder, zap.Error(err)) + return orders.NewGetUserOrdersDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, err.Error())) } totalOrders := int64(total) listOrders := &models.UserOrdersList{ @@ -276,7 +279,7 @@ func (o Order) ListAllOrdersFunc(repository domain.OrderRepository) orders.GetAl _, ok := domain.AllOrderStatuses[*p.Status] if !ok { return orders.NewGetAllOrdersDefault(http.StatusBadRequest). - WithPayload(buildStringPayload(fmt.Sprintf("Invalid order status '%v'", *p.Status))) + WithPayload(buildBadRequestErrorPayload(messages.ErrQueryOrders, fmt.Sprintf("invalid order status '%v'", *p.Status))) } orderFilter.Status = p.Status } @@ -288,24 +291,26 @@ func (o Order) ListAllOrdersFunc(repository domain.OrderRepository) orders.GetAl total, err := repository.OrdersTotal(ctx, nil) if err != nil { - o.logger.Error("Error while getting total of all orders", zap.Error(err)) + o.logger.Error(messages.ErrQueryTotalOrders, zap.Error(err)) return orders.NewGetAllOrdersDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalOrders, err.Error())) } var items []*ent.Order if total > 0 { items, err = repository.List(ctx, nil, orderFilter) if err != nil { - o.logger.Error("list items failed", zap.Error(err)) - return orders.NewGetAllOrdersDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrQueryOrders, zap.Error(err)) + return orders.NewGetAllOrdersDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrQueryOrders, err.Error())) } } mappedOrders, err := mapOrdersToResponse(items, o.logger) if err != nil { - o.logger.Error("map orders to response failed", zap.Error(err)) - return orders.NewGetAllOrdersDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrMapOrder, zap.Error(err)) + return orders.NewGetAllOrdersDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, err.Error())) } totalOrders := int64(total) listOrders := &models.OrdersList{ @@ -329,20 +334,35 @@ func (o Order) CreateOrderFunc( isEquipmentAvailable, err := eqStatusRepo.HasStatusByPeriod(ctx, domain.EquipmentStatusAvailable, id, time.Time(*p.Data.RentStart), time.Time(*p.Data.RentEnd)) if err != nil { - o.logger.Error("error while checking if equipment is available for period", zap.Error(err)) - return orders.NewCreateOrderDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrCheckEqStatusFailed, zap.Error(err)) + return orders.NewCreateOrderDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrCheckEqStatusFailed, err.Error())) } if !isEquipmentAvailable { - o.logger.Warn("equipment is not free") - return orders.NewCreateOrderDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("requested equipment is not free")) + o.logger.Warn(messages.ErrEquipmentIsNotFree) + return orders.NewCreateOrderDefault(http.StatusConflict). + WithPayload(buildConflictErrorPayload(messages.ErrEquipmentIsNotFree, "")) + } + + rentStart := time.Time(*p.Data.RentStart) + rentEnd := time.Time(*p.Data.RentEnd) + + if rentStart.After(rentEnd) { + return orders.NewCreateOrderDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrStartDateAfterEnd, "")) + } + + if rentEnd.Sub(rentStart).Hours() < 24 { + return orders.NewCreateOrderDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrSmallRentPeriod, "")) } order, err := orderRepo.Create(ctx, p.Data, userID, []int{id}) if err != nil { - o.logger.Error("map orders to response failed", zap.Error(err)) - return orders.NewCreateOrderDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrMapOrder, zap.Error(err)) + return orders.NewCreateOrderDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, err.Error())) } equipmentBookedStartDate := strfmt.DateTime(time.Time(*p.Data.RentStart).AddDate(0, 0, -1)) @@ -355,15 +375,16 @@ func (o Order) CreateOrderFunc( StatusName: &domain.EquipmentStatusBooked, OrderID: int64(order.ID), }); err != nil { - o.logger.Error("error while creating equipment status", zap.Error(err)) - return orders.NewGetUserOrdersDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrCreateEqStatus, zap.Error(err)) + return orders.NewGetAllOrdersDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrCreateEqStatus, err.Error())) } mappedOrder, err := mapUserOrder(order, o.logger) if err != nil { - o.logger.Error("failed to map order", zap.Error(err)) - return orders.NewGetUserOrdersDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrMapOrder, zap.Error(err)) + return orders.NewGetAllOrdersDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, err.Error())) } return orders.NewCreateOrderCreated().WithPayload(mappedOrder) @@ -378,14 +399,16 @@ func (o Order) UpdateOrderFunc(repository domain.OrderRepository) orders.UpdateO order, err := repository.Update(ctx, orderID, p.Data, userID) if err != nil { - o.logger.Error("update order failed", zap.Error(err)) - return orders.NewUpdateOrderDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrUpdateOrder, zap.Error(err)) + return orders.NewUpdateOrderDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrUpdateOrder, err.Error())) } mappedOrder, err := mapUserOrder(order, o.logger) if err != nil { - o.logger.Error("failed to map order", zap.Error(err)) - return orders.NewUpdateOrderDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + o.logger.Error(messages.ErrMapOrder, zap.Error(err)) + return orders.NewUpdateOrderDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, err.Error())) } return orders.NewUpdateOrderOK().WithPayload(mappedOrder) diff --git a/internal/handlers/order_status.go b/internal/handlers/order_status.go index 3df522e3..bf2243fb 100644 --- a/internal/handlers/order_status.go +++ b/internal/handlers/order_status.go @@ -17,6 +17,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/orders" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/roles" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" @@ -59,17 +60,18 @@ func (h *OrderStatus) OrderStatusesHistory(repository domain.OrderStatusReposito history, err := repository.StatusHistory(ctx, orderID) if err != nil { h.logger.Error("ListOrderStatus error", zap.Error(err)) - return orders.NewGetFullOrderHistoryDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + return orders.NewGetFullOrderHistoryDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrQueryOrderHistory, err.Error())) } if !canUserAccessOrderHistory(userID, role, history) { h.logger.Warn("User have no right to get order history", zap.Any("principal", principal)) return orders.NewGetFullOrderHistoryDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "You don't have rights to see this order"}}) + WithPayload(buildForbiddenErrorPayload(messages.ErrQueryOrderHistoryForbidden, "")) } if len(history) == 0 { - h.logger.Info("No order with such id", zap.Int("order_id", orderID)) - return orders.NewGetFullOrderHistoryNotFound().WithPayload("No order with such id") + h.logger.Info(messages.ErrOrderNotFound, zap.Int("order_id", orderID)) + return orders.NewGetFullOrderHistoryNotFound().WithPayload(messages.ErrOrderNotFound) } result := make([]*models.OrderStatus, len(history)) for index, status := range history { @@ -77,7 +79,8 @@ func (h *OrderStatus) OrderStatusesHistory(repository domain.OrderStatusReposito if mapErr != nil { h.logger.Error("ListOrderStatus error", zap.Error(mapErr)) - return orders.NewGetFullOrderHistoryDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(mapErr)) + return orders.NewGetFullOrderHistoryDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrQueryOrderHistory, mapErr.Error())) } result[index] = tmpStatus } @@ -157,16 +160,16 @@ func (h *OrderStatus) AddNewStatusToOrder( newOrderStatus := params.Data.Status if newOrderStatus == nil { - h.logger.Error("Status is empty") + h.logger.Error(messages.ErrOrderStatusEmpty) return orders.NewAddNewOrderStatusDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Status is empty")) + WithPayload(buildBadRequestErrorPayload(messages.ErrOrderStatusEmpty, "")) } currentOrderStatus, err := orderStatusRepo.GetOrderCurrentStatus(ctx, int(*params.Data.OrderID)) if err != nil { - h.logger.Error("getting order current status failed", zap.Error(err)) + h.logger.Error(messages.ErrGetOrderStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't get order current status")) + WithPayload(buildInternalErrorPayload(messages.ErrGetOrderStatus, err.Error())) } canUserCancelOrder := canUserCancelOrder(userID, currentOrderStatus, *newOrderStatus) @@ -175,7 +178,7 @@ func (h *OrderStatus) AddNewStatusToOrder( if !canUserCancelOrder && !canRoleChangeStatus { h.logger.Error("User does not have the right to create an order status", zap.Any("principal", principal)) return orders.NewAddNewOrderStatusDefault(http.StatusForbidden). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "You don't have rights to add a new status"}}) + WithPayload(buildForbiddenErrorPayload(messages.ErrCreateOrderStatusForbidden, "")) } orderID := currentOrderStatus.Edges.Order.ID @@ -183,20 +186,20 @@ func (h *OrderStatus) AddNewStatusToOrder( if err != nil { h.logger.Error("GetEquipmentStatusByOrder error", zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't get equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrGetEqStatus, err.Error())) } err = checkEqStatusRequirements(*newOrderStatus, h.logger, orderEquipmentStatuses) if err != nil { return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateOrderStatus, err.Error())) } err = orderStatusRepo.UpdateStatus(ctx, userID, *params.Data) if err != nil { - h.logger.Error("Update order status error", zap.Error(err)) + h.logger.Error(messages.ErrUpdateOrderStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't update status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateOrderStatus, err.Error())) } switch *newOrderStatus { @@ -207,9 +210,9 @@ func (h *OrderStatus) AddNewStatusToOrder( } err = UpdateEqStatuses(ctx, equipmentStatusRepo, orderEquipmentStatuses, model) if err != nil { - h.logger.Error("Update equipment status error", zap.Error(err)) + h.logger.Error(messages.ErrUpdateEqStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't update equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } case domain.OrderStatusInProgress: @@ -219,9 +222,9 @@ func (h *OrderStatus) AddNewStatusToOrder( } err = UpdateEqStatuses(ctx, equipmentStatusRepo, orderEquipmentStatuses, model) if err != nil { - h.logger.Error("Update equipment status error", zap.Error(err)) + h.logger.Error(messages.ErrUpdateEqStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't update equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } case domain.OrderStatusClosed: @@ -254,13 +257,13 @@ func (h *OrderStatus) AddNewStatusToOrder( err = UpdateEqStatuses(ctx, equipmentStatusRepo, orderEquipmentStatuses, model) if err != nil { - h.logger.Error("Update equipment status error", zap.Error(err)) + h.logger.Error(messages.ErrUpdateEqStatus, zap.Error(err)) return orders.NewAddNewOrderStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't update equipment status")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateEqStatus, err.Error())) } } - return orders.NewAddNewOrderStatusOK().WithPayload("all ok") + return orders.NewAddNewOrderStatusOK().WithPayload(messages.MsgAllOk) } } @@ -276,7 +279,7 @@ func (h *OrderStatus) GetOrdersByStatus(repository domain.OrderRepositoryWithFil if err != nil { h.logger.Error("GetOrdersByStatus error", zap.Error(err)) return orders.NewGetOrdersByStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload(fmt.Sprintf("Can't get total count of orders by status. error: %s", err.Error()))) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalOrdersByStatus, err.Error())) } var ordersByStatus []*ent.Order @@ -285,7 +288,7 @@ func (h *OrderStatus) GetOrdersByStatus(repository domain.OrderRepositoryWithFil if err != nil { h.logger.Error("GetOrdersByStatus error", zap.Error(err)) return orders.NewGetOrdersByStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload(fmt.Sprintf("Can't get orders by status. error: %s", err.Error()))) + WithPayload(buildInternalErrorPayload(messages.ErrQueryOrdersByStatus, err.Error())) } } ordersResult := make([]*models.UserOrder, len(ordersByStatus)) @@ -294,7 +297,7 @@ func (h *OrderStatus) GetOrdersByStatus(repository domain.OrderRepositoryWithFil if errMap != nil { h.logger.Error("GetOrdersByStatus error", zap.Error(errMap)) return orders.NewGetOrdersByStatusDefault(http.StatusInternalServerError). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Can't map order"}}) + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, errMap.Error())) } ordersResult[index] = tmpOrder } @@ -321,7 +324,7 @@ func (h *OrderStatus) GetOrdersByPeriodAndStatus(repository domain.OrderReposito if err != nil { h.logger.Error("GetOrdersByPeriodAndStatus error", zap.Error(err)) return orders.NewGetOrdersByDateAndStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't get total amount of orders by period and status")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalOrdersByPeriodAndStatus, err.Error())) } var ordersByPeriodAndStatus []*ent.Order @@ -332,7 +335,7 @@ func (h *OrderStatus) GetOrdersByPeriodAndStatus(repository domain.OrderReposito if err != nil { h.logger.Error("GetOrdersByPeriodAndStatus error", zap.Error(err)) return orders.NewGetOrdersByDateAndStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't get orders by period and status")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryOrdersByPeriodAndStatus, err.Error())) } } ordersResult := make([]*models.UserOrder, len(ordersByPeriodAndStatus)) @@ -341,7 +344,7 @@ func (h *OrderStatus) GetOrdersByPeriodAndStatus(repository domain.OrderReposito if errMap != nil { h.logger.Error("GetOrdersByPeriodAndStatus error", zap.Error(errMap)) return orders.NewGetOrdersByDateAndStatusDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't map order")) + WithPayload(buildInternalErrorPayload(messages.ErrMapOrder, errMap.Error())) } ordersResult[index] = tmpOrder } @@ -364,15 +367,15 @@ func (h *OrderStatus) GetAllStatusNames(repository domain.OrderStatusNameReposit if err != nil { h.logger.Error("GetAllStatusNames error", zap.Error(err)) return orders.NewGetAllStatusNamesDefault(http.StatusInternalServerError). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Can't get all status names"}}) + WithPayload(buildInternalErrorPayload(messages.ErrQueryStatusNames, err.Error())) } statusNamesResult := make([]*models.OrderStatusName, len(statusNames)) for index, statusName := range statusNames { tmpStatusName, errMap := MapOrderStatusName(statusName) if errMap != nil { - h.logger.Error("Cant map ent order status name to model order status name", zap.Error(errMap)) + h.logger.Error(messages.ErrMapOrderStatus, zap.Error(errMap)) return orders.NewGetAllStatusNamesDefault(http.StatusInternalServerError). - WithPayload(&models.Error{Data: &models.ErrorData{Message: "Can't map order status name"}}) + WithPayload(buildInternalErrorPayload(messages.ErrMapOrderStatus, errMap.Error())) } statusNamesResult[index] = tmpStatusName } diff --git a/internal/handlers/order_status_test.go b/internal/handlers/order_status_test.go index da9963e2..1307b9d4 100644 --- a/internal/handlers/order_status_test.go +++ b/internal/handlers/order_status_test.go @@ -1049,12 +1049,13 @@ func (s *OrderStatusTestSuite) TestOrderStatus_AddNewStatusToOrder_ApprovedToPre responseRecorder := httptest.NewRecorder() producer := runtime.JSONProducer() resp.WriteResponse(responseRecorder, producer) - response := models.Error{} + response := models.SwaggerError{} err := json.Unmarshal(responseRecorder.Body.Bytes(), &response) require.NoError(t, err) require.NotEmpty(t, response) - require.NotEmpty(t, response.Data) - require.Contains(t, response.Data.Message, "equipment IDs don't have correspondent status: [1]") + require.NotEmpty(t, response.Message) + require.Contains(t, *response.Message, "can't update status") + require.Contains(t, response.Details, "equipment IDs don't have correspondent status: [1]") require.Equal(t, http.StatusInternalServerError, responseRecorder.Code) s.orderStatusRepository.AssertExpectations(t) } diff --git a/internal/handlers/order_test.go b/internal/handlers/order_test.go index ecb25fc4..685bb720 100644 --- a/internal/handlers/order_test.go +++ b/internal/handlers/order_test.go @@ -3,7 +3,6 @@ package handlers import ( "encoding/json" "errors" - "fmt" "math" "net/http" "net/http/httptest" @@ -151,14 +150,14 @@ func (s *orderTestSuite) TestOrder_ListUserOrders_WrongStatus() { producer := runtime.JSONProducer() resp.WriteResponse(responseRecorder, producer) - var response models.Error + var response models.SwaggerError err := json.Unmarshal(responseRecorder.Body.Bytes(), &response) if err != nil { t.Fatal(err) } require.Equal(t, http.StatusBadRequest, responseRecorder.Code) - require.Equal(t, fmt.Sprintf("Invalid order status '%v'", st), response.Data.Message) + require.Equal(t, "can't get orders", *response.Message) } func (s *orderTestSuite) TestOrder_ListUserOrders_MapErr() { @@ -832,7 +831,7 @@ func (s *orderTestSuite) TestOrder_CreateOrder_NoAvailableEquipments() { responseRecorder := httptest.NewRecorder() producer := runtime.JSONProducer() resp.WriteResponse(responseRecorder, producer) - require.Equal(t, http.StatusInternalServerError, responseRecorder.Code) + require.Equal(t, http.StatusConflict, responseRecorder.Code) responseOrder := models.Order{} err := json.Unmarshal(responseRecorder.Body.Bytes(), &responseOrder) if err != nil { diff --git a/internal/handlers/password_reset.go b/internal/handlers/password_reset.go index 727cd767..6088f195 100644 --- a/internal/handlers/password_reset.go +++ b/internal/handlers/password_reset.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/password_reset" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -37,19 +38,17 @@ func (c passwordResetHandler) SendLinkByLoginFunc() password_reset.SendLinkByLog login := *s.Login.Data.Login if login == "" { c.logger.Warn("Login is empty") - return password_reset.NewSendLinkByLoginDefault(http.StatusBadRequest).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Login is required", - }, - }) + return password_reset.NewSendLinkByLoginDefault(http.StatusBadRequest). + WithPayload(buildBadRequestErrorPayload(messages.ErrLoginRequired, "")) } err := c.passwordReset.SendResetPasswordLink(ctx, login) if err != nil { c.logger.Error("Error while sending reset password link", zap.Error(err)) - return password_reset.NewSendLinkByLoginOK().WithPayload("Check your email for a reset link") + return password_reset.NewSendLinkByLoginOK().WithPayload( + models.PasswordResetResponse(messages.MsgPasswordResetSuccesful)) } - return password_reset.NewSendLinkByLoginOK().WithPayload("Check your email for a reset link") + return password_reset.NewSendLinkByLoginOK().WithPayload( + models.PasswordResetResponse(messages.MsgPasswordResetSuccesful)) } } diff --git a/internal/handlers/pet_kind.go b/internal/handlers/pet_kind.go index ada30290..5e7c15d9 100644 --- a/internal/handlers/pet_kind.go +++ b/internal/handlers/pet_kind.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/pet_kind" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -40,14 +41,14 @@ func (pk PetKind) CreatePetKindFunc(repository domain.PetKindRepository) pet_kin ctx := p.HTTPRequest.Context() petKind, err := repository.Create(ctx, *p.NewPetKind) if err != nil { - pk.logger.Error("Error while creating pet kind", zap.Error(err)) + pk.logger.Error(messages.ErrCreatePetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while creating pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePetKind, err.Error())) } if petKind == nil { pk.logger.Error("Pet kind is nil") return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while creating pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePetKind, "")) } id := int64(petKind.ID) return pet_kind.NewCreateNewPetKindCreated().WithPayload(&models.PetKindResponse{ @@ -63,13 +64,13 @@ func (pk PetKind) GetAllPetKindFunc(repository domain.PetKindRepository) pet_kin ctx := p.HTTPRequest.Context() petKinds, err := repository.GetAll(ctx) if err != nil { - pk.logger.Error("Error while getting pet kind", zap.Error(err)) + pk.logger.Error(messages.ErrGetPetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrGetPetKind, err.Error())) } if len(petKinds) == 0 { return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("No pet kind found")) + WithPayload(buildInternalErrorPayload(messages.ErrPetKindNotFound, "")) } listOfPetKind := models.ListOfPetKinds{} for _, v := range petKinds { @@ -86,13 +87,13 @@ func (pk PetKind) GetPetKindsByID(repo domain.PetKindRepository) pet_kind.GetPet ctx := p.HTTPRequest.Context() petKind, err := repo.GetByID(ctx, int(p.PetKindID)) if err != nil { - pk.logger.Error("Error while getting pet kind by id", zap.Error(err)) + pk.logger.Error(messages.ErrGetPetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrGetPetKind, err.Error())) } if petKind == nil { return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while getting pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrGetPetKind, "")) } id := int64(petKind.ID) return pet_kind.NewGetPetKindOK().WithPayload(&models.PetKindResponse{ID: &id, Name: &petKind.Name}) @@ -104,11 +105,11 @@ func (pk PetKind) DeletePetKindByID(repo domain.PetKindRepository) pet_kind.Dele ctx := p.HTTPRequest.Context() err := repo.Delete(ctx, int(p.PetKindID)) if err != nil { - pk.logger.Error("Error while deleting pet kind by id", zap.Error(err)) + pk.logger.Error(messages.ErrDeletePetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while deleting pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrDeletePetKind, err.Error())) } - return pet_kind.NewDeletePetKindOK().WithPayload("Pet kind deleted") + return pet_kind.NewDeletePetKindOK().WithPayload(messages.MsgPetKindDeleted) } } @@ -117,14 +118,14 @@ func (pk PetKind) UpdatePetKindByID(repo domain.PetKindRepository) pet_kind.Edit ctx := p.HTTPRequest.Context() petSize, err := repo.Update(ctx, int(p.PetKindID), p.EditPetKind) if err != nil { - pk.logger.Error("Error while updating pet kind by id", zap.Error(err)) + pk.logger.Error(messages.ErrUpdatePetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while updating pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdatePetKind, err.Error())) } if petSize == nil { - pk.logger.Error("Error while updating pet kind by id", zap.Error(err)) + pk.logger.Error(messages.ErrUpdatePetKind, zap.Error(err)) return pet_kind.NewCreateNewPetKindDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while updating pet kind")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdatePetKind, "")) } id := int64(petSize.ID) diff --git a/internal/handlers/pet_size.go b/internal/handlers/pet_size.go index 669b5773..234956d6 100644 --- a/internal/handlers/pet_size.go +++ b/internal/handlers/pet_size.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/pet_size" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -39,43 +40,27 @@ func (ps PetSize) CreatePetSizeFunc(repository domain.PetSizeRepository) pet_siz ctx := p.HTTPRequest.Context() allPetSizes, err := repository.GetAll(ctx) if err != nil { - ps.logger.Error("Error while getting pet size", zap.Error(err)) - return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while creating pet size", - }, - }) + ps.logger.Error(messages.ErrGetPetSize, zap.Error(err)) + return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrCreatePetSize, err.Error())) } for _, petSize := range allPetSizes { if *p.NewPetSize.Name == petSize.Name { - ps.logger.Error("Error while creating pet size", zap.Error(err)) - return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while creating pet size: the name already exist", - }, - }) + ps.logger.Error(messages.ErrCreatePetSize, zap.Error(err)) + return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrPetSizeAlreadyExists, "")) } } petSize, err := repository.Create(ctx, *p.NewPetSize) if err != nil { - ps.logger.Error("Error while creating pet size", zap.Error(err)) - return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while creating pet size", - }, - }) + ps.logger.Error(messages.ErrCreatePetSize, zap.Error(err)) + return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildBadRequestErrorPayload(messages.ErrCreatePetSize, err.Error())) } if petSize == nil { ps.logger.Error("Pet size is nil") - return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while creating pet size", - }, - }) + return pet_size.NewCreateNewPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrCreatePetSize, "")) } id := int64(petSize.ID) return pet_size.NewCreateNewPetSizeCreated().WithPayload(&models.PetSizeResponse{ @@ -93,21 +78,13 @@ func (ps PetSize) GetAllPetSizeFunc(repository domain.PetSizeRepository) pet_siz ctx := p.HTTPRequest.Context() petSizes, err := repository.GetAll(ctx) if err != nil { - ps.logger.Error("Error while getting pet size", zap.Error(err)) - return pet_size.NewGetAllPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while getting pet size", - }, - }) + ps.logger.Error(messages.ErrGetPetSize, zap.Error(err)) + return pet_size.NewGetAllPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrGetPetSize, "")) } if len(petSizes) == 0 { - return pet_size.NewGetAllPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "No pet size found", - }, - }) + return pet_size.NewGetAllPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrPetSizeNotFound, "")) } listOfPetSize := models.ListOfPetSizes{} for _, v := range petSizes { @@ -128,21 +105,13 @@ func (ps PetSize) GetPetSizeByID(repo domain.PetSizeRepository) pet_size.GetPetS ctx := p.HTTPRequest.Context() petSize, err := repo.GetByID(ctx, int(p.PetSizeID)) if err != nil { - ps.logger.Error("Error while getting pet size by id", zap.Error(err)) - return pet_size.NewGetPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while getting pet size", - }, - }) + ps.logger.Error(messages.ErrGetPetSize, zap.Error(err)) + return pet_size.NewGetPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrGetPetSize, err.Error())) } if petSize == nil { - return pet_size.NewGetPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while getting pet size", - }, - }) + return pet_size.NewGetPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrGetPetSize, "")) } id := int64(petSize.ID) return pet_size.NewGetPetSizeOK().WithPayload(&models.PetSizeResponse{ID: &id, Name: &petSize.Name, Size: &petSize.Size}) @@ -154,15 +123,11 @@ func (ps PetSize) DeletePetSizeByID(repo domain.PetSizeRepository) pet_size.Dele ctx := p.HTTPRequest.Context() err := repo.Delete(ctx, int(p.PetSizeID)) if err != nil { - ps.logger.Error("Error while deleting pet size by id", zap.Error(err)) - return pet_size.NewDeletePetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while deleting pet size", - }, - }) + ps.logger.Error(messages.ErrDeletePetSize, zap.Error(err)) + return pet_size.NewDeletePetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrDeletePetSize, err.Error())) } - return pet_size.NewDeletePetSizeOK().WithPayload("Pet size deleted") + return pet_size.NewDeletePetSizeOK().WithPayload(messages.MsgPetSizeDeleted) } } @@ -171,22 +136,14 @@ func (ps PetSize) UpdatePetSizeByID(repo domain.PetSizeRepository) pet_size.Edit ctx := p.HTTPRequest.Context() petSize, err := repo.Update(ctx, int(p.PetSizeID), p.EditPetSize) if err != nil { - ps.logger.Error("Error while updating pet size by id", zap.Error(err)) - return pet_size.NewEditPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while updating pet size", - }, - }) + ps.logger.Error(messages.ErrUpdatePetSize, zap.Error(err)) + return pet_size.NewEditPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrUpdatePetSize, err.Error())) } if petSize == nil { - ps.logger.Error("Error while updating pet size by id", zap.Error(err)) - return pet_size.NewEditPetSizeDefault(http.StatusInternalServerError).WithPayload( - &models.Error{ - Data: &models.ErrorData{ - Message: "Error while updating pet size", - }, - }) + ps.logger.Error(messages.ErrUpdatePetSize, zap.Error(err)) + return pet_size.NewEditPetSizeDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrUpdatePetSize, "")) } id := int64(petSize.ID) diff --git a/internal/handlers/photo.go b/internal/handlers/photo.go index 626b6549..64f2536f 100644 --- a/internal/handlers/photo.go +++ b/internal/handlers/photo.go @@ -14,6 +14,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/photos" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" @@ -47,32 +48,32 @@ func (p Photo) CreateNewPhotoFunc(repository domain.PhotoRepository) photos.Crea if err != nil { p.logger.Error("failed to read file", zap.Error(err)) return photos.NewCreateNewPhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePhoto, err.Error())) } if err := s.File.Close(); err != nil { p.logger.Error("Failed to close file", zap.Error(err)) return photos.NewCreateNewPhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePhoto, err.Error())) } // check if file is not empty if len(fileBytes) == 0 { - p.logger.Error("file is empty") + p.logger.Error(messages.ErrFileEmpty) return photos.NewCreateNewPhotoDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("File is empty")) + WithPayload(buildBadRequestErrorPayload(messages.ErrFileEmpty, "")) } // check if file is image jpg/jpeg mimeType := http.DetectContentType(fileBytes) if mimeType != "image/jpg" && mimeType != "image/jpeg" { p.logger.Error(fmt.Sprintf("wrong file format: %s. file should be jpg or jpeg", mimeType)) return photos.NewCreateNewPhotoDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Wrong file format. File should be jpg or jpeg")) + WithPayload(buildBadRequestErrorPayload(messages.ErrWrongFormat, "")) } photoID, err := utils.GenerateFileName() if err != nil { p.logger.Error("failed to generate photo name", zap.Error(err)) return photos.NewCreateNewPhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePhoto, err.Error())) } fileName := fmt.Sprintf("%s.jpg", photoID) @@ -86,7 +87,7 @@ func (p Photo) CreateNewPhotoFunc(repository domain.PhotoRepository) photos.Crea if err != nil { p.logger.Error("failed to save photo to db", zap.Error(err)) return photos.NewCreateNewPhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrCreatePhoto, err.Error())) } return photos.NewCreateNewPhotoCreated().WithPayload(&models.CreateNewPhotoResponse{ Data: &models.Photo{ @@ -103,7 +104,7 @@ func (p Photo) GetPhotoFunc(repository domain.PhotoRepository) photos.GetPhotoHa ctx := s.HTTPRequest.Context() photo, err := repository.PhotoByID(ctx, s.PhotoID) if err != nil { - p.logger.Error("failed to get photo", zap.Error(err)) + p.logger.Error(messages.ErrGetPhoto, zap.Error(err)) if err := writeErrorInResponse(w, err); err != nil { p.logger.Error("failed to response to client", zap.Error(err)) } @@ -126,7 +127,7 @@ func (p Photo) DownloadPhotoFunc(repository domain.PhotoRepository) photos.Downl ctx := s.HTTPRequest.Context() photo, err := repository.PhotoByID(ctx, s.PhotoID) if err != nil { - p.logger.Error("failed to get photo", zap.Error(err)) + p.logger.Error(messages.ErrGetPhoto, zap.Error(err)) if err := writeErrorInResponse(w, err); err != nil { p.logger.Error("failed to response to client", zap.Error(err)) } @@ -156,28 +157,28 @@ func (p Photo) DeletePhotoFunc(repository domain.PhotoRepository) photos.DeleteP ctx := s.HTTPRequest.Context() photo, err := repository.PhotoByID(ctx, s.PhotoID) if err != nil { - p.logger.Error("failed to get photo", zap.Error(err)) + p.logger.Error(messages.ErrGetPhoto, zap.Error(err)) return photos.NewDeletePhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrDeletePhoto, err.Error())) } err = repository.DeletePhotoByID(ctx, photo.ID) if err != nil { p.logger.Error("delete photo failed", zap.Error(err)) return photos.NewDeletePhotoDefault(http.StatusInternalServerError). - WithPayload(buildErrorPayload(err)) + WithPayload(buildInternalErrorPayload(messages.ErrDeletePhoto, err.Error())) } //err = fileManager.DeleteFile(photo.FileName) //if err != nil { // p.logger.Error("failed to delete photo file", zap.Error(err)) //} - return photos.NewDeletePhotoOK().WithPayload("Photo deleted") + return photos.NewDeletePhotoOK().WithPayload(messages.MsgPhotoDeleted) } } func writeErrorInResponse(w http.ResponseWriter, err error) error { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) - return json.NewEncoder(w).Encode(buildErrorPayload(err)) + return json.NewEncoder(w).Encode(buildInternalErrorPayload(messages.ErrGetPhoto, err.Error())) } diff --git a/internal/handlers/photo_test.go b/internal/handlers/photo_test.go index 5883ab0c..5bb49a21 100644 --- a/internal/handlers/photo_test.go +++ b/internal/handlers/photo_test.go @@ -91,14 +91,14 @@ func (s *PhotoTestSuite) TestPhoto_CreatePhoto_EmptyFile() { resp.WriteResponse(responseRecorder, producer) require.Equal(t, http.StatusBadRequest, responseRecorder.Code) - response := models.Error{} + response := models.SwaggerError{} err = json.Unmarshal(responseRecorder.Body.Bytes(), &response) if err != nil { t.Fatal(err) } require.NotEmpty(t, response) - require.NotEmpty(t, response.Data) - require.Equal(t, "File is empty", response.Data.Message) + require.NotEmpty(t, response.Message) + require.Equal(t, "File is empty", *response.Message) s.repository.AssertExpectations(t) } @@ -134,14 +134,14 @@ func (s *PhotoTestSuite) TestPhoto_CreatePhoto_WrongMimeType() { resp.WriteResponse(responseRecorder, producer) require.Equal(t, http.StatusBadRequest, responseRecorder.Code) - response := models.Error{} + response := models.SwaggerError{} err = json.Unmarshal(responseRecorder.Body.Bytes(), &response) if err != nil { t.Fatal(err) } require.NotEmpty(t, response) - require.NotEmpty(t, response.Data) - require.Containsf(t, response.Data.Message, "Wrong file format", "returned wrong error") + require.NotEmpty(t, response.Message) + require.Containsf(t, *response.Message, "Wrong file format", "returned wrong error") s.repository.AssertExpectations(t) } @@ -257,14 +257,14 @@ func (s *PhotoTestSuite) TestPhoto_GetPhoto_RepoErr() { require.Equal(t, http.StatusInternalServerError, responseRecorder.Code) require.Equal(t, "application/json", responseRecorder.Header().Get("Content-Type")) - response := models.Error{} + response := models.SwaggerError{} err := json.Unmarshal(responseRecorder.Body.Bytes(), &response) if err != nil { t.Fatal(err) } require.NotEmpty(t, response) - require.NotEmpty(t, response.Data) - require.Equal(t, errorToReturn.Error(), response.Data.Message) + require.NotEmpty(t, response.Message) + require.Contains(t, errorToReturn.Error(), response.Details) s.repository.AssertExpectations(t) } @@ -315,7 +315,7 @@ func (s *PhotoTestSuite) TestPhoto_DeletePhoto_NotExists() { PhotoID: id, } - errorToReturn := errors.New("not found") + errorToReturn := errors.New("failed to delete photo") s.repository.On("PhotoByID", ctx, data.PhotoID).Return(nil, errorToReturn) handlerFunc := s.handler.DeletePhotoFunc(s.repository) @@ -327,14 +327,14 @@ func (s *PhotoTestSuite) TestPhoto_DeletePhoto_NotExists() { resp.WriteResponse(responseRecorder, producer) require.Equal(t, http.StatusInternalServerError, responseRecorder.Code) - response := models.Error{} + response := models.SwaggerError{} err := json.Unmarshal(responseRecorder.Body.Bytes(), &response) if err != nil { t.Fatal(err) } require.NotEmpty(t, response) - require.NotEmpty(t, response.Data) - require.Equal(t, errorToReturn.Error(), response.Data.Message) + require.NotEmpty(t, response.Message) + require.Equal(t, errorToReturn.Error(), *response.Message) s.repository.AssertExpectations(t) } diff --git a/internal/handlers/registration_confirm.go b/internal/handlers/registration_confirm.go index 24bac781..c5c01b54 100644 --- a/internal/handlers/registration_confirm.go +++ b/internal/handlers/registration_confirm.go @@ -6,8 +6,10 @@ import ( "github.com/go-openapi/runtime/middleware" "go.uber.org/zap" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/registration_confirm" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/services" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -38,7 +40,7 @@ func (rc registrationConfirmHandler) SendRegistrationConfirmLinkByLoginFunc() re if login == "" { rc.logger.Warn("Login is empty") return registration_confirm.NewSendRegistrationConfirmLinkByLoginDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Login is required")) + WithPayload(buildBadRequestErrorPayload(messages.ErrLoginRequired, "")) } err := rc.regConfirm.SendConfirmationLink(ctx, login) if err != nil { @@ -46,19 +48,21 @@ func (rc registrationConfirmHandler) SendRegistrationConfirmLinkByLoginFunc() re switch err { case services.ErrRegistrationAlreadyConfirmed: return registration_confirm.NewSendRegistrationConfirmLinkByLoginDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Registration is already confirmed.")) + WithPayload(buildInternalErrorPayload(messages.ErrRegistrationAlreadyConfirmed, "")) case services.ErrUserNotFound: return registration_confirm.NewSendRegistrationConfirmLinkByLoginDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't find this user, registration confirmation link wasn't send")) + WithPayload(buildInternalErrorPayload(messages.ErrRegistrationCannotFindUser, "")) default: return registration_confirm.NewSendRegistrationConfirmLinkByLoginDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't send registration confirmation link. Please try again later")) + WithPayload(buildInternalErrorPayload(messages.ErrRegistrationCannotSend, "")) } } if !rc.regConfirm.IsSendRequired() { - return registration_confirm.NewSendRegistrationConfirmLinkByLoginOK().WithPayload("Confirmation link was not sent to email, sending parameter was set to false and not required") + return registration_confirm.NewSendRegistrationConfirmLinkByLoginOK().WithPayload( + models.RegistrationConfirmResponse(messages.MsgConfirmationNotRequired)) } - return registration_confirm.NewSendRegistrationConfirmLinkByLoginOK().WithPayload("Confirmation link was sent") + return registration_confirm.NewSendRegistrationConfirmLinkByLoginOK().WithPayload( + models.RegistrationConfirmResponse(messages.MsgConfirmationSent)) } } @@ -70,8 +74,9 @@ func (rc registrationConfirmHandler) VerifyRegistrationConfirmTokenFunc() regist if err != nil { rc.logger.Error("Failed to verify confirmation token", zap.Error(err)) return registration_confirm.NewVerifyRegistrationConfirmTokenDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Failed to verify confirmation token. Please try again later")) + WithPayload(buildInternalErrorPayload(messages.ErrFailedToConfirm, "")) } - return registration_confirm.NewVerifyRegistrationConfirmTokenOK().WithPayload("You have successfully confirmed registration") + return registration_confirm.NewVerifyRegistrationConfirmTokenOK().WithPayload( + models.RegistrationConfirmResponse(messages.MsgRegistrationConfirmed)) } } diff --git a/internal/handlers/role.go b/internal/handlers/role.go index 74510d0b..235c7d3c 100644 --- a/internal/handlers/role.go +++ b/internal/handlers/role.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/roles" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -35,9 +36,9 @@ func (r Role) GetRolesFunc(repository domain.RoleRepository) roles.GetRolesHandl ctx := s.HTTPRequest.Context() e, err := repository.GetRoles(ctx) if err != nil { - r.logger.Error("query orders failed") + r.logger.Error(messages.ErrQueryRoles) return roles.NewGetRolesDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant get all roles")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryRoles, "")) } listRoles := models.ListRoles{} for _, element := range e { diff --git a/internal/handlers/subcategory.go b/internal/handlers/subcategory.go index 558d1c8c..510c921f 100644 --- a/internal/handlers/subcategory.go +++ b/internal/handlers/subcategory.go @@ -11,6 +11,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/subcategories" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -42,15 +43,15 @@ func (s *Subcategory) CreateNewSubcategoryFunc(repository domain.SubcategoryRepo categoryID := int(p.CategoryID) createdSubcategory, err := repository.CreateSubcategory(ctx, categoryID, *p.NewSubcategory) if err != nil { - s.logger.Error("failed to create new subcategory", zap.Error(err)) + s.logger.Error(messages.ErrCreateSubcategory, zap.Error(err)) return subcategories.NewCreateNewSubcategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to create new subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrCreateSubcategory, err.Error())) } result, err := mapSubcategory(createdSubcategory) if err != nil { - s.logger.Error("failed to map new subcategory", zap.Error(err)) + s.logger.Error(messages.ErrMapSubcategory, zap.Error(err)) return subcategories.NewCreateNewSubcategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to map new subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrMapSubcategory, err.Error())) } return subcategories.NewCreateNewSubcategoryCreated().WithPayload(&models.SubcategoryResponse{ Data: result, @@ -64,17 +65,17 @@ func (s *Subcategory) ListSubcategoriesFunc(repository domain.SubcategoryReposit categoryID := int(p.CategoryID) subcategoriesList, err := repository.ListSubcategories(ctx, categoryID) if err != nil { - s.logger.Error("failed to list subcategories by category id", zap.Error(err)) + s.logger.Error(messages.ErrQuerySCatByCategory, zap.Error(err)) return subcategories.NewListSubcategoriesByCategoryIDDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to list subcategories by category id")) + WithPayload(buildInternalErrorPayload(messages.ErrQuerySCatByCategory, err.Error())) } mappedSubcategories := make([]*models.Subcategory, len(subcategoriesList)) for i, v := range subcategoriesList { mappedSubcategory, err := mapSubcategory(v) if err != nil { - s.logger.Error("failed to map subcategories by category id", zap.Error(err)) + s.logger.Error(messages.ErrMapSubcategory, zap.Error(err)) return subcategories.NewListSubcategoriesByCategoryIDDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to map subcategories by category id")) + WithPayload(buildInternalErrorPayload(messages.ErrMapSubcategory, err.Error())) } mappedSubcategories[i] = mappedSubcategory } @@ -87,15 +88,15 @@ func (s *Subcategory) GetSubcategoryByIDFunc(repository domain.SubcategoryReposi ctx := p.HTTPRequest.Context() subcategory, err := repository.SubcategoryByID(ctx, int(p.SubcategoryID)) if err != nil { - s.logger.Error("failed to get subcategory", zap.Error(err)) + s.logger.Error(messages.ErrGetSubcategory, zap.Error(err)) return subcategories.NewGetSubcategoryByIDDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to get subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrGetSubcategory, err.Error())) } result, err := mapSubcategory(subcategory) if err != nil { - s.logger.Error("failed to map subcategory", zap.Error(err)) + s.logger.Error(messages.ErrMapSubcategory, zap.Error(err)) return subcategories.NewGetSubcategoryByIDDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to map subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrMapSubcategory, err.Error())) } return subcategories.NewGetSubcategoryByIDOK(). WithPayload(&models.SubcategoryResponse{Data: result}) @@ -107,12 +108,12 @@ func (s *Subcategory) DeleteSubcategoryFunc(repository domain.SubcategoryReposit ctx := p.HTTPRequest.Context() err := repository.DeleteSubcategoryByID(ctx, int(p.SubcategoryID)) if err != nil { - s.logger.Error("failed to delete subcategory", zap.Error(err)) + s.logger.Error(messages.ErrDeleteSubcategory, zap.Error(err)) return subcategories.NewDeleteSubcategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to delete subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteSubcategory, err.Error())) } return subcategories.NewDeleteSubcategoryOK(). - WithPayload("subcategory deleted") + WithPayload(messages.MsgSubcategoryDeleted) } } @@ -121,15 +122,15 @@ func (s *Subcategory) UpdateSubcategoryFunc(repository domain.SubcategoryReposit ctx := p.HTTPRequest.Context() updateSubcategory, err := repository.UpdateSubcategory(ctx, int(p.SubcategoryID), *p.UpdateSubcategory) if err != nil { - s.logger.Error("failed to update subcategory", zap.Error(err)) + s.logger.Error(messages.ErrUpdateSubcategory, zap.Error(err)) return subcategories.NewUpdateSubcategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to update subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateSubcategory, err.Error())) } result, err := mapSubcategory(updateSubcategory) if err != nil { - s.logger.Error("failed to map subcategory", zap.Error(err)) + s.logger.Error(messages.ErrMapSubcategory, zap.Error(err)) return subcategories.NewUpdateSubcategoryDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to map subcategory")) + WithPayload(buildInternalErrorPayload(messages.ErrMapSubcategory, err.Error())) } return subcategories.NewUpdateSubcategoryOK().WithPayload(&models.SubcategoryResponse{ Data: result, diff --git a/internal/handlers/user.go b/internal/handlers/user.go index cdc09642..b00d56bb 100644 --- a/internal/handlers/user.go +++ b/internal/handlers/user.go @@ -15,6 +15,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/restapi/operations/users" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/repositories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" @@ -62,7 +63,7 @@ func (c User) LoginUserFunc(service domain.TokenManager) users.LoginHandlerFunc if isInternalErr { return users.NewLoginDefault(http.StatusInternalServerError) } - return users.NewLoginUnauthorized().WithPayload("Invalid login or password") + return users.NewLoginUnauthorized().WithPayload(messages.ErrInvalidLoginOrPass) } return users.NewLoginOK().WithPayload(&models.TokenPair{ @@ -83,7 +84,7 @@ func (c User) LogoutUserFunc(tokenManager domain.TokenManager) users.LogoutHandl if err != nil { return users.NewLogoutDefault(http.StatusInternalServerError) } - return users.NewLogoutOK().WithPayload("Successfully logged out") + return users.NewLogoutOK().WithPayload(messages.MsgLogoutSuccessful) } } @@ -93,11 +94,11 @@ func (c User) PostUserFunc(repository domain.UserRepository, regConfirmService d createdUser, err := repository.CreateUser(ctx, p.Data) if err != nil { if ent.IsConstraintError(err) { - return users.NewPostUserDefault(http.StatusExpectationFailed).WithPayload( - buildErrorPayload(errors.New("login is already used")), - ) + return users.NewPostUserDefault(http.StatusExpectationFailed). + WithPayload(buildExFailedErrorPayload(messages.ErrLoginInUse, "")) } - return users.NewPostUserDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + return users.NewPostUserDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrCreateUser, err.Error())) } id := int64(createdUser.ID) @@ -122,14 +123,14 @@ func (c User) Refresh(manager domain.TokenManager) users.RefreshHandlerFunc { refreshToken := *p.RefreshToken.RefreshToken newAccess, NewRefresh, isValid, err := manager.RefreshToken(ctx, refreshToken) if isValid { - c.logger.Info("token invalid", zap.String("token", refreshToken)) + c.logger.Info(messages.ErrInvalidToken, zap.String("token", refreshToken)) return users.NewRefreshDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("token invalid")) + WithPayload(buildBadRequestErrorPayload(messages.ErrInvalidToken, "")) } if err != nil { - c.logger.Error("Error while refreshing token", zap.Error(err)) + c.logger.Error(messages.ErrTokenRefresh, zap.Error(err)) return users.NewRefreshDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while refreshing token")) + WithPayload(buildInternalErrorPayload(messages.ErrTokenRefresh, err.Error())) } return users.NewRefreshOK().WithPayload(&models.TokenPair{ AccessToken: &newAccess, @@ -145,17 +146,16 @@ func (c User) GetUserFunc(repository domain.UserRepository) users.GetCurrentUser user, err := repository.GetUserByID(ctx, userID) if err != nil { - c.logger.Error("get user by id error", zap.Error(err)) - return users.NewGetCurrentUserDefault(http.StatusInternalServerError).WithPayload(&models.Error{Data: &models.ErrorData{ - Message: "cant find user by id", - }}) + c.logger.Error(messages.ErrUserNotFound, zap.Error(err)) + return users.NewGetCurrentUserDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrUserNotFound, "")) } result, err := mapUserInfo(user) if err != nil { - c.logger.Error("map user error", zap.Error(err)) + c.logger.Error(messages.ErrMapUser, zap.Error(err)) return users.NewGetCurrentUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("map user error")) + WithPayload(buildInternalErrorPayload(messages.ErrMapUser, err.Error())) } return users.NewGetCurrentUserOK().WithPayload(result) @@ -169,9 +169,9 @@ func (c User) PatchUserFunc(repository domain.UserRepository) users.PatchUserHan err := repository.UpdateUserByID(ctx, userID, p.UserPatch) if err != nil { - c.logger.Error("get user by id error", zap.Error(err)) + c.logger.Error(messages.ErrUpdateUser, zap.Error(err)) return users.NewPatchUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant update user")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateUser, err.Error())) } return users.NewPatchUserNoContent() } @@ -184,17 +184,18 @@ func (c User) AssignRoleToUserFunc(repository domain.UserRepository) users.Assig userId := int(p.UserID) if p.Data.RoleID == nil { return users.NewAssignRoleToUserDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("role id is required")) + WithPayload(buildInternalErrorPayload(messages.ErrRoleRequired, "")) } roleId := int(*p.Data.RoleID) err := repository.SetUserRole(ctx, userId, roleId) if err != nil { - c.logger.Error("set user role error", zap.Error(err)) - return users.NewAssignRoleToUserDefault(http.StatusInternalServerError).WithPayload(buildErrorPayload(err)) + c.logger.Error(messages.ErrSetUserRole, zap.Error(err)) + return users.NewAssignRoleToUserDefault(http.StatusInternalServerError). + WithPayload(buildInternalErrorPayload(messages.ErrSetUserRole, err.Error())) } - return users.NewAssignRoleToUserOK().WithPayload("role assigned") + return users.NewAssignRoleToUserOK().WithPayload(messages.MsgRoleAssigned) } } @@ -205,14 +206,14 @@ func (c User) GetUserById(repository domain.UserRepository) users.GetUserHandler foundUser, err := repository.GetUserByID(ctx, id) if err != nil { return users.NewGetUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("cant find user by id")) + WithPayload(buildInternalErrorPayload(messages.ErrUserNotFound, "")) } userToResponse, err := mapUserInfo(foundUser) if err != nil { - c.logger.Error("map user error", zap.Error(err)) + c.logger.Error(messages.ErrMapUser, zap.Error(err)) return users.NewGetUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("map user error")) + WithPayload(buildInternalErrorPayload(messages.ErrMapUser, err.Error())) } return users.NewGetUserOK().WithPayload(userToResponse) @@ -228,17 +229,17 @@ func (c User) GetUsersList(repository domain.UserRepository) users.GetAllUsersHa orderColumn := utils.GetValueByPointerOrDefaultValue(p.OrderColumn, user.FieldID) total, err := repository.UsersListTotal(ctx) if err != nil { - c.logger.Error("failed get user total amount", zap.Error(err)) + c.logger.Error(messages.ErrQueryTotalUsers, zap.Error(err)) return users.NewGetAllUsersDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to get user total amount")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryTotalUsers, err.Error())) } var allUsers []*ent.User if total > 0 { allUsers, err = repository.UserList(ctx, int(limit), int(offset), orderBy, orderColumn) if err != nil { - c.logger.Error("failed get user list", zap.Error(err)) + c.logger.Error(messages.ErrQueryUsers, zap.Error(err)) return users.NewGetAllUsersDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("failed to get user list")) + WithPayload(buildInternalErrorPayload(messages.ErrQueryUsers, err.Error())) } } @@ -246,9 +247,9 @@ func (c User) GetUsersList(repository domain.UserRepository) users.GetAllUsersHa for i, element := range allUsers { userToResponse, errMap := mapUserInfo(element) if errMap != nil { - c.logger.Error("map user error", zap.Error(errMap)) + c.logger.Error(messages.ErrMapUser, zap.Error(errMap)) return users.NewGetAllUsersDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("map user error")) + WithPayload(buildInternalErrorPayload(messages.ErrMapUser, errMap.Error())) } usersToResponse[i] = userToResponse } @@ -269,9 +270,9 @@ func (c User) DeleteCurrentUser(repository domain.UserRepository) users.DeleteCu err := repository.Delete(ctx, userID) if err != nil { - c.logger.Error("error during deleting user", zap.Error(err)) + c.logger.Error(messages.ErrDeleteUser, zap.Error(err)) return users.NewDeleteCurrentUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("can't delete user")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteUser, err.Error())) } return users.NewDeleteCurrentUserOK() @@ -289,26 +290,26 @@ func (c User) DeleteUser(repo domain.UserRepository) users.DeleteUserHandlerFunc c.logger.Error(fmt.Sprintf("retrieving user by ID %d", userID), zap.Error(err)) if ent.IsNotFound(err) { return users.NewDeleteUserNotFound(). - WithPayload(buildStringPayload("User not found")) + WithPayload(buildNotFoundErrorPayload(messages.ErrUserNotFound, "")) } return users.NewDeleteUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Unexpected error")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteUser, err.Error())) } if !user.IsReadonly { - c.logger.Error("User must be readonly for deletion", zap.Int("userID", userID)) + c.logger.Error(messages.ErrDeleteUserNotRO, zap.Int("userID", userID)) return users.NewDeleteUserDefault(http.StatusForbidden). - WithPayload(buildStringPayload("User must be readonly for deletion")) + WithPayload(buildForbiddenErrorPayload(messages.ErrDeleteUserNotRO, "")) } if err := repo.Delete(ctx, userID); err != nil { c.logger.Error("deleting user", zap.Error(err)) if ent.IsNotFound(err) { return users.NewDeleteUserNotFound(). - WithPayload(buildStringPayload("User not found")) + WithPayload(buildNotFoundErrorPayload(messages.ErrUserNotFound, "")) } return users.NewDeleteUserDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Unexpected error")) + WithPayload(buildInternalErrorPayload(messages.ErrDeleteUser, err.Error())) } c.logger.Info("User deleted successfully", zap.Int("userID", userID), zap.Int("deletedByUserID", deletedByUserID)) @@ -322,32 +323,32 @@ func (c User) ChangePassword(repo domain.UserRepository) users.ChangePasswordHan userID := int(principal.ID) if p.PasswordPatch == nil { - c.logger.Error("password patch is nil", zap.Any("principal", principal)) + c.logger.Error(messages.ErrPasswordPatchEmpty, zap.Any("principal", principal)) return users.NewChangePasswordDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Password patch is nil")) + WithPayload(buildBadRequestErrorPayload(messages.ErrPasswordPatchEmpty, "")) } //TODO: add validation for password or ask frontend to do it if p.PasswordPatch.OldPassword == p.PasswordPatch.NewPassword { c.logger.Error("old and new passwords are the same", zap.Any("principal", principal)) return users.NewChangePasswordDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Old and new passwords are the same")) + WithPayload(buildBadRequestErrorPayload(messages.ErrPasswordsAreSame, "")) } requestedUser, err := repo.GetUserByID(ctx, userID) if err != nil { c.logger.Error("getting user failed", zap.Error(err)) return users.NewChangePasswordDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't get user by id")) + WithPayload(buildInternalErrorPayload(messages.ErrUserPasswordChange, err.Error())) } expectedPasswordHash := requestedUser.Password if err = bcrypt.CompareHashAndPassword([]byte(expectedPasswordHash), []byte(p.PasswordPatch.OldPassword)); err != nil { - c.logger.Error("wrong password", zap.Error(err)) + c.logger.Error(messages.ErrWrongPassword, zap.Error(err)) return users.NewChangePasswordDefault(http.StatusForbidden). - WithPayload(buildStringPayload("Wrong password")) + WithPayload(buildForbiddenErrorPayload(messages.ErrWrongPassword, "")) } if err = repo.ChangePasswordByLogin(ctx, requestedUser.Login, p.PasswordPatch.NewPassword); err != nil { c.logger.Error("error while changing password", zap.Error(err)) return users.NewChangePasswordDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Error while changing password")) + WithPayload(buildInternalErrorPayload(messages.ErrUserPasswordChange, err.Error())) } return users.NewChangePasswordNoContent() } @@ -361,13 +362,13 @@ func (c User) UpdateReadonlyAccess(repo domain.UserRepository) users.UpdateReado isReadonly := p.Body.IsReadonly if err := repo.SetIsReadonly(ctx, userID, isReadonly); err != nil { - c.logger.Error("error while updating readonly access", zap.Error(err)) + c.logger.Error(messages.ErrUpdateROAccess, zap.Error(err)) if ent.IsNotFound(err) { return users.NewUpdateReadonlyAccessNotFound(). - WithPayload(buildStringPayload("User not found")) + WithPayload(buildNotFoundErrorPayload(messages.ErrUserNotFound, "")) } return users.NewUpdateReadonlyAccessDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Unexpected error")) + WithPayload(buildInternalErrorPayload(messages.ErrUpdateROAccess, err.Error())) } if isReadonly { @@ -387,23 +388,23 @@ func (c User) ChangeEmail(repo domain.UserRepository, userID := int(principal.ID) if p.EmailPatch == nil { - c.logger.Error("email patch is nil", zap.Any("principal", principal)) + c.logger.Error(messages.ErrEmailPatchEmpty, zap.Any("principal", principal)) return users.NewChangeEmailDefault(http.StatusBadRequest). - WithPayload(buildStringPayload("Email patch is nil")) + WithPayload(buildBadRequestErrorPayload(messages.ErrEmailPatchEmpty, "")) } requestedUser, err := repo.GetUserByID(ctx, userID) if err != nil { c.logger.Error("getting user for changing email failed", zap.Error(err)) return users.NewChangeEmailDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't get user by id")) + WithPayload(buildInternalErrorPayload(messages.ErrChangeEmail, err.Error())) } err = changeEmailService.SendEmailConfirmationLink(ctx, requestedUser.Login, p.EmailPatch.NewEmail) if err != nil { c.logger.Error("error while sending link for confirmation new email", zap.Error(err)) return users.NewChangeEmailDefault(http.StatusInternalServerError). - WithPayload(buildStringPayload("Can't send link for confirmation new email")) + WithPayload(buildInternalErrorPayload(messages.ErrNewEmailConfirmation, err.Error())) } return users.NewChangeEmailNoContent() diff --git a/internal/integration-tests/activeareas/integration_test.go b/internal/integration-tests/activeareas/integration_test.go index 27fa5d48..a9b998af 100644 --- a/internal/integration-tests/activeareas/integration_test.go +++ b/internal/integration-tests/activeareas/integration_test.go @@ -11,6 +11,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/active_areas" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" ) func TestIntegration_GetActiveAreas(t *testing.T) { @@ -39,8 +40,11 @@ func TestIntegration_GetActiveAreas(t *testing.T) { require.Error(t, err) errExp := active_areas.NewGetAllActiveAreasDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -53,8 +57,10 @@ func TestIntegration_GetActiveAreas(t *testing.T) { require.Error(t, err) errExp := active_areas.NewGetAllActiveAreasDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/category/category_test.go b/internal/integration-tests/category/category_test.go index 93eaa81c..7edafa76 100644 --- a/internal/integration-tests/category/category_test.go +++ b/internal/integration-tests/category/category_test.go @@ -17,6 +17,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/categories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" ) var ( @@ -61,7 +62,12 @@ func TestIntegration_GetAllCategories(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewGetAllCategoriesDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "order_column in query should be one of [id name]" + codeExp := int32(606) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) } @@ -88,7 +94,11 @@ func TestIntegration_CreateCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewCreateNewCategoryDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -163,9 +173,12 @@ func TestIntegration_GetCategoryByID(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewGetCategoryByIDDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "failed to get category", - }} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrGetCategory, + Details: "ent: category not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -175,7 +188,11 @@ func TestIntegration_GetCategoryByID(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewGetCategoryByIDDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -257,9 +274,12 @@ func TestIntegration_EditCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewUpdateCategoryDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "cant update category", - }} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrUpdateCategory, + Details: "ent: category not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -279,7 +299,11 @@ func TestIntegration_EditCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewUpdateCategoryDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -289,7 +313,12 @@ func TestIntegration_EditCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewUpdateCategoryDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "updateCategory in body is required" + codeExp := int32(602) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) } @@ -307,7 +336,12 @@ func TestIntegration_DeleteCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewDeleteCategoryDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "delete category failed"}} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrDeleteCategory, + Details: "ent: category not found", + } assert.Equal(t, wantErr, gotErr) _, gotErr = client.Categories.DeleteCategory(categories.NewDeleteCategoryParamsWithContext(ctx).WithCategoryID(-33), auth) @@ -322,7 +356,11 @@ func TestIntegration_DeleteCategory(t *testing.T) { require.Error(t, gotErr) wantErr := categories.NewDeleteCategoryDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) diff --git a/internal/integration-tests/equipment/integration_test.go b/internal/integration-tests/equipment/integration_test.go index 8d31a3e4..116c5068 100644 --- a/internal/integration-tests/equipment/integration_test.go +++ b/internal/integration-tests/equipment/integration_test.go @@ -23,8 +23,8 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/photos" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/subcategories" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" - "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/handlers" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -128,9 +128,12 @@ func TestIntegration_CreateEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewCreateNewEquipmentDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "Error while creating equipment", - }} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrCreateEquipment, + Details: "ent: constraint failed: ERROR: insert or update on table \"equipment\" violates foreign key constraint \"equipment_photo_equipments_fkey\" (SQLSTATE 23503)", + } assert.Equal(t, wantErr, gotErr) }) @@ -146,7 +149,11 @@ func TestIntegration_CreateEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewCreateNewEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -179,7 +186,11 @@ func TestIntegration_GetAllEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewGetAllEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -239,8 +250,13 @@ func TestIntegration_GetEquipment(t *testing.T) { _, gotErr := client.Equipment.GetEquipment(params, auth) require.Error(t, gotErr) - wantErr := equipment.NewGetEquipmentDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "Error while getting equipment"}} + wantErr := equipment.NewGetEquipmentDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrGetEquipment, + Details: "ent: equipment not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -254,7 +270,11 @@ func TestIntegration_GetEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewGetEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -316,7 +336,11 @@ func TestIntegration_FindEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewFindEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -371,8 +395,13 @@ func TestIntegration_EditEquipment(t *testing.T) { _, gotErr := client.Equipment.EditEquipment(params, auth) require.Error(t, gotErr) - wantErr := equipment.NewEditEquipmentDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "Error while updating equipment"}} + wantErr := equipment.NewEditEquipmentDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrUpdateEquipment, + Details: "ent: equipment not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -386,7 +415,11 @@ func TestIntegration_EditEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewEditEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -422,15 +455,20 @@ func TestIntegration_ArchiveEquipment(t *testing.T) { require.Error(t, gotErr) fmt.Print(resp) - wantedErr := equipment.NewArchiveEquipmentNotFound() - wantedErr.Payload = &models.Error{Data: &models.ErrorData{Message: handlers.EquipmentNotFoundMsg}} + wantErr := equipment.NewArchiveEquipmentNotFound() + codeExp := int32(http.StatusNotFound) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentNotFound, + } - require.Equal(t, wantedErr, gotErr) + require.Equal(t, wantErr, gotErr) }) t.Run("Archive Equipment with active orders", func(t *testing.T) { orStartDate, orEndDate := time.Now(), time.Now().AddDate(0, 0, 1) orderID, err := createOrder(ctx, client, auth, created.Payload.ID, orStartDate, orEndDate) + require.NoError(t, err) params := equipment.NewArchiveEquipmentParamsWithContext(ctx).WithEquipmentID(*created.Payload.ID) var res *equipment.ArchiveEquipmentNoContent res, err = client.Equipment.ArchiveEquipment(params, auth) @@ -448,9 +486,13 @@ func TestIntegration_ArchiveEquipment(t *testing.T) { _, gotErr := client.Equipment.ArchiveEquipment(params, utils.AuthInfoFunc(&token)) require.Error(t, gotErr) - wantedErr := equipment.NewArchiveEquipmentDefault(http.StatusUnauthorized) - wantedErr.Payload = &models.Error{Data: nil} - assert.Equal(t, wantedErr, gotErr) + wantErr := equipment.NewArchiveEquipmentDefault(http.StatusUnauthorized) + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } + assert.Equal(t, wantErr, gotErr) }) // todo: test for archive equipment with non-default status @@ -545,7 +587,11 @@ func TestIntegration_BlockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewBlockEquipmentNotFound() - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: handlers.EquipmentNotFoundMsg}} + codeExp := int32(http.StatusNotFound) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentNotFound, + } assert.Equal(t, wantErr, err) }) @@ -562,9 +608,11 @@ func TestIntegration_BlockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewBlockEquipmentDefault(http.StatusForbidden) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "You don't have rights to block the equipment", - }} + codeExp := int32(http.StatusForbidden) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentBlockForbidden, + } assert.Equal(t, wantErr, err) }) @@ -581,9 +629,11 @@ func TestIntegration_BlockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewBlockEquipmentDefault(http.StatusForbidden) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "You don't have rights to block the equipment", - }} + codeExp := int32(http.StatusForbidden) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentBlockForbidden, + } assert.Equal(t, wantErr, err) }) @@ -600,6 +650,27 @@ func TestIntegration_BlockEquipment(t *testing.T) { require.NoError(t, err) require.True(t, res.IsCode(http.StatusNoContent)) }) + + t.Run("Block Equipment is failed, endDate before startDate", func(t *testing.T) { + tokens := utils.ManagerUserLogin(t) + auth := utils.AuthInfoFunc(tokens.GetPayload().AccessToken) + params := equipment.NewBlockEquipmentParamsWithContext(ctx).WithEquipmentID(*eq.Payload.ID) + params.Data = &models.ChangeEquipmentStatusToBlockedRequest{ + StartDate: strfmt.DateTime(endDate), + EndDate: strfmt.DateTime(startDate), + } + + _, err := client.Equipment.BlockEquipment(params, auth) + require.Error(t, err) + + wantErr := equipment.NewBlockEquipmentDefault(http.StatusBadRequest) + codeExp := int32(http.StatusBadRequest) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrStartDateAfterEnd, + } + assert.Equal(t, wantErr, err) + }) } func TestIntegration_DeleteEquipment(t *testing.T) { @@ -638,9 +709,12 @@ func TestIntegration_DeleteEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewDeleteEquipmentDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "Error while getting equipment", - }} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrDeleteEquipment, + Details: "ent: equipment not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -653,7 +727,11 @@ func TestIntegration_DeleteEquipment(t *testing.T) { require.Error(t, gotErr) wantErr := equipment.NewDeleteEquipmentDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -684,9 +762,11 @@ func TestIntegration_UnblockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewUnblockEquipmentDefault(http.StatusForbidden) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "You don't have rights to unblock the equipment", - }} + codeExp := int32(http.StatusForbidden) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentUnblockForbidden, + } assert.Equal(t, wantErr, err) }) @@ -699,9 +779,11 @@ func TestIntegration_UnblockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewUnblockEquipmentDefault(http.StatusForbidden) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "You don't have rights to unblock the equipment", - }} + codeExp := int32(http.StatusForbidden) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentUnblockForbidden, + } assert.Equal(t, wantErr, err) }) @@ -748,7 +830,11 @@ func TestIntegration_UnblockEquipment(t *testing.T) { require.Error(t, err) wantErr := equipment.NewUnblockEquipmentNotFound() - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: handlers.EquipmentNotFoundMsg}} + codeExp := int32(http.StatusNotFound) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrEquipmentNotFound, + } assert.Equal(t, wantErr, err) }) } diff --git a/internal/integration-tests/equipmentstatusname/equipment_status_name_test.go b/internal/integration-tests/equipmentstatusname/equipment_status_name_test.go index e86a75be..29afdf7d 100644 --- a/internal/integration-tests/equipmentstatusname/equipment_status_name_test.go +++ b/internal/integration-tests/equipmentstatusname/equipment_status_name_test.go @@ -11,6 +11,7 @@ import ( eqStatusName "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/equipment_status_name" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) @@ -41,7 +42,11 @@ func TestIntegration_GetStatuses(t *testing.T) { require.Error(t, gotErr) wantErr := eqStatusName.NewListEquipmentStatusNamesDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -75,9 +80,12 @@ func TestIntegration_GetStatus(t *testing.T) { require.Error(t, gotErr) wantErr := eqStatusName.NewGetEquipmentStatusNameDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "can't get status", - }} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrGetEqStatus, + Details: "ent: equipment_status_name not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -90,7 +98,11 @@ func TestIntegration_GetStatus(t *testing.T) { require.Error(t, gotErr) wantErr := eqStatusName.NewGetEquipmentStatusNameDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -128,8 +140,13 @@ func TestIntegration_PostStatus(t *testing.T) { _, gotErr := client.EquipmentStatusName.PostEquipmentStatusName(params, utils.AuthInfoFunc(token)) require.Error(t, gotErr) - wantErr := eqStatusName.NewPostEquipmentStatusNameDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "can't create status"}} + wantErr := eqStatusName.NewPostEquipmentStatusNameDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrCreateEqStatus, + Details: "ent: constraint failed: ERROR: duplicate key value violates unique constraint \"equipment_status_names_name_key\" (SQLSTATE 23505)", + } assert.Equal(t, wantErr, gotErr) }) @@ -144,7 +161,11 @@ func TestIntegration_PostStatus(t *testing.T) { require.Error(t, gotErr) wantErr := eqStatusName.NewPostEquipmentStatusNameDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } @@ -178,8 +199,13 @@ func TestIntegration_DeleteStatus(t *testing.T) { _, gotErr := client.EquipmentStatusName.DeleteEquipmentStatusName(params, utils.AuthInfoFunc(token)) require.Error(t, gotErr) - wantErr := eqStatusName.NewDeleteEquipmentStatusNameDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "can't delete status"}} + wantErr := eqStatusName.NewDeleteEquipmentStatusNameDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrDeleteEqStatus, + Details: "ent: equipment_status_name not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -189,8 +215,13 @@ func TestIntegration_DeleteStatus(t *testing.T) { _, gotErr := client.EquipmentStatusName.DeleteEquipmentStatusName(params, utils.AuthInfoFunc(token)) require.Error(t, gotErr) - wantErr := eqStatusName.NewDeleteEquipmentStatusNameDefault(500) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "can't delete status"}} + wantErr := eqStatusName.NewDeleteEquipmentStatusNameDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrDeleteEqStatus, + Details: "ent: equipment_status_name not found", + } assert.Equal(t, wantErr, gotErr) }) @@ -203,7 +234,11 @@ func TestIntegration_DeleteStatus(t *testing.T) { require.Error(t, gotErr) wantErr := eqStatusName.NewDeleteEquipmentStatusNameDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } diff --git a/internal/integration-tests/orders/order_test.go b/internal/integration-tests/orders/order_test.go index 5b543081..0280be3d 100644 --- a/internal/integration-tests/orders/order_test.go +++ b/internal/integration-tests/orders/order_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/subcategories" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/ent/order" @@ -91,7 +92,11 @@ func TestIntegration_CreateOrder(t *testing.T) { require.Error(t, gotErr) wantErr := orders.NewCreateOrderDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -110,8 +115,12 @@ func TestIntegration_CreateOrder(t *testing.T) { _, gotErr := client.Orders.CreateOrder(params, auth) require.Error(t, gotErr) - wantErr := orders.NewCreateOrderDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "start date should be before end date"}} + wantErr := orders.NewCreateOrderDefault(http.StatusBadRequest) + codeExp := int32(http.StatusBadRequest) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrStartDateAfterEnd, + } assert.Equal(t, wantErr, gotErr) }) @@ -130,8 +139,12 @@ func TestIntegration_CreateOrder(t *testing.T) { _, gotErr := client.Orders.CreateOrder(params, auth) require.Error(t, gotErr) - wantErr := orders.NewCreateOrderDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "small rent period"}} + wantErr := orders.NewCreateOrderDefault(http.StatusBadRequest) + codeExp := int32(http.StatusBadRequest) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrSmallRentPeriod, + } assert.Equal(t, wantErr, gotErr) }) @@ -151,7 +164,12 @@ func TestIntegration_CreateOrder(t *testing.T) { require.Error(t, gotErr) wantErr := orders.NewCreateOrderDefault(http.StatusInternalServerError) - wantErr.Payload = &models.Error{Data: &models.ErrorData{Message: "too big reservation period"}} + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrMapOrder, + Details: "too big reservation period", + } assert.Equal(t, wantErr, gotErr) }) @@ -169,7 +187,12 @@ func TestIntegration_CreateOrder(t *testing.T) { require.Error(t, gotErr) wantErr := orders.NewCreateOrderDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "equipment_id in body is required" + codeExp := int32(602) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) @@ -306,7 +329,11 @@ func TestIntegration_GetUserOrders(t *testing.T) { require.Error(t, gotErr) wantErr := orders.NewGetUserOrdersDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -326,7 +353,12 @@ func TestIntegration_GetUserOrders(t *testing.T) { require.Error(t, gotErr) wantErr := orders.NewGetUserOrdersDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "order_column in query should be one of [id rent_start]" + codeExp := int32(606) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) diff --git a/internal/integration-tests/passwordreset/integration_test.go b/internal/integration-tests/passwordreset/integration_test.go index 0c7b939a..8e30a1df 100644 --- a/internal/integration-tests/passwordreset/integration_test.go +++ b/internal/integration-tests/passwordreset/integration_test.go @@ -11,6 +11,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/password_reset" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" ) func TestIntegration_PasswordReset(t *testing.T) { @@ -36,7 +37,7 @@ func TestIntegration_PasswordReset(t *testing.T) { require.NoError(t, err) want := &password_reset.SendLinkByLoginOK{ - Payload: models.PasswordResetResponse("Check your email for a reset link"), + Payload: models.PasswordResetResponse("check your email for a reset link"), } assert.Equal(t, want, got) }) @@ -51,8 +52,10 @@ func TestIntegration_PasswordReset(t *testing.T) { require.Error(t, err) errExp := password_reset.NewSendLinkByLoginDefault(http.StatusBadRequest) - errExp.Payload = &models.Error{ - Data: &models.ErrorData{Message: "Login is required"}, + codeExp := int32(http.StatusBadRequest) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrLoginRequired, } assert.Equal(t, errExp, err) }) @@ -67,7 +70,7 @@ func TestIntegration_PasswordReset(t *testing.T) { require.NoError(t, err) want := &password_reset.SendLinkByLoginOK{ - Payload: models.PasswordResetResponse("Check your email for a reset link"), + Payload: models.PasswordResetResponse("check your email for a reset link"), } assert.Equal(t, want, got) }) diff --git a/internal/integration-tests/petkind/create_integration_test.go b/internal/integration-tests/petkind/create_integration_test.go index 27d4a056..aa39c560 100644 --- a/internal/integration-tests/petkind/create_integration_test.go +++ b/internal/integration-tests/petkind/create_integration_test.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/pet_kind" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -53,8 +54,11 @@ func TestIntegration_PetKind(t *testing.T) { require.Error(t, err) errExp := pet_kind.NewCreateNewPetKindDefault(http.StatusUnprocessableEntity) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "name in body is required" + codeExp := int32(602) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -66,8 +70,11 @@ func TestIntegration_PetKind(t *testing.T) { require.Error(t, err) errExp := pet_kind.NewCreateNewPetKindDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -80,8 +87,10 @@ func TestIntegration_PetKind(t *testing.T) { require.Error(t, err) errExp := pet_kind.NewCreateNewPetKindDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/petkind/get_integration_test.go b/internal/integration-tests/petkind/get_integration_test.go index b5b2bc21..57b3539a 100644 --- a/internal/integration-tests/petkind/get_integration_test.go +++ b/internal/integration-tests/petkind/get_integration_test.go @@ -122,5 +122,5 @@ func TestIntegration_DeletePetKind(t *testing.T) { kind, err := client.PetKind.DeletePetKind(params, utils.AuthInfoFunc(token)) require.NoError(t, err) - assert.Equal(t, kind.GetPayload(), "Pet kind deleted") + assert.Equal(t, kind.GetPayload(), "pet kind deleted") } diff --git a/internal/integration-tests/petsize/create_integration_test.go b/internal/integration-tests/petsize/create_integration_test.go index 437d2fe5..9e663a8b 100644 --- a/internal/integration-tests/petsize/create_integration_test.go +++ b/internal/integration-tests/petsize/create_integration_test.go @@ -8,6 +8,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/pet_size" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -60,8 +61,11 @@ func TestIntegration_PetSize(t *testing.T) { require.Error(t, err) errExp := pet_size.NewCreateNewPetSizeDefault(http.StatusUnprocessableEntity) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "name in body is required" + codeExp := int32(602) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -73,8 +77,11 @@ func TestIntegration_PetSize(t *testing.T) { require.Error(t, err) errExp := pet_size.NewCreateNewPetSizeDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -87,8 +94,10 @@ func TestIntegration_PetSize(t *testing.T) { require.Error(t, err) errExp := pet_size.NewCreateNewPetSizeDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/petsize/get_integration_test.go b/internal/integration-tests/petsize/get_integration_test.go index c15b34d1..9d1ec8e9 100644 --- a/internal/integration-tests/petsize/get_integration_test.go +++ b/internal/integration-tests/petsize/get_integration_test.go @@ -83,7 +83,7 @@ func TestIntegration_DeletePetSize(t *testing.T) { res, err := client.PetSize.DeletePetSize(params, utils.AuthInfoFunc(token)) require.NoError(t, err) - assert.Equal(t, "Pet size deleted", res.GetPayload()) + assert.Equal(t, "pet size deleted", res.GetPayload()) } func getSizeIDByName(ctx context.Context, client *client.Be, token *string, petSizeName string) (*int64, error) { diff --git a/internal/integration-tests/photos/integration_test.go b/internal/integration-tests/photos/integration_test.go index 07776abb..375795e6 100644 --- a/internal/integration-tests/photos/integration_test.go +++ b/internal/integration-tests/photos/integration_test.go @@ -16,6 +16,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/photos" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" ) var ( @@ -93,8 +94,8 @@ func TestIntegration_PhotosUpload(t *testing.T) { require.True(t, errors.As(err, &phErr)) wantMessage := "Wrong file format. File should be jpg or jpeg" - require.NotNil(t, phErr.Payload.Data) - assert.Equal(t, wantMessage, phErr.Payload.Data.Message) + require.NotNil(t, phErr.Payload.Message) + assert.Equal(t, wantMessage, *phErr.Payload.Message) f.Close() }) @@ -106,9 +107,14 @@ func TestIntegration_PhotosUpload(t *testing.T) { _, err = beClient.Photos.CreateNewPhoto(params, auth) require.Error(t, err) - var phErr *photos.CreateNewPhotoBadRequest - require.True(t, errors.As(err, &phErr)) - assert.Nil(t, phErr.Payload.Data) + wantErr := photos.NewCreateNewPhotoBadRequest() + msgExp := "multipart: NextPart: EOF" + codeExp := int32(http.StatusBadRequest) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } + assert.Equal(t, wantErr, err) emptyFile.Close() require.NoError(t, os.Remove("empty.jpeg")) @@ -125,7 +131,11 @@ func TestIntegration_PhotosUpload(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewCreateNewPhotoDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) f.Close() }) @@ -155,7 +165,11 @@ func TestIntegration_DeletePhoto(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewDeletePhotoDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) @@ -164,7 +178,12 @@ func TestIntegration_DeletePhoto(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewDeletePhotoDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "equipmentId in path must be of type int64: \"photos\"" + codeExp := int32(601) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) @@ -173,19 +192,22 @@ func TestIntegration_DeletePhoto(t *testing.T) { require.NoError(t, err) got := result.Payload - want := "Photo deleted" + want := "photo deleted" assert.Equal(t, want, got) }) t.Run("Delete Photo failed: trying to delete again the same photo, photo not found", func(t *testing.T) { - _, err = beClient.Photos.DeletePhoto(photos.NewDeletePhotoParamsWithContext(ctx).WithPhotoID(*res.Payload.Data.ID), auth) - require.Error(t, err) - - var phErr *photos.DeletePhotoDefault - ok := errors.As(err, &phErr) - require.True(t, ok) + _, gotErr := beClient.Photos.DeletePhoto(photos.NewDeletePhotoParamsWithContext(ctx).WithPhotoID(*res.Payload.Data.ID), auth) + require.Error(t, gotErr) - assert.Contains(t, phErr.Payload.Data.Message, "photo not found") + wantErr := photos.NewDeletePhotoDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrDeletePhoto, + Details: "ent: photo not found", + } + assert.Equal(t, wantErr, gotErr) }) f.Close() @@ -252,20 +274,28 @@ func TestIntegration_PhotosDownload(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewDownloadPhotoDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) f.Close() }) t.Run("Download Photo failed: photoID not provided", func(t *testing.T) { - _, err := beClient.Photos.DownloadPhoto(photos.NewDownloadPhotoParamsWithContext(ctx), auth, io.Discard) - require.Error(t, err) - - var phErr *photos.DownloadPhotoDefault - require.True(t, errors.As(err, &phErr)) + _, gotErr := beClient.Photos.DownloadPhoto(photos.NewDownloadPhotoParamsWithContext(ctx), auth, io.Discard) + require.Error(t, gotErr) - assert.Equal(t, http.StatusInternalServerError, phErr.Code()) - assert.Contains(t, phErr.Payload.Data.Message, "photo not found") + wantErr := photos.NewDownloadPhotoDefault(http.StatusInternalServerError) + msgExp := "failed to get photo" + codeExp := int32(http.StatusInternalServerError) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + Details: "ent: photo not found", + } + assert.Equal(t, wantErr, gotErr) }) } @@ -328,7 +358,11 @@ func TestIntegration_PhotoGet(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewGetPhotoDefault(http.StatusUnauthorized) - wantErr.Payload = &models.Error{Data: nil} + codeExp := int32(http.StatusUnauthorized) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) f.Close() }) @@ -338,7 +372,12 @@ func TestIntegration_PhotoGet(t *testing.T) { require.Error(t, gotErr) wantErr := photos.NewGetPhotoDefault(http.StatusUnprocessableEntity) - wantErr.Payload = &models.Error{Data: nil} + msgExp := "equipmentId in path must be of type int64: \"photos\"" + codeExp := int32(601) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) } diff --git a/internal/integration-tests/registrationconfirm/integration_test.go b/internal/integration-tests/registrationconfirm/integration_test.go index d4821237..405572b1 100644 --- a/internal/integration-tests/registrationconfirm/integration_test.go +++ b/internal/integration-tests/registrationconfirm/integration_test.go @@ -8,6 +8,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/registration_confirm" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -53,8 +54,10 @@ func TestIntegration_SendConfirmLink(t *testing.T) { require.Error(t, err) errExp := registration_confirm.NewSendRegistrationConfirmLinkByLoginDefault(http.StatusInternalServerError) - errExp.Payload = &models.Error{ - Data: &models.ErrorData{Message: "Can't find this user, registration confirmation link wasn't send"}, + codeExp := int32(http.StatusInternalServerError) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrRegistrationCannotFindUser, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/roles/integration_test.go b/internal/integration-tests/roles/integration_test.go index f0f70b37..a93b3ee4 100644 --- a/internal/integration-tests/roles/integration_test.go +++ b/internal/integration-tests/roles/integration_test.go @@ -8,6 +8,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/roles" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,8 +40,11 @@ func TestIntegration_GetRoles(t *testing.T) { require.Error(t, err) errExp := roles.NewGetRolesDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -53,8 +57,10 @@ func TestIntegration_GetRoles(t *testing.T) { require.Error(t, err) errExp := roles.NewGetRolesDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/user/get_data_integration_test.go b/internal/integration-tests/user/get_data_integration_test.go index 3a4ebd76..5205c65a 100644 --- a/internal/integration-tests/user/get_data_integration_test.go +++ b/internal/integration-tests/user/get_data_integration_test.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/users" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -55,8 +56,10 @@ func TestIntegration_GetCurrentUser(t *testing.T) { _, err = client.Users.GetCurrentUser(params, authInfo) errExp := users.NewGetCurrentUserDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) @@ -69,8 +72,11 @@ func TestIntegration_GetCurrentUser(t *testing.T) { assert.Error(t, err) errExp := users.NewGetCurrentUserDefault(401) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -104,8 +110,11 @@ func TestIntegration_GetAllUsers(t *testing.T) { assert.Error(t, err) errExp := users.NewGetAllUsersDefault(401) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -118,8 +127,10 @@ func TestIntegration_GetAllUsers(t *testing.T) { _, err := client.Users.GetAllUsers(params, authInfo) errExp := users.NewGetAllUsersDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/user/login_integration_test.go b/internal/integration-tests/user/login_integration_test.go index 611e15fc..470be61c 100644 --- a/internal/integration-tests/user/login_integration_test.go +++ b/internal/integration-tests/user/login_integration_test.go @@ -61,7 +61,7 @@ func TestIntegration_Login(t *testing.T) { require.Equal(t, ok, true) wantErr := users.NewLoginUnauthorized() - wantErr.Payload = "Invalid login or password" + wantErr.Payload = "invalid login or password" assert.Equal(t, wantErr, gotErr) }) @@ -84,7 +84,7 @@ func TestIntegration_Login(t *testing.T) { require.Equal(t, ok, true) wantErr := users.NewLoginUnauthorized() - wantErr.Payload = "Invalid login or password" + wantErr.Payload = "invalid login or password" assert.Equal(t, wantErr, gotErr) }) @@ -103,8 +103,12 @@ func TestIntegration_Login(t *testing.T) { require.Equal(t, ok, true) wantErr := users.NewLoginDefault(422) - wantErr.Payload = &models.Error{Data: nil} - + msgExp := "login in body is required" + codeExp := int32(602) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, + } assert.Equal(t, wantErr, gotErr) }) } diff --git a/internal/integration-tests/user/patch_user_integration_test.go b/internal/integration-tests/user/patch_user_integration_test.go index 92e28b8e..bdf2b314 100644 --- a/internal/integration-tests/user/patch_user_integration_test.go +++ b/internal/integration-tests/user/patch_user_integration_test.go @@ -9,6 +9,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/users" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/brianvoe/gofakeit/v6" "github.com/go-openapi/strfmt" @@ -78,8 +79,11 @@ func TestIntegration_PatchUpdate(t *testing.T) { assert.Error(t, err) errExp := users.NewPatchUserDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "unauthenticated for invalid credentials" + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) @@ -95,8 +99,10 @@ func TestIntegration_PatchUpdate(t *testing.T) { assert.Error(t, err) errExp := users.NewPatchUserDefault(http.StatusUnauthorized) - errExp.Payload = &models.Error{ - Data: nil, + codeExp := int32(http.StatusUnauthorized) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, } assert.Equal(t, errExp, err) }) @@ -108,8 +114,11 @@ func TestIntegration_PatchUpdate(t *testing.T) { assert.Error(t, err) errExp := users.NewPatchUserDefault(http.StatusUnprocessableEntity) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "userPatch in body is required" + codeExp := int32(602) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) diff --git a/internal/integration-tests/user/refresh_integration_test.go b/internal/integration-tests/user/refresh_integration_test.go index ea5383cf..a11a89a9 100644 --- a/internal/integration-tests/user/refresh_integration_test.go +++ b/internal/integration-tests/user/refresh_integration_test.go @@ -2,12 +2,14 @@ package user import ( "context" + "net/http" "testing" "time" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/users" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" _ "github.com/jackc/pgx/v4/stdlib" "github.com/stretchr/testify/assert" @@ -79,9 +81,11 @@ func TestIntegration_Refresh(t *testing.T) { require.Error(t, gotErr) wantErr := users.NewRefreshDefault(400) - wantErr.Payload = &models.Error{Data: &models.ErrorData{ - Message: "token invalid", - }} + codeExp := int32(http.StatusBadRequest) + wantErr.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrInvalidToken, + } assert.Equal(t, wantErr, gotErr) }) } diff --git a/internal/integration-tests/user/register_integration_test.go b/internal/integration-tests/user/register_integration_test.go index a58e3c2b..a7d6d14d 100644 --- a/internal/integration-tests/user/register_integration_test.go +++ b/internal/integration-tests/user/register_integration_test.go @@ -8,6 +8,7 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/client/users" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" utils "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/integration-tests/common" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "github.com/brianvoe/gofakeit/v6" "github.com/go-openapi/strfmt" @@ -57,14 +58,12 @@ func TestIntegration_RegisterUser(t *testing.T) { r, err := c.Users.PostUser(params) require.Error(t, err, r) - errExp := users.NewPostUserDefault(417) - errExp.Payload = &models.Error{ - Data: &models.ErrorData{ - CorrelationID: "", - Message: "login is already used", - }, + errExp := users.NewPostUserDefault(http.StatusExpectationFailed) + codeExp := int32(http.StatusExpectationFailed) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrLoginInUse, } - assert.Equal(t, errExp, err) }) @@ -120,8 +119,11 @@ func TestIntegration_RegisterUser(t *testing.T) { require.Error(t, err) errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "type in body should be one of [person organization]" + codeExp := int32(606) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) @@ -136,24 +138,37 @@ func TestIntegration_RegisterUser(t *testing.T) { require.Error(t, err) errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "login in body should be at least 3 chars long" + codeExp := int32(604) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) t.Run("name validation error", func(t *testing.T) { - empty := "" - data.Name = empty + userType = "person" + data = &models.UserRegister{ + ActiveAreas: []int64{3}, + Login: &l, + Password: &p, + Type: &userType, + Name: "", + Email: strfmt.Email(gofakeit.Email()), + } params.SetData(data) _, err := c.Users.PostUser(params) require.Error(t, err) - errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + errExp := users.NewPostUserDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrCreateUser, + Details: "ent: validator failed for field \"User.name\": value is less than the required length", } assert.Equal(t, errExp, err) @@ -161,36 +176,65 @@ func TestIntegration_RegisterUser(t *testing.T) { t.Run("email validation error", func(t *testing.T) { empty := "" - data.Email = strfmt.Email(empty) + data = &models.UserRegister{ + ActiveAreas: []int64{3}, + Login: &l, + Password: &p, + Type: &userType, + Name: gofakeit.Name(), + Email: strfmt.Email(empty), + } + params.SetData(data) _, err := c.Users.PostUser(params) require.Error(t, err) - errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + errExp := users.NewPostUserDefault(http.StatusInternalServerError) + codeExp := int32(http.StatusInternalServerError) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &messages.ErrCreateUser, + Details: "ent: validator failed for field \"User.email\": value is less than the required length", } assert.Equal(t, errExp, err) }) t.Run("password validation error", func(t *testing.T) { - data.Password = nil + data = &models.UserRegister{ + ActiveAreas: []int64{3}, + Login: &l, + Password: nil, + Type: &userType, + Name: gofakeit.Name(), + Email: strfmt.Email(gofakeit.Email()), + } params.SetData(data) _, err := c.Users.PostUser(params) require.Error(t, err) errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "password in body is required" + codeExp := int32(602) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } - assert.Equal(t, errExp, err) }) t.Run("password validation error: length less than 3", func(t *testing.T) { + data = &models.UserRegister{ + ActiveAreas: []int64{3}, + Login: &l, + Password: &p, + Type: &userType, + Name: gofakeit.Name(), + Email: strfmt.Email(gofakeit.Email()), + } + notEmpty := "22" data.Password = ¬Empty params.SetData(data) @@ -199,14 +243,30 @@ func TestIntegration_RegisterUser(t *testing.T) { require.Error(t, err) errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "password in body should be at least 6 chars long" + codeExp := int32(604) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) }) t.Run("type validation error: type is not person or organization", func(t *testing.T) { + data = &models.UserRegister{ + ActiveAreas: []int64{3}, + Login: &l, + Password: &p, + Type: &userType, + // not provided in documentation, but also required + // todo: update documentation + Name: gofakeit.Name(), + // not provided in documentation, but also required + // todo: update documentation + Email: strfmt.Email(gofakeit.Email()), + } + notDefinedType := "some type" data.Type = ¬DefinedType params.SetData(data) @@ -215,8 +275,11 @@ func TestIntegration_RegisterUser(t *testing.T) { require.Error(t, err) errExp := users.NewPostUserDefault(422) - errExp.Payload = &models.Error{ - Data: nil, + msgExp := "type in body should be one of [person organization]" + codeExp := int32(606) + errExp.Payload = &models.SwaggerError{ + Code: &codeExp, + Message: &msgExp, } assert.Equal(t, errExp, err) diff --git a/internal/messages/messages.go b/internal/messages/messages.go new file mode 100644 index 00000000..8b310a41 --- /dev/null +++ b/internal/messages/messages.go @@ -0,0 +1,174 @@ +package messages + +// Keep in mind that these messages will be used by frontend team. +// So, if you change it, you should notify them. +var ( + MsgAllOk = "all ok" + + // Area + + ErrQueryTotalAreas = "failed to query total active areas" + ErrQueryAreas = "failed to query active areas" + + // Category + + ErrCreateCategory = "cant create new category" + ErrQueryTotalCategories = "cant get total amount of categories" + ErrQueryCategories = "cant get all categories" + ErrGetCategory = "failed to get category" + ErrDeleteCategory = "delete category failed" + ErrUpdateCategory = "cant update category" + MsgCategoryDeleted = "category deleted" + + // Email Confirmation + + ErrEmailConfirm = "failed to verify email confirmation token" + MsgEmailConfirmed = "you have successfully confirmed new email" + + // Equipment Periods + + ErrGetUnavailableEqStatus = "can't find unavailable equipment status dates" + + // Equipment Status Names + + ErrCreateEqStatus = "can't create equipment status" + ErrQueryEqStatuses = "can't get equipment statuses" + ErrGetEqStatus = "can't get equipment status" + ErrDeleteEqStatus = "can't delete equipment status" + + // Equipment Status + + ErrWrongEqStatus = "wrong new equipment status, status should be only 'not available'" + ErrGetEqStatusByID = "can't find equipment status by provided id" + ErrOrderAndUserByEqStatusID = "can't receive order and user data during checking equipment status" + ErrUpdateEqStatus = "can't update equipment status" + + // Equipment + + ErrCreateEquipment = "error while creating equipment" + ErrMapEquipment = "error while mapping equipment" + ErrGetEquipment = "error while getting equipment" + ErrEquipmentNotFound = "equipment not found" + ErrEquipmentArchive = "error while archiving equipment" + ErrEquipmentBlock = "error while blocking equipment" + ErrEquipmentUnblock = "error while unblocking equipment" + ErrDeleteEquipment = "error while deleting equipment" + ErrQueryTotalEquipments = "error while getting total of all equipments" + ErrQueryEquipments = "error while getting all equipments" + ErrUpdateEquipment = "error while updating equipment" + ErrFindEquipment = "error while finding equipment" + ErrEquipmentBlockForbidden = "you don't have rights to block the equipment" + ErrEquipmentUnblockForbidden = "you don't have rights to unblock the equipment" + ErrStartDateAfterEnd = "start date should be before end date" + MsgEquipmentDeleted = "equipment deleted" + + // Order Status + + ErrQueryOrderHistory = "can't get order history" + ErrQueryOrderHistoryForbidden = "you don't have rights to see this order" + ErrCreateOrderStatusForbidden = "you don't have rights to add a new status" + ErrOrderStatusEmpty = "order status is empty" + ErrGetOrderStatus = "can't get order current status" + ErrUpdateOrderStatus = "can't update status" + ErrQueryTotalOrdersByStatus = "can't get total count of orders by status" + ErrQueryOrdersByStatus = "can't get orders by status" + ErrQueryTotalOrdersByPeriodAndStatus = "can't get total amount of orders by period and status" + ErrQueryOrdersByPeriodAndStatus = "can't get orders by period and status" + ErrMapOrderStatus = "can't map order status name" + ErrQueryStatusNames = "can't get all status names" + + // Order + + ErrOrderNotFound = "no order with such id" + ErrMapOrder = "can't map order" + ErrQueryOrders = "can't get orders" + ErrQueryTotalOrders = "error while getting total of orders" + ErrUpdateOrder = "update order failed" + ErrEquipmentIsNotFree = "requested equipment is not free" + ErrCheckEqStatusFailed = "error while checking if equipment is available for period" + ErrSmallRentPeriod = "small rent period" + + // Password Reset + + ErrLoginRequired = "login is required" + MsgPasswordResetSuccesful = "check your email for a reset link" + + // Pet Kind + + ErrCreatePetKind = "error while creating pet kind" + ErrGetPetKind = "error while getting pet kind" + ErrPetKindNotFound = "no pet kind found" + ErrUpdatePetKind = "error while updating pet kind" + ErrDeletePetKind = "error while deleting pet kind" + MsgPetKindDeleted = "pet kind deleted" + + // Pet Size + + ErrCreatePetSize = "error while creating pet size" + ErrPetSizeAlreadyExists = "error while creating pet size: the name already exist" + ErrGetPetSize = "error while getting pet size" + ErrPetSizeNotFound = "no pet size found" + ErrUpdatePetSize = "error while updating pet size" + ErrDeletePetSize = "error while deleting pet size" + MsgPetSizeDeleted = "pet size deleted" + + // Photo + + ErrCreatePhoto = "failed to save photo" + ErrFileEmpty = "File is empty" + ErrWrongFormat = "Wrong file format. File should be jpg or jpeg" + ErrGetPhoto = "failed to get photo" + ErrDeletePhoto = "failed to delete photo" + MsgPhotoDeleted = "photo deleted" + + // Registration Confirm + + ErrRegistrationAlreadyConfirmed = "Registration is already confirmed." + ErrRegistrationCannotFindUser = "Can't find this user, registration confirmation link wasn't send" + ErrRegistrationCannotSend = "Can't send registration confirmation link. Please try again later" + ErrFailedToConfirm = "Failed to verify confirmation token. Please try again later" + MsgConfirmationNotRequired = "Confirmation link was not sent to email, sending parameter was set to false and not required" + MsgConfirmationSent = "Confirmation link was sent" + MsgRegistrationConfirmed = "You have successfully confirmed registration" + + // Roles + + ErrQueryRoles = "can't get all roles" + + // Subcategory + + ErrCreateSubcategory = "failed to create new subcategory" + ErrMapSubcategory = "failed to map new subcategory" + ErrQuerySCatByCategory = "failed to list subcategories by category id" + ErrGetSubcategory = "failed to get subcategory" + ErrDeleteSubcategory = "failed to delete subcategory" + ErrUpdateSubcategory = "failed to update subcategory" + MsgSubcategoryDeleted = "subcategory deleted" + + // User + + ErrInvalidLoginOrPass = "invalid login or password" + ErrLoginInUse = "login is already used" + ErrCreateUser = "failed to create user" + ErrInvalidToken = "token is invalid" + ErrTokenRefresh = "error while refreshing token" + ErrMapUser = "map user error" + ErrUserNotFound = "can't find user by id" + ErrUpdateUser = "can't update user" + ErrRoleRequired = "role id is required" + ErrSetUserRole = "set user role error" + ErrQueryTotalUsers = "failed get user total amount" + ErrQueryUsers = "failed to get user list" + ErrDeleteUser = "can't delete user" + ErrDeleteUserNotRO = "user must be readonly for deletion" + ErrUserPasswordChange = "error while changing password" + ErrWrongPassword = "wrong password" + ErrPasswordsAreSame = "old and new passwords are the same" + ErrPasswordPatchEmpty = "password patch is empty" + ErrUpdateROAccess = "error while updating readonly access" + ErrChangeEmail = "error while changing email" + ErrEmailPatchEmpty = "email patch is empty" + ErrNewEmailConfirmation = "can't send link for confirmation new email" + MsgLogoutSuccessful = "successfully logged out" + MsgRoleAssigned = "role assigned" +) diff --git a/internal/middlewares/access_manager.go b/internal/middlewares/access_manager.go index 78384ec3..b0268c9a 100644 --- a/internal/middlewares/access_manager.go +++ b/internal/middlewares/access_manager.go @@ -77,12 +77,12 @@ func allRoleVariation(roles []Role) []Role { variations := []bool{false, true} for _, role := range roles { - for _, isRegistrationConfirmed := range variations { + for _, IsRegistrationConfirmed := range variations { for _, isPersonalDataConfirmed := range variations { for _, isReadonly := range variations { res = append(res, Role{ Slug: role.Slug, - IsRegistrationConfirmed: isRegistrationConfirmed, + IsRegistrationConfirmed: IsRegistrationConfirmed, IsPersonalDataConfirmed: isPersonalDataConfirmed, IsReadonly: isReadonly, }) @@ -199,7 +199,7 @@ func (a *blackListAccessManager) VerifyAccess(role Role, method, path string) er } allowedPaths, ok := a.accessMap[role][method] if !ok { - return openApiErrors.New(http.StatusForbidden, models.SwaggerErrorMessageUserIsNotAuthorized) + return openApiErrors.New(http.StatusForbidden, "user is not authorized") } for _, allowedPath := range allowedPaths { if allowedPath.isMatch(path) { @@ -207,15 +207,15 @@ func (a *blackListAccessManager) VerifyAccess(role Role, method, path string) er } } if !role.IsRegistrationConfirmed { - return openApiErrors.New(http.StatusForbidden, models.SwaggerErrorMessageUserHasNoConfirmedEmail) + return openApiErrors.New(http.StatusForbidden, "user has no confirmed email") } - return openApiErrors.New(http.StatusForbidden, models.SwaggerErrorMessageUserIsNotAuthorized) + return openApiErrors.New(http.StatusForbidden, "user is not authorized") } func (a *blackListAccessManager) Authorize(r *http.Request, auth interface{}) error { principal, ok := auth.(*models.Principal) if !ok { - return openApiErrors.New(http.StatusForbidden, models.SwaggerErrorMessageUserIsNotAuthorized) + return openApiErrors.New(http.StatusForbidden, "user is not authorized") } role := Role{ diff --git a/internal/middlewares/api_key_auth.go b/internal/middlewares/api_key_auth.go index 4ba67317..4523c773 100644 --- a/internal/middlewares/api_key_auth.go +++ b/internal/middlewares/api_key_auth.go @@ -10,13 +10,14 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/ent" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/messages" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/services" "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) func TokenInvalidError() error { // make sure that the error message is exactly as the one in the #/definitions/SwaggerError object. - return errors.New(http.StatusUnauthorized, "Token is invalid") + return errors.New(http.StatusUnauthorized, messages.ErrInvalidToken) } func APIKeyAuthFunc(key interface{}, userRepository domain.UserRepository) func(context.Context, string) (context.Context, interface{}, error) { diff --git a/internal/middlewares/tx.go b/internal/middlewares/tx.go index 895086a7..6a88c6da 100644 --- a/internal/middlewares/tx.go +++ b/internal/middlewares/tx.go @@ -2,12 +2,11 @@ package middlewares import ( "context" - "encoding/json" "fmt" "net/http" "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/ent" - "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/utils" ) type contextKey string @@ -34,13 +33,7 @@ func Tx(cln *ent.Client) func(next http.Handler) http.Handler { ctx := r.Context() tx, err = cln.Tx(ctx) if err != nil { - writeResponse(w, http.StatusInternalServerError, &models.Error{ - Data: &models.ErrorData{ - // TODO: add correlation id - CorrelationID: "", - Message: "Error initiating transaction", - }, - }) + utils.WriteErrorResponse(w, http.StatusInternalServerError, "Error initiating transaction") return } defer func() { @@ -62,15 +55,3 @@ func Tx(cln *ent.Client) func(next http.Handler) http.Handler { }) } } - -func writeResponse(w http.ResponseWriter, code int, v interface{}) { - w.Header().Set("Content-Type", "application/json") - b, err := json.Marshal(v) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - w.Write([]byte(`{"data":{"message":"Internal server error"}}`)) - return - } - w.WriteHeader(code) - w.Write(b) -} diff --git a/internal/repositories/equipment.go b/internal/repositories/equipment.go index 708815c9..b19fa7fd 100644 --- a/internal/repositories/equipment.go +++ b/internal/repositories/equipment.go @@ -510,11 +510,6 @@ func (r *equipmentRepository) BlockEquipment( return err } - start, end, err := checkDates(&startDate, &endDate) - if err != nil { - return err - } - // Set a new EquipmentStatusName for current Equipment _, err = eqToBlock.Update().SetCurrentStatus(eqStatusNotAvailable).Save(ctx) if err != nil { @@ -524,8 +519,8 @@ func (r *equipmentRepository) BlockEquipment( // Create a new EquipmentStatus and set startDate, endDate, Equipment and EquipmentStatusName _, err = tx.EquipmentStatus.Create(). SetCreatedAt(time.Now()). - SetEndDate(*end). - SetStartDate(*start). + SetEndDate(startDate). + SetStartDate(endDate). SetEquipments(eqToBlock). SetEquipmentStatusName(eqStatusNotAvailable). SetUpdatedAt(time.Now()). @@ -545,8 +540,8 @@ func (r *equipmentRepository) BlockEquipment( // Find all Orders which have OrderStatusName booked and start from startDate and later orderIDs, err := eqToBlock.QueryOrder(). - Where(order.RentStartGTE(*start), order.RentStartLTE(*end)). // rentStart must be in range of startDate..endDate - Where(order.RentEndGTE(*start)). // rentEnd must be equal or greater than startDate + Where(order.RentStartGTE(startDate), order.RentStartLTE(endDate)). // rentStart must be in range of startDate..endDate + Where(order.RentEndGTE(startDate)). // rentEnd must be equal or greater than startDate Where(order.HasCurrentStatusWith(orderstatusname.StatusIn( domain.OrderStatusPrepared, domain.OrderStatusApproved))). @@ -637,17 +632,6 @@ func (r *equipmentRepository) UnblockEquipment(ctx context.Context, id int) erro return err } -func checkDates(start *time.Time, end *time.Time) (*time.Time, *time.Time, error) { - startDate := time.Time(*start) - endDate := time.Time(*end) - - if startDate.After(endDate) { - return nil, nil, errors.New("start date should be before end date") - } - - return &startDate, &endDate, nil -} - // Set EquipmentStatus EndDate back in time to give access for the unblocked equipment again func truncateHours(date *time.Time) time.Time { extraHour := 1 diff --git a/internal/repositories/equipment_test.go b/internal/repositories/equipment_test.go index c5aba342..2dd32f16 100644 --- a/internal/repositories/equipment_test.go +++ b/internal/repositories/equipment_test.go @@ -658,56 +658,6 @@ func (s *EquipmentSuite) TestEquipmentRepository_UnblockEquipment() { require.NoError(t, tx.Commit()) } -func Test_checkDates(t *testing.T) { - start := time.Now() - end := time.Now().Add(time.Hour * 24) - var blankTime time.Time - type args struct { - start *time.Time - end *time.Time - } - tests := []struct { - name string - args args - want *time.Time - want1 *time.Time - wantErr bool - }{ - { - name: "When correct time", - args: args{start: &start, end: &end}, - want: &start, - want1: &end, - wantErr: false, - }, - { - name: "When end date becomes earlier thar start date", - args: args{start: &end, end: &start}, - want: nil, - want1: nil, - wantErr: true, - }, - { - name: "When default time", - args: args{start: &blankTime, end: &blankTime}, - want: &blankTime, - want1: &blankTime, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, got1, err := checkDates(tt.args.start, tt.args.end) - require.Equal(t, tt.want, got) - require.Equal(t, tt.want1, got1) - if (err != nil) != tt.wantErr { - t.Errorf("checkDates() error = %v, wantErr %v", err, tt.wantErr) - return - } - }) - } -} - func Test_truncateHours(t *testing.T) { date := time.Now() type args struct { diff --git a/internal/repositories/order.go b/internal/repositories/order.go index 26f74f0e..6185360d 100644 --- a/internal/repositories/order.go +++ b/internal/repositories/order.go @@ -22,11 +22,11 @@ import ( "git.epam.com/epm-lstr/epm-lstr-lc/be/pkg/domain" ) -type OrderAccessDenied struct { +type OrderValidationError struct { Err error } -func (r OrderAccessDenied) Error() string { +func (r OrderValidationError) Error() string { return r.Err.Error() } @@ -46,18 +46,9 @@ func getDates(start *strfmt.DateTime, end *strfmt.DateTime, maxSeconds int) (*ti rentStart := time.Time(*start) rentEnd := time.Time(*end) - if rentStart.After(rentEnd) { - return nil, nil, errors.New("start date should be before end date") - } - - diff := rentEnd.Sub(rentStart) - days := diff.Hours() / 24 - if days < 1 { - return nil, nil, errors.New("small rent period") - } - - if int(diff.Seconds()) > maxSeconds { - return nil, nil, errors.New("too big reservation period") + if int(rentEnd.Sub(rentStart).Seconds()) > maxSeconds { + // This kind of validation cannot be performed on handler's layer + return nil, nil, OrderValidationError{Err: errors.New("too big reservation period")} } return &rentStart, &rentEnd, nil @@ -65,7 +56,8 @@ func getDates(start *strfmt.DateTime, end *strfmt.DateTime, maxSeconds int) (*ti func getQuantity(quantity int, maxQuantity int) (*int, error) { if quantity > maxQuantity { - return nil, fmt.Errorf("quantity limit exceeded: %d allowed", maxQuantity) + // This kind of validation cannot be performed on handler's layer + return nil, OrderValidationError{Err: fmt.Errorf("quantity limit exceeded: %d allowed", maxQuantity)} } return &quantity, nil @@ -224,7 +216,7 @@ func (r *orderRepository) Update(ctx context.Context, id int, data *models.Order } if owner.ID != userId { - return nil, OrderAccessDenied{Err: errors.New("permission denied")} + return nil, OrderValidationError{Err: errors.New("permission denied")} } equipment, err := foundOrder.QueryEquipments().First(ctx) diff --git a/internal/utils/error_response.go b/internal/utils/error_response.go new file mode 100644 index 00000000..a4a2c42a --- /dev/null +++ b/internal/utils/error_response.go @@ -0,0 +1,24 @@ +package utils + +import ( + "encoding/json" + "net/http" + + "git.epam.com/epm-lstr/epm-lstr-lc/be/internal/generated/swagger/models" +) + +func WriteErrorResponse(w http.ResponseWriter, code int32, message string) { + w.Header().Set("Content-Type", "application/json") + e := models.SwaggerError{ + Code: &code, + Message: &message, + } + b, err := json.Marshal(e) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte(`{"code":500,"message":"Unexpected error"}`)) + return + } + w.WriteHeader(int(code)) + w.Write(b) +} diff --git a/swagger.yaml b/swagger.yaml index 4cdbe1ca..10640968 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -32,7 +32,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/login: post: description: 'Returns token for authorized User' @@ -60,7 +60,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/logout: post: description: 'Logout user' @@ -84,11 +84,11 @@ paths: 404: description: Refresh token not found. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/refresh: post: description: 'Returns new token pair for an authorized User' @@ -113,11 +113,11 @@ paths: 404: description: Refresh token not found. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users: get: parameters: @@ -169,7 +169,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" post: summary: Register a new user. tags: @@ -190,7 +190,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users/me: get: summary: Get the current user data. @@ -207,7 +207,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" patch: summary: Edit selected fields of the current user. security: @@ -230,7 +230,7 @@ paths: default: description: Unexpected error schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete the current user. security: @@ -244,7 +244,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users/me/password: patch: summary: Change the current user password. @@ -268,15 +268,15 @@ paths: 401: description: Unauthorized schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" 403: description: Wrong old password schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users/me/email: patch: summary: Change the current email. @@ -300,11 +300,11 @@ paths: 401: description: Unauthorized schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/email_confirm/{token}: get: summary: Verify email confirmation token. @@ -324,7 +324,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /management/users/{userId}: parameters: - name: userId @@ -347,7 +347,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/roles: get: summary: List all roles. @@ -364,7 +364,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/management/users/{userId}/role: parameters: - name: userId @@ -396,7 +396,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users/{userId}: parameters: @@ -429,7 +429,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: consumes: - application/json @@ -445,11 +445,11 @@ paths: 404: description: User not found schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/users/{userId}/readonly-access: put: @@ -481,23 +481,23 @@ paths: 400: description: Bad request schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" 401: description: Unauthorized schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" 403: description: Forbidden schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" 404: description: User not found schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipmentstatus/repaired/{equipmentstatusId}: parameters: @@ -528,7 +528,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Change equipment status on unavailable with start/end dates by id. security: @@ -551,7 +551,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" get: summary: Check that equipment status has orders on provided dates. security: @@ -574,7 +574,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" patch: summary: Change repaired equipment status dates by id. security: @@ -597,7 +597,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/status_names: post: summary: Creating a new equipment status. @@ -621,7 +621,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" get: summary: List all statuses. security: @@ -637,7 +637,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/statuses/{statusId}: parameters: - name: statusId @@ -660,7 +660,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete status by id security: @@ -676,7 +676,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/categories: get: parameters: @@ -730,7 +730,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" post: summary: Create a new Category. security: @@ -753,7 +753,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/unavailability_periods/{equipmentId}: parameters: - name: equipmentId @@ -776,7 +776,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" 404: schema: type: string @@ -803,7 +803,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete category of equipment from db by id. security: @@ -819,7 +819,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Edit equipment category by id. security: @@ -841,7 +841,7 @@ paths: default: description: Unexpected error schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/categories/{categoryId}/subcategories: parameters: - name: categoryId @@ -864,7 +864,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" post: summary: Create a new Subcategory. security: @@ -887,7 +887,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/categories/subcategories/{subcategoryId}: parameters: - name: subcategoryId @@ -910,7 +910,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete subcategory of equipment from db by id. security: @@ -926,7 +926,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Edit equipment subcategory by id. security: @@ -948,7 +948,7 @@ paths: default: description: Unexpected error schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/photos: post: summary: Upload a new equipment photo @@ -973,11 +973,11 @@ paths: 400: description: Bad request schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/photos/{photoId}: parameters: - name: photoId @@ -1003,7 +1003,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete photo by id security: @@ -1019,7 +1019,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/photos/{photoId}/download: parameters: - name: photoId @@ -1045,7 +1045,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/orders: get: tags: @@ -1110,7 +1110,7 @@ paths: default: description: 'Unexpected error' schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' post: tags: - Orders @@ -1127,7 +1127,7 @@ paths: default: description: 'Unexpected error' schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' parameters: - name: data in: body @@ -1163,7 +1163,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/order_statuses/{orderId}: get: summary: Get full order status history. @@ -1190,7 +1190,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /v1/order_statuses/: post: summary: Add new order status to order status history. @@ -1214,7 +1214,7 @@ paths: default: description: Unexpected error. schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' /v1/orders/status/{status}: get: summary: Get orders by status. @@ -1274,7 +1274,7 @@ paths: default: description: Unexpected error. schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' /v1/orders/from={fromDate}&to={toDate}&status={statusName}: get: summary: Get orders by date and status. @@ -1343,7 +1343,7 @@ paths: default: description: Unexpected error. schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' /v1/status_names: get: summary: Get all status names. @@ -1360,7 +1360,7 @@ paths: default: description: Unexpected error. schema: - $ref: '#/definitions/Error' + $ref: '#/definitions/SwaggerError' /v1/active_areas: get: parameters: @@ -1408,7 +1408,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment: post: summary: Register a new equipment @@ -1434,7 +1434,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" get: summary: Get all equipment security: @@ -1482,7 +1482,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/{equipmentId}: parameters: - name: equipmentId @@ -1505,7 +1505,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete equipment by id security: @@ -1521,7 +1521,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Edit equipment by id security: @@ -1544,7 +1544,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/achive/{equipmentId}/: parameters: - name: equipmentId @@ -1565,11 +1565,11 @@ paths: 404: description: Equipment not found schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/{equipmentId}/blocking: parameters: - name: equipmentId @@ -1597,11 +1597,11 @@ paths: 404: description: Equipment not found schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/{equipmentId}/unblocking: parameters: - name: equipmentId @@ -1622,11 +1622,11 @@ paths: 404: description: Equipment not found schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /equipment/search: post: summary: Equipment filtered list @@ -1681,7 +1681,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /pet_size: post: summary: Register a new pet size @@ -1707,7 +1707,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" get: summary: Get all pet size security: @@ -1723,7 +1723,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /pet_size/{petSizeId}: parameters: - name: petSizeId @@ -1746,7 +1746,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete pet size by id security: @@ -1762,7 +1762,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Edit pet size by id security: @@ -1785,7 +1785,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /password_reset/: post: @@ -1807,7 +1807,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /password_reset/{token}: get: @@ -1828,7 +1828,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /pet_kind: get: @@ -1846,7 +1846,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" post: summary: Register a new pet kind security: @@ -1871,7 +1871,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /pet_kind/{petKindId}: parameters: - name: petKindId @@ -1894,7 +1894,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" delete: summary: Delete pet kind by id security: @@ -1910,7 +1910,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" put: summary: Edit pet kind by id security: @@ -1933,7 +1933,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /registration_confirm/: post: @@ -1955,7 +1955,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /registration_confirm/{token}: get: @@ -1976,7 +1976,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" /management/orders: get: summary: Get all orders @@ -2048,7 +2048,7 @@ paths: default: description: Unexpected error. schema: - $ref: "#/definitions/Error" + $ref: "#/definitions/SwaggerError" definitions: principal: @@ -2072,16 +2072,11 @@ definitions: properties: code: type: integer - enum: - - 401 - - 403 format: int32 message: type: string - enum: - - Token is invalid - - User is not authorized - - User has no confirmed email + details: + type: string PetKind: type: object required: @@ -2089,18 +2084,6 @@ definitions: properties: name: type: string - Error: - type: object - required: - - data - properties: - data: - type: object - properties: - correlationId: - type: string - message: - type: string ListOfPetKinds: type: array