ably 0.7.0 → 0.7.1
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.
- 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
|