spec/acceptance/realtime/connection_failures_spec.rb in ably-0.7.0 vs spec/acceptance/realtime/connection_failures_spec.rb in ably-0.7.1

- old
+ new

@@ -190,11 +190,11 @@ end it 'is reset to nil when :connected' do connection.once(:disconnected) do |error| # stub the host so that the connection connects - allow(connection).to receive(:host).and_return(TestApp.instance.host) + allow(connection).to receive(:determine_host).and_yield(TestApp.instance.realtime_host) connection.once(:connected) do expect(connection.error_reason).to be_nil stop_reactor end end @@ -391,10 +391,63 @@ end end end end end + + context 'when failing to resume because the connection_key is not or no longer valid' do + def kill_connection_transport_and_prevent_valid_resume + connection.transport.close_connection_after_writing + connection.update_connection_id_and_key '0123456789abcdef', '0123456789abcdef' # force the resume connection key to be invalid + end + + it 'updates the connection_id and connection_key' do + connection.once(:connected) do + previous_connection_id = connection.id + previous_connection_key = connection.key + + connection.once(:connected) do + expect(connection.key).to_not eql(previous_connection_key) + expect(connection.id).to_not eql(previous_connection_id) + stop_reactor + end + + kill_connection_transport_and_prevent_valid_resume + end + end + + it 'detaches all channels' do + channel_count = 10 + channels = channel_count.times.map { |index| client.channel("channel-#{index}") } + when_all(*channels.map(&:attach)) do + detached_channels = [] + channels.each do |channel| + channel.on(:detached) do + detached_channels << channel + next unless detached_channels.count == channel_count + expect(detached_channels.count).to eql(channel_count) + stop_reactor + end + end + + kill_connection_transport_and_prevent_valid_resume + end + end + + it 'emits an error on the channel and sets the error reason' do + client.channel(random_str).attach do |channel| + channel.on(:error) do |error| + expect(error.message).to match(/Invalid connection key/i) + expect(error.code).to eql(80008) + expect(channel.error_reason).to eql(error) + stop_reactor + end + + kill_connection_transport_and_prevent_valid_resume + end + end + end end describe 'fallback host feature' do let(:retry_every_for_tests) { 0.1 } let(:max_time_in_state_for_tests) { 0.3 } @@ -454,44 +507,67 @@ let(:expected_host) { Ably::Realtime::Client::DOMAIN } let(:client_options) { default_options.merge(environment: nil, log_level: :none) } let(:fallback_hosts_used) { Array.new } - it 'uses a fallback host on every subsequent disconnected attempt until suspended' do - request = 0 - expect(EventMachine).to receive(:connect).exactly(retry_count_for_one_state).times do |host| - if request == 0 + context 'when the Internet is down' do + before do + allow(connection).to receive(:internet_up?).and_yield(false) + end + + it 'never uses a fallback host' do + expect(EventMachine).to receive(:connect).exactly(retry_count_for_all_states).times do |host| expect(host).to eql(expected_host) - else - expect(custom_hosts).to include(host) - fallback_hosts_used << host + raise EventMachine::ConnectionError end - request += 1 - raise EventMachine::ConnectionError - end - connection.on(:suspended) do - expect(fallback_hosts_used.uniq).to match_array(custom_hosts) - stop_reactor + connection.on(:failed) do + stop_reactor + end end end - it 'uses the primary host when suspended, and a fallback host on every subsequent suspended attempt' do - request = 0 - expect(EventMachine).to receive(:connect).exactly(retry_count_for_all_states).times do |host| - if request == 0 || request == expected_retry_attempts + 1 - expect(host).to eql(expected_host) - else - expect(custom_hosts).to include(host) - fallback_hosts_used << host + context 'when the Internet is up' do + before do + allow(connection).to receive(:internet_up?).and_yield(true) + end + + it 'uses a fallback host on every subsequent disconnected attempt until suspended' do + request = 0 + expect(EventMachine).to receive(:connect).exactly(retry_count_for_one_state).times do |host| + if request == 0 + expect(host).to eql(expected_host) + else + expect(custom_hosts).to include(host) + fallback_hosts_used << host + end + request += 1 + raise EventMachine::ConnectionError end - request += 1 - raise EventMachine::ConnectionError + + connection.on(:suspended) do + expect(fallback_hosts_used.uniq).to match_array(custom_hosts) + stop_reactor + end end - connection.on(:failed) do - expect(fallback_hosts_used.uniq).to match_array(custom_hosts) - stop_reactor + it 'uses the primary host when suspended, and a fallback host on every subsequent suspended attempt' do + request = 0 + expect(EventMachine).to receive(:connect).exactly(retry_count_for_all_states).times do |host| + if request == 0 || request == expected_retry_attempts + 1 + expect(host).to eql(expected_host) + else + expect(custom_hosts).to include(host) + fallback_hosts_used << host + end + request += 1 + raise EventMachine::ConnectionError + end + + connection.on(:failed) do + expect(fallback_hosts_used.uniq).to match_array(custom_hosts) + stop_reactor + end end end end end end