ably-rest 1.0.5 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +6 -3
- data/CHANGELOG.md +1 -1
- data/LICENSE +1 -1
- data/README.md +26 -7
- data/SPEC.md +2003 -1605
- data/ably-rest.gemspec +4 -2
- data/lib/submodules/ably-ruby/.editorconfig +14 -0
- data/lib/submodules/ably-ruby/.travis.yml +10 -8
- data/lib/submodules/ably-ruby/CHANGELOG.md +97 -1
- data/lib/submodules/ably-ruby/LICENSE +1 -3
- data/lib/submodules/ably-ruby/README.md +12 -7
- data/lib/submodules/ably-ruby/Rakefile +32 -0
- data/lib/submodules/ably-ruby/SPEC.md +1277 -835
- data/lib/submodules/ably-ruby/ably.gemspec +17 -11
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +34 -8
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +10 -4
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +8 -2
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +87 -0
- data/lib/submodules/ably-ruby/lib/ably/models/device_push_details.rb +86 -0
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +23 -2
- data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +12 -12
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +6 -4
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +6 -4
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +32 -2
- data/lib/submodules/ably-ruby/lib/ably/models/push_channel_subscription.rb +89 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/event_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +15 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/safe_deferrable.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/safe_yield.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +5 -5
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +27 -105
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +4 -8
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +74 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/push_channel.rb +62 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +91 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +9 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +45 -26
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +25 -9
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +7 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +9 -9
- data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +40 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/admin.rb +61 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/submodules/ably-ruby/lib/ably/rest.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +54 -18
- data/lib/submodules/ably-ruby/lib/ably/rest/channel/push_channel.rb +62 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +171 -41
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +42 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +54 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/device_registrations.rb +103 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +7 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +253 -49
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +33 -21
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +180 -62
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +155 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +293 -13
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +142 -39
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +38 -36
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +12 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +207 -173
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +736 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +27 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +62 -51
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +79 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +6 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +318 -74
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +158 -6
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +952 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +25 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/run_parallel_tests +33 -0
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +1 -9
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +3 -1
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +9 -5
- data/lib/submodules/ably-ruby/spec/support/event_emitter_helper.rb +31 -0
- data/lib/submodules/ably-ruby/spec/support/event_machine_helper.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +2 -2
- data/lib/submodules/ably-ruby/spec/support/test_logger_helper.rb +42 -0
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +11 -12
- data/lib/submodules/ably-ruby/spec/unit/models/device_details_spec.rb +102 -0
- data/lib/submodules/ably-ruby/spec/unit/models/device_push_details_spec.rb +101 -0
- data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +51 -3
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +17 -2
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/push_channel_subscription_spec.rb +86 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +3 -3
- data/lib/submodules/ably-ruby/spec/unit/modules/state_emitter_spec.rb +10 -10
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +13 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/unit/realtime/presence_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/push_channel_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +30 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +30 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/push_channel_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/util/pub_sub_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- metadata +51 -10
@@ -45,7 +45,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
45
45
|
connection.on(:failed) do |connection_state_change|
|
46
46
|
error = connection_state_change.reason
|
47
47
|
expect(connection.state).to eq(:failed)
|
48
|
-
# TODO: Check error type is a
|
48
|
+
# TODO: Check error type is a TokenNotFound exception
|
49
49
|
expect(error.status).to eq(401)
|
50
50
|
expect(error.code).to eq(40400) # not found
|
51
51
|
stop_reactor
|
@@ -110,6 +110,72 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
|
+
|
114
|
+
context 'request fails due to slow response and subsequent timeout', :webmock, em_timeout: (Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5) * 2 do
|
115
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
116
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
117
|
+
|
118
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
119
|
+
before do
|
120
|
+
stub_request(:get, auth_url).
|
121
|
+
to_return do |request|
|
122
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5
|
123
|
+
{ status: [500, "Internal Server Error"] }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
128
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
129
|
+
|
130
|
+
connection.once(:connected) { raise "Connection can never move to connected because of auth failures" }
|
131
|
+
|
132
|
+
connection.on do |connection_state|
|
133
|
+
states[connection_state.current.to_sym] << Time.now
|
134
|
+
if states[:disconnected].count == 2 && connection_state.current == :disconnected
|
135
|
+
expect(connection.error_reason).to be_a(Ably::Exceptions::ConnectionError)
|
136
|
+
expect(connection.error_reason.message).to match(/auth_url/)
|
137
|
+
EventMachine.add_timer(2) do
|
138
|
+
expect(states.keys).to include(:connecting, :disconnected)
|
139
|
+
expect(states[:connecting].count).to eql(2)
|
140
|
+
expect(states[:connected].count).to eql(0)
|
141
|
+
stop_reactor
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'request fails once due to slow response but succeeds the second time' do
|
149
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
150
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
151
|
+
|
152
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
153
|
+
before do
|
154
|
+
token_response = Ably::Rest::Client.new(default_options).auth.request_token
|
155
|
+
WebMock.enable!
|
156
|
+
|
157
|
+
stub_request(:get, auth_url).
|
158
|
+
to_return do |request|
|
159
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout)
|
160
|
+
{ status: [500, "Internal Server Error"] }
|
161
|
+
end.then.
|
162
|
+
to_return(:status => 201, :body => token_response.to_json, :headers => { 'Content-Type' => 'application/json' })
|
163
|
+
end
|
164
|
+
|
165
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
166
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
167
|
+
|
168
|
+
connection.once(:connected) do
|
169
|
+
expect(states[:disconnected].count).to eql(1)
|
170
|
+
expect(states[:connecting].count).to eql(2)
|
171
|
+
stop_reactor
|
172
|
+
end
|
173
|
+
|
174
|
+
connection.on do |connection_state|
|
175
|
+
states[connection_state.current.to_sym] << Time.now
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
113
179
|
end
|
114
180
|
|
115
181
|
context 'existing CONNECTED connection' do
|
@@ -143,7 +209,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
143
209
|
context 'with auth_callback' do
|
144
210
|
context 'opening a new connection' do
|
145
211
|
context 'when callback fails due to an exception' do
|
146
|
-
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_callback:
|
212
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_callback: lambda { |token_params| raise "Cannot issue token" }, log_level: :fatal) }
|
147
213
|
|
148
214
|
it 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
149
215
|
states = Hash.new { |hash, key| hash[key] = [] }
|
@@ -174,7 +240,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
174
240
|
use_token_auth: true,
|
175
241
|
log_level: :fatal)
|
176
242
|
}
|
177
|
-
let(:auth_options) { { auth_callback:
|
243
|
+
let(:auth_options) { { auth_callback: lambda { |token_params| sleep 10 }, } }
|
178
244
|
|
179
245
|
it 'the authorization request fails as configured in the realtime_request_timeout (#RSA4c, #RSA4c1, #RSA4c3)' do
|
180
246
|
connection.once(:connected) do
|
@@ -425,7 +491,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
425
491
|
let(:client_options) do
|
426
492
|
default_options.merge(
|
427
493
|
log_level: :none,
|
428
|
-
realtime_request_timeout: timeout
|
494
|
+
realtime_request_timeout: timeout,
|
429
495
|
)
|
430
496
|
end
|
431
497
|
|
@@ -514,6 +580,216 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
514
580
|
end
|
515
581
|
end
|
516
582
|
|
583
|
+
context 'connection state freshness is monitored' do
|
584
|
+
it 'resumes connections when disconnected within the connection_state_ttl period (#RTN15g)' do
|
585
|
+
connection.once(:connected) do
|
586
|
+
connection_id = connection.id
|
587
|
+
reconnected_with_resume = false
|
588
|
+
|
589
|
+
# Make sure the next connect has the resume param
|
590
|
+
allow(EventMachine).to receive(:connect).and_wrap_original do |original, *args, &block|
|
591
|
+
url = args[4]
|
592
|
+
uri = URI.parse(url)
|
593
|
+
expect(CGI::parse(uri.query)['resume'][0]).to_not be_empty
|
594
|
+
reconnected_with_resume = true
|
595
|
+
original.call(*args, &block)
|
596
|
+
end
|
597
|
+
|
598
|
+
connection.once(:disconnected) do
|
599
|
+
disconnected_at = Time.now
|
600
|
+
|
601
|
+
connection.once(:connecting) do
|
602
|
+
expect(Time.now.to_f - disconnected_at.to_f).to be < connection.connection_state_ttl
|
603
|
+
connection.once(:connected) do |state_change|
|
604
|
+
expect(connection.id).to eql(connection_id)
|
605
|
+
expect(reconnected_with_resume).to be_truthy
|
606
|
+
stop_reactor
|
607
|
+
end
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
connection.transport.unbind
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
context 'when connection_state_ttl period has passed since being disconnected' do
|
616
|
+
let(:client_options) do
|
617
|
+
default_options.merge(
|
618
|
+
disconnected_retry_timeout: 4,
|
619
|
+
suspended_retry_timeout: 8,
|
620
|
+
max_connection_state_ttl: 2,
|
621
|
+
)
|
622
|
+
end
|
623
|
+
|
624
|
+
it 'clears the local connection state and uses a new connection when the connection_state_ttl period has passed (#RTN15g)' do
|
625
|
+
connection.once(:connected) do
|
626
|
+
connection_id = connection.id
|
627
|
+
resumed_with_clean_connection = false
|
628
|
+
|
629
|
+
connection.once(:disconnected) do
|
630
|
+
disconnected_at = Time.now
|
631
|
+
|
632
|
+
connection.once(:connecting) do
|
633
|
+
connection.once(:disconnected) do
|
634
|
+
# Make sure the next connect does not have the resume param
|
635
|
+
allow(EventMachine).to receive(:connect).and_wrap_original do |original, *args, &block|
|
636
|
+
url = args[4]
|
637
|
+
uri = URI.parse(url)
|
638
|
+
expect(CGI::parse(uri.query)['resume']).to be_empty
|
639
|
+
resumed_with_clean_connection = true
|
640
|
+
original.call(*args, &block)
|
641
|
+
end
|
642
|
+
|
643
|
+
allow(connection.details).to receive(:max_idle_interval).and_return(0)
|
644
|
+
connection.__incoming_protocol_msgbus__.plugin_listeners
|
645
|
+
|
646
|
+
connection.once(:connecting) do
|
647
|
+
expect(Time.now.to_f - disconnected_at.to_f).to be > connection.connection_state_ttl
|
648
|
+
connection.once(:connected) do |state_change|
|
649
|
+
expect(connection.id).to_not eql(connection_id)
|
650
|
+
expect(resumed_with_clean_connection).to be_truthy
|
651
|
+
stop_reactor
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
# Disconnect the transport and trigger a new disconnected state
|
657
|
+
wait_until(lambda { connection.transport }) do
|
658
|
+
connection.transport.unbind
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
connection.__incoming_protocol_msgbus__.unplug_listeners
|
663
|
+
end
|
664
|
+
|
665
|
+
connection.transport.unbind
|
666
|
+
end
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
context 'when connection_state_ttl period has passed since last activity on the connection' do
|
671
|
+
let(:client_options) do
|
672
|
+
default_options.merge(
|
673
|
+
max_connection_state_ttl: 2,
|
674
|
+
)
|
675
|
+
end
|
676
|
+
|
677
|
+
it 'does not clear the local connection state when the connection_state_ttl period has passed since last activity, but the idle timeout has not passed (#RTN15g1, #RTN15g2)' do
|
678
|
+
expect(connection.connection_state_ttl).to eql(client_options.fetch(:max_connection_state_ttl))
|
679
|
+
|
680
|
+
connection.once(:connected) do
|
681
|
+
connection_id = connection.id
|
682
|
+
resumed_connection = false
|
683
|
+
|
684
|
+
connection.once(:disconnected) do
|
685
|
+
disconnected_at = Time.now
|
686
|
+
|
687
|
+
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(connection.connection_state_ttl + 1)
|
688
|
+
|
689
|
+
# Make sure the next connect does not have the resume param
|
690
|
+
allow(EventMachine).to receive(:connect).and_wrap_original do |original, *args, &block|
|
691
|
+
url = args[4]
|
692
|
+
uri = URI.parse(url)
|
693
|
+
expect(CGI::parse(uri.query)['resume']).to_not be_empty
|
694
|
+
resumed_connection = true
|
695
|
+
original.call(*args, &block)
|
696
|
+
end
|
697
|
+
|
698
|
+
connection.once(:connecting) do
|
699
|
+
connection.once(:connected) do |state_change|
|
700
|
+
expect(connection.id).to eql(connection_id)
|
701
|
+
expect(resumed_connection).to be_truthy
|
702
|
+
stop_reactor
|
703
|
+
end
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
connection.transport.unbind
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
it 'clears the local connection state and uses a new connection when the connection_state_ttl + max_idle_interval period has passed since last activity (#RTN15g1, #RTN15g2)' do
|
712
|
+
expect(connection.connection_state_ttl).to eql(client_options.fetch(:max_connection_state_ttl))
|
713
|
+
|
714
|
+
connection.once(:connected) do
|
715
|
+
connection_id = connection.id
|
716
|
+
resumed_with_clean_connection = false
|
717
|
+
|
718
|
+
connection.once(:disconnected) do
|
719
|
+
disconnected_at = Time.now
|
720
|
+
|
721
|
+
pseudo_time_passed = connection.connection_state_ttl + connection.details.max_idle_interval + 1
|
722
|
+
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(pseudo_time_passed)
|
723
|
+
|
724
|
+
# Make sure the next connect does not have the resume param
|
725
|
+
allow(EventMachine).to receive(:connect).and_wrap_original do |original, *args, &block|
|
726
|
+
url = args[4]
|
727
|
+
uri = URI.parse(url)
|
728
|
+
expect(CGI::parse(uri.query)['resume']).to be_empty
|
729
|
+
resumed_with_clean_connection = true
|
730
|
+
original.call(*args, &block)
|
731
|
+
end
|
732
|
+
|
733
|
+
connection.once(:connecting) do
|
734
|
+
connection.once(:connected) do |state_change|
|
735
|
+
expect(connection.id).to_not eql(connection_id)
|
736
|
+
expect(resumed_with_clean_connection).to be_truthy
|
737
|
+
stop_reactor
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
connection.transport.unbind
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
it 'still reattaches the channels automatically following a new connection being established (#RTN15g2)' do
|
747
|
+
connection.once(:connected) do
|
748
|
+
connection_id = connection.id
|
749
|
+
resumed_with_clean_connection = false
|
750
|
+
channel_emitted_an_attached = false
|
751
|
+
|
752
|
+
channel.attach do
|
753
|
+
channel.once(:attached) do |channel_state_change|
|
754
|
+
expect(channel_state_change.resumed).to be_falsey
|
755
|
+
channel_emitted_an_attached = true
|
756
|
+
end
|
757
|
+
|
758
|
+
connection.once(:disconnected) do
|
759
|
+
disconnected_at = Time.now
|
760
|
+
|
761
|
+
pseudo_time_passed = connection.connection_state_ttl + connection.details.max_idle_interval + 1
|
762
|
+
allow(connection).to receive(:time_since_connection_confirmed_alive?).and_return(pseudo_time_passed)
|
763
|
+
|
764
|
+
# Make sure the next connect does not have the resume param
|
765
|
+
allow(EventMachine).to receive(:connect).and_wrap_original do |original, *args, &block|
|
766
|
+
url = args[4]
|
767
|
+
uri = URI.parse(url)
|
768
|
+
expect(CGI::parse(uri.query)['resume']).to be_empty
|
769
|
+
resumed_with_clean_connection = true
|
770
|
+
original.call(*args, &block)
|
771
|
+
end
|
772
|
+
|
773
|
+
connection.once(:connecting) do
|
774
|
+
connection.once(:connected) do |state_change|
|
775
|
+
expect(connection.id).to_not eql(connection_id)
|
776
|
+
expect(resumed_with_clean_connection).to be_truthy
|
777
|
+
|
778
|
+
wait_until(lambda { channel.attached? }) do
|
779
|
+
expect(channel_emitted_an_attached).to be_truthy
|
780
|
+
stop_reactor
|
781
|
+
end
|
782
|
+
end
|
783
|
+
end
|
784
|
+
end
|
785
|
+
|
786
|
+
connection.transport.unbind
|
787
|
+
end
|
788
|
+
end
|
789
|
+
end
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
517
793
|
context 'and subsequently fails to reconnect' do
|
518
794
|
let(:retry_every) { 1.5 }
|
519
795
|
|
@@ -711,11 +987,11 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
711
987
|
end
|
712
988
|
end
|
713
989
|
|
714
|
-
it 'retains the
|
990
|
+
it 'retains the client_msg_serial (#RTN15c2, #RTN15c3)' do
|
715
991
|
last_message = nil
|
716
992
|
channel = client.channels.get("foo")
|
717
993
|
|
718
|
-
|
994
|
+
channel.attach do
|
719
995
|
connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
720
996
|
if protocol_message.action == :message
|
721
997
|
last_message = protocol_message
|
@@ -893,7 +1169,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
893
1169
|
end
|
894
1170
|
end
|
895
1171
|
|
896
|
-
it '
|
1172
|
+
it 'continues to use the client_msg_serial (#RTN15c3)' do
|
897
1173
|
last_message = nil
|
898
1174
|
channel = client.channels.get("foo")
|
899
1175
|
|
@@ -911,7 +1187,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
911
1187
|
connection.once(:connected) do
|
912
1188
|
channel.publish("first on new connection") do
|
913
1189
|
# Message serial reset after failed resume
|
914
|
-
expect(last_message.message_serial).to eql(
|
1190
|
+
expect(last_message.message_serial).to eql(2)
|
915
1191
|
stop_reactor
|
916
1192
|
end
|
917
1193
|
end
|
@@ -935,16 +1211,20 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
935
1211
|
previous_connection_id = connection.id
|
936
1212
|
previous_connection_key = connection.key
|
937
1213
|
|
938
|
-
five_minutes_time = Time.now + 5 * 60
|
939
|
-
allow(Time).to receive(:now) { five_minutes_time }
|
940
|
-
|
941
1214
|
connection.once(:connected) do
|
942
1215
|
expect(connection.key).to_not eql(previous_connection_key)
|
943
1216
|
expect(connection.id).to_not eql(previous_connection_id)
|
944
1217
|
stop_reactor
|
945
1218
|
end
|
946
1219
|
|
947
|
-
|
1220
|
+
# Wait until next tick before stubbing otherwise liveness test may
|
1221
|
+
# record the stubbed last contact time as the future time
|
1222
|
+
EventMachine.next_tick do
|
1223
|
+
five_minutes_time = Time.now + 5 * 60
|
1224
|
+
allow(Time).to receive(:now) { five_minutes_time }
|
1225
|
+
|
1226
|
+
kill_connection_transport_and_prevent_valid_resume
|
1227
|
+
end
|
948
1228
|
end
|
949
1229
|
end
|
950
1230
|
end
|
@@ -1017,7 +1297,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1017
1297
|
}
|
1018
1298
|
|
1019
1299
|
let(:client_options) do
|
1020
|
-
default_options.merge(auth_callback:
|
1300
|
+
default_options.merge(auth_callback: lambda do |token_params|
|
1021
1301
|
@auth_requests ||= 0
|
1022
1302
|
@auth_requests += 1
|
1023
1303
|
|
@@ -27,6 +27,13 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
context 'current_host' do
|
31
|
+
it 'is available immediately after the client is instanced' do
|
32
|
+
expect(connection.current_host.to_s).to match(/\.ably\.io$/)
|
33
|
+
stop_reactor
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
30
37
|
context 'with :auto_connect option set to false' do
|
31
38
|
let(:client) do
|
32
39
|
auto_close Ably::Realtime::Client.new(default_options.merge(auto_connect: false))
|
@@ -131,7 +138,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
131
138
|
let(:ttl) { 0.001 }
|
132
139
|
let(:auth_requests) { [] }
|
133
140
|
let(:token_callback) do
|
134
|
-
|
141
|
+
lambda do |token_params|
|
135
142
|
auth_requests << Time.now
|
136
143
|
Ably::Rest::Client.new(default_options).auth.request_token(ttl: ttl).token
|
137
144
|
end
|
@@ -246,7 +253,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
246
253
|
let(:ttl) { 4 }
|
247
254
|
let(:auth_requests) { [] }
|
248
255
|
let(:token_callback) do
|
249
|
-
|
256
|
+
lambda do |token_params|
|
250
257
|
sleep 2
|
251
258
|
auth_requests << Time.now
|
252
259
|
Ably::Rest::Client.new(default_options).auth.request_token(ttl: ttl).token
|
@@ -264,7 +271,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
264
271
|
channel.subscribe('event') do |message|
|
265
272
|
messages_received << message.data.to_i
|
266
273
|
if messages_received.count == total_expected
|
267
|
-
expect(messages_received).to match(total_expected.times)
|
274
|
+
expect(messages_received).to match(total_expected.times.to_a)
|
268
275
|
expect(auth_requests.count).to eql(iteration + 1)
|
269
276
|
EventMachine.add_timer(1) do
|
270
277
|
channel.unsubscribe 'event'
|
@@ -298,7 +305,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
298
305
|
context 'and subsequent token is invalid' do
|
299
306
|
let(:ttl) { 2 }
|
300
307
|
let(:token_callback) do
|
301
|
-
|
308
|
+
lambda do |token_params|
|
302
309
|
if @token_issued
|
303
310
|
"#{app_id}.invalid-token-invalid-token-invalid-token"
|
304
311
|
else
|
@@ -417,7 +424,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
417
424
|
let(:phases) { [:connecting, :connected] }
|
418
425
|
let(:events_emitted) { [] }
|
419
426
|
let(:test_expectation) do
|
420
|
-
|
427
|
+
lambda do
|
421
428
|
expect(events_emitted).to eq(phases)
|
422
429
|
stop_reactor
|
423
430
|
end
|
@@ -466,7 +473,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
466
473
|
been_disconnected = true
|
467
474
|
end
|
468
475
|
connection.once(:connecting) do
|
469
|
-
close_if_transport_available =
|
476
|
+
close_if_transport_available = lambda do
|
470
477
|
EventMachine.add_timer(0.001) do
|
471
478
|
if connection.transport
|
472
479
|
connection.transport.close_connection_after_writing
|
@@ -649,16 +656,47 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
649
656
|
end
|
650
657
|
|
651
658
|
it 'is set to 1 when the second message is received' do
|
652
|
-
channel.
|
653
|
-
|
659
|
+
channel.attach do
|
660
|
+
messages = []
|
661
|
+
channel.subscribe do |message|
|
662
|
+
messages << message
|
663
|
+
if messages.length == 2
|
664
|
+
expect(connection.serial).to eql(1)
|
665
|
+
stop_reactor
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
channel.publish('event', 'data') do
|
670
|
+
channel.publish('event', 'data')
|
671
|
+
end
|
654
672
|
end
|
673
|
+
end
|
674
|
+
end
|
655
675
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
676
|
+
describe '#msgSerial' do
|
677
|
+
context 'when messages are queued for publish before a connection is established' do
|
678
|
+
let(:batches) { 6 }
|
679
|
+
let(:messages_per_batch) { 10 }
|
680
|
+
|
681
|
+
let(:publishing_client) { auto_close Ably::Realtime::Client.new(default_options) }
|
682
|
+
let(:channel_name) { random_str }
|
683
|
+
let(:publishing_channel) { publishing_client.channels.get(channel_name) }
|
684
|
+
let(:receiving_channel) { client.channels.get(channel_name) }
|
685
|
+
|
686
|
+
it 'the msgSerial is always incrementing (and not reset when the new connection is established) ensuring messages are never de-duped by the realtime service' do
|
687
|
+
messages = []
|
688
|
+
|
689
|
+
receiving_channel.attach do
|
690
|
+
receiving_channel.subscribe('event') do |message|
|
691
|
+
messages << message
|
692
|
+
stop_reactor if messages.count == batches * messages_per_batch
|
693
|
+
end
|
694
|
+
|
695
|
+
batches.times do |batch|
|
696
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
697
|
+
messages_per_batch.times { |index| publishing_channel.publish('event') }
|
698
|
+
end
|
699
|
+
end
|
662
700
|
end
|
663
701
|
end
|
664
702
|
end
|
@@ -796,7 +834,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
796
834
|
end
|
797
835
|
end
|
798
836
|
|
799
|
-
ping_block =
|
837
|
+
ping_block = lambda do |time|
|
800
838
|
pings_complete << true
|
801
839
|
if pings_complete.length == 3
|
802
840
|
expect(heartbeat_ids.uniq.length).to eql(3)
|
@@ -980,7 +1018,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
980
1018
|
|
981
1019
|
context 'transport-level heartbeats are supported in the websocket transport' do
|
982
1020
|
it 'provides the heartbeats argument in the websocket connection params (#RTN23b)' do
|
983
|
-
skip 'Native heartbeats not yet supported in the WS driver https://github.com/ably/ably-ruby/issues/116'
|
984
1021
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
985
1022
|
uri = URI.parse(url)
|
986
1023
|
expect(CGI::parse(uri.query)['heartbeats'][0]).to eql('false')
|
@@ -990,12 +1027,10 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
990
1027
|
end
|
991
1028
|
|
992
1029
|
it 'receives websocket heartbeat messages (#RTN23b) [slow test as need to wait for heartbeat]', em_timeout: 45 do
|
993
|
-
skip "Heartbeats param is missing from realtime implementation, see https://github.com/ably/realtime/issues/656"
|
994
|
-
|
995
1030
|
connection.once(:connected) do
|
996
1031
|
connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
997
1032
|
if protocol_message.action == :heartbeat
|
998
|
-
expect(protocol_message.attributes[:source]).to eql(
|
1033
|
+
expect(protocol_message.attributes[:source]).to eql(:websocket)
|
999
1034
|
expect(connection.time_since_connection_confirmed_alive?).to be_within(1).of(0)
|
1000
1035
|
stop_reactor
|
1001
1036
|
end
|
@@ -1008,10 +1043,9 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1008
1043
|
let(:client_options) { default_options.merge(websocket_heartbeats_disabled: true) }
|
1009
1044
|
|
1010
1045
|
it 'does not provide the heartbeats argument in the websocket connection params (#RTN23b)' do
|
1011
|
-
skip 'Native heartbeats not yet supported in the WS driver https://github.com/ably/ably-ruby/issues/116'
|
1012
1046
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1013
1047
|
uri = URI.parse(url)
|
1014
|
-
expect(CGI::parse(uri.query)['heartbeats'][0]).to
|
1048
|
+
expect(CGI::parse(uri.query)['heartbeats'][0]).to eql('true')
|
1015
1049
|
stop_reactor
|
1016
1050
|
end
|
1017
1051
|
client
|
@@ -1021,7 +1055,8 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1021
1055
|
connection.once(:connected) do
|
1022
1056
|
connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
1023
1057
|
if protocol_message.action == :heartbeat
|
1024
|
-
|
1058
|
+
next if protocol_message.attributes[:source] == :websocket # ignore the native heartbeats
|
1059
|
+
expect(protocol_message.attributes[:source]).to_not eql(:websocket)
|
1025
1060
|
expect(connection.time_since_connection_confirmed_alive?).to be_within(1).of(0)
|
1026
1061
|
stop_reactor
|
1027
1062
|
end
|
@@ -1128,7 +1163,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1128
1163
|
expected_serial += 1 # attach message received
|
1129
1164
|
expect(connection.serial).to eql(expected_serial)
|
1130
1165
|
|
1131
|
-
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}")
|
1166
|
+
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}:#{connection.send(:client_msg_serial)}")
|
1132
1167
|
stop_reactor
|
1133
1168
|
end
|
1134
1169
|
end
|
@@ -1176,24 +1211,18 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1176
1211
|
end
|
1177
1212
|
|
1178
1213
|
context "opening a new connection using a recently disconnected connection's #recovery_key" do
|
1179
|
-
context 'connection#id
|
1180
|
-
it 'remains the same
|
1181
|
-
connection_key_consistent_part_regex = /.*?!([\w-]{5,})-\w+/
|
1214
|
+
context 'connection#id after recovery' do
|
1215
|
+
it 'remains the same' do
|
1182
1216
|
previous_connection_id = nil
|
1183
|
-
previous_connection_key = nil
|
1184
1217
|
|
1185
1218
|
connection.once(:connected) do
|
1186
1219
|
previous_connection_id = connection.id
|
1187
|
-
previous_connection_key = connection.key
|
1188
1220
|
connection.transition_state_machine! :failed
|
1189
1221
|
end
|
1190
1222
|
|
1191
1223
|
connection.once(:failed) do
|
1192
1224
|
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
1193
1225
|
recover_client.connection.on(:connected) do
|
1194
|
-
expect(recover_client.connection.key[connection_key_consistent_part_regex, 1]).to_not be_nil
|
1195
|
-
expect(recover_client.connection.key[connection_key_consistent_part_regex, 1]).to eql(
|
1196
|
-
previous_connection_key[connection_key_consistent_part_regex, 1])
|
1197
1226
|
expect(recover_client.connection.id).to eql(previous_connection_id)
|
1198
1227
|
stop_reactor
|
1199
1228
|
end
|
@@ -1245,6 +1274,80 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1245
1274
|
end
|
1246
1275
|
end
|
1247
1276
|
end
|
1277
|
+
|
1278
|
+
context 'when messages have been published' do
|
1279
|
+
describe 'the new connection' do
|
1280
|
+
it 'uses the correct msgSerial from the old connection' do
|
1281
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1282
|
+
|
1283
|
+
channel.attach do
|
1284
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1285
|
+
connection_id = client.connection.id
|
1286
|
+
connection.transport.__incoming_protocol_msgbus__
|
1287
|
+
channel.publish('event', 'message') do
|
1288
|
+
msg_serial = connection.send(:client_msg_serial)
|
1289
|
+
expect(msg_serial).to eql(0)
|
1290
|
+
recovery_key = client.connection.recovery_key
|
1291
|
+
connection.transition_state_machine! :failed
|
1292
|
+
end
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
connection.on(:failed) do
|
1296
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1297
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1298
|
+
recover_client_channel.attach do
|
1299
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1300
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1301
|
+
stop_reactor
|
1302
|
+
end
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
end
|
1306
|
+
end
|
1307
|
+
|
1308
|
+
context 'when messages are published before the new connection is recovered' do
|
1309
|
+
describe 'the new connection' do
|
1310
|
+
it 'uses the correct msgSerial from the old connection for the queued messages' do
|
1311
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1312
|
+
|
1313
|
+
channel.attach do
|
1314
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1315
|
+
connection_id = client.connection.id
|
1316
|
+
connection.transport.__incoming_protocol_msgbus__
|
1317
|
+
channel.subscribe('event') do |message|
|
1318
|
+
expect(message.data).to eql('message-1')
|
1319
|
+
msg_serial = connection.send(:client_msg_serial)
|
1320
|
+
expect(msg_serial).to eql(0)
|
1321
|
+
recovery_key = client.connection.recovery_key
|
1322
|
+
connection.transition_state_machine! :failed
|
1323
|
+
end
|
1324
|
+
channel.publish('event', 'message-1')
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
connection.on(:failed) do
|
1328
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1329
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1330
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1331
|
+
|
1332
|
+
recover_client.connection.once(:connecting) do
|
1333
|
+
recover_client_channel.publish('event', 'message-2')
|
1334
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial + 1)
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
recover_client_channel.attach do
|
1338
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1339
|
+
|
1340
|
+
recover_client_channel.subscribe do |message|
|
1341
|
+
expect(message.data).to eql('message-2')
|
1342
|
+
EventMachine.add_timer(2) do
|
1343
|
+
stop_reactor
|
1344
|
+
end
|
1345
|
+
end
|
1346
|
+
end
|
1347
|
+
end
|
1348
|
+
end
|
1349
|
+
end
|
1350
|
+
end
|
1248
1351
|
end
|
1249
1352
|
|
1250
1353
|
context 'with :recover option' do
|
@@ -1258,7 +1361,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1258
1361
|
end
|
1259
1362
|
|
1260
1363
|
context 'with invalid formatted value sent to server' do
|
1261
|
-
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1', log_level: :none) }
|
1364
|
+
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1:0', log_level: :none) }
|
1262
1365
|
|
1263
1366
|
it 'sets the #error_reason and moves the connection to FAILED' do
|
1264
1367
|
connection.once(:failed) do |state_change|
|
@@ -1273,7 +1376,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1273
1376
|
end
|
1274
1377
|
|
1275
1378
|
context 'with expired (missing) value sent to server' do
|
1276
|
-
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0', log_level: :fatal) }
|
1379
|
+
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0:0', log_level: :fatal) }
|
1277
1380
|
|
1278
1381
|
it 'connects but sets the error reason and includes the reason in the state change' do
|
1279
1382
|
connection.once(:connected) do |state_change|
|
@@ -1480,12 +1583,12 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1480
1583
|
channel.attach do
|
1481
1584
|
channel.once(:suspended) do
|
1482
1585
|
channel.publish('test').errback do |error|
|
1483
|
-
expect(error).to be_a(Ably::Exceptions::
|
1586
|
+
expect(error).to be_a(Ably::Exceptions::ChannelInactive)
|
1484
1587
|
stop_reactor
|
1485
1588
|
end
|
1486
1589
|
end
|
1487
1590
|
|
1488
|
-
close_connection_proc =
|
1591
|
+
close_connection_proc = lambda do
|
1489
1592
|
EventMachine.add_timer(0.001) do
|
1490
1593
|
if connection.transport.nil?
|
1491
1594
|
close_connection_proc.call
|
@@ -1523,7 +1626,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1523
1626
|
# See https://github.com/ably/ably-ruby/issues/103
|
1524
1627
|
it 'emits event to all and single subscribers' do
|
1525
1628
|
connected_emitted = []
|
1526
|
-
block =
|
1629
|
+
block = lambda do |state_change|
|
1527
1630
|
if state_change.current == :connected
|
1528
1631
|
connected_emitted << state_change
|
1529
1632
|
EventMachine.add_timer(0.5) do
|
@@ -1740,7 +1843,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1740
1843
|
it 'sends the protocol version param v (#G4, #RTN2f)' do
|
1741
1844
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1742
1845
|
uri = URI.parse(url)
|
1743
|
-
expect(CGI::parse(uri.query)['v'][0]).to eql('1.
|
1846
|
+
expect(CGI::parse(uri.query)['v'][0]).to eql('1.1')
|
1744
1847
|
stop_reactor
|
1745
1848
|
end
|
1746
1849
|
client
|
@@ -1749,7 +1852,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1749
1852
|
it 'sends the lib version param lib (#RTN2g)' do
|
1750
1853
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1751
1854
|
uri = URI.parse(url)
|
1752
|
-
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-1\.
|
1855
|
+
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-1\.1\.\d+(-[\w\.]+)?+$/)
|
1753
1856
|
stop_reactor
|
1754
1857
|
end
|
1755
1858
|
client
|
@@ -1769,7 +1872,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1769
1872
|
it 'sends the lib version param lib with the variant (#RTN2g + #RSC7b)' do
|
1770
1873
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1771
1874
|
uri = URI.parse(url)
|
1772
|
-
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-#{variant}-1\.
|
1875
|
+
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-#{variant}-1\.1\.\d+(-[\w\.]+)?$/)
|
1773
1876
|
stop_reactor
|
1774
1877
|
end
|
1775
1878
|
client
|