1
0
зеркало из https://github.com/glebtv/telegram-bot.git synced 2026-09-03 17:55:52 +03:00
Этот коммит содержится в:
Max Melentiev
2016-02-22 22:53:59 +06:00
Коммит 37a63f7b23
29 изменённых файлов: 1333 добавлений и 0 удалений

81
spec/spec_helper.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,81 @@
require 'pathname'
require 'pry'
require 'rspec/its'
if ENV['CI']
require 'coveralls'
Coveralls.wear!
elsif ENV.key?('COV')
require 'simplecov'
SimpleCov.start
end
GEM_ROOT = Pathname.new File.expand_path('../..', __FILE__)
$LOAD_PATH.unshift GEM_ROOT.join('lib')
require 'telegram/bot'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
# This option will default to `true` in RSpec 4. It makes the `description`
# and `failure_message` of custom matchers include text for helper methods
# defined using `chain`, e.g.:
# be_bigger_than(2).and_smaller_than(4).description
# # => "be bigger than 2 and smaller than 4"
# ...rather than:
# # => "be bigger than 2"
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
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
# `true` in RSpec 4.
mocks.verify_partial_doubles = true
end
# These two settings work together to allow you to limit a spec run
# to individual examples or groups you care about by tagging them with
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
# get run.
#
# Use `FULL=true bin/rspec` to disable filters.
config.filter_run :focus
config.run_all_when_everything_filtered = true
# Limits the available syntax to the non-monkey patched syntax that is recommended.
# For more details, see:
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
# - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
config.disable_monkey_patching!
# Many RSpec users commonly either run the entire suite or an individual
# file, and it's useful to allow more verbose output when running an
# individual spec file.
config.default_formatter = 'doc' if config.files_to_run.one?
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
# config.profile_examples = 3
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
# Make it more convenient.
require 'bigdecimal'
BigDecimal.class_eval do
alias_method :inspect_orig, :inspect
alias_method :inspect, :to_s
end
end

18
spec/telegram/bot/middleware_spec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,18 @@
RSpec.describe Telegram::Bot::Middleware do
let(:instance) { described_class.new bot, controller }
let(:bot) { double(:bot) }
let(:controller) { double(:controller, dispatch: :dispatch_result) }
describe '#call' do
subject { instance.call(env) }
let(:env) { {'action_dispatch.request.request_parameters' => json_body} }
let(:json_body) { double(:json_body) }
it 'calls dispatch on controller' do
expect(controller).to receive(:dispatch).with(bot, json_body)
subject
end
it { should eq [200, {}, ''] }
end
end

