ably-rest 1.0.6 → 1.1.4.rc
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/CHANGELOG.md +1 -1
- data/README.md +23 -15
- data/ably-rest.gemspec +6 -6
- data/lib/submodules/ably-ruby/.editorconfig +14 -0
- data/lib/submodules/ably-ruby/.travis.yml +10 -8
- data/lib/submodules/ably-ruby/CHANGELOG.md +75 -3
- data/lib/submodules/ably-ruby/LICENSE +1 -3
- data/lib/submodules/ably-ruby/README.md +12 -7
- data/lib/submodules/ably-ruby/Rakefile +32 -0
- data/lib/submodules/ably-ruby/SPEC.md +1277 -835
- data/lib/submodules/ably-ruby/ably.gemspec +15 -10
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +30 -4
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +10 -4
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +7 -1
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/connection_state_change.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/device_details.rb +87 -0
- data/lib/submodules/ably-ruby/lib/ably/models/device_push_details.rb +86 -0
- data/lib/submodules/ably-ruby/lib/ably/models/error_info.rb +23 -2
- data/lib/submodules/ably-ruby/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -4
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +32 -2
- data/lib/submodules/ably-ruby/lib/ably/models/push_channel_subscription.rb +89 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/conversions.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/encodeable.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/model_common.rb +15 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +24 -102
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +2 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/publisher.rb +74 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/push_channel.rb +62 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +91 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +34 -20
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +25 -9
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/websocket_transport.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +4 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence/members_map.rb +3 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/push.rb +40 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/admin.rb +61 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/submodules/ably-ruby/lib/ably/rest.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +53 -17
- data/lib/submodules/ably-ruby/lib/ably/rest/channel/push_channel.rb +62 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +162 -35
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +4 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push.rb +42 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/admin.rb +54 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/submodules/ably-ruby/lib/ably/rest/push/device_registrations.rb +103 -0
- data/lib/submodules/ably-ruby/lib/ably/version.rb +7 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +245 -17
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +26 -20
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +177 -59
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +153 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +72 -6
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +129 -18
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +36 -34
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +201 -167
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +736 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_spec.rb +27 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +41 -3
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +2 -2
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +79 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +6 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +129 -10
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +158 -6
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +952 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_spec.rb +25 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/run_parallel_tests +33 -0
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +9 -5
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +2 -2
- data/lib/submodules/ably-ruby/spec/unit/logger_spec.rb +10 -3
- data/lib/submodules/ably-ruby/spec/unit/models/device_details_spec.rb +102 -0
- data/lib/submodules/ably-ruby/spec/unit/models/device_push_details_spec.rb +101 -0
- data/lib/submodules/ably-ruby/spec/unit/models/error_info_spec.rb +51 -3
- data/lib/submodules/ably-ruby/spec/unit/models/message_spec.rb +17 -2
- data/lib/submodules/ably-ruby/spec/unit/models/presence_message_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/models/push_channel_subscription_spec.rb +86 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +13 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/push_channel_spec.rb +36 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +8 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +30 -0
- data/lib/submodules/ably-ruby/spec/unit/rest/push_channel_spec.rb +36 -0
- metadata +46 -21
@@ -45,7 +45,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
45
45
|
connection.on(:failed) do |connection_state_change|
|
46
46
|
error = connection_state_change.reason
|
47
47
|
expect(connection.state).to eq(:failed)
|
48
|
-
# TODO: Check error type is a
|
48
|
+
# TODO: Check error type is a TokenNotFound exception
|
49
49
|
expect(error.status).to eq(401)
|
50
50
|
expect(error.code).to eq(40400) # not found
|
51
51
|
stop_reactor
|
@@ -110,6 +110,72 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
113
|
+
|
114
|
+
context 'request fails due to slow response and subsequent timeout', :webmock, em_timeout: (Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5) * 2 do
|
115
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
116
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
117
|
+
|
118
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
119
|
+
before do
|
120
|
+
stub_request(:get, auth_url).
|
121
|
+
to_return do |request|
|
122
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout) + 5
|
123
|
+
{ status: [500, "Internal Server Error"] }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
128
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
129
|
+
|
130
|
+
connection.once(:connected) { raise "Connection can never move to connected because of auth failures" }
|
131
|
+
|
132
|
+
connection.on do |connection_state|
|
133
|
+
states[connection_state.current.to_sym] << Time.now
|
134
|
+
if states[:disconnected].count == 2 && connection_state.current == :disconnected
|
135
|
+
expect(connection.error_reason).to be_a(Ably::Exceptions::ConnectionError)
|
136
|
+
expect(connection.error_reason.message).to match(/auth_url/)
|
137
|
+
EventMachine.add_timer(2) do
|
138
|
+
expect(states.keys).to include(:connecting, :disconnected)
|
139
|
+
expect(states[:connecting].count).to eql(2)
|
140
|
+
expect(states[:connected].count).to eql(0)
|
141
|
+
stop_reactor
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'request fails once due to slow response but succeeds the second time' do
|
149
|
+
let(:auth_url) { "http://#{random_str}.domain.will.be.stubbed/path" }
|
150
|
+
let(:client_options) { default_options.reject { |k, v| k == :key }.merge(auth_url: auth_url, log_level: :fatal) }
|
151
|
+
|
152
|
+
# Timeout +5 seconds, beyond default allowed timeout
|
153
|
+
before do
|
154
|
+
token_response = Ably::Rest::Client.new(default_options).auth.request_token
|
155
|
+
WebMock.enable!
|
156
|
+
|
157
|
+
stub_request(:get, auth_url).
|
158
|
+
to_return do |request|
|
159
|
+
sleep Ably::Rest::Client::HTTP_DEFAULTS.fetch(:request_timeout)
|
160
|
+
{ status: [500, "Internal Server Error"] }
|
161
|
+
end.then.
|
162
|
+
to_return(:status => 201, :body => token_response.to_json, :headers => { 'Content-Type' => 'application/json' })
|
163
|
+
end
|
164
|
+
|
165
|
+
specify 'the connection moves to the disconnected state and tries again, returning again to the disconnected state (#RSA4c, #RSA4c1, #RSA4c2)' do
|
166
|
+
states = Hash.new { |hash, key| hash[key] = [] }
|
167
|
+
|
168
|
+
connection.once(:connected) do
|
169
|
+
expect(states[:disconnected].count).to eql(1)
|
170
|
+
expect(states[:connecting].count).to eql(2)
|
171
|
+
stop_reactor
|
172
|
+
end
|
173
|
+
|
174
|
+
connection.on do |connection_state|
|
175
|
+
states[connection_state.current.to_sym] << Time.now
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
113
179
|
end
|
114
180
|
|
115
181
|
context 'existing CONNECTED connection' do
|
@@ -425,7 +491,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
425
491
|
let(:client_options) do
|
426
492
|
default_options.merge(
|
427
493
|
log_level: :none,
|
428
|
-
realtime_request_timeout: timeout
|
494
|
+
realtime_request_timeout: timeout,
|
429
495
|
)
|
430
496
|
end
|
431
497
|
|
@@ -921,11 +987,11 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
921
987
|
end
|
922
988
|
end
|
923
989
|
|
924
|
-
it 'retains the
|
990
|
+
it 'retains the client_msg_serial (#RTN15c2, #RTN15c3)' do
|
925
991
|
last_message = nil
|
926
992
|
channel = client.channels.get("foo")
|
927
993
|
|
928
|
-
|
994
|
+
channel.attach do
|
929
995
|
connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
930
996
|
if protocol_message.action == :message
|
931
997
|
last_message = protocol_message
|
@@ -1103,7 +1169,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1103
1169
|
end
|
1104
1170
|
end
|
1105
1171
|
|
1106
|
-
it '
|
1172
|
+
it 'continues to use the client_msg_serial (#RTN15c3)' do
|
1107
1173
|
last_message = nil
|
1108
1174
|
channel = client.channels.get("foo")
|
1109
1175
|
|
@@ -1121,7 +1187,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1121
1187
|
connection.once(:connected) do
|
1122
1188
|
channel.publish("first on new connection") do
|
1123
1189
|
# Message serial reset after failed resume
|
1124
|
-
expect(last_message.message_serial).to eql(
|
1190
|
+
expect(last_message.message_serial).to eql(2)
|
1125
1191
|
stop_reactor
|
1126
1192
|
end
|
1127
1193
|
end
|
@@ -27,6 +27,13 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
context 'current_host' do
|
31
|
+
it 'is available immediately after the client is instanced' do
|
32
|
+
expect(connection.current_host.to_s).to match(/\.ably\.io$/)
|
33
|
+
stop_reactor
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
30
37
|
context 'with :auto_connect option set to false' do
|
31
38
|
let(:client) do
|
32
39
|
auto_close Ably::Realtime::Client.new(default_options.merge(auto_connect: false))
|
@@ -264,7 +271,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
264
271
|
channel.subscribe('event') do |message|
|
265
272
|
messages_received << message.data.to_i
|
266
273
|
if messages_received.count == total_expected
|
267
|
-
expect(messages_received).to match(total_expected.times)
|
274
|
+
expect(messages_received).to match(total_expected.times.to_a)
|
268
275
|
expect(auth_requests.count).to eql(iteration + 1)
|
269
276
|
EventMachine.add_timer(1) do
|
270
277
|
channel.unsubscribe 'event'
|
@@ -649,16 +656,47 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
649
656
|
end
|
650
657
|
|
651
658
|
it 'is set to 1 when the second message is received' do
|
652
|
-
channel.
|
653
|
-
|
659
|
+
channel.attach do
|
660
|
+
messages = []
|
661
|
+
channel.subscribe do |message|
|
662
|
+
messages << message
|
663
|
+
if messages.length == 2
|
664
|
+
expect(connection.serial).to eql(1)
|
665
|
+
stop_reactor
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
channel.publish('event', 'data') do
|
670
|
+
channel.publish('event', 'data')
|
671
|
+
end
|
654
672
|
end
|
673
|
+
end
|
674
|
+
end
|
655
675
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
676
|
+
describe '#msgSerial' do
|
677
|
+
context 'when messages are queued for publish before a connection is established' do
|
678
|
+
let(:batches) { 6 }
|
679
|
+
let(:messages_per_batch) { 10 }
|
680
|
+
|
681
|
+
let(:publishing_client) { auto_close Ably::Realtime::Client.new(default_options) }
|
682
|
+
let(:channel_name) { random_str }
|
683
|
+
let(:publishing_channel) { publishing_client.channels.get(channel_name) }
|
684
|
+
let(:receiving_channel) { client.channels.get(channel_name) }
|
685
|
+
|
686
|
+
it 'the msgSerial is always incrementing (and not reset when the new connection is established) ensuring messages are never de-duped by the realtime service' do
|
687
|
+
messages = []
|
688
|
+
|
689
|
+
receiving_channel.attach do
|
690
|
+
receiving_channel.subscribe('event') do |message|
|
691
|
+
messages << message
|
692
|
+
stop_reactor if messages.count == batches * messages_per_batch
|
693
|
+
end
|
694
|
+
|
695
|
+
batches.times do |batch|
|
696
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
697
|
+
messages_per_batch.times { |index| publishing_channel.publish('event') }
|
698
|
+
end
|
699
|
+
end
|
662
700
|
end
|
663
701
|
end
|
664
702
|
end
|
@@ -1005,10 +1043,9 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1005
1043
|
let(:client_options) { default_options.merge(websocket_heartbeats_disabled: true) }
|
1006
1044
|
|
1007
1045
|
it 'does not provide the heartbeats argument in the websocket connection params (#RTN23b)' do
|
1008
|
-
skip 'Native heartbeats not yet supported in the WS driver https://github.com/ably/ably-ruby/issues/116'
|
1009
1046
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1010
1047
|
uri = URI.parse(url)
|
1011
|
-
expect(CGI::parse(uri.query)['heartbeats'][0]).to
|
1048
|
+
expect(CGI::parse(uri.query)['heartbeats'][0]).to eql('true')
|
1012
1049
|
stop_reactor
|
1013
1050
|
end
|
1014
1051
|
client
|
@@ -1126,7 +1163,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1126
1163
|
expected_serial += 1 # attach message received
|
1127
1164
|
expect(connection.serial).to eql(expected_serial)
|
1128
1165
|
|
1129
|
-
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}")
|
1166
|
+
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}:#{connection.send(:client_msg_serial)}")
|
1130
1167
|
stop_reactor
|
1131
1168
|
end
|
1132
1169
|
end
|
@@ -1237,6 +1274,80 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1237
1274
|
end
|
1238
1275
|
end
|
1239
1276
|
end
|
1277
|
+
|
1278
|
+
context 'when messages have been published' do
|
1279
|
+
describe 'the new connection' do
|
1280
|
+
it 'uses the correct msgSerial from the old connection' do
|
1281
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1282
|
+
|
1283
|
+
channel.attach do
|
1284
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1285
|
+
connection_id = client.connection.id
|
1286
|
+
connection.transport.__incoming_protocol_msgbus__
|
1287
|
+
channel.publish('event', 'message') do
|
1288
|
+
msg_serial = connection.send(:client_msg_serial)
|
1289
|
+
expect(msg_serial).to eql(0)
|
1290
|
+
recovery_key = client.connection.recovery_key
|
1291
|
+
connection.transition_state_machine! :failed
|
1292
|
+
end
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
connection.on(:failed) do
|
1296
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1297
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1298
|
+
recover_client_channel.attach do
|
1299
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1300
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1301
|
+
stop_reactor
|
1302
|
+
end
|
1303
|
+
end
|
1304
|
+
end
|
1305
|
+
end
|
1306
|
+
end
|
1307
|
+
|
1308
|
+
context 'when messages are published before the new connection is recovered' do
|
1309
|
+
describe 'the new connection' do
|
1310
|
+
it 'uses the correct msgSerial from the old connection for the queued messages' do
|
1311
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1312
|
+
|
1313
|
+
channel.attach do
|
1314
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1315
|
+
connection_id = client.connection.id
|
1316
|
+
connection.transport.__incoming_protocol_msgbus__
|
1317
|
+
channel.subscribe('event') do |message|
|
1318
|
+
expect(message.data).to eql('message-1')
|
1319
|
+
msg_serial = connection.send(:client_msg_serial)
|
1320
|
+
expect(msg_serial).to eql(0)
|
1321
|
+
recovery_key = client.connection.recovery_key
|
1322
|
+
connection.transition_state_machine! :failed
|
1323
|
+
end
|
1324
|
+
channel.publish('event', 'message-1')
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
connection.on(:failed) do
|
1328
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1329
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1330
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1331
|
+
|
1332
|
+
recover_client.connection.once(:connecting) do
|
1333
|
+
recover_client_channel.publish('event', 'message-2')
|
1334
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial + 1)
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
recover_client_channel.attach do
|
1338
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1339
|
+
|
1340
|
+
recover_client_channel.subscribe do |message|
|
1341
|
+
expect(message.data).to eql('message-2')
|
1342
|
+
EventMachine.add_timer(2) do
|
1343
|
+
stop_reactor
|
1344
|
+
end
|
1345
|
+
end
|
1346
|
+
end
|
1347
|
+
end
|
1348
|
+
end
|
1349
|
+
end
|
1350
|
+
end
|
1240
1351
|
end
|
1241
1352
|
|
1242
1353
|
context 'with :recover option' do
|
@@ -1250,7 +1361,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1250
1361
|
end
|
1251
1362
|
|
1252
1363
|
context 'with invalid formatted value sent to server' do
|
1253
|
-
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1', log_level: :none) }
|
1364
|
+
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1:0', log_level: :none) }
|
1254
1365
|
|
1255
1366
|
it 'sets the #error_reason and moves the connection to FAILED' do
|
1256
1367
|
connection.once(:failed) do |state_change|
|
@@ -1265,7 +1376,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1265
1376
|
end
|
1266
1377
|
|
1267
1378
|
context 'with expired (missing) value sent to server' do
|
1268
|
-
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0', log_level: :fatal) }
|
1379
|
+
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0:0', log_level: :fatal) }
|
1269
1380
|
|
1270
1381
|
it 'connects but sets the error reason and includes the reason in the state change' do
|
1271
1382
|
connection.once(:connected) do |state_change|
|
@@ -1472,7 +1583,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1472
1583
|
channel.attach do
|
1473
1584
|
channel.once(:suspended) do
|
1474
1585
|
channel.publish('test').errback do |error|
|
1475
|
-
expect(error).to be_a(Ably::Exceptions::
|
1586
|
+
expect(error).to be_a(Ably::Exceptions::ChannelInactive)
|
1476
1587
|
stop_reactor
|
1477
1588
|
end
|
1478
1589
|
end
|
@@ -1732,7 +1843,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1732
1843
|
it 'sends the protocol version param v (#G4, #RTN2f)' do
|
1733
1844
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1734
1845
|
uri = URI.parse(url)
|
1735
|
-
expect(CGI::parse(uri.query)['v'][0]).to eql('1.
|
1846
|
+
expect(CGI::parse(uri.query)['v'][0]).to eql('1.1')
|
1736
1847
|
stop_reactor
|
1737
1848
|
end
|
1738
1849
|
client
|
@@ -1741,7 +1852,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1741
1852
|
it 'sends the lib version param lib (#RTN2g)' do
|
1742
1853
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1743
1854
|
uri = URI.parse(url)
|
1744
|
-
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-1\.
|
1855
|
+
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-1\.1\.\d+(-[\w\.]+)?+$/)
|
1745
1856
|
stop_reactor
|
1746
1857
|
end
|
1747
1858
|
client
|
@@ -1761,7 +1872,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1761
1872
|
it 'sends the lib version param lib with the variant (#RTN2g + #RSC7b)' do
|
1762
1873
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1763
1874
|
uri = URI.parse(url)
|
1764
|
-
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-#{variant}-1\.
|
1875
|
+
expect(CGI::parse(uri.query)['lib'][0]).to match(/^ruby-#{variant}-1\.1\.\d+(-[\w\.]+)?$/)
|
1765
1876
|
stop_reactor
|
1766
1877
|
end
|
1767
1878
|
client
|
@@ -96,8 +96,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
context 'JSON Array' do
|
99
|
-
|
100
|
-
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
99
|
+
let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
|
101
100
|
|
102
101
|
it 'is encoded and decoded to the same Array' do
|
103
102
|
publish_and_check_extras data
|
@@ -116,7 +115,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
116
115
|
context 'Integer' do
|
117
116
|
let(:data) { 1 }
|
118
117
|
|
119
|
-
it 'is raises an UnsupportedDataType
|
118
|
+
it 'is raises an UnsupportedDataType 40013 exception' do
|
120
119
|
expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
|
121
120
|
stop_reactor
|
122
121
|
end
|
@@ -125,7 +124,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
125
124
|
context 'Float' do
|
126
125
|
let(:data) { 1.1 }
|
127
126
|
|
128
|
-
it 'is raises an UnsupportedDataType
|
127
|
+
it 'is raises an UnsupportedDataType 40013 exception' do
|
129
128
|
expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
|
130
129
|
stop_reactor
|
131
130
|
end
|
@@ -134,7 +133,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
134
133
|
context 'Boolean' do
|
135
134
|
let(:data) { true }
|
136
135
|
|
137
|
-
it 'is raises an UnsupportedDataType
|
136
|
+
it 'is raises an UnsupportedDataType 40013 exception' do
|
138
137
|
expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
|
139
138
|
stop_reactor
|
140
139
|
end
|
@@ -143,7 +142,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
143
142
|
context 'False' do
|
144
143
|
let(:data) { false }
|
145
144
|
|
146
|
-
it 'is raises an UnsupportedDataType
|
145
|
+
it 'is raises an UnsupportedDataType 40013 exception' do
|
147
146
|
expect { channel.publish 'event', data }.to raise_error(Ably::Exceptions::UnsupportedDataType)
|
148
147
|
stop_reactor
|
149
148
|
end
|
@@ -353,23 +352,25 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
353
352
|
first_message_protocol_message ||= protocol_message unless protocol_message.messages.empty?
|
354
353
|
end
|
355
354
|
|
356
|
-
channel.
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
355
|
+
channel.attach do
|
356
|
+
channel.subscribe do |message|
|
357
|
+
messages_received << message
|
358
|
+
if messages_received.count == 2
|
359
|
+
# simulate a duplicate protocol message being received
|
360
|
+
EventMachine.next_tick do
|
361
|
+
connection.__incoming_protocol_msgbus__.publish :protocol_message, first_message_protocol_message
|
362
|
+
end
|
362
363
|
end
|
363
364
|
end
|
364
|
-
|
365
|
-
2.times { |i| EventMachine.add_timer(i.to_f / 5) { channel.publish('event', 'data') } }
|
365
|
+
2.times { |i| EventMachine.add_timer(i.to_f / 5) { channel.publish('event', 'data') } }
|
366
366
|
|
367
|
-
|
368
|
-
|
367
|
+
expect(client.logger).to receive(:error) do |*args, &block|
|
368
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to match(/duplicate/)
|
369
369
|
|
370
|
-
|
371
|
-
|
372
|
-
|
370
|
+
EventMachine.add_timer(0.5) do
|
371
|
+
expect(messages_received.count).to eql(2)
|
372
|
+
stop_reactor
|
373
|
+
end
|
373
374
|
end
|
374
375
|
end
|
375
376
|
end
|
@@ -413,30 +414,32 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
413
414
|
let(:encrypted_channel) { client.channel(channel_name, cipher: cipher_options) }
|
414
415
|
|
415
416
|
it 'encrypts message automatically before they are pushed to the server (#RTL7d)' do
|
416
|
-
encrypted_channel.
|
417
|
+
encrypted_channel.attach do
|
418
|
+
encrypted_channel.__incoming_msgbus__.unsubscribe # remove all subscribe callbacks that could decrypt the message
|
417
419
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
420
|
+
encrypted_channel.__incoming_msgbus__.subscribe(:message) do |message|
|
421
|
+
if protocol == :json
|
422
|
+
expect(message['encoding']).to eql(encrypted_encoding)
|
423
|
+
expect(message['data']).to eql(encrypted_data)
|
424
|
+
else
|
425
|
+
# Messages received over binary protocol will not have Base64 encoded data
|
426
|
+
expect(message['encoding']).to eql(encrypted_encoding.gsub(%r{/base64$}, ''))
|
427
|
+
expect(message['data']).to eql(encrypted_data_decoded)
|
428
|
+
end
|
429
|
+
stop_reactor
|
426
430
|
end
|
427
|
-
stop_reactor
|
428
|
-
end
|
429
431
|
|
430
|
-
|
432
|
+
encrypted_channel.publish 'example', encoded_data_decoded
|
433
|
+
end
|
431
434
|
end
|
432
435
|
|
433
436
|
it 'sends and receives messages that are encrypted & decrypted by the Ably library (#RTL7d)' do
|
434
|
-
encrypted_channel.publish 'example', encoded_data_decoded
|
435
437
|
encrypted_channel.subscribe do |message|
|
436
438
|
expect(message.data).to eql(encoded_data_decoded)
|
437
439
|
expect(message.encoding).to be_nil
|
438
440
|
stop_reactor
|
439
441
|
end
|
442
|
+
encrypted_channel.publish 'example', encoded_data_decoded
|
440
443
|
end
|
441
444
|
end
|
442
445
|
end
|
@@ -654,8 +657,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
654
657
|
expect(message_state).to be_empty
|
655
658
|
EventMachine.add_timer(2) do
|
656
659
|
expect(message_state).to contain_exactly(:delivered)
|
657
|
-
|
658
|
-
# expect(msgs_received.length).to eql(1)
|
660
|
+
expect(msgs_received.length).to eql(1)
|
659
661
|
stop_reactor
|
660
662
|
end
|
661
663
|
end
|