ably 1.1.6 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/check.yml +15 -1
- data/CHANGELOG.md +131 -0
- data/COPYRIGHT +1 -1
- data/README.md +14 -2
- data/SPEC.md +0 -7
- data/UPDATING.md +30 -0
- data/ably.gemspec +12 -7
- data/lib/ably/agent.rb +3 -0
- data/lib/ably/auth.rb +3 -3
- data/lib/ably/exceptions.rb +6 -0
- data/lib/ably/models/channel_options.rb +97 -0
- data/lib/ably/models/connection_details.rb +8 -0
- data/lib/ably/models/delta_extras.rb +29 -0
- data/lib/ably/models/error_info.rb +6 -2
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -0
- data/lib/ably/models/message.rb +28 -3
- data/lib/ably/models/presence_message.rb +14 -0
- data/lib/ably/models/protocol_message.rb +29 -12
- data/lib/ably/models/token_details.rb +7 -2
- data/lib/ably/modules/channels_collection.rb +22 -2
- data/lib/ably/modules/conversions.rb +34 -0
- data/lib/ably/realtime/channel/channel_manager.rb +18 -6
- data/lib/ably/realtime/channel/channel_state_machine.rb +10 -1
- data/lib/ably/realtime/channel/publisher.rb +6 -0
- data/lib/ably/realtime/channel.rb +54 -22
- data/lib/ably/realtime/channels.rb +1 -1
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -6
- data/lib/ably/realtime/connection/connection_manager.rb +13 -4
- data/lib/ably/realtime/connection/connection_state_machine.rb +4 -0
- data/lib/ably/realtime/connection.rb +2 -2
- data/lib/ably/rest/channel.rb +31 -31
- data/lib/ably/rest/client.rb +27 -12
- data/lib/ably/util/crypto.rb +1 -1
- data/lib/ably/version.rb +2 -14
- data/lib/ably.rb +1 -0
- data/spec/acceptance/realtime/auth_spec.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +25 -0
- data/spec/acceptance/realtime/channel_spec.rb +466 -21
- data/spec/acceptance/realtime/channels_spec.rb +59 -7
- data/spec/acceptance/realtime/connection_failures_spec.rb +59 -2
- data/spec/acceptance/realtime/connection_spec.rb +256 -28
- data/spec/acceptance/realtime/message_spec.rb +77 -0
- data/spec/acceptance/realtime/presence_history_spec.rb +3 -1
- data/spec/acceptance/realtime/presence_spec.rb +31 -159
- data/spec/acceptance/rest/auth_spec.rb +18 -0
- data/spec/acceptance/rest/channel_spec.rb +84 -9
- data/spec/acceptance/rest/channels_spec.rb +23 -6
- data/spec/acceptance/rest/client_spec.rb +25 -21
- data/spec/acceptance/rest/message_spec.rb +61 -3
- data/spec/lib/unit/models/channel_options_spec.rb +52 -0
- data/spec/shared/model_behaviour.rb +1 -1
- data/spec/spec_helper.rb +11 -2
- data/spec/support/test_app.rb +1 -1
- data/spec/unit/models/delta_extras_spec.rb +14 -0
- data/spec/unit/models/error_info_spec.rb +17 -1
- data/spec/unit/models/message_spec.rb +97 -0
- data/spec/unit/models/presence_message_spec.rb +49 -0
- data/spec/unit/models/protocol_message_spec.rb +125 -27
- data/spec/unit/models/token_details_spec.rb +14 -0
- data/spec/unit/realtime/channel_spec.rb +3 -2
- data/spec/unit/realtime/channels_spec.rb +53 -15
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +38 -0
- data/spec/unit/rest/channel_spec.rb +44 -1
- data/spec/unit/rest/channels_spec.rb +81 -14
- data/spec/unit/rest/client_spec.rb +47 -0
- metadata +60 -24
@@ -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
|
@@ -750,6 +874,107 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
750
874
|
end
|
751
875
|
end
|
752
876
|
|
877
|
+
describe '#(RTL17)' do
|
878
|
+
context 'when channel is initialized' do
|
879
|
+
it 'sends messages only on attach' do
|
880
|
+
expect(channel).to be_initialized
|
881
|
+
channel.publish('event', payload)
|
882
|
+
|
883
|
+
channel.subscribe do |message|
|
884
|
+
stop_reactor if message.data == payload && channel.attached?
|
885
|
+
end
|
886
|
+
|
887
|
+
channel.attach
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
891
|
+
context 'when channel is attaching' do
|
892
|
+
it 'sends messages only on attach' do
|
893
|
+
channel.publish('event', payload)
|
894
|
+
|
895
|
+
sent_message = nil
|
896
|
+
channel.subscribe do |message|
|
897
|
+
return if message.data != payload
|
898
|
+
sent_message = message
|
899
|
+
|
900
|
+
stop_reactor if channel.attached?
|
901
|
+
end
|
902
|
+
|
903
|
+
channel.on(:attaching) do
|
904
|
+
expect(channel).to be_attaching
|
905
|
+
expect(sent_message).to be_nil
|
906
|
+
end
|
907
|
+
|
908
|
+
channel.attach
|
909
|
+
end
|
910
|
+
end
|
911
|
+
|
912
|
+
context 'when channel is detaching' do
|
913
|
+
it 'stops sending message' do
|
914
|
+
sent_message = nil
|
915
|
+
event_published = false
|
916
|
+
channel.subscribe do |message|
|
917
|
+
sent_message = message if message.data == payload
|
918
|
+
end
|
919
|
+
|
920
|
+
channel.on(:detaching) do
|
921
|
+
channel.publish('event', payload)
|
922
|
+
event_published = true
|
923
|
+
end
|
924
|
+
|
925
|
+
channel.on(:detaching) do
|
926
|
+
EventMachine.next_tick do
|
927
|
+
expect(sent_message).to be_nil
|
928
|
+
stop_reactor if event_published
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
channel.attach do
|
933
|
+
channel.detach
|
934
|
+
end
|
935
|
+
end
|
936
|
+
end
|
937
|
+
|
938
|
+
context 'when channel is detached' do
|
939
|
+
it 'stops sending message' do
|
940
|
+
sent_message = nil
|
941
|
+
event_published = false
|
942
|
+
channel.subscribe do |message|
|
943
|
+
sent_message = message if message.data == payload
|
944
|
+
end
|
945
|
+
|
946
|
+
channel.on(:detaching) do
|
947
|
+
channel.publish('event', payload)
|
948
|
+
event_published = true
|
949
|
+
end
|
950
|
+
|
951
|
+
channel.on(:detached) do
|
952
|
+
expect(sent_message).to be_nil
|
953
|
+
stop_reactor if event_published
|
954
|
+
end
|
955
|
+
|
956
|
+
channel.attach do
|
957
|
+
channel.detach
|
958
|
+
end
|
959
|
+
end
|
960
|
+
end
|
961
|
+
|
962
|
+
context 'when channel is failed' do
|
963
|
+
it 'errors when trying to send a message' do
|
964
|
+
channel.once(:failed) do
|
965
|
+
channel.publish('event', payload).errback do |error|
|
966
|
+
expect(error).to be_a(Ably::Exceptions::ChannelInactive)
|
967
|
+
stop_reactor
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
971
|
+
channel.attach do
|
972
|
+
channel.transition_state_machine(:failed)
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
end
|
977
|
+
|
753
978
|
context 'when channel is not attached in state Initializing (#RTL6c1)' do
|
754
979
|
it 'publishes messages immediately and does not implicitly attach (#RTL6c1)' do
|
755
980
|
sub_channel.attach do
|
@@ -1181,7 +1406,7 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1181
1406
|
end
|
1182
1407
|
|
1183
1408
|
context 'with more than allowed messages in a single publish' do
|
1184
|
-
|
1409
|
+
65536
|
1185
1410
|
|
1186
1411
|
it 'rejects the publish' do
|
1187
1412
|
messages = (Ably::Realtime::Connection::MAX_PROTOCOL_MESSAGE_BATCH_SIZE + 1).times.map do
|
@@ -1403,6 +1628,103 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1403
1628
|
end
|
1404
1629
|
end
|
1405
1630
|
end
|
1631
|
+
|
1632
|
+
context 'message size exceeded (#TO3l8)' do
|
1633
|
+
let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
|
1634
|
+
let(:channel) { client.channels.get(channel_name) }
|
1635
|
+
|
1636
|
+
context 'and max_message_size is default (65536 bytes)' do
|
1637
|
+
let(:channel_name) { random_str }
|
1638
|
+
let(:max_message_size) { 65536 }
|
1639
|
+
|
1640
|
+
it 'should allow to send a message (32 bytes)' do
|
1641
|
+
client.connection.once(:connected) do
|
1642
|
+
channel.subscribe('event') do |msg|
|
1643
|
+
expect(msg.data).to eq('x' * 32)
|
1644
|
+
stop_reactor
|
1645
|
+
end
|
1646
|
+
channel.publish('event', 'x' * 32)
|
1647
|
+
end
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
it 'should not allow to send a message (700000 bytes)' do
|
1651
|
+
client.connection.once(:connected) do
|
1652
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1653
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1654
|
+
)
|
1655
|
+
client.connection.set_connection_details(connection_details)
|
1656
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1657
|
+
channel.publish('event', 'x' * 700000).errback do |error|
|
1658
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1659
|
+
stop_reactor
|
1660
|
+
end
|
1661
|
+
end
|
1662
|
+
end
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
context 'and max_message_size is customized (11 bytes)' do
|
1666
|
+
let(:max_message_size) { 11 }
|
1667
|
+
|
1668
|
+
context 'and the message size is 30 bytes' do
|
1669
|
+
let(:channel_name) { random_str }
|
1670
|
+
|
1671
|
+
it 'should not allow to send a message' do
|
1672
|
+
client.connection.once(:connected) do
|
1673
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1674
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1675
|
+
)
|
1676
|
+
client.connection.set_connection_details(connection_details)
|
1677
|
+
expect(client.connection.details.max_message_size).to eq(11)
|
1678
|
+
channel.publish('event', 'x' * 30).errback do |error|
|
1679
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1680
|
+
stop_reactor
|
1681
|
+
end
|
1682
|
+
end
|
1683
|
+
end
|
1684
|
+
end
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
context 'and max_message_size is nil' do
|
1688
|
+
let(:max_message_size) { nil }
|
1689
|
+
|
1690
|
+
context 'and the message size is 30 bytes' do
|
1691
|
+
let(:channel_name) { random_str }
|
1692
|
+
|
1693
|
+
it 'should allow to send a message' do
|
1694
|
+
client.connection.once(:connected) do
|
1695
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1696
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1697
|
+
)
|
1698
|
+
client.connection.set_connection_details(connection_details)
|
1699
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1700
|
+
channel.subscribe('event') do |msg|
|
1701
|
+
expect(msg.data).to eq('x' * 30)
|
1702
|
+
stop_reactor
|
1703
|
+
end
|
1704
|
+
channel.publish('event', 'x' * 30)
|
1705
|
+
end
|
1706
|
+
end
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
context 'and the message size is 65537 bytes' do
|
1710
|
+
let(:channel_name) { random_str }
|
1711
|
+
|
1712
|
+
it 'should not allow to send a message' do
|
1713
|
+
client.connection.once(:connected) do
|
1714
|
+
connection_details = Ably::Models::ConnectionDetails.new(
|
1715
|
+
client.connection.details.attributes.attributes.merge('maxMessageSize' => max_message_size)
|
1716
|
+
)
|
1717
|
+
client.connection.set_connection_details(connection_details)
|
1718
|
+
expect(client.connection.details.max_message_size).to eq(65536)
|
1719
|
+
channel.publish('event', 'x' * 65537).errback do |error|
|
1720
|
+
expect(error).to be_instance_of(Ably::Exceptions::MaxMessageSizeExceeded)
|
1721
|
+
stop_reactor
|
1722
|
+
end
|
1723
|
+
end
|
1724
|
+
end
|
1725
|
+
end
|
1726
|
+
end
|
1727
|
+
end
|
1406
1728
|
end
|
1407
1729
|
|
1408
1730
|
describe '#subscribe' do
|
@@ -1738,15 +2060,33 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1738
2060
|
end
|
1739
2061
|
end
|
1740
2062
|
|
1741
|
-
|
1742
|
-
|
1743
|
-
channel.
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
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
|
1747
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
|
1748
2089
|
end
|
1749
|
-
client.connection.transition_state_machine :suspended
|
1750
2090
|
end
|
1751
2091
|
end
|
1752
2092
|
end
|
@@ -1936,6 +2276,68 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1936
2276
|
end
|
1937
2277
|
end
|
1938
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
|
+
|
1939
2341
|
context 'channel state change' do
|
1940
2342
|
it 'emits a ChannelStateChange object' do
|
1941
2343
|
channel.on(:attached) do |channel_state_change|
|
@@ -2177,11 +2579,20 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2177
2579
|
end
|
2178
2580
|
|
2179
2581
|
context 'and channel is attached' do
|
2180
|
-
it 'reattaches immediately (#RTL13a)' do
|
2181
|
-
|
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
|
+
|
2182
2592
|
channel.once(:attaching) do |state_change|
|
2183
2593
|
expect(state_change.reason.code).to eql(50505)
|
2184
2594
|
channel.once(:attached) do
|
2595
|
+
expect(resume_flag).to eq(true)
|
2185
2596
|
stop_reactor
|
2186
2597
|
end
|
2187
2598
|
end
|
@@ -2189,25 +2600,59 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2189
2600
|
detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
|
2190
2601
|
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
|
2191
2602
|
end
|
2603
|
+
|
2604
|
+
channel.attach
|
2192
2605
|
end
|
2193
2606
|
end
|
2194
2607
|
|
2195
2608
|
context 'and channel is suspended' do
|
2196
|
-
it 'reattaches immediately (#RTL13a)' do
|
2197
|
-
|
2198
|
-
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2609
|
+
it 'reattaches immediately (#RTL13a) with ATTACH_RESUME flag(RTL4j)' do
|
2610
|
+
resume_flag = false
|
2611
|
+
|
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?
|
2621
|
+
end
|
2622
|
+
|
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
|
2633
|
+
end
|
2634
|
+
|
2635
|
+
channel.attach
|
2636
|
+
end
|
2637
|
+
|
2638
|
+
context 'when connection is no longer connected' do
|
2639
|
+
it 'will not attempt to reattach (#RTL13c)' do
|
2640
|
+
channel.attach do
|
2641
|
+
connection.once(:closing) do
|
2642
|
+
channel.once(:attaching) do |state_change|
|
2643
|
+
raise 'Channel should not attempt to reattach'
|
2203
2644
|
end
|
2645
|
+
|
2646
|
+
channel.transition_state_machine! :suspended
|
2204
2647
|
end
|
2205
2648
|
|
2206
|
-
|
2207
|
-
|
2208
|
-
|
2649
|
+
connection.once(:closed) do
|
2650
|
+
expect(channel).to be_suspended
|
2651
|
+
stop_reactor
|
2652
|
+
end
|
2209
2653
|
|
2210
|
-
|
2654
|
+
connection.close
|
2655
|
+
end
|
2211
2656
|
end
|
2212
2657
|
end
|
2213
2658
|
end
|
@@ -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
|