117
spec/telegram/bot/routes_helper_spec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,117 @@
require 'telegram/bot/routes_helper'
RSpec.describe Telegram::Bot::RoutesHelper do
let(:bot) { Telegram::Bot.new('bot_token') }
let(:other_bot) { Telegram::Bot.new('other_token') }
let(:bots) { {default: bot, other: other_bot} }
describe '.route_name_for_bot' do
subject { described_class.route_name_for_bot(input) }
before { expect(Telegram).to receive(:bots) { bots } }
context 'when there is only one bot' do
let(:bots) { {default: bot} }
context 'for existing bot' do
let(:input) { bot }
it { should eq 'telegram_webhook' }
end
context 'for non-existing bot' do
let(:input) { other_bot }
it { should eq 'telegram_webhook' }
end
end
context 'when there are multiple bots' do
context 'for existing bot' do
let(:input) { bot }
it { should eq 'default_telegram_webhook' }
end
context 'for non-existing bot' do
let(:input) { double(:missing_bot) }
it { should eq 'telegram_webhook' }
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 } }
def assert_routes(*expected) # rubocop:disable AbcSize
expected.each do |(bot, controller, route_name, options)|
expect(mapper).to receive(:post) do |path, params|
expect(path).to eq "telegram/#{bot.token}"
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
end
context 'when called with hash' do
let(:input) do
[
{
bot => controller,
'custom_token' => [other_controller, as: :custom_route, option: :other_val],
},
option: :val,
]
end
it 'creates routes for every bot and its controller' do
assert_routes [bot, controller, 'default_telegram_webhook', option: :val],
[
Telegram::Bot.new('custom_token'),
other_controller,
:custom_route,
option: :other_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 [
Telegram::Bot.new('custom_token'),
controller,
'telegram_webhook',
option: :val,
], [
Telegram::Bot.new(bot.token, 'new_name'),
controller,
'telegram_webhook',
option: :val,
]
end
end
end
end

133
spec/telegram/bot/updates_controller_spec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,133 @@
RSpec.describe Telegram::Bot::UpdatesController do
let(:instance) { described_class.new(bot, update) }
let(:update) { {payload_type => payload} }
let(:payload_type) { 'some_type' }
let(:payload) { double(:payload) }
let(:bot) { double(username: bot_name) }
let(:bot_name) { 'bot' }
let(:other_bot_name) { 'other_bot' }
describe '.action_for_command' do
subject { ->(*args) { described_class.action_for_command(*args) } }
def assert_subject(input, expected)
expect(subject.call input).to eq expected
end
it 'bypasses and downcases not conflictint commands' do
assert_subject 'test', 'test'
assert_subject 'TeSt', 'test'
assert_subject '_Te1St', '_te1st'
end
it 'adds _on to conflicting commands' do
described_class::PAYLOAD_TYPES.each do |x|
assert_subject x, "on_#{x}"
assert_subject x.upcase, "on_#{x}"
end
assert_subject '1TeSt', 'on_1test'
end
end
describe '.command_from_text' do
subject { ->(*args) { described_class.command_from_text(*args) } }
def assert_subject(input, cmd, *args)
expected = cmd ? [cmd, args] : cmd
expect(subject.call(*input)).to eq expected
end
let(:max_cmd_size) { 32 }
let(:long_cmd) { 'a' * (max_cmd_size - 1) }
let(:too_long_cmd) { 'a' * max_cmd_size }
it 'works for simple commands' do
assert_subject '/test', 'test'
assert_subject '/tE_2_St', 'tE_2_St'
assert_subject '/123', '123'
assert_subject "/#{long_cmd}", long_cmd
end
it 'works for simple messages' do
assert_subject 'text', nil
assert_subject ' ', nil
assert_subject ' text', nil
assert_subject ' 1', nil
assert_subject ' /text', nil
assert_subject '/te-xt', nil
assert_subject 'text /cmd ', nil
assert_subject "/#{too_long_cmd}", nil
end
it 'works for mentioned commands' do
assert_subject ['/test@bot', 'bot'], 'test'
assert_subject ['/test@otherbot', 'bot'], nil
assert_subject ['/test@Bot', 'bot'], nil
assert_subject '/test@bot', nil
assert_subject ['/test@bot', true], 'test'
assert_subject ['/test@otherbot', true], 'test'
end
it 'works for commands with args' do
assert_subject '/test arg', 'test', 'arg'
assert_subject '/test arg 1 2', 'test', 'arg', '1', '2'
assert_subject ['/test@bot arg', 'bot'], 'test', 'arg'
assert_subject ['/test@otherbot arg', 'bot'], nil
assert_subject '/test@bot arg', nil
end
it 'works for commands with multiline args' do
assert_subject "/test arg\nother", 'test', 'arg', 'other'
assert_subject "/test one\ntwo\n\nthree", 'test', 'one', 'two', 'three'
end
end
describe '#action_for_payload' do
subject { instance.action_for_payload }
(described_class::PAYLOAD_TYPES - %w(message)).each do |type|
context "when payload is #{type}" do
let(:payload_type) { type }
it { should eq [false, type, [payload]] }
end
end
context 'when payload is message' do
let(:payload_type) { 'message' }
let(:payload) { {'text' => text} }
let(:text) { 'test' }
it { should eq [false, payload_type, [payload]] }
context 'with command' do
let(:text) { "/test#{"@#{mention}" if mention} arg 1 2" }
let(:mention) {}
it { should eq [true, 'test', %w(arg 1 2)] }
context 'with mention' do
let(:mention) { bot.username }
it { should eq [true, 'test', %w(arg 1 2)] }
end
context 'with mention for other bot' do
let(:mention) { other_bot_name }
it { should eq [false, 'message', [payload]] }
end
end
end
end
describe '#bot_username' do
subject { instance.bot_username }
context 'when bot is not set' do
let(:bot) {}
it { should eq nil }
end
context 'when bot is set' do
let(:bot) { double(username: double(:username)) }
it { should eq bot.username }
end
end
end

9
spec/telegram/bot/updates_poller_spec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,9 @@
RSpec.describe Telegram::Bot::UpdatesPoller do
describe '#initialize' do
subject { described_class.new bot, controller }
let(:bot) { double }
let(:controller) { double }
it { should be }
end
end

51
spec/telegram/bot_spec.rb Обычный файл
Просмотреть файл

@@ -0,0 +1,51 @@
RSpec.describe Telegram::Bot do
it 'has a version number' do
expect(Telegram::Bot::VERSION).not_to be nil
end
describe '.wrap' do
subject { described_class.wrap(input) }
let(:result) { double(:result) }
let(:token) { 'token' }
let(:username) { 'username' }
let(:instance) { described_class.new 'token' }
context 'when input is a string' do
let(:input) { token }
it 'treats string as token' do
expect(described_class).to receive(:new).with(token) { result }
should eq result
end
end
context 'when input is a hash' do
let(:input) { {token: token, username: username, ignore: :ignore} }
it 'extracts token & username' do
expect(described_class).to receive(:new).with(token, username) { result }
should eq result
end
end
context 'when input is an instance of described_class' do
let!(:input) { instance }
it 'returns input' do
expect(described_class).to_not receive(:new)
should eq input
end
end
context 'when input is an array' do
let!(:input) { ['other_token', instance, token: token, username: username] }
let(:result_2) { double(:result_2) }
it 'calls wrap for every element' do
expect(described_class).to receive(:new).with('other_token') { result }
expect(described_class).to receive(:new).with(token, username) { result_2 }
should eq [result, instance, result_2]
end
end
end
end