ably 1.1.0 → 1.1.4
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 +4 -4
- data/.github/workflows/check.yml +27 -0
- data/CHANGELOG.md +68 -2
- data/COPYRIGHT +1 -0
- data/LICENSE +172 -11
- data/MAINTAINERS.md +1 -0
- data/README.md +3 -7
- data/SPEC.md +944 -914
- data/ably.gemspec +7 -7
- data/lib/ably/auth.rb +12 -2
- data/lib/ably/exceptions.rb +2 -2
- data/lib/ably/logger.rb +7 -1
- data/lib/ably/modules/state_machine.rb +1 -1
- data/lib/ably/realtime/channel.rb +7 -11
- data/lib/ably/realtime/channel/channel_manager.rb +2 -2
- data/lib/ably/realtime/channel/channel_properties.rb +24 -0
- data/lib/ably/realtime/client.rb +12 -3
- data/lib/ably/realtime/connection.rb +31 -19
- data/lib/ably/realtime/connection/connection_manager.rb +19 -3
- data/lib/ably/realtime/connection/websocket_transport.rb +67 -1
- data/lib/ably/realtime/presence.rb +0 -14
- data/lib/ably/rest/channel.rb +25 -17
- data/lib/ably/rest/client.rb +22 -11
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +16 -13
- data/spec/acceptance/realtime/channel_history_spec.rb +26 -20
- data/spec/acceptance/realtime/channel_spec.rb +21 -8
- data/spec/acceptance/realtime/client_spec.rb +80 -20
- data/spec/acceptance/realtime/connection_failures_spec.rb +71 -5
- data/spec/acceptance/realtime/connection_spec.rb +153 -26
- data/spec/acceptance/realtime/message_spec.rb +17 -17
- data/spec/acceptance/realtime/presence_history_spec.rb +0 -58
- data/spec/acceptance/realtime/presence_spec.rb +250 -162
- data/spec/acceptance/realtime/push_admin_spec.rb +49 -25
- data/spec/acceptance/rest/auth_spec.rb +6 -75
- data/spec/acceptance/rest/channel_spec.rb +79 -4
- data/spec/acceptance/rest/channels_spec.rb +6 -0
- data/spec/acceptance/rest/client_spec.rb +72 -12
- data/spec/acceptance/rest/message_spec.rb +8 -27
- data/spec/acceptance/rest/push_admin_spec.rb +67 -27
- data/spec/shared/client_initializer_behaviour.rb +0 -8
- data/spec/spec_helper.rb +2 -1
- data/spec/support/debug_failure_helper.rb +9 -5
- data/spec/support/serialization_helper.rb +21 -0
- data/spec/support/test_app.rb +2 -2
- data/spec/unit/modules/enum_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +20 -7
- data/spec/unit/realtime/connection_spec.rb +1 -1
- metadata +40 -29
- data/.travis.yml +0 -16
@@ -87,22 +87,6 @@ describe Ably::Realtime::Client, :event_machine do
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
-
|
91
|
-
context 'with client_id' do
|
92
|
-
let(:client_options) do
|
93
|
-
default_options.merge(client_id: random_str)
|
94
|
-
end
|
95
|
-
it 'connects using token auth' do
|
96
|
-
run_reactor do
|
97
|
-
connection.on(:connected) do
|
98
|
-
expect(connection.state).to eq(:connected)
|
99
|
-
expect(auth_params[:access_token]).to_not be_nil
|
100
|
-
expect(auth_params[:key]).to be_nil
|
101
|
-
stop_reactor
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
90
|
end
|
107
91
|
end
|
108
92
|
|
@@ -249,6 +233,8 @@ describe Ably::Realtime::Client, :event_machine do
|
|
249
233
|
|
250
234
|
context '#request (#RSC19*)' do
|
251
235
|
let(:client_options) { default_options.merge(key: api_key) }
|
236
|
+
let(:device_id) { random_str }
|
237
|
+
let(:endpoint) { subject.rest_client.endpoint }
|
252
238
|
|
253
239
|
context 'get' do
|
254
240
|
it 'returns an HttpPaginatedResponse object' do
|
@@ -297,6 +283,76 @@ describe Ably::Realtime::Client, :event_machine do
|
|
297
283
|
end
|
298
284
|
end
|
299
285
|
end
|
286
|
+
|
287
|
+
|
288
|
+
context 'post', :webmock do
|
289
|
+
before do
|
290
|
+
stub_request(:delete, "#{endpoint}/push/deviceRegistrations/#{device_id}/resetUpdateToken").
|
291
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'supports post' do
|
295
|
+
subject.request(:delete, "push/deviceRegistrations/#{device_id}/resetUpdateToken").callback do |response|
|
296
|
+
expect(response).to be_success
|
297
|
+
stop_reactor
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context 'delete', :webmock do
|
303
|
+
before do
|
304
|
+
stub_request(:delete, "#{endpoint}/push/channelSubscriptions?deviceId=#{device_id}").
|
305
|
+
to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'supports delete' do
|
309
|
+
subject.request(:delete, "/push/channelSubscriptions", { deviceId: device_id}).callback do |response|
|
310
|
+
expect(response).to be_success
|
311
|
+
stop_reactor
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'patch', :webmock do
|
317
|
+
let(:body_params) { { 'metadata' => { 'key' => 'value' } } }
|
318
|
+
|
319
|
+
before do
|
320
|
+
stub_request(:patch, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
321
|
+
.with(body: serialize_body(body_params, protocol))
|
322
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'supports patch' do
|
326
|
+
subject.request(:patch, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
|
327
|
+
expect(response).to be_success
|
328
|
+
stop_reactor
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context 'put', :webmock do
|
334
|
+
let(:body_params) do
|
335
|
+
{
|
336
|
+
'id' => random_str,
|
337
|
+
'platform' => 'ios',
|
338
|
+
'formFactor' => 'phone',
|
339
|
+
'metadata' => { 'key' => 'value' }
|
340
|
+
}
|
341
|
+
end
|
342
|
+
|
343
|
+
before do
|
344
|
+
stub_request(:put, "#{endpoint}/push/deviceRegistrations/#{device_id}")
|
345
|
+
.with(body: serialize_body(body_params, protocol))
|
346
|
+
.to_return(status: 200, body: '{}', headers: { 'Content-Type' => 'application/json' })
|
347
|
+
end
|
348
|
+
|
349
|
+
it 'supports put' do
|
350
|
+
subject.request(:put, "/push/deviceRegistrations/#{device_id}", {}, body_params).callback do |response|
|
351
|
+
expect(response).to be_success
|
352
|
+
stop_reactor
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
300
356
|
end
|
301
357
|
|
302
358
|
context '#publish (#TBC)' do
|
@@ -315,8 +371,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
315
371
|
expect(msg.data).to eql(data)
|
316
372
|
stop_reactor
|
317
373
|
end
|
374
|
+
|
375
|
+
subject.publish channel_name, event_name, data
|
318
376
|
end
|
319
|
-
subject.publish channel_name, event_name, data
|
320
377
|
end
|
321
378
|
|
322
379
|
specify 'publishing does not result in a channel being created' do
|
@@ -341,8 +398,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
341
398
|
expect(msg.extras).to eql(extras)
|
342
399
|
stop_reactor
|
343
400
|
end
|
401
|
+
|
402
|
+
subject.publish channel_name, event_name, {}, extras: extras
|
344
403
|
end
|
345
|
-
subject.publish channel_name, event_name, {}, extras: extras
|
346
404
|
end
|
347
405
|
end
|
348
406
|
|
@@ -353,8 +411,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
353
411
|
expect(msg.data).to eql(data)
|
354
412
|
stop_reactor
|
355
413
|
end
|
414
|
+
|
415
|
+
subject.publish channel_name, [message]
|
356
416
|
end
|
357
|
-
subject.publish channel_name, [message]
|
358
417
|
end
|
359
418
|
|
360
419
|
specify 'publishing supports an array of Hash objects' do
|
@@ -364,8 +423,9 @@ describe Ably::Realtime::Client, :event_machine do
|
|
364
423
|
expect(msg.data).to eql(data)
|
365
424
|
stop_reactor
|
366
425
|
end
|
426
|
+
|
427
|
+
subject.publish channel_name, [name: event_name, data: data]
|
367
428
|
end
|
368
|
-
subject.publish channel_name, [name: event_name, data: data]
|
369
429
|
end
|
370
430
|
|
371
431
|
specify 'publishing on a closed connection fails' do
|
@@ -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
|
@@ -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
|
|
@@ -921,7 +987,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
921
987
|
end
|
922
988
|
end
|
923
989
|
|
924
|
-
it 'retains the
|
990
|
+
it 'retains the client_msg_serial (#RTN15c2, #RTN15c3)' do
|
925
991
|
last_message = nil
|
926
992
|
channel = client.channels.get("foo")
|
927
993
|
|
@@ -1103,7 +1169,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1103
1169
|
end
|
1104
1170
|
end
|
1105
1171
|
|
1106
|
-
it '
|
1172
|
+
it 'continues to use the client_msg_serial (#RTN15c3)' do
|
1107
1173
|
last_message = nil
|
1108
1174
|
channel = client.channels.get("foo")
|
1109
1175
|
|
@@ -1121,7 +1187,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1121
1187
|
connection.once(:connected) do
|
1122
1188
|
channel.publish("first on new connection") do
|
1123
1189
|
# Message serial reset after failed resume
|
1124
|
-
expect(last_message.message_serial).to eql(
|
1190
|
+
expect(last_message.message_serial).to eql(2)
|
1125
1191
|
stop_reactor
|
1126
1192
|
end
|
1127
1193
|
end
|
@@ -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))
|
@@ -70,18 +77,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
70
77
|
end
|
71
78
|
end
|
72
79
|
end
|
73
|
-
|
74
|
-
context 'with implicit authorisation' do
|
75
|
-
let(:client_options) { default_options.merge(client_id: 'force_token_auth') }
|
76
|
-
|
77
|
-
it 'uses the token created by the implicit authorisation' do
|
78
|
-
expect(client.rest_client.auth).to receive(:request_token).once.and_call_original
|
79
|
-
|
80
|
-
connection.once(:connected) do
|
81
|
-
stop_reactor
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
80
|
end
|
86
81
|
|
87
82
|
context 'that expire' do
|
@@ -264,7 +259,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
264
259
|
channel.subscribe('event') do |message|
|
265
260
|
messages_received << message.data.to_i
|
266
261
|
if messages_received.count == total_expected
|
267
|
-
expect(messages_received).to match(total_expected.times)
|
262
|
+
expect(messages_received).to match(total_expected.times.to_a)
|
268
263
|
expect(auth_requests.count).to eql(iteration + 1)
|
269
264
|
EventMachine.add_timer(1) do
|
270
265
|
channel.unsubscribe 'event'
|
@@ -649,16 +644,47 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
649
644
|
end
|
650
645
|
|
651
646
|
it 'is set to 1 when the second message is received' do
|
652
|
-
channel.
|
653
|
-
|
647
|
+
channel.attach do
|
648
|
+
messages = []
|
649
|
+
channel.subscribe do |message|
|
650
|
+
messages << message
|
651
|
+
if messages.length == 2
|
652
|
+
expect(connection.serial).to eql(1)
|
653
|
+
stop_reactor
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
channel.publish('event', 'data') do
|
658
|
+
channel.publish('event', 'data')
|
659
|
+
end
|
654
660
|
end
|
661
|
+
end
|
662
|
+
end
|
655
663
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
664
|
+
describe '#msgSerial' do
|
665
|
+
context 'when messages are queued for publish before a connection is established' do
|
666
|
+
let(:batches) { 6 }
|
667
|
+
let(:messages_per_batch) { 10 }
|
668
|
+
|
669
|
+
let(:publishing_client) { auto_close Ably::Realtime::Client.new(default_options) }
|
670
|
+
let(:channel_name) { random_str }
|
671
|
+
let(:publishing_channel) { publishing_client.channels.get(channel_name) }
|
672
|
+
let(:receiving_channel) { client.channels.get(channel_name) }
|
673
|
+
|
674
|
+
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
|
675
|
+
messages = []
|
676
|
+
|
677
|
+
receiving_channel.attach do
|
678
|
+
receiving_channel.subscribe('event') do |message|
|
679
|
+
messages << message
|
680
|
+
stop_reactor if messages.count == batches * messages_per_batch
|
681
|
+
end
|
682
|
+
|
683
|
+
batches.times do |batch|
|
684
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
685
|
+
messages_per_batch.times { |index| publishing_channel.publish('event') }
|
686
|
+
end
|
687
|
+
end
|
662
688
|
end
|
663
689
|
end
|
664
690
|
end
|
@@ -1005,10 +1031,9 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1005
1031
|
let(:client_options) { default_options.merge(websocket_heartbeats_disabled: true) }
|
1006
1032
|
|
1007
1033
|
it 'does not provide the heartbeats argument in the websocket connection params (#RTN23b)' do
|
1008
|
-
skip 'Native heartbeats not yet supported in the WS driver https://github.com/ably/ably-ruby/issues/116'
|
1009
1034
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1010
1035
|
uri = URI.parse(url)
|
1011
|
-
expect(CGI::parse(uri.query)['heartbeats'][0]).to
|
1036
|
+
expect(CGI::parse(uri.query)['heartbeats'][0]).to eql('true')
|
1012
1037
|
stop_reactor
|
1013
1038
|
end
|
1014
1039
|
client
|
@@ -1126,7 +1151,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1126
1151
|
expected_serial += 1 # attach message received
|
1127
1152
|
expect(connection.serial).to eql(expected_serial)
|
1128
1153
|
|
1129
|
-
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}")
|
1154
|
+
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}:#{connection.send(:client_msg_serial)}")
|
1130
1155
|
stop_reactor
|
1131
1156
|
end
|
1132
1157
|
end
|
@@ -1237,6 +1262,80 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1237
1262
|
end
|
1238
1263
|
end
|
1239
1264
|
end
|
1265
|
+
|
1266
|
+
context 'when messages have been published' do
|
1267
|
+
describe 'the new connection' do
|
1268
|
+
it 'uses the correct msgSerial from the old connection' do
|
1269
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1270
|
+
|
1271
|
+
channel.attach do
|
1272
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1273
|
+
connection_id = client.connection.id
|
1274
|
+
connection.transport.__incoming_protocol_msgbus__
|
1275
|
+
channel.publish('event', 'message') do
|
1276
|
+
msg_serial = connection.send(:client_msg_serial)
|
1277
|
+
expect(msg_serial).to eql(0)
|
1278
|
+
recovery_key = client.connection.recovery_key
|
1279
|
+
connection.transition_state_machine! :failed
|
1280
|
+
end
|
1281
|
+
end
|
1282
|
+
|
1283
|
+
connection.on(:failed) do
|
1284
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1285
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1286
|
+
recover_client_channel.attach do
|
1287
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1288
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1289
|
+
stop_reactor
|
1290
|
+
end
|
1291
|
+
end
|
1292
|
+
end
|
1293
|
+
end
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
context 'when messages are published before the new connection is recovered' do
|
1297
|
+
describe 'the new connection' do
|
1298
|
+
it 'uses the correct msgSerial from the old connection for the queued messages' do
|
1299
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1300
|
+
|
1301
|
+
channel.attach do
|
1302
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1303
|
+
connection_id = client.connection.id
|
1304
|
+
connection.transport.__incoming_protocol_msgbus__
|
1305
|
+
channel.subscribe('event') do |message|
|
1306
|
+
expect(message.data).to eql('message-1')
|
1307
|
+
msg_serial = connection.send(:client_msg_serial)
|
1308
|
+
expect(msg_serial).to eql(0)
|
1309
|
+
recovery_key = client.connection.recovery_key
|
1310
|
+
connection.transition_state_machine! :failed
|
1311
|
+
end
|
1312
|
+
channel.publish('event', 'message-1')
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
connection.on(:failed) do
|
1316
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1317
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1318
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1319
|
+
|
1320
|
+
recover_client.connection.once(:connecting) do
|
1321
|
+
recover_client_channel.publish('event', 'message-2')
|
1322
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial + 1)
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
recover_client_channel.attach do
|
1326
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1327
|
+
|
1328
|
+
recover_client_channel.subscribe do |message|
|
1329
|
+
expect(message.data).to eql('message-2')
|
1330
|
+
EventMachine.add_timer(2) do
|
1331
|
+
stop_reactor
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
end
|
1335
|
+
end
|
1336
|
+
end
|
1337
|
+
end
|
1338
|
+
end
|
1240
1339
|
end
|
1241
1340
|
|
1242
1341
|
context 'with :recover option' do
|
@@ -1250,7 +1349,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1250
1349
|
end
|
1251
1350
|
|
1252
1351
|
context 'with invalid formatted value sent to server' do
|
1253
|
-
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1', log_level: :none) }
|
1352
|
+
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1:0', log_level: :none) }
|
1254
1353
|
|
1255
1354
|
it 'sets the #error_reason and moves the connection to FAILED' do
|
1256
1355
|
connection.once(:failed) do |state_change|
|
@@ -1265,7 +1364,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1265
1364
|
end
|
1266
1365
|
|
1267
1366
|
context 'with expired (missing) value sent to server' do
|
1268
|
-
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0', log_level: :fatal) }
|
1367
|
+
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0:0', log_level: :fatal) }
|
1269
1368
|
|
1270
1369
|
it 'connects but sets the error reason and includes the reason in the state change' do
|
1271
1370
|
connection.once(:connected) do |state_change|
|
@@ -1768,5 +1867,33 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1768
1867
|
end
|
1769
1868
|
end
|
1770
1869
|
end
|
1870
|
+
|
1871
|
+
context 'transport_params (#RTC1f)' do
|
1872
|
+
let(:client_options) { default_options.merge(transport_params: { 'extra_param' => 'extra_param' }) }
|
1873
|
+
|
1874
|
+
it 'pases transport_params to query' do
|
1875
|
+
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1876
|
+
uri = URI.parse(url)
|
1877
|
+
expect(CGI::parse(uri.query)['extra_param'][0]).to eq('extra_param')
|
1878
|
+
stop_reactor
|
1879
|
+
end
|
1880
|
+
|
1881
|
+
client
|
1882
|
+
end
|
1883
|
+
|
1884
|
+
context 'when changing default param' do
|
1885
|
+
let(:client_options) { default_options.merge(transport_params: { v: '1.0' }) }
|
1886
|
+
|
1887
|
+
it 'overrides default param (#RTC1f1)' do
|
1888
|
+
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1889
|
+
uri = URI.parse(url)
|
1890
|
+
expect(CGI::parse(uri.query)['v'][0]).to eq('1.0')
|
1891
|
+
stop_reactor
|
1892
|
+
end
|
1893
|
+
|
1894
|
+
client
|
1895
|
+
end
|
1896
|
+
end
|
1897
|
+
end
|
1771
1898
|
end
|
1772
1899
|
end
|