ably 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -2
- data/Rakefile +2 -0
- data/SPEC.md +230 -194
- data/ably.gemspec +2 -0
- data/lib/ably/auth.rb +7 -5
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +5 -7
- data/lib/ably/models/paginated_resource.rb +14 -21
- data/lib/ably/models/protocol_message.rb +1 -1
- data/lib/ably/modules/ably.rb +4 -0
- data/lib/ably/modules/async_wrapper.rb +2 -2
- data/lib/ably/modules/channels_collection.rb +31 -8
- data/lib/ably/modules/conversions.rb +10 -0
- data/lib/ably/modules/enum.rb +2 -3
- data/lib/ably/modules/state_emitter.rb +8 -8
- data/lib/ably/modules/state_machine.rb +7 -3
- data/lib/ably/realtime/channel.rb +6 -5
- data/lib/ably/realtime/channel/channel_manager.rb +11 -10
- data/lib/ably/realtime/channel/channel_state_machine.rb +10 -9
- data/lib/ably/realtime/channels.rb +3 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
- data/lib/ably/realtime/connection.rb +55 -16
- data/lib/ably/realtime/connection/connection_manager.rb +25 -8
- data/lib/ably/realtime/connection/connection_state_machine.rb +9 -9
- data/lib/ably/realtime/connection/websocket_transport.rb +2 -2
- data/lib/ably/realtime/presence.rb +16 -17
- data/lib/ably/util/crypto.rb +1 -1
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +6 -5
- data/spec/acceptance/realtime/connection_failures_spec.rb +103 -27
- data/spec/acceptance/realtime/connection_spec.rb +81 -17
- data/spec/acceptance/realtime/presence_spec.rb +82 -30
- data/spec/acceptance/rest/auth_spec.rb +22 -19
- data/spec/acceptance/rest/client_spec.rb +4 -4
- data/spec/acceptance/rest/presence_spec.rb +12 -6
- data/spec/rspec_config.rb +9 -0
- data/spec/shared/model_behaviour.rb +1 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/support/event_machine_helper.rb +26 -37
- data/spec/support/markdown_spec_formatter.rb +96 -68
- data/spec/support/rest_testapp_before_retry.rb +15 -0
- data/spec/support/test_app.rb +4 -0
- data/spec/unit/models/idiomatic_ruby_wrapper_spec.rb +20 -2
- data/spec/unit/models/message_spec.rb +1 -1
- data/spec/unit/models/paginated_resource_spec.rb +15 -1
- data/spec/unit/modules/enum_spec.rb +10 -0
- data/spec/unit/realtime/channels_spec.rb +30 -0
- data/spec/unit/rest/channels_spec.rb +30 -0
- metadata +101 -35
- checksums.yaml +0 -7
@@ -192,7 +192,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
192
192
|
it 'is reset to nil when :connected' do
|
193
193
|
connection.once(:disconnected) do |error|
|
194
194
|
# stub the host so that the connection connects
|
195
|
-
allow(connection).to receive(:
|
195
|
+
allow(connection).to receive(:determine_host).and_yield(TestApp.instance.realtime_host)
|
196
196
|
connection.once(:connected) do
|
197
197
|
expect(connection.error_reason).to be_nil
|
198
198
|
stop_reactor
|
@@ -393,6 +393,59 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
393
393
|
end
|
394
394
|
end
|
395
395
|
end
|
396
|
+
|
397
|
+
context 'when failing to resume because the connection_key is not or no longer valid' do
|
398
|
+
def kill_connection_transport_and_prevent_valid_resume
|
399
|
+
connection.transport.close_connection_after_writing
|
400
|
+
connection.update_connection_id_and_key '0123456789abcdef', '0123456789abcdef' # force the resume connection key to be invalid
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'updates the connection_id and connection_key' do
|
404
|
+
connection.once(:connected) do
|
405
|
+
previous_connection_id = connection.id
|
406
|
+
previous_connection_key = connection.key
|
407
|
+
|
408
|
+
connection.once(:connected) do
|
409
|
+
expect(connection.key).to_not eql(previous_connection_key)
|
410
|
+
expect(connection.id).to_not eql(previous_connection_id)
|
411
|
+
stop_reactor
|
412
|
+
end
|
413
|
+
|
414
|
+
kill_connection_transport_and_prevent_valid_resume
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
it 'detaches all channels' do
|
419
|
+
channel_count = 10
|
420
|
+
channels = channel_count.times.map { |index| client.channel("channel-#{index}") }
|
421
|
+
when_all(*channels.map(&:attach)) do
|
422
|
+
detached_channels = []
|
423
|
+
channels.each do |channel|
|
424
|
+
channel.on(:detached) do
|
425
|
+
detached_channels << channel
|
426
|
+
next unless detached_channels.count == channel_count
|
427
|
+
expect(detached_channels.count).to eql(channel_count)
|
428
|
+
stop_reactor
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
kill_connection_transport_and_prevent_valid_resume
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'emits an error on the channel and sets the error reason' do
|
437
|
+
client.channel(random_str).attach do |channel|
|
438
|
+
channel.on(:error) do |error|
|
439
|
+
expect(error.message).to match(/Invalid connection key/i)
|
440
|
+
expect(error.code).to eql(80008)
|
441
|
+
expect(channel.error_reason).to eql(error)
|
442
|
+
stop_reactor
|
443
|
+
end
|
444
|
+
|
445
|
+
kill_connection_transport_and_prevent_valid_resume
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
396
449
|
end
|
397
450
|
|
398
451
|
describe 'fallback host feature' do
|
@@ -456,41 +509,64 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
456
509
|
|
457
510
|
let(:fallback_hosts_used) { Array.new }
|
458
511
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
512
|
+
context 'when the Internet is down' do
|
513
|
+
before do
|
514
|
+
allow(connection).to receive(:internet_up?).and_yield(false)
|
515
|
+
end
|
516
|
+
|
517
|
+
it 'never uses a fallback host' do
|
518
|
+
expect(EventMachine).to receive(:connect).exactly(retry_count_for_all_states).times do |host|
|
463
519
|
expect(host).to eql(expected_host)
|
464
|
-
|
465
|
-
expect(custom_hosts).to include(host)
|
466
|
-
fallback_hosts_used << host
|
520
|
+
raise EventMachine::ConnectionError
|
467
521
|
end
|
468
|
-
request += 1
|
469
|
-
raise EventMachine::ConnectionError
|
470
|
-
end
|
471
522
|
|
472
|
-
|
473
|
-
|
474
|
-
|
523
|
+
connection.on(:failed) do
|
524
|
+
stop_reactor
|
525
|
+
end
|
475
526
|
end
|
476
527
|
end
|
477
528
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
529
|
+
context 'when the Internet is up' do
|
530
|
+
before do
|
531
|
+
allow(connection).to receive(:internet_up?).and_yield(true)
|
532
|
+
end
|
533
|
+
|
534
|
+
it 'uses a fallback host on every subsequent disconnected attempt until suspended' do
|
535
|
+
request = 0
|
536
|
+
expect(EventMachine).to receive(:connect).exactly(retry_count_for_one_state).times do |host|
|
537
|
+
if request == 0
|
538
|
+
expect(host).to eql(expected_host)
|
539
|
+
else
|
540
|
+
expect(custom_hosts).to include(host)
|
541
|
+
fallback_hosts_used << host
|
542
|
+
end
|
543
|
+
request += 1
|
544
|
+
raise EventMachine::ConnectionError
|
545
|
+
end
|
546
|
+
|
547
|
+
connection.on(:suspended) do
|
548
|
+
expect(fallback_hosts_used.uniq).to match_array(custom_hosts)
|
549
|
+
stop_reactor
|
486
550
|
end
|
487
|
-
request += 1
|
488
|
-
raise EventMachine::ConnectionError
|
489
551
|
end
|
490
552
|
|
491
|
-
|
492
|
-
|
493
|
-
|
553
|
+
it 'uses the primary host when suspended, and a fallback host on every subsequent suspended attempt' do
|
554
|
+
request = 0
|
555
|
+
expect(EventMachine).to receive(:connect).exactly(retry_count_for_all_states).times do |host|
|
556
|
+
if request == 0 || request == expected_retry_attempts + 1
|
557
|
+
expect(host).to eql(expected_host)
|
558
|
+
else
|
559
|
+
expect(custom_hosts).to include(host)
|
560
|
+
fallback_hosts_used << host
|
561
|
+
end
|
562
|
+
request += 1
|
563
|
+
raise EventMachine::ConnectionError
|
564
|
+
end
|
565
|
+
|
566
|
+
connection.on(:failed) do
|
567
|
+
expect(fallback_hosts_used.uniq).to match_array(custom_hosts)
|
568
|
+
stop_reactor
|
569
|
+
end
|
494
570
|
end
|
495
571
|
end
|
496
572
|
end
|
@@ -93,7 +93,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
93
93
|
it 'renews the token on connect' do
|
94
94
|
sleep ttl + 0.1
|
95
95
|
expect(client.auth.current_token).to be_expired
|
96
|
-
expect(client.auth).to receive(:authorise).once.and_call_original
|
96
|
+
expect(client.auth).to receive(:authorise).at_least(:once).and_call_original
|
97
97
|
connection.once(:connected) do
|
98
98
|
expect(client.auth.current_token).to_not be_expired
|
99
99
|
stop_reactor
|
@@ -105,7 +105,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
105
105
|
let(:ttl) { 0.01 }
|
106
106
|
|
107
107
|
it 'renews the token on connect, and only makes one subsequent attempt to obtain a new token' do
|
108
|
-
expect(client.auth).to receive(:authorise).twice.and_call_original
|
108
|
+
expect(client.auth).to receive(:authorise).at_least(:twice).and_call_original
|
109
109
|
connection.once(:disconnected) do
|
110
110
|
connection.once(:failed) do |error|
|
111
111
|
expect(error.code).to eql(40140) # token expired
|
@@ -117,7 +117,10 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
117
117
|
it 'uses the primary host for subsequent connection and auth requests' do
|
118
118
|
EventMachine.add_timer(1) do # wait for token to expire
|
119
119
|
connection.once(:disconnected) do
|
120
|
-
expect(client.rest_client.connection).to receive(:post).
|
120
|
+
expect(client.rest_client.connection).to receive(:post).
|
121
|
+
with(/requestToken$/, anything).
|
122
|
+
at_least(:once).
|
123
|
+
and_call_original
|
121
124
|
|
122
125
|
expect(client.rest_client).to_not receive(:fallback_connection)
|
123
126
|
expect(client).to_not receive(:fallback_endpoint)
|
@@ -139,23 +142,25 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
139
142
|
|
140
143
|
context 'the server' do
|
141
144
|
it 'disconnects the client, and the client automatically renews the token and then reconnects', em_timeout: 10 do
|
142
|
-
expect(client.auth.current_token).to_not be_expired
|
143
|
-
|
144
|
-
channel.attach
|
145
145
|
original_token = client.auth.current_token
|
146
|
+
expect(original_token).to_not be_expired
|
146
147
|
|
147
148
|
connection.once(:connected) do
|
148
149
|
started_at = Time.now
|
149
150
|
connection.once(:disconnected) do |error|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
151
|
+
EventMachine.add_timer(1) do # allow 1 second
|
152
|
+
expect(Time.now - started_at >= ttl)
|
153
|
+
expect(original_token).to be_expired
|
154
|
+
expect(error.code).to eql(40140) # token expired
|
155
|
+
connection.once(:connected) do
|
156
|
+
expect(client.auth.current_token).to_not be_expired
|
157
|
+
stop_reactor
|
158
|
+
end
|
156
159
|
end
|
157
160
|
end
|
158
161
|
end
|
162
|
+
|
163
|
+
channel.attach
|
159
164
|
end
|
160
165
|
end
|
161
166
|
|
@@ -601,13 +606,28 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
601
606
|
end
|
602
607
|
end
|
603
608
|
|
604
|
-
context 'with invalid value' do
|
605
|
-
let(:client_options) { default_options.merge(recover: '
|
609
|
+
context 'with invalid formatted value sent to server' do
|
610
|
+
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1', log_level: :none) }
|
606
611
|
|
607
|
-
|
608
|
-
connection.
|
612
|
+
it 'triggers a fatal error on the connection object, sets the #error_reason and disconnects' do
|
613
|
+
connection.once(:error) do |error|
|
614
|
+
expect(connection.state).to eq(:failed)
|
615
|
+
expect(connection.error_reason.message).to match(/Invalid connection key/)
|
616
|
+
expect(connection.error_reason.code).to eql(40006)
|
617
|
+
expect(connection.error_reason).to eql(error)
|
618
|
+
stop_reactor
|
619
|
+
end
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
context 'with expired (missing) value sent to server' do
|
624
|
+
let(:client_options) { default_options.merge(recover: '0123456789abcdef:0', log_level: :fatal) }
|
625
|
+
|
626
|
+
it 'triggers an error on the connection object, sets the #error_reason, yet will connect anyway' do
|
627
|
+
connection.once(:error) do |error|
|
609
628
|
expect(connection.state).to eq(:connected)
|
610
|
-
expect(connection.error_reason.message).to match(/
|
629
|
+
expect(connection.error_reason.message).to match(/Invalid connection key/i)
|
630
|
+
expect(connection.error_reason.code).to eql(80008)
|
611
631
|
expect(connection.error_reason).to eql(error)
|
612
632
|
stop_reactor
|
613
633
|
end
|
@@ -652,5 +672,49 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
652
672
|
end
|
653
673
|
end
|
654
674
|
end
|
675
|
+
|
676
|
+
|
677
|
+
context 'undocumented method' do
|
678
|
+
context '#internet_up?' do
|
679
|
+
it 'returns a Deferrable' do
|
680
|
+
expect(connection.internet_up?).to be_a(EventMachine::Deferrable)
|
681
|
+
stop_reactor
|
682
|
+
end
|
683
|
+
|
684
|
+
context 'when the Internet is up' do
|
685
|
+
it 'calls the block with true' do
|
686
|
+
connection.internet_up? do |result|
|
687
|
+
expect(result).to be_truthy
|
688
|
+
stop_reactor
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
it 'calls the success callback of the Deferrable' do
|
693
|
+
connection.internet_up?.callback do
|
694
|
+
stop_reactor
|
695
|
+
end
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
699
|
+
context 'when the Internet is down' do
|
700
|
+
before do
|
701
|
+
stub_const 'Ably::INTERNET_CHECK', { url: 'http://does.not.exist.com', ok_text: 'no.way.this.will.match' }
|
702
|
+
end
|
703
|
+
|
704
|
+
it 'calls the block with false' do
|
705
|
+
connection.internet_up? do |result|
|
706
|
+
expect(result).to be_falsey
|
707
|
+
stop_reactor
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
it 'calls the failure callback of the Deferrable' do
|
712
|
+
connection.internet_up?.errback do
|
713
|
+
stop_reactor
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
end
|
718
|
+
end
|
655
719
|
end
|
656
720
|
end
|
@@ -256,6 +256,16 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
256
256
|
end
|
257
257
|
end
|
258
258
|
|
259
|
+
it 'updates the data to nil if :data argument is not provided (assumes nil value)' do
|
260
|
+
presence_client_one.enter(data: 'prior') do
|
261
|
+
presence_client_one.update
|
262
|
+
end
|
263
|
+
presence_client_one.subscribe(:update) do |message|
|
264
|
+
expect(message.data).to be_nil
|
265
|
+
stop_reactor
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
259
269
|
it 'returns a Deferrable' do
|
260
270
|
presence_client_one.enter do
|
261
271
|
expect(presence_client_one.update).to be_a(EventMachine::Deferrable)
|
@@ -277,10 +287,11 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
277
287
|
context '#leave' do
|
278
288
|
context ':data option' do
|
279
289
|
let(:data) { random_str }
|
290
|
+
let(:enter_data) { random_str }
|
280
291
|
|
281
292
|
context 'when set to a string' do
|
282
293
|
it 'emits the new data for the leave event' do
|
283
|
-
presence_client_one.enter data:
|
294
|
+
presence_client_one.enter data: enter_data do
|
284
295
|
presence_client_one.leave data: data
|
285
296
|
end
|
286
297
|
|
@@ -292,26 +303,26 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
292
303
|
end
|
293
304
|
|
294
305
|
context 'when set to nil' do
|
295
|
-
it 'emits
|
296
|
-
presence_client_one.enter data:
|
306
|
+
it 'emits the previously defined value as a convenience' do
|
307
|
+
presence_client_one.enter data: enter_data do
|
297
308
|
presence_client_one.leave data: nil
|
298
309
|
end
|
299
310
|
|
300
311
|
presence_client_one.subscribe(:leave) do |presence_message|
|
301
|
-
expect(presence_message.data).to
|
312
|
+
expect(presence_message.data).to eql(enter_data)
|
302
313
|
stop_reactor
|
303
314
|
end
|
304
315
|
end
|
305
316
|
end
|
306
317
|
|
307
318
|
context 'when not passed as an argument' do
|
308
|
-
it 'emits the
|
309
|
-
presence_client_one.enter data:
|
319
|
+
it 'emits the previously defined value as a convenience' do
|
320
|
+
presence_client_one.enter data: enter_data do
|
310
321
|
presence_client_one.leave
|
311
322
|
end
|
312
323
|
|
313
324
|
presence_client_one.subscribe(:leave) do |presence_message|
|
314
|
-
expect(presence_message.data).to eql(
|
325
|
+
expect(presence_message.data).to eql(enter_data)
|
315
326
|
stop_reactor
|
316
327
|
end
|
317
328
|
end
|
@@ -380,7 +391,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
380
391
|
presence_client_one.on(:entered) { raise 'Should not have entered' }
|
381
392
|
next unless client_id == client_count - 1
|
382
393
|
|
383
|
-
EventMachine.add_timer(
|
394
|
+
EventMachine.add_timer(1) do
|
384
395
|
expect(presence_client_one.state).to eq(:initialized)
|
385
396
|
stop_reactor
|
386
397
|
end
|
@@ -435,7 +446,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
435
446
|
clients << presence
|
436
447
|
next unless clients.count == 5
|
437
448
|
|
438
|
-
|
449
|
+
wait_until(proc { updated_callback_count == 5 }) do
|
439
450
|
expect(clients.map(&:client_id).uniq.count).to eql(5)
|
440
451
|
expect(updated_callback_count).to eql(5)
|
441
452
|
stop_reactor
|
@@ -443,6 +454,18 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
443
454
|
end
|
444
455
|
end
|
445
456
|
|
457
|
+
it 'updates the data attribute to null for the member when :data option is not provided (assumed null)' do
|
458
|
+
presence_client_one.enter_client('client_1') do
|
459
|
+
presence_client_one.update_client('client_1')
|
460
|
+
end
|
461
|
+
|
462
|
+
presence_anonymous_client.subscribe(:update) do |presence|
|
463
|
+
expect(presence.client_id).to eql('client_1')
|
464
|
+
expect(presence.data).to be_nil
|
465
|
+
stop_reactor
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
446
469
|
it 'enters if not already entered' do
|
447
470
|
updated_callback_count = 0
|
448
471
|
|
@@ -457,7 +480,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
457
480
|
clients << presence
|
458
481
|
next unless clients.count == 5
|
459
482
|
|
460
|
-
|
483
|
+
wait_until(proc { updated_callback_count == 5 }) do
|
461
484
|
expect(clients.map(&:client_id).uniq.count).to eql(5)
|
462
485
|
expect(updated_callback_count).to eql(5)
|
463
486
|
stop_reactor
|
@@ -498,7 +521,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
498
521
|
clients << presence
|
499
522
|
next unless clients.count == 5
|
500
523
|
|
501
|
-
|
524
|
+
wait_until(proc { left_callback_count == 5 }) do
|
502
525
|
expect(clients.map(&:client_id).uniq.count).to eql(5)
|
503
526
|
expect(left_callback_count).to eql(5)
|
504
527
|
stop_reactor
|
@@ -520,7 +543,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
520
543
|
clients << presence
|
521
544
|
next unless clients.count == 5
|
522
545
|
|
523
|
-
|
546
|
+
wait_until(proc { left_callback_count == 5 }) do
|
524
547
|
expect(clients.map(&:client_id).uniq.count).to eql(5)
|
525
548
|
expect(left_callback_count).to eql(5)
|
526
549
|
stop_reactor
|
@@ -543,20 +566,20 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
543
566
|
end
|
544
567
|
|
545
568
|
context 'with a nil value in :data option' do
|
546
|
-
it 'emits the leave event with
|
569
|
+
it 'emits the leave event with the previous value as a convenience' do
|
547
570
|
presence_client_one.enter_client("client:unique", data: data) do
|
548
571
|
presence_client_one.leave_client("client:unique", data: nil)
|
549
572
|
end
|
550
573
|
|
551
574
|
presence_client_one.subscribe(:leave) do |presence_message|
|
552
|
-
expect(presence_message.data).to
|
575
|
+
expect(presence_message.data).to eql(data)
|
553
576
|
stop_reactor
|
554
577
|
end
|
555
578
|
end
|
556
579
|
end
|
557
580
|
|
558
581
|
context 'with no :data option' do
|
559
|
-
it 'emits the leave event with the previous
|
582
|
+
it 'emits the leave event with the previous value as a convenience' do
|
560
583
|
presence_client_one.enter_client("client:unique", data: data) do
|
561
584
|
presence_client_one.leave_client("client:unique")
|
562
585
|
end
|
@@ -612,7 +635,14 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
612
635
|
end
|
613
636
|
|
614
637
|
it 'filters by connection_id option if provided' do
|
615
|
-
|
638
|
+
presence_client_one.enter do
|
639
|
+
presence_client_two.enter
|
640
|
+
end
|
641
|
+
|
642
|
+
presence_client_one.subscribe(:enter) do |presence_message|
|
643
|
+
# wait until the client_two enter event has been sent to client_one
|
644
|
+
next unless presence_message.client_id == client_two.client_id
|
645
|
+
|
616
646
|
presence_client_one.get(connection_id: client_one.connection.id) do |members|
|
617
647
|
expect(members.count).to eq(1)
|
618
648
|
expect(members.first.connection_id).to eql(client_one.connection.id)
|
@@ -627,7 +657,14 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
627
657
|
end
|
628
658
|
|
629
659
|
it 'filters by client_id option if provided' do
|
630
|
-
|
660
|
+
presence_client_one.enter(client_id: 'one') do
|
661
|
+
presence_client_two.enter client_id: 'two'
|
662
|
+
end
|
663
|
+
|
664
|
+
presence_client_one.subscribe(:enter) do |presence_message|
|
665
|
+
# wait until the client_two enter event has been sent to client_one
|
666
|
+
next unless presence_message.client_id == 'two'
|
667
|
+
|
631
668
|
presence_client_one.get(client_id: 'one') do |members|
|
632
669
|
expect(members.count).to eq(1)
|
633
670
|
expect(members.first.client_id).to eql('one')
|
@@ -665,21 +702,36 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
665
702
|
end
|
666
703
|
end
|
667
704
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
presence_client_two.get do |client_two_members|
|
673
|
-
expect(client_one_members.count).to eq(client_two_members.count)
|
705
|
+
context 'with lots of members on different clients' do
|
706
|
+
let(:members_per_client) { 10 }
|
707
|
+
let(:clients_entered) { Hash.new { |hash, key| hash[key] = 0 } }
|
708
|
+
let(:total_members) { members_per_client * 2 }
|
674
709
|
|
675
|
-
|
676
|
-
|
710
|
+
it 'returns a complete list of members on all clients' do
|
711
|
+
members_per_client.times do |index|
|
712
|
+
presence_client_one.enter_client("client_1:#{index}")
|
713
|
+
presence_client_two.enter_client("client_2:#{index}")
|
714
|
+
end
|
677
715
|
|
678
|
-
|
679
|
-
|
680
|
-
|
716
|
+
presence_client_one.subscribe(:enter) do
|
717
|
+
clients_entered[:client_one] += 1
|
718
|
+
end
|
681
719
|
|
682
|
-
|
720
|
+
presence_client_two.subscribe(:enter) do
|
721
|
+
clients_entered[:client_two] += 1
|
722
|
+
end
|
723
|
+
|
724
|
+
wait_until(proc { clients_entered[:client_one] + clients_entered[:client_two] == total_members * 2 }) do
|
725
|
+
presence_anonymous_client.get do |anonymous_members|
|
726
|
+
expect(anonymous_members.count).to eq(total_members)
|
727
|
+
expect(anonymous_members.map(&:client_id).uniq.count).to eq(total_members)
|
728
|
+
|
729
|
+
presence_client_one.get do |client_one_members|
|
730
|
+
presence_client_two.get do |client_two_members|
|
731
|
+
expect(client_one_members.count).to eq(total_members)
|
732
|
+
expect(client_one_members.count).to eq(client_two_members.count)
|
733
|
+
stop_reactor
|
734
|
+
end
|
683
735
|
end
|
684
736
|
end
|
685
737
|
end
|
@@ -720,7 +772,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
720
772
|
presence_client_one.enter
|
721
773
|
presence_client_one.update
|
722
774
|
presence_client_one.leave do
|
723
|
-
EventMachine.add_timer(
|
775
|
+
EventMachine.add_timer(1) do
|
724
776
|
stop_reactor
|
725
777
|
end
|
726
778
|
end
|