Skip to content

Commit 5a985c9

Browse files
rafaelmf3Rafael Marinho
andauthored
[CHA-941]: update channel to accept ChannelMembers too (#336)
* [CHA-941]: update channel to accept ChannelMembers too * remove unused code * add unit tests * adding new method to add channel members with the ChannelMember object * adding unit tests * fix unit test * unexport method * unexport method * fix unit test --------- Co-authored-by: Rafael Marinho <[email protected]>
1 parent 91a99b7 commit 5a985c9

File tree

2 files changed

+143
-5
lines changed

2 files changed

+143
-5
lines changed

channel.go

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ type ChannelMember struct {
4242
UpdatedAt time.Time `json:"updated_at,omitempty"`
4343
}
4444

45+
// newChannelMembersFromStrings creates a ChannelMembers from a slice of strings
46+
func newChannelMembersFromStrings(members []string) []*ChannelMember {
47+
channelMembers := make([]*ChannelMember, len(members))
48+
for i, m := range members {
49+
channelMembers[i] = &ChannelMember{
50+
UserID: m,
51+
}
52+
}
53+
return channelMembers
54+
}
55+
4556
type channelMemberForJSON ChannelMember
4657

4758
// UnmarshalJSON implements json.Unmarshaler.
@@ -155,7 +166,8 @@ type ChannelRequest struct {
155166
AutoTranslationLanguage string `json:"auto_translation_language,omitempty"`
156167
Frozen *bool `json:"frozen,omitempty"`
157168
Disabled *bool `json:"disabled,omitempty"`
158-
Members []string `json:"members,omitempty"`
169+
ChannelMembers []*ChannelMember `json:"members,omitempty"`
170+
Members []string `json:"-"`
159171
Invites []string `json:"invites,omitempty"`
160172
ExtraData map[string]interface{} `json:"-"`
161173
}
@@ -374,7 +386,8 @@ func (ch *Channel) GetMessages(ctx context.Context, messageIDs []string) (*GetMe
374386
}
375387

376388
type addMembersOptions struct {
377-
MemberIDs []string `json:"add_members"`
389+
MemberIDs []string `json:"-"`
390+
ChannelMembers []*ChannelMember `json:"add_members"`
378391

379392
RolesAssignement []*RoleAssignment `json:"assign_roles"`
380393
HideHistory bool `json:"hide_history"`
@@ -401,14 +414,35 @@ func AddMembersWithRolesAssignment(assignements []*RoleAssignment) func(*addMemb
401414
}
402415
}
403416

404-
// AddMembers adds members with given user IDs to the channel.
417+
// AddMembers adds members with given user IDs to the channel. If you want to add members with ChannelMember objects, use AddChannelMembers instead.
405418
func (ch *Channel) AddMembers(ctx context.Context, userIDs []string, options ...AddMembersOptions) (*Response, error) {
406419
if len(userIDs) == 0 {
407420
return nil, errors.New("user IDs are empty")
408421
}
409422

410423
opts := &addMembersOptions{
411-
MemberIDs: userIDs,
424+
ChannelMembers: newChannelMembersFromStrings(userIDs),
425+
}
426+
427+
for _, fn := range options {
428+
fn(opts)
429+
}
430+
431+
p := path.Join("channels", url.PathEscape(ch.Type), url.PathEscape(ch.ID))
432+
433+
var resp Response
434+
err := ch.client.makeRequest(ctx, http.MethodPost, p, nil, opts, &resp)
435+
return &resp, err
436+
}
437+
438+
// AddChannelMembers adds members with given []*ChannelMember to the channel.
439+
func (ch *Channel) AddChannelMembers(ctx context.Context, members []*ChannelMember, options ...AddMembersOptions) (*Response, error) {
440+
if len(members) == 0 {
441+
return nil, errors.New("members are empty")
442+
}
443+
444+
opts := &addMembersOptions{
445+
ChannelMembers: members,
412446
}
413447

414448
for _, fn := range options {
@@ -770,7 +804,7 @@ func (c *Client) CreateChannel(ctx context.Context, chanType, chanID, userID str
770804
switch {
771805
case chanType == "":
772806
return nil, errors.New("channel type is empty")
773-
case chanID == "" && (data == nil || len(data.Members) == 0):
807+
case chanID == "" && (data == nil || (len(data.Members) == 0 && len(data.ChannelMembers) == 0)):
774808
return nil, errors.New("either channel ID or members must be provided")
775809
case userID == "":
776810
return nil, errors.New("user ID is empty")
@@ -792,6 +826,9 @@ func (c *Client) CreateChannel(ctx context.Context, chanType, chanID, userID str
792826
data = &ChannelRequest{CreatedBy: &User{ID: userID}}
793827
} else {
794828
data.CreatedBy = &User{ID: userID}
829+
if len(data.ChannelMembers) == 0 {
830+
data.ChannelMembers = newChannelMembersFromStrings(data.Members)
831+
}
795832
}
796833

797834
q := &QueryRequest{

channel_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ func TestClient_CreateChannel(t *testing.T) {
8686
[]CreateChannelOptionFunc{HideForCreator(true)},
8787
false,
8888
},
89+
{"create channel with ChannelMembers", "messaging", "", userID,
90+
&ChannelRequest{
91+
ChannelMembers: []*ChannelMember{
92+
{UserID: userID},
93+
{UserID: randomUsersID(t, c, 1)[0]},
94+
},
95+
}, nil, false,
96+
},
8997
}
9098

9199
for _, tt := range tests {
@@ -152,6 +160,99 @@ func TestChannel_AddMembers(t *testing.T) {
152160
assert.Equal(t, user.ID, ch.Members[0].User.ID, "members contain user id")
153161
}
154162

163+
func TestChannel_AddChannelMembers(t *testing.T) {
164+
c := initClient(t)
165+
ctx := context.Background()
166+
AddChannelMemberUser := randomUser(t, c)
167+
168+
channelModeratorID := randomUser(t, c).ID
169+
channelAdminID := randomUser(t, c).ID
170+
171+
tests := []struct {
172+
name string
173+
members []*ChannelMember
174+
options []AddMembersOptions
175+
expectedCount int
176+
expectedRoles map[string]string // userID -> expected role
177+
expectedUsers []string // expected user IDs
178+
}{
179+
{
180+
name: "Add members with ID only",
181+
members: []*ChannelMember{
182+
{UserID: randomUser(t, c).ID},
183+
{UserID: randomUser(t, c).ID},
184+
},
185+
options: []AddMembersOptions{
186+
AddMembersWithMessage(&Message{Text: "adding members with ID only", User: AddChannelMemberUser}),
187+
AddMembersWithHideHistory(),
188+
},
189+
expectedCount: 2,
190+
expectedRoles: map[string]string{},
191+
expectedUsers: []string{},
192+
},
193+
{
194+
name: "Add members with ID and role",
195+
members: []*ChannelMember{
196+
{UserID: randomUser(t, c).ID, ChannelRole: "channel_moderator"},
197+
{UserID: randomUser(t, c).ID, ChannelRole: "channel_member"},
198+
},
199+
options: []AddMembersOptions{
200+
AddMembersWithMessage(&Message{Text: "adding members with roles", User: AddChannelMemberUser}),
201+
},
202+
expectedCount: 2,
203+
expectedRoles: map[string]string{
204+
channelModeratorID: "channel_moderator",
205+
channelAdminID: "channel_member",
206+
},
207+
expectedUsers: []string{},
208+
},
209+
}
210+
211+
for _, tt := range tests {
212+
t.Run(tt.name, func(t *testing.T) {
213+
// Store user IDs for verification
214+
userIDs := make([]string, len(tt.members))
215+
for i, member := range tt.members {
216+
userIDs[i] = member.UserID
217+
}
218+
219+
chanID := randomString(12)
220+
resp, err := c.CreateChannel(ctx, "messaging", chanID, AddChannelMemberUser.ID, nil)
221+
require.NoError(t, err, "create channel")
222+
ch := resp.Channel
223+
assert.Empty(t, ch.Members, "members are empty")
224+
225+
// Add members
226+
_, err = ch.AddChannelMembers(ctx, tt.members, tt.options...)
227+
require.NoError(t, err, "add channel members")
228+
229+
// Refresh channel state
230+
require.NoError(t, ch.refresh(ctx), "refresh channel")
231+
232+
// Verify member count
233+
assert.Len(t, ch.Members, tt.expectedCount, "member count should match")
234+
235+
// Verify each member
236+
for i, userID := range userIDs {
237+
found := false
238+
for _, member := range ch.Members {
239+
if member.User.ID == userID {
240+
found = true
241+
242+
// Check role if expected
243+
if tt.members[i].ChannelRole != "" {
244+
assert.Equal(t, tt.members[i].ChannelRole, member.ChannelRole,
245+
"user %s should have role %s", userID, tt.members[i].ChannelRole)
246+
}
247+
break
248+
}
249+
}
250+
assert.True(t, found, "user %s should be found in members", userID)
251+
}
252+
})
253+
}
254+
}
255+
155256
func TestChannel_AssignRoles(t *testing.T) {
156257
c := initClient(t)
157258
ctx := context.Background()

0 commit comments

Comments
 (0)