Skip to content

Commit

Permalink
adding more unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Chris Collins <[email protected]>
  • Loading branch information
clcollins committed Aug 23, 2024
1 parent 93bfee5 commit aee32a2
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 78 deletions.
21 changes: 21 additions & 0 deletions pkg/pd/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,27 @@ func (m *MockPagerDutyClient) GetIncidentWithContext(ctx context.Context, id str
}, nil
}

func (m *MockPagerDutyClient) ListIncidentsWithContext(ctx context.Context, opts pagerduty.ListIncidentsOptions) (*pagerduty.ListIncidentsResponse, error) {
// Provided so we can mock error responses for unit tests
if opts.UserIDs != nil && opts.UserIDs[0] == "err" {
return &pagerduty.ListIncidentsResponse{}, ErrMockError
}
return &pagerduty.ListIncidentsResponse{
Incidents: []pagerduty.Incident{
{
APIObject: pagerduty.APIObject{
ID: "QABCDEFG1234567",
},
},
{
APIObject: pagerduty.APIObject{
ID: "QABCDEFG7654321",
},
},
},
}, nil
}

func (m *MockPagerDutyClient) ListIncidentAlertsWithContext(ctx context.Context, id string, opts pagerduty.ListIncidentAlertsOptions) (*pagerduty.ListAlertsResponse, error) {
if id == "err" {
return &pagerduty.ListAlertsResponse{}, ErrMockError
Expand Down
2 changes: 1 addition & 1 deletion pkg/pd/pd.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ func GetIncidents(client PagerDutyClient, opts pagerduty.ListIncidentsOptions) (
for {
response, err := client.ListIncidentsWithContext(ctx, opts)
if err != nil {
return i, fmt.Errorf("pd.GetIncidents(): failed to get incidents : %v", err)
return i, fmt.Errorf("pd.GetIncidents(): failed to get incidents: %v", err)
}

i = append(i, response.Incidents...)
Expand Down
122 changes: 73 additions & 49 deletions pkg/tui/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func getIncidentAlerts(p *pd.Config, id string) tea.Cmd {
}
}

// got IncidentNotesMsg is a message that contains the fetched incident notes
// gotIncidentNotesMsg is a message that contains the fetched incident notes
type gotIncidentNotesMsg struct {
notes []pagerduty.IncidentNote
err error
Expand All @@ -90,6 +90,78 @@ func getIncidentNotes(p *pd.Config, id string) tea.Cmd {
}
}

// updateIncidentListMsg is a message that triggers the fetching of the incident list
type updateIncidentListMsg string

// updatedIncidentListMsg is a message that contains the fetched incident list
type updatedIncidentListMsg struct {
incidents []pagerduty.Incident
err error
}

// updateIncidentList returns a command that fetches the incident list from the PagerDuty API
func updateIncidentList(p *pd.Config) tea.Cmd {
return func() tea.Msg {
opts := newListIncidentOptsFromConfig(p)
i, err := pd.GetIncidents(p.Client, opts)
return updatedIncidentListMsg{i, err}
}
}

// newListIncidentOptsFromConfig returns a ListIncidentsOptions struct
// with the UserIDs and TeamIDs fields populated from the given Config
func newListIncidentOptsFromConfig(p *pd.Config) pagerduty.ListIncidentsOptions {
var opts = pagerduty.ListIncidentsOptions{}

// If the Config is nil, return the default options
if p == nil {
return opts
}

// Convert the list of *pagerduty.User to a slice of user IDs
if p.IgnoredUsers == nil {
p.IgnoredUsers = []*pagerduty.User{}
}

ignoredUserIDs := func(u []*pagerduty.User) []string {
var l []string
for _, i := range u {
l = append(l, i.ID)
}
return l
}(p.IgnoredUsers)

// If the UserID from p.TeamMemberIDs is not in the ignoredUserIDs slice, add it to the opts.UserIDs slice
if p.TeamsMemberIDs == nil {
p.TeamsMemberIDs = []string{}
}

opts.UserIDs = func(a []string, i []string) []string {
var l []string
for _, u := range a {
if !slices.Contains(i, u) {
l = append(l, u)
}
}
return l
}(p.TeamsMemberIDs, ignoredUserIDs)

// Convert the list of *pagerduty.Team to a slice of team IDs
if p.Teams == nil {
p.Teams = []*pagerduty.Team{}
}

opts.TeamIDs = func(t []*pagerduty.Team) []string {
var l []string
for _, x := range t {
l = append(l, x.ID)
}
return l
}(p.Teams)

return opts
}

// HOUSEKEEPING: The above are commands that have complete unit tests and incoming
// and outgoing tea.Msg types, ordered alphabetically. Below are commands that need to
// be refactored to have unit tests and incoming and outgoing tea.Msg types, ordered
Expand All @@ -108,45 +180,6 @@ type PollIncidentsMsg struct {
PollInterval time.Duration
}

type updateIncidentListMsg string
type updatedIncidentListMsg struct {
incidents []pagerduty.Incident
err error
}

func updateIncidentList(p *pd.Config) tea.Cmd {
return tea.Sequence(
func() tea.Msg { return clearSelectedIncidentsMsg("updateIncidentList") },
func() tea.Msg {
opts := pd.NewListIncidentOptsFromDefaults()
opts.TeamIDs = getTeamsAsStrings(p)

// Convert the list of *pagerduty.User to a slice of user IDs
ignoredUserIDs := func(u []*pagerduty.User) []string {
var l []string
for _, i := range u {
l = append(l, i.ID)
}
return l
}(p.IgnoredUsers)

// If the UserID from p.TeamMemberIDs is not in the ignoredUserIDs slice, add it to the opts.UserIDs slice
opts.UserIDs = func(a []string, i []string) []string {
var l []string
for _, u := range a {
if !slices.Contains(i, u) {
l = append(l, u)
}
}
return l
}(p.TeamsMemberIDs, ignoredUserIDs)

// Retrieve incidents assigned to the TeamIDs and filtered UserIDs
i, err := pd.GetIncidents(p.Client, opts)
return updatedIncidentListMsg{i, err}
})
}

type renderIncidentMsg string

type renderedIncidentMsg struct {
Expand Down Expand Up @@ -561,15 +594,6 @@ func removeCommentsFromBytes(b []byte, prefixes ...string) string {
return content.String()
}

// getTeamsAsStrings returns a slice of team IDs as strings from the []*pagerduty.Teams in a *pd.Config
func getTeamsAsStrings(p *pd.Config) []string {
var teams []string
for _, t := range p.Teams {
teams = append(teams, t.ID)
}
return teams
}

func getDetailFieldFromAlert(f string, a pagerduty.IncidentAlert) string {
if a.Body["details"] != nil {

Expand Down
136 changes: 111 additions & 25 deletions pkg/tui/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ func TestGetIncident(t *testing.T) {
id: id,
expected: gotIncidentMsg{
incident: &pagerduty.Incident{
APIObject: pagerduty.APIObject{
ID: id,
},
APIObject: pagerduty.APIObject{ID: id},
},
err: nil,
},
Expand All @@ -56,8 +54,8 @@ func TestGetIncident(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd := getIncident(test.config, test.id)
msg := cmd()
assert.Equal(t, msg, test.expected)
actual := cmd()
assert.Equal(t, test.expected, actual)
})
}
}
Expand All @@ -84,16 +82,8 @@ func TestGetIncidentAlerts(t *testing.T) {
id: rand.ID("Q"),
expected: gotIncidentAlertsMsg{
alerts: []pagerduty.IncidentAlert{
{
APIObject: pagerduty.APIObject{
ID: "QABCDEFG1234567",
},
},
{
APIObject: pagerduty.APIObject{
ID: "QABCDEFG7654321",
},
},
{APIObject: pagerduty.APIObject{ID: "QABCDEFG1234567"}},
{APIObject: pagerduty.APIObject{ID: "QABCDEFG7654321"}},
},
err: nil,
},
Expand All @@ -112,8 +102,8 @@ func TestGetIncidentAlerts(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd := getIncidentAlerts(test.config, test.id)
msg := cmd()
assert.Equal(t, msg, test.expected)
actual := cmd()
assert.Equal(t, test.expected, actual)
})
}
}
Expand All @@ -140,12 +130,8 @@ func TestGetIncidentNotes(t *testing.T) {
id: rand.ID("Q"),
expected: gotIncidentNotesMsg{
notes: []pagerduty.IncidentNote{
{
ID: "QABCDEFG1234567",
},
{
ID: "QABCDEFG7654321",
},
{ID: "QABCDEFG1234567"},
{ID: "QABCDEFG7654321"},
},
err: nil,
},
Expand All @@ -164,8 +150,108 @@ func TestGetIncidentNotes(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd := getIncidentNotes(test.config, test.id)
msg := cmd()
assert.Equal(t, msg, test.expected)
actual := cmd()
assert.Equal(t, test.expected, actual)
})
}
}

