diff --git a/lib/telegram/bot/updates_controller.rb b/lib/telegram/bot/updates_controller.rb index 2f34889..1355461 100644 --- a/lib/telegram/bot/updates_controller.rb +++ b/lib/telegram/bot/updates_controller.rb @@ -143,13 +143,13 @@ module Telegram # Accessor to `'chat'` field of payload. Can be overriden with `chat` option # for #initialize. def chat - @_chat || payload && payload['chat'] + @_chat ||= payload && payload['chat'] end # Accessor to `'from'` field of payload. Can be overriden with `from` option # for #initialize. def from - @_from || payload && payload['from'] + @_from ||= payload && payload['from'] end # Processes current update. @@ -164,7 +164,11 @@ module Telegram # it uses fallback with action same as payload type. # Returns array `[is_command?, action, args]`. def action_for_payload - send("action_for_#{payload_type}") || [false, payload_type, [payload]] + if payload_type + send("action_for_#{payload_type}") || [false, payload_type, [payload]] + else + [false, :unsupported_payload_type, []] + end end # If payload is a message with command, then returned action is an diff --git a/lib/telegram/bot/updates_controller/session.rb b/lib/telegram/bot/updates_controller/session.rb index 9bc0268..3324fb8 100644 --- a/lib/telegram/bot/updates_controller/session.rb +++ b/lib/telegram/bot/updates_controller/session.rb @@ -17,11 +17,15 @@ module Telegram protected def session - @_session ||= SessionHash.new(self.class.session_store, session_key) + @_session ||= begin + key = session_key + key ? SessionHash.new(self.class.session_store, key) : NullSessionHash.new + end end def session_key - "#{bot.username}:#{from ? "from:#{from['id']}" : "chat:#{chat['id']}"}" + subject = from || chat + "#{bot.username}:#{subject['id']}" if subject end # Rack::Session::Abstract::SessionHash is taken to provide lazy loading. @@ -59,6 +63,18 @@ module Telegram end end + class NullSessionHash < Session::SessionHash + def initialize + @data = {} + @loaded = true + @exists = true + end + + alias_method :destroy, :clear + alias_method :load!, :id + alias_method :commit, :id + end + module ConfigMethods delegate :session_store, to: :config diff --git a/lib/telegram/bot/updates_controller/testing.rb b/lib/telegram/bot/updates_controller/testing.rb index 974c6a9..8441aae 100644 --- a/lib/telegram/bot/updates_controller/testing.rb +++ b/lib/telegram/bot/updates_controller/testing.rb @@ -27,19 +27,7 @@ module Telegram # Stubs session. def session - @_session ||= Testing::SessionHash.new - end - - class SessionHash < Session::SessionHash - def initialize - @data = {} - @loaded = true - @exists = true - end - - alias_method :destroy, :clear - alias_method :load!, :id - alias_method :commit, :id + @_session ||= Session::NullSessionHash.new end end end diff --git a/spec/telegram/bot/updates_controller/session_spec.rb b/spec/telegram/bot/updates_controller/session_spec.rb index 6e95eca..83c61d2 100644 --- a/spec/telegram/bot/updates_controller/session_spec.rb +++ b/spec/telegram/bot/updates_controller/session_spec.rb @@ -26,6 +26,12 @@ RSpec.describe Telegram::Bot::UpdatesController::Session do def read session[:text] end + + def action_missing(*) + [:action_missing, session[:text]].tap do + session[:text] = 'test' + end + end end end @@ -39,5 +45,13 @@ RSpec.describe Telegram::Bot::UpdatesController::Session do expect(subject.call(bot, build_message('/read', id: 2))).to eq nil expect(subject.call(other_bot, build_message('/read', id: 1))).to eq nil end + + context 'payload is not supported' do + let(:payload_type) { '_unsupported_' } + it 'provides empty session' do + 2.times { expect(subject.call(bot)).to eq [:action_missing, nil] } + expect(subject.call(other_bot)).to eq [:action_missing, nil] + end + end end end diff --git a/spec/telegram/bot/updates_controller_spec.rb b/spec/telegram/bot/updates_controller_spec.rb index f1269ec..64d1f08 100644 --- a/spec/telegram/bot/updates_controller_spec.rb +++ b/spec/telegram/bot/updates_controller_spec.rb @@ -102,6 +102,11 @@ RSpec.describe Telegram::Bot::UpdatesController do it { should eq [false, payload_type, payload.values_at(:data)] } end + context 'when payload is not supported' do + let(:payload_type) { '_unsupported_' } + it { should eq [false, :unsupported_payload_type, []] } + end + context 'when payload is message' do let(:payload_type) { 'message' } let(:payload) { {'text' => text} }