ably 1.1.8 → 1.2.2
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/.github/workflows/check.yml +14 -5
- data/CHANGELOG.md +48 -0
- data/README.md +2 -2
- data/UPDATING.md +30 -0
- data/ably.gemspec +12 -24
- data/lib/ably/auth.rb +8 -8
- data/lib/ably/logger.rb +4 -4
- data/lib/ably/models/channel_details.rb +59 -0
- data/lib/ably/models/channel_metrics.rb +84 -0
- data/lib/ably/models/channel_occupancy.rb +43 -0
- data/lib/ably/models/channel_options.rb +97 -0
- data/lib/ably/models/channel_status.rb +53 -0
- data/lib/ably/models/device_details.rb +1 -1
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
- data/lib/ably/models/message.rb +4 -4
- data/lib/ably/models/protocol_message.rb +19 -7
- data/lib/ably/models/token_details.rb +7 -2
- data/lib/ably/models/token_request.rb +1 -1
- data/lib/ably/modules/ably.rb +1 -1
- data/lib/ably/modules/channels_collection.rb +22 -2
- data/lib/ably/modules/conversions.rb +34 -0
- data/lib/ably/realtime/auth.rb +2 -2
- data/lib/ably/realtime/channel/channel_manager.rb +16 -4
- data/lib/ably/realtime/channel/channel_state_machine.rb +5 -0
- data/lib/ably/realtime/channel.rb +54 -24
- data/lib/ably/realtime/channels.rb +1 -1
- data/lib/ably/rest/channel.rb +33 -34
- data/lib/ably/rest/client.rb +8 -5
- data/lib/ably/rest/middleware/encoder.rb +1 -1
- data/lib/ably/rest/middleware/exceptions.rb +1 -1
- data/lib/ably/rest/middleware/external_exceptions.rb +1 -1
- data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +1 -1
- data/lib/ably/rest/middleware/logger.rb +1 -1
- data/lib/ably/rest/middleware/parse_json.rb +1 -1
- data/lib/ably/rest/middleware/parse_message_pack.rb +1 -1
- data/lib/ably/util/crypto.rb +1 -1
- data/lib/ably/version.rb +2 -2
- data/spec/acceptance/realtime/channel_spec.rb +247 -21
- data/spec/acceptance/realtime/channels_spec.rb +59 -7
- data/spec/acceptance/realtime/connection_spec.rb +21 -1
- data/spec/acceptance/realtime/message_spec.rb +77 -0
- data/spec/acceptance/rest/auth_spec.rb +18 -0
- data/spec/acceptance/rest/channel_spec.rb +19 -1
- data/spec/acceptance/rest/channels_spec.rb +22 -5
- data/spec/acceptance/rest/client_spec.rb +3 -3
- data/spec/acceptance/rest/message_spec.rb +61 -3
- data/spec/lib/unit/models/channel_options_spec.rb +52 -0
- data/spec/run_parallel_tests +2 -7
- data/spec/unit/logger_spec.rb +6 -14
- data/spec/unit/models/channel_details_spec.rb +30 -0
- data/spec/unit/models/channel_metrics_spec.rb +42 -0
- data/spec/unit/models/channel_occupancy_spec.rb +17 -0
- data/spec/unit/models/channel_status_spec.rb +36 -0
- data/spec/unit/models/message_spec.rb +14 -0
- data/spec/unit/models/protocol_message_spec.rb +53 -7
- data/spec/unit/models/token_details_spec.rb +14 -0
- data/spec/unit/realtime/channels_spec.rb +52 -14
- data/spec/unit/rest/channels_spec.rb +81 -14
- metadata +69 -11
@@ -5,7 +5,7 @@ module Ably
|
|
5
5
|
module Middleware
|
6
6
|
# HTTP exceptions raised due to a status code error on a 3rd party site
|
7
7
|
# Used by auth calls
|
8
|
-
class ExternalExceptions < Faraday::
|
8
|
+
class ExternalExceptions < Faraday::Middleware
|
9
9
|
def on_complete(env)
|
10
10
|
if env.status >= 400
|
11
11
|
error_status_code = env.status
|
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
module Ably
|
5
5
|
module Rest
|
6
6
|
module Middleware
|
7
|
-
class FailIfUnsupportedMimeType < Faraday::
|
7
|
+
class FailIfUnsupportedMimeType < Faraday::Middleware
|
8
8
|
def on_complete(env)
|
9
9
|
unless env.response_headers['Ably-Middleware-Parsed'] == true
|
10
10
|
# Ignore empty body with success status code for no body response
|
@@ -4,7 +4,7 @@ require 'json'
|
|
4
4
|
module Ably
|
5
5
|
module Rest
|
6
6
|
module Middleware
|
7
|
-
class ParseJson < Faraday::
|
7
|
+
class ParseJson < Faraday::Middleware
|
8
8
|
def on_complete(env)
|
9
9
|
if env.response_headers['Content-Type'] == 'application/json'
|
10
10
|
env.body = parse(env.body) unless env.response_headers['Ably-Middleware-Parsed'] == true
|
@@ -4,7 +4,7 @@ require 'msgpack'
|
|
4
4
|
module Ably
|
5
5
|
module Rest
|
6
6
|
module Middleware
|
7
|
-
class ParseMessagePack < Faraday::
|
7
|
+
class ParseMessagePack < Faraday::Middleware
|
8
8
|
def on_complete(env)
|
9
9
|
if env.response_headers['Content-Type'] == 'application/x-msgpack'
|
10
10
|
env.body = parse(env.body) unless env.response_headers['Ably-Middleware-Parsed'] == true
|
data/lib/ably/util/crypto.rb
CHANGED
@@ -30,7 +30,7 @@ module Ably::Util
|
|
30
30
|
# crypto.decrypt(decrypted) # => 'secret text'
|
31
31
|
#
|
32
32
|
def initialize(params)
|
33
|
-
@fixed_iv = params
|
33
|
+
@fixed_iv = params[:fixed_iv]
|
34
34
|
@cipher_params = Ably::Models::CipherParams(params)
|
35
35
|
end
|
36
36
|
|
data/lib/ably/version.rb
CHANGED
@@ -117,6 +117,94 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
context 'context when channel options contain modes' do
|
121
|
+
before do
|
122
|
+
channel.options = { modes: %i[publish] }
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'sends an ATTACH with options as flags (#RTL4l)' do
|
126
|
+
connection.once(:connected) do
|
127
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
128
|
+
next if protocol_message.action != :attach
|
129
|
+
|
130
|
+
expect(protocol_message.has_attach_publish_flag?).to eq(true)
|
131
|
+
stop_reactor
|
132
|
+
end
|
133
|
+
|
134
|
+
channel.attach
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when channel is reattaching' do
|
139
|
+
it 'sends ATTACH_RESUME flag along with other modes (RTL4j)' do
|
140
|
+
channel.attach do
|
141
|
+
channel.on(:suspended) do
|
142
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
143
|
+
next if protocol_message.action != :attach
|
144
|
+
|
145
|
+
expect(protocol_message.has_attach_resume_flag?).to eq(true)
|
146
|
+
expect(protocol_message.has_attach_publish_flag?).to eq(true)
|
147
|
+
stop_reactor
|
148
|
+
end
|
149
|
+
|
150
|
+
client.connection.connect
|
151
|
+
end
|
152
|
+
client.connection.transition_state_machine :suspended
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'context when channel options contain params' do
|
159
|
+
let(:params) do
|
160
|
+
{ foo: 'foo', bar: 'bar'}
|
161
|
+
end
|
162
|
+
|
163
|
+
before do
|
164
|
+
channel.options = { params: params }
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'sends an ATTACH with params (#RTL4k)' do
|
168
|
+
connection.once(:connected) do
|
169
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
170
|
+
next if protocol_message.action != :attach
|
171
|
+
|
172
|
+
expect(protocol_message.params).to eq(params)
|
173
|
+
stop_reactor
|
174
|
+
end
|
175
|
+
|
176
|
+
channel.attach
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'when received attached' do
|
182
|
+
it 'decodes flags and sets it as modes on channel options (#RTL4m)'do
|
183
|
+
channel.on(:attached) do
|
184
|
+
expect(channel.options.modes.map(&:to_sym)).to eq(%i[subscribe])
|
185
|
+
stop_reactor
|
186
|
+
end
|
187
|
+
|
188
|
+
channel.transition_state_machine(:attaching)
|
189
|
+
attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name, flags: 262144)
|
190
|
+
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'set params as channel options params (#RTL4k1)' do
|
194
|
+
params = { param: :something }
|
195
|
+
|
196
|
+
channel.on(:attached) do
|
197
|
+
expect(channel.params).to eq(channel.options.params)
|
198
|
+
expect(channel.params).to eq(params)
|
199
|
+
stop_reactor
|
200
|
+
end
|
201
|
+
|
202
|
+
channel.transition_state_machine(:attaching)
|
203
|
+
attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name, params: params)
|
204
|
+
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
120
208
|
it 'implicitly attaches the channel (#RTL7c)' do
|
121
209
|
expect(channel).to be_initialized
|
122
210
|
channel.subscribe { |message| }
|
@@ -368,6 +456,42 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
368
456
|
end
|
369
457
|
end
|
370
458
|
end
|
459
|
+
|
460
|
+
describe 'clean attach (RTL4j)' do
|
461
|
+
context "when channel wasn't previously attached" do
|
462
|
+
it "doesn't send ATTACH_RESUME" do
|
463
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
464
|
+
next if protocol_message.action != :attach
|
465
|
+
|
466
|
+
expect(protocol_message.has_attach_resume_flag?).to eq(false)
|
467
|
+
stop_reactor
|
468
|
+
end
|
469
|
+
|
470
|
+
channel.attach
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context "when channel was explicitly detached" do
|
475
|
+
it "doesn't send ATTACH_RESUME" do
|
476
|
+
channel.once(:detached) do
|
477
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
478
|
+
next if protocol_message.action != :attach
|
479
|
+
|
480
|
+
expect(protocol_message.has_attach_resume_flag?).to eq(false)
|
481
|
+
stop_reactor
|
482
|
+
end
|
483
|
+
|
484
|
+
channel.attach
|
485
|
+
end
|
486
|
+
|
487
|
+
channel.once(:attached) do
|
488
|
+
channel.detach
|
489
|
+
end
|
490
|
+
|
491
|
+
channel.attach
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
371
495
|
end
|
372
496
|
|
373
497
|
describe '#detach' do
|
@@ -1936,15 +2060,33 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1936
2060
|
end
|
1937
2061
|
end
|
1938
2062
|
|
1939
|
-
|
1940
|
-
|
1941
|
-
channel.
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
2063
|
+
describe 'reattaching (#RTN15c3)' do
|
2064
|
+
it 'transitions state automatically to :attaching once the connection is re-established ' do
|
2065
|
+
channel.attach do
|
2066
|
+
channel.on(:suspended) do
|
2067
|
+
client.connection.connect
|
2068
|
+
channel.once(:attached) do
|
2069
|
+
stop_reactor
|
2070
|
+
end
|
1945
2071
|
end
|
2072
|
+
client.connection.transition_state_machine :suspended
|
2073
|
+
end
|
2074
|
+
end
|
2075
|
+
|
2076
|
+
it 'sends ATTACH_RESUME flag when reattaching (RTL4j)' do
|
2077
|
+
channel.attach do
|
2078
|
+
channel.on(:suspended) do
|
2079
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2080
|
+
next if protocol_message.action != :attach
|
2081
|
+
|
2082
|
+
expect(protocol_message.has_attach_resume_flag?).to eq(true)
|
2083
|
+
stop_reactor
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
client.connection.connect
|
2087
|
+
end
|
2088
|
+
client.connection.transition_state_machine :suspended
|
1946
2089
|
end
|
1947
|
-
client.connection.transition_state_machine :suspended
|
1948
2090
|
end
|
1949
2091
|
end
|
1950
2092
|
end
|
@@ -2134,6 +2276,68 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2134
2276
|
end
|
2135
2277
|
end
|
2136
2278
|
|
2279
|
+
describe '#set_options (#RTL16a)' do
|
2280
|
+
let(:modes) { %i[subscribe] }
|
2281
|
+
let(:channel_options) do
|
2282
|
+
{ modes: modes }
|
2283
|
+
end
|
2284
|
+
|
2285
|
+
def self.build_flags(flags)
|
2286
|
+
flags.map { |flag| Ably::Models::ProtocolMessage::ATTACH_FLAGS_MAPPING[flag] }.reduce(:|)
|
2287
|
+
end
|
2288
|
+
|
2289
|
+
shared_examples 'an update that sends ATTACH message' do |state, flags|
|
2290
|
+
it 'sends an ATTACH message on options change' do
|
2291
|
+
attach_sent = nil
|
2292
|
+
|
2293
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2294
|
+
if protocol_message.action == :attach && protocol_message.flags.nonzero?
|
2295
|
+
attach_sent = true
|
2296
|
+
expect(protocol_message.flags).to eq(flags)
|
2297
|
+
end
|
2298
|
+
end
|
2299
|
+
|
2300
|
+
channel.once(state) do
|
2301
|
+
channel.options = channel_options
|
2302
|
+
end
|
2303
|
+
|
2304
|
+
channel.on(:attached) do
|
2305
|
+
client.connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2306
|
+
next if protocol_message.action != :attached
|
2307
|
+
|
2308
|
+
expect(attach_sent).to eq(true)
|
2309
|
+
stop_reactor
|
2310
|
+
end
|
2311
|
+
end
|
2312
|
+
|
2313
|
+
channel.attach
|
2314
|
+
end
|
2315
|
+
end
|
2316
|
+
|
2317
|
+
context 'when channel is attaching' do
|
2318
|
+
it_behaves_like 'an update that sends ATTACH message', :attaching, build_flags(%i[subscribe])
|
2319
|
+
end
|
2320
|
+
|
2321
|
+
context 'when channel is attaching' do
|
2322
|
+
it_behaves_like 'an update that sends ATTACH message', :attached, build_flags(%i[resume subscribe])
|
2323
|
+
end
|
2324
|
+
|
2325
|
+
context 'when channel is initialized' do
|
2326
|
+
it "doesn't send ATTACH message" do
|
2327
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2328
|
+
raise "Unexpected message" if protocol_message.action == :attach
|
2329
|
+
end
|
2330
|
+
|
2331
|
+
channel.options = channel_options
|
2332
|
+
expect(channel.options.modes.map(&:to_sym)).to eq(modes)
|
2333
|
+
|
2334
|
+
EventMachine.next_tick do
|
2335
|
+
stop_reactor
|
2336
|
+
end
|
2337
|
+
end
|
2338
|
+
end
|
2339
|
+
end
|
2340
|
+
|
2137
2341
|
context 'channel state change' do
|
2138
2342
|
it 'emits a ChannelStateChange object' do
|
2139
2343
|
channel.on(:attached) do |channel_state_change|
|
@@ -2375,11 +2579,20 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2375
2579
|
end
|
2376
2580
|
|
2377
2581
|
context 'and channel is attached' do
|
2378
|
-
it 'reattaches immediately (#RTL13a)' do
|
2379
|
-
|
2582
|
+
it 'reattaches immediately (#RTL13a) with ATTACH_RESUME flag(RTL4j)' do
|
2583
|
+
resume_flag = false
|
2584
|
+
|
2585
|
+
channel.once(:attached) do
|
2586
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2587
|
+
next if protocol_message.action != :attach
|
2588
|
+
|
2589
|
+
resume_flag = protocol_message.has_attach_resume_flag?
|
2590
|
+
end
|
2591
|
+
|
2380
2592
|
channel.once(:attaching) do |state_change|
|
2381
2593
|
expect(state_change.reason.code).to eql(50505)
|
2382
2594
|
channel.once(:attached) do
|
2595
|
+
expect(resume_flag).to eq(true)
|
2383
2596
|
stop_reactor
|
2384
2597
|
end
|
2385
2598
|
end
|
@@ -2387,26 +2600,39 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2387
2600
|
detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
|
2388
2601
|
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
|
2389
2602
|
end
|
2603
|
+
|
2604
|
+
channel.attach
|
2390
2605
|
end
|
2391
2606
|
end
|
2392
2607
|
|
2393
2608
|
context 'and channel is suspended' do
|
2394
|
-
it 'reattaches immediately (#RTL13a)' do
|
2395
|
-
|
2396
|
-
channel.once(:suspended) do
|
2397
|
-
channel.once(:attaching) do |state_change|
|
2398
|
-
expect(state_change.reason.code).to eql(50505)
|
2399
|
-
channel.once(:attached) do
|
2400
|
-
stop_reactor
|
2401
|
-
end
|
2402
|
-
end
|
2609
|
+
it 'reattaches immediately (#RTL13a) with ATTACH_RESUME flag(RTL4j)' do
|
2610
|
+
resume_flag = false
|
2403
2611
|
|
2404
|
-
|
2405
|
-
|
2612
|
+
channel.once(:attached) do
|
2613
|
+
channel.transition_state_machine! :suspended
|
2614
|
+
end
|
2615
|
+
|
2616
|
+
channel.once(:suspended) do
|
2617
|
+
client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
|
2618
|
+
next if protocol_message.action != :attach
|
2619
|
+
|
2620
|
+
resume_flag = protocol_message.has_attach_resume_flag?
|
2406
2621
|
end
|
2407
2622
|
|
2408
|
-
channel.
|
2623
|
+
channel.once(:attaching) do |state_change|
|
2624
|
+
expect(state_change.reason.code).to eql(50505)
|
2625
|
+
channel.once(:attached) do
|
2626
|
+
expect(resume_flag).to eq(true)
|
2627
|
+
stop_reactor
|
2628
|
+
end
|
2629
|
+
end
|
2630
|
+
|
2631
|
+
detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
|
2632
|
+
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
|
2409
2633
|
end
|
2634
|
+
|
2635
|
+
channel.attach
|
2410
2636
|
end
|
2411
2637
|
|
2412
2638
|
context 'when connection is no longer connected' do
|
@@ -10,17 +10,56 @@ describe Ably::Realtime::Channels, :event_machine do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'returns channel object and passes the provided options' do
|
13
|
-
expect(
|
13
|
+
expect(channel_options).to be_a(Ably::Models::ChannelOptions)
|
14
|
+
expect(channel_options.to_h).to eq(options)
|
14
15
|
stop_reactor
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
vary_by_protocol do
|
20
|
+
let(:client_options) do
|
21
|
+
{ key: api_key, environment: environment, protocol: protocol }
|
22
|
+
end
|
19
23
|
let(:client) do
|
20
|
-
auto_close Ably::Realtime::Client.new(
|
24
|
+
auto_close Ably::Realtime::Client.new(client_options)
|
21
25
|
end
|
22
26
|
let(:channel_name) { random_str }
|
23
|
-
let(:options)
|
27
|
+
let(:options) do
|
28
|
+
{ params: { key: 'value' } }
|
29
|
+
end
|
30
|
+
|
31
|
+
subject(:channel_options) { channel_with_options.options }
|
32
|
+
|
33
|
+
context 'when channel supposed to trigger reattachment per RTL16a (#RTS3c1)' do
|
34
|
+
it 'will raise an error' do
|
35
|
+
channel = client.channels.get(channel_name, options)
|
36
|
+
|
37
|
+
channel.on(:attached) do
|
38
|
+
expect { client.channels.get(channel_name, { modes: [] }) }.to raise_error ArgumentError, /use Channel#set_options directly/
|
39
|
+
stop_reactor
|
40
|
+
end
|
41
|
+
|
42
|
+
channel.attach
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'params keys are the same but values are different' do
|
46
|
+
let(:options) do
|
47
|
+
{ params: { x: '1' } }
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'will raise an error' do
|
51
|
+
channel = client.channels.get(channel_name, options)
|
52
|
+
|
53
|
+
channel.on(:attached) do
|
54
|
+
expect { client.channels.get(channel_name, { params: { x: '2' } }) }.to raise_error ArgumentError, /use Channel#set_options directly/
|
55
|
+
|
56
|
+
stop_reactor
|
57
|
+
end
|
58
|
+
|
59
|
+
channel.attach
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
24
63
|
|
25
64
|
describe 'using shortcut method #channel on the client object' do
|
26
65
|
let(:channel) { client.channel(channel_name) }
|
@@ -35,26 +74,39 @@ describe Ably::Realtime::Channels, :event_machine do
|
|
35
74
|
end
|
36
75
|
|
37
76
|
describe 'accessing an existing channel object with different options' do
|
77
|
+
let(:client_options) { super().merge(logger: custom_logger_object) }
|
78
|
+
let(:custom_logger_object) { TestLogger.new }
|
38
79
|
let(:new_channel_options) { { encrypted: true } }
|
39
|
-
let(:original_channel) { client.channels.get(channel_name, options) }
|
80
|
+
let!(:original_channel) { client.channels.get(channel_name, options) }
|
40
81
|
|
41
82
|
it 'overrides the existing channel options and returns the channel object' do
|
42
|
-
expect(original_channel.options).to_not include(:encrypted)
|
83
|
+
expect(original_channel.options.to_h).to_not include(:encrypted)
|
43
84
|
new_channel = client.channels.get(channel_name, new_channel_options)
|
44
85
|
expect(new_channel).to be_a(Ably::Realtime::Channel)
|
45
86
|
expect(new_channel.options[:encrypted]).to eql(true)
|
46
87
|
stop_reactor
|
47
88
|
end
|
89
|
+
|
90
|
+
it 'shows deprecation warning' do
|
91
|
+
client.channels.get(channel_name, new_channel_options)
|
92
|
+
|
93
|
+
warning = custom_logger_object.logs.find do |severity, message|
|
94
|
+
message.match(/Using this method to update channel options is deprecated and may be removed/)
|
95
|
+
end
|
96
|
+
|
97
|
+
expect(warning).to_not be_nil
|
98
|
+
stop_reactor
|
99
|
+
end
|
48
100
|
end
|
49
101
|
|
50
102
|
describe 'accessing an existing channel object without specifying any channel options' do
|
51
103
|
let(:original_channel) { client.channels.get(channel_name, options) }
|
52
104
|
|
53
105
|
it 'returns the existing channel without modifying the channel options' do
|
54
|
-
expect(original_channel.options).to
|
106
|
+
expect(original_channel.options.to_h).to eq(options)
|
55
107
|
new_channel = client.channels.get(channel_name)
|
56
108
|
expect(new_channel).to be_a(Ably::Realtime::Channel)
|
57
|
-
expect(original_channel.options).to
|
109
|
+
expect(original_channel.options.to_h).to eq(options)
|
58
110
|
stop_reactor
|
59
111
|
end
|
60
112
|
end
|
@@ -482,6 +482,26 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
482
482
|
end
|
483
483
|
end
|
484
484
|
|
485
|
+
context "when can't connect to host" do
|
486
|
+
let(:client_options) { super().merge(realtime_host: 'non-existent.ably.io') }
|
487
|
+
|
488
|
+
it 'logs error on failed connection attempt' do
|
489
|
+
logger_expectation = lambda do |*args, &block|
|
490
|
+
error_message = "Connection to non-existent.ably.io:443 failed"
|
491
|
+
expect(args.concat([block ? block.call : nil]).join(',')).to include(error_message)
|
492
|
+
stop_reactor
|
493
|
+
end
|
494
|
+
|
495
|
+
expect(connection.logger).to receive(:warn, &logger_expectation).at_least(:once)
|
496
|
+
|
497
|
+
connection.on(:connected) do
|
498
|
+
raise "Connection should not succeed"
|
499
|
+
end
|
500
|
+
|
501
|
+
connection.connect
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
485
505
|
context 'when explicitly reconnecting disconnected/suspended connection in retry (#RTN11c)' do
|
486
506
|
let(:close_connection_proc) do
|
487
507
|
lambda do
|
@@ -2083,7 +2103,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
2083
2103
|
it 'sends the protocol version param v (#G4, #RTN2f)' do
|
2084
2104
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
2085
2105
|
uri = URI.parse(url)
|
2086
|
-
expect(CGI::parse(uri.query)['v'][0]).to eql('1.
|
2106
|
+
expect(CGI::parse(uri.query)['v'][0]).to eql('1.2')
|
2087
2107
|
stop_reactor
|
2088
2108
|
end
|
2089
2109
|
client
|
@@ -75,6 +75,83 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
context 'a single Message object (#RSL1a)' do
|
79
|
+
let(:name) { random_str }
|
80
|
+
let(:data) { random_str }
|
81
|
+
let(:message) { Ably::Models::Message.new(name: name, data: data) }
|
82
|
+
|
83
|
+
it 'publishes the message' do
|
84
|
+
channel.attach
|
85
|
+
channel.publish(message)
|
86
|
+
channel.subscribe do |msg|
|
87
|
+
expect(msg.name).to eq(message.name)
|
88
|
+
expect(msg.data).to eq(message.data)
|
89
|
+
stop_reactor
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'an array of Message objects (#RSL1a)' do
|
95
|
+
let(:data) { random_str }
|
96
|
+
let(:message1) { Ably::Models::Message.new(name: random_str, data: data) }
|
97
|
+
let(:message2) { Ably::Models::Message.new(name: random_str, data: data) }
|
98
|
+
let(:message3) { Ably::Models::Message.new(name: random_str, data: data) }
|
99
|
+
|
100
|
+
it 'publishes three messages' do
|
101
|
+
channel.attach
|
102
|
+
channel.publish([message1, message2, message3])
|
103
|
+
counter = 0
|
104
|
+
channel.subscribe do |message|
|
105
|
+
counter += 1
|
106
|
+
expect(message.data).to eq(data)
|
107
|
+
expect(message.name).to eq(message1.name) if counter == 1
|
108
|
+
expect(message.name).to eq(message2.name) if counter == 2
|
109
|
+
if counter == 3
|
110
|
+
expect(message.name).to eq(message3.name)
|
111
|
+
stop_reactor
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'an array of hashes (#RSL1a)' do
|
118
|
+
let(:data) { random_str }
|
119
|
+
let(:message1) { { name: random_str, data: data } }
|
120
|
+
let(:message2) { { name: random_str, data: data } }
|
121
|
+
let(:message3) { { name: random_str, data: data } }
|
122
|
+
|
123
|
+
it 'publishes three messages' do
|
124
|
+
channel.attach
|
125
|
+
channel.publish([message1, message2, message3])
|
126
|
+
counter = 0
|
127
|
+
channel.subscribe do |message|
|
128
|
+
counter += 1
|
129
|
+
expect(message.data).to eq(data)
|
130
|
+
expect(message.name).to eq(message1[:name]) if counter == 1
|
131
|
+
expect(message.name).to eq(message2[:name]) if counter == 2
|
132
|
+
if counter == 3
|
133
|
+
expect(message.name).to eq(message3[:name])
|
134
|
+
stop_reactor
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'a name with data payload (#RSL1a, #RSL1b)' do
|
141
|
+
let(:name) { random_str }
|
142
|
+
let(:data) { random_str }
|
143
|
+
|
144
|
+
it 'publishes a message' do
|
145
|
+
channel.attach
|
146
|
+
channel.publish(name, data)
|
147
|
+
channel.subscribe do |message|
|
148
|
+
expect(message.name).to eql(name)
|
149
|
+
expect(message.data).to eq(data)
|
150
|
+
stop_reactor
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
78
155
|
context 'with supported extra payload content type (#RTL6h, #RSL6a2)' do
|
79
156
|
let(:channel) { client.channel("pushenabled:#{random_str}") }
|
80
157
|
|
@@ -1165,6 +1165,24 @@ describe Ably::Auth do
|
|
1165
1165
|
end
|
1166
1166
|
end
|
1167
1167
|
|
1168
|
+
context 'when token does not expire' do
|
1169
|
+
let(:client_options) { default_options.merge(use_token_auth: true, key: api_key, query_time: true) }
|
1170
|
+
let(:channel) { client.channels.get(random_str) }
|
1171
|
+
|
1172
|
+
context 'for the next 2 hours' do
|
1173
|
+
let(:local_time) { Time.now - 2 * 60 * 60 }
|
1174
|
+
|
1175
|
+
before { allow(Time).to receive(:now).and_return(local_time) }
|
1176
|
+
|
1177
|
+
it 'should not request for the new token (#RSA4b1)' do
|
1178
|
+
expect { channel.publish 'event' }.to change { auth.current_token_details }
|
1179
|
+
expect do
|
1180
|
+
expect { channel.publish 'event' }.not_to change { auth.current_token_details }
|
1181
|
+
end.not_to change { auth.current_token_details.expires }
|
1182
|
+
end
|
1183
|
+
end
|
1184
|
+
end
|
1185
|
+
|
1168
1186
|
context 'when :client_id is provided in a token' do
|
1169
1187
|
let(:client_id) { '123' }
|
1170
1188
|
let(:token) do
|
@@ -5,7 +5,7 @@ describe Ably::Rest::Channel do
|
|
5
5
|
include Ably::Modules::Conversions
|
6
6
|
|
7
7
|
vary_by_protocol do
|
8
|
-
let(:default_options) { { key: api_key, environment: environment, protocol: protocol, max_frame_size: max_frame_size, max_message_size: max_message_size } }
|
8
|
+
let(:default_options) { { key: api_key, environment: environment, protocol: protocol, max_frame_size: max_frame_size, max_message_size: max_message_size, idempotent_rest_publishing: false } }
|
9
9
|
let(:client_options) { default_options }
|
10
10
|
let(:client) do
|
11
11
|
Ably::Rest::Client.new(client_options)
|
@@ -595,5 +595,23 @@ describe Ably::Rest::Channel do
|
|
595
595
|
expect(channel.presence).to be_a(Ably::Rest::Presence)
|
596
596
|
end
|
597
597
|
end
|
598
|
+
|
599
|
+
context '#status' do
|
600
|
+
let(:channel_name) { "persisted:#{random_str(4)}" }
|
601
|
+
let(:channel) { client.channel(channel_name) }
|
602
|
+
let(:channel_details) { channel.status }
|
603
|
+
|
604
|
+
it 'should return channel details status (#RSL8, #RSL8a)' do
|
605
|
+
expect(channel_details.channel_id).to eq(channel_name)
|
606
|
+
expect(channel_details.name).to eq(channel_name)
|
607
|
+
expect(channel_details.status).to be_a(Ably::Models::ChannelStatus)
|
608
|
+
expect(channel_details.status.is_active).to eq(true)
|
609
|
+
expect(channel_details.status.occupancy.metrics.publishers).to eq(0)
|
610
|
+
expect(channel_details.status.occupancy.metrics.subscribers).to eq(0)
|
611
|
+
expect(channel_details.status.occupancy.metrics.presence_connections).to eq(0)
|
612
|
+
expect(channel_details.status.occupancy.metrics.presence_members).to eq(0)
|
613
|
+
expect(channel_details.status.occupancy.metrics.presence_subscribers).to eq(0)
|
614
|
+
end
|
615
|
+
end
|
598
616
|
end
|
599
617
|
end
|