Skip to content

Commit

Permalink
Update Slack conversation adapter to paginate GetUsersInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
mike-gregory-ovo committed Oct 31, 2022
1 parent a91af06 commit 0201816
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
44 changes: 43 additions & 1 deletion adapters/slack/conversation/conversation.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"context"
"fmt"
"log"
"math"
"os"
"strings"
"time"
Expand Down Expand Up @@ -111,6 +112,47 @@ func (c *Conversation) getListOfSlackUsernames() ([]string, error) {
return users, nil
}

// paginateUsersInfo requests.
func (c *Conversation) paginateUsersInfo(slackUsers []string) (*[]slack.User, error) {
currentPage := 0
pageSize := 30
out := make([]slack.User, 0, cap(slackUsers))
totalPages := math.Floor(float64(len(slackUsers)) / float64(pageSize))

for {
c.Logger.Printf("Calling GetUsersInfo page %v of %v", currentPage+1, totalPages+1)

start := currentPage * pageSize
end := (currentPage * pageSize) + pageSize

if end > cap(slackUsers) {
end = cap(slackUsers)
}

// Get a page of slackUsers to send up to the API.
page := slackUsers[start:end]

// Request only the page of users.
users, err := c.client.GetUsersInfo(page...)
if err != nil {
return nil, fmt.Errorf("paginateusersinfo -> %w", err)
}

// Append the results to combined output.
out = append(out, *users...)

// When the output matches the number of input slack users, end the loop.
if len(out) == len(slackUsers) {
break
}

// Increment the current page.
currentPage++
}

return &out, nil
}

// Get email addresses in a Slack Conversation.
func (c *Conversation) Get(_ context.Context) ([]string, error) {
c.Logger.Printf("Fetching accounts from Slack conversation %s", c.conversationName)
Expand All @@ -129,7 +171,7 @@ func (c *Conversation) Get(_ context.Context) ([]string, error) {
return []string{}, nil
}

users, err := c.client.GetUsersInfo(slackUsers...)
users, err := c.paginateUsersInfo(slackUsers)
if err != nil {
return nil, fmt.Errorf("slack.conversation.get.getusersinfo -> %w", err)
}
Expand Down
44 changes: 44 additions & 0 deletions adapters/slack/conversation/conversation_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package conversation
import (
"context"
"errors"
"fmt"
"testing"

gosync "github.com/ovotech/go-sync"
Expand Down Expand Up @@ -56,6 +57,49 @@ func TestConversation_Get(t *testing.T) {
assert.Equal(t, map[string]string{"foo@email": "foo", "bar@email": "bar"}, adapter.cache)
}

func TestConversation_Get_Pagination(t *testing.T) {
t.Parallel()

slackClient := newMockISlackConversation(t)
adapter := New(&slack.Client{}, "test")
adapter.client = slackClient

incrementingSlice := make([]string, 60)
firstPage := make([]interface{}, 30)
secondPage := make([]interface{}, 30)
firstResponse := make([]slack.User, 30)
secondResponse := make([]slack.User, 30)

for idx := range incrementingSlice {
incrementingSlice[idx] = fmt.Sprint(idx)

if idx < 30 {
firstPage[idx] = fmt.Sprint(idx)
firstResponse[idx] = slack.User{
ID: fmt.Sprint(idx), IsBot: false, Profile: slack.UserProfile{Email: fmt.Sprint(idx)},
}
} else {
secondPage[idx-30] = fmt.Sprint(idx)
secondResponse[idx-30] = slack.User{
ID: fmt.Sprint(idx), IsBot: false, Profile: slack.UserProfile{Email: fmt.Sprint(idx)},
}
}
}

slackClient.EXPECT().GetUsersInConversation(&slack.GetUsersInConversationParameters{
ChannelID: "test",
Cursor: "",
Limit: 50,
}).Return(incrementingSlice, "", nil)

slackClient.EXPECT().GetUsersInfo(firstPage...).Return(&firstResponse, nil)
slackClient.EXPECT().GetUsersInfo(secondPage...).Return(&secondResponse, nil)

_, err := adapter.Get(context.TODO())

assert.NoError(t, err)
}

func TestConversation_Add(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 0201816

Please sign in to comment.