зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-04 10:15:50 +03:00
Testing: run multiple dispatches on same instance
Этот коммит содержится в:
@@ -242,7 +242,8 @@ end
|
|||||||
```
|
```
|
||||||
|
|
||||||
There are also some helpers for controller tests.
|
There are also some helpers for controller tests.
|
||||||
Check out `telegram/bot/updates_controller/rspec_helpers`.
|
Check out `telegram/bot/updates_controller/rspec_helpers` and
|
||||||
|
`telegram/bot/updates_controller/testing`.
|
||||||
|
|
||||||
### Deploying
|
### Deploying
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
|
require 'telegram/bot/updates_controller/testing'
|
||||||
|
|
||||||
RSpec.shared_context 'telegram/bot/updates_controller' do
|
RSpec.shared_context 'telegram/bot/updates_controller' do
|
||||||
let(:controller_class) { described_class }
|
let(:controller_class) { described_class }
|
||||||
let(:instance) { controller_class.new(bot, update) }
|
let(:controller) do
|
||||||
|
controller_class.new(bot, update).tap do |x|
|
||||||
|
x.extend Telegram::Bot::UpdatesController::Testing
|
||||||
|
end
|
||||||
|
end
|
||||||
let(:update) { {payload_type => payload} }
|
let(:update) { {payload_type => payload} }
|
||||||
let(:payload_type) { 'some_type' }
|
let(:payload_type) { 'some_type' }
|
||||||
let(:payload) { double(:payload) }
|
let(:payload) { double(:payload) }
|
||||||
let(:bot) { Telegram::Bot::ClientStub.new(bot_name) }
|
let(:bot) { Telegram::Bot::ClientStub.new(bot_name) }
|
||||||
let(:bot_name) { 'bot' }
|
let(:bot_name) { 'bot' }
|
||||||
let(:session) do
|
let(:session) { controller.send(:session) }
|
||||||
session = Telegram::Bot::UpdatesController::Session::TestSessionHash.new
|
|
||||||
allow_any_instance_of(controller_class).to receive(:session) { session }
|
def dispatch(bot = self.bot, update = self.update)
|
||||||
session
|
controller.dispatch_again(bot, update)
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_message(text, options = {})
|
def dispatch_message(text, options = {})
|
||||||
payload = build_payload :message, options.merge(text: text)
|
update = build_update :message, options.merge(text: text)
|
||||||
controller_class.dispatch bot, payload
|
dispatch bot, update
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_payload(type, content)
|
def build_update(type, content)
|
||||||
deep_stringify type => content
|
deep_stringify type => content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -59,18 +59,6 @@ module Telegram
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TestSessionHash < SessionHash
|
|
||||||
def initialize
|
|
||||||
@data = {}
|
|
||||||
@loaded = true
|
|
||||||
@exists = true
|
|
||||||
end
|
|
||||||
|
|
||||||
alias_method :destroy, :clear
|
|
||||||
alias_method :load!, :id
|
|
||||||
alias_method :commit, :id
|
|
||||||
end
|
|
||||||
|
|
||||||
module ConfigMethods
|
module ConfigMethods
|
||||||
delegate :session_store, to: :config
|
delegate :session_store, to: :config
|
||||||
|
|
||||||
|
|||||||
47
lib/telegram/bot/updates_controller/testing.rb
Обычный файл
47
lib/telegram/bot/updates_controller/testing.rb
Обычный файл
@@ -0,0 +1,47 @@
|
|||||||
|
module Telegram
|
||||||
|
module Bot
|
||||||
|
class UpdatesController
|
||||||
|
module Testing
|
||||||
|
IVARS_TO_KEEP = %i(@_session).freeze
|
||||||
|
|
||||||
|
# Perform multiple dispatches on same instance.
|
||||||
|
def dispatch_again(bot = nil, update = nil)
|
||||||
|
recycle!
|
||||||
|
initialize(bot, update)
|
||||||
|
dispatch
|
||||||
|
end
|
||||||
|
|
||||||
|
# Cleans controller between dispatches.
|
||||||
|
# Seems like there is nothing to clean between requests for now:
|
||||||
|
# everything will be rewriten with #initialize.
|
||||||
|
#
|
||||||
|
# With `full` set to `true` it'll clear all cached instance variables.
|
||||||
|
def recycle!(full = false)
|
||||||
|
return unless full
|
||||||
|
(instance_variables - IVARS_TO_KEEP).each do |ivar|
|
||||||
|
remove_instance_variable(ivar)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# 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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -4,7 +4,7 @@ module Telegram
|
|||||||
# Include this module to type cast update to Virtus model
|
# Include this module to type cast update to Virtus model
|
||||||
# using `telegram-bot-types` gem (install this gem first).
|
# using `telegram-bot-types` gem (install this gem first).
|
||||||
module TypedUpdate
|
module TypedUpdate
|
||||||
def initialize(bot, update)
|
def initialize(bot = nil, update = nil)
|
||||||
update = Types::Update.new(update) if update && !update.is_a?(Types::Update)
|
update = Types::Update.new(update) if update && !update.is_a?(Types::Update)
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|||||||
27
spec/telegram/bot/updates_controller/testing_spec.rb
Обычный файл
27
spec/telegram/bot/updates_controller/testing_spec.rb
Обычный файл
@@ -0,0 +1,27 @@
|
|||||||
|
RSpec.describe Telegram::Bot::UpdatesController::Testing do
|
||||||
|
include_context 'telegram/bot/updates_controller'
|
||||||
|
let(:controller_class) do
|
||||||
|
Class.new(Telegram::Bot::UpdatesController) do
|
||||||
|
attr_accessor :ivar
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#recycle!' do
|
||||||
|
subject { -> { controller.recycle!(full) } }
|
||||||
|
before do
|
||||||
|
controller.ivar = :ival
|
||||||
|
session[:key] = 'sval'
|
||||||
|
end
|
||||||
|
let(:full) {}
|
||||||
|
|
||||||
|
it { should_not change(controller, :ivar).from :ival }
|
||||||
|
it { should_not change { controller.send(:session)[:key] }.from 'sval' }
|
||||||
|
|
||||||
|
context 'when full is true' do
|
||||||
|
let(:full) { true }
|
||||||
|
it { should change(controller, :ivar).from(:ival).to nil }
|
||||||
|
it { should change { controller.instance_variable_defined?(:@ivar) }.to false }
|
||||||
|
it { should_not change { controller.send(:session)[:key] }.from 'sval' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -8,7 +8,7 @@ RSpec.describe Telegram::Bot::UpdatesController::TypedUpdate do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'when `update` is a virtus model' do
|
context 'when `update` is a virtus model' do
|
||||||
subject { instance }
|
subject { controller }
|
||||||
%w(
|
%w(
|
||||||
message
|
message
|
||||||
inline_query
|
inline_query
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#action_for_payload' do
|
describe '#action_for_payload' do
|
||||||
subject { instance.action_for_payload }
|
subject { controller.action_for_payload }
|
||||||
|
|
||||||
(described_class::PAYLOAD_TYPES - %w(message)).each do |type|
|
(described_class::PAYLOAD_TYPES - %w(message)).each do |type|
|
||||||
context "when payload is #{type}" do
|
context "when payload is #{type}" do
|
||||||
@@ -113,7 +113,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
context 'when `update` is a virtus model' do
|
context 'when `update` is a virtus model' do
|
||||||
subject { instance }
|
subject { controller }
|
||||||
let(:update) { Telegram::Bot::Types::Update.new(super()) }
|
let(:update) { Telegram::Bot::Types::Update.new(super()) }
|
||||||
%w(
|
%w(
|
||||||
message
|
message
|
||||||
@@ -131,7 +131,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#bot_username' do
|
describe '#bot_username' do
|
||||||
subject { instance.bot_username }
|
subject { controller.bot_username }
|
||||||
|
|
||||||
context 'when bot is not set' do
|
context 'when bot is not set' do
|
||||||
let(:bot) {}
|
let(:bot) {}
|
||||||
@@ -145,7 +145,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe '#process_action' do
|
describe '#process_action' do
|
||||||
subject { -> { instance.process_action(:action) } }
|
subject { -> { controller.process_action(:action) } }
|
||||||
|
|
||||||
context 'when callbacks are defined' do
|
context 'when callbacks are defined' do
|
||||||
let(:controller_class) do
|
let(:controller_class) do
|
||||||
@@ -165,8 +165,8 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it { should change(instance, :hooked).to true }
|
it { should change(controller, :hooked).to true }
|
||||||
it { should change(instance, :acted).to true }
|
it { should change(controller, :acted).to true }
|
||||||
|
|
||||||
context 'when callback returns false' do
|
context 'when callback returns false' do
|
||||||
before do
|
before do
|
||||||
@@ -178,8 +178,8 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { should change(instance, :hooked).to true }
|
it { should change(controller, :hooked).to true }
|
||||||
it { should_not change(instance, :acted).from nil }
|
it { should_not change(controller, :acted).from nil }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user