зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-03 09:46:17 +03:00
Async requests with ActiveJob
Этот коммит содержится в:
89
spec/support/examples/async.rb
Обычный файл
89
spec/support/examples/async.rb
Обычный файл
@@ -0,0 +1,89 @@
|
||||
RSpec.shared_examples 'async' do |request_args: -> {}|
|
||||
let(:instance) { described_class.new(token: token, id: id, async: async) }
|
||||
let(:id) { :default_bot }
|
||||
let(:async) { true }
|
||||
let!(:application_job_class) do
|
||||
klass = Class.new do
|
||||
def self.perform_later(*)
|
||||
end
|
||||
end
|
||||
klass.tap { |x| stub_const('ApplicationJob', x) }
|
||||
end
|
||||
after { described_class.default_async_job = nil }
|
||||
|
||||
describe '#async' do
|
||||
subject { ->(*args, &block) { instance.async(*args, &block) } }
|
||||
its(:call) { should eq described_class.default_async_job }
|
||||
|
||||
context 'when async is disabled' do
|
||||
let(:async) { false }
|
||||
its(:call) { should eq false }
|
||||
end
|
||||
|
||||
context 'when using with block' do
|
||||
it 'sets value inside block' do
|
||||
expect do
|
||||
expect do
|
||||
subject.call(false) do
|
||||
expect do
|
||||
subject.call(nil) { expect(subject[]).to eq nil }
|
||||
end.to_not change(&subject).from false
|
||||
raise 'TestError'
|
||||
end
|
||||
end.to raise_error(/TestError/)
|
||||
end.to_not change(instance, :async).from(described_class.default_async_job)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.default_async_job' do
|
||||
subject { described_class.default_async_job }
|
||||
its(:superclass) { should eq application_job_class }
|
||||
it { should include Telegram::Bot::Async::Job }
|
||||
its(:client_class) { should eq described_class }
|
||||
|
||||
context 'when ApplicationJob is not defined' do
|
||||
let(:application_job_class) {}
|
||||
it { expect { subject }.to raise_error(/Define ApplicationJob/) }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#request' do
|
||||
subject { ->(*args) { instance.request(*(args.empty? ? self.args : args)) } }
|
||||
let(:args, &request_args)
|
||||
let(:result) { double(:result) }
|
||||
|
||||
shared_examples 'enqueues job' do
|
||||
it 'enqueues job' do
|
||||
expect(instance).to_not receive(:http_request)
|
||||
expect(described_class).to receive(:prepare_async_args).with(*args) { args }
|
||||
expect(instance.async).to receive(:perform_later).with(id.to_s, *args) { result }
|
||||
expect(subject.call).to eq result
|
||||
end
|
||||
end
|
||||
|
||||
include_examples 'enqueues job'
|
||||
|
||||
context 'with custom job class' do
|
||||
let(:async) { double(:job_class) }
|
||||
include_examples 'enqueues job'
|
||||
end
|
||||
|
||||
context 'when id is not set' do
|
||||
let(:id) {}
|
||||
it { should raise_error(/Can not enqueue/) }
|
||||
end
|
||||
|
||||
context 'when async is disabled' do
|
||||
let(:async) { false }
|
||||
let(:result) { double(status: 200, body: '{"test":"ok"}') }
|
||||
let(:args, &request_args)
|
||||
|
||||
it 'performs request immediately' do
|
||||
expect(instance).to receive(:request).with(*args).and_call_original
|
||||
expect(instance).to receive(:http_request) { result }
|
||||
expect(subject[]).to eq 'test' => 'ok'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
28
spec/telegram/bot/async_spec.rb
Обычный файл
28
spec/telegram/bot/async_spec.rb
Обычный файл
@@ -0,0 +1,28 @@
|
||||
RSpec.describe Telegram::Bot::Async::Job do
|
||||
let(:job_class) do
|
||||
described_class = self.described_class
|
||||
client_class = self.client_class
|
||||
Class.new do
|
||||
include described_class
|
||||
self.client_class = client_class
|
||||
end
|
||||
end
|
||||
let(:client_class) { Telegram::Bot::Client }
|
||||
let(:instance) { job_class.new }
|
||||
|
||||
describe '#perform' do
|
||||
subject { instance.perform(id, *args) }
|
||||
let(:id) { 'bot_id' }
|
||||
let(:args) { [double(:action), {body: :content}] }
|
||||
let(:client) { Telegram::Bot::Client.new(async: custom_job_class) }
|
||||
let(:custom_job_class) { Class.new }
|
||||
let(:result) { double(status: 200, body: '{"test":"ok"}') }
|
||||
|
||||
it 'finds client and performs request' do
|
||||
expect(client_class).to receive(:wrap).with(id.to_sym) { client }
|
||||
expect(client).to receive(:request).with(*args).and_call_original
|
||||
expect(client).to receive(:http_request) { result }
|
||||
should eq 'test' => 'ok'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,6 +13,12 @@ RSpec.describe Telegram::Bot::Client do
|
||||
let(:client_args) { [token, id: client_id, async: Class.new, botan: botan_token] }
|
||||
it { should be_instance_of Telegram::Bot::Botan }
|
||||
its(:token) { should eq botan_token }
|
||||
its(:id) { should eq client_id }
|
||||
|
||||
it 'doesnt inherit async from client' do
|
||||
expect(instance.async).to be
|
||||
expect(subject.async).to_not be
|
||||
end
|
||||
end
|
||||
|
||||
context 'when botan is configured with hash' do
|
||||
@@ -20,6 +26,8 @@ RSpec.describe Telegram::Bot::Client do
|
||||
let(:botan_config) { {token: botan_token, async: Class.new} }
|
||||
it { should be_instance_of Telegram::Bot::Botan }
|
||||
its(:token) { should eq botan_token }
|
||||
its(:id) { should eq client_id }
|
||||
its(:async) { should eq botan_config[:async] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ RSpec.describe Telegram::Bot::Botan do
|
||||
let(:token) { 'token' }
|
||||
|
||||
include_examples 'initializers', :botans
|
||||
include_examples 'async', request_args: -> { [double(:method), double(:url)] }
|
||||
|
||||
describe '.new' do
|
||||
subject { described_class.new(*args) }
|
||||
@@ -17,4 +18,10 @@ RSpec.describe Telegram::Bot::Botan do
|
||||
its(:token) { should eq args[0][:token] }
|
||||
end
|
||||
end
|
||||
|
||||
describe '.prepare_async_args' do
|
||||
subject { described_class.prepare_async_args(*input) }
|
||||
let(:input) { [:post, :uri, {a: 1, b: :sym, 'd' => 'str'}, 'body'] }
|
||||
it { should eq ['post', 'uri', {a: 1, b: 'sym', 'd' => 'str'}, 'body'] }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ RSpec.describe Telegram::Bot::Client do
|
||||
let(:botan_token) { double(:botan_token) }
|
||||
|
||||
include_examples 'initializers'
|
||||
include_examples 'async', request_args: -> { [double(:action), {body: :content}] }
|
||||
|
||||
describe '.prepare_body' do
|
||||
subject { described_class.prepare_body(input) }
|
||||
@@ -24,6 +25,12 @@ RSpec.describe Telegram::Bot::Client do
|
||||
end
|
||||
end
|
||||
|
||||
describe '.prepare_async_args' do
|
||||
subject { described_class.prepare_async_args(*input) }
|
||||
let(:input) { [:action, a: 1, b: :sym, c: [:other], 'd' => 'str'] }
|
||||
it { should eq ['action', a: 1, b: 'sym', c: '["other"]', 'd' => 'str'] }
|
||||
end
|
||||
|
||||
describe '.new' do
|
||||
subject { described_class.new(*args) }
|
||||
|
||||
|
||||
94
spec/telegram/bot/config_methods_spec.rb
Обычный файл
94
spec/telegram/bot/config_methods_spec.rb
Обычный файл
@@ -0,0 +1,94 @@
|
||||
RSpec.describe Telegram::Bot::ConfigMethods do
|
||||
let(:registry) do
|
||||
Object.new.tap do |x|
|
||||
x.extend described_class
|
||||
x.bots_config = config
|
||||
end
|
||||
end
|
||||
let(:config) do
|
||||
{
|
||||
default: 'default_token',
|
||||
chat: {
|
||||
token: 'chat_token',
|
||||
username: 'Chat',
|
||||
botan: 'chat_botan_token',
|
||||
},
|
||||
other_chat: {
|
||||
'token' => 'other_chat_token',
|
||||
'username' => 'OtherChat',
|
||||
'botan' => 'other_chat_botan_token',
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
describe '#bot' do
|
||||
subject { registry.bot }
|
||||
it { should eq registry.bots[:default] }
|
||||
end
|
||||
|
||||
describe '#bots' do
|
||||
context 'configured by token' do
|
||||
subject { registry.bots[:default] }
|
||||
its(:id) { should eq :default }
|
||||
its(:token) { should eq config[:default] }
|
||||
end
|
||||
|
||||
context 'configured by hash' do
|
||||
subject { registry.bots[:chat] }
|
||||
its(:id) { should eq :chat }
|
||||
its(:token) { should eq config[:chat][:token] }
|
||||
its(:username) { should eq config[:chat][:username] }
|
||||
its('botan.token') { should eq config[:chat][:botan] }
|
||||
end
|
||||
|
||||
context 'configured by hash with stringified keys' do
|
||||
subject { registry.bots[:other_chat] }
|
||||
its(:id) { should eq :other_chat }
|
||||
its(:token) { should eq config[:other_chat]['token'] }
|
||||
its(:username) { should eq config[:other_chat]['username'] }
|
||||
its('botan.token') { should eq config[:other_chat]['botan'] }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#botans' do
|
||||
subject { registry.botans }
|
||||
it do
|
||||
should eq(
|
||||
default: nil,
|
||||
chat: registry.bots[:chat].botan,
|
||||
other_chat: registry.bots[:other_chat].botan,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#bots_config' do
|
||||
subject { registry.bots_config }
|
||||
it { should eq config }
|
||||
|
||||
context 'when not configured' do
|
||||
let(:registry) { Object.new.tap { |x| x.extend described_class } }
|
||||
it { should eq({}) }
|
||||
|
||||
context 'in rails environment' do
|
||||
before { stub_const('Rails', double(application: double(secrets: secrets))) }
|
||||
let(:secrets) { {} }
|
||||
it { should eq({}) }
|
||||
|
||||
context 'when there is telegram section in secrets' do
|
||||
let(:secrets) { {telegram: config.stringify_keys} }
|
||||
let(:config) do
|
||||
{
|
||||
bot: double(:bot_config),
|
||||
bots: {
|
||||
chat: double(:chat_config),
|
||||
other_chat: double(:other_chat_config),
|
||||
},
|
||||
}
|
||||
end
|
||||
it { should include default: config[:bot] }
|
||||
it { should include config[:bots] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Ссылка в новой задаче
Block a user