-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add utility function for validating slack integrations (#1114)
- Loading branch information
1 parent
36cc060
commit 62f6d38
Showing
6 changed files
with
162 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -363,6 +363,7 @@ workflows: | |
- test: | ||
context: | ||
- Gruntwork Admin | ||
- Slack Token For Test | ||
requires: | ||
- setup | ||
filters: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Package slack contains routines useful for testing slack integrations. | ||
package slack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package slack | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/gruntwork-io/terratest/modules/testing" | ||
"github.com/slack-go/slack" | ||
) | ||
|
||
// ValidateExpectedSlackMessage validates whether a message containing the expected text was posted in the given channel | ||
// ID, looking back historyLimit messages up to the given duration. For example, if you set (15*time.Minute) as the | ||
// lookBack parameter with historyLimit set to 50, then this will look back the last 50 messages, up to 15 minutes ago. | ||
// This expects a slack token to be provided. This returns MessageNotFoundErr when there is no match. | ||
// For the purposes of matching, this only checks the following blocks: | ||
// - Section block text | ||
// - Header block text | ||
// All other blocks are ignored in the validation. | ||
// NOTE: This only looks for bot posted messages. | ||
func ValidateExpectedSlackMessageE( | ||
t testing.TestingT, | ||
token, | ||
channelID, | ||
expectedText string, | ||
historyLimit int, | ||
lookBack time.Duration, | ||
) error { | ||
lookBackTime := time.Now().Add(-1 * lookBack) | ||
slackClt := slack.New(token) | ||
params := slack.GetConversationHistoryParameters{ | ||
ChannelID: channelID, | ||
Limit: historyLimit, | ||
Oldest: strconv.FormatInt(lookBackTime.Unix(), 10), | ||
} | ||
|
||
resp, err := slackClt.GetConversationHistory(¶ms) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, msg := range resp.Messages { | ||
if checkMessageContainsText(msg.Msg, expectedText) { | ||
return nil | ||
} | ||
|
||
if msg.SubMessage != nil { | ||
if checkMessageContainsText(*msg.SubMessage, expectedText) { | ||
return nil | ||
} | ||
} | ||
} | ||
return fmt.Errorf("still no message") | ||
} | ||
|
||
func checkMessageContainsText(msg slack.Msg, expectedText string) bool { | ||
// If this message is not a bot message, ignore. | ||
if msg.Type != slack.MsgSubTypeBotMessage && msg.BotID == "" { | ||
return false | ||
} | ||
|
||
// Check message text | ||
if strings.Contains(msg.Text, expectedText) { | ||
return true | ||
} | ||
|
||
// Check attachments | ||
for _, attachment := range msg.Attachments { | ||
if strings.Contains(attachment.Text, expectedText) { | ||
return true | ||
} | ||
} | ||
|
||
// Check blocks | ||
for _, block := range msg.Blocks.BlockSet { | ||
switch block.BlockType() { | ||
case slack.MBTSection: | ||
sectionBlk := block.(*slack.SectionBlock) | ||
if sectionBlk.Text != nil && strings.Contains(sectionBlk.Text.Text, expectedText) { | ||
return true | ||
} | ||
case slack.MBTHeader: | ||
headerBlk := block.(*slack.HeaderBlock) | ||
if headerBlk.Text != nil && strings.Contains(headerBlk.Text.Text, expectedText) { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
return false | ||
} | ||
|
||
type MessageNotFoundErr struct{} | ||
|
||
func (err MessageNotFoundErr) Error() string { | ||
return "Could not find the expected text in any of the messages posted in the given channel." | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package slack | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/slack-go/slack" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/gruntwork-io/terratest/modules/environment" | ||
"github.com/gruntwork-io/terratest/modules/random" | ||
"github.com/gruntwork-io/terratest/modules/retry" | ||
) | ||
|
||
const ( | ||
slackTokenEnv = "SLACK_TOKEN_FOR_TEST" | ||
slackChannelIDEnv = "SLACK_CHANNEL_ID_FOR_TEST" | ||
) | ||
|
||
func TestValidateSlackMessage(t *testing.T) { | ||
t.Parallel() | ||
|
||
environment.RequireEnvVar(t, slackTokenEnv) | ||
environment.RequireEnvVar(t, slackChannelIDEnv) | ||
|
||
token := os.Getenv(slackTokenEnv) | ||
channelID := os.Getenv(slackChannelIDEnv) | ||
|
||
uniqueID := random.UniqueId() | ||
msgTxt := fmt.Sprintf("Test message from terratest: %s", uniqueID) | ||
|
||
slackClt := slack.New(token) | ||
|
||
_, _, err := slackClt.PostMessage( | ||
channelID, | ||
slack.MsgOptionText(msgTxt, false), | ||
) | ||
require.NoError(t, err) | ||
|
||
retry.DoWithRetry( | ||
t, | ||
"wait for slack message", | ||
6, 10*time.Second, | ||
func() (string, error) { | ||
err := ValidateExpectedSlackMessageE(t, token, channelID, msgTxt, 10, 5*time.Minute) | ||
return "", err | ||
}, | ||
) | ||
} |