Skip to content

Commit

Permalink
Added E2E test to verify large output is received as plaintext file w…
Browse files Browse the repository at this point in the history
…ith executor command as message.
  • Loading branch information
ezodude committed Sep 28, 2022
1 parent 4f3e5ff commit c675dd3
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
32 changes: 25 additions & 7 deletions test/e2e/bots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ type DiscordConfig struct {
}

const (
channelNamePrefix = "test"
welcomeText = "Let the tests begin 🤞"
pollInterval = time.Second
slackAnnotation = "<http://botkube.io/*|botkube.io/*>"
discordAnnotation = "botkube.io/*"
discordInvalidCmd = "You must specify the type of resource to get. Use \"kubectl api-resources\" for a complete list of supported resources.\n\nerror: Required resource not specified.\nUse \"kubectl explain <resource>\" for a detailed description of that resource (e.g. kubectl explain pods).\nSee 'kubectl get -h' for help and examples\nexit status 1"
channelNamePrefix = "test"
welcomeText = "Let the tests begin 🤞"
pollInterval = time.Second
globalConfigMapName = "botkube-global-config"
slackAnnotation = "<http://botkube.io/*|botkube.io/*>"
discordAnnotation = "botkube.io/*"
discordInvalidCmd = "You must specify the type of resource to get. Use \"kubectl api-resources\" for a complete list of supported resources.\n\nerror: Required resource not specified.\nUse \"kubectl explain <resource>\" for a detailed description of that resource (e.g. kubectl explain pods).\nSee 'kubectl get -h' for help and examples\nexit status 1"
)

