ably 1.1.6 → 1.2.0
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 +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
|