Skip to content

[CHA-1578] add feature parity tests#35

Open
mogita wants to merge 17 commits intomasterfrom
cha-1578_openapi-refactor-codegen
Open

[CHA-1578] add feature parity tests#35
mogita wants to merge 17 commits intomasterfrom
cha-1578_openapi-refactor-codegen

Conversation

@mogita
Copy link
Collaborator

@mogita mogita commented Feb 25, 2026

Adding test cases to cover feature parity with https://github.com/GetStream/stream-chat-ruby

mogita and others added 7 commits February 25, 2026 11:21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 25, 2026 12:48
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive integration tests to achieve feature parity with the stream-chat-ruby SDK. The PR introduces eight new test specification files covering video, chat users, reactions, polls, moderation, miscellaneous features, messages, and channels, along with a shared test helpers module.

Changes:

  • Added chat_test_helpers.rb module providing shared utilities for test setup, user/channel creation, and resource cleanup
  • Added comprehensive integration tests for video operations (call types, calls, external storage, recording/transcription)
  • Added integration tests for chat functionality covering users, channels, messages, reactions, polls, and moderation features

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
spec/integration/chat_test_helpers.rb Shared helper module for integration tests with setup/teardown and common operations
spec/integration/video_integration_spec.rb Tests for video call types, calls, permissions, blocking, muting, external storage, and deletion
spec/integration/chat_user_integration_spec.rb Tests for user CRUD, blocking, deactivation, privacy settings, teams, and custom data
spec/integration/chat_reaction_integration_spec.rb Tests for sending, retrieving, deleting, and enforcing unique reactions
spec/integration/chat_polls_integration_spec.rb Tests for poll creation, querying, voting, and verification
spec/integration/chat_moderation_integration_spec.rb Tests for banning, muting, and flagging users and messages
spec/integration/chat_misc_integration_spec.rb Tests for devices, blocklists, commands, channel types, permissions, roles, threads, reminders, and exports
spec/integration/chat_message_integration_spec.rb Tests for message CRUD, pinning, translation, threads, search, pending messages, and history
spec/integration/chat_channel_integration_spec.rb Tests for channel CRUD, members, roles, hiding/showing, truncation, freezing, muting, file uploads

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 150 to 156
@client.common.create_block_list(
GetStream::Generated::Models::CreateBlockListRequest.new(
name: del_name,
words: %w[word1]
)
)
@client.common.delete_block_list(del_name)
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test creates a separate resource (del_name) just to test deletion, which is good for isolation. However, this resource is never added to @created_blocklist_names before deletion, so if the deletion fails, it won't be cleaned up in the after(:all) block. Consider adding it to the tracking array before attempting deletion, or wrapping in a begin-ensure block.

Suggested change
@client.common.create_block_list(
GetStream::Generated::Models::CreateBlockListRequest.new(
name: del_name,
words: %w[word1]
)
)
@client.common.delete_block_list(del_name)
created = false
begin
@client.common.create_block_list(
GetStream::Generated::Models::CreateBlockListRequest.new(
name: del_name,
words: %w[word1]
)
)
created = true
@client.common.delete_block_list(del_name)
rescue StandardError
@created_blocklist_names << del_name if created
raise
end

Copilot uses AI. Check for mistakes.
Comment on lines 24 to 33
@created_call_ids&.each do |call_type, call_id|
@client.make_request(
:post,
"/api/v2/video/call/#{call_type}/#{call_id}/delete",
body: {}
)
rescue StandardError => e
puts "Warning: Failed to delete call #{call_type}:#{call_id}: #{e.message}"
end

Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cleanup logic in the after(:all) block uses @created_call_ids&.each with a rescue block that only prints a warning but doesn't track failures. If the API call to delete a call fails consistently (e.g., due to permissions or a missing call), this could lead to orphaned resources and test pollution. Consider logging failures to a list and raising an error after all cleanup attempts, or implementing exponential backoff retry logic similar to other cleanup operations in the codebase.

Suggested change
@created_call_ids&.each do |call_type, call_id|
@client.make_request(
:post,
"/api/v2/video/call/#{call_type}/#{call_id}/delete",
body: {}
)
rescue StandardError => e
puts "Warning: Failed to delete call #{call_type}:#{call_id}: #{e.message}"
end
failed_call_deletions = []
@created_call_ids&.each do |call_type, call_id|
attempts = 0
begin
attempts += 1
@client.make_request(
:post,
"/api/v2/video/call/#{call_type}/#{call_id}/delete",
body: {}
)
rescue StandardError => e
if attempts < 3
sleep(2**(attempts - 1))
retry
else
puts "Warning: Failed to delete call #{call_type}:#{call_id} after #{attempts} attempts: #{e.message}"
failed_call_deletions << [call_type, call_id, e]
end
end
end
unless failed_call_deletions.empty?
failed_descriptions = failed_call_deletions.map { |type, id, error| "#{type}:#{id} (#{error.class}: #{error.message})" }
raise "Failed to delete calls during cleanup: #{failed_descriptions.join(', ')}"
end

Copilot uses AI. Check for mistakes.
Comment on lines 122 to 127
break
rescue GetStreamRuby::APIError => e
raise if i == 2

sleep(5)
end
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error variable e is captured but never used in the rescue block. Either remove the unused variable by using rescue GetStreamRuby::APIError without capturing it, or use the error for logging/debugging purposes before re-raising on the final attempt.

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +98
resp = query_users_with_filter({ 'id' => uid })
user = resp.users.first
user_h = user.to_h
# Custom fields may be at top-level or under 'custom'
country = user_h['custom'].is_a?(Hash) ? user_h['custom']['country'] : user_h['country']
expect(country).to eq('NL')

Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper method converts responses to hashes and uses dig to extract nested values, but doesn't handle cases where intermediate keys might be missing. While dig returns nil for missing keys (which is safe), the test expectations immediately follow. Consider adding nil checks or more descriptive error messages if the response structure is unexpectedly missing required fields.

Copilot uses AI. Check for mistakes.
Comment on lines 213 to 225
# Verify unblocked (with retry for eventual consistency)
unblocked = false
6.times do |i|
sleep(2)
resp2 = get_call('default', call_id)
call_h2 = resp2.to_h
blocked_ids2 = call_h2.dig('call', 'blocked_user_ids') || []
unless blocked_ids2.include?(@user2)
unblocked = true
break
end
end
expect(unblocked).to be(true), 'Expected user to be unblocked after unblock call'
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The polling loop for verifying the unblock operation retries 6 times with 2-second sleeps (total 12 seconds). This hardcoded polling logic is duplicated in multiple tests. Consider extracting a reusable wait_until helper that accepts a condition lambda and timeout parameters to reduce code duplication and make timeouts more consistent across tests.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants