diff --git a/.gitignore b/.gitignore index 7b9e112..3d5de80 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ go.sum .DS_STORE -*.env \ No newline at end of file +*.env + +houston \ No newline at end of file diff --git a/pkg/socketModeClient/socket_mode_client_wrapper.go b/pkg/socketModeClient/socket_mode_client_wrapper.go index 3a10fa0..1b32f7d 100644 --- a/pkg/socketModeClient/socket_mode_client_wrapper.go +++ b/pkg/socketModeClient/socket_mode_client_wrapper.go @@ -79,6 +79,10 @@ func (wrapper *SocketModeClientWrapper) GetConversationInfo( return wrapper.SocketModeClient.GetConversationInfo(input) } +func (wrapper *SocketModeClientWrapper) RenameConversation(channelID string, name string) (*slack.Channel, error) { + return wrapper.SocketModeClient.RenameConversation(channelID, name) +} + func (wrapper *SocketModeClientWrapper) GetConversationHistory( params *slack.GetConversationHistoryParameters, ) (*slack.GetConversationHistoryResponse, error) { diff --git a/pkg/socketModeClient/socket_mode_client_wrapper_interface.go b/pkg/socketModeClient/socket_mode_client_wrapper_interface.go index 67fc57e..9476fdf 100644 --- a/pkg/socketModeClient/socket_mode_client_wrapper_interface.go +++ b/pkg/socketModeClient/socket_mode_client_wrapper_interface.go @@ -16,6 +16,7 @@ type ISocketModeClientWrapper interface { CreateConversation(params slack.CreateConversationParams) (*slack.Channel, error) JoinConversation(channelID string) (*slack.Channel, string, []string, error) GetConversationInfo(input *slack.GetConversationInfoInput) (*slack.Channel, error) + RenameConversation(channelID string, name string) (*slack.Channel, error) GetConversationHistory(params *slack.GetConversationHistoryParameters) (*slack.GetConversationHistoryResponse, error) GetConversationReplies(params *slack.GetConversationRepliesParameters) ([]slack.Message, bool, string, error) SetTopicOfConversation(channelID string, topic string) (*slack.Channel, error) diff --git a/service/incident/impl/incident_service_test.go b/service/incident/impl/incident_service_test.go index 38b5e62..1a11f81 100644 --- a/service/incident/impl/incident_service_test.go +++ b/service/incident/impl/incident_service_test.go @@ -108,6 +108,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_Success() { suite.slackService.InviteUsersToConversationMock.Return(nil) suite.slackService.GetConversationRepliesMock.Return([]slack.Message{}, false, "", nil) + suite.slackService.RenameSlackChannelMock.Return(nil) suite.incidentRepository.UpsertIncidentRoleMock.Return(nil) @@ -204,7 +205,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidStatus() { mockIncident := GetMockIncident() mockUser := GetMockUser() mockTeam := GetMockTeamWithId(suite.previousTeamId) - mockSeverirty := GetMockSeverityWithId(suite.previousSeverityId) + mockSeverity := GetMockSeverityWithId(suite.previousSeverityId) suite.incidentRepository.FindIncidentByIdMock.When(suite.mockIncidentId). Then(mockIncident, nil) @@ -213,7 +214,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidStatus() { suite.teamRepository.FindTeamByIdMock.Return(mockTeam, nil) - suite.severityRepository.FindSeverityByIdMock.Return(mockSeverirty, nil) + suite.severityRepository.FindSeverityByIdMock.Return(mockSeverity, nil) suite.incidentRepository.FindIncidentStatusByIdMock.Return(nil, errors.New("record not found")) @@ -231,7 +232,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidChannel() { mockIncident := GetMockIncident() mockUser := GetMockUser() mockTeam := GetMockTeamWithId(suite.previousTeamId) - mockSeverirty := GetMockSeverityWithId(suite.previousSeverityId) + mockSeverity := GetMockSeverityWithId(suite.previousSeverityId) mockStatus := GetMockStatusWithId(suite.previousStatusId) suite.incidentRepository.FindIncidentByIdMock.When(suite.mockIncidentId). @@ -241,7 +242,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidChannel() { suite.teamRepository.FindTeamByIdMock.Return(mockTeam, nil) - suite.severityRepository.FindSeverityByIdMock.Return(mockSeverirty, nil) + suite.severityRepository.FindSeverityByIdMock.Return(mockSeverity, nil) suite.incidentRepository.FindIncidentStatusByIdMock.Return(mockStatus, nil) @@ -261,7 +262,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_DBError() { mockIncident := GetMockIncident() mockUser := GetMockUser() mockTeam := GetMockTeamWithId(suite.previousTeamId) - mockSeverirty := GetMockSeverityWithId(suite.previousSeverityId) + mockSeverity := GetMockSeverityWithId(suite.previousSeverityId) mockStatus := GetMockStatusWithId(suite.previousStatusId) mockChannels := GetMockChannels() @@ -272,7 +273,7 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_DBError() { suite.teamRepository.FindTeamByIdMock.Return(mockTeam, nil) - suite.severityRepository.FindSeverityByIdMock.Return(mockSeverirty, nil) + suite.severityRepository.FindSeverityByIdMock.Return(mockSeverity, nil) suite.incidentRepository.FindIncidentStatusByIdMock.Return(mockStatus, nil) @@ -313,6 +314,49 @@ func (suite *IncidentServiceSuite) Test_UpdateIncident_SlackError() { suite.incidentRepository.UpdateIncidentMock.Return(nil) + suite.slackService.RenameSlackChannelMock.Return(nil) + + suite.slackService.PostMessageByChannelIDMock.Return("", errors.New("Could not post message to slack channel")) + + suite.slackService.UpdateMessageWithAttachmentsMock.Return(errors.New("Could not update message")) + + suite.slackService.SetTopicOfConversationByChannelIdMock.Return(errors.New("Could not set topic of conversation")) + + _, err := suite.incidentService.UpdateIncident( + service.UpdateIncidentRequest{ + Id: suite.mockIncidentId, + Status: "2", + }, + suite.mockUserEmail, + ) + suite.Error(err, "update incident should fail when slack throws an error") +} + +func (suite *IncidentServiceSuite) Test_UpdateIncident_ChannelRenameError() { + mockIncident := GetMockIncident() + mockUser := GetMockUser() + mockTeam := GetMockTeamWithId(suite.previousTeamId) + mockSeverity := GetMockSeverityWithId(suite.previousSeverityId) + mockStatus := GetMockStatusWithId(suite.previousStatusId) + mockChannels := GetMockChannels() + + suite.incidentRepository.FindIncidentByIdMock.When(suite.mockIncidentId). + Then(mockIncident, nil) + suite.slackService.GetUserByEmailOrIDMock.When(suite.mockUserEmail). + Then(mockUser, nil) + + suite.teamRepository.FindTeamByIdMock.Return(mockTeam, nil) + + suite.severityRepository.FindSeverityByIdMock.Return(mockSeverity, nil) + + suite.incidentRepository.FindIncidentStatusByIdMock.Return(mockStatus, nil) + + suite.incidentChannelService.GetIncidentChannelsMock.Return(mockChannels, nil) + + suite.incidentRepository.UpdateIncidentMock.Return(nil) + + suite.slackService.RenameSlackChannelMock.Return(errors.New("could not rename slack channel")) + suite.slackService.PostMessageByChannelIDMock.Return("", errors.New("Could not post message to slack channel")) suite.slackService.UpdateMessageWithAttachmentsMock.Return(errors.New("Could not update message")) diff --git a/service/incident/impl/incident_service_v2.go b/service/incident/impl/incident_service_v2.go index 0a0698e..1b913e2 100644 --- a/service/incident/impl/incident_service_v2.go +++ b/service/incident/impl/incident_service_v2.go @@ -59,6 +59,7 @@ import ( teamUserServiceImpl "houston/service/teamUser/impl" teamUserSeverityServiceImpl "houston/service/teamUserSeverity/impl" userService "houston/service/user" + utils "houston/service/utils" "math" "net/http" "reflect" @@ -155,8 +156,8 @@ func NewIncidentServiceV2(db *gorm.DB) *IncidentServiceV2 { const logTag = "[create-incident]" const updateLogTag = "[update-incident-v2]" const resolveLogTag = "[resolve-incident]" -const updateSeveritySlackActionCount = 6 -const updateStatusSlackActionCount = 3 +const updateSeveritySlackActionCount = 7 +const updateStatusSlackActionCount = 4 const updateTeamSlackActionCount = 5 /* @@ -1372,7 +1373,13 @@ func (i *IncidentServiceV2) UpdateSeverityId( incidentEntity.SeverityTat = time.Now().AddDate(0, 0, severityEntity.Sla) incidentEntity.UpdatedAt = time.Now() incidentEntity.UpdatedBy = userId - err := i.incidentRepository.UpdateIncidentWithJustification(incidentEntity, request.Justification) + incidentEntity.IncidentName = utils.ConstructIncidentChannelName( + incidentEntity.ID, + incidentEntity.SeverityId, + incidentStatusEntity.Name, + ) + + err = i.incidentRepository.UpdateIncidentWithJustification(incidentEntity, request.Justification) if err != nil { logger.Error(fmt.Sprintf("%s error in committing update to DB", updateLogTag), zap.Error(err)) return err @@ -1479,6 +1486,14 @@ func (i *IncidentServiceV2) UpdateSeverityWorkflow( processUpdateMessage(incidentEntity, teamEntity, severityEntity, incidentStatusEntity, incidentChannels, i) }) + go util.ExecuteConcurrentAction(&waitGroup, func() { + err = i.slackService.RenameSlackChannel(incidentEntity.SlackChannel, incidentEntity.IncidentName) + if err != nil { + logger.Error("error in renaming slack channel", zap.Error(err)) + slackErrors = append(slackErrors, err) + } + }) + go util.ExecuteConcurrentAction(&waitGroup, func() { channelTopic := ChannelTopic{ ProductNames: getProductNamesFromProducts(incidentEntity.Products), @@ -1533,11 +1548,18 @@ func (i *IncidentServiceV2) UpdateStatus( if incidentEntity.Status != uint(statusID) { currentStatus, _ := i.incidentRepository.FindIncidentStatusById(incidentEntity.Status) statusToBeUpdated, _ := i.incidentRepository.FindIncidentStatusById(uint(statusID)) + if statusToBeUpdated == nil { logger.Error(fmt.Sprintf("%s no status found for status id %s", updateLogTag, request.Status), zap.String("Status", request.Status), zap.Error(err)) return fmt.Errorf("Invalid status ID: %s", request.Status) } + incidentEntity.IncidentName = utils.ConstructIncidentChannelName( + incidentEntity.ID, + incidentEntity.SeverityId, + statusToBeUpdated.Name, + ) + switch uint(statusID) { case incident.DuplicateId: { @@ -1639,6 +1661,14 @@ func (i *IncidentServiceV2) UpdateStatusWorkflow( processUpdateMessage(incidentEntity, teamEntity, severityEntity, incidentStatus, incidentChannels, i) }) + go util.ExecuteConcurrentAction(&waitGroup, func() { + err := i.slackService.RenameSlackChannel(incidentEntity.SlackChannel, incidentEntity.IncidentName) + if err != nil { + logger.Error(fmt.Sprintf("%s error in renaming slack channel", updateLogTag), zap.Error(err)) + slackErrors = append(slackErrors, err) + } + }) + go util.ExecuteConcurrentAction(&waitGroup, func() { channelTopic := ChannelTopic{ ProductNames: getProductNamesFromProducts(incidentEntity.Products), diff --git a/service/incident/impl/incident_update_status.go b/service/incident/impl/incident_update_status.go index 145ee43..7290013 100644 --- a/service/incident/impl/incident_update_status.go +++ b/service/incident/impl/incident_update_status.go @@ -17,13 +17,14 @@ import ( tagModel "houston/model/tag" rcaService "houston/service/rca/impl" service "houston/service/request" + utils "houston/service/utils" "strconv" "strings" "sync" "time" ) -const postUpdateResolveStatusActionCount = 4 +const postUpdateResolveStatusActionCount = 5 func (i *IncidentServiceV2) DuplicateUpdateIncidentStatus(duplicateOfID uint, userID string, incidentEntity *incident.IncidentEntity) error { channelID := incidentEntity.SlackChannel @@ -46,6 +47,12 @@ func (i *IncidentServiceV2) DuplicateUpdateIncidentStatus(duplicateOfID uint, us metrics.PublishHoustonFlowFailureMetrics(DUPLICATE_INCIDENT, postErr.Error()) return customErrors.NewSlackError("Failed to post message in slack channel") } + + incidentEntity.IncidentName = utils.ConstructIncidentChannelName( + incidentEntity.ID, + incidentEntity.SeverityId, + incident.Duplicated, + ) err = i.incidentRepository.UpdateIncident(incidentEntity) if err != nil { logger.Error(fmt.Sprintf("%s Failed to update incident with id %d", updateLogTag, incidentId), zap.Error(err)) @@ -95,6 +102,15 @@ func (i *IncidentServiceV2) DuplicateUpdateStatusWorkFlow(currentChannel, origin } }) + waitGroup.Add(1) + go util.ExecuteConcurrentAction(&waitGroup, func() { + err := i.slackService.RenameSlackChannel(incidentEntity.SlackChannel, incidentEntity.IncidentName) + if err != nil { + logger.Error(fmt.Sprintf("%s error in renaming slack channel", updateLogTag), zap.Error(err)) + metrics.PublishHoustonFlowFailureMetrics(DUPLICATE_INCIDENT, err.Error()) + } + }) + waitGroup.Add(1) go util.ExecuteConcurrentAction(&waitGroup, func() { responderTeam, err := i.teamServiceV2.GetTeamById(incidentEntity.TeamId) @@ -611,6 +627,12 @@ func (i *IncidentServiceV2) updateIncidentResolveStatus(incidentEntity *incident endTime := time.Now() incidentEntity.Status = incidentStatusEntity.ID incidentEntity.EndTime = &endTime + incidentEntity.IncidentName = utils.ConstructIncidentChannelName( + incidentEntity.ID, + incidentEntity.SeverityId, + incident.Resolved, + ) + err = i.commitIncidentEntity(incidentEntity, userId) if err != nil { logger.Error(fmt.Sprintf("%s Error while updating incident status to resolved", resolveLogTag), zap.Error(err)) @@ -773,6 +795,14 @@ func (i *IncidentServiceV2) postUpdateResolveStatusFlow(incidentEntity *incident } }) + go util.ExecuteConcurrentAction(&waitGroup, func() { + err := i.slackService.RenameSlackChannel(incidentEntity.SlackChannel, incidentEntity.IncidentName) + if err != nil { + logger.Error(fmt.Sprintf("%s error in renaming slack channel", updateLogTag), zap.Error(err)) + postResolveErrors.AddErrors(err) + } + }) + go i.DeleteConferenceEvent(incidentEntity) go i.processIncidentRCAFlow(incidentEntity) diff --git a/service/incident/impl/incident_update_status_test.go b/service/incident/impl/incident_update_status_test.go index b68b625..ce7492c 100644 --- a/service/incident/impl/incident_update_status_test.go +++ b/service/incident/impl/incident_update_status_test.go @@ -69,6 +69,7 @@ func (suite *IncidentServiceSuite) TestDuplicateUpdateIncidentStatus_Success() { suite.slackService.PostMessageByChannelIDMock.Return("", nil) suite.teamServiceV2.GetTeamByIdMock.Return(GetMockTeamWithId(1), nil) suite.severityService.FindSeverityByIdMock.Return(GetMockSeverityDTOWitId(mockCurrentIncident.SeverityId), nil) + suite.slackService.RenameSlackChannelMock.Return(nil) suite.slackService.SetTopicOfConversationByChannelIdMock.Return(nil) err := suite.incidentService.DuplicateUpdateIncidentStatus(mockOriginalIncident.ID, "userID", mockCurrentIncident) suite.NoError(err) @@ -542,6 +543,7 @@ func (suite *IncidentServiceSuite) TestResolveIncident_PostResolveFlowErrorCase( suite.tagService.GetMandatoryActiveTagsMock.Return(GetMockActiveMandatoryTags(), nil) suite.incidentRepository.GetIncidentTagsByTagIdsMock.Return(mockIncidentTag, nil) suite.slackService.PostMessageOptionMock.Return("", errors.New("Slack Error")) + suite.slackService.RenameSlackChannelMock.Return(nil) suite.teamRepository.FindTeamByIdMock.Return(GetMockTeamWithId(1), nil) suite.severityRepository.FindSeverityByIdMock.Return(GetMockSeverityWithId(3), nil) suite.incidentRepository.FindIncidentStatusByIdMock.Return(GetMockIncidentStatus(), nil) @@ -591,6 +593,7 @@ func (suite *IncidentServiceSuite) TestResolveIncident_HappyFlow() { suite.incidentChannelService.GetIncidentChannelsMock.Return(GetMockChannels(), nil) suite.slackService.UpdateMessageWithAttachmentsMock.Return(nil) suite.calendarService.DeleteEventMock.Return(nil) + suite.slackService.RenameSlackChannelMock.Return(nil) suite.rcaService.SendConversationDataForGeneratingRCAMock.Return(nil) suite.teamServiceV2.GetTeamByIdMock.Return(GetMockTeamWithId(1), nil) suite.severityService.FindSeverityByIdMock.Return(GetMockSeverityDTOWitId(mockIncident.SeverityId), nil) diff --git a/service/orchestration/incident_orchestrator_impl.go b/service/orchestration/incident_orchestrator_impl.go index 07ced8c..d4254a7 100644 --- a/service/orchestration/incident_orchestrator_impl.go +++ b/service/orchestration/incident_orchestrator_impl.go @@ -24,6 +24,7 @@ import ( "houston/service/teamService" "houston/service/teamUser" "houston/service/user" + utils "houston/service/utils" "sort" "sync" "time" @@ -211,7 +212,13 @@ func (i *incidentOrchestratorImpl) CreateIncident( tx.Rollback() return nil, err } - slackChannel, err := i.createSlackChannelTransactionally(incidentEntity.ID, tx, incidentEntity.IncidentName) + slackChannel, err := i.createSlackChannelTransactionally( + incidentEntity.ID, + incidentEntity.IncidentName, + utils.ConstructIncidentChannelName( + incidentEntity.ID, request.SeverityID, string(incident.Investigating), + ), + ) if err != nil { tx.Rollback() return nil, err @@ -432,10 +439,8 @@ func (i *incidentOrchestratorImpl) createIncidentEntityTransactionally( return entity, channelTopic, nil } -func (i *incidentOrchestratorImpl) createSlackChannelTransactionally( - incidentID uint, tx *gorm.DB, incidentName string, -) (*slack2.Channel, error) { - channel, err := i.slackService.CreateSlackChannel(incidentID) +func (i *incidentOrchestratorImpl) createSlackChannelTransactionally(incidentID uint, incidentName string, channelName string) (*slack2.Channel, error) { + channel, err := i.slackService.CreateSlackChannel(incidentID, channelName) if err != nil { logger.Error( fmt.Sprintf("%s [%s] Error while crating slack channel", logTag, incidentName), diff --git a/service/slack/slack_service.go b/service/slack/slack_service.go index 9adc2b3..f262808 100644 --- a/service/slack/slack_service.go +++ b/service/slack/slack_service.go @@ -15,7 +15,6 @@ import ( "houston/model/team" "houston/pkg/socketModeClient" service "houston/service/response" - "strconv" "strings" "sync" ) @@ -274,8 +273,8 @@ func (s *SlackService) IsASlackUser(slackIdOrEmail string) (bool, *slack.User) { return true, user } -func (s *SlackService) CreateSlackChannel(incidentId uint) (*slack.Channel, error) { - channel, err := createChannel(getIncidentChannelName(incidentId), s.SocketModeClientWrapper) +func (s *SlackService) CreateSlackChannel(incidentId uint, channelName string) (*slack.Channel, error) { + channel, err := createChannel(channelName, s.SocketModeClientWrapper) if err != nil { return nil, fmt.Errorf("%s failed to create Slack Channel for incident %d. error: %+v", logTag, incidentId, err) } @@ -314,19 +313,6 @@ func (s *SlackService) InviteUsersToConversation(channelId string, userIds ...st return nil } -func getIncidentChannelName(incidentID uint) string { - var channelPrefix string - env := viper.GetString("env") - if env == "prod" { - channelPrefix = "_houston-" - } else if env == "qa" { - channelPrefix = "_test-issue-" - } else { - channelPrefix = "_dev-issue-" - } - return channelPrefix + strconv.Itoa(int(incidentID)) -} - func createChannel(channelName string, socketModeWrapper socketModeClient.ISocketModeClientWrapper) (*slack.Channel, error) { request := slack.CreateConversationParams{ ChannelName: channelName, @@ -601,6 +587,12 @@ func (s *SlackService) GetConversationInfo(channelId string) (*slack.Channel, er return channel, nil } +func (s *SlackService) RenameSlackChannel(channelId string, channelName string) error { + _, err := s.SocketModeClientWrapper.RenameConversation(channelId, + channelName) + return err +} + func (s *SlackService) PostDivider(channelId string) error { blocks := slack.Blocks{ BlockSet: []slack.Block{ diff --git a/service/slack/slack_service_interface.go b/service/slack/slack_service_interface.go index bf31348..37fcf57 100644 --- a/service/slack/slack_service_interface.go +++ b/service/slack/slack_service_interface.go @@ -25,7 +25,7 @@ type ISlackService interface { GetUserBySlackID(slackUserID string) (*slack.User, error) GetSlackUserIdOrEmail(email string) string IsASlackUser(slackIdOrEmail string) (bool, *slack.User) - CreateSlackChannel(incidentId uint) (*slack.Channel, error) + CreateSlackChannel(incidentId uint, channelName string) (*slack.Channel, error) InviteUsersToConversation(channelId string, userIds ...string) error GetSlackConversationHistoryWithReplies(channelId string) ([]service.ConversationResponse, error) GetChannelConversationHistory(channelId string) ([]slack.Message, error) @@ -46,6 +46,7 @@ type ISlackService interface { UploadFilesToChannel(files []string, channel string) UploadFileByPath(filePath string, channels string) (file *slack.File, err error) GetConversationInfo(channelId string) (*slack.Channel, error) + RenameSlackChannel(channelId string, channelName string) error AckRequest(request socketmode.Request) CheckUserInConversation(userID, channelID string) (bool, error) PostDivider(channelId string) error diff --git a/service/slack/slack_service_test.go b/service/slack/slack_service_test.go index 8613d18..23618cc 100644 --- a/service/slack/slack_service_test.go +++ b/service/slack/slack_service_test.go @@ -314,7 +314,7 @@ func (suite *SlackServiceSuite) Test_GetUsersInfo_UsersMoreThanSplitSize() { func (suite *SlackServiceSuite) Test_CreateSlackChannel() { suite.SocketModeClientWrapper.CreateConversationMock.Return(GetMockChannel(), nil) - channel, err := suite.SlackService.CreateSlackChannel(1) + channel, err := suite.SlackService.CreateSlackChannel(1, "TestSlackChannel") suite.NoError(err, "service must not throw error") suite.NotNil(channel, "channel must not be nil") } @@ -667,6 +667,12 @@ func (suite *SlackServiceSuite) Test_ArchiveConversation_SuccessCase() { } +func (suite *SlackServiceSuite) Test_RenameSlackChannel_SuccessCase() { + suite.SocketModeClientWrapper.RenameConversationMock.Return(GetMockChannel(), nil) + err := suite.SlackService.RenameSlackChannel("testSlackChannelID", "RenamedSlackChannel") + suite.NoError(err, "service must not throw error") +} + func GetMockMessageText() string { return "Hello World!" } diff --git a/service/utils/channel_name_util.go b/service/utils/channel_name_util.go new file mode 100644 index 0000000..c8e3b98 --- /dev/null +++ b/service/utils/channel_name_util.go @@ -0,0 +1,37 @@ +package service + +import ( + "fmt" + "github.com/spf13/viper" + "strconv" +) + +func appendEnvPostfixToChannel(channelName string) string { + var envPostfix string + env := viper.GetString("env") + if env == "prod" { + envPostfix = "houston" + } else if env == "qa" { + envPostfix = "test-issue" + } else { + envPostfix = "dev-issue" + } + return fmt.Sprintf("%s-%s", channelName, envPostfix) +} + +func ConstructIncidentChannelName(incidentId uint, severityId uint, status string) string { + var severityStatusPrefix string + var channelPrefix = "_" + switch status { + case "Investigating", "Identified": + severityStatusPrefix = "i" + case "Monitoring": + severityStatusPrefix = "m" + case "Resolved": + severityStatusPrefix = "r" + case "Duplicated": + severityStatusPrefix = "rd" + } + var channelName = fmt.Sprintf("%s%s%d-%s", channelPrefix, severityStatusPrefix, severityId-1, strconv.Itoa(int(incidentId))) + return appendEnvPostfixToChannel(channelName) +} diff --git a/service/utils/channel_name_util_test.go b/service/utils/channel_name_util_test.go new file mode 100644 index 0000000..1405e29 --- /dev/null +++ b/service/utils/channel_name_util_test.go @@ -0,0 +1,62 @@ +package service + +import ( + "github.com/spf13/viper" + "github.com/stretchr/testify/suite" + "houston/logger" + "testing" +) + +type SlackChannelNameUtilsSuite struct { + suite.Suite +} + +func (suite *SlackChannelNameUtilsSuite) Test_Investigating_Channel_Name_SuccessCase() { + viper.Set("env", "prod") + channelName := ConstructIncidentChannelName(15300, 1, "Investigating") + suite.Equal("_i0-15300-houston", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Identified_Channel_Name_SuccessCase() { + viper.Set("env", "prod") + channelName := ConstructIncidentChannelName(15399, 1, "Identified") + suite.Equal("_i0-15399-houston", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Monitoring_Channel_Name_SuccessCase() { + viper.Set("env", "dev") + channelName := ConstructIncidentChannelName(15229, 1, "Monitoring") + suite.Equal("_m0-15229-dev-issue", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Resolved_Channel_Name_SuccessCase() { + viper.Set("env", "qa") + channelName := ConstructIncidentChannelName(15398, 1, "Resolved") + suite.Equal("_r0-15398-test-issue", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Duplicated_Channel_Name_SuccessCase() { + viper.Set("env", "prod") + channelName := ConstructIncidentChannelName(15400, 1, "Duplicated") + suite.Equal("_rd0-15400-houston", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Duplicated_Channel_Name_SuccessCase_Sev1() { + viper.Set("env", "prod") + channelName := ConstructIncidentChannelName(15400, 2, "Duplicated") + suite.Equal("_rd1-15400-houston", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) Test_Monitoring_Channel_Name_SuccessCase_Sev3() { + viper.Set("env", "dev") + channelName := ConstructIncidentChannelName(15229, 4, "Monitoring") + suite.Equal("_m3-15229-dev-issue", channelName) +} + +func (suite *SlackChannelNameUtilsSuite) SetupTest() { + logger.InitLogger() +} + +func TestSlackUtilsSuite(t *testing.T) { + suite.Run(t, new(SlackChannelNameUtilsSuite)) +}