Skip to content
This repository has been archived by the owner on Mar 2, 2021. It is now read-only.

Commit

Permalink
Merge pull request #7 from Bajena/6-binding
Browse files Browse the repository at this point in the history
Execute only first found binding and add message_dispatch tests
  • Loading branch information
Bajena authored May 5, 2018
2 parents 7de069f + 5d1c17a commit 9cec58a
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 1 deletion.
2 changes: 2 additions & 0 deletions lib/rubotnik/message_dispatch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def bind_commands(&block)
end

def bind(*regex_strings, all: false, to: nil, reply_with: {})
return if @matched

regexps = regex_strings.map { |rs| /\b#{rs}/i }
proceed = regexps.any? { |regex| @message.text =~ regex }
proceed = regexps.all? { |regex| @message.text =~ regex } if all
Expand Down
2 changes: 1 addition & 1 deletion lib/rubotnik/user_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class UserStore
include Singleton
attr_reader :users

def initialize
@users = []
end
Expand Down
16 changes: 16 additions & 0 deletions spec/factories/message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

FactoryBot.define do
factory :message, class: Facebook::Messenger::Incoming::Message do
skip_create
initialize_with { new(attributes.stringify_keys) }

transient do
sender_id 1
text 'bla'
end

sender { { 'id' => sender_id } }
message { { 'text' => text } }
end
end
170 changes: 170 additions & 0 deletions spec/lib/rubotnik/message_dispatch_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Rubotnik::MessageDispatch do
let(:sender_id) { 2 }
let(:message) do
FactoryBot.build(:message, sender_id: sender_id, text: message_text)
end
let(:message_text) { 'bla' }
let(:user) do
FactoryBot.build(:user, :with_commands, id: sender_id, commands: commands)
end
let(:commands) { [] }
let(:dispatch) { described_class.new(message) }
let(:commands_module) do
Module.new do
def command1;end

def command2;end
end
end

before do
allow(UserStore.instance)
.to receive(:find_or_create_user)
.with(sender_id) { user }
dispatch.extend(commands_module)
end

describe 'route' do
context 'when user has an active command' do
let(:commands) { %i[command1 command2] }

it 'executes the command' do
expect(dispatch).to receive(:command2)

dispatch.route
end

context 'when a command raises an error' do
let(:debug) { nil }
let(:commands_module) do
Module.new do
def command2
raise 'err'
end
end
end

before do
allow(ENV).to receive(:[]).and_wrap_original do |m, *args|
if args[0] == 'DEBUG'
debug
else
m.call(*args)
end
end
end

context 'and debug is on' do
let(:debug) { 'true' }

it 'shows the error' do
expect(dispatch).to receive(:say) { 'There was an error: err' }

dispatch.route
end
end

context 'and debug is off' do
it 'reraises the error' do
expect(dispatch).to receive(:command2).and_call_original

expect { dispatch.route }.to raise_error('err')
end
end
end
end

context 'with user has no active command' do
context 'and message matches a binding with \'all: true\'' do
let(:message_text) { 'good morning' }

context 'when :to option is given' do
it 'executes the command' do
expect(dispatch).to receive(:command2)

dispatch.route do
bind 'Good', 'morning', all: true, to: :command2
end
end
end

context 'when block is given' do
it 'executes the command' do
expect(dispatch).to receive(:command1)

dispatch.route do
bind 'Good', 'morning', all: true do
command1
end
end
end
end
end

context 'and message matches a binding without \'all: true\'' do
let(:message_text) { 'Morning, sir' }

context 'when :to option is given' do
it 'executes the command' do
expect(dispatch).to receive(:command2)

dispatch.route do
bind 'Good', 'morning', to: :command2
end
end
end

context 'when block is given' do
it 'executes the command' do
expect(dispatch).to receive(:command1)

dispatch.route do
bind 'Good', 'morning' do
command1
end
end
end
end
end

context 'and message matches multiple commands' do
let(:message_text) { 'do something' }

it 'executes only the first matched command' do
expect(dispatch).to receive(:command1)
expect(dispatch).not_to receive(:command2)

dispatch.route do
bind 'do', 'something', all: true do
command1
end

bind 'something' do
command2
end
end
end
end

context 'and message matches no binding' do
it 'executes \'default\' block' do
expect(dispatch).to receive(:command1)

dispatch.route do
bind 'something' do
command2
end

default do
command1
end
end
end
end
end
end
end

0 comments on commit 9cec58a

Please sign in to comment.