func TestUpdateIncidentList(t *testing.T) {
tests := []struct {
name string
config *pd.Config
expected tea.Msg
}{
{
name: "return updatedIncidentListMsg with non-nil error if error occurs",
config: &pd.Config{
Client: &pd.MockPagerDutyClient{},
TeamsMemberIDs: []string{"err"}, // "err" signals the mock client to produce a mock error
},
expected: updatedIncidentListMsg{
incidents: []pagerduty.Incident(nil),
err: fmt.Errorf("pd.GetIncidents(): failed to get incidents: %v", pd.ErrMockError),
},
},
{
name: "return updatedIncidentListMsg with an incident list if no error occurs",
config: &pd.Config{Client: &pd.MockPagerDutyClient{}},
expected: updatedIncidentListMsg{
// These incidents are defined in the Mock for ListIncidentsWithContext
incidents: []pagerduty.Incident{
{APIObject: pagerduty.APIObject{ID: "QABCDEFG1234567"}},
{APIObject: pagerduty.APIObject{ID: "QABCDEFG7654321"}},
},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd := updateIncidentList(test.config)
actual := cmd()
assert.Equal(t, test.expected, actual)
})
}
}

func TestNewListIncidentOptsFromConfig(t *testing.T) {
tests := []struct {
name string
config *pd.Config
expected pagerduty.ListIncidentsOptions
}{
{
name: "return default ListIncidentsOptions if config is nil",
config: nil,
expected: pagerduty.ListIncidentsOptions{},
},
{
name: "p.TeamsMembers is properly converted to ListIncidentsOptions.UserIDs",
config: &pd.Config{
TeamsMemberIDs: []string{
"PABC123",
"PDEF456",
},
},
expected: pagerduty.ListIncidentsOptions{
UserIDs: []string{"PABC123", "PDEF456"},
},
},
{
name: "p.IgnopredUsers are properly excluded from ListIncidentsOptions.UserIDs, and extra Ignored users have no effect",
config: &pd.Config{
TeamsMemberIDs: []string{
"PABC123",
"PDEF456",
},
IgnoredUsers: []*pagerduty.User{
{APIObject: pagerduty.APIObject{ID: "PDEF456"}},
{APIObject: pagerduty.APIObject{ID: "PXYZ789"}},
},
},
expected: pagerduty.ListIncidentsOptions{
UserIDs: []string{"PABC123"},
},
},
{
name: "p.Teams is properly converted to ListIncidentsOptions.TeamIDs",
config: &pd.Config{
Teams: []*pagerduty.Team{
{APIObject: pagerduty.APIObject{ID: "PABC123"}},
{APIObject: pagerduty.APIObject{ID: "PDEF456"}},
},
},
expected: pagerduty.ListIncidentsOptions{
TeamIDs: []string{"PABC123", "PDEF456"},
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
actual := newListIncidentOptsFromConfig(test.config)
assert.Equal(t, test.expected, actual)
})
}
}
Loading

0 comments on commit aee32a2

Please sign in to comment.