зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-03 17:55:52 +03:00
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,3 +1,16 @@
|
||||
# Unreleased
|
||||
|
||||
- Make integration & controller specs consistent.
|
||||
__Breaking changes__ for controller specs:
|
||||
- Changed signature `dispatch(bot, update) => dispatch(update, bot)`.
|
||||
- `update` helper is symbolized by default.
|
||||
- `build_update(type, data)` is dropped in favor of `deep_stringify(type => data)`.
|
||||
- Provide support for integration testing of bots in poller mode and non-Rails apps.
|
||||
__Breaking changes__:
|
||||
- Requiring `telegram/bot/rspec/integration` is deprecated in favor of
|
||||
`telegram/bot/rspec/integration/rails`.
|
||||
- `:telegram_bot` rspec tag is replaced with `telegram_bot: :rails`.
|
||||
|
||||
# 0.13.1
|
||||
|
||||
- Extracted typed response mappings to telegram-bot-types gem.
|
||||
|
||||
92
README.md
92
README.md
@@ -192,8 +192,9 @@ end
|
||||
#### Reply helpers
|
||||
|
||||
There are helpers to respond for basic actions. They just set chat/message/query
|
||||
identifiers from update. See [`ReplyHelpers`](https://github.com/telegram-bot-rb/telegram-bot/blob/master/lib/telegram/bot/updates_controller/reply_helpers.rb) module for more information.
|
||||
Here are this methods signatures:
|
||||
identifiers from update. See
|
||||
[`ReplyHelpers`](https://github.com/telegram-bot-rb/telegram-bot/blob/master/lib/telegram/bot/updates_controller/reply_helpers.rb)
|
||||
module for more information. Here are this methods signatures:
|
||||
|
||||
```ruby
|
||||
def respond_with(type, params); end
|
||||
@@ -394,11 +395,11 @@ Telegram::Bot::UpdatesPoller.start(bot, controller_class)
|
||||
|
||||
### Testing
|
||||
|
||||
There is `Telegram::Bot::ClientStub` class to stub client for tests.
|
||||
Instead of performing API requests it stores them in `requests` hash.
|
||||
There is a `Telegram::Bot::ClientStub` class to stub client for tests.
|
||||
Instead of performing API requests it stores them in a `requests` hash.
|
||||
|
||||
To stub all possible clients use `Telegram::Bot::ClientStub.stub_all!` before
|
||||
initializing clients. Here is template for RSpec:
|
||||
initializing clients. Here is a template for RSpec:
|
||||
|
||||
```ruby
|
||||
# environments/test.rb
|
||||
@@ -416,47 +417,82 @@ RSpec.configure do |config|
|
||||
end
|
||||
```
|
||||
|
||||
There are integration and controller contexts for RSpec and some built-in matchers:
|
||||
RSpec contexts and helpers are included automatically for groups and examples with matching
|
||||
tags. In RSpec < 3.4 it's required to use `include_context` explicitly.
|
||||
See [list of available helpers](https://github.com/telegram-bot-rb/telegram-bot/tree/master/lib/telegram/bot/rspec)
|
||||
for details.
|
||||
|
||||
There are 3 types of integration tests:
|
||||
|
||||
- `:rails` - for testing bot in webhooks-mode in Rails application.
|
||||
It simulates webhook requests POSTing data to controller's endpoint.
|
||||
It works on the top of requests specs, so `rspec-rails` gem is required.
|
||||
- `:rack` - For testing bot in webhooks-mode in non-Rails application.
|
||||
It uses `rack-test` gem to POST requests to bot's endpoint.
|
||||
- `:poller` - Calls `.dispatch` directly on controller class.
|
||||
|
||||
Pick the appropriate one, then require `telegram/bot/rspec/integration/#{type}`
|
||||
and mark spec group with tag `telegram_bot: type`. See configuration options
|
||||
for each type in
|
||||
[telegram/bot/rspec/integration/](https://github.com/telegram-bot-rb/telegram-bot/tree/master/lib/telegram/bot/rspec/integration).
|
||||
|
||||
Here is an example test for a Rails app:
|
||||
|
||||
```ruby
|
||||
# spec/requests/telegram_webhooks_spec.rb
|
||||
require 'telegram/bot/rspec/integration'
|
||||
require 'telegram/bot/rspec/integration/rails'
|
||||
|
||||
RSpec.describe TelegramWebhooksController, :telegram_bot do
|
||||
# for old rspec add:
|
||||
# include_context 'telegram/bot/integration'
|
||||
RSpec.describe TelegramWebhooksController, telegram_bot: :rails do
|
||||
# for old RSpec:
|
||||
# include_context 'telegram/bot/integration/rails'
|
||||
|
||||
# Main method is #dispatch(update). Some helpers are:
|
||||
# dispatch_message(text, options = {})
|
||||
# dispatch_command(cmd, *args)
|
||||
|
||||
# Available matchers can be found in Telegram::Bot::RSpec::ClientMatchers.
|
||||
it 'shows usage of basic matchers'
|
||||
# The most basic one is #make_telegram_request(bot, endpoint, params_matcher)
|
||||
expect { dispatch_command(:start) }.
|
||||
to make_telegram_request(bot, :sendMessage, hash_including(text: 'msg text'))
|
||||
|
||||
# There are some shortcuts for dispatching basic updates and testing responses.
|
||||
expect { dispatch_message('Hi') }.to send_telegram_message(bot, /msg regexp/, some: :option)
|
||||
end
|
||||
|
||||
describe '#start' do
|
||||
subject { -> { dispatch_command :start } }
|
||||
# Using built in matcher for `respond_to`:
|
||||
it { should respond_with_message 'Hi there!' }
|
||||
end
|
||||
|
||||
# There is context for callback queries with related matchers.
|
||||
# There is context for callback queries with related matchers,
|
||||
# use :callback_query tag to include it.
|
||||
describe '#hey_callback_query', :callback_query do
|
||||
let(:data) { "hey:#{name}" }
|
||||
let(:name) { 'Joe' }
|
||||
it { should answer_callback_query('Hey Joe') }
|
||||
it { should edit_current_message :text, text: 'Done' }
|
||||
end
|
||||
end
|
||||
|
||||
# For controller specs use
|
||||
require 'telegram/bot/updates_controller/rspec_helpers'
|
||||
RSpec.describe TelegramWebhooksController, type: :telegram_bot_controller do
|
||||
# for old rspec add:
|
||||
# include_context 'telegram/bot/updates_controller'
|
||||
end
|
||||
|
||||
# Matchers are available for custom specs:
|
||||
include Telegram::Bot::RSpec::ClientMatchers
|
||||
|
||||
expect(&process_update).to send_telegram_message(bot, /msg regexp/, some: :option)
|
||||
expect(&process_update).
|
||||
to make_telegram_request(bot, :sendMessage, hash_including(text: 'msg text'))
|
||||
```
|
||||
|
||||
Place integration tests inside `spec/requests`
|
||||
when using RSpec's `infer_spec_type_from_file_location!`,
|
||||
or just add `type: :request` to `describe`.
|
||||
There is a context for testing bot controller in the way similar to Rails controller tests.
|
||||
It's supposed to be a low-level alternative for integration tests. Among the differences is
|
||||
that controller tests use a single controller instance for all dispatches in specific exaple,
|
||||
session is stubbed (does not use configured store engine), and update is not serialized
|
||||
so it also supports mocks. This can be useful for unit testing, but should not be used as
|
||||
the default way to test the bot.
|
||||
|
||||
```ruby
|
||||
require 'telegram/bot/updates_controller/rspec_helpers'
|
||||
RSpec.describe TelegramWebhooksController, type: :telegram_bot_controller do
|
||||
# for old RSpec:
|
||||
# include_context 'telegram/bot/updates_controller'
|
||||
|
||||
# Same helpers and matchers like dispatch_command, answer_callback_query are available here.
|
||||
end
|
||||
```
|
||||
|
||||
See sample app for more examples.
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ module Telegram
|
||||
|
||||
module_function
|
||||
|
||||
def deprecation_0_14
|
||||
def deprecation_0_15
|
||||
@deprecation ||= begin
|
||||
require 'active_support/deprecation'
|
||||
ActiveSupport::Deprecation.new('0.14', 'Telegram::Bot')
|
||||
ActiveSupport::Deprecation.new('0.15', 'Telegram::Bot')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
require 'active_support/concern'
|
||||
require 'active_support/core_ext/hash/indifferent_access'
|
||||
require 'active_support/json'
|
||||
require 'action_dispatch/http/mime_type'
|
||||
require 'action_dispatch/http/request'
|
||||
require 'action_dispatch'
|
||||
|
||||
module Telegram
|
||||
module Bot
|
||||
|
||||
@@ -24,33 +24,6 @@ module Telegram
|
||||
end
|
||||
end
|
||||
|
||||
# # Create routes for all Telegram.bots to use same controller:
|
||||
# telegram_webhooks TelegramController
|
||||
#
|
||||
# # Or pass custom bots usin any of supported config options:
|
||||
# telegram_webhooks TelegramController, [
|
||||
# bot,
|
||||
# {token: token, username: username},
|
||||
# other_bot_token,
|
||||
# ]
|
||||
def telegram_webhooks(controllers, bots = nil, **options)
|
||||
Bot.deprecation_0_14.deprecation_warning(:telegram_webhooks, <<-TXT.strip_heredoc)
|
||||
It brings unnecessary complexity and encourages writeng less readable code.
|
||||
Please use telegram_webhook method instead.
|
||||
It's signature `telegram_webhook(controller, bot = :default, **options)`.
|
||||
Multiple-bot environments now requires calling this method in a loop
|
||||
or using statement for each bot.
|
||||
TXT
|
||||
unless controllers.is_a?(Hash)
|
||||
bots = bots ? Array.wrap(bots) : Telegram.bots.values
|
||||
controllers = Hash[bots.map { |x| [x, controllers] }]
|
||||
end
|
||||
controllers.each do |bot, controller|
|
||||
controller, bot_options = controller if controller.is_a?(Array)
|
||||
telegram_webhook(controller, bot, options.merge(bot_options || {}))
|
||||
end
|
||||
end
|
||||
|
||||
# Define route which processes requests using given controller and bot.
|
||||
#
|
||||
# telegram_webhook TelegramController, bot
|
||||
|
||||
@@ -2,6 +2,15 @@ module Telegram
|
||||
module Bot
|
||||
module RSpec
|
||||
autoload :ClientMatchers, 'telegram/bot/rspec/client_matchers'
|
||||
|
||||
module_function
|
||||
|
||||
# Yelds a block if `include_context` is supported.
|
||||
def with_include_context
|
||||
::RSpec.configure do |config|
|
||||
yield(config) if config.respond_to?(:include_context)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
39
lib/telegram/bot/rspec/callback_query_helpers.rb
Обычный файл
39
lib/telegram/bot/rspec/callback_query_helpers.rb
Обычный файл
@@ -0,0 +1,39 @@
|
||||
require 'telegram/bot/rspec'
|
||||
require 'telegram/bot/rspec/message_helpers'
|
||||
|
||||
# Shared helpers for testing callback query updates.
|
||||
RSpec.shared_context 'telegram/bot/callback_query' do
|
||||
include_context 'telegram/bot/message_helpers'
|
||||
|
||||
subject { -> { dispatch callback_query: payload } }
|
||||
let(:payload) { {id: callback_query_id, from: from, message: message, data: data} }
|
||||
let(:callback_query_id) { 11 }
|
||||
let(:message_id) { 22 }
|
||||
let(:message) { {message_id: message_id, chat: chat, text: 'message text'} }
|
||||
let(:data) { raise '`let(:data) { "callback query data here" }` is required' }
|
||||
|
||||
# Matcher to check that origin message got edited.
|
||||
def edit_current_message(type, options = {})
|
||||
description = 'edit current message'
|
||||
options = options.merge(
|
||||
message_id: message[:message_id],
|
||||
chat_id: chat_id,
|
||||
)
|
||||
Telegram::Bot::RSpec::ClientMatchers::MakeTelegramRequest.new(
|
||||
bot, :"editMessage#{type.to_s.camelize}", description: description
|
||||
).with(hash_including(options))
|
||||
end
|
||||
|
||||
# Matcher to check that callback query is answered.
|
||||
def answer_callback_query(text = Regexp.new(''), options = {})
|
||||
description = "answer callback query with #{text.inspect}"
|
||||
text = a_string_matching(text) if text.is_a?(Regexp)
|
||||
options = options.merge(
|
||||
callback_query_id: payload[:id],
|
||||
text: text,
|
||||
)
|
||||
Telegram::Bot::RSpec::ClientMatchers::MakeTelegramRequest.new(
|
||||
bot, :answerCallbackQuery, description: description
|
||||
).with(hash_including(options))
|
||||
end
|
||||
end
|
||||
@@ -1,85 +1,10 @@
|
||||
RSpec.shared_context 'telegram/bot/integration' do
|
||||
let(:bot) { Telegram.bot }
|
||||
let(:default_message_options) { {from: from, chat: chat} }
|
||||
let(:from) { {id: from_id} }
|
||||
let(:from_id) { 123 }
|
||||
let(:chat) { {id: chat_id} }
|
||||
let(:chat_id) { 456 }
|
||||
let(:controller_path) do
|
||||
route_name = Telegram::Bot::RoutesHelper.route_name_for_bot(bot)
|
||||
Rails.application.routes.url_helpers.public_send("#{route_name}_path")
|
||||
end
|
||||
let(:request_headers) do
|
||||
{
|
||||
'ACCEPT' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
}
|
||||
end
|
||||
let(:clear_session?) { described_class.respond_to?(:session_store) }
|
||||
before { described_class.session_store.try!(:clear) if clear_session? }
|
||||
require 'telegram/bot'
|
||||
Telegram::Bot.deprecation_0_15.warn(
|
||||
"`require 'telegram/bot/rspec/integration'` is deprecated in favor of " \
|
||||
"`require 'telegram/bot/rspec/integration/rails'`"
|
||||
)
|
||||
require 'telegram/bot/rspec/integration/rails'
|
||||
|
||||
include Telegram::Bot::RSpec::ClientMatchers
|
||||
|
||||
def dispatch(update)
|
||||
if ActionPack::VERSION::MAJOR >= 5
|
||||
post(controller_path, params: update.to_json, headers: request_headers)
|
||||
else
|
||||
post(controller_path, update.to_json, request_headers)
|
||||
end
|
||||
end
|
||||
|
||||
def dispatch_message(text, options = {})
|
||||
dispatch message: default_message_options.merge(options).merge(text: text)
|
||||
end
|
||||
|
||||
def dispatch_command(*args)
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
dispatch_message("/#{args.join ' '}", options)
|
||||
end
|
||||
|
||||
# Matcher to check response. Make sure to define `let(:chat_id)`.
|
||||
def respond_with_message(expected = Regexp.new(''))
|
||||
raise 'Define chat_id to use respond_with_message' unless defined?(chat_id)
|
||||
send_telegram_message(bot, expected, chat_id: chat_id)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.shared_context 'telegram/bot/callback_query', callback_query: true do
|
||||
include_context 'telegram/bot/integration'
|
||||
|
||||
subject { -> { dispatch callback_query: payload } }
|
||||
let(:payload) { {id: 11, from: from, message: message, data: data} }
|
||||
let(:message) { {message_id: 22, chat: chat, text: 'message text'} }
|
||||
|
||||
# Matcher to check that origin message got edited.
|
||||
def edit_current_message(type, options = {})
|
||||
description = 'edit current message'
|
||||
options = options.merge(
|
||||
message_id: message[:message_id],
|
||||
chat_id: chat_id,
|
||||
)
|
||||
Telegram::Bot::RSpec::ClientMatchers::MakeTelegramRequest.new(
|
||||
bot, :"editMessage#{type.to_s.camelize}", description: description
|
||||
).with(hash_including(options))
|
||||
end
|
||||
|
||||
# Matcher to check that callback query is answered.
|
||||
def answer_callback_query(text = Regexp.new(''), options = {})
|
||||
description = "answer callback query with #{text.inspect}"
|
||||
text = a_string_matching(text) if text.is_a?(Regexp)
|
||||
options = options.merge(
|
||||
callback_query_id: payload[:id],
|
||||
text: text,
|
||||
)
|
||||
Telegram::Bot::RSpec::ClientMatchers::MakeTelegramRequest.new(
|
||||
bot, :answerCallbackQuery, description: description
|
||||
).with(hash_including(options))
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
if config.respond_to?(:include_context)
|
||||
config.include_context 'telegram/bot/integration', :telegram_bot
|
||||
config.include_context 'telegram/bot/callback_query', :telegram_bot, :callback_query
|
||||
end
|
||||
Telegram::Bot::RSpec.with_include_context do |config|
|
||||
config.include_context 'telegram/bot/integration/rails', telegram_bot: true
|
||||
end
|
||||
|
||||
14
lib/telegram/bot/rspec/integration/poller.rb
Обычный файл
14
lib/telegram/bot/rspec/integration/poller.rb
Обычный файл
@@ -0,0 +1,14 @@
|
||||
require 'telegram/bot/rspec/integration/shared'
|
||||
|
||||
RSpec.shared_context 'telegram/bot/integration/poller' do
|
||||
include_context 'telegram/bot/integration/shared'
|
||||
let(:controller_class) { described_class }
|
||||
|
||||
def dispatch(update)
|
||||
controller_class.dispatch(bot, update.as_json)
|
||||
end
|
||||
end
|
||||
|
||||
Telegram::Bot::RSpec.with_include_context do |config|
|
||||
config.include_context 'telegram/bot/integration/poller', telegram_bot: :poller
|
||||
end
|
||||
24
lib/telegram/bot/rspec/integration/rack.rb
Обычный файл
24
lib/telegram/bot/rspec/integration/rack.rb
Обычный файл
@@ -0,0 +1,24 @@
|
||||
require 'telegram/bot/rspec/integration/shared'
|
||||
require 'rack/test'
|
||||
|
||||
RSpec.shared_context 'telegram/bot/integration/rack' do
|
||||
include_context 'telegram/bot/integration/shared'
|
||||
include Rack::Test::Methods
|
||||
|
||||
let(:request_path) { raise '`let(:request_path) { path to bot }` is required' }
|
||||
let(:app) { raise '`let(:app) { your rack app here }` is required' }
|
||||
let(:request_headers) do
|
||||
{
|
||||
'ACCEPT' => 'application/json',
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
}
|
||||
end
|
||||
|
||||
def dispatch(update)
|
||||
post request_path, update.to_json, request_headers
|
||||
end
|
||||
end
|
||||
|
||||
Telegram::Bot::RSpec.with_include_context do |config|
|
||||
config.include_context 'telegram/bot/integration/rack', telegram_bot: :rack
|
||||
end
|
||||
28
lib/telegram/bot/rspec/integration/rails.rb
Обычный файл
28
lib/telegram/bot/rspec/integration/rails.rb
Обычный файл
@@ -0,0 +1,28 @@
|
||||
require 'telegram/bot/rspec/integration/shared'
|
||||
|
||||
RSpec.shared_context 'telegram/bot/integration/rails', type: :request do
|
||||
include_context 'telegram/bot/integration/shared'
|
||||
|
||||
let(:controller_path) do
|
||||
route_name = Telegram::Bot::RoutesHelper.route_name_for_bot(bot)
|
||||
Rails.application.routes.url_helpers.public_send("#{route_name}_path")
|
||||
end
|
||||
let(:request_headers) do
|
||||
{
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
}
|
||||
end
|
||||
|
||||
def dispatch(update)
|
||||
if ActionPack::VERSION::MAJOR >= 5
|
||||
post(controller_path, params: update.to_json, headers: request_headers)
|
||||
else
|
||||
post(controller_path, update.to_json, request_headers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Telegram::Bot::RSpec.with_include_context do |config|
|
||||
config.include_context 'telegram/bot/integration/rails', telegram_bot: :rails
|
||||
end
|
||||
14
lib/telegram/bot/rspec/integration/shared.rb
Обычный файл
14
lib/telegram/bot/rspec/integration/shared.rb
Обычный файл
@@ -0,0 +1,14 @@
|
||||
require 'active_support/json'
|
||||
require 'telegram/bot'
|
||||
require 'telegram/bot/rspec/message_helpers'
|
||||
require 'telegram/bot/rspec/callback_query_helpers'
|
||||
|
||||
RSpec.shared_context 'telegram/bot/integration/shared' do
|
||||
include Telegram::Bot::RSpec::ClientMatchers
|
||||
include_context 'telegram/bot/message_helpers'
|
||||
include_context 'telegram/bot/callback_query', :callback_query
|
||||
|
||||
let(:bot) { Telegram.bot }
|
||||
let(:clear_session?) { described_class.respond_to?(:session_store) }
|
||||
before { described_class.session_store.try!(:clear) if clear_session? }
|
||||
end
|
||||
26
lib/telegram/bot/rspec/message_helpers.rb
Обычный файл
26
lib/telegram/bot/rspec/message_helpers.rb
Обычный файл
@@ -0,0 +1,26 @@
|
||||
# Shared helpers for testing message updates.
|
||||
RSpec.shared_context 'telegram/bot/message_helpers' do
|
||||
let(:default_message_options) { {from: from, chat: chat} }
|
||||
let(:from) { {id: from_id} }
|
||||
let(:from_id) { 123 }
|
||||
let(:chat) { {id: chat_id} }
|
||||
let(:chat_id) { 456 }
|
||||
|
||||
# Shortcut for dispatching messages with default params.
|
||||
def dispatch_message(text, options = {})
|
||||
dispatch message: default_message_options.merge(options).merge(text: text)
|
||||
end
|
||||
|
||||
# Dispatch command message.
|
||||
def dispatch_command(cmd, *args)
|
||||
options = args.last.is_a?(Hash) ? args.pop : {}
|
||||
args.unshift("/#{cmd}")
|
||||
dispatch_message(args.join(' '), options)
|
||||
end
|
||||
|
||||
# Matcher to check response. Make sure to define `let(:chat_id)`.
|
||||
def respond_with_message(expected = Regexp.new(''))
|
||||
raise 'Define chat_id to use respond_with_message' unless defined?(chat_id)
|
||||
send_telegram_message(bot, expected, chat_id: chat_id)
|
||||
end
|
||||
end
|
||||
@@ -1,37 +1,32 @@
|
||||
require 'telegram/bot/updates_controller/testing'
|
||||
require 'telegram/bot/rspec/message_helpers'
|
||||
require 'telegram/bot/rspec/callback_query_helpers'
|
||||
|
||||
RSpec.shared_context 'telegram/bot/updates_controller' do
|
||||
include Telegram::Bot::RSpec::ClientMatchers
|
||||
include_context 'telegram/bot/message_helpers'
|
||||
include_context 'telegram/bot/callback_query', :callback_query
|
||||
|
||||
let(:controller_class) { described_class }
|
||||
let(:controller) do
|
||||
controller_class.new(bot, update).tap do |x|
|
||||
controller_class.new(*controller_args).tap do |x|
|
||||
x.extend Telegram::Bot::UpdatesController::Testing
|
||||
end
|
||||
end
|
||||
let(:update) { build_update(payload_type, payload) }
|
||||
let(:controller_args) { [bot, deep_stringify(update)] }
|
||||
let(:update) { {payload_type => payload} }
|
||||
let(:payload_type) { :some_type }
|
||||
let(:payload) { double(:payload) }
|
||||
let(:bot) { Telegram::Bot::ClientStub.new(bot_name) }
|
||||
let(:bot_name) { 'bot' }
|
||||
let(:session) { controller.send(:session) }
|
||||
let(:from_id) { 123 }
|
||||
let(:chat_id) { 456 }
|
||||
let(:default_message_options) { {from: {id: from_id}, chat: {id: chat_id}} }
|
||||
|
||||
include Telegram::Bot::RSpec::ClientMatchers
|
||||
|
||||
def dispatch(bot = self.bot, update = self.update)
|
||||
controller.dispatch_again(bot, update)
|
||||
end
|
||||
|
||||
def dispatch_message(text, options = {})
|
||||
update = build_update :message, default_message_options.merge(options).merge(text: text)
|
||||
dispatch bot, update
|
||||
end
|
||||
|
||||
def build_update(type, content)
|
||||
deep_stringify type => content
|
||||
# Process update.
|
||||
def dispatch(update = self.update, bot = self.bot)
|
||||
controller.dispatch_again(bot, deep_stringify(update))
|
||||
end
|
||||
|
||||
# Same as `.as_json` but mocks-friendly.
|
||||
def deep_stringify(input)
|
||||
case input
|
||||
when Array then input.map(&method(__callee__))
|
||||
@@ -39,15 +34,8 @@ RSpec.shared_context 'telegram/bot/updates_controller' do
|
||||
else input
|
||||
end
|
||||
end
|
||||
|
||||
# Matcher to check response. Make sure to define `let(:chat_id)`.
|
||||
def respond_with_message(expected)
|
||||
send_telegram_message(bot, expected, chat_id: chat_id)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
if config.respond_to?(:include_context)
|
||||
config.include_context 'telegram/bot/updates_controller', type: :telegram_bot_controller
|
||||
end
|
||||
Telegram::Bot::RSpec.with_include_context do |config|
|
||||
config.include_context 'telegram/bot/updates_controller', type: :telegram_bot_controller
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'integration_helper'
|
||||
|
||||
RSpec.describe DefaultBotController, :telegram_bot, type: :request do
|
||||
RSpec.describe DefaultBotController, telegram_bot: :rails do
|
||||
describe '#start' do
|
||||
subject { -> { dispatch_command :start } }
|
||||
it { should respond_with_message 'from default' }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'integration_helper'
|
||||
|
||||
RSpec.describe NamedBotController, :telegram_bot, type: :request do
|
||||
RSpec.describe NamedBotController, telegram_bot: :rails do
|
||||
let(:bot) { Telegram.bots[:named] }
|
||||
describe '#start' do
|
||||
subject { -> { dispatch_command :start } }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'integration_helper'
|
||||
|
||||
RSpec.describe OtherBotController, :telegram_bot, type: :request do
|
||||
RSpec.describe OtherBotController, telegram_bot: :rails do
|
||||
let(:bot) { Telegram.bots[:other] }
|
||||
describe '#start' do
|
||||
subject { -> { dispatch_command :start } }
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
require 'telegram/bot/rspec/integration'
|
||||
require 'telegram/bot/rspec/integration/rails'
|
||||
require 'action_controller'
|
||||
require 'action_dispatch'
|
||||
require 'action_dispatch/testing/integration'
|
||||
|
||||
require 'rails'
|
||||
require 'telegram/bot/railtie'
|
||||
|
||||
@@ -32,6 +32,14 @@ RSpec.configure do |config|
|
||||
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
||||
end
|
||||
|
||||
# This config option will be enabled by default on RSpec 4,
|
||||
# but for reasons of backwards compatibility, you have to
|
||||
# set it on RSpec 3.
|
||||
#
|
||||
# It causes the host group and examples to inherit metadata
|
||||
# from the shared context.
|
||||
config.shared_context_metadata_behavior = :apply_to_host_groups
|
||||
|
||||
config.mock_with :rspec do |mocks|
|
||||
# Prevents you from mocking or stubbing a method that does not exist on
|
||||
# a real object. This is generally recommended, and will default to
|
||||
|
||||
24
spec/support/examples/integration.rb
Обычный файл
24
spec/support/examples/integration.rb
Обычный файл
@@ -0,0 +1,24 @@
|
||||
RSpec.shared_examples 'shared integration examples' do
|
||||
let(:bot) { Telegram::Bot::ClientStub.new('token') }
|
||||
let(:controller_class) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
def start(data = nil, *)
|
||||
respond_with :message, text: "Hi #{data}"
|
||||
end
|
||||
|
||||
def callback_query(data, *)
|
||||
answer_callback_query "pong: #{data}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#start' do
|
||||
subject { -> { dispatch_command(:start, :test_data) } }
|
||||
it { should respond_with_message('Hi test_data') }
|
||||
end
|
||||
|
||||
describe '#callback_query', :callback_query do
|
||||
let(:data) { :test_data }
|
||||
it { should answer_callback_query "pong: #{data}" }
|
||||
end
|
||||
end
|
||||
@@ -7,7 +7,6 @@ RSpec.describe Telegram::Bot::Middleware do
|
||||
|
||||
describe '#call' do
|
||||
subject { instance.call(env) }
|
||||
let(:env) { {'action_dispatch.request.request_parameters' => json_body} }
|
||||
let(:update) { {'message' => {'id' => 1}} }
|
||||
let(:env) do
|
||||
Rack::MockRequest.env_for('/',
|
||||
@@ -21,7 +20,6 @@ RSpec.describe Telegram::Bot::Middleware do
|
||||
if ActionPack::VERSION::MAJOR < 5
|
||||
# Before Rails 5, params are parsed in middleware.
|
||||
# In Rails 5, they are parsed in Request#request_parameters.
|
||||
require 'action_dispatch/middleware/params_parser'
|
||||
let(:instance) { ActionDispatch::ParamsParser.new(super()) }
|
||||
end
|
||||
|
||||
|
||||
@@ -95,108 +95,4 @@ RSpec.describe Telegram::Bot::RoutesHelper do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#telegram_webhooks' do
|
||||
subject { mapper.telegram_webhooks(*input) }
|
||||
let(:mapper) { double(:mapper).tap { |x| x.extend described_class } }
|
||||
let(:bots) { {default: bot, other: other_bot} }
|
||||
let(:controller) { double(:controller, name: :controller) }
|
||||
let(:other_controller) { double(:other_controller, name: :other_controller) }
|
||||
before { allow(Telegram).to receive(:bots) { bots } }
|
||||
around { |ex| Telegram::Bot.deprecation_0_14.silence { ex.run } }
|
||||
|
||||
def assert_routes(*expected) # rubocop:disable AbcSize
|
||||
expected.each do |(bot, controller, route_name, options)|
|
||||
expected_path = options.delete(:path) || "telegram/#{bot.token}"
|
||||
expect(mapper).to receive(:post) do |path, params|
|
||||
expect(path).to eq expected_path
|
||||
middleware = params[:to]
|
||||
expect(middleware.controller).to eq(controller)
|
||||
expect(middleware.bot.token).to eq(bot.token)
|
||||
expect(middleware.bot.username).to eq(bot.username)
|
||||
expect(params[:as]).to eq route_name
|
||||
expect(params).to include(options) if options
|
||||
end
|
||||
end
|
||||
subject
|
||||
end
|
||||
|
||||
context 'when called with controller' do
|
||||
let(:input) { [controller, option: :val] }
|
||||
|
||||
it 'creates routes for every bot and this controller' do
|
||||
assert_routes [bot, controller, 'default_telegram_webhook', option: :val],
|
||||
[other_bot, controller, 'other_telegram_webhook', option: :val]
|
||||
end
|
||||
|
||||
context 'and bot does not have configured token' do
|
||||
let(:bot) { create_bot(nil) }
|
||||
it 'creates routes for every bot and this controller' do
|
||||
assert_routes [bot, controller, 'default_telegram_webhook', option: :val],
|
||||
[other_bot, controller, 'other_telegram_webhook', option: :val]
|
||||
end
|
||||
end
|
||||
|
||||
context 'and bot has colon in token' do
|
||||
let(:bot) { create_bot('some:token') }
|
||||
it 'replaces colon with underscore' do
|
||||
assert_routes [
|
||||
bot,
|
||||
controller,
|
||||
'default_telegram_webhook',
|
||||
option: :val,
|
||||
path: 'telegram/some_token',
|
||||
], [other_bot, controller, 'other_telegram_webhook', option: :val]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when called with hash' do
|
||||
let(:input) do
|
||||
[
|
||||
{
|
||||
bot => controller,
|
||||
'custom_token' => [other_controller, as: :custom_route, option: :other_val],
|
||||
other: controller,
|
||||
},
|
||||
option: :val,
|
||||
]
|
||||
end
|
||||
|
||||
it 'creates routes for every bot and its controller' do
|
||||
assert_routes [bot, controller, 'default_telegram_webhook', option: :val],
|
||||
[
|
||||
create_bot('custom_token'),
|
||||
other_controller,
|
||||
:custom_route,
|
||||
option: :other_val,
|
||||
],
|
||||
[Telegram.bots[:other], controller, 'other_telegram_webhook', option: :val]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when called with controller and smth castable to bot' do
|
||||
let(:input) do
|
||||
[
|
||||
controller,
|
||||
['custom_token', token: bot.token, username: 'new_name'],
|
||||
option: :val,
|
||||
]
|
||||
end
|
||||
|
||||
it 'creates routes for every created bot and controller' do
|
||||
assert_routes [
|
||||
create_bot('custom_token'),
|
||||
controller,
|
||||
'telegram_webhook',
|
||||
option: :val,
|
||||
], [
|
||||
create_bot(bot.token, 'new_name'),
|
||||
controller,
|
||||
'telegram_webhook',
|
||||
option: :val,
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
42
spec/telegram/bot/rspec/callback_query_helpers_spec.rb
Обычный файл
42
spec/telegram/bot/rspec/callback_query_helpers_spec.rb
Обычный файл
@@ -0,0 +1,42 @@
|
||||
require 'telegram/bot/rspec/integration/poller'
|
||||
|
||||
RSpec.describe 'Integration spec helpers', telegram_bot: :poller do
|
||||
let(:bot) { Telegram::Bot::ClientStub.new('token') }
|
||||
let(:controller_class) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
include Telegram::Bot::UpdatesController::CallbackQueryContext
|
||||
|
||||
def callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}"
|
||||
end
|
||||
|
||||
def context_callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}", extra: :param
|
||||
end
|
||||
|
||||
def answer_and_edit_callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}"
|
||||
edit_message :text, text: 'edited-text', extra: :param
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#callback_query', :callback_query do
|
||||
let(:data) { 'unknown:command' }
|
||||
it { should answer_callback_query("data: #{data}") }
|
||||
end
|
||||
|
||||
describe '#context_callback_query', :callback_query do
|
||||
let(:data) { 'context:test:payload' }
|
||||
it { should answer_callback_query('data: test:payload', extra: :param) }
|
||||
it { should_not edit_current_message(:text) }
|
||||
end
|
||||
|
||||
describe '#answer_and_edit_callback_query', :callback_query do
|
||||
let(:data) { 'answer_and_edit:test:payload' }
|
||||
it do
|
||||
should answer_callback_query(/test:payload/).
|
||||
and edit_current_message(:text, text: /edited/, extra: :param)
|
||||
end
|
||||
end
|
||||
end
|
||||
5
spec/telegram/bot/rspec/integration/poller_spec.rb
Обычный файл
5
spec/telegram/bot/rspec/integration/poller_spec.rb
Обычный файл
@@ -0,0 +1,5 @@
|
||||
require 'telegram/bot/rspec/integration/poller'
|
||||
|
||||
RSpec.describe 'Poller integration spec', telegram_bot: :poller do
|
||||
include_examples 'shared integration examples'
|
||||
end
|
||||
20
spec/telegram/bot/rspec/integration/rack_spec.rb
Обычный файл
20
spec/telegram/bot/rspec/integration/rack_spec.rb
Обычный файл
@@ -0,0 +1,20 @@
|
||||
require 'telegram/bot/rspec/integration/rack'
|
||||
|
||||
RSpec.describe 'Rack integration spec', telegram_bot: :rack do
|
||||
include_examples 'shared integration examples'
|
||||
let(:request_path) { '/bot' }
|
||||
let(:app) do
|
||||
path = request_path
|
||||
bot_app = Telegram::Bot::Middleware.new(bot, controller_class)
|
||||
app = Rack::Builder.new do
|
||||
map(path) { run bot_app }
|
||||
run ->(env) { raise "Route is not mapped: #{env['PATH_INFO']}" }
|
||||
end
|
||||
if ActionPack::VERSION::MAJOR >= 5
|
||||
app
|
||||
else
|
||||
require 'action_dispatch/middleware/params_parser'
|
||||
ActionDispatch::ParamsParser.new(app)
|
||||
end
|
||||
end
|
||||
end
|
||||
1
spec/telegram/bot/rspec/integration/rails_spec.rb
Обычный файл
1
spec/telegram/bot/rspec/integration/rails_spec.rb
Обычный файл
@@ -0,0 +1 @@
|
||||
# Tested in spec/integration
|
||||
@@ -1,112 +0,0 @@
|
||||
require 'telegram/bot/rspec/integration'
|
||||
require 'action_controller'
|
||||
require 'action_dispatch'
|
||||
require 'action_dispatch/testing/integration'
|
||||
|
||||
RSpec.describe 'Integrations helper', :telegram_bot do
|
||||
include ActionDispatch::Integration::Runner
|
||||
def reset_template_assertion
|
||||
end
|
||||
|
||||
let(:app) do
|
||||
app = Telegram::Bot::Middleware.new(bot, controller)
|
||||
if ActionPack::VERSION::MAJOR >= 5
|
||||
app
|
||||
else
|
||||
require 'action_dispatch/middleware/params_parser'
|
||||
ActionDispatch::ParamsParser.new(app)
|
||||
end
|
||||
end
|
||||
let(:bot) { Telegram::Bot::ClientStub.new('token') }
|
||||
let(:controller_path) { '/' }
|
||||
let(:controller) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
def start(*args)
|
||||
respond_with :message, text: "Start: #{args.inspect}, option: #{payload[:option]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_message_options' do
|
||||
subject { default_message_options }
|
||||
it { should eq from: {id: from_id}, chat: {id: chat_id} }
|
||||
end
|
||||
|
||||
describe '#dispatch' do
|
||||
subject { -> { dispatch message: {text: '/start', **default_message_options} } }
|
||||
it { should respond_with_message 'Start: [], option: ' }
|
||||
end
|
||||
|
||||
describe '#dispatch_message' do
|
||||
subject { -> { dispatch_message "/start #{args.join ' '}", options } }
|
||||
let(:args) { %w[asd qwe] }
|
||||
let(:options) { {} }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
|
||||
context 'with options' do
|
||||
let(:options) { {option: 1} }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: 1" }
|
||||
|
||||
context 'and chat_id is not set' do
|
||||
let(:options) { super().merge(chat: nil) }
|
||||
it { should raise_error(/chat is not present/) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#dispatch_command' do
|
||||
subject { -> { dispatch_command :start, *args } }
|
||||
let(:args) { [] }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
|
||||
context 'with args' do
|
||||
let(:args) { %w[asd qwe] }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
end
|
||||
|
||||
context 'with options' do
|
||||
let(:args) { ['asd', 'qwe', option: 1] }
|
||||
it { should respond_with_message "Start: #{args[0...-1].inspect}, option: 1" }
|
||||
end
|
||||
end
|
||||
|
||||
describe 'callback queries', :callback_query do
|
||||
let(:controller) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
include Telegram::Bot::UpdatesController::CallbackQueryContext
|
||||
|
||||
def callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}"
|
||||
end
|
||||
|
||||
def context_callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}", extra: :param
|
||||
end
|
||||
|
||||
def answer_and_edit_callback_query(data = nil, *)
|
||||
answer_callback_query "data: #{data}"
|
||||
edit_message :text, text: 'edited-text', extra: :param
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#callback_query' do
|
||||
let(:data) { 'unknown:command' }
|
||||
it { should answer_callback_query("data: #{data}") }
|
||||
end
|
||||
|
||||
describe '#context_callback_query' do
|
||||
let(:data) { 'context:test:payload' }
|
||||
it { should answer_callback_query('data: test:payload', extra: :param) }
|
||||
it { should_not edit_current_message(:text) }
|
||||
end
|
||||
|
||||
describe '#answer_and_edit_callback_query' do
|
||||
let(:data) { 'answer_and_edit:test:payload' }
|
||||
it do
|
||||
should answer_callback_query(/test:payload/).
|
||||
and edit_current_message(:text, text: /edited/, extra: :param)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
115
spec/telegram/bot/rspec/message_helpers_spec.rb
Обычный файл
115
spec/telegram/bot/rspec/message_helpers_spec.rb
Обычный файл
@@ -0,0 +1,115 @@
|
||||
require 'telegram/bot/rspec/integration/poller'
|
||||
|
||||
RSpec.describe 'Integration: message helpers', telegram_bot: :poller do
|
||||
describe '#default_message_options' do
|
||||
subject { default_message_options }
|
||||
it { should eq from: {id: from_id}, chat: {id: chat_id} }
|
||||
end
|
||||
|
||||
describe '#dispatch_message' do
|
||||
subject { -> { dispatch_message text, options } }
|
||||
let(:text) { '/start asd qwe' }
|
||||
let(:options) { {} }
|
||||
let(:result) { double(:result) }
|
||||
|
||||
it 'invokes dispatch' do
|
||||
expect(self).to receive(:dispatch).with(
|
||||
message: hash_including(default_message_options.merge(
|
||||
text: text,
|
||||
)),
|
||||
) { result }
|
||||
expect(subject.call).to eq result
|
||||
end
|
||||
|
||||
context 'with options' do
|
||||
let(:options) { {option: 1} }
|
||||
it 'invokes dispatch' do
|
||||
expect(self).to receive(:dispatch).with(
|
||||
message: hash_including(default_message_options.merge(
|
||||
text: text,
|
||||
).merge(options)),
|
||||
) { result }
|
||||
expect(subject.call).to eq result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#dispatch_command' do
|
||||
subject { -> { dispatch_command :start, *args } }
|
||||
let(:args) { [] }
|
||||
let(:result) { double(:result) }
|
||||
|
||||
it 'invokes dispatch' do
|
||||
expect(self).to receive(:dispatch).with(
|
||||
message: hash_including(default_message_options.merge(
|
||||
text: '/start',
|
||||
)),
|
||||
) { result }
|
||||
expect(subject.call).to eq result
|
||||
end
|
||||
|
||||
context 'with args & options' do
|
||||
let(:args) { [*params, options] }
|
||||
let(:params) { %w[qwe asd] }
|
||||
let(:options) { {option: 1} }
|
||||
it 'invokes dispatch' do
|
||||
expect(self).to receive(:dispatch).with(
|
||||
message: hash_including(default_message_options.merge(
|
||||
text: "/start #{params.join(' ')}",
|
||||
).merge(options)),
|
||||
) { result }
|
||||
expect(subject.call).to eq result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Old specs
|
||||
RSpec.describe 'Integration: message helpers', telegram_bot: :poller do
|
||||
let(:bot) { Telegram::Bot::ClientStub.new('token') }
|
||||
let(:controller_class) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
def start(*args)
|
||||
respond_with :message, text: "Start: #{args.inspect}, option: #{payload['option']}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_message_options' do
|
||||
subject { default_message_options }
|
||||
it { should eq from: {id: from_id}, chat: {id: chat_id} }
|
||||
end
|
||||
|
||||
describe '#dispatch_message' do
|
||||
subject { -> { dispatch_message "/start #{args.join ' '}", options } }
|
||||
let(:args) { %w[asd qwe] }
|
||||
let(:options) { {} }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
|
||||
context 'with options' do
|
||||
let(:options) { {option: 1} }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: 1" }
|
||||
|
||||
context 'and chat_id is not set' do
|
||||
let(:options) { super().merge(chat: nil) }
|
||||
it { should raise_error(/chat is not present/) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#dispatch_command' do
|
||||
subject { -> { dispatch_command :start, *args } }
|
||||
let(:args) { [] }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
|
||||
context 'with args' do
|
||||
let(:args) { %w[asd qwe] }
|
||||
it { should respond_with_message "Start: #{args.inspect}, option: " }
|
||||
end
|
||||
|
||||
context 'with options' do
|
||||
let(:args) { ['asd', 'qwe', option: 1] }
|
||||
it { should respond_with_message "Start: #{args[0...-1].inspect}, option: 1" }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -27,7 +27,7 @@ RSpec.describe Telegram::Bot::UpdatesController::CallbackQueryContext do
|
||||
describe '#dispatch' do
|
||||
subject { -> { dispatch } }
|
||||
let(:payload_type) { :callback_query }
|
||||
let(:payload) { {'data' => data} }
|
||||
let(:payload) { {data: data} }
|
||||
let(:data) { text }
|
||||
let(:text) { 'asd qwe zxc' }
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@ RSpec.describe Telegram::Bot::UpdatesController::Instrumentation do
|
||||
include_context 'telegram/bot/updates_controller'
|
||||
|
||||
subject { -> { dispatch } }
|
||||
let(:update) do
|
||||
build_update :message, default_message_options.merge(text: '/start')
|
||||
end
|
||||
let(:update) { {message: default_message_options.merge(text: '/start')} }
|
||||
|
||||
let(:controller_class) do
|
||||
Class.new(Telegram::Bot::UpdatesController) do
|
||||
@@ -36,11 +34,11 @@ RSpec.describe Telegram::Bot::UpdatesController::Instrumentation do
|
||||
|
||||
action = action_name(:start_processing)
|
||||
expect(events[action].size).to eq(1)
|
||||
expect(events[action][0].last).to include(update: update)
|
||||
expect(events[action][0].last).to include(update: deep_stringify(update))
|
||||
|
||||
action = action_name(:process_action)
|
||||
expect(events[action].size).to eq(1)
|
||||
expect(events[action][0].last).to include(update: update)
|
||||
expect(events[action][0].last).to include(update: deep_stringify(update))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
let(:respond_type) { :photo }
|
||||
let(:result) { double(:result) }
|
||||
let(:payload_type) { :message }
|
||||
let(:payload) { {message_id: double(:message_id)} }
|
||||
let(:chat) { {'id' => double(:chat_id)} }
|
||||
let(:payload) { {message_id: double(:message_id), chat: chat} }
|
||||
let(:chat) { {id: double(:chat_id)} }
|
||||
|
||||
shared_examples 'missing chat' do
|
||||
context 'when chat is missing' do
|
||||
@@ -19,9 +19,8 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
include_examples 'missing chat'
|
||||
|
||||
it 'sets chat_id & reply_to_message_id' do
|
||||
expect(controller).to receive(:chat) { chat }
|
||||
expect(bot).to receive("send_#{respond_type}").
|
||||
with(params.merge(chat_id: chat['id'])) { result }
|
||||
with(params.merge(chat_id: chat[:id])) { result }
|
||||
should eq result
|
||||
end
|
||||
end
|
||||
@@ -31,19 +30,18 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
include_examples 'missing chat'
|
||||
|
||||
it 'sets chat_id & reply_to_message_id' do
|
||||
expect(controller).to receive(:chat) { chat }
|
||||
expect(bot).to receive("send_#{respond_type}").with(params.merge(
|
||||
chat_id: chat['id'],
|
||||
chat_id: chat[:id],
|
||||
reply_to_message_id: payload[:message_id],
|
||||
)) { result }
|
||||
should eq result
|
||||
end
|
||||
|
||||
context 'when update is not set' do
|
||||
let(:update) { {chat: chat} }
|
||||
let(:controller_args) { [bot, chat: deep_stringify(chat)] }
|
||||
it 'sets chat_id' do
|
||||
expect(bot).to receive("send_#{respond_type}").
|
||||
with(params.merge(chat_id: chat['id'])) { result }
|
||||
with(params.merge(chat_id: chat[:id])) { result }
|
||||
should eq result
|
||||
end
|
||||
end
|
||||
@@ -70,7 +68,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
it 'sets chat_id & message_id' do
|
||||
expect(bot).to receive("edit_message_#{type}").with(params.merge(
|
||||
message_id: payload[:message][:message_id],
|
||||
chat_id: payload[:message][:chat]['id'],
|
||||
chat_id: payload[:message][:chat][:id],
|
||||
)) { result }
|
||||
should eq result
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ RSpec.describe Telegram::Bot::UpdatesController::Session do
|
||||
end
|
||||
|
||||
def build_message(text, from)
|
||||
{'message' => {'text' => text, 'from' => from.stringify_keys}}
|
||||
deep_stringify(message: {text: text, from: from})
|
||||
end
|
||||
|
||||
it 'stores session between requests' do
|
||||
|
||||
@@ -278,11 +278,13 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
instance_eval(&block)
|
||||
context 'when re-initialized' do
|
||||
let(:controller) do
|
||||
described_class.new(double(:other_bot), build_update(:message,
|
||||
initial_update = deep_stringify message: {
|
||||
text: 'original message',
|
||||
from: double(:original_from),
|
||||
chat: double(:original_chat),
|
||||
)).tap { |x| x.send(:initialize, bot, update) }
|
||||
}
|
||||
described_class.new(double(:other_bot), initial_update).
|
||||
tap { |x| x.send(:initialize, *controller_args) }
|
||||
end
|
||||
instance_eval(&block)
|
||||
end
|
||||
@@ -300,7 +302,7 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
||||
end
|
||||
|
||||
context 'when options hash is given' do
|
||||
let(:update) { {from: from, chat: chat} }
|
||||
let(:controller_args) { [bot, from: from, chat: chat] }
|
||||
with_reinitialize do
|
||||
its(:bot) { should eq bot }
|
||||
its(:update) { should eq nil }
|
||||
|
||||
Ссылка в новой задаче
Block a user