Skip to content

Commit bbf666b

Browse files
fix: multiple ID encoding for get_activities
1 parent 50df8e7 commit bbf666b

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

lib/stream/activities.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ def get_activities(params = {})
5252
end
5353
end
5454
%i[enrich reactions].each { |k| params.delete(k) }
55+
56+
# Handle multiple IDs by joining with commas
57+
params[:ids] = params[:ids].join(',') if params[:ids]&.is_a?(Array)
5558

5659
signature = Stream::Signer.create_jwt_token('activities', '*', @api_secret, '*')
5760
make_request(:get, uri, signature, params)

spec/client_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,64 @@
139139
http_client = client.get_http_client
140140
expect(http_client.conn.options[:timeout]).to eq 5
141141
end
142+
143+
describe 'get_activities' do
144+
before do
145+
@client = Stream::Client.new('key', 'secret', 'app_id')
146+
@captured_requests = []
147+
148+
# Mock the HTTP client to capture requests
149+
allow_any_instance_of(Stream::StreamHTTPClient).to receive(:make_http_request) do |instance, method, relative_url, params, data, headers|
150+
@captured_requests << {
151+
method: method,
152+
url: relative_url,
153+
params: params,
154+
data: data,
155+
headers: headers
156+
}
157+
158+
# Return mock response
159+
{
160+
'results' => [],
161+
'duration' => '10ms'
162+
}
163+
end
164+
end
165+
166+
it 'should encode multiple activity IDs as comma-separated values' do
167+
ids = ['id1', 'id2', 'id3']
168+
169+
@client.get_activities(ids: ids)
170+
171+
expect(@captured_requests.length).to eq(1)
172+
request = @captured_requests.first
173+
174+
# Verify the IDs are joined with commas, not passed as an array
175+
expect(request[:params][:ids]).to eq('id1,id2,id3')
176+
expect(request[:params][:ids]).not_to be_a(Array)
177+
expect(request[:url]).to eq('/activities/')
178+
end
179+
180+
it 'should handle single ID without comma separation' do
181+
@client.get_activities(ids: ['single-id'])
182+
183+
expect(@captured_requests.length).to eq(1)
184+
request = @captured_requests.first
185+
186+
# Single ID should still be encoded correctly
187+
expect(request[:params][:ids]).to eq('single-id')
188+
expect(request[:params][:ids]).not_to be_a(Array)
189+
end
190+
191+
it 'should preserve other parameters when encoding IDs' do
192+
@client.get_activities(ids: ['id1', 'id2'], limit: 10, offset: 20)
193+
194+
expect(@captured_requests.length).to eq(1)
195+
request = @captured_requests.first
196+
197+
expect(request[:params][:ids]).to eq('id1,id2')
198+
expect(request[:params][:limit]).to eq(10)
199+
expect(request[:params][:offset]).to eq(20)
200+
end
201+
end
142202
end

spec/integration_spec.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,56 @@
675675
response = @client.get_activities(ids: [activity['id']], reactions: { own: true })
676676
expect(response['results'][0]['own_reactions']['like'][0]).to eq reaction
677677
end
678+
example 'get multiple activities by IDs' do
679+
# Create two different activities
680+
activity1 = @feed42.add_activity({
681+
actor: 'alice',
682+
verb: 'tweet',
683+
object: 'message1',
684+
foreign_id: "tweet-#{Time.now.to_i}-1"
685+
})
686+
687+
activity2 = @feed42.add_activity({
688+
actor: 'bob',
689+
verb: 'like',
690+
object: 'post1',
691+
foreign_id: "like-#{Time.now.to_i}-2"
692+
})
693+
694+
# Remove duration from comparison since it varies
695+
activity1.delete('duration')
696+
activity2.delete('duration')
697+
698+
# Wait a moment for activities to be indexed
699+
sleep(2)
700+
701+
# Test: Get both activities by their IDs in a single call
702+
response = @client.get_activities(
703+
ids: [activity1['id'], activity2['id']]
704+
)
705+
706+
expect(response).to include('duration', 'results')
707+
expect(response['results'].count).to be 2
708+
709+
# Verify both activities are returned
710+
returned_ids = response['results'].map { |a| a['id'] }
711+
expect(returned_ids).to include(activity1['id'])
712+
expect(returned_ids).to include(activity2['id'])
713+
714+
# Verify the returned activities match the original activities
715+
response['results'].each do |returned_activity|
716+
returned_activity.delete('duration')
717+
718+
if returned_activity['id'] == activity1['id']
719+
expect(returned_activity).to eq(activity1)
720+
elsif returned_activity['id'] == activity2['id']
721+
expect(returned_activity).to eq(activity2)
722+
else
723+
fail "Unexpected activity ID: #{returned_activity['id']}"
724+
end
725+
end
726+
end
727+
678728
example 'activity recent reaction enrichment' do
679729
activity = @feed42.add_activity({ actor: 'jim', verb: 'buy', object: 'wallet' })
680730
reaction = @client.reactions.add('dislike', activity['id'], 'jim')

0 commit comments

Comments
 (0)