boty 0.0.17 → 0.0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|