ably 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +42 -48
  4. data/SPEC.md +1099 -640
  5. data/ably.gemspec +10 -4
  6. data/lib/ably/auth.rb +155 -47
  7. data/lib/ably/exceptions.rb +2 -0
  8. data/lib/ably/models/channel_state_change.rb +2 -3
  9. data/lib/ably/models/connection_details.rb +54 -0
  10. data/lib/ably/models/protocol_message.rb +14 -4
  11. data/lib/ably/models/token_details.rb +13 -7
  12. data/lib/ably/models/token_request.rb +1 -2
  13. data/lib/ably/modules/ably.rb +3 -2
  14. data/lib/ably/modules/message_emitter.rb +1 -3
  15. data/lib/ably/modules/state_emitter.rb +2 -2
  16. data/lib/ably/realtime/auth.rb +6 -0
  17. data/lib/ably/realtime/channel/channel_manager.rb +2 -0
  18. data/lib/ably/realtime/channel.rb +15 -4
  19. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
  20. data/lib/ably/realtime/client.rb +10 -3
  21. data/lib/ably/realtime/connection/connection_manager.rb +58 -54
  22. data/lib/ably/realtime/connection.rb +62 -6
  23. data/lib/ably/realtime/presence.rb +18 -5
  24. data/lib/ably/rest/channel.rb +9 -1
  25. data/lib/ably/rest/client.rb +32 -14
  26. data/lib/ably/rest/presence.rb +1 -1
  27. data/lib/ably/version.rb +1 -1
  28. data/lib/ably.rb +2 -0
  29. data/spec/acceptance/realtime/auth_spec.rb +251 -11
  30. data/spec/acceptance/realtime/channel_history_spec.rb +12 -2
  31. data/spec/acceptance/realtime/channel_spec.rb +316 -24
  32. data/spec/acceptance/realtime/client_spec.rb +93 -1
  33. data/spec/acceptance/realtime/connection_failures_spec.rb +177 -86
  34. data/spec/acceptance/realtime/connection_spec.rb +284 -60
  35. data/spec/acceptance/realtime/message_spec.rb +45 -6
  36. data/spec/acceptance/realtime/presence_history_spec.rb +4 -0
  37. data/spec/acceptance/realtime/presence_spec.rb +181 -49
  38. data/spec/acceptance/realtime/time_spec.rb +13 -0
  39. data/spec/acceptance/rest/auth_spec.rb +222 -4
  40. data/spec/acceptance/rest/channel_spec.rb +132 -1
  41. data/spec/acceptance/rest/client_spec.rb +129 -28
  42. data/spec/acceptance/rest/presence_spec.rb +7 -7
  43. data/spec/acceptance/rest/time_spec.rb +10 -0
  44. data/spec/shared/client_initializer_behaviour.rb +41 -17
  45. data/spec/spec_helper.rb +1 -0
  46. data/spec/support/debug_failure_helper.rb +16 -0
  47. data/spec/unit/models/connection_details_spec.rb +60 -0
  48. data/spec/unit/models/protocol_message_spec.rb +45 -0
  49. data/spec/unit/modules/event_emitter_spec.rb +3 -1
  50. data/spec/unit/realtime/channel_spec.rb +6 -5
  51. data/spec/unit/realtime/client_spec.rb +5 -1
  52. data/spec/unit/realtime/connection_spec.rb +5 -1
  53. data/spec/unit/realtime/realtime_spec.rb +5 -1
  54. metadata +54 -7
@@ -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(:client_one) { auto_close Ably::Realtime::Client.new(client_options.merge(client_id: random_str)) }
13
- let(:client_two) { auto_close Ably::Realtime::Client.new(client_options.merge(client_id: random_str)) }
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: random_str)) }
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: random_str, :log_level => :error)) }
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, 'client_id', data: data)
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, 'client_id', data: data)
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
- force_connection_failure client_one
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
- stop_reactor
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
- stop_reactor
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
- stop_reactor
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', event_machine: 15 do
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', event_machine: 15 do
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::Standard, /without a client_id/)
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 { channel_anonymous_client.presence.leave }.to raise_error(Ably::Exceptions::Standard, /Unable to leave presence channel that is not entered/)
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) { random_str }
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) { 2 }
1095
- let(:members_per_page) { 100 }
1229
+ let(:pages) { 2 }
1230
+ let(:members_per_page) { 100 }
1096
1231
  let(:sync_pages_received) { [] }
1097
- let(:client_options) { default_options.merge(log_level: :none) }
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
- force_connection_failure client_two if sync_pages_received.count == 1
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(client_id: 'one') do
1200
- presence_client_two.enter client_id: 'two'
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 == 'two'
1335
+ next unless presence_message.client_id == client_two_id
1206
1336
 
1207
- presence_client_one.get(client_id: 'one') do |members|
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('one')
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: 'two') do |members|
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('two')
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(client_id: 'one') do
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
- presence_client_one.enter_client("client:#{index}")
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|
@@ -22,6 +22,19 @@ describe Ably::Realtime::Client, '#time', :event_machine do
22
22
  stop_reactor
23
23
  end
24
24
  end
25
+
26
+ context 'with reconfigured HTTP timeout' do
27
+ let(:client) do
28
+ auto_close Ably::Realtime::Client.new(http_request_timeout: 0.0001, key: api_key, environment: environment, protocol: protocol, log_level: :fatal)
29
+ end
30
+
31
+ it 'should raise a timeout exception' do
32
+ client.time.errback do |error|
33
+ expect(error).to be_a Ably::Exceptions::ConnectionTimeout
34
+ stop_reactor
35
+ end
36
+ end
37
+ end
25
38
  end
26
39
  end
27
40
  end