spec/acceptance/realtime/connection_spec.rb in ably-0.1.6 vs spec/acceptance/realtime/connection_spec.rb in ably-0.2.0
- old
+ new
@@ -1,23 +1,47 @@
require 'spec_helper'
describe Ably::Realtime::Connection do
include RSpec::EventMachine
- [:msgpack, :json].each do |protocol|
+ let(:connection) { client.connection }
+
+ [:json, :msgpack].each do |protocol|
context "over #{protocol}" do
+ let(:default_options) do
+ { api_key: api_key, environment: environment, protocol: protocol }
+ end
+
let(:client) do
- Ably::Realtime::Client.new(api_key: api_key, environment: environment, protocol: protocol)
+ Ably::Realtime::Client.new(default_options)
end
- subject { client.connection }
+ context 'with API key' do
+ it 'connects automatically' do
+ run_reactor do
+ connection.on(:connected) do
+ expect(connection.state).to eq(:connected)
+ expect(client.auth.auth_params[:key_id]).to_not be_nil
+ expect(client.auth.auth_params[:access_token]).to be_nil
+ stop_reactor
+ end
+ end
+ end
+ end
- it 'connects automatically' do
- run_reactor do
- subject.on(:connected) do
- expect(subject.state).to eq(:connected)
- stop_reactor
+ context 'with client_id resulting in token auth' do
+ let(:default_options) do
+ { api_key: api_key, environment: environment, protocol: protocol, client_id: SecureRandom.hex, log_level: :debug }
+ end
+ it 'connects automatically' do
+ run_reactor do
+ connection.on(:connected) do
+ expect(connection.state).to eq(:connected)
+ expect(client.auth.auth_params[:access_token]).to_not be_nil
+ expect(client.auth.auth_params[:key_id]).to be_nil
+ stop_reactor
+ end
end
end
end
context 'initialization phases' do
@@ -30,52 +54,124 @@
stop_reactor
end
run_reactor do
phases.each do |phase|
- subject.on(phase) do
+ connection.on(phase) do
events_triggered << phase
test_expectation.call if events_triggered.length == phases.length
end
end
end
end
end
- skip '#closed disconnects and closes the connection once timeout is reached'
+ skip '#close disconnects, closes the connection immediately and changes the connection state to closed'
- specify '#closed disconnects and closes the connection gracefully' do
+ specify '#close(graceful: true) gracefully waits for the server to close the connection' do
run_reactor(8) do
- subject.close
- subject.on(:closed) do
- expect(subject.state).to eq(:closed)
+ connection.close
+ connection.on(:closed) do
+ expect(connection.state).to eq(:closed)
stop_reactor
end
end
end
- it 'receives a heart beat' do
- run_reactor(20) do
- subject.on(:connected) do
- subject.__incoming_protocol_msgbus__.subscribe(:message) do |protocol_message|
- if protocol_message.action == :heartbeat
- expect(protocol_message.action).to eq(:heartbeat)
+ it 'echoes a heart beat with #ping' do
+ run_reactor do
+ connection.on(:connected) do
+ connection.ping do |time_elapsed|
+ expect(time_elapsed).to be > 0
+ stop_reactor
+ end
+ end
+ end
+ end
+
+ skip 'connects, closes gracefully and reconnects on #connect'
+
+ it 'connects, closes the connection, and then reconnects with a new connection ID' do
+ run_reactor(15) do
+ connection.connect do
+ connection_id = connection.id
+ connection.close do
+ connection.connect do
+ expect(connection.id).to_not eql(connection_id)
stop_reactor
end
end
end
end
end
- skip 'connects, closes gracefully and reconnects on #connect'
+ context 'failures' do
+ context 'with invalid app part of the key' do
+ let(:missing_key) { 'not_an_app.invalid_key_id:invalid_key_value' }
+ let(:client) do
+ Ably::Realtime::Client.new(default_options.merge(api_key: missing_key))
+ end
- it 'connects, closes then connection when timeout is reaached and reconnects on #connect' do
+ it 'enters the failed state and returns a not found error' do
+ run_reactor do
+ connection.on(:failed) do |error|
+ expect(connection.state).to eq(:failed)
+ expect(error.status).to eq(404)
+ stop_reactor
+ end
+ end
+ end
+ end
+
+ context 'with invalid key ID part of the key' do
+ let(:invalid_key) { "#{app_id}.invalid_key_id:invalid_key_value" }
+ let(:client) do
+ Ably::Realtime::Client.new(default_options.merge(api_key: invalid_key))
+ end
+
+ it 'enters the failed state and returns an authorization error' do
+ run_reactor do
+ connection.on(:failed) do |error|
+ expect(connection.state).to eq(:failed)
+ expect(error.status).to eq(401)
+ stop_reactor
+ end
+ end
+ end
+ end
+
+ context 'with invalid WebSocket host' do
+ let(:client) do
+ Ably::Realtime::Client.new(default_options.merge(ws_host: 'non.existent.host'))
+ end
+
+ it 'enters the failed state and returns an authorization error' do
+ run_reactor do
+ connection.on(:failed) do |error|
+ expect(connection.state).to eq(:failed)
+ expect(error.code).to eq(80000)
+ expect(error.status).to be_nil
+ stop_reactor
+ end
+ end
+ end
+ end
+ end
+
+ it 'opens many connections simultaneously' do
run_reactor(15) do
- subject.connect do
- connection_id = subject.id
- subject.close do
- subject.connect do
- expect(subject.id).to_not eql(connection_id)
+ count, connected_ids = 25, []
+
+ clients = count.times.map do
+ Ably::Realtime::Client.new(default_options)
+ end
+
+ clients.each do |client|
+ client.connection.on(:connected) do
+ connected_ids << client.connection.id
+
+ if connected_ids.count == 25
+ expect(connected_ids.uniq.count).to eql(25)
stop_reactor
end
end
end
end