INFRA-2971 : Add member api segregated (#385)
* INFRA-2971 : Add member api segregated * INFRA-2971 : pr review changes * INFRA-2971 : Message updated
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
common "houston/service/response/common"
|
||||
"houston/service/teamService"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
@@ -158,6 +159,22 @@ func (handler *TeamHandler) HandleMakeManager(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, common.SuccessResponse("Team manager updated successfully", http.StatusOK))
|
||||
}
|
||||
|
||||
func (handler *TeamHandler) HandleAddMembers(c *gin.Context, request team.UpdateTeamRequest) {
|
||||
err := validateAddMemberRequest(request)
|
||||
if err != nil {
|
||||
handler.handleErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
err = handler.service.AddTeamMember(request, c.GetHeader(util.UserEmailHeader))
|
||||
if err != nil {
|
||||
handler.handleErrorResponse(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, common.SuccessResponse("Members added successfully", http.StatusOK))
|
||||
}
|
||||
|
||||
func validateAddTeamRequest(request team.AddTeamRequest) error {
|
||||
teamName := request.Name
|
||||
minLength := viper.GetInt("TEAM_NAME_MIN_LENGTH")
|
||||
@@ -193,12 +210,9 @@ func validateUpdateTeamRequest(request team.UpdateTeamRequest) error {
|
||||
}
|
||||
|
||||
if request.Members != nil {
|
||||
if request.Members.SeverityId == 0 {
|
||||
return customErrors.NewInvalidInputError("Severity id not provided for members to add")
|
||||
}
|
||||
|
||||
if len(request.Members.UserEmailIds) == 0 {
|
||||
return customErrors.NewInvalidInputError("No user email ids provided for members to add")
|
||||
err := validateMembers(request.Members)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,3 +255,46 @@ func validateGetTeamParams(c *gin.Context) (uint, error) {
|
||||
|
||||
return uint(teamId), nil
|
||||
}
|
||||
|
||||
func validateAddMemberRequest(request team.UpdateTeamRequest) error {
|
||||
if request.Id == 0 {
|
||||
return customErrors.NewInvalidInputError("Team id not provided")
|
||||
}
|
||||
|
||||
err := validateMembers(request.Members)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateMembers(members *team.Members) error {
|
||||
if members == nil {
|
||||
return customErrors.NewInvalidInputError("Members not provided")
|
||||
}
|
||||
|
||||
if members.SeverityId == 0 {
|
||||
return customErrors.NewInvalidInputError("Severity was not selected")
|
||||
}
|
||||
|
||||
if len(members.UserEmailIds) == 0 {
|
||||
return customErrors.NewInvalidInputError("No email id string entered in input field- Please enter a valid email id.")
|
||||
}
|
||||
|
||||
if err := validateEachMemberEmail(members.UserEmailIds); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateEachMemberEmail(emailIds []string) error {
|
||||
emailRegex := regexp.MustCompile(util.EMAIL_REGEX)
|
||||
for _, email := range emailIds {
|
||||
if !emailRegex.MatchString(email) {
|
||||
return customErrors.NewInvalidInputError(fmt.Sprintf("Invalid email: %s", email))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ func (s *Server) teamHandler(houstonGroup *gin.RouterGroup) {
|
||||
houstonGroup.POST("/teams/add", teamHandler.AddTeam)
|
||||
houstonGroup.POST("/teams-v2/add", s.authService.IfAdmin(teamHandlerV2.HandleAddTeam))
|
||||
houstonGroup.POST("/teams-v2", s.authService.IfMemberOrAdmin(teamHandlerV2.HandleUpdateTeam))
|
||||
houstonGroup.POST("/teams/members", s.authService.IfMemberOrAdmin(teamHandlerV2.HandleAddMembers))
|
||||
houstonGroup.POST("/teams", teamHandler.UpdateTeam)
|
||||
houstonGroup.PATCH("/teams/:id/manager/:userId", teamHandler.MakeManager)
|
||||
houstonGroup.PATCH("/teams-v2/:id/manager/:userId", s.authService.IfManagerOrAdmin(teamHandlerV2.HandleMakeManager))
|
||||
|
||||
@@ -121,3 +121,7 @@ const RedColorCode = "#FF0000"
|
||||
const (
|
||||
DUPLICATE_KEY_VALUE_MESSAGE = "duplicate key value"
|
||||
)
|
||||
|
||||
const (
|
||||
EMAIL_REGEX = `^[a-zA-Z]+\.[a-zA-Z]+@navi\.com$`
|
||||
)
|
||||
|
||||
@@ -72,6 +72,20 @@ func (repo *teamUserRepositoryImpl) GetTeamUserByTeamIdAndUserEmailId(teamId uin
|
||||
return &teamUser, nil
|
||||
}
|
||||
|
||||
func (repo *teamUserRepositoryImpl) GetTeamUsersByTeamIdAndUserEmailIds(teamId uint, userEmailIds []string) ([]teamUser.TeamUserEntity, error) {
|
||||
var teamUsers []teamUser.TeamUserEntity
|
||||
if err := repo.gormClient.
|
||||
Preload("User").
|
||||
Joins("JOIN houston_user ON houston_user.id = team_user.user_id").
|
||||
Where("houston_user.email IN (?) AND team_user.team_id = ?", userEmailIds, teamId).
|
||||
Find(&teamUsers).
|
||||
Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return teamUsers, nil
|
||||
}
|
||||
|
||||
func (repo *teamUserRepositoryImpl) GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity(teamId, severityId uint) ([]teamUser.TeamUserEntity, error) {
|
||||
var teamUsers []teamUser.TeamUserEntity
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ type TeamUserRepository interface {
|
||||
GetTeamsByUserId(userId uint) ([]teamUser.TeamUserEntity, error)
|
||||
RemoveTeamUserByTeamIdAndUserId(teamId, userId uint) error
|
||||
GetTeamUserByTeamIdAndUserEmailId(teamId uint, userEmailId string) (*teamUser.TeamUserEntity, error)
|
||||
GetTeamUsersByTeamIdAndUserEmailIds(teamId uint, userEmailIds []string) ([]teamUser.TeamUserEntity, error)
|
||||
GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity(teamId, severityId uint) ([]teamUser.TeamUserEntity, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -423,8 +423,17 @@ func (teamService *TeamServiceV2) UpdateTeam(request teamRequest.UpdateTeamReque
|
||||
return err
|
||||
}
|
||||
|
||||
err = teamService.commitTeamDetails(teamEntity, userEmail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (teamService *TeamServiceV2) commitTeamDetails(teamEntity *team.TeamEntity, userEmail string) error {
|
||||
teamEntity.UpdatedBy = userEmail
|
||||
err = teamService.teamRepository.UpdateTeam(teamEntity)
|
||||
err := teamService.teamRepository.UpdateTeam(teamEntity)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("%s could not update team with id: %d : %+v", logTag, teamEntity.ID, err))
|
||||
return customErrors.NewDataAccessError(fmt.Sprintf("could not update team with id: %d", teamEntity.ID))
|
||||
@@ -433,6 +442,29 @@ func (teamService *TeamServiceV2) UpdateTeam(request teamRequest.UpdateTeamReque
|
||||
return nil
|
||||
}
|
||||
|
||||
func (teamService *TeamServiceV2) AddTeamMember(request teamRequest.UpdateTeamRequest, userEmail string) error {
|
||||
teamEntity, err := teamService.GetTeamById(request.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = teamService.doUsersWithEmailsExistInTeam(request.Id, request.Members.UserEmailIds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := teamService.addMembers(teamEntity, request.Members); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = teamService.commitTeamDetails(teamEntity, userEmail)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (teamService *TeamServiceV2) RemoveTeamMember(teamId, userId uint, requesterEmail string) error {
|
||||
teamEntity, err := teamService.GetTeamById(teamId)
|
||||
if err != nil {
|
||||
@@ -715,6 +747,24 @@ func (teamService *TeamServiceV2) removeUserFromTeamEntity(teamEntity team.TeamE
|
||||
return customErrors.NewNotFoundError("User not found in team")
|
||||
}
|
||||
|
||||
func (teamService *TeamServiceV2) doUsersWithEmailsExistInTeam(teamId uint, emails []string) (bool, error) {
|
||||
teamUsers, err := teamService.teamUserService.GetTeamUsersByTeamIdAndUserEmailIds(teamId, emails)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("%s error in fetching team users for team with id: %d : %+v", logTag, teamId, err))
|
||||
return false, customErrors.NewDataAccessError("Could not fetch team users for team")
|
||||
}
|
||||
|
||||
if teamUsers != nil && len(teamUsers) > 0 {
|
||||
var existingEmails []string
|
||||
for _, teamUser := range teamUsers {
|
||||
existingEmails = append(existingEmails, teamUser.User.Email)
|
||||
}
|
||||
return true, customErrors.NewInvalidInputError("User(s) already exist in the team: " + strings.Join(existingEmails, ", "))
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func findUserInTeam(emailId string, teamUsers []*teamUserModel.TeamUserDTO) *teamUserModel.TeamUserDTO {
|
||||
for _, teamUserValue := range teamUsers {
|
||||
if teamUserValue.User.Email == emailId {
|
||||
|
||||
@@ -13,6 +13,7 @@ type ITeamServiceV2 interface {
|
||||
GetExternalTeam(teamId uint, provider string) (*externalTeam.ExternalTeamDTO, error)
|
||||
AddTeam(request teamRequest.AddTeamRequest, userEmail string) (*service.AddTeamResponse, error)
|
||||
UpdateTeam(request teamRequest.UpdateTeamRequest, userEmail string) error
|
||||
AddTeamMember(request teamRequest.UpdateTeamRequest, userEmail string) error
|
||||
RemoveTeamMember(teamId, userId uint, requesterEmail string) error
|
||||
MakeManager(teamId, memberToMakeManagerId uint, requesterEmail string) error
|
||||
GetTeam(teamId uint) (*service.TeamResponseV2, error)
|
||||
|
||||
@@ -619,6 +619,56 @@ func (suite *TeamServiceV2Suite) Test_UpdateTeam_AddMembers_Success() {
|
||||
suite.Nil(err, "error should be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamServiceV2Suite) Test_AddTeamMember_TeamNotFound() {
|
||||
suite.teamRepository.FindTeamByIdMock.Return(nil, errors.New("error"))
|
||||
|
||||
err := suite.teamService.AddTeamMember(teamRequest.UpdateTeamRequest{Id: 1, Members: &teamRequest.Members{
|
||||
SeverityId: 2,
|
||||
UserEmailIds: []string{"test1@navi.com", "test2@navi.com"},
|
||||
}}, "")
|
||||
suite.NotNil(err, "error should not be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamServiceV2Suite) Test_AddTeamMember_TeamUserError() {
|
||||
suite.teamRepository.FindTeamByIdMock.Return(GetMockTeamEntity(), nil)
|
||||
suite.teamUserService.GetTeamUsersByTeamIdAndUserEmailIdsMock.Return(nil, errors.New("error"))
|
||||
|
||||
err := suite.teamService.AddTeamMember(teamRequest.UpdateTeamRequest{Id: 1, Members: &teamRequest.Members{
|
||||
SeverityId: 2,
|
||||
UserEmailIds: []string{"test1@navi.com", "test2@navi.com"},
|
||||
}}, "")
|
||||
suite.NotNil(err, "error should not be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamServiceV2Suite) Test_AddTeamMember_DuplicateUserCase() {
|
||||
suite.teamRepository.FindTeamByIdMock.Return(GetMockTeamEntity(), nil)
|
||||
suite.teamUserService.GetTeamUsersByTeamIdAndUserEmailIdsMock.Return(GetMockTeamUsers(), nil)
|
||||
|
||||
err := suite.teamService.AddTeamMember(teamRequest.UpdateTeamRequest{Id: 1, Members: &teamRequest.Members{
|
||||
SeverityId: 2,
|
||||
UserEmailIds: []string{"test1@navi.com", "test2@navi.com"},
|
||||
}}, "")
|
||||
suite.NotNil(err, "error should not be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamServiceV2Suite) Test_AddTeamMember_SuccessCase() {
|
||||
suite.teamRepository.FindTeamByIdMock.Return(GetMockTeamEntity(), nil)
|
||||
suite.teamUserService.GetTeamUsersByTeamIdAndUserEmailIdsMock.Return(nil, nil)
|
||||
suite.teamSeverityService.GetSeveritiesMapForATeamMock.Return(GetMockTeamSeverityMap(), nil)
|
||||
suite.teamUserService.GetTeamUsersByTeamIdMock.Return(GetMockTeamUsers(), nil)
|
||||
suite.userService.GetHoustonUserByEmailIdMock.Return(GetMockUserDTO(), nil)
|
||||
suite.teamUserService.AddTeamUserMock.Return(GetMockTeamUserDTO(), nil)
|
||||
suite.teamUserSeverityService.AddTeamUserSeverityMock.Return(nil)
|
||||
suite.teamUserSeverityService.UpdateTeamSeverityForTeamUserMock.Return(nil)
|
||||
suite.teamRepository.UpdateTeamMock.Return(nil)
|
||||
|
||||
err := suite.teamService.AddTeamMember(teamRequest.UpdateTeamRequest{Id: 1, Members: &teamRequest.Members{
|
||||
SeverityId: 2,
|
||||
UserEmailIds: []string{"test1@navi.com", "test2@navi.com"},
|
||||
}}, "")
|
||||
suite.Nil(err, "error should be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamServiceV2Suite) Test_RemoveTeamMember_TeamNotFound() {
|
||||
suite.teamRepository.FindTeamByIdMock.Return(nil, errors.New("error"))
|
||||
|
||||
|
||||
@@ -83,6 +83,16 @@ func (service *TeamUserService) GetTeamUserByTeamIdAndUserEmailId(teamId uint, u
|
||||
return teamUser.ToDTO(), nil
|
||||
}
|
||||
|
||||
func (service *TeamUserService) GetTeamUsersByTeamIdAndUserEmailIds(teamId uint, userEmailIds []string) ([]*teamUserModel.TeamUserDTO, error) {
|
||||
teamUsers, err := service.teamUserRepository.GetTeamUsersByTeamIdAndUserEmailIds(teamId, userEmailIds)
|
||||
if err != nil {
|
||||
logger.Error("error in fetching team users", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dtoConverter.TeamUserEntitiesToDTOs(teamUsers), nil
|
||||
}
|
||||
|
||||
func (service *TeamUserService) GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity(teamId, severityId uint) ([]*teamUserModel.TeamUserDTO, error) {
|
||||
teamUsers, err := service.teamUserRepository.GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity(teamId, severityId)
|
||||
if err != nil {
|
||||
|
||||
@@ -112,6 +112,22 @@ func (suite *TeamUserServiceSuite) Test_GetTeamUserByTeamIdAndUserEmailId_Succes
|
||||
suite.NotNil(teamUser, "teamUser should not be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamUserServiceSuite) Test_GetTeamUsersByTeamIdAndUserEmailIds_RepoFailureCase() {
|
||||
suite.teamUserRepository.GetTeamUsersByTeamIdAndUserEmailIdsMock.Return(nil, errors.New("error"))
|
||||
|
||||
teamUsers, err := suite.teamUserService.GetTeamUsersByTeamIdAndUserEmailIds(1, []string{"email"})
|
||||
suite.Nil(teamUsers, "teamUsers should be nil")
|
||||
suite.EqualError(err, "error", "error should be error")
|
||||
}
|
||||
|
||||
func (suite *TeamUserServiceSuite) Test_GetTeamUsersByTeamIdAndUserEmailIds_SuccessCase() {
|
||||
suite.teamUserRepository.GetTeamUsersByTeamIdAndUserEmailIdsMock.Return(GetMockTeamUserEntities(), nil)
|
||||
|
||||
teamUsers, err := suite.teamUserService.GetTeamUsersByTeamIdAndUserEmailIds(1, []string{"email"})
|
||||
suite.Nil(err, "error should be nil")
|
||||
suite.NotNil(teamUsers, "teamUsers should not be nil")
|
||||
}
|
||||
|
||||
func (suite *TeamUserServiceSuite) Test_GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity_RepoFailureCase() {
|
||||
suite.teamUserRepository.GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverityMock.Return(nil, errors.New("error"))
|
||||
|
||||
|
||||
@@ -9,5 +9,6 @@ type ITeamUserService interface {
|
||||
GetTeamsByUserId(userId uint) ([]*teamUserModel.TeamUserDTO, error)
|
||||
RemoveTeamUser(teamId, userId uint) error
|
||||
GetTeamUserByTeamIdAndUserEmailId(teamId uint, userEmailId string) (*teamUserModel.TeamUserDTO, error)
|
||||
GetTeamUsersByTeamIdAndUserEmailIds(teamId uint, userEmailIds []string) ([]*teamUserModel.TeamUserDTO, error)
|
||||
GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverity(teamId, severityId uint) ([]*teamUserModel.TeamUserDTO, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user