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