lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb in ably-rest-1.1.8 vs lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb in ably-rest-1.2.0
- old
+ new
@@ -115,10 +115,98 @@
end
end
end
end
+ context 'context when channel options contain modes' do
+ before do
+ channel.options = { modes: %i[publish] }
+ end
+
+ it 'sends an ATTACH with options as flags (#RTL4l)' do
+ connection.once(:connected) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.has_attach_publish_flag?).to eq(true)
+ stop_reactor
+ end
+
+ channel.attach
+ end
+ end
+
+ context 'when channel is reattaching' do
+ it 'sends ATTACH_RESUME flag along with other modes (RTL4j)' do
+ channel.attach do
+ channel.on(:suspended) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.has_attach_resume_flag?).to eq(true)
+ expect(protocol_message.has_attach_publish_flag?).to eq(true)
+ stop_reactor
+ end
+
+ client.connection.connect
+ end
+ client.connection.transition_state_machine :suspended
+ end
+ end
+ end
+ end
+
+ context 'context when channel options contain params' do
+ let(:params) do
+ { foo: 'foo', bar: 'bar'}
+ end
+
+ before do
+ channel.options = { params: params }
+ end
+
+ it 'sends an ATTACH with params (#RTL4k)' do
+ connection.once(:connected) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.params).to eq(params)
+ stop_reactor
+ end
+
+ channel.attach
+ end
+ end
+ end
+
+ context 'when received attached' do
+ it 'decodes flags and sets it as modes on channel options (#RTL4m)'do
+ channel.on(:attached) do
+ expect(channel.options.modes.map(&:to_sym)).to eq(%i[subscribe])
+ stop_reactor
+ end
+
+ channel.transition_state_machine(:attaching)
+ attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name, flags: 262144)
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
+ end
+
+ it 'set params as channel options params (#RTL4k1)' do
+ params = { param: :something }
+
+ channel.on(:attached) do
+ expect(channel.params).to eq(channel.options.params)
+ expect(channel.params).to eq(params)
+ stop_reactor
+ end
+
+ channel.transition_state_machine(:attaching)
+ attached_message = Ably::Models::ProtocolMessage.new(action: 11, channel: channel_name, params: params)
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, attached_message
+ end
+ end
+
it 'implicitly attaches the channel (#RTL7c)' do
expect(channel).to be_initialized
channel.subscribe { |message| }
channel.once(:attached) do
stop_reactor
@@ -366,10 +454,46 @@
end
disconnect_transport
end
end
end
+
+ describe 'clean attach (RTL4j)' do
+ context "when channel wasn't previously attached" do
+ it "doesn't send ATTACH_RESUME" do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.has_attach_resume_flag?).to eq(false)
+ stop_reactor
+ end
+
+ channel.attach
+ end
+ end
+
+ context "when channel was explicitly detached" do
+ it "doesn't send ATTACH_RESUME" do
+ channel.once(:detached) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.has_attach_resume_flag?).to eq(false)
+ stop_reactor
+ end
+
+ channel.attach
+ end
+
+ channel.once(:attached) do
+ channel.detach
+ end
+
+ channel.attach
+ end
+ end
+ end
end
describe '#detach' do
context 'when state is :attached' do
it 'it detaches from a channel (#RTL5d)' do
@@ -1934,20 +2058,38 @@
end
client.connection.transition_state_machine :suspended
end
end
- it 'transitions state automatically to :attaching once the connection is re-established (#RTN15c3)' do
- channel.attach do
- channel.on(:suspended) do
- client.connection.connect
- channel.once(:attached) do
- stop_reactor
+ describe 'reattaching (#RTN15c3)' do
+ it 'transitions state automatically to :attaching once the connection is re-established ' do
+ channel.attach do
+ channel.on(:suspended) do
+ client.connection.connect
+ channel.once(:attached) do
+ stop_reactor
+ end
end
+ client.connection.transition_state_machine :suspended
end
- client.connection.transition_state_machine :suspended
end
+
+ it 'sends ATTACH_RESUME flag when reattaching (RTL4j)' do
+ channel.attach do
+ channel.on(:suspended) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ expect(protocol_message.has_attach_resume_flag?).to eq(true)
+ stop_reactor
+ end
+
+ client.connection.connect
+ end
+ client.connection.transition_state_machine :suspended
+ end
+ end
end
end
context 'a :detached channel' do
it 'remains in the :detached state (#RTL3c)' do
@@ -2132,10 +2274,72 @@
expect(channel.presence).to be_a(Ably::Realtime::Presence)
stop_reactor
end
end
+ describe '#set_options (#RTL16a)' do
+ let(:modes) { %i[subscribe] }
+ let(:channel_options) do
+ { modes: modes }
+ end
+
+ def self.build_flags(flags)
+ flags.map { |flag| Ably::Models::ProtocolMessage::ATTACH_FLAGS_MAPPING[flag] }.reduce(:|)
+ end
+
+ shared_examples 'an update that sends ATTACH message' do |state, flags|
+ it 'sends an ATTACH message on options change' do
+ attach_sent = nil
+
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ if protocol_message.action == :attach && protocol_message.flags.nonzero?
+ attach_sent = true
+ expect(protocol_message.flags).to eq(flags)
+ end
+ end
+
+ channel.once(state) do
+ channel.options = channel_options
+ end
+
+ channel.on(:attached) do
+ client.connection.__incoming_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attached
+
+ expect(attach_sent).to eq(true)
+ stop_reactor
+ end
+ end
+
+ channel.attach
+ end
+ end
+
+ context 'when channel is attaching' do
+ it_behaves_like 'an update that sends ATTACH message', :attaching, build_flags(%i[subscribe])
+ end
+
+ context 'when channel is attaching' do
+ it_behaves_like 'an update that sends ATTACH message', :attached, build_flags(%i[resume subscribe])
+ end
+
+ context 'when channel is initialized' do
+ it "doesn't send ATTACH message" do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ raise "Unexpected message" if protocol_message.action == :attach
+ end
+
+ channel.options = channel_options
+ expect(channel.options.modes.map(&:to_sym)).to eq(modes)
+
+ EventMachine.next_tick do
+ stop_reactor
+ end
+ end
+ end
+ end
+
context 'channel state change' do
it 'emits a ChannelStateChange object' do
channel.on(:attached) do |channel_state_change|
expect(channel_state_change).to be_a(Ably::Models::ChannelStateChange)
stop_reactor
@@ -2373,41 +2577,63 @@
end
end
end
context 'and channel is attached' do
- it 'reattaches immediately (#RTL13a)' do
- channel.attach do
+ it 'reattaches immediately (#RTL13a) with ATTACH_RESUME flag(RTL4j)' do
+ resume_flag = false
+
+ channel.once(:attached) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ resume_flag = protocol_message.has_attach_resume_flag?
+ end
+
channel.once(:attaching) do |state_change|
expect(state_change.reason.code).to eql(50505)
channel.once(:attached) do
+ expect(resume_flag).to eq(true)
stop_reactor
end
end
detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
end
+
+ channel.attach
end
end
context 'and channel is suspended' do
- it 'reattaches immediately (#RTL13a)' do
- channel.attach do
- channel.once(:suspended) do
- channel.once(:attaching) do |state_change|
- expect(state_change.reason.code).to eql(50505)
- channel.once(:attached) do
- stop_reactor
- end
- end
+ it 'reattaches immediately (#RTL13a) with ATTACH_RESUME flag(RTL4j)' do
+ resume_flag = false
- detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
- client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
+ channel.once(:attached) do
+ channel.transition_state_machine! :suspended
+ end
+
+ channel.once(:suspended) do
+ client.connection.__outgoing_protocol_msgbus__.subscribe(:protocol_message) do |protocol_message|
+ next if protocol_message.action != :attach
+
+ resume_flag = protocol_message.has_attach_resume_flag?
end
- channel.transition_state_machine! :suspended
+ channel.once(:attaching) do |state_change|
+ expect(state_change.reason.code).to eql(50505)
+ channel.once(:attached) do
+ expect(resume_flag).to eq(true)
+ stop_reactor
+ end
+ end
+
+ detach_message = Ably::Models::ProtocolMessage.new(action: detached_action, channel: channel_name, error: { code: 50505 })
+ client.connection.__incoming_protocol_msgbus__.publish :protocol_message, detach_message
end
+
+ channel.attach
end
context 'when connection is no longer connected' do
it 'will not attempt to reattach (#RTL13c)' do
channel.attach do