lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb in ably-rest-0.8.5 vs lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb in ably-rest-0.8.6
- old
+ new
@@ -502,59 +502,147 @@
end
end
end
end
+ context 'nil attributes' do
+ context 'when name is nil' do
+ let(:data) { random_str }
+
+ it 'publishes the message without a name attribute in the payload' do
+ published = false
+ channel.publish(nil, data) do
+ published = true
+ end
+
+ channel.subscribe do |message|
+ expect(message.name).to be_nil
+ channel.history do |page|
+ expect(page.items.first.name).to be_nil
+ expect(page.items.first.data).to eql(data)
+ EM.add_timer(0.5) do
+ expect(published).to eql(true)
+ stop_reactor
+ end
+ end
+ end
+ end
+ end
+
+ context 'when data is nil' do
+ let(:name) { random_str }
+
+ it 'publishes the message without a data attribute in the payload' do
+ published = false
+ channel.publish(name, nil) do
+ published = true
+ end
+
+ channel.subscribe do |message|
+ expect(message.data).to be_nil
+ channel.history do |page|
+ expect(page.items.first.name).to eql(name)
+ expect(page.items.first.data).to be_nil
+ EM.add_timer(0.5) do
+ expect(published).to eql(true)
+ stop_reactor
+ end
+ end
+ end
+ end
+ end
+
+ context 'with neither name or data attributes' do
+ let(:name) { random_str }
+
+ it 'publishes the message without any attributes in the payload' do
+ channel.publish(nil) do
+ channel.history do |page|
+ expect(page.items.first.name).to be_nil
+ expect(page.items.first.data).to be_nil
+ stop_reactor
+ end
+ end
+ end
+ end
+ end
+
context 'with two invalid message out of 12' do
- let(:client_options) { default_options.merge(client_id: 'valid') }
+ let(:rest_client) { Ably::Rest::Client.new(default_options.merge(client_id: 'valid')) }
+
let(:invalid_messages) do
2.times.map do |index|
Ably::Models::Message(name: index.to_s, data: { "index" => index + 10 }, client_id: 'prohibited')
end
end
- it 'calls the errback once' do
- skip 'Waiting for issue #256 to be resolved'
- channel.publish(messages + invalid_messages).tap do |deferrable|
- deferrable.callback do
- raise 'Publish should have failed'
- end
+ context 'before client_id is known (validated)' do
+ let(:client_options) { default_options.merge(token: rest_client.auth.request_token.token, log_level: :error) }
- deferrable.errback do |error, message|
- # TODO: Review whether we should fail once or multiple times
- channel.history do |page|
- expect(page.items.count).to eql(0)
- stop_reactor
+ it 'calls the errback once' do
+ channel.publish(messages + invalid_messages).tap do |deferrable|
+ deferrable.callback do
+ raise 'Publish should have failed'
end
+
+ deferrable.errback do |error, message|
+ # TODO: Review whether we should fail once or multiple times
+ channel.history do |page|
+ expect(page.items.count).to eql(0)
+ stop_reactor
+ end
+ end
end
end
end
+
+ context 'when client_id is known (validated)' do
+ let(:client_options) { default_options.merge(client_id: 'valid') }
+
+ it 'raises an exception' do
+ expect { channel.publish(messages + invalid_messages) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
end
context 'only invalid messages' do
- let(:client_options) { default_options.merge(client_id: 'valid') }
+ let(:rest_client) { Ably::Rest::Client.new(default_options.merge(client_id: 'valid')) }
+
let(:invalid_messages) do
10.times.map do |index|
Ably::Models::Message(name: index.to_s, data: { "index" => index + 10 }, client_id: 'prohibited')
end
end
- it 'calls the errback once' do
- skip 'Waiting for issue #256 to be resolved'
- channel.publish(invalid_messages).tap do |deferrable|
- deferrable.callback do
- raise 'Publish should have failed'
- end
+ context 'before client_id is known (validated)' do
+ let(:client_options) { default_options.merge(token: rest_client.auth.request_token.token, log_level: :error) }
- deferrable.errback do |error, message|
- channel.history do |page|
- expect(page.items.count).to eql(0)
- stop_reactor
+ it 'calls the errback once' do
+ channel.publish(invalid_messages).tap do |deferrable|
+ deferrable.callback do
+ raise 'Publish should have failed'
end
+
+ deferrable.errback do |error, message|
+ channel.history do |page|
+ expect(page.items.count).to eql(0)
+ stop_reactor
+ end
+ end
end
end
end
+
+ context 'when client_id is known (validated)' do
+ let(:client_options) { default_options.merge(client_id: 'valid') }
+
+ it 'raises an exception' do
+ expect { channel.publish(invalid_messages) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
end
end
context 'with many many messages and many connections simultaneously' do
let(:connection_count) { 5 }
@@ -579,10 +667,212 @@
end
end
end
end
end
+
+ context 'identified clients' do
+ context 'when authenticated with a wildcard client_id' do
+ let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: '*') }
+ let(:client_options) { default_options.merge(key: nil, token: token) }
+ let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
+ let(:channel) { client.channels.get(channel_name) }
+
+ context 'with a valid client_id in the message' do
+ it 'succeeds' do
+ channel.publish([name: 'event', client_id: 'validClient']).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('validClient')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+
+ context 'with a wildcard client_id in the message' do
+ it 'throws an exception' do
+ expect { channel.publish([name: 'event', client_id: '*']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+
+ context 'with an empty client_id in the message' do
+ it 'succeeds and publishes without a client_id' do
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to be_nil
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+
+ context 'when authenticated with a Token string with an implicit client_id' do
+ let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: 'valid').token }
+ let(:client_options) { default_options.merge(key: nil, token: token) }
+ let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
+ let(:channel) { client.channels.get(channel_name) }
+
+ context 'before the client is CONNECTED and the client\'s identity has been obtained' do
+ context 'with a valid client_id in the message' do
+ it 'succeeds' do
+ channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+
+ context 'with an invalid client_id in the message' do
+ let(:client_options) { default_options.merge(key: nil, token: token, log_level: :error) }
+ it 'succeeds in the client library but then fails when delivered to Ably' do
+ channel.publish([name: 'event', client_id: 'invalid']).tap do |deferrable|
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ channel.subscribe('event') do |message|
+ raise 'Message should not have been published'
+ end
+ end
+ end
+
+ context 'with an empty client_id in the message' do
+ it 'succeeds and publishes with an implicit client_id' do
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+
+ context 'after the client is CONNECTED and the client\'s identity is known' do
+ context 'with a valid client_id in the message' do
+ it 'succeeds' do
+ client.connection.once(:connected) do
+ channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+
+ context 'with an invalid client_id in the message' do
+ it 'throws an exception' do
+ client.connection.once(:connected) do
+ expect { channel.publish([name: 'event', client_id: 'invalid']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+ end
+
+ context 'with an empty client_id in the message' do
+ it 'succeeds and publishes with an implicit client_id' do
+ client.connection.once(:connected) do
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+ end
+ end
+
+ context 'when authenticated with a valid client_id' do
+ let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: 'valid') }
+ let(:client_options) { default_options.merge(key: nil, token: token) }
+ let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
+ let(:channel) { client.channels.get(channel_name) }
+
+ context 'with a valid client_id' do
+ it 'succeeds' do
+ channel.publish([name: 'event', client_id: 'valid']).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+
+ context 'with a wildcard client_id in the message' do
+ it 'throws an exception' do
+ expect { channel.publish([name: 'event', client_id: '*']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+
+ context 'with an invalid client_id in the message' do
+ it 'throws an exception' do
+ expect { channel.publish([name: 'event', client_id: 'invalid']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+
+ context 'with an empty client_id in the message' do
+ it 'succeeds and publishes with an implicit client_id' do
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to eql('valid')
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+
+ context 'when anonymous and no client_id' do
+ let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: nil) }
+ let(:client_options) { default_options.merge(key: nil, token: token) }
+ let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
+ let(:channel) { client.channels.get(channel_name) }
+
+ context 'with a client_id in the message' do
+ it 'throws an exception' do
+ expect { channel.publish([name: 'event', client_id: 'invalid']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+
+ context 'with a wildcard client_id in the message' do
+ it 'throws an exception' do
+ expect { channel.publish([name: 'event', client_id: '*']) }.to raise_error Ably::Exceptions::IncompatibleClientId
+ stop_reactor
+ end
+ end
+
+ context 'with an empty client_id in the message' do
+ it 'succeeds and publishes with an implicit client_id' do
+ channel.publish([name: 'event', client_id: nil]).tap do |deferrable|
+ deferrable.errback { raise 'Should have succeeded' }
+ end
+ channel.subscribe('event') do |message|
+ expect(message.client_id).to be_nil
+ EM.add_timer(0.5) { stop_reactor }
+ end
+ end
+ end
+ end
+ end
end
describe '#subscribe' do
context 'with an event argument' do
it 'subscribes for a single event' do
@@ -879,11 +1169,11 @@
end
end
context 'a :failed channel' do
let(:original_error) { RuntimeError.new }
- let(:client_options) { default_options.merge(log_level: :fatal) }
+ let(:client_options) { default_options.merge(log_level: :fatal) }
it 'remains in the :failed state and retains the error_reason' do
channel.attach do
channel.once(:error) do
channel.on(:detached) { raise 'Detached state should not have been reached' }
@@ -902,9 +1192,11 @@
end
end
end
context 'a channel ATTACH request when connection SUSPENDED' do
+ let(:client_options) { default_options.merge(log_level: :fatal) }
+
it 'raises an exception' do
client.connect do
client.connection.once(:suspended) do
expect { channel.attach }.to raise_error Ably::Exceptions::InvalidStateChange
stop_reactor