Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 11 additions & 29 deletions slack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ func (c *Client) doUpdateMessage(ctx context.Context, ref *MessageRef, title str
return &MessageRef{ChannelID: channelID, Timestamp: timestamp}, nil
}

// buildAttachmentFieldsFromDetails constructs Slack attachment fields from the given error and details.
func buildAttachmentFieldsFromDetails(err error, details []Detail) []slack.AttachmentField {
attachmentFields := make([]slack.AttachmentField, 0, len(details)+1)
// buildAttachmentFields constructs Slack attachment fields from the given error, details, and links.
func buildAttachmentFields(err error, details []Detail, links []Link) []slack.AttachmentField {
attachmentFields := make([]slack.AttachmentField, 0, len(details)+len(links)+1)

if err != nil {
attachmentFields = append(attachmentFields, slack.AttachmentField{
Expand All @@ -122,41 +122,23 @@ func buildAttachmentFieldsFromDetails(err error, details []Detail) []slack.Attac
})
}

return attachmentFields
}

// buildAttachmentFieldsFromLinks constructs Slack attachment fields for the given links.
func buildAttachmentFieldsFromLinks(links []Link) []slack.AttachmentField {
attachmentLinks := make([]slack.AttachmentField, 0, len(links))

for _, link := range links {
attachmentLinks = append(attachmentLinks, slack.AttachmentField{
attachmentFields = append(attachmentFields, slack.AttachmentField{
Value: fmt.Sprintf("<%s|%s>", link.URL, link.Title),
})
}

return attachmentLinks
return attachmentFields
}

// buildAttachments constructs Slack attachments for a message, including the details, links, and error if present.
// buildAttachments constructs a Slack attachment for a message, including the error, details, and links if present.
func buildAttachments(err error, details []Detail, links []Link, color Colour) []slack.Attachment {
attachments := make([]slack.Attachment, 0, 2)

// Message details
attachments = append(attachments, slack.Attachment{
Fields: buildAttachmentFieldsFromDetails(err, details),
Color: color.String(),
})

// Message links
if len(links) > 0 {
attachments = append(attachments, slack.Attachment{
Title: "Resources",
Fields: buildAttachmentFieldsFromLinks(links),
})
return []slack.Attachment{
{
Fields: buildAttachmentFields(err, details, links),
Color: color.String(),
},
}

return attachments
}

// GetTimeout returns the timeout duration for Slack API requests.
Expand Down
108 changes: 66 additions & 42 deletions slack/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,13 @@ func TestClient_DoUpdateMessage(t *testing.T) {
})
}

func TestBuildAttachmentFieldsFromDetails(t *testing.T) {
Convey("Given an error and details", t, func() {
Convey("When buildAttachmentFieldsFromDetails is called", func() {
attachmentFields := buildAttachmentFieldsFromDetails(errExampleError, testDetails)
func TestBuildAttachmentFields(t *testing.T) {
Convey("Given an error, details, and links", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(errExampleError, testDetails, testLinks)

Convey("Then the returned attachmentFields contain the error and details", func() {
So(len(attachmentFields), ShouldEqual, 4)
Convey("Then the returned attachmentFields contain error, details, and links in order", func() {
So(len(attachmentFields), ShouldEqual, 7)
So(attachmentFields[0].Title, ShouldEqual, "Error")
So(attachmentFields[0].Value, ShouldEqual, "test error")
So(attachmentFields[1].Title, ShouldEqual, "key 1")
Expand All @@ -320,92 +320,116 @@ func TestBuildAttachmentFieldsFromDetails(t *testing.T) {
So(attachmentFields[2].Value, ShouldEqual, "value 2")
So(attachmentFields[3].Title, ShouldEqual, "key 3")
So(attachmentFields[3].Value, ShouldEqual, "value 3")
So(attachmentFields[4].Value, ShouldEqual, "<http://example.com/1|link 1>")
So(attachmentFields[5].Value, ShouldEqual, "<http://example.com/2|link 2>")
So(attachmentFields[6].Value, ShouldEqual, "<http://example.com/3|link 3>")
})
})
})

Convey("Given no error and details", t, func() {
Convey("When buildAttachmentFieldsFromDetails is called", func() {
attachmentFields := buildAttachmentFieldsFromDetails(nil, testDetails)
Convey("Given no error, details, and links", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(nil, testDetails, testLinks)

Convey("Then the returned attachmentFields contain only the details", func() {
So(len(attachmentFields), ShouldEqual, 3)
Convey("Then the returned attachmentFields contain only details and links", func() {
So(len(attachmentFields), ShouldEqual, 6)
So(attachmentFields[0].Title, ShouldEqual, "key 1")
So(attachmentFields[0].Value, ShouldEqual, "value 1")
So(attachmentFields[1].Title, ShouldEqual, "key 2")
So(attachmentFields[1].Value, ShouldEqual, "value 2")
So(attachmentFields[2].Title, ShouldEqual, "key 3")
So(attachmentFields[2].Value, ShouldEqual, "value 3")
So(attachmentFields[3].Value, ShouldEqual, "<http://example.com/1|link 1>")
So(attachmentFields[4].Value, ShouldEqual, "<http://example.com/2|link 2>")
So(attachmentFields[5].Value, ShouldEqual, "<http://example.com/3|link 3>")
})
})
})

Convey("Given an error and no details", t, func() {
Convey("When buildAttachmentFieldsFromDetails is called", func() {
attachmentFields := buildAttachmentFieldsFromDetails(errExampleError, nil)
Convey("Given an error, details, but no links", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(errExampleError, testDetails, nil)

Convey("Then the returned attachmentFields contain only the error", func() {
So(len(attachmentFields), ShouldEqual, 1)
Convey("Then the returned attachmentFields contain error and details", func() {
So(len(attachmentFields), ShouldEqual, 4)
So(attachmentFields[0].Title, ShouldEqual, "Error")
So(attachmentFields[0].Value, ShouldEqual, "test error")
So(attachmentFields[1].Title, ShouldEqual, "key 1")
So(attachmentFields[1].Value, ShouldEqual, "value 1")
So(attachmentFields[2].Title, ShouldEqual, "key 2")
So(attachmentFields[2].Value, ShouldEqual, "value 2")
So(attachmentFields[3].Title, ShouldEqual, "key 3")
So(attachmentFields[3].Value, ShouldEqual, "value 3")
})
})
})

Convey("Given no error and no details", t, func() {
Convey("When buildAttachmentFieldsFromDetails is called", func() {
attachmentFields := buildAttachmentFieldsFromDetails(nil, nil)
Convey("Given an error, but no details and no links", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(errExampleError, nil, nil)

Convey("Then the returned attachmentFields are empty", func() {
So(len(attachmentFields), ShouldEqual, 0)
Convey("Then the returned attachmentFields contain only the error", func() {
So(len(attachmentFields), ShouldEqual, 1)
So(attachmentFields[0].Title, ShouldEqual, "Error")
So(attachmentFields[0].Value, ShouldEqual, "test error")
})
})
})
}

func TestBuildAttachmentFieldsFromLinks(t *testing.T) {
Convey("Given some links", t, func() {
Convey("When buildAttachmentFieldsFromLinks is called", func() {
attachmentLinks := buildAttachmentFieldsFromLinks(testLinks)
Convey("Given no error, no details, and no links", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(nil, nil, nil)

Convey("Then the returned attachmentLinks match the input links", func() {
So(len(attachmentLinks), ShouldEqual, 3)
So(attachmentLinks[0].Value, ShouldEqual, "<http://example.com/1|link 1>")
So(attachmentLinks[1].Value, ShouldEqual, "<http://example.com/2|link 2>")
So(attachmentLinks[2].Value, ShouldEqual, "<http://example.com/3|link 3>")
Convey("Then the returned attachmentFields are empty", func() {
So(len(attachmentFields), ShouldEqual, 0)
})
})
})

Convey("Given no links", t, func() {
Convey("When buildAttachmentFieldsFromLinks is called", func() {
attachmentLinks := buildAttachmentFieldsFromLinks(nil)
Convey("Given details and links, but no error", t, func() {
Convey("When buildAttachmentFields is called", func() {
attachmentFields := buildAttachmentFields(nil, testDetails, testLinks)

Convey("Then the returned links are empty", func() {
So(len(attachmentLinks), ShouldEqual, 0)
Convey("Then the returned attachmentFields contain details and links", func() {
So(len(attachmentFields), ShouldEqual, 6)
})
})
})
}

func TestBuildAttachments(t *testing.T) {
Convey("Given valid parameters", t, func() {
Convey("Given valid parameters with error, details, and links", t, func() {
Convey("When buildAttachments is called", func() {
attachments := buildAttachments(errExampleError, testDetails, testLinks, RedColour)

Convey("Then 2 attachments are returned", func() {
So(len(attachments), ShouldEqual, 2)
Convey("Then 1 attachment is returned with all fields", func() {
So(len(attachments), ShouldEqual, 1)
So(attachments[0].Color, ShouldEqual, RedColour.String())
So(attachments[1].Title, ShouldEqual, "Resources")
So(len(attachments[0].Fields), ShouldEqual, 7)
})
})
})

Convey("When buildAttachments is called without links", func() {
Convey("Given parameters without links", t, func() {
Convey("When buildAttachments is called", func() {
attachments := buildAttachments(errExampleError, testDetails, nil, RedColour)

Convey("Then 1 attachment is returned", func() {
Convey("Then 1 attachment is returned with error and details", func() {
So(len(attachments), ShouldEqual, 1)
So(attachments[0].Color, ShouldEqual, RedColour.String())
So(len(attachments[0].Fields), ShouldEqual, 4)
})
})
})

Convey("Given parameters without error", t, func() {
Convey("When buildAttachments is called", func() {
attachments := buildAttachments(nil, testDetails, testLinks, YellowColour)

Convey("Then 1 attachment is returned with details and links", func() {
So(len(attachments), ShouldEqual, 1)
So(attachments[0].Color, ShouldEqual, YellowColour.String())
So(len(attachments[0].Fields), ShouldEqual, 6)
})
})
})
Expand Down