From 32b6794924837590c441f596f3ed7a0ce2427db3 Mon Sep 17 00:00:00 2001 From: Max Melentiev Date: Fri, 4 Mar 2016 15:27:41 +0600 Subject: [PATCH] Ability to stub all clients. --- README.md | 30 ++++++++++++++++++--- lib/telegram/bot/client_stub.rb | 29 ++++++++++++++++++++ lib/telegram/bot/config_methods.rb | 7 +++++ spec/telegram/bot/client_stub_spec.rb | 38 +++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 spec/telegram/bot/client_stub_spec.rb diff --git a/README.md b/README.md index f8c193b..f2121ca 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController end def read - session[:text] + reply_with :message, text: session[:text] end private @@ -215,13 +215,35 @@ call `.dispatch(bot, update)` on controller. ### Development & Debugging -Use `rake telegram:bot:poller BOT=chat` to run poller. It'll automatically load -changes without restart in development env. This task will not if you don't use -`telegram_webhooks`. +Use `rake telegram:bot:poller` to run poller. It'll automatically load +changes without restart in development env. Optionally specify bot to run poller for +with `BOT` envvar (`BOT=chat`). +This task will not work if you don't use `telegram_webhooks`. You can run poller manually with `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. + +To stub all possible clients use `Telegram::Bot::ClientStub.stub_all!` before +initializing clients. Most likely you'll want something like this: + +```ruby +RSpec.configure do |config| + # ... + Telegram.reset_bots + Telegram::Bot::ClientStub.stub_all! + config.after { Telegram.bot.reset } + # ... +end +``` + +There are also some helpers for controller tests. +Check out `telegram/bot/updates_controller/rspec_helpers`. + ### Deploying Use `rake telegram:bot:set_webhook` to update webhook url for all configured bots. diff --git a/lib/telegram/bot/client_stub.rb b/lib/telegram/bot/client_stub.rb index b3b9eb6..6f9ef22 100644 --- a/lib/telegram/bot/client_stub.rb +++ b/lib/telegram/bot/client_stub.rb @@ -4,6 +4,35 @@ module Telegram class ClientStub < Client attr_reader :requests + module StubbedConstructor + def new(*args) + if self == ClientStub || !ClientStub.stub_all? + super + else + ClientStub.new(args[1]) + end + end + end + + class << self + # Makes all + def stub_all!(enabled = true) + Client.extend(StubbedConstructor) unless Client < StubbedConstructor + return @_stub_all = enabled unless block_given? + begin + old = @_stub_all + stub_all!(enabled) + yield + ensure + stub_all!(old) + end + end + + def stub_all? + @_stub_all + end + end + def initialize(username = nil) @username = username reset diff --git a/lib/telegram/bot/config_methods.rb b/lib/telegram/bot/config_methods.rb index 3903447..ba2bcbb 100644 --- a/lib/telegram/bot/config_methods.rb +++ b/lib/telegram/bot/config_methods.rb @@ -41,6 +41,13 @@ module Telegram config[:default] = default if default end end + + # Resets all cached bots and their configs. + def reset_bots + @bots = nil + @bot = nil + @bots_config = nil + end end end end diff --git a/spec/telegram/bot/client_stub_spec.rb b/spec/telegram/bot/client_stub_spec.rb new file mode 100644 index 0000000..64af69f --- /dev/null +++ b/spec/telegram/bot/client_stub_spec.rb @@ -0,0 +1,38 @@ +RSpec.describe Telegram::Bot::ClientStub do + describe '#stub_all!' do + let(:client) { Telegram::Bot::Client.new('token', 'bot_name') } + let(:clients) { Telegram::Bot::Client.wrap(['token', token: 'token2']) } + + shared_examples 'constructors' do |expected_class| + it 'makes Client.new return ClientStub' do + expect(client).to be_instance_of expected_class + expect(client.username).to eq 'bot_name' + end + + it 'makes Client.wrap raturn ClientStub' do + expect(clients).to contain_exactly instance_of(expected_class), + instance_of(expected_class) + end + end + + context 'when not used' do + include_examples 'constructors', Telegram::Bot::Client + end + + context 'when enabled' do + around { |ex| described_class.stub_all! { ex.run } } + include_examples 'constructors', Telegram::Bot::ClientStub + end + + context 'when redisabled' do + around do |ex| + described_class.stub_all! do + described_class.stub_all!(false) do + ex.run + end + end + end + include_examples 'constructors', Telegram::Bot::Client + end + end +end