Files
houston-be/service/incident/impl/incident_service_test.go
Vijay Joshi 293220ded8 INFRA-3565 : Remove retrospective and service owner in incident roles (#434)
* INFRA-3565 : Remove retrospective and service owner in incident roles

* INFRA-3565 : Build failure fix
2024-07-11 14:53:39 +05:30

613 lines
21 KiB
Go

package impl
import (
"errors"
"github.com/google/uuid"
"github.com/lib/pq"
"github.com/slack-go/slack"
"github.com/spf13/viper"
"github.com/stretchr/testify/suite"
"gorm.io/gorm"
"houston/logger"
"houston/mocks"
"houston/model/incident"
"houston/model/incident_channel"
"houston/model/product"
"houston/model/severity"
"houston/model/team"
teamUserModel "houston/model/teamUser"
"houston/model/user"
service "houston/service/request"
incidentRequest "houston/service/request/incident"
"testing"
"time"
)
type IncidentServiceSuite struct {
suite.Suite
slackService mocks.ISlackServiceMock
incidentService *IncidentServiceV2
incidentRepository mocks.IIncidentRepositoryMock
teamRepository mocks.ITeamRepositoryMock
userRepository mocks.IUserRepositoryMock
teamUserService mocks.ITeamUserServiceMock
severityRepository mocks.ISeverityRepositoryMock
krakatoaService mocks.IKrakatoaServiceMock
incidentChannelService mocks.IIncidentChannelServiceMock
incidentJiraService mocks.IncidentJiraServiceMock
tagService mocks.ITagServiceMock
calendarService mocks.ICalendarServiceMock
rcaService mocks.IRcaServiceMock
severityService mocks.ISeverityServiceMock
teamServiceV2 mocks.ITeamServiceV2Mock
mockDirectory string
mockPngName string
mockCsvName string
mockIncidentId uint
mockIncidentSlackChannelID string
mockUserEmail string
previousSeverityId uint
updatedSeverityId uint
previousStatusId uint
updatedStatusId uint
previousTeamId uint
updatedTeamId uint
mockValidJiraLink string
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_Success() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
mockHoustonUser := GetMockHoustonUser()
mockUpdatedTeam := GetMockTeamWithId(suite.updatedTeamId)
mockSeverity := GetMockSeverityWithId(suite.previousSeverityId)
mockUpdatedSeverity := GetMockSeverityWithId(suite.updatedSeverityId)
mockStatus := GetMockStatusWithId(suite.previousStatusId)
mockUpdatedStatus := GetMockStatusWithId(suite.updatedStatusId)
mockChannels := GetMockChannels()
mockMetaData := getMockMetaData()
krakatoaIncidents := []incident.IncidentEntity{*GetMockIncident(), *GetMockIncident()}
suite.incidentRepository.FindIncidentByIdMock.When(suite.mockIncidentId).
Then(mockIncident, nil)
suite.incidentRepository.FindIncidentByChannelIdMock.When(suite.mockIncidentSlackChannelID).
Then(mockIncident, nil)
suite.slackService.GetUserByEmailOrIDMock.When(suite.mockUserEmail).
Then(mockUser, nil)
suite.teamRepository.FindTeamByIdMock.When(suite.previousTeamId).
Then(mockTeam, nil)
suite.userRepository.FindHoustonUserBySlackUserIdMock.When(mockUser.ID).
Then(mockHoustonUser, nil)
suite.teamRepository.FindTeamByIdMock.When(suite.updatedTeamId).
Then(mockUpdatedTeam, nil)
suite.severityRepository.FindSeverityByIdMock.When(suite.previousSeverityId).
Then(mockSeverity, nil)
suite.severityRepository.FindSeverityByIdMock.When(suite.updatedSeverityId).
Then(mockUpdatedSeverity, nil)
suite.incidentRepository.FindIncidentStatusByIdMock.When(suite.previousStatusId).
Then(mockStatus, nil)
suite.incidentRepository.FindIncidentStatusByIdMock.When(suite.updatedStatusId).
Then(mockUpdatedStatus, nil)
suite.incidentChannelService.GetIncidentChannelsMock.When(mockIncident.ID).
Then(mockChannels, nil)
suite.incidentRepository.UpdateIncidentMock.When(mockIncident).
Then(nil)
suite.incidentRepository.UpdateIncidentWithJustificationMock.When(mockIncident, "").Then(nil)
suite.slackService.PostMessageByChannelIDMock.Return("", nil)
suite.slackService.UpdateMessageWithAttachmentsMock.Return(nil)
suite.slackService.InviteUsersToConversationMock.Return(nil)
suite.slackService.GetConversationRepliesMock.Return([]slack.Message{}, false, "", nil)
suite.slackService.RenameSlackChannelMock.Return(nil)
suite.incidentRepository.UpsertIncidentRoleMock.Return(nil)
suite.slackService.SetChannelTopicByChannelIdMock.Return(nil)
suite.slackService.PostMessageWithAttachmentsMock.Return("", nil)
suite.slackService.PostMessageOptionMock.Return("", nil)
suite.incidentRepository.GetOpenIncidentsByCreatorIdForGivenTeamMock.Return(&krakatoaIncidents, nil)
suite.krakatoaService.ExecuteKrakatoaWorkflowMock.Return(nil)
tu := teamUserModel.TeamUserDTO{User: user.UserDTO{ID: 1, Name: "test", Email: "", SlackUserId: "1", Active: true}}
suite.teamUserService.GetTeamUsersForGivenSeverityMock.Return([]teamUserModel.TeamUserDTO{tu}, nil)
suite.teamUserService.GetTeamUsersWithMinimumSeverityIdLessThanOrEqualToGivenSeverityMock.Return([]teamUserModel.TeamUserDTO{tu}, nil)
suite.teamServiceV2.GetTeamByIdMock.Return(GetMockTeamWithId(1), nil)
suite.severityService.FindSeverityByIdMock.Return(GetMockSeverityDTOWitId(mockIncident.SeverityId), nil)
suite.slackService.SetTopicOfConversationByChannelIdMock.Return(nil)
suite.incidentRepository.UpdateIncidentWithAssociationsMock.Return(nil)
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
SeverityId: "3",
TeamId: "2",
MetaData: mockMetaData,
ProductIDs: []uint{1, 2},
},
suite.mockUserEmail,
)
suite.Equal(err, nil)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidIncident() {
suite.incidentRepository.FindIncidentByIdMock.Return(nil, errors.New("record not found"))
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidTeam() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
suite.incidentRepository.FindIncidentByIdMock.When(suite.mockIncidentId).
Then(mockIncident, nil)
suite.slackService.GetUserByEmailOrIDMock.When(suite.mockUserEmail).
Then(mockUser, nil)
suite.teamRepository.FindTeamByIdMock.Return(nil, errors.New("record not found"))
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
TeamId: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidSeverity() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
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(nil, errors.New("record not found"))
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
SeverityId: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidStatus() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
mockSeverity := GetMockSeverityWithId(suite.previousSeverityId)
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(nil, errors.New("record not found"))
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_InvalidChannel() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
mockSeverity := GetMockSeverityWithId(suite.previousSeverityId)
mockStatus := GetMockStatusWithId(suite.previousStatusId)
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(nil, errors.New("record not found"))
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_DBError() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
mockSeverity := GetMockSeverityWithId(suite.previousSeverityId)
mockStatus := GetMockStatusWithId(suite.previousStatusId)
mockChannels := GetMockChannels()
mockHoustonUser := GetMockHoustonUser()
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(errors.New("Update failed: SQL State 123"))
suite.userRepository.FindHoustonUserBySlackUserIdMock.When(mockUser.ID).
Then(mockHoustonUser, nil)
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_UpdateIncident_SlackError() {
mockIncident := GetMockIncident()
mockUser := GetMockUser()
mockTeam := GetMockTeamWithId(suite.previousTeamId)
mockSeverity := GetMockSeverityWithId(suite.previousSeverityId)
mockStatus := GetMockStatusWithId(suite.previousStatusId)
mockChannels := GetMockChannels()
mockHoustonUser := GetMockHoustonUser()
suite.userRepository.FindHoustonUserBySlackUserIdMock.When(mockUser.ID).
Then(mockHoustonUser, nil)
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(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"))
suite.slackService.SetTopicOfConversationByChannelIdMock.Return(errors.New("Could not set topic of conversation"))
suite.userRepository.FindHoustonUserBySlackUserIdMock.Return(GetMockHoustonUser(), nil)
_, err := suite.incidentService.UpdateIncident(
service.UpdateIncidentRequest{
Id: suite.mockIncidentId,
Status: "2",
},
suite.mockUserEmail,
)
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_GetAllIncidents_FailureCase() {
suite.incidentRepository.GetAllIncidentsMock.Return(nil, 0, errors.New("error while fetching incidents"))
incidents, count, err := suite.incidentService.GetAllIncidents(nil, nil, nil)
suite.Nil(incidents, "Incidents should be nil")
suite.Equal(0, count, "Count should be 0")
suite.Error(err, "Error should not be nil")
}
func (suite *IncidentServiceSuite) Test_GetAllIncidents_SuccessCase() {
mockIncidents := &[]incident.IncidentEntity{*GetMockIncident()}
suite.incidentRepository.GetAllIncidentsMock.Return(mockIncidents, 1, nil)
incidents, count, err := suite.incidentService.GetAllIncidents(nil, nil, nil)
suite.NotNil(incidents, "Incidents should not be nil")
suite.Equal(1, count, "Count should be 1")
suite.Nil(err, "Error should be nil")
}
func (suite *IncidentServiceSuite) Test_GetIncidentRolesByIncidentIdsAndRole_DBError() {
incidentIds := []uint{1, 2}
suite.incidentRepository.GetIncidentRolesByIncidentIdsAndRoleMock.Return(nil, errors.New("DB error"))
_, err := suite.incidentService.GetIncidentRolesByIncidentIdsAndRole(incidentIds, string(incident.Responder))
suite.Error(err)
}
func (suite *IncidentServiceSuite) Test_GetIncidentRolesByIncidentIdsAndRole_SuccessCase() {
mockIncidentRoles := []incident.IncidentRoleEntity{{IncidentId: 1, Role: "Responder"}, {IncidentId: 2, Role: "Responder"}}
incidentIds := []uint{1, 2}
suite.incidentRepository.GetIncidentRolesByIncidentIdsAndRoleMock.Return(mockIncidentRoles, nil)
incidentRoles, err := suite.incidentService.GetIncidentRolesByIncidentIdsAndRole(incidentIds, string(incident.Responder))
suite.NotNil(incidentRoles, "Incident roles should not be nil")
suite.Equal(2, len(incidentRoles), "Incident roles should have 2 elements")
suite.Nil(err, "Error should be nil")
}
func GetMockIncident() *incident.IncidentEntity {
return &incident.IncidentEntity{
Model: gorm.Model{ID: 1},
Title: "Mock Title",
Description: "Mock Description",
Status: 1,
SeverityId: 4,
IncidentName: "Mock Name",
SlackChannel: "mock_channel",
DetectionTime: nil,
StartTime: time.Time{},
EndTime: nil,
TeamId: 1,
JiraLinks: nil,
ConfluenceId: nil,
SeverityTat: time.Time{},
RemindMeAt: nil,
EnableReminder: false,
CreatedBy: "123456",
UpdatedBy: "123456",
MetaData: nil,
RCA: "",
ConferenceId: "",
ConferenceLink: "",
Products: make([]product.ProductEntity, 1),
}
}
func GetMockUser() *slack.User {
return &slack.User{
ID: "1",
Name: "Mock User",
}
}
func GetMockHoustonUser() *user.UserEntity {
return &user.UserEntity{
Model: gorm.Model{
ID: 1,
},
Name: "Mock User",
}
}
func GetMockTeamWithId(teamId uint) *team.TeamEntity {
return &team.TeamEntity{
Model: gorm.Model{
ID: teamId,
},
Name: "Mock Team",
SlackUserIds: pq.StringArray{"001", "002"},
ConfluenceLink: "",
OncallHandle: "mockId",
PseOncallHandle: "mockId",
Active: true,
WebhookSlackChannel: "mockChannel",
ManagerHandle: "",
CreatedBy: "",
UpdatedBy: "",
}
}
func GetMockSeverityWithId(severityId uint) *severity.SeverityEntity {
return &severity.SeverityEntity{
Model: gorm.Model{
ID: severityId,
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
DeletedAt: gorm.DeletedAt{},
},
SlackUserIds: pq.StringArray{"1", "2"},
}
}
func GetMockSeverityDTOWitId(severityId uint) *severity.SeverityDTO {
return &severity.SeverityDTO{
ID: severityId,
Name: "Mock Severity",
Description: "Mock Description",
SlackUserIds: pq.StringArray{"1", "2"},
}
}
func GetMockStatusWithId(statusId uint) *incident.IncidentStatusEntity {
return &incident.IncidentStatusEntity{
Model: gorm.Model{
ID: statusId,
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
DeletedAt: gorm.DeletedAt{},
},
IsTerminalStatus: false,
}
}
func GetMockChannels() []incident_channel.IncidentChannelEntity {
return []incident_channel.IncidentChannelEntity{
{
Model: gorm.Model{
ID: 1,
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
DeletedAt: gorm.DeletedAt{},
},
IncidentId: 1,
SlackChannel: "abc",
MessageTimeStamp: "",
IsArchived: false,
},
{
Model: gorm.Model{
ID: 2,
CreatedAt: time.Time{},
UpdatedAt: time.Time{},
DeletedAt: gorm.DeletedAt{},
},
IncidentId: 1,
SlackChannel: "def",
MessageTimeStamp: "",
IsArchived: false,
},
}
}
func getMockMetaData() *incidentRequest.CreateIncidentMetadata {
return &incidentRequest.CreateIncidentMetadata{
CustomerId: uuid.UUID{},
CustomerName: "Mock Name",
PhoneNumber: "9999999999",
CrmTicketCreationTime: nil,
TicketId: "123",
TicketGroup: "Mock Group",
AgentName: "Mock Agent",
}
}
func (suite *IncidentServiceSuite) SetupTest() {
logger.InitLogger()
viper.Set("MONITORING_SERVICE_TIMEOUT_IN_SECONDS", 3)
viper.Set("navi.jira.base.url", "mock_base_url")
suite.slackService = *mocks.NewISlackServiceMock(suite.T())
suite.incidentRepository = *mocks.NewIIncidentRepositoryMock(suite.T())
suite.krakatoaService = *mocks.NewIKrakatoaServiceMock(suite.T())
suite.severityRepository = *mocks.NewISeverityRepositoryMock(suite.T())
suite.teamRepository = *mocks.NewITeamRepositoryMock(suite.T())
suite.userRepository = *mocks.NewIUserRepositoryMock(suite.T())
suite.incidentChannelService = *mocks.NewIIncidentChannelServiceMock(suite.T())
suite.tagService = *mocks.NewITagServiceMock(suite.T())
suite.incidentJiraService = *mocks.NewIncidentJiraServiceMock(suite.T())
suite.calendarService = *mocks.NewICalendarServiceMock(suite.T())
suite.rcaService = *mocks.NewIRcaServiceMock(suite.T())
suite.mockIncidentId = 1
suite.mockIncidentSlackChannelID = "mock_channel"
suite.mockUserEmail = "testemail@testemail.com"
suite.mockValidJiraLink = "mock_base_url/browse/TP-123"
suite.previousStatusId = 1
suite.updatedStatusId = 2
suite.previousSeverityId = 4
suite.updatedSeverityId = 3
suite.previousTeamId = 1
suite.updatedTeamId = 2
suite.teamUserService = *mocks.NewITeamUserServiceMock(suite.T())
suite.severityService = *mocks.NewISeverityServiceMock(suite.T())
suite.teamServiceV2 = *mocks.NewITeamServiceV2Mock(suite.T())
suite.incidentService = &IncidentServiceV2{
db: nil,
slackService: &suite.slackService,
teamRepository: &suite.teamRepository,
severityRepository: &suite.severityRepository,
incidentRepository: &suite.incidentRepository,
userRepository: &suite.userRepository,
incidentChannelService: &suite.incidentChannelService,
krakatoaService: &suite.krakatoaService,
tagService: &suite.tagService,
incidentJiraService: &suite.incidentJiraService,
calendarService: &suite.calendarService,
rcaService: &suite.rcaService,
teamUserService: &suite.teamUserService,
severityService: &suite.severityService,
teamServiceV2: &suite.teamServiceV2,
}
suite.mockDirectory = "test_file"
suite.mockPngName = "/dummy.png"
suite.mockCsvName = "/dummy.csv"
}
func TestIncidentService(t *testing.T) {
suite.Run(t, new(IncidentServiceSuite))
}