From 219acc23345bdcdfe1e37def6ab63beba38ab948 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Fri, 23 May 2025 10:10:25 +0200 Subject: [PATCH 01/11] feature(CHA-769): add shared location support --- lib/stream-chat/client.rb | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index 8d4944c..173b6d2 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -807,6 +807,35 @@ def query_drafts(user_id, filter: nil, sort: nil, **options) post('drafts/query', data: data) end + # Get active_live_locations for the current user + # + # @return [StreamChat::StreamResponse] + sig { returns(StreamChat::StreamResponse) } + def get_active_live_locations + get('users/locations') + end + + # Update live location + # + # @param [String] created_by_device_id The device ID that created the location + # @param [String] message_id The message ID associated with the location + # @param [Float] latitude Optional latitude coordinate + # @param [Float] longitude Optional longitude coordinate + # @param [String] end_at Optional end time for the location sharing + # @return [StreamChat::StreamResponse] + sig { params(created_by_device_id: String, message_id: String, latitude: T.nilable(Float), longitude: T.nilable(Float), end_at: T.nilable(String)).returns(StreamChat::StreamResponse) } + def update_location(created_by_device_id:, message_id:, latitude: nil, longitude: nil, end_at: nil) + data = { + created_by_device_id: created_by_device_id, + message_id: message_id + } + data[:latitude] = latitude if latitude + data[:longitude] = longitude if longitude + data[:end_at] = end_at if end_at + + put('users/location', data: data) + end + # Gets a comamnd. sig { params(name: String).returns(StreamChat::StreamResponse) } def get_command(name) From d460aa5edab0927a04a8b6724e4ea119c28d8874 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 26 May 2025 08:39:10 +0200 Subject: [PATCH 02/11] fix Sorbet type checking error --- lib/stream-chat/client.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index 173b6d2..d25c940 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -688,7 +688,7 @@ def delete_channels(cids, hard_delete: false) # Revoke tokens for an application issued since the given date. sig { params(before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) } def revoke_tokens(before) - before = T.cast(before, DateTime).rfc3339 if before.instance_of?(DateTime) + before = before.rfc3339 if before.instance_of?(DateTime) update_app_settings({ 'revoke_tokens_issued_before' => before }) end @@ -701,7 +701,7 @@ def revoke_user_token(user_id, before) # Revoke tokens for users issued since. sig { params(user_ids: T::Array[String], before: T.any(DateTime, String)).returns(StreamChat::StreamResponse) } def revoke_users_token(user_ids, before) - before = T.cast(before, DateTime).rfc3339 if before.instance_of?(DateTime) + before = before.rfc3339 if before.instance_of?(DateTime) updates = [] user_ids.map do |user_id| From 785d723660622e2c45bb735093a45e3fb3f49946 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 26 May 2025 08:48:07 +0200 Subject: [PATCH 03/11] fix spec --- spec/client_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index b0e5dc9..24c19d9 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -526,7 +526,7 @@ def loop_times(times) describe 'blocklist' do before(:all) do - @blocklist = SecureRandom.uuid + @blocklist = "test_blocklist_#{SecureRandom.hex(8)}" end it 'list available blocklists' do From a843cc007178a31c8b771f358d1bfdb68d96e6d2 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 26 May 2025 13:46:29 +0200 Subject: [PATCH 04/11] add specs and fix location methods --- lib/stream-chat/client.rb | 13 +++--- spec/client_spec.rb | 84 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index d25c940..2b4d570 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -810,21 +810,22 @@ def query_drafts(user_id, filter: nil, sort: nil, **options) # Get active_live_locations for the current user # # @return [StreamChat::StreamResponse] - sig { returns(StreamChat::StreamResponse) } - def get_active_live_locations - get('users/locations') + sig { params(user_id: String).returns(StreamChat::StreamResponse) } + def get_active_live_locations(user_id) + get('users/locations', params: { user_id: user_id }) end # Update live location # + # @param [String] user_id The ID of the user to update the location # @param [String] created_by_device_id The device ID that created the location # @param [String] message_id The message ID associated with the location # @param [Float] latitude Optional latitude coordinate # @param [Float] longitude Optional longitude coordinate # @param [String] end_at Optional end time for the location sharing # @return [StreamChat::StreamResponse] - sig { params(created_by_device_id: String, message_id: String, latitude: T.nilable(Float), longitude: T.nilable(Float), end_at: T.nilable(String)).returns(StreamChat::StreamResponse) } - def update_location(created_by_device_id:, message_id:, latitude: nil, longitude: nil, end_at: nil) + sig { params(user_id: String, created_by_device_id: String, message_id: String, latitude: T.nilable(Float), longitude: T.nilable(Float), end_at: T.nilable(String)).returns(StreamChat::StreamResponse) } + def update_location(user_id, created_by_device_id:, message_id:, latitude: nil, longitude: nil, end_at: nil) data = { created_by_device_id: created_by_device_id, message_id: message_id @@ -833,7 +834,7 @@ def update_location(created_by_device_id:, message_id:, latitude: nil, longitude data[:longitude] = longitude if longitude data[:end_at] = end_at if end_at - put('users/location', data: data) + put('users/location', data: data, params: { user_id: user_id }) end # Gets a comamnd. diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 24c19d9..b2f6cba 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -825,7 +825,9 @@ def loop_times(times) list_resp = @client.list_imports({ limit: 1 }) expect(list_resp['import_tasks'].length).to eq 1 end + end + describe 'drafts' do it 'can query drafts' do # Create multiple drafts in different channels draft1 = { 'text' => 'Draft in channel 1' } @@ -1020,4 +1022,86 @@ def loop_times(times) expect(response['threads'].length).to be >= 1 end end + + describe 'live locations' do + before(:all) do + @location_test_user = { id: SecureRandom.uuid } + @client.upsert_users([@location_test_user]) + @location_channel = @client.channel('messaging', channel_id: SecureRandom.uuid) + @location_channel.create(@location_test_user[:id]) + @location_message = @location_channel.send_message({ text: 'Location sharing message' }, @location_test_user[:id]) + end + + after(:all) do + @location_channel.delete + @client.delete_user(@location_test_user[:id]) + end + + it 'can create and update a location' do + location = { + created_by_device_id: SecureRandom.uuid, + latitude: 40.7128, + longitude: -74.0060, + end_at: (Time.now + 3600).iso8601 + } + + response = @channel.send_message({ + text: 'Location sharing message', + shared_location: location, + }, @location_test_user[:id]) + + expect(response['message']).to include 'shared_location' + expect(response['message']['shared_location']['created_by_device_id']).to eq(location[:created_by_device_id]) + expect(response['message']['shared_location']['latitude']).to eq(location[:latitude]) + expect(response['message']['shared_location']['longitude']).to eq(location[:longitude]) + + new_latitude = location[:latitude] + 10 + response = @client.update_location( + response['message']['user']['id'], + created_by_device_id: location[:created_by_device_id], + message_id: response['message']['id'], + latitude: new_latitude, + longitude: location[:longitude], + end_at: location[:end_at], + ) + + expect(response['created_by_device_id']).to eq(location[:created_by_device_id]) + expect(response['latitude']).to eq(new_latitude) + expect(response['longitude']).to eq(location[:longitude]) + end + + it 'can get active live locations' do + device_id = SecureRandom.uuid + latitude = 40.7128 + longitude = -74.0060 + end_at = (Time.now + 3600).iso8601 + + response = @location_channel.send_message({ + text: 'Location sharing message', + shared_location: { + created_by_device_id: device_id, + latitude: latitude, + longitude: longitude, + end_at: end_at + } + }, @location_test_user[:id]) + + response = @client.get_active_live_locations(@location_test_user[:id]) + expect(response).to include 'active_live_locations' + expect(response['active_live_locations']).to be_an(Array) + expect(response['active_live_locations'].length).to be >= 1 + + location = response['active_live_locations'].find { |loc| loc['created_by_device_id'] == device_id } + expect(location).not_to be_nil + expect(location['latitude']).to eq(latitude) + expect(location['longitude']).to eq(longitude) + expect(DateTime.parse(location['end_at']).iso8601).to eq(end_at) + end + + it 'should have active live locations on the channel' do + response = @channel.query() + expect(response).to include 'active_live_locations' + expect(response['active_live_locations'].length).to be >= 1 + end + end end From 8c73c4973f431d3da80f9830b356063ca79fea58 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 26 May 2025 13:58:16 +0200 Subject: [PATCH 05/11] minor fixes --- lib/stream-chat/client.rb | 9 +++------ spec/client_spec.rb | 35 +++++++++++++++++++---------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index 2b4d570..9243a79 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -824,16 +824,13 @@ def get_active_live_locations(user_id) # @param [Float] longitude Optional longitude coordinate # @param [String] end_at Optional end time for the location sharing # @return [StreamChat::StreamResponse] - sig { params(user_id: String, created_by_device_id: String, message_id: String, latitude: T.nilable(Float), longitude: T.nilable(Float), end_at: T.nilable(String)).returns(StreamChat::StreamResponse) } - def update_location(user_id, created_by_device_id:, message_id:, latitude: nil, longitude: nil, end_at: nil) + sig { params(user_id: String, created_by_device_id: String, message_id: String, options: T.untyped).returns(StreamChat::StreamResponse) } + def update_location(user_id, created_by_device_id:, message_id:, **options) data = { created_by_device_id: created_by_device_id, message_id: message_id } - data[:latitude] = latitude if latitude - data[:longitude] = longitude if longitude - data[:end_at] = end_at if end_at - + data.merge!(options) if options put('users/location', data: data, params: { user_id: user_id }) end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index b2f6cba..886ffa3 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1038,17 +1038,19 @@ def loop_times(times) end it 'can create and update a location' do - location = { + location = { created_by_device_id: SecureRandom.uuid, latitude: 40.7128, longitude: -74.0060, end_at: (Time.now + 3600).iso8601 } - response = @channel.send_message({ - text: 'Location sharing message', - shared_location: location, - }, @location_test_user[:id]) + response = @channel.send_message( + { + text: 'Location sharing message', + shared_location: location + }, @location_test_user[:id] + ) expect(response['message']).to include 'shared_location' expect(response['message']['shared_location']['created_by_device_id']).to eq(location[:created_by_device_id]) @@ -1076,21 +1078,22 @@ def loop_times(times) longitude = -74.0060 end_at = (Time.now + 3600).iso8601 - response = @location_channel.send_message({ - text: 'Location sharing message', - shared_location: { - created_by_device_id: device_id, - latitude: latitude, - longitude: longitude, - end_at: end_at - } - }, @location_test_user[:id]) + response = @location_channel.send_message( + { + text: 'Location sharing message', + shared_location: { + created_by_device_id: device_id, + latitude: latitude, + longitude: longitude, + end_at: end_at + } + }, @location_test_user[:id] + ) response = @client.get_active_live_locations(@location_test_user[:id]) expect(response).to include 'active_live_locations' expect(response['active_live_locations']).to be_an(Array) expect(response['active_live_locations'].length).to be >= 1 - location = response['active_live_locations'].find { |loc| loc['created_by_device_id'] == device_id } expect(location).not_to be_nil expect(location['latitude']).to eq(latitude) @@ -1099,7 +1102,7 @@ def loop_times(times) end it 'should have active live locations on the channel' do - response = @channel.query() + response = @channel.query expect(response).to include 'active_live_locations' expect(response['active_live_locations'].length).to be >= 1 end From af6b9f1cc8dcff1341f4c01407bac1602992dd24 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 26 May 2025 14:06:38 +0200 Subject: [PATCH 06/11] lint --- spec/client_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 886ffa3..2a31c24 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1064,7 +1064,7 @@ def loop_times(times) message_id: response['message']['id'], latitude: new_latitude, longitude: location[:longitude], - end_at: location[:end_at], + end_at: location[:end_at] ) expect(response['created_by_device_id']).to eq(location[:created_by_device_id]) From 2448a2bfbdcd9cd0d004c62faf977ffdc9308a56 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 7 Jul 2025 08:53:20 +0200 Subject: [PATCH 07/11] feat(cha-651): add shared locations support --- spec/client_spec.rb | 86 ++------------------------------------------- 1 file changed, 2 insertions(+), 84 deletions(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 88a41ad..2054bc0 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1215,94 +1215,12 @@ def loop_times(times) expect(reminder).to include('channel_cid') end end - - describe 'live locations' do - before(:all) do - @location_test_user = { id: SecureRandom.uuid } - @client.upsert_users([@location_test_user]) - @location_channel = @client.channel('messaging', channel_id: SecureRandom.uuid) - @location_channel.create(@location_test_user[:id]) - @location_message = @location_channel.send_message({ text: 'Location sharing message' }, @location_test_user[:id]) - end - - after(:all) do - @location_channel.delete - @client.delete_user(@location_test_user[:id]) - end - - it 'can create and update a location' do - location = { - created_by_device_id: SecureRandom.uuid, - latitude: 40.7128, - longitude: -74.0060, - end_at: (Time.now + 3600).iso8601 - } - - response = @channel.send_message( - { - text: 'Location sharing message', - shared_location: location - }, @location_test_user[:id] - ) - - expect(response['message']).to include 'shared_location' - expect(response['message']['shared_location']['created_by_device_id']).to eq(location[:created_by_device_id]) - expect(response['message']['shared_location']['latitude']).to eq(location[:latitude]) - expect(response['message']['shared_location']['longitude']).to eq(location[:longitude]) - - new_latitude = location[:latitude] + 10 - response = @client.update_location( - response['message']['user']['id'], - created_by_device_id: location[:created_by_device_id], - message_id: response['message']['id'], - latitude: new_latitude, - longitude: location[:longitude], - end_at: location[:end_at] - ) - - expect(response['created_by_device_id']).to eq(location[:created_by_device_id]) - expect(response['latitude']).to eq(new_latitude) - expect(response['longitude']).to eq(location[:longitude]) - end - - it 'can get active live locations' do - device_id = SecureRandom.uuid - latitude = 40.7128 - longitude = -74.0060 - end_at = (Time.now + 3600).iso8601 - - response = @location_channel.send_message( - { - text: 'Location sharing message', - shared_location: { - created_by_device_id: device_id, - latitude: latitude, - longitude: longitude, - end_at: end_at - } - }, @location_test_user[:id] - ) - - response = @client.get_active_live_locations(@location_test_user[:id]) - expect(response).to include 'active_live_locations' - expect(response['active_live_locations']).to be_an(Array) - expect(response['active_live_locations'].length).to be >= 1 - location = response['active_live_locations'].find { |loc| loc['created_by_device_id'] == device_id } - expect(location).not_to be_nil - expect(location['latitude']).to eq(latitude) - expect(location['longitude']).to eq(longitude) - expect(DateTime.parse(location['end_at']).iso8601).to eq(end_at) - end - - it 'should have active live locations on the channel' do - response = @channel.query - expect(response).to include 'active_live_locations' - expect(response['active_live_locations'].length).to be >= 1 - end + end end describe 'live locations' do before(:all) do + @channel.update_partial({ config_overrides: { shared_locations: true } }) @location_test_user = { id: SecureRandom.uuid } @client.upsert_users([@location_test_user]) @location_channel = @client.channel('messaging', channel_id: SecureRandom.uuid) From b3a685ea0d0abc194d5e0fb9c1279bc64c8fd9a0 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 7 Jul 2025 08:59:18 +0200 Subject: [PATCH 08/11] feat(cha-651): add location sharing support --- lib/stream-chat/client.rb | 4 ++-- spec/client_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/stream-chat/client.rb b/lib/stream-chat/client.rb index 358df7d..97b6e49 100644 --- a/lib/stream-chat/client.rb +++ b/lib/stream-chat/client.rb @@ -832,7 +832,7 @@ def query_drafts(user_id, filter: nil, sort: nil, **options) # @return [StreamChat::StreamResponse] sig { params(user_id: String).returns(StreamChat::StreamResponse) } def get_active_live_locations(user_id) - get('users/locations', params: { user_id: user_id }) + get('users/live_locations', params: { user_id: user_id }) end # Update live location @@ -851,7 +851,7 @@ def update_location(user_id, created_by_device_id:, message_id:, **options) message_id: message_id } data.merge!(options) if options - put('users/location', data: data, params: { user_id: user_id }) + put('users/live_locations', data: data, params: { user_id: user_id }) end # Gets a comamnd. diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 2054bc0..ab28a23 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1220,11 +1220,11 @@ def loop_times(times) describe 'live locations' do before(:all) do - @channel.update_partial({ config_overrides: { shared_locations: true } }) @location_test_user = { id: SecureRandom.uuid } @client.upsert_users([@location_test_user]) @location_channel = @client.channel('messaging', channel_id: SecureRandom.uuid) @location_channel.create(@location_test_user[:id]) + @location_channel.update_partial({ config_overrides: { shared_locations: true } }) @location_message = @location_channel.send_message({ text: 'Location sharing message' }, @location_test_user[:id]) end From 9bc6b43ab94d454aa1dcca3ecb9bff35045a8709 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 7 Jul 2025 09:08:14 +0200 Subject: [PATCH 09/11] test(cha-651): fix unit test --- spec/client_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index ab28a23..71f0f2c 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1241,7 +1241,7 @@ def loop_times(times) end_at: (Time.now + 3600).iso8601 } - response = @channel.send_message( + response = @location_channel.send_message( { text: 'Location sharing message', shared_location: location @@ -1298,7 +1298,7 @@ def loop_times(times) end it 'should have active live locations on the channel' do - response = @channel.query + response = @location_channel.query expect(response).to include 'active_live_locations' expect(response['active_live_locations'].length).to be >= 1 end From 5be7c54d4299e11577e523f81f35e2c207af4c17 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 7 Jul 2025 09:11:44 +0200 Subject: [PATCH 10/11] fix(cha-651): fix unit tests --- spec/client_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 71f0f2c..45ec0c5 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -1215,7 +1215,7 @@ def loop_times(times) expect(reminder).to include('channel_cid') end end - end + end end describe 'live locations' do @@ -1242,7 +1242,7 @@ def loop_times(times) } response = @location_channel.send_message( - { + { text: 'Location sharing message', shared_location: location }, @location_test_user[:id] @@ -1274,7 +1274,7 @@ def loop_times(times) longitude = -74.0060 end_at = (Time.now + 3600).iso8601 - response = @location_channel.send_message( + @location_channel.send_message( { text: 'Location sharing message', shared_location: { From 8b4000afe3257075138be4073183fd0fbe70f996 Mon Sep 17 00:00:00 2001 From: Rafael Marinho Date: Mon, 7 Jul 2025 09:20:17 +0200 Subject: [PATCH 11/11] fix(cha-651): fix unit test --- spec/client_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/client_spec.rb b/spec/client_spec.rb index 45ec0c5..8377e6c 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -629,7 +629,7 @@ def loop_times(times) describe 'blocklist' do before(:all) do - @blocklist = "test_blocklist_#{SecureRandom.hex(8)}" + @blocklist = SecureRandom.uuid end it 'list available blocklists' do