boty 0.0.17 → 0.0.17.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/boty.gemspec +1 -1
- data/lib/boty/version.rb +1 -1
- data/spec/boty/bot_spec.rb +419 -0
- data/spec/boty/cli_spec.rb +87 -0
- data/spec/boty/logger_spec.rb +32 -0
- data/spec/boty/message_spec.rb +32 -0
- data/spec/boty/rspec_spec.rb +36 -0
- data/spec/boty/session_spec.rb +70 -0
- data/spec/boty/slack/chat_spec.rb +73 -0
- data/spec/boty/slack/im_spec.rb +34 -0
- data/spec/boty/slack/rtm_spec.rb +20 -0
- data/spec/boty/slack/url_spec.rb +71 -0
- data/spec/boty/slack/users_spec.rb +44 -0
- data/spec/happy_path_spec.rb +88 -0
- data/spec/script/i18n_spec.rb +22 -0
- data/spec/script/knows_spec.rb +18 -0
- data/spec/script/pug_spec.rb +53 -0
- data/spec/script/remember_spec.rb +43 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/em_support.rb +13 -0
- data/spec/support/fakefs_support.rb +13 -0
- data/spec/support/faraday_support.rb +15 -0
- data/spec/support/faye_support.rb +34 -0
- data/spec/support/file_system_matchers.rb +19 -0
- data/spec/support/session_support.rb +31 -0
- data/spec/support/slack_support.rb +28 -0
- data/spec/support/template_project_support.rb +44 -0
- data/spec/support/thor_support.rb +21 -0
- metadata +27 -1
@@ -0,0 +1,44 @@
|
|
1
|
+
module Boty
|
2
|
+
module Slack
|
3
|
+
RSpec.describe Users do
|
4
|
+
subject(:users) { described_class.new }
|
5
|
+
|
6
|
+
let(:action) { :info }
|
7
|
+
|
8
|
+
let(:url) {
|
9
|
+
"https://slack.com/api/users.#{action}?"+
|
10
|
+
"token=#{ENV['SLACK_BOT_API_TOKEN']}"
|
11
|
+
}
|
12
|
+
|
13
|
+
before do
|
14
|
+
allow(Slack::URL).to receive(:get).with(url + "&user=U023BECGF").
|
15
|
+
and_return(
|
16
|
+
{
|
17
|
+
"ok" => true,
|
18
|
+
"user" => {
|
19
|
+
"id" => "U023BECGF",
|
20
|
+
"name" => "julian"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#info" do
|
27
|
+
it "calls Slack::URL get with token and user" do
|
28
|
+
expect(Slack::URL).to receive(:get).with(url + "&user=U023BECGF")
|
29
|
+
|
30
|
+
users.info "U023BECGF"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns a channel object with the im channel information" do
|
34
|
+
expect(Slack::URL).to receive(:get).with(url + "&user=U023BECGF")
|
35
|
+
|
36
|
+
user = users.info("U023BECGF")
|
37
|
+
|
38
|
+
expect(user.id).to eq "U023BECGF"
|
39
|
+
expect(user.name).to eq "julian"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Boty
|
4
|
+
RSpec.describe "happy pathy with integration", :project, :session do
|
5
|
+
def start_session(only_knows: nil)
|
6
|
+
executable_bot = File.read "bot"
|
7
|
+
@session = instance_eval executable_bot, "bot", 1
|
8
|
+
|
9
|
+
if only_knows
|
10
|
+
extra_to_remove = bot.know_how.keys - only_knows
|
11
|
+
extra_to_remove.each do |command_desc|
|
12
|
+
bot.no command_desc
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def message(message)
|
18
|
+
faye.message(message, {user: current_user_id})
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:bot_name) { "boty" }
|
22
|
+
|
23
|
+
# I know =(, hard to understand, check the spec/support/slack_support
|
24
|
+
# TODO: enhance this =)
|
25
|
+
let(:current_user) { user_name }
|
26
|
+
let(:current_user_id) { user_id }
|
27
|
+
|
28
|
+
before do
|
29
|
+
@dir = Dir.pwd
|
30
|
+
dry_run
|
31
|
+
capture(:stdout) do
|
32
|
+
create_bot bot_name, company: "omg", api_key: "lol"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
after do
|
37
|
+
Dir.chdir @dir
|
38
|
+
Boty.locale = :en
|
39
|
+
end
|
40
|
+
|
41
|
+
it "creates the bot directory" do
|
42
|
+
expect(Dir.exists? bot_name).to eq true
|
43
|
+
end
|
44
|
+
|
45
|
+
context "on the bot directory" do
|
46
|
+
before do
|
47
|
+
Dir.chdir bot_name
|
48
|
+
end
|
49
|
+
|
50
|
+
it "connects to the server and hear it's name" do
|
51
|
+
expect(Faye::WebSocket::Client).to receive(:new).with(rtm_ws_url)
|
52
|
+
start_session
|
53
|
+
|
54
|
+
expect(bot).to receive(:say).
|
55
|
+
with "Ohay <@#{current_user}>! I'm here, that's for sure."
|
56
|
+
message "hey boty!"
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "knows" do
|
60
|
+
before do
|
61
|
+
start_session only_knows: ['knows']
|
62
|
+
end
|
63
|
+
|
64
|
+
it "responds in particular with the known commands and handlers" do
|
65
|
+
# check that a im arrived to the current user with knows result
|
66
|
+
message = "```\nknows: List all the commands known by this bot.\n```"
|
67
|
+
expect{ message "<@boty>: knows" }.
|
68
|
+
to send_im(current_user_id, message)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "overrides default locale with the project specific one" do
|
73
|
+
File.open("locale/xpto.yml", "w") do |file|
|
74
|
+
file.write(%{xpto:
|
75
|
+
scripts:
|
76
|
+
knows: "Wow! Such commands!"})
|
77
|
+
end
|
78
|
+
start_session only_knows: ['knows']
|
79
|
+
::Boty.locale = :xpto
|
80
|
+
|
81
|
+
message = "```\nknows: List all the commands known by this bot.\n```"
|
82
|
+
|
83
|
+
expect{ message "<@boty>: knows" }.
|
84
|
+
to send_im(current_user_id, message)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
RSpec.describe "I18n on default scripts", :session do
|
2
|
+
after do
|
3
|
+
Boty.locale = :en
|
4
|
+
end
|
5
|
+
|
6
|
+
it "describes scripts in :en locale (default)" do
|
7
|
+
session = Boty::Session.new
|
8
|
+
session.start do |bot|
|
9
|
+
expect(bot.know_how["knows"]).
|
10
|
+
to eq "List all the commands known by this bot."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "describes scripts in :pt-br local when forced" do
|
15
|
+
Boty.locale = :"pt-br"
|
16
|
+
session = Boty::Session.new
|
17
|
+
session.start do |bot|
|
18
|
+
expect(bot.know_how["knows"]).
|
19
|
+
to eq "Lista os comandos conhecidos por esse bot."
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec.describe "script/knows", :session do
|
2
|
+
before do
|
3
|
+
start_session
|
4
|
+
|
5
|
+
extra_to_remove = bot.know_how.keys - ['knows', 'pug me']
|
6
|
+
extra_to_remove.each do |command_desc|
|
7
|
+
bot.no command_desc
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "formats the output indenting by the command name size" do
|
12
|
+
expect(bot).to receive(:im).
|
13
|
+
with %{```\n knows: List all the commands known by this bot.
|
14
|
+
pug me: Send some nice pug in the channel.
|
15
|
+
```}
|
16
|
+
faye.message "<@jeeba>: knows"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "faraday"
|
2
|
+
|
3
|
+
RSpec.describe "script/pug", :session do
|
4
|
+
before do
|
5
|
+
start_session
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "pug me", :faraday do
|
9
|
+
before do
|
10
|
+
requests.get("/random") { |env|
|
11
|
+
[200,
|
12
|
+
{ "Content-Type" => "application/json;charset=utf-8" },
|
13
|
+
{pug: "some_pug"}.to_json]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "displays a pug" do
|
18
|
+
expect(bot).to receive(:say).with "<some_pug>"
|
19
|
+
|
20
|
+
faye.message "<@jeeba>:pug me"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "pug bomb x", :faraday do
|
25
|
+
it "displays x pugs" do
|
26
|
+
requests.get("/bomb") { |env|
|
27
|
+
expect(env.params).to eq "count" => "3"
|
28
|
+
[200,
|
29
|
+
{ "Content-Type" => "application/json;charset=utf-8" },
|
30
|
+
{ pugs: ["1", "2", "3"] }.to_json]
|
31
|
+
}
|
32
|
+
(1..3).each do |num|
|
33
|
+
expect(bot).to receive(:say).with("<#{num}>")
|
34
|
+
end
|
35
|
+
|
36
|
+
faye.message "<@jeeba>: pug bomb 3"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "defaults to 5 pugs when no count is given" do
|
40
|
+
requests.get("/bomb") { |env|
|
41
|
+
expect(env.params).to eq "count" => "5"
|
42
|
+
[200,
|
43
|
+
{ "Content-Type" => "application/json;charset=utf-8" },
|
44
|
+
{ pugs: ["1", "2", "3", "4", "5"] }.to_json]
|
45
|
+
}
|
46
|
+
(1..5).each do |num|
|
47
|
+
expect(bot).to receive(:say).with("<#{num}>")
|
48
|
+
end
|
49
|
+
|
50
|
+
faye.message "<@jeeba>: pug bomb"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
RSpec.describe "script/brain", :session do
|
2
|
+
before do
|
3
|
+
allow(::Boty::Slack.users).to receive(:info).with("U9876").and_return(
|
4
|
+
::Boty::Slack::User.new({
|
5
|
+
"id" => "U9876",
|
6
|
+
"name" => "valeriano"
|
7
|
+
})
|
8
|
+
)
|
9
|
+
|
10
|
+
allow(::Boty::Slack.users).to receive(:info).with("U7777").and_return(
|
11
|
+
::Boty::Slack::User.new({
|
12
|
+
"id" => "U7777",
|
13
|
+
"name" => "julian"
|
14
|
+
})
|
15
|
+
)
|
16
|
+
|
17
|
+
start_session
|
18
|
+
end
|
19
|
+
|
20
|
+
it "stores something about the user issuing the command" do
|
21
|
+
expect(bot).to receive(:im).
|
22
|
+
with "No worries, your secrets aren't safe with me... oh wait..."
|
23
|
+
|
24
|
+
faye.message "<@#{bot.name}>: remember I'm at the dentist until 12pm",
|
25
|
+
user: "U9876"
|
26
|
+
|
27
|
+
expect(bot.brain[:user]["valeriano"].first).to eq "I'm at the dentist until 12pm"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "recovers information from the brain" do
|
31
|
+
allow(bot).to receive(:im)
|
32
|
+
faye.message "<@#{bot.name}>: remember I'm at the dentist until 12pm",
|
33
|
+
user: "U9876"
|
34
|
+
|
35
|
+
expect(bot).to receive(:im).
|
36
|
+
with("julian, I'm searching my user database for valeriano:\n")
|
37
|
+
expect(bot).to receive(:im).
|
38
|
+
with("```\n - I'm at the dentist until 12pm\n```")
|
39
|
+
|
40
|
+
faye.message "<@#{bot.name}>: about user valeriano",
|
41
|
+
user: "U7777"
|
42
|
+
end
|
43
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift File.expand_path("..", __FILE__)
|
2
|
+
$:.unshift File.expand_path("../../lib", __FILE__)
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "byebug"
|
6
|
+
require "rubinius/debugger"
|
7
|
+
rescue LoadError
|
8
|
+
end
|
9
|
+
require "boty"
|
10
|
+
|
11
|
+
Dir['./spec/support/**/*.rb'].each { |f| require f }
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.include EMSupport, em: true
|
15
|
+
config.include FayeSupport, faye: true
|
16
|
+
config.include FakeFSSupport, fakefs: true
|
17
|
+
config.include SessionSupport, session: true
|
18
|
+
config.include ThorSupport, thor: true
|
19
|
+
config.include TemplateProjectSupport, project: true
|
20
|
+
config.include FaradaySupport, faraday: true
|
21
|
+
|
22
|
+
config.include SlackSupport::Users, users: true
|
23
|
+
|
24
|
+
Boty::Logger.adapter = Boty::Logger::Null.new
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module FaradaySupport
|
2
|
+
def self.included(base)
|
3
|
+
base.instance_eval do
|
4
|
+
|
5
|
+
let(:requests) { Faraday::Adapter::Test::Stubs.new }
|
6
|
+
|
7
|
+
around do |example|
|
8
|
+
adapter = Faraday.default_adapter
|
9
|
+
Faraday.default_adapter = [:test, requests]
|
10
|
+
example.run
|
11
|
+
Faraday.default_adapter = adapter
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module FayeSupport
|
2
|
+
class FakeFaye
|
3
|
+
def on(type, &block)
|
4
|
+
@events ||= {}
|
5
|
+
@events[type] ||= []
|
6
|
+
@events[type] << block
|
7
|
+
end
|
8
|
+
|
9
|
+
def send_event(type, data)
|
10
|
+
Array(Hash(@events)[type]).each do |block| block.call(data) end
|
11
|
+
end
|
12
|
+
|
13
|
+
def message(message, extra_args = {})
|
14
|
+
send_event(:message, OpenStruct.new(data: {
|
15
|
+
"type" => "message",
|
16
|
+
"text" => message }.merge(extra_args).to_json)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.included(base)
|
22
|
+
base.instance_eval do
|
23
|
+
let(:faye) { FakeFaye.new }
|
24
|
+
|
25
|
+
before do
|
26
|
+
allow(Faye::WebSocket::Client).to receive(:new).and_return faye
|
27
|
+
end
|
28
|
+
|
29
|
+
around do |example|
|
30
|
+
example.run
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
RSpec::Matchers.define :create_directory do |dir_name|
|
2
|
+
match do |block|
|
3
|
+
return false if Dir.exists? dir_name # change this to use a proper message
|
4
|
+
block.call
|
5
|
+
Dir.exists? dir_name
|
6
|
+
end
|
7
|
+
|
8
|
+
supports_block_expectations
|
9
|
+
end
|
10
|
+
|
11
|
+
RSpec::Matchers.define :create_file do |file_name|
|
12
|
+
match do |block|
|
13
|
+
return false if File.exists? file_name # change this to use a proper message
|
14
|
+
block.call
|
15
|
+
File.exists? file_name
|
16
|
+
end
|
17
|
+
|
18
|
+
supports_block_expectations
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SessionSupport
|
2
|
+
def self.included(base)
|
3
|
+
def start_session(only_knows:nil)
|
4
|
+
@session = Boty::Session.new
|
5
|
+
@session.start do |_| end
|
6
|
+
end
|
7
|
+
|
8
|
+
base.instance_eval do
|
9
|
+
include EMSupport
|
10
|
+
include FayeSupport
|
11
|
+
include SlackSupport::Users
|
12
|
+
|
13
|
+
let(:bot) { ::Boty::ScriptDSL.new @session.bot }
|
14
|
+
let(:dsl) { bot }
|
15
|
+
let(:bot_name) { "jeeba" }
|
16
|
+
let(:bot_id) { "U1234" }
|
17
|
+
let(:rtm_ws_url) { "ws://example.org/slack/sse/url" }
|
18
|
+
|
19
|
+
before do
|
20
|
+
allow(Boty::Slack.rtm).to receive(:start).
|
21
|
+
and_return JSON.parse '{
|
22
|
+
"url": "'+ rtm_ws_url + '",
|
23
|
+
"self": {
|
24
|
+
"id": "'+ bot_id + '",
|
25
|
+
"name": "'+ bot_name + '"
|
26
|
+
}
|
27
|
+
}'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SlackSupport
|
2
|
+
module Users
|
3
|
+
def self.included(base)
|
4
|
+
base.instance_eval do
|
5
|
+
let(:user_name) { "julian" }
|
6
|
+
let(:user_id) { "U023BECGF" }
|
7
|
+
|
8
|
+
before do
|
9
|
+
allow(::Boty::Slack.users).to receive(:info).and_return(
|
10
|
+
::Boty::Slack::User.new({
|
11
|
+
"id" => user_id,
|
12
|
+
"name" => user_name
|
13
|
+
})
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec::Matchers.define :send_im do |user_id, message|
|
21
|
+
supports_block_expectations
|
22
|
+
|
23
|
+
match do |block|
|
24
|
+
expect(::Boty::Slack.chat).to receive(:post_im).with(user_id, message)
|
25
|
+
block.call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|