ably 1.1.7 → 1.2.1
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 +1 -1
- data/CHANGELOG.md +99 -0
- data/COPYRIGHT +1 -1
- data/README.md +2 -2
- data/SPEC.md +0 -7
- data/UPDATING.md +30 -0
- data/ably.gemspec +11 -24
- data/lib/ably/auth.rb +8 -8
- data/lib/ably/logger.rb +4 -4
- data/lib/ably/models/channel_options.rb +97 -0
- data/lib/ably/models/connection_details.rb +8 -2
- data/lib/ably/models/delta_extras.rb +29 -0
- data/lib/ably/models/device_details.rb +1 -1
- 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 +14 -3
- data/lib/ably/models/protocol_message.rb +23 -14
- 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 +10 -1
- data/lib/ably/realtime/channel/publisher.rb +3 -2
- data/lib/ably/realtime/channel.rb +54 -22
- data/lib/ably/realtime/channels.rb +1 -1
- 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 +0 -3
- data/lib/ably/rest/channel.rb +28 -35
- data/lib/ably/rest/client.rb +23 -8
- 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 +458 -27
- data/spec/acceptance/realtime/channels_spec.rb +59 -7
- data/spec/acceptance/realtime/connection_failures_spec.rb +56 -1
- data/spec/acceptance/realtime/connection_spec.rb +270 -1
- data/spec/acceptance/realtime/message_spec.rb +77 -0
- data/spec/acceptance/realtime/presence_spec.rb +18 -1
- data/spec/acceptance/rest/auth_spec.rb +18 -0
- data/spec/acceptance/rest/channel_spec.rb +73 -11
- data/spec/acceptance/rest/channels_spec.rb +23 -6
- 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/support/test_app.rb +1 -1
- data/spec/unit/logger_spec.rb +6 -14
- 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 +38 -0
- data/spec/unit/models/protocol_message_spec.rb +77 -27
- data/spec/unit/models/token_details_spec.rb +14 -0
- data/spec/unit/realtime/channel_spec.rb +2 -1
- data/spec/unit/realtime/channels_spec.rb +53 -15
- data/spec/unit/rest/channel_spec.rb +40 -7
- data/spec/unit/rest/channels_spec.rb +81 -14
- data/spec/unit/rest/client_spec.rb +27 -0
- metadata +46 -11
@@ -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
|
@@ -1405,15 +1630,98 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1405
1630
|
end
|
1406
1631
|
|
1407
1632
|
context 'message size exceeded (#TO3l8)' do
|
1408
|
-
let(:message) { 'x' * 700000 }
|
1409
|
-
|
1410
1633
|
let(:client) { auto_close Ably::Realtime::Client.new(client_options) }
|
1411
1634
|
let(:channel) { client.channels.get(channel_name) }
|
1412
1635
|
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
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
|
1417
1725
|
end
|
1418
1726
|
end
|
1419
1727
|
end
|
@@ -1752,15 +2060,33 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1752
2060
|
end
|
1753
2061
|
end
|
1754
2062
|
|
1755
|
-
|
1756
|
-
|
1757
|
-
channel.
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
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
|
1761
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
|
1762
2089
|
end
|
1763
|
-
client.connection.transition_state_machine :suspended
|
1764
2090
|
end
|
1765
2091
|
end
|
1766
2092
|
end
|
@@ -1950,6 +2276,68 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
1950
2276
|
end
|
1951
2277
|
end
|
1952
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
|
+
|
1953
2341
|
context 'channel state change' do
|
1954
2342
|
it 'emits a ChannelStateChange object' do
|
1955
2343
|
channel.on(:attached) do |channel_state_change|
|
@@ -2191,11 +2579,20 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2191
2579
|
end
|
2192
2580
|
|
2193
2581
|
context 'and channel is attached' do
|
2194
|
-
it 'reattaches immediately (#RTL13a)' do
|
2195
|
-
|
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
|
+
|
2196
2592
|
channel.once(:attaching) do |state_change|
|
2197
2593
|
expect(state_change.reason.code).to eql(50505)
|
2198
2594
|
channel.once(:attached) do
|
2595
|
+
expect(resume_flag).to eq(true)
|
2199
2596
|
stop_reactor
|
2200
2597
|
end
|
2201
2598
|
end
|
@@ -2203,25 +2600,59 @@ describe Ably::Realtime::Channel, :event_machine do
|
|
2203
2600
|
detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
|
2204
2601
|
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
|
2205
2602
|
end
|
2603
|
+
|
2604
|
+
channel.attach
|
2206
2605
|
end
|
2207
2606
|
end
|
2208
2607
|
|
2209
2608
|
context 'and channel is suspended' do
|
2210
|
-
it 'reattaches immediately (#RTL13a)' do
|
2211
|
-
|
2212
|
-
|
2213
|
-
|
2214
|
-
|
2215
|
-
|
2216
|
-
|
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'
|
2217
2644
|
end
|
2645
|
+
|
2646
|
+
channel.transition_state_machine! :suspended
|
2218
2647
|
end
|
2219
2648
|
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2649
|
+
connection.once(:closed) do
|
2650
|
+
expect(channel).to be_suspended
|
2651
|
+
stop_reactor
|
2652
|
+
end
|
2223
2653
|
|
2224
|
-
|
2654
|
+
connection.close
|
2655
|
+
end
|
2225
2656
|
end
|
2226
2657
|
end
|
2227
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
|