Skip to content

Commit e6fa5b3

Browse files
[CHA-17] - added support for pinning, archiving and partial member update (#142)
1 parent 9216c4c commit e6fa5b3

File tree

4 files changed

+129
-5
lines changed

4 files changed

+129
-5
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ jobs:
1515
with:
1616
fetch-depth: 0 # gives the commit linter access to previous commits
1717

18-
- name: Commit message linter
19-
if: ${{ matrix.ruby == '2.7' }}
20-
uses: wagoid/commitlint-github-action@v4
21-
2218
- uses: ruby/setup-ruby@v1
2319
with:
2420
ruby-version: ${{ matrix.ruby }}

lib/stream-chat/channel.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ class Channel
1616
sig { returns(String) }
1717
attr_reader :channel_type
1818

19+
sig { returns(String) }
20+
attr_reader :cid
21+
1922
sig { returns(StringKeyHash) }
2023
attr_reader :custom_data
2124

@@ -166,6 +169,68 @@ def unmute(user_id)
166169
@client.post('moderation/unmute/channel', data: { 'user_id' => user_id, 'channel_cid' => @cid })
167170
end
168171

172+
# Pins a channel for a user.
173+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
174+
def pin(user_id)
175+
raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
176+
177+
payload = {
178+
set: {
179+
pinned: true
180+
}
181+
}
182+
@client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
183+
end
184+
185+
# Unins a channel for a user.
186+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
187+
def unpin(user_id)
188+
raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
189+
190+
payload = {
191+
set: {
192+
pinned: false
193+
}
194+
}
195+
@client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
196+
end
197+
198+
# Archives a channel for a user.
199+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
200+
def archive(user_id)
201+
raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
202+
203+
payload = {
204+
set: {
205+
archived: true
206+
}
207+
}
208+
@client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
209+
end
210+
211+
# Archives a channel for a user.
212+
sig { params(user_id: String).returns(StreamChat::StreamResponse) }
213+
def unarchive(user_id)
214+
raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
215+
216+
payload = {
217+
set: {
218+
archived: false
219+
}
220+
}
221+
@client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
222+
end
223+
224+
# Updates a member partially in the channel.
225+
sig { params(user_id: String, set: T.nilable(StringKeyHash), unset: T.nilable(T::Array[String])).returns(StreamChat::StreamResponse) }
226+
def update_member_partial(user_id, set: nil, unset: nil)
227+
raise StreamChannelException, 'user ID must not be empty' if user_id.empty?
228+
raise StreamChannelException, 'set or unset is required' if set.nil? && unset.nil?
229+
230+
payload = { set: set, unset: unset }
231+
@client.patch("#{url}/member/#{CGI.escape(user_id)}", data: payload)
232+
end
233+
169234
# Adds members to the channel.
170235
sig { params(user_ids: T::Array[String], options: T.untyped).returns(StreamChat::StreamResponse) }
171236
def add_members(user_ids, **options)

spec/channel_spec.rb

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,67 @@ def loop_times(times)
288288
response = @channel.query_members(filter_conditions: { notifications_muted: true })
289289
expect(response['members'].length).to eq 2
290290
end
291+
292+
it 'can pin and unpin a channel' do
293+
@channel.add_members([@random_users[0][:id]])
294+
@channel.add_members([@random_users[1][:id]])
295+
296+
# Pin the channel
297+
now = Time.now
298+
response = @channel.pin(@random_users[0][:id])
299+
expect(response['channel_member']['pinned_at']).not_to be_nil
300+
expect(Time.parse(response['channel_member']['pinned_at']).to_i).to be >= now.to_i
301+
302+
# Query for pinned channel
303+
response = @client.query_channels({ 'pinned' => true, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
304+
expect(response['channels'].length).to eq 1
305+
expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
306+
307+
# Unpin the channel
308+
response = @channel.unpin(@random_users[0][:id])
309+
expect(response['channel_member']).not_to have_key('pinned_at')
310+
311+
# Query for unpinned channel
312+
response = @client.query_channels({ 'pinned' => false, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
313+
expect(response['channels'].length).to eq 1
314+
expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
315+
end
316+
317+
it 'can archive and unarchive a channel' do
318+
@channel.add_members([@random_users[0][:id]])
319+
@channel.add_members([@random_users[1][:id]])
320+
321+
# Pin the channel
322+
now = Time.now
323+
response = @channel.archive(@random_users[0][:id])
324+
expect(response['channel_member']['archived_at']).not_to be_nil
325+
expect(Time.parse(response['channel_member']['archived_at']).to_i).to be >= now.to_i
326+
327+
# Query for archived channel
328+
response = @client.query_channels({ 'archived' => true, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
329+
expect(response['channels'].length).to eq 1
330+
expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
331+
332+
# Unarchive the channel
333+
response = @channel.unarchive(@random_users[0][:id])
334+
expect(response['channel_member']).not_to have_key('archived_at')
335+
336+
# Query for unarchived channel
337+
response = @client.query_channels({ 'archived' => false, 'cid' => @channel.cid }, sort: nil, user_id: @random_users[0][:id])
338+
expect(response['channels'].length).to eq 1
339+
expect(response['channels'][0]['channel']['cid']).to eq @channel.cid
340+
end
341+
342+
it 'can update channel member partially' do
343+
@channel.add_members([@random_users[0][:id]])
344+
345+
# Test setting a field
346+
response = @channel.update_member_partial(@random_users[0][:id], set: { 'hat' => 'blue' })
347+
expect(response['channel_member']['hat']).to eq 'blue'
348+
349+
# Test setting and unsetting fields
350+
response = @channel.update_member_partial(@random_users[0][:id], set: { 'color' => 'red' }, unset: ['hat'])
351+
expect(response['channel_member']['color']).to eq 'red'
352+
expect(response['channel_member']).not_to have_key('hat')
353+
end
291354
end

spec/client_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ def loop_times(times)
718718
end
719719

720720
it 'import end2end' do
721-
url_resp = @client.create_import_url("#{SecureRandom.uuid}.json'")
721+
url_resp = @client.create_import_url("#{SecureRandom.uuid}.json")
722722
expect(url_resp['upload_url']).not_to be_empty
723723
expect(url_resp['path']).not_to be_empty
724724

0 commit comments

Comments
 (0)