ably 0.8.4 → 0.8.5
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/Rakefile +1 -1
- data/lib/ably/auth.rb +23 -19
- data/lib/ably/models/token_details.rb +8 -6
- data/lib/ably/modules/conversions.rb +4 -0
- data/lib/ably/modules/state_emitter.rb +1 -1
- data/lib/ably/modules/uses_state_machine.rb +8 -1
- data/lib/ably/realtime/auth.rb +13 -13
- data/lib/ably/realtime/channel.rb +2 -2
- data/lib/ably/realtime/channel/channel_manager.rb +3 -3
- data/lib/ably/realtime/channel/channel_state_machine.rb +2 -1
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +13 -7
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +6 -0
- data/lib/ably/realtime/connection.rb +4 -4
- data/lib/ably/realtime/connection/connection_manager.rb +9 -3
- data/lib/ably/realtime/connection/connection_state_machine.rb +1 -1
- data/lib/ably/realtime/presence.rb +4 -4
- data/lib/ably/rest/client.rb +2 -2
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +9 -9
- data/spec/acceptance/realtime/channel_history_spec.rb +2 -2
- data/spec/acceptance/realtime/channel_spec.rb +13 -12
- data/spec/acceptance/realtime/channels_spec.rb +6 -2
- data/spec/acceptance/realtime/client_spec.rb +4 -3
- data/spec/acceptance/realtime/connection_failures_spec.rb +21 -15
- data/spec/acceptance/realtime/connection_spec.rb +31 -27
- data/spec/acceptance/realtime/message_spec.rb +31 -24
- data/spec/acceptance/realtime/presence_history_spec.rb +2 -2
- data/spec/acceptance/realtime/presence_spec.rb +10 -11
- data/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/spec/acceptance/realtime/time_spec.rb +1 -1
- data/spec/acceptance/rest/auth_spec.rb +77 -46
- data/spec/acceptance/rest/channel_spec.rb +22 -3
- data/spec/acceptance/rest/client_spec.rb +6 -6
- data/spec/acceptance/rest/presence_spec.rb +9 -7
- data/spec/support/event_machine_helper.rb +30 -4
- data/spec/support/protocol_helper.rb +9 -6
- data/spec/unit/auth_spec.rb +1 -1
- data/spec/unit/models/token_details_spec.rb +8 -0
- data/spec/unit/modules/async_wrapper_spec.rb +1 -1
- metadata +2 -2
@@ -11,7 +11,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
let(:client_options) { default_options }
|
14
|
-
let(:client) { Ably::Realtime::Client.new(client_options) }
|
14
|
+
let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
|
15
15
|
|
16
16
|
before(:example) do
|
17
17
|
EventMachine.add_shutdown_hook do
|
@@ -29,7 +29,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
29
29
|
|
30
30
|
context 'with :auto_connect option set to false' do
|
31
31
|
let(:client) do
|
32
|
-
Ably::Realtime::Client.new(default_options.merge(auto_connect: false))
|
32
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(auto_connect: false))
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'does not connect automatically' do
|
@@ -96,7 +96,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
96
96
|
stub_const 'Ably::Auth::TOKEN_DEFAULTS', Ably::Auth::TOKEN_DEFAULTS.merge(renew_token_buffer: 0)
|
97
97
|
|
98
98
|
# Authorise synchronously to ensure token has been issued
|
99
|
-
client.auth.authorise_sync(
|
99
|
+
client.auth.authorise_sync(ttl: ttl)
|
100
100
|
end
|
101
101
|
|
102
102
|
let(:original_renew_token_buffer) { @original_renew_token_buffer }
|
@@ -158,7 +158,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
158
158
|
context 'when connected with a valid non-expired token' do
|
159
159
|
context 'that then expires following the connection being opened' do
|
160
160
|
let(:ttl) { 5 }
|
161
|
-
let(:channel) { client.channel(
|
161
|
+
let(:channel) { client.channel(random_str) }
|
162
162
|
|
163
163
|
context 'the server' do
|
164
164
|
it 'disconnects the client, and the client automatically renews the token and then reconnects', em_timeout: 15 do
|
@@ -204,7 +204,8 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
204
204
|
|
205
205
|
let!(:expired_token_details) do
|
206
206
|
# Request a token synchronously
|
207
|
-
Ably::Realtime::Client.new(default_options)
|
207
|
+
token_client = auto_close Ably::Realtime::Client.new(default_options)
|
208
|
+
token_client.auth.request_token_sync(ttl: 0.01)
|
208
209
|
end
|
209
210
|
|
210
211
|
context 'opening a new connection' do
|
@@ -270,8 +271,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
270
271
|
end
|
271
272
|
|
272
273
|
it 'calls the Deferrable callback on success' do
|
273
|
-
connection.connect.callback do
|
274
|
-
expect(connection).to be_a(Ably::Realtime::Connection)
|
274
|
+
connection.connect.callback do
|
275
275
|
expect(connection.state).to eq(:connected)
|
276
276
|
stop_reactor
|
277
277
|
end
|
@@ -306,7 +306,8 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
306
306
|
end
|
307
307
|
|
308
308
|
describe 'once connected' do
|
309
|
-
let(:
|
309
|
+
let(:client2) { auto_close Ably::Realtime::Client.new(client_options) }
|
310
|
+
let(:connection2) { client2.connection }
|
310
311
|
|
311
312
|
describe 'connection#id' do
|
312
313
|
it 'is a string' do
|
@@ -436,7 +437,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
436
437
|
|
437
438
|
it 'calls the Deferrable callback on success' do
|
438
439
|
connection.connect do
|
439
|
-
connection.close.callback do
|
440
|
+
connection.close.callback do
|
440
441
|
expect(connection).to be_a(Ably::Realtime::Connection)
|
441
442
|
expect(connection.state).to eq(:closed)
|
442
443
|
stop_reactor
|
@@ -576,7 +577,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
576
577
|
let(:channel_name) { random_str }
|
577
578
|
let(:channel) { client.channel(channel_name) }
|
578
579
|
let(:publishing_client) do
|
579
|
-
Ably::Realtime::Client.new(client_options)
|
580
|
+
auto_close Ably::Realtime::Client.new(client_options)
|
580
581
|
end
|
581
582
|
let(:publishing_client_channel) { publishing_client.channel(channel_name) }
|
582
583
|
let(:client_options) { default_options.merge(log_level: :fatal) }
|
@@ -594,9 +595,10 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
594
595
|
def self.available_states
|
595
596
|
[:connecting, :connected, :disconnected, :suspended, :failed]
|
596
597
|
end
|
597
|
-
let(:available_states) { self.class.available_states}
|
598
|
+
let(:available_states) { self.class.available_states }
|
598
599
|
let(:states) { Hash.new }
|
599
600
|
let(:client_options) { default_options.merge(log_level: :none) }
|
601
|
+
let(:channel) { client.channel(random_str) }
|
600
602
|
|
601
603
|
it 'is composed of connection key and serial that is kept up to date with each message ACK received' do
|
602
604
|
connection.on(:connected) do
|
@@ -604,7 +606,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
604
606
|
expect(connection.key).to_not be_nil
|
605
607
|
expect(connection.serial).to eql(expected_serial)
|
606
608
|
|
607
|
-
|
609
|
+
channel.attach do
|
608
610
|
channel.publish('event', 'data') do
|
609
611
|
expected_serial += 1 # attach message received
|
610
612
|
expect(connection.serial).to eql(expected_serial)
|
@@ -670,9 +672,10 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
670
672
|
end
|
671
673
|
|
672
674
|
connection.once(:failed) do
|
673
|
-
recover_client = Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
675
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
674
676
|
recover_client.connection.on(:connected) do
|
675
|
-
expect(recover_client.connection.key).
|
677
|
+
expect(recover_client.connection.key[/^\w{5,}-/, 0]).to_not be_nil
|
678
|
+
expect(recover_client.connection.key[/^\w{5,}-/, 0]).to eql(previous_connection_key[/^\w{5,}-/, 0])
|
676
679
|
expect(recover_client.connection.id).to eql(previous_connection_id)
|
677
680
|
stop_reactor
|
678
681
|
end
|
@@ -685,7 +688,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
685
688
|
end
|
686
689
|
|
687
690
|
connection.once(:failed) do
|
688
|
-
recover_client = Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
691
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
689
692
|
recover_client.connection.on_resume do
|
690
693
|
raise 'Should not call the resume callback'
|
691
694
|
end
|
@@ -701,14 +704,15 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
701
704
|
let(:client_options) { default_options.merge(log_level: :none) }
|
702
705
|
|
703
706
|
it 'recovers server-side queued messages' do
|
704
|
-
channel.attach do
|
707
|
+
channel.attach do
|
705
708
|
connection.transition_state_machine! :failed
|
706
709
|
end
|
707
710
|
|
708
711
|
connection.on(:failed) do
|
709
712
|
publishing_client_channel.publish('event', 'message') do
|
710
|
-
recover_client = Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
711
|
-
recover_client.channel(channel_name)
|
713
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: client.connection.recovery_key))
|
714
|
+
recover_client_channel = recover_client.channel(channel_name)
|
715
|
+
recover_client_channel.attach do
|
712
716
|
recover_client_channel.subscribe('event') do |message|
|
713
717
|
expect(message.data).to eql('message')
|
714
718
|
stop_reactor
|
@@ -737,9 +741,9 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
737
741
|
it 'emits a fatal error on the connection object, sets the #error_reason and disconnects' do
|
738
742
|
connection.once(:error) do |error|
|
739
743
|
expect(connection.state).to eq(:failed)
|
740
|
-
expect(error.message).to match(/Invalid
|
741
|
-
expect(connection.error_reason.message).to match(/Invalid
|
742
|
-
expect(connection.error_reason.code).to eql(
|
744
|
+
expect(error.message).to match(/Invalid connectionKey/i)
|
745
|
+
expect(connection.error_reason.message).to match(/Invalid connectionKey/i)
|
746
|
+
expect(connection.error_reason.code).to eql(80018)
|
743
747
|
expect(connection.error_reason).to eql(error)
|
744
748
|
stop_reactor
|
745
749
|
end
|
@@ -747,13 +751,13 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
747
751
|
end
|
748
752
|
|
749
753
|
context 'with expired (missing) value sent to server' do
|
750
|
-
let(:client_options) { default_options.merge(recover: '
|
754
|
+
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0', log_level: :fatal) }
|
751
755
|
|
752
756
|
it 'emits an error on the connection object, sets the #error_reason, yet will connect anyway' do
|
753
757
|
connection.once(:error) do |error|
|
754
758
|
expect(connection.state).to eq(:connected)
|
755
|
-
expect(error.message).to match(/
|
756
|
-
expect(connection.error_reason.message).to match(/
|
759
|
+
expect(error.message).to match(/Unable to recover connection/i)
|
760
|
+
expect(connection.error_reason.message).to match(/Unable to recover connection/i)
|
757
761
|
expect(connection.error_reason.code).to eql(80008)
|
758
762
|
expect(connection.error_reason).to eql(error)
|
759
763
|
stop_reactor
|
@@ -1046,7 +1050,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1046
1050
|
end
|
1047
1051
|
|
1048
1052
|
context 'retry_in' do
|
1049
|
-
let(:client_options) { default_options.merge(log_level: :
|
1053
|
+
let(:client_options) { default_options.merge(log_level: :error) }
|
1050
1054
|
|
1051
1055
|
it 'is nil when a retry is not required' do
|
1052
1056
|
connection.on(:connected) do |connection_state_change|
|
@@ -1061,7 +1065,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1061
1065
|
expect(connection_state_change.retry_in).to eql(0)
|
1062
1066
|
stop_reactor
|
1063
1067
|
end
|
1064
|
-
EventMachine.add_timer(0.
|
1068
|
+
EventMachine.add_timer(0.005) { connection.transport.unbind }
|
1065
1069
|
end
|
1066
1070
|
end
|
1067
1071
|
|
@@ -1082,7 +1086,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1082
1086
|
expect(connection_state_change.retry_in).to be > 0
|
1083
1087
|
stop_reactor
|
1084
1088
|
end
|
1085
|
-
EventMachine.add_timer(0.
|
1089
|
+
EventMachine.add_timer(0.005) { connection.transport.unbind }
|
1086
1090
|
end
|
1087
1091
|
connection.transport.unbind
|
1088
1092
|
end
|
@@ -9,12 +9,12 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
9
9
|
let(:default_options) { options.merge(key: api_key, environment: environment, protocol: protocol) }
|
10
10
|
let(:client_options) { default_options }
|
11
11
|
let(:client) do
|
12
|
-
Ably::Realtime::Client.new(client_options)
|
12
|
+
auto_close Ably::Realtime::Client.new(client_options)
|
13
13
|
end
|
14
14
|
let(:channel) { client.channel(channel_name) }
|
15
15
|
|
16
16
|
let(:other_client) do
|
17
|
-
Ably::Realtime::Client.new(client_options)
|
17
|
+
auto_close Ably::Realtime::Client.new(client_options)
|
18
18
|
end
|
19
19
|
let(:other_client_channel) { other_client.channel(channel_name) }
|
20
20
|
|
@@ -181,12 +181,12 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
181
181
|
|
182
182
|
context 'with :echo_messages option set to false' do
|
183
183
|
let(:no_echo_client) do
|
184
|
-
Ably::Realtime::Client.new(default_options.merge(echo_messages: false
|
184
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(echo_messages: false))
|
185
185
|
end
|
186
186
|
let(:no_echo_channel) { no_echo_client.channel(channel_name) }
|
187
187
|
|
188
188
|
let(:rest_client) do
|
189
|
-
Ably::Rest::Client.new(default_options
|
189
|
+
Ably::Rest::Client.new(default_options)
|
190
190
|
end
|
191
191
|
|
192
192
|
it 'will not echo messages to the client but will still broadcast messages to other connected clients', em_timeout: 10 do
|
@@ -275,7 +275,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
275
275
|
|
276
276
|
context 'without suitable publishing permissions' do
|
277
277
|
let(:restricted_client) do
|
278
|
-
Ably::Realtime::Client.new(options.merge(key: restricted_api_key, environment: environment, protocol: protocol, :log_level => :error))
|
278
|
+
auto_close Ably::Realtime::Client.new(options.merge(key: restricted_api_key, environment: environment, protocol: protocol, :log_level => :error))
|
279
279
|
end
|
280
280
|
let(:restricted_channel) { restricted_client.channel("cansubscribe:example") }
|
281
281
|
let(:payload) { 'Test message without permission to publish' }
|
@@ -283,8 +283,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
283
283
|
it 'calls the error callback' do
|
284
284
|
restricted_channel.attach do
|
285
285
|
deferrable = restricted_channel.publish('test_event', payload)
|
286
|
-
deferrable.errback do |
|
287
|
-
expect(message.data).to eql(payload)
|
286
|
+
deferrable.errback do |error|
|
288
287
|
expect(error.status).to eql(401)
|
289
288
|
stop_reactor
|
290
289
|
end
|
@@ -418,31 +417,39 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
418
417
|
let(:encrypted_channel_client1) { client.channel(channel_name, encrypted: true, cipher_params: cipher_options) }
|
419
418
|
let(:encrypted_channel_client2) { other_client.channel(channel_name, encrypted: true, cipher_params: cipher_options) }
|
420
419
|
|
421
|
-
let(:data) {
|
420
|
+
let(:data) { { 'key' => random_str } }
|
422
421
|
let(:message_count) { 50 }
|
423
422
|
|
424
423
|
it 'encrypts and decrypts all messages' do
|
425
|
-
messages_received =
|
426
|
-
decrypted: 0,
|
427
|
-
encrypted: 0
|
428
|
-
}
|
424
|
+
messages_received = []
|
429
425
|
|
430
|
-
|
431
|
-
|
432
|
-
expect(message.data).to eql(
|
426
|
+
encrypted_channel_client1.attach do
|
427
|
+
encrypted_channel_client1.subscribe do |message|
|
428
|
+
expect(message.data).to eql(MessagePack.pack(data.merge(index: message.name.to_i)))
|
433
429
|
expect(message.encoding).to be_nil
|
434
|
-
messages_received
|
435
|
-
stop_reactor if messages_received
|
430
|
+
messages_received << message
|
431
|
+
stop_reactor if messages_received.count == message_count
|
436
432
|
end
|
437
433
|
|
438
|
-
|
439
|
-
|
440
|
-
messages_received[:encrypted] += 1
|
434
|
+
message_count.times do |index|
|
435
|
+
encrypted_channel_client2.publish index.to_s, MessagePack.pack(data.merge(index: index))
|
441
436
|
end
|
442
437
|
end
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'receives raw messages with the correct encoding' do
|
441
|
+
encrypted_channel_client1.attach do
|
442
|
+
client.connection.__incoming_protocol_msgbus__.unsubscribe # remove all listeners
|
443
|
+
client.connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
444
|
+
if protocol_message.action == Ably::Models::ProtocolMessage::ACTION.Message
|
445
|
+
protocol_message.messages.each do |message|
|
446
|
+
expect(message['encoding']).to match(/cipher\+/)
|
447
|
+
end
|
448
|
+
stop_reactor
|
449
|
+
end
|
450
|
+
end
|
443
451
|
|
444
|
-
|
445
|
-
encrypted_channel_client2.publish index.to_s, "#{index}-#{data}"
|
452
|
+
encrypted_channel_client2.publish 'name', MessagePack.pack('data')
|
446
453
|
end
|
447
454
|
end
|
448
455
|
end
|
@@ -450,7 +457,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
450
457
|
context 'subscribing with a different transport protocol' do
|
451
458
|
let(:other_protocol) { protocol == :msgpack ? :json : :msgpack }
|
452
459
|
let(:other_client) do
|
453
|
-
Ably::Realtime::Client.new(default_options.merge(protocol: other_protocol))
|
460
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(protocol: other_protocol))
|
454
461
|
end
|
455
462
|
|
456
463
|
let(:cipher_options) { { key: random_str(32), algorithm: 'aes', mode: 'cbc', key_length: 256 } }
|
@@ -592,7 +599,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
592
599
|
let(:event_name) { random_str }
|
593
600
|
let(:message_state) { [] }
|
594
601
|
let(:connection) { client.connection }
|
595
|
-
let(:client_options) { default_options.merge(:log_level => :
|
602
|
+
let(:client_options) { default_options.merge(:log_level => :none) }
|
596
603
|
let(:msgs_received) { [] }
|
597
604
|
|
598
605
|
it 'publishes the message again, later receives the ACK and only one message is ever received from Ably' do
|
@@ -7,11 +7,11 @@ describe Ably::Realtime::Presence, 'history', :event_machine do
|
|
7
7
|
|
8
8
|
let(:channel_name) { "persisted:#{random_str(2)}" }
|
9
9
|
|
10
|
-
let(:client_one) { Ably::Realtime::Client.new(default_options.merge(client_id: random_str)) }
|
10
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(client_id: random_str)) }
|
11
11
|
let(:channel_client_one) { client_one.channel(channel_name) }
|
12
12
|
let(:presence_client_one) { channel_client_one.presence }
|
13
13
|
|
14
|
-
let(:client_two) { Ably::Realtime::Client.new(default_options.merge(client_id: random_str)) }
|
14
|
+
let(:client_two) { auto_close Ably::Realtime::Client.new(default_options.merge(client_id: random_str)) }
|
15
15
|
let(:channel_client_two) { client_two.channel(channel_name) }
|
16
16
|
let(:presence_client_two) { channel_client_two.presence }
|
17
17
|
|
@@ -8,9 +8,9 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
8
8
|
let(:default_options) { { key: api_key, environment: environment, protocol: protocol } }
|
9
9
|
let(:client_options) { default_options }
|
10
10
|
|
11
|
-
let(:anonymous_client) { Ably::Realtime::Client.new(client_options) }
|
12
|
-
let(:client_one) { Ably::Realtime::Client.new(client_options.merge(client_id: random_str)) }
|
13
|
-
let(:client_two) { Ably::Realtime::Client.new(client_options.merge(client_id: random_str)) }
|
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)) }
|
14
14
|
|
15
15
|
let(:channel_name) { "presence-#{random_str(4)}" }
|
16
16
|
let(:channel_anonymous_client) { anonymous_client.channel(channel_name) }
|
@@ -72,7 +72,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
context 'when :queue_messages client option is false' do
|
75
|
-
let(:client_one) { Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: random_str)) }
|
75
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: random_str)) }
|
76
76
|
|
77
77
|
context 'and connection state initialized' do
|
78
78
|
it 'raises an exception' do
|
@@ -94,7 +94,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
94
94
|
end
|
95
95
|
|
96
96
|
context 'and connection state disconnected' do
|
97
|
-
let(:client_one) { Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: random_str, :log_level => :error)) }
|
97
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(queue_messages: false, client_id: random_str, :log_level => :error)) }
|
98
98
|
|
99
99
|
it 'raises an exception' do
|
100
100
|
client_one.connection.once(:connected) do
|
@@ -277,8 +277,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
277
277
|
|
278
278
|
presence_client_one.public_send(method_name, args).tap do |deferrable|
|
279
279
|
deferrable.callback { raise 'Should not succeed' }
|
280
|
-
deferrable.errback do |
|
281
|
-
expect(presence).to be_a(Ably::Realtime::Presence)
|
280
|
+
deferrable.errback do |error|
|
282
281
|
expect(error).to be_kind_of(Ably::Exceptions::BaseAblyException)
|
283
282
|
stop_reactor
|
284
283
|
end
|
@@ -663,7 +662,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
663
662
|
|
664
663
|
context 'without necessary capabilities to join presence' do
|
665
664
|
let(:restricted_client) do
|
666
|
-
Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
665
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
667
666
|
end
|
668
667
|
let(:restricted_channel) { restricted_client.channel("cansubscribe:channel") }
|
669
668
|
let(:restricted_presence) { restricted_channel.presence }
|
@@ -880,7 +879,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
880
879
|
|
881
880
|
context 'without necessary capabilities to enter on behalf of another client' do
|
882
881
|
let(:restricted_client) do
|
883
|
-
Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
882
|
+
auto_close Ably::Realtime::Client.new(default_options.merge(key: restricted_api_key, log_level: :fatal))
|
884
883
|
end
|
885
884
|
let(:restricted_channel) { restricted_client.channel("cansubscribe:channel") }
|
886
885
|
let(:restricted_presence) { restricted_channel.presence }
|
@@ -1400,7 +1399,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1400
1399
|
let(:client_id) { random_str.encode(Encoding::ASCII_8BIT) }
|
1401
1400
|
|
1402
1401
|
context 'in connection set up' do
|
1403
|
-
let(:client_one) { Ably::Realtime::Client.new(default_options.merge(client_id: client_id)) }
|
1402
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options.merge(client_id: client_id)) }
|
1404
1403
|
|
1405
1404
|
it 'is converted into UTF_8' do
|
1406
1405
|
presence_client_one.enter
|
@@ -1413,7 +1412,7 @@ describe Ably::Realtime::Presence, :event_machine do
|
|
1413
1412
|
end
|
1414
1413
|
|
1415
1414
|
context 'in channel options' do
|
1416
|
-
let(:client_one) { Ably::Realtime::Client.new(default_options) }
|
1415
|
+
let(:client_one) { auto_close Ably::Realtime::Client.new(default_options) }
|
1417
1416
|
|
1418
1417
|
it 'is converted into UTF_8' do
|
1419
1418
|
presence_client_one.enter(client_id: client_id)
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Ably::Realtime::Client, '#stats', :event_machine do
|
4
4
|
vary_by_protocol do
|
5
5
|
let(:client) do
|
6
|
-
Ably::Realtime::Client.new(key: api_key, environment: environment, protocol: protocol)
|
6
|
+
auto_close Ably::Realtime::Client.new(key: api_key, environment: environment, protocol: protocol)
|
7
7
|
end
|
8
8
|
|
9
9
|
describe 'fetching stats' do
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Ably::Realtime::Client, '#time', :event_machine do
|
4
4
|
vary_by_protocol do
|
5
5
|
let(:client) do
|
6
|
-
Ably::Realtime::Client.new(key: api_key, environment: environment, protocol: protocol)
|
6
|
+
auto_close Ably::Realtime::Client.new(key: api_key, environment: environment, protocol: protocol)
|
7
7
|
end
|
8
8
|
|
9
9
|
describe 'fetching the service time' do
|
@@ -27,7 +27,7 @@ describe Ably::Auth do
|
|
27
27
|
|
28
28
|
vary_by_protocol do
|
29
29
|
let(:default_options) { { environment: environment, protocol: protocol } }
|
30
|
-
let(:client_options)
|
30
|
+
let(:client_options) { default_options.merge(key: api_key) }
|
31
31
|
let(:client) do
|
32
32
|
Ably::Rest::Client.new(client_options)
|
33
33
|
end
|
@@ -66,10 +66,10 @@ describe Ably::Auth do
|
|
66
66
|
let(:capability) { { :foo => ['publish'] } }
|
67
67
|
|
68
68
|
let(:token_details) do
|
69
|
-
auth.request_token(
|
69
|
+
auth.request_token(
|
70
70
|
ttl: ttl,
|
71
71
|
capability: capability
|
72
|
-
|
72
|
+
)
|
73
73
|
end
|
74
74
|
|
75
75
|
it 'creates a TokenRequest automatically and sends it to Ably to obtain a token', webmock: true do
|
@@ -112,7 +112,7 @@ describe Ably::Auth do
|
|
112
112
|
)
|
113
113
|
end
|
114
114
|
|
115
|
-
before { auth.request_token token_params
|
115
|
+
before { auth.request_token token_params }
|
116
116
|
|
117
117
|
it "overrides default and uses camelCase notation for attributes" do
|
118
118
|
expect(request_token_stub).to have_been_requested
|
@@ -126,7 +126,7 @@ describe Ably::Auth do
|
|
126
126
|
let(:nonce) { random_str }
|
127
127
|
let(:auth_options) { { key: "#{key_name}:#{key_secret}" } }
|
128
128
|
let(:token_params) { { nonce: nonce, timestamp: Time.now } }
|
129
|
-
let(:token_request) { auth.create_token_request(
|
129
|
+
let(:token_request) { auth.create_token_request(token_params, auth_options) }
|
130
130
|
let(:mac) do
|
131
131
|
hmac_for(token_request, key_secret)
|
132
132
|
end
|
@@ -142,7 +142,7 @@ describe Ably::Auth do
|
|
142
142
|
:headers => { 'Content-Type' => content_type })
|
143
143
|
end
|
144
144
|
|
145
|
-
let!(:token) { auth.request_token(
|
145
|
+
let!(:token) { auth.request_token(token_params, auth_options) }
|
146
146
|
|
147
147
|
specify 'key_name is used in request and signing uses key_secret' do
|
148
148
|
expect(request_token_stub).to have_been_requested
|
@@ -156,7 +156,7 @@ describe Ably::Auth do
|
|
156
156
|
|
157
157
|
let(:auth_options) { { key_name: key_name, key_secret: key_secret } }
|
158
158
|
let(:token_params) { { nonce: nonce, timestamp: Time.now } }
|
159
|
-
let(:token_request) { auth.create_token_request(
|
159
|
+
let(:token_request) { auth.create_token_request(token_params, auth_options) }
|
160
160
|
let(:mac) do
|
161
161
|
hmac_for(token_request, key_secret)
|
162
162
|
end
|
@@ -172,7 +172,7 @@ describe Ably::Auth do
|
|
172
172
|
:headers => { 'Content-Type' => content_type })
|
173
173
|
end
|
174
174
|
|
175
|
-
let!(:token) { auth.request_token(
|
175
|
+
let!(:token) { auth.request_token(token_params, auth_options) }
|
176
176
|
|
177
177
|
specify 'key_name is used in request and signing uses key_secret' do
|
178
178
|
expect(request_token_stub).to have_been_requested
|
@@ -184,7 +184,7 @@ describe Ably::Auth do
|
|
184
184
|
|
185
185
|
it 'queries the server for the time' do
|
186
186
|
expect(client).to receive(:time).and_call_original
|
187
|
-
auth.request_token(options)
|
187
|
+
auth.request_token({}, options)
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
@@ -193,7 +193,7 @@ describe Ably::Auth do
|
|
193
193
|
|
194
194
|
it 'does not query the server for the time' do
|
195
195
|
expect(client).to_not receive(:time)
|
196
|
-
auth.request_token(options)
|
196
|
+
auth.request_token({}, options)
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
@@ -237,7 +237,7 @@ describe Ably::Auth do
|
|
237
237
|
end
|
238
238
|
|
239
239
|
context 'when response from :auth_url is a valid token request' do
|
240
|
-
let!(:token) { auth.request_token(auth_options) }
|
240
|
+
let!(:token) { auth.request_token({}, auth_options) }
|
241
241
|
|
242
242
|
it 'requests a token from :auth_url using an HTTP GET request' do
|
243
243
|
expect(request_token_stub).to have_been_requested
|
@@ -290,7 +290,7 @@ describe Ably::Auth do
|
|
290
290
|
}.to_json
|
291
291
|
end
|
292
292
|
|
293
|
-
let!(:token_details) { auth.request_token(auth_options) }
|
293
|
+
let!(:token_details) { auth.request_token({}, auth_options) }
|
294
294
|
|
295
295
|
it 'returns TokenDetails created from the token JSON' do
|
296
296
|
expect(auth_url_request_stub).to have_been_requested
|
@@ -308,7 +308,7 @@ describe Ably::Auth do
|
|
308
308
|
let(:auth_url_content_type) { 'text/plain' }
|
309
309
|
let(:auth_url_response) { token }
|
310
310
|
|
311
|
-
let!(:token_details) { auth.request_token(auth_options) }
|
311
|
+
let!(:token_details) { auth.request_token({}, auth_options) }
|
312
312
|
|
313
313
|
it 'returns TokenDetails created from the token JSON' do
|
314
314
|
expect(auth_url_request_stub).to have_been_requested
|
@@ -325,7 +325,7 @@ describe Ably::Auth do
|
|
325
325
|
end
|
326
326
|
|
327
327
|
it 'raises ServerError' do
|
328
|
-
expect { auth.request_token auth_options }.to raise_error(Ably::Exceptions::ServerError)
|
328
|
+
expect { auth.request_token({}, auth_options) }.to raise_error(Ably::Exceptions::ServerError)
|
329
329
|
end
|
330
330
|
end
|
331
331
|
|
@@ -336,7 +336,7 @@ describe Ably::Auth do
|
|
336
336
|
end
|
337
337
|
|
338
338
|
it 'raises InvalidResponseBody' do
|
339
|
-
expect { auth.request_token auth_options }.to raise_error(Ably::Exceptions::InvalidResponseBody)
|
339
|
+
expect { auth.request_token({}, auth_options) }.to raise_error(Ably::Exceptions::InvalidResponseBody)
|
340
340
|
end
|
341
341
|
end
|
342
342
|
end
|
@@ -350,12 +350,12 @@ describe Ably::Auth do
|
|
350
350
|
Proc.new do |token_params_arg|
|
351
351
|
@block_called = true
|
352
352
|
expect(token_params_arg).to eq(token_params)
|
353
|
-
auth.create_token_request(
|
353
|
+
auth.create_token_request(client_id: client_id)
|
354
354
|
end
|
355
355
|
end
|
356
356
|
let(:token_params) { { ttl: ttl } }
|
357
357
|
let!(:request_token) do
|
358
|
-
auth.request_token(auth_callback: auth_callback
|
358
|
+
auth.request_token(token_params, auth_callback: auth_callback)
|
359
359
|
end
|
360
360
|
|
361
361
|
it 'calls the Proc with token_params when authenticating to obtain the request token' do
|
@@ -369,7 +369,7 @@ describe Ably::Auth do
|
|
369
369
|
|
370
370
|
context 'that returns a TokenDetails JSON object' do
|
371
371
|
let(:client_id) { random_str }
|
372
|
-
let(:
|
372
|
+
let(:token_params){ { client_id: client_id } }
|
373
373
|
let(:token) { 'J_0Tlg.D7AVZkdOZW-PqNNGvCSp38' }
|
374
374
|
let(:issued) { Time.now }
|
375
375
|
let(:expires) { Time.now + 60}
|
@@ -377,7 +377,7 @@ describe Ably::Auth do
|
|
377
377
|
let(:capability_str) { JSON.dump(capability) }
|
378
378
|
|
379
379
|
let!(:token_details) do
|
380
|
-
auth.request_token(auth_callback: Proc.new do |token_params_arg|
|
380
|
+
auth.request_token(token_params, auth_callback: Proc.new do |token_params_arg|
|
381
381
|
@block_called = true
|
382
382
|
@block_params = token_params_arg
|
383
383
|
{
|
@@ -388,12 +388,12 @@ describe Ably::Auth do
|
|
388
388
|
'expires' => expires.to_i * 1000,
|
389
389
|
'capability'=> capability_str
|
390
390
|
}
|
391
|
-
end
|
391
|
+
end)
|
392
392
|
end
|
393
393
|
|
394
394
|
it 'calls the Proc when authenticating to obtain the request token' do
|
395
395
|
expect(@block_called).to eql(true)
|
396
|
-
expect(@block_params).to include(
|
396
|
+
expect(@block_params).to include(token_params)
|
397
397
|
end
|
398
398
|
|
399
399
|
it 'uses the token request returned from the callback when requesting a new token' do
|
@@ -410,10 +410,8 @@ describe Ably::Auth do
|
|
410
410
|
let(:client_id) { random_str }
|
411
411
|
|
412
412
|
let!(:token_details) do
|
413
|
-
auth.request_token(auth_callback: Proc.new do |block_options|
|
414
|
-
auth.create_token_request(
|
415
|
-
client_id: client_id
|
416
|
-
})
|
413
|
+
auth.request_token({}, auth_callback: Proc.new do |block_options|
|
414
|
+
auth.create_token_request(client_id: client_id)
|
417
415
|
end)
|
418
416
|
end
|
419
417
|
|
@@ -428,7 +426,7 @@ describe Ably::Auth do
|
|
428
426
|
let(:token) { second_client.auth.request_token.token }
|
429
427
|
|
430
428
|
let!(:token_details) do
|
431
|
-
auth.request_token(auth_callback: Proc.new do |block_options|
|
429
|
+
auth.request_token({}, auth_callback: Proc.new do |block_options|
|
432
430
|
token
|
433
431
|
end)
|
434
432
|
end
|
@@ -440,10 +438,9 @@ describe Ably::Auth do
|
|
440
438
|
end
|
441
439
|
end
|
442
440
|
|
443
|
-
context 'persisted option', api_private: true do
|
441
|
+
context 'persisted option of token params', api_private: true do
|
444
442
|
context 'when set to true', api_private: true do
|
445
|
-
let(:
|
446
|
-
let(:token_details) { auth.request_token(token_params: options) }
|
443
|
+
let(:token_details) { auth.request_token(persisted: true) }
|
447
444
|
|
448
445
|
it 'returns a token with a short token ID that is used to look up the token details' do
|
449
446
|
expect(token_details.token.length).to be < 64
|
@@ -462,7 +459,7 @@ describe Ably::Auth do
|
|
462
459
|
|
463
460
|
context 'with auth_option :client_id' do
|
464
461
|
let(:client_id) { random_str }
|
465
|
-
let(:token_details) { auth.request_token(client_id: client_id) }
|
462
|
+
let(:token_details) { auth.request_token({}, client_id: client_id) }
|
466
463
|
|
467
464
|
it 'returns a token with the client_id' do
|
468
465
|
expect(token_details.client_id).to eql(client_id)
|
@@ -471,7 +468,7 @@ describe Ably::Auth do
|
|
471
468
|
|
472
469
|
context 'with token_param :client_id' do
|
473
470
|
let(:client_id) { random_str }
|
474
|
-
let(:token_details) { auth.request_token(
|
471
|
+
let(:token_details) { auth.request_token(client_id: client_id) }
|
475
472
|
|
476
473
|
it 'returns a token with the client_id' do
|
477
474
|
expect(token_details.client_id).to eql(client_id)
|
@@ -495,8 +492,8 @@ describe Ably::Auth do
|
|
495
492
|
end
|
496
493
|
|
497
494
|
it 'passes all auth_options and token_params to #request_token' do
|
498
|
-
expect(auth).to receive(:request_token).with(
|
499
|
-
auth.authorise
|
495
|
+
expect(auth).to receive(:request_token).with(token_params, auth_options)
|
496
|
+
auth.authorise token_params, auth_options
|
500
497
|
end
|
501
498
|
|
502
499
|
it 'returns a valid token' do
|
@@ -526,20 +523,26 @@ describe Ably::Auth do
|
|
526
523
|
end
|
527
524
|
|
528
525
|
it 'issues a new token if option :force => true' do
|
529
|
-
expect { auth.authorise(force: true) }.to change { auth.current_token_details }
|
526
|
+
expect { auth.authorise({}, force: true) }.to change { auth.current_token_details }
|
530
527
|
end
|
531
528
|
end
|
532
529
|
|
533
|
-
it 'updates the persisted
|
534
|
-
expect(auth.
|
530
|
+
it 'updates the persisted token params that are then used for subsequent authorise requests' do
|
531
|
+
expect(auth.token_params[:ttl]).to_not eql(26)
|
535
532
|
auth.authorise(ttl: 26)
|
536
|
-
expect(auth.
|
533
|
+
expect(auth.token_params[:ttl]).to eql(26)
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'updates the persisted token params that are then used for subsequent authorise requests' do
|
537
|
+
expect(auth.options[:query_time]).to_not eql(true)
|
538
|
+
auth.authorise({}, query_time: true)
|
539
|
+
expect(auth.options[:query_time]).to eql(true)
|
537
540
|
end
|
538
541
|
|
539
542
|
context 'with a Proc for the :auth_callback option' do
|
540
543
|
let(:client_id) { random_str }
|
541
544
|
let!(:token) do
|
542
|
-
auth.authorise(auth_callback: Proc.new do
|
545
|
+
auth.authorise({}, auth_callback: Proc.new do
|
543
546
|
@block_called ||= 0
|
544
547
|
@block_called += 1
|
545
548
|
auth.create_token_request(client_id: client_id)
|
@@ -564,13 +567,41 @@ describe Ably::Auth do
|
|
564
567
|
|
565
568
|
context 'with a provided block' do
|
566
569
|
it 'does not call the originally provided Proc and calls the new #request_token :auth_callback Proc' do
|
567
|
-
auth.request_token(auth_callback: Proc.new { @request_block_called = true; auth.create_token_request })
|
570
|
+
auth.request_token({}, auth_callback: Proc.new { @request_block_called = true; auth.create_token_request })
|
568
571
|
expect(@block_called).to eql(1)
|
569
572
|
expect(@request_block_called).to eql(true)
|
570
573
|
end
|
571
574
|
end
|
572
575
|
end
|
573
576
|
end
|
577
|
+
|
578
|
+
context 'with an explicit token string that expires' do
|
579
|
+
context 'and a Proc for the :auth_callback option to provide a means to renew the token' do
|
580
|
+
before do
|
581
|
+
# Ensure a soon to expire token is not treated as expired
|
582
|
+
stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', 0
|
583
|
+
old_token_defaults = Ably::Auth::TOKEN_DEFAULTS
|
584
|
+
stub_const 'Ably::Auth::TOKEN_DEFAULTS', old_token_defaults.merge(renew_token_buffer: 0)
|
585
|
+
end
|
586
|
+
|
587
|
+
let(:token_client) { Ably::Rest::Client.new(default_options.merge(key: api_key, token_params: { ttl: 3 })) }
|
588
|
+
let(:client_options) {
|
589
|
+
default_options.merge(token: token_client.auth.request_token.token, auth_callback: Proc.new do
|
590
|
+
@block_called ||= 0
|
591
|
+
@block_called += 1
|
592
|
+
token_client.auth.create_token_request
|
593
|
+
end)
|
594
|
+
}
|
595
|
+
|
596
|
+
it 'calls the Proc once the token has expired and the new token is used' do
|
597
|
+
client.stats
|
598
|
+
expect(@block_called).to be_nil
|
599
|
+
sleep 3.5
|
600
|
+
expect { client.stats }.to change { client.auth.current_token_details }
|
601
|
+
expect(@block_called).to eql(1)
|
602
|
+
end
|
603
|
+
end
|
604
|
+
end
|
574
605
|
end
|
575
606
|
|
576
607
|
describe '#create_token_request' do
|
@@ -578,7 +609,7 @@ describe Ably::Auth do
|
|
578
609
|
let(:capability) { { "foo" => ["publish"] } }
|
579
610
|
let(:token_params) { Hash.new }
|
580
611
|
|
581
|
-
subject { auth.create_token_request(token_params
|
612
|
+
subject { auth.create_token_request(token_params) }
|
582
613
|
|
583
614
|
it 'returns a TokenRequest object' do
|
584
615
|
expect(subject).to be_a(Ably::Models::TokenRequest)
|
@@ -666,11 +697,11 @@ describe Ably::Auth do
|
|
666
697
|
let(:client) { Ably::Rest::Client.new(auth_url: 'http://example.com', protocol: protocol) }
|
667
698
|
|
668
699
|
it 'should raise an exception if key secret is missing' do
|
669
|
-
expect { auth.create_token_request(key_name: 'name') }.to raise_error Ably::Exceptions::TokenRequestFailed
|
700
|
+
expect { auth.create_token_request({}, key_name: 'name') }.to raise_error Ably::Exceptions::TokenRequestFailed
|
670
701
|
end
|
671
702
|
|
672
703
|
it 'should raise an exception if key name is missing' do
|
673
|
-
expect { auth.create_token_request(key_secret: 'secret') }.to raise_error Ably::Exceptions::TokenRequestFailed
|
704
|
+
expect { auth.create_token_request({}, key_secret: 'secret') }.to raise_error Ably::Exceptions::TokenRequestFailed
|
674
705
|
end
|
675
706
|
end
|
676
707
|
|
@@ -679,7 +710,7 @@ describe Ably::Auth do
|
|
679
710
|
let(:time) { Time.now - 30 }
|
680
711
|
let(:auth_options) { { query_time: true } }
|
681
712
|
|
682
|
-
subject { auth.create_token_request(auth_options) }
|
713
|
+
subject { auth.create_token_request({}, auth_options) }
|
683
714
|
|
684
715
|
it 'queries the server for the timestamp' do
|
685
716
|
expect(client).to receive(:time).and_return(time)
|
@@ -733,10 +764,10 @@ describe Ably::Auth do
|
|
733
764
|
describe 'with :token option' do
|
734
765
|
let(:ttl) { 60 * 60 }
|
735
766
|
let(:token_details) do
|
736
|
-
auth.request_token(
|
767
|
+
auth.request_token(
|
737
768
|
ttl: ttl,
|
738
769
|
capability: capability
|
739
|
-
|
770
|
+
)
|
740
771
|
end
|
741
772
|
let(:token) { token_details.token }
|
742
773
|
let(:token_auth_client) do
|
@@ -756,7 +787,7 @@ describe Ably::Auth do
|
|
756
787
|
end
|
757
788
|
|
758
789
|
it 'fails if timestamp is invalid' do
|
759
|
-
expect { auth.request_token(
|
790
|
+
expect { auth.request_token(timestamp: Time.now - 180) }.to raise_error do |error|
|
760
791
|
expect(error).to be_a(Ably::Exceptions::InvalidRequest)
|
761
792
|
expect(error.status).to eql(401)
|
762
793
|
expect(error.code).to eql(40101)
|