ably-rest 0.8.5 → 0.8.6
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/README.md +1 -1
- data/SPEC.md +1380 -631
- data/ably-rest.gemspec +11 -5
- data/lib/submodules/ably-ruby/.travis.yml +1 -1
- data/lib/submodules/ably-ruby/CHANGELOG.md +42 -48
- data/lib/submodules/ably-ruby/ably.gemspec +7 -1
- data/lib/submodules/ably-ruby/lib/ably.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +155 -47
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +2 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +54 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +14 -4
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +13 -7
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +15 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +10 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +62 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +58 -54
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +18 -5
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +9 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +32 -14
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +251 -11
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +12 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +316 -24
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +93 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +177 -86
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +284 -60
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +45 -6
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +4 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +181 -49
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +13 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +222 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +132 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +129 -28
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +7 -7
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +10 -0
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +41 -17
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -0
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +16 -0
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +60 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +45 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +3 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +6 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb +5 -1
- metadata +57 -13
@@ -132,7 +132,6 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
132
132
|
let(:client_options) { default_options.merge(client_id: client_id) }
|
133
133
|
|
134
134
|
it 'contains a #client_id attribute' do
|
135
|
-
skip 'Waiting for issue #256 to be resolved'
|
136
135
|
when_all(channel.attach, other_client_channel.attach) do
|
137
136
|
other_client_channel.subscribe('event') do |message|
|
138
137
|
expect(message.client_id).to eql(client_id)
|
@@ -208,14 +207,26 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
208
207
|
end
|
209
208
|
end
|
210
209
|
|
211
|
-
it 'will not echo messages to the client from other REST clients publishing using that
|
212
|
-
skip 'Waiting on realtime#285 to be resolved'
|
210
|
+
it 'will not echo messages to the client from other REST clients publishing using that connection_key', em_timeout: 10 do
|
213
211
|
no_echo_channel.attach do
|
214
212
|
no_echo_channel.subscribe('test_event') do |message|
|
215
213
|
fail "Message should not have been echoed back"
|
216
214
|
end
|
217
215
|
|
218
|
-
rest_client.channel(channel_name).publish('test_event', nil,
|
216
|
+
rest_client.channel(channel_name).publish('test_event', nil, connection_key: no_echo_client.connection.key)
|
217
|
+
EventMachine.add_timer(1.5) do
|
218
|
+
stop_reactor
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'will echo messages with a valid connection_id to the client from other REST clients publishing using that connection_key', em_timeout: 10 do
|
224
|
+
channel.attach do
|
225
|
+
channel.subscribe('test_event') do |message|
|
226
|
+
expect(message.connection_id).to eql(client.connection.id)
|
227
|
+
end
|
228
|
+
|
229
|
+
rest_client.channel(channel_name).publish('test_event', nil, connection_key: client.connection.key)
|
219
230
|
EventMachine.add_timer(1.5) do
|
220
231
|
stop_reactor
|
221
232
|
end
|
@@ -599,7 +610,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
599
610
|
let(:event_name) { random_str }
|
600
611
|
let(:message_state) { [] }
|
601
612
|
let(:connection) { client.connection }
|
602
|
-
let(:client_options) { default_options.merge(:log_level => :
|
613
|
+
let(:client_options) { default_options.merge(:log_level => :fatal) }
|
603
614
|
let(:msgs_received) { [] }
|
604
615
|
|
605
616
|
it 'publishes the message again, later receives the ACK and only one message is ever received from Ably' do
|
@@ -642,6 +653,32 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
642
653
|
let(:connection) { client.connection }
|
643
654
|
let(:event_name) { random_str }
|
644
655
|
|
656
|
+
describe 'the connection is not resumed' do
|
657
|
+
let(:client_options) { default_options.merge(:log_level => :fatal) }
|
658
|
+
|
659
|
+
it 'calls the errback for all messages' do
|
660
|
+
connection.once(:connected) do
|
661
|
+
connection.transport.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
662
|
+
if protocol_message.messages.find { |message| message.name == event_name }
|
663
|
+
EventMachine.add_timer(0.0001) do
|
664
|
+
connection.transport.unbind # trigger failure
|
665
|
+
connection.configure_new '0123456789abcdef', 'wVIsgTHAB1UvXh7z-1991d8586', -1 # force the resume connection key to be invalid
|
666
|
+
end
|
667
|
+
end
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
671
|
+
channel.publish(event_name).tap do |deferrable|
|
672
|
+
deferrable.callback do
|
673
|
+
raise 'Message delivery should not happen'
|
674
|
+
end
|
675
|
+
deferrable.errback do
|
676
|
+
stop_reactor
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
645
682
|
describe 'the connection becomes suspended' do
|
646
683
|
let(:client_options) { default_options.merge(:log_level => :fatal) }
|
647
684
|
|
@@ -649,8 +686,10 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
649
686
|
connection.once(:connected) do
|
650
687
|
connection.transport.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
651
688
|
if protocol_message.messages.find { |message| message.name == event_name }
|
652
|
-
EventMachine.add_timer(0.
|
689
|
+
EventMachine.add_timer(0.0001) do
|
653
690
|
connection.transition_state_machine :suspended
|
691
|
+
stub_const 'Ably::FALLBACK_HOSTS', []
|
692
|
+
allow(client).to receive(:endpoint).and_return(URI::Generic.build(scheme: 'wss', host: 'does.not.exist.com'))
|
654
693
|
end
|
655
694
|
end
|
656
695
|
end
|
@@ -71,6 +71,10 @@ describe Ably::Realtime::Presence, 'history', :event_machine do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
context 'and two pages of messages' do
|
74
|
+
let(:wildcard_token) { Proc.new { Ably::Rest::Client.new(default_options).auth.request_token(client_id: '*') } }
|
75
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(auth_callback: wildcard_token)) }
|
76
|
+
let(:client_two) { auto_close Ably::Realtime::Client.new(default_options.merge(auth_callback: wildcard_token)) }
|
77
|
+
|
74
78
|
it 'retrieves two pages of messages before channel was attached' do
|
75
79
|
when_all(*10.times.map { |i| presence_client_two.enter_client("client:#{i}", data: presence_data_before_attach) }) do
|
76
80
|
when_all(*10.times.map { |i| presence_client_one.enter_client("client:#{i}", data: presence_data_after_attach) }) do
|
@@ -9,9 +9,12 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
9
9
|
let(:client_options) { default_options }
|
10
10
|
|
11
11
|
let(:anonymous_client) { auto_close Ably::Realtime::Client.new(client_options) }
|
12
|
-
let(:
|
13
|
-
let(:
|
12
|
+
let(:client_one_id) { random_str }
|
13
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(client_id: client_one_id)) }
|
14
|
+
let(:client_two_id) { random_str }
|
15
|
+
let(:client_two) { auto_close Ably::Realtime::Client.new(client_options.merge(client_id: client_two_id)) }
|
14
16
|
|
17
|
+
let(:wildcard_token) { Proc.new { Ably::Rest::Client.new(client_options).auth.request_token(client_id: '*') } }
|
15
18
|
let(:channel_name) { "presence-#{random_str(4)}" }
|
16
19
|
let(:channel_anonymous_client) { anonymous_client.channel(channel_name) }
|
17
20
|
let(:presence_anonymous_client) { channel_anonymous_client.presence }
|
@@ -29,6 +32,14 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
29
32
|
end
|
30
33
|
|
31
34
|
shared_examples_for 'a public presence method' do |method_name, expected_state, args, options = {}|
|
35
|
+
let(:client_id) do
|
36
|
+
if args.empty?
|
37
|
+
random_str
|
38
|
+
else
|
39
|
+
args
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
32
43
|
def setup_test(method_name, args, options)
|
33
44
|
if options[:enter_first]
|
34
45
|
presence_client_one.public_send(method_name.to_s.gsub(/leave|update/, 'enter'), args) do
|
@@ -72,7 +83,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
72
83
|
end
|
73
84
|
|
74
85
|
context 'when :queue_messages client option is false' do
|
75
|
-
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id:
|
86
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: client_id)) }
|
76
87
|
|
77
88
|
context 'and connection state initialized' do
|
78
89
|
it 'raises an exception' do
|
@@ -94,7 +105,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
94
105
|
end
|
95
106
|
|
96
107
|
context 'and connection state disconnected' do
|
97
|
-
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id:
|
108
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: client_id, :log_level => :error)) }
|
98
109
|
|
99
110
|
it 'raises an exception' do
|
100
111
|
client_one.connection.once(:connected) do
|
@@ -122,7 +133,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
122
133
|
context 'with supported data payload content type' do
|
123
134
|
def register_presence_and_check_data(method_name, data)
|
124
135
|
if method_name.to_s.match(/_client/)
|
125
|
-
presence_client_one.public_send(method_name,
|
136
|
+
presence_client_one.public_send(method_name, client_id, data: data)
|
126
137
|
else
|
127
138
|
presence_client_one.public_send(method_name, data: data)
|
128
139
|
end
|
@@ -177,7 +188,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
177
188
|
context 'with unsupported data payload content type' do
|
178
189
|
def presence_action(method_name, data)
|
179
190
|
if method_name.to_s.match(/_client/)
|
180
|
-
presence_client_one.public_send(method_name,
|
191
|
+
presence_client_one.public_send(method_name, client_id, data: data)
|
181
192
|
else
|
182
193
|
presence_client_one.public_send(method_name, data: data)
|
183
194
|
end
|
@@ -255,15 +266,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
255
266
|
end
|
256
267
|
|
257
268
|
context 'if connection fails before success' do
|
258
|
-
before do
|
259
|
-
# Reconfigure client library so that it makes no retry attempts and fails immediately
|
260
|
-
stub_const 'Ably::Realtime::Connection::ConnectionManager::CONNECT_RETRY_CONFIG',
|
261
|
-
Ably::Realtime::Connection::ConnectionManager::CONNECT_RETRY_CONFIG.merge(
|
262
|
-
disconnected: { retry_every: 0.1, max_time_in_state: 0 },
|
263
|
-
suspended: { retry_every: 0.1, max_time_in_state: 0 }
|
264
|
-
)
|
265
|
-
end
|
266
|
-
|
267
269
|
let(:client_options) { default_options.merge(log_level: :none) }
|
268
270
|
|
269
271
|
it 'calls the Deferrable errback if channel is detached' do
|
@@ -272,7 +274,8 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
272
274
|
client_one.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
273
275
|
# Don't allow any messages to reach the server
|
274
276
|
client_one.connection.__outgoing_protocol_msgbus__.unsubscribe
|
275
|
-
|
277
|
+
error_message = Ably::Models::ProtocolMessage.new(action: 9, error: { message: 'force failure' })
|
278
|
+
client_one.connection.__incoming_protocol_msgbus__.publish :protocol_message, error_message
|
276
279
|
end
|
277
280
|
|
278
281
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
@@ -288,6 +291,123 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
288
291
|
end
|
289
292
|
end
|
290
293
|
|
294
|
+
shared_examples_for 'a presence on behalf of another client method' do |method_name|
|
295
|
+
context ":#{method_name} when authenticated with a wildcard client_id" do
|
296
|
+
let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: '*').token }
|
297
|
+
let(:client_options) { default_options.merge(key: nil, token: token) }
|
298
|
+
let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
|
299
|
+
let(:presence_channel) { client.channels.get(channel_name).presence }
|
300
|
+
|
301
|
+
context 'and a valid client_id' do
|
302
|
+
it 'succeeds' do
|
303
|
+
presence_channel.public_send(method_name, 'clientId') do
|
304
|
+
EM.add_timer(0.5) { stop_reactor }
|
305
|
+
end.tap do |deferrable|
|
306
|
+
deferrable.errback { raise 'Should have succeeded' }
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'and a wildcard client_id' do
|
312
|
+
it 'throws an exception' do
|
313
|
+
expect { presence_channel.public_send(method_name, '*') }.to raise_error Ably::Exceptions::IncompatibleClientId
|
314
|
+
stop_reactor
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
context 'and an empty client_id' do
|
319
|
+
it 'throws an exception' do
|
320
|
+
expect { presence_channel.public_send(method_name, nil) }.to raise_error Ably::Exceptions::IncompatibleClientId
|
321
|
+
stop_reactor
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context ":#{method_name} when authenticated with a valid client_id" do
|
327
|
+
let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: 'valid').token }
|
328
|
+
let(:client_options) { default_options.merge(key: nil, token: token) }
|
329
|
+
let(:client) { auto_close Ably::Realtime::Client.new(client_options.merge(log_level: :error)) }
|
330
|
+
let(:channel) { client.channels.get(channel_name) }
|
331
|
+
let(:presence_channel) { channel.presence }
|
332
|
+
|
333
|
+
context 'and another invalid client_id' do
|
334
|
+
context 'before authentication' do
|
335
|
+
it 'allows the operation and then Ably rejects the operation' do
|
336
|
+
presence_channel.public_send(method_name, 'invalid').errback do |error|
|
337
|
+
expect(error.code).to eql(40012)
|
338
|
+
stop_reactor
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
context 'after authentication' do
|
344
|
+
it 'throws an exception' do
|
345
|
+
channel.attach do
|
346
|
+
expect { presence_channel.public_send(method_name, 'invalid') }.to raise_error Ably::Exceptions::IncompatibleClientId
|
347
|
+
stop_reactor
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context 'and a wildcard client_id' do
|
354
|
+
it 'throws an exception' do
|
355
|
+
expect { presence_channel.public_send(method_name, '*') }.to raise_error Ably::Exceptions::IncompatibleClientId
|
356
|
+
stop_reactor
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
context 'and an empty client_id' do
|
361
|
+
it 'throws an exception' do
|
362
|
+
expect { presence_channel.public_send(method_name, nil) }.to raise_error Ably::Exceptions::IncompatibleClientId
|
363
|
+
stop_reactor
|
364
|
+
end
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
context ":#{method_name} when anonymous and no client_id" do
|
369
|
+
let(:token) { Ably::Rest::Client.new(default_options).auth.request_token(client_id: nil).token }
|
370
|
+
let(:client_options) { default_options.merge(key: nil, token: token) }
|
371
|
+
let(:client) { auto_close Ably::Realtime::Client.new(client_options.merge(log_level: :error)) }
|
372
|
+
let(:channel) { client.channels.get(channel_name) }
|
373
|
+
let(:presence_channel) { channel.presence }
|
374
|
+
|
375
|
+
context 'and another invalid client_id' do
|
376
|
+
context 'before authentication' do
|
377
|
+
it 'allows the operation and then Ably rejects the operation' do
|
378
|
+
presence_channel.public_send(method_name, 'invalid').errback do |error|
|
379
|
+
expect(error.code).to eql(40012)
|
380
|
+
stop_reactor
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
context 'after authentication' do
|
386
|
+
it 'throws an exception' do
|
387
|
+
channel.attach do
|
388
|
+
expect { presence_channel.public_send(method_name, 'invalid') }.to raise_error Ably::Exceptions::IncompatibleClientId
|
389
|
+
stop_reactor
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
context 'and a wildcard client_id' do
|
396
|
+
it 'throws an exception' do
|
397
|
+
expect { presence_channel.public_send(method_name, '*') }.to raise_error Ably::Exceptions::IncompatibleClientId
|
398
|
+
stop_reactor
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context 'and an empty client_id' do
|
403
|
+
it 'throws an exception' do
|
404
|
+
expect { presence_channel.public_send(method_name, nil) }.to raise_error Ably::Exceptions::IncompatibleClientId
|
405
|
+
stop_reactor
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
291
411
|
context 'when attached (but not present) on a presence channel with an anonymous client (no client ID)' do
|
292
412
|
it 'maintains state as other clients enter and leave the channel' do
|
293
413
|
channel_anonymous_client.attach do
|
@@ -394,6 +514,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
394
514
|
let(:present) { [] }
|
395
515
|
let(:entered) { [] }
|
396
516
|
let(:sync_pages_received) { [] }
|
517
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
397
518
|
|
398
519
|
def setup_members_on(presence)
|
399
520
|
enter_expected_count.times do |index|
|
@@ -434,7 +555,10 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
434
555
|
presence_anonymous_client.subscribe(:leave) do |leave_message|
|
435
556
|
expect(leave_message.client_id).to eql(leave_member.client_id)
|
436
557
|
expect(present.count).to be < enter_expected_count
|
437
|
-
|
558
|
+
EventMachine.add_timer(1) do
|
559
|
+
presence_anonymous_client.unsubscribe
|
560
|
+
stop_reactor
|
561
|
+
end
|
438
562
|
end
|
439
563
|
|
440
564
|
anonymous_client.connect do
|
@@ -471,7 +595,10 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
471
595
|
if present.count == enter_expected_count
|
472
596
|
presence_anonymous_client.get do |members|
|
473
597
|
expect(members.find { |member| member.client_id == leave_member.client_id}.action).to eq(:present)
|
474
|
-
|
598
|
+
EventMachine.add_timer(1) do
|
599
|
+
presence_anonymous_client.unsubscribe
|
600
|
+
stop_reactor
|
601
|
+
end
|
475
602
|
end
|
476
603
|
end
|
477
604
|
end
|
@@ -523,7 +650,10 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
523
650
|
expect(members.count).to eql(enter_expected_count - 1)
|
524
651
|
expect(member_left_emitted).to eql(true)
|
525
652
|
expect(members.map(&:client_id)).to_not include(left_client_id)
|
526
|
-
|
653
|
+
EventMachine.add_timer(1) do
|
654
|
+
presence_anonymous_client.unsubscribe
|
655
|
+
stop_reactor
|
656
|
+
end
|
527
657
|
end
|
528
658
|
|
529
659
|
channel_anonymous_client.attach do
|
@@ -544,7 +674,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
544
674
|
|
545
675
|
context '#get' do
|
546
676
|
context 'with :wait_for_sync option set to true' do
|
547
|
-
it 'waits until sync is complete',
|
677
|
+
it 'waits until sync is complete', em_timeout: 15 do
|
548
678
|
enter_expected_count.times do |index|
|
549
679
|
presence_client_one.enter_client("client:#{index}") do |message|
|
550
680
|
entered << message
|
@@ -561,7 +691,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
561
691
|
end
|
562
692
|
|
563
693
|
context 'by default' do
|
564
|
-
it 'it does not wait for sync',
|
694
|
+
it 'it does not wait for sync', em_timeout: 15 do
|
565
695
|
enter_expected_count.times do |index|
|
566
696
|
presence_client_one.enter_client("client:#{index}") do |message|
|
567
697
|
entered << message
|
@@ -656,7 +786,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
656
786
|
end
|
657
787
|
|
658
788
|
it 'raises an exception if client_id is not set' do
|
659
|
-
expect { channel_anonymous_client.presence.enter }.to raise_error(Ably::Exceptions::
|
789
|
+
expect { channel_anonymous_client.presence.enter }.to raise_error(Ably::Exceptions::IncompatibleClientId, /without a client_id/)
|
660
790
|
stop_reactor
|
661
791
|
end
|
662
792
|
|
@@ -789,7 +919,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
789
919
|
end
|
790
920
|
|
791
921
|
it 'raises an exception if not entered' do
|
792
|
-
expect {
|
922
|
+
expect { channel_client_one.presence.leave }.to raise_error(Ably::Exceptions::Standard, /Unable to leave presence channel that is not entered/)
|
793
923
|
stop_reactor
|
794
924
|
end
|
795
925
|
|
@@ -824,8 +954,10 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
824
954
|
|
825
955
|
context 'entering/updating/leaving presence state on behalf of another client_id' do
|
826
956
|
let(:client_count) { 5 }
|
827
|
-
let(:clients)
|
828
|
-
let(:data)
|
957
|
+
let(:clients) { [] }
|
958
|
+
let(:data) { random_str }
|
959
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
960
|
+
let(:client_two) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
829
961
|
|
830
962
|
context '#enter_client' do
|
831
963
|
context 'multiple times on the same channel with different client_ids' do
|
@@ -875,8 +1007,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
875
1007
|
end
|
876
1008
|
end
|
877
1009
|
|
878
|
-
it_should_behave_like 'a public presence method', :enter_client, nil, 'client_id'
|
879
|
-
|
880
1010
|
context 'without necessary capabilities to enter on behalf of another client' do
|
881
1011
|
let(:restricted_client) do
|
882
1012
|
auto_close Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
@@ -891,6 +1021,9 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
891
1021
|
end
|
892
1022
|
end
|
893
1023
|
end
|
1024
|
+
|
1025
|
+
it_should_behave_like 'a public presence method', :enter_client, nil, 'client_id'
|
1026
|
+
it_should_behave_like 'a presence on behalf of another client method', :enter_client
|
894
1027
|
end
|
895
1028
|
|
896
1029
|
context '#update_client' do
|
@@ -955,6 +1088,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
955
1088
|
end
|
956
1089
|
|
957
1090
|
it_should_behave_like 'a public presence method', :update_client, nil, 'client_id'
|
1091
|
+
it_should_behave_like 'a presence on behalf of another client method', :update_client
|
958
1092
|
end
|
959
1093
|
|
960
1094
|
context '#leave_client' do
|
@@ -1048,6 +1182,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1048
1182
|
end
|
1049
1183
|
|
1050
1184
|
it_should_behave_like 'a public presence method', :leave_client, nil, 'client_id'
|
1185
|
+
it_should_behave_like 'a presence on behalf of another client method', :leave_client
|
1051
1186
|
end
|
1052
1187
|
end
|
1053
1188
|
|
@@ -1091,10 +1226,11 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1091
1226
|
end
|
1092
1227
|
|
1093
1228
|
context 'during a sync' do
|
1094
|
-
let(:pages)
|
1095
|
-
let(:members_per_page)
|
1229
|
+
let(:pages) { 2 }
|
1230
|
+
let(:members_per_page) { 100 }
|
1096
1231
|
let(:sync_pages_received) { [] }
|
1097
|
-
let(:
|
1232
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
1233
|
+
let(:client_options) { default_options.merge(log_level: :none) }
|
1098
1234
|
|
1099
1235
|
def connect_members_deferrables
|
1100
1236
|
(members_per_page * pages + 1).times.map do |index|
|
@@ -1102,15 +1238,6 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1102
1238
|
end
|
1103
1239
|
end
|
1104
1240
|
|
1105
|
-
before do
|
1106
|
-
# Reconfigure client library so that it makes no retry attempts and fails immediately
|
1107
|
-
stub_const 'Ably::Realtime::Connection::ConnectionManager::CONNECT_RETRY_CONFIG',
|
1108
|
-
Ably::Realtime::Connection::ConnectionManager::CONNECT_RETRY_CONFIG.merge(
|
1109
|
-
disconnected: { retry_every: 0.1, max_time_in_state: 0 },
|
1110
|
-
suspended: { retry_every: 0.1, max_time_in_state: 0 }
|
1111
|
-
)
|
1112
|
-
end
|
1113
|
-
|
1114
1241
|
context 'when :wait_for_sync is true' do
|
1115
1242
|
it 'fails if the connection fails' do
|
1116
1243
|
when_all(*connect_members_deferrables) do
|
@@ -1118,7 +1245,10 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1118
1245
|
client_two.connection.transport.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
1119
1246
|
if protocol_message.action == :sync
|
1120
1247
|
sync_pages_received << protocol_message
|
1121
|
-
|
1248
|
+
if sync_pages_received.count == 1
|
1249
|
+
error_message = Ably::Models::ProtocolMessage.new(action: 9, error: { message: 'force failure' })
|
1250
|
+
client_two.connection.__incoming_protocol_msgbus__.publish :protocol_message, error_message
|
1251
|
+
end
|
1122
1252
|
end
|
1123
1253
|
end
|
1124
1254
|
end
|
@@ -1196,22 +1326,22 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1196
1326
|
end
|
1197
1327
|
|
1198
1328
|
it 'filters by client_id option if provided' do
|
1199
|
-
presence_client_one.enter
|
1200
|
-
presence_client_two.enter
|
1329
|
+
presence_client_one.enter do
|
1330
|
+
presence_client_two.enter
|
1201
1331
|
end
|
1202
1332
|
|
1203
1333
|
presence_client_one.subscribe(:enter) do |presence_message|
|
1204
1334
|
# wait until the client_two enter event has been sent to client_one
|
1205
|
-
next unless presence_message.client_id ==
|
1335
|
+
next unless presence_message.client_id == client_two_id
|
1206
1336
|
|
1207
|
-
presence_client_one.get(client_id:
|
1337
|
+
presence_client_one.get(client_id: client_one_id) do |members|
|
1208
1338
|
expect(members.count).to eq(1)
|
1209
|
-
expect(members.first.client_id).to eql(
|
1339
|
+
expect(members.first.client_id).to eql(client_one_id)
|
1210
1340
|
expect(members.first.connection_id).to eql(client_one.connection.id)
|
1211
1341
|
|
1212
|
-
presence_client_one.get(client_id:
|
1342
|
+
presence_client_one.get(client_id: client_two_id) do |members|
|
1213
1343
|
expect(members.count).to eq(1)
|
1214
|
-
expect(members.first.client_id).to eql(
|
1344
|
+
expect(members.first.client_id).to eql(client_two_id)
|
1215
1345
|
expect(members.first.connection_id).to eql(client_two.connection.id)
|
1216
1346
|
stop_reactor
|
1217
1347
|
end
|
@@ -1220,7 +1350,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1220
1350
|
end
|
1221
1351
|
|
1222
1352
|
it 'does not wait for SYNC to complete if :wait_for_sync option is false' do
|
1223
|
-
presence_client_one.enter
|
1353
|
+
presence_client_one.enter do
|
1224
1354
|
presence_client_two.get(wait_for_sync: false) do |members|
|
1225
1355
|
expect(members.count).to eql(0)
|
1226
1356
|
stop_reactor
|
@@ -1242,6 +1372,8 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1242
1372
|
end
|
1243
1373
|
|
1244
1374
|
context 'with lots of members on different clients' do
|
1375
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
1376
|
+
let(:client_two) { auto_close Ably::Realtime::Client.new(client_options.merge(auth_callback: wildcard_token)) }
|
1245
1377
|
let(:members_per_client) { 10 }
|
1246
1378
|
let(:clients_entered) { Hash.new { |hash, key| hash[key] = 0 } }
|
1247
1379
|
let(:total_members) { members_per_client * 2 }
|
@@ -1588,7 +1720,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1588
1720
|
|
1589
1721
|
it 'resumes the SYNC operation', em_timeout: 15 do
|
1590
1722
|
when_all(*members_count.times.map do |index|
|
1591
|
-
|
1723
|
+
presence_anonymous_client.enter_client("client:#{index}")
|
1592
1724
|
end) do
|
1593
1725
|
channel_client_two.attach do
|
1594
1726
|
client_two.connection.transport.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|