var (
Expand Down Expand Up @@ -170,12 +171,14 @@ func runBotTest(t *testing.T,
err = waitForDeploymentReady(deployNsCli, appCfg.Deployment.Name, appCfg.Deployment.WaitTimeout)
require.NoError(t, err)

t.Log("Waiting for Bot message in channel...")
t.Log("Waiting for interactive help")
err = botDriver.WaitForInteractiveMessagePostedRecentlyEqual(botDriver.BotUserID(),
botDriver.Channel().ID(),
interactive.Help(config.CommPlatformIntegration(botDriver.Type()), appCfg.ClusterName, botDriver.BotName()),
)
require.NoError(t, err)

t.Log("Waiting for Bot message in channel...")
err = botDriver.WaitForMessagePostedRecentlyEqual(botDriver.BotUserID(), botDriver.Channel().ID(), fmt.Sprintf("...and now my watch begins for cluster '%s'! :crossed_swords:", appCfg.ClusterName))
require.NoError(t, err)

Expand Down Expand Up @@ -330,6 +333,21 @@ func runBotTest(t *testing.T,
assert.NoError(t, err)
})

t.Run("Receive large output as plaintext file with executor command as message", func(t *testing.T) {
command := fmt.Sprintf("get configmap %s -o yaml -n %s", globalConfigMapName, appCfg.Deployment.Namespace)
fileUploadAssertionFn := func(title, mimetype string) bool {
return title == "Response.txt" && strings.Contains(mimetype, "text/plain")
}
botDriver.PostMessageToBot(t, botDriver.Channel().Identifier(), command)
err = botDriver.WaitForMessagePostedWithFileUpload(botDriver.BotUserID(), botDriver.Channel().ID(), fileUploadAssertionFn)
assert.NoError(t, err)

assertionFn := func(msg string) bool {
return strings.Contains(msg, heredoc.Doc(fmt.Sprintf("`%s` on `%s`", command, appCfg.ClusterName)))
}
err = botDriver.WaitForMessagePosted(botDriver.BotUserID(), botDriver.Channel().ID(), 1, assertionFn)
})

t.Run("Get forbidden resource", func(t *testing.T) {
command := "get ingress"
expectedBody := codeBlock(fmt.Sprintf("Sorry, the kubectl command is not authorized to work with 'ingress' resources in the 'default' Namespace on cluster '%s'. Use 'commands list' to see allowed commands.", appCfg.ClusterName))
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/bots_tester_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var structDumper = litter.Options{

type MessageAssertion func(content string) bool
type AttachmentAssertion func(title, color, msg string) bool
type FileUploadAssertion func(title, mimetype string) bool

type Channel interface {
ID() string
Expand Down Expand Up @@ -53,6 +54,7 @@ type BotDriver interface {
WaitForLastMessageEqual(userID, channel, expectedMsg string) error
WaitForMessagePosted(userID, channel string, limitMessages int, assertFn MessageAssertion) error
WaitForInteractiveMessagePosted(userID, channelID string, limitMessages int, assertFn MessageAssertion) error
WaitForMessagePostedWithFileUpload(userID, channelID string, assertFn FileUploadAssertion) error
WaitForMessagePostedWithAttachment(userID, channel string, assertFn AttachmentAssertion) error
WaitForMessagesPostedOnChannelsWithAttachment(userID string, channelIDs []string, assertFn AttachmentAssertion) error
Channel() Channel
Expand Down
51 changes: 51 additions & 0 deletions test/e2e/discord_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,57 @@ func (d *discordTester) WaitForInteractiveMessagePosted(userID, channelID string
return d.WaitForMessagePosted(userID, channelID, limitMessages, assertFn)
}

func (d *discordTester) WaitForMessagePostedWithFileUpload(userID, channelID string, assertFn FileUploadAssertion) error {
// To always receive message content:
// ensure you enable the MESSAGE CONTENT INTENT for the tester bot on the developer portal.
// Applications ↦ Settings ↦ Bot ↦ Privileged Gateway Intents
// This setting has been enforced from August 31, 2022

var fetchedMessages []*discordgo.Message
var lastErr error

err := wait.Poll(pollInterval, d.cfg.MessageWaitTimeout, func() (done bool, err error) {
messages, err := d.cli.ChannelMessages(channelID, 1, "", "", "")
if err != nil {
lastErr = err
return false, nil
}

fetchedMessages = messages
for _, msg := range messages {
if msg.Author.ID != userID {
continue
}

if len(msg.Attachments) != 1 {
lastErr = err
return false, nil
}

upload := msg.Attachments[0]
if !assertFn(upload.Filename, upload.ContentType) {
// different message
continue
}

return true, nil
}

return false, nil
})
if lastErr == nil {
lastErr = errors.New("message assertion function returned false")
}
if err != nil {
if err == wait.ErrWaitTimeout {
return fmt.Errorf("while waiting for condition: last error: %w; fetched messages: %s", lastErr, structDumper.Sdump(fetchedMessages))
}
return err
}

return nil
}

func (d *discordTester) WaitForMessagePostedWithAttachment(userID, channelID string, assertFn AttachmentAssertion) error {
// To always receive message content:
// ensure you enable the MESSAGE CONTENT INTENT for the tester bot on the developer portal.
Expand Down
46 changes: 46 additions & 0 deletions test/e2e/slack_driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,52 @@ func (s *slackTester) WaitForInteractiveMessagePosted(userID, channelID string,
return s.WaitForMessagePosted(userID, channelID, limitMessages, assertFn)
}

func (s *slackTester) WaitForMessagePostedWithFileUpload(userID, channelID string, assertFn FileUploadAssertion) error {
var fetchedMessages []slack.Message
var lastErr error
err := wait.Poll(pollInterval, s.cfg.MessageWaitTimeout, func() (done bool, err error) {
historyRes, err := s.cli.GetConversationHistory(&slack.GetConversationHistoryParameters{
ChannelID: channelID, Limit: 1,
})
if err != nil {
lastErr = err
return false, nil
}

fetchedMessages = historyRes.Messages
for _, msg := range historyRes.Messages {
if msg.User != userID {
continue
}

if len(msg.Files) != 1 {
return false, nil
}

upload := msg.Files[0]
if !assertFn(upload.Title, upload.Mimetype) {
// different message
return false, nil
}

return true, nil
}

return false, nil
})
if lastErr == nil {
lastErr = errors.New("message assertion function returned false")
}
if err != nil {
if err == wait.ErrWaitTimeout {
return fmt.Errorf("while waiting for condition: last error: %w; fetched messages: %s", lastErr, structDumper.Sdump(fetchedMessages))
}
return err
}

return nil
}

func (s *slackTester) WaitForMessagePostedWithAttachment(userID, channelID string, assertFn AttachmentAssertion) error {
var fetchedMessages []slack.Message
var lastErr error
Expand Down

0 comments on commit c675dd3

Please sign in to comment.