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,87 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "boty/cli"
|
3
|
+
|
4
|
+
module Boty
|
5
|
+
RSpec.describe CLI, :thor do
|
6
|
+
subject(:cli) { described_class.new }
|
7
|
+
|
8
|
+
before(:all) do
|
9
|
+
FileUtils.mkdir_p "tmp" if !Dir.exists? "tmp"
|
10
|
+
FileUtils.chdir "tmp"
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
FileUtils.rm_rf "nice_bot" if Dir.exists? "nice_bot"
|
15
|
+
|
16
|
+
allow(cli).to receive(:ask).
|
17
|
+
and_return ENV["SLACK_COMPANY"], ENV["SLACK_BOT_API_TOKEN"]
|
18
|
+
|
19
|
+
allow(cli).to receive(:run)
|
20
|
+
end
|
21
|
+
|
22
|
+
after(:all) do
|
23
|
+
FileUtils.rm_rf "nice_bot" if Dir.exists? "nice_bot"
|
24
|
+
FileUtils.chdir "../"
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#new PROJECT" do
|
28
|
+
def create_nice_bot
|
29
|
+
capture(:stdout) do
|
30
|
+
cli.new "nice_bot"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "creates a directory named after the PROJECT" do
|
35
|
+
expect { create_nice_bot }.to create_directory "nice_bot"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "creates the executable" do
|
39
|
+
expect { create_nice_bot }.to create_file "nice_bot/bot"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "creates the empty dir for scripts" do
|
43
|
+
expect { create_nice_bot }.to create_directory "nice_bot/script"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "creates the empty dir for locales" do
|
47
|
+
expect { create_nice_bot }.to create_directory "nice_bot/locale"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "creates the empty dir for bot development" do
|
51
|
+
expect { create_nice_bot }.to create_directory "nice_bot/app"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "creates the Gemfile" do
|
55
|
+
expect { create_nice_bot }.to create_file "nice_bot/Gemfile"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "creates the Procfile" do
|
59
|
+
expect { create_nice_bot }.to create_file "nice_bot/Procfile"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "creates the README.md" do
|
63
|
+
expect { create_nice_bot }.to create_file "nice_bot/README.md"
|
64
|
+
end
|
65
|
+
|
66
|
+
context "/spec" do
|
67
|
+
it "creates the spec/ dir" do
|
68
|
+
expect { create_nice_bot }.to create_directory "nice_bot/spec"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "creates the .rspec file" do
|
72
|
+
expect { create_nice_bot }.to create_file "nice_bot/.rspec"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "turns the ./bot an executable file" do
|
77
|
+
expect(cli).to run "chmod +x bot"
|
78
|
+
create_nice_bot
|
79
|
+
end
|
80
|
+
|
81
|
+
it "runs bundle install after create the project" do
|
82
|
+
expect(cli).to run "bundle install"
|
83
|
+
create_nice_bot
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Boty
|
2
|
+
RSpec.describe Logger do
|
3
|
+
class Client; include Logger end
|
4
|
+
|
5
|
+
let(:logger) { Boty::Logger }
|
6
|
+
let(:client) { Client.new }
|
7
|
+
|
8
|
+
describe ".adapter" do
|
9
|
+
it "changes the internal logger representation" do
|
10
|
+
memory_logger = Boty::Logger::Memory.new
|
11
|
+
logger.adapter = memory_logger
|
12
|
+
expect(memory_logger).to receive(:info).with "hello"
|
13
|
+
|
14
|
+
client.logger.info "hello"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Logger::Memory do
|
19
|
+
subject(:adapter) { described_class.new }
|
20
|
+
|
21
|
+
before do
|
22
|
+
logger.adapter = adapter
|
23
|
+
end
|
24
|
+
|
25
|
+
it "stores the logs in memory" do
|
26
|
+
client.logger.info "hello"
|
27
|
+
|
28
|
+
expect(adapter.logs.last).to eq "hello"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Boty
|
2
|
+
RSpec.describe Message, :users do
|
3
|
+
subject(:message) { described_class.new message_json }
|
4
|
+
|
5
|
+
let(:user_id) { "U7777" }
|
6
|
+
let(:user_name) { "julian" }
|
7
|
+
|
8
|
+
let(:message_json) {{
|
9
|
+
"type" => "message",
|
10
|
+
"text" => "omg lol bbq",
|
11
|
+
"user" => "U7777",
|
12
|
+
"channel" => "333",
|
13
|
+
"ts" => "1234",
|
14
|
+
"team" => "3452"
|
15
|
+
}}
|
16
|
+
|
17
|
+
it "uses Slack.users.info to create a User instance" do
|
18
|
+
expect(message.user.id).to eq "U7777"
|
19
|
+
expect(message.user.name).to eq "julian"
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#from?" do
|
23
|
+
it "returns true if the param is the message author" do
|
24
|
+
expect(message.from? "U7777").to eq true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns true if the param `respond_to? :id` returning the message author" do
|
28
|
+
expect(message.from? OpenStruct.new(id: "U7777")).to eq true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "boty/rspec"
|
2
|
+
|
3
|
+
module Boty
|
4
|
+
::RSpec.describe Boty::RSpec::Bot do
|
5
|
+
include described_class
|
6
|
+
|
7
|
+
context "bot[Boty::Bot] instance" do
|
8
|
+
it "includes a `bot` instance in the example scope" do
|
9
|
+
expect(bot).to be_a Boty::ScriptDSL
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "have_responded matcher" do
|
14
|
+
it "provides a custom matcher to check against bot responses" do
|
15
|
+
expect(self).to respond_to(:have_responded)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "makes `Bot#say` work with the custom `have_responded` matcher" do
|
19
|
+
bot.say "something"
|
20
|
+
expect(bot).to have_responded "something"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "clears up the `Bot#_response` after check by matcher" do
|
24
|
+
bot.say "something"
|
25
|
+
expect(bot).to have_responded "something"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "helpers" do
|
30
|
+
it "includes #message_event to fire `data['type'] = 'message' events" do
|
31
|
+
expect(@_bot).to receive(:event).with "type" => "message", "text" => "omg"
|
32
|
+
message "omg"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Boty
|
2
|
+
RSpec.describe Session do
|
3
|
+
subject(:session) { described_class.new }
|
4
|
+
|
5
|
+
let(:rtm_start_json_response) {
|
6
|
+
JSON.parse '{
|
7
|
+
"url": "ws://example.org/slack/sse/url",
|
8
|
+
"self": {
|
9
|
+
"id": "1234"
|
10
|
+
}
|
11
|
+
}'
|
12
|
+
}
|
13
|
+
|
14
|
+
before do
|
15
|
+
allow(Slack.rtm).to receive(:start).and_return rtm_start_json_response
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#start", :em, :faye do
|
19
|
+
specify do
|
20
|
+
expect { |b| session.start(&b) }.to yield_control
|
21
|
+
end
|
22
|
+
|
23
|
+
it "logs in (request session url)" do
|
24
|
+
expect(Slack.rtm).to receive(:start).and_return rtm_start_json_response
|
25
|
+
|
26
|
+
session.start
|
27
|
+
end
|
28
|
+
|
29
|
+
it "creates the event loop" do
|
30
|
+
expect(EM).to receive(:run)
|
31
|
+
|
32
|
+
session.start
|
33
|
+
end
|
34
|
+
|
35
|
+
it "intializes the sse client with the session url" do
|
36
|
+
expect(Faye::WebSocket::Client).to receive(:new).
|
37
|
+
with("ws://example.org/slack/sse/url")
|
38
|
+
|
39
|
+
session.start
|
40
|
+
end
|
41
|
+
|
42
|
+
it "repasses `:message` event to `bot#event`" do
|
43
|
+
data = '{
|
44
|
+
"type": "omg",
|
45
|
+
"text": "lol"
|
46
|
+
}'
|
47
|
+
session.start do |dsl|
|
48
|
+
@dsl = dsl
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(@dsl.bot).to receive(:event).with(JSON.parse data)
|
52
|
+
faye.send_event :message, OpenStruct.new(data: data)
|
53
|
+
end
|
54
|
+
|
55
|
+
context "bot instantiation" do
|
56
|
+
it "creates the Bot instance" do
|
57
|
+
session.start do |bot|
|
58
|
+
expect(bot).to be_a ScriptDSL
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it "intializes the Bot with the right data" do
|
63
|
+
expect(Bot).to receive(:new).with({"id" => "1234"}, session)
|
64
|
+
|
65
|
+
session.start
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Boty
|
2
|
+
module Slack
|
3
|
+
RSpec.describe Chat do
|
4
|
+
subject(:chat) { described_class.new }
|
5
|
+
|
6
|
+
let(:parameters) {
|
7
|
+
"as_user=true&channel=general"
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:post_message_url) {
|
11
|
+
"https://slack.com/api/chat.postMessage?"+
|
12
|
+
"token=#{ENV['SLACK_BOT_API_TOKEN']}&#{parameters}"
|
13
|
+
}
|
14
|
+
|
15
|
+
describe "#post_message" do
|
16
|
+
it "uses api end point to send message with default parameters" do
|
17
|
+
expect(Slack::URL).to receive(:get).
|
18
|
+
with(post_message_url + "&text=omglolbbq")
|
19
|
+
chat.post_message "omglolbbq"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uri encodes the message" do
|
23
|
+
expect(Slack::URL).to receive(:get).
|
24
|
+
with(post_message_url + "&text=omg%20lol%20bbq")
|
25
|
+
chat.post_message "omg lol bbq"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "accepts extra api parameters" do
|
29
|
+
expect(Slack::URL).to receive(:get).
|
30
|
+
with(post_message_url + "&text=omg&extra=param")
|
31
|
+
chat.post_message "omg", extra: "param"
|
32
|
+
end
|
33
|
+
|
34
|
+
context "sending to a specific channel" do
|
35
|
+
let(:parameters) { "as_user=true&channel=lol" }
|
36
|
+
|
37
|
+
it "sends to a specific channel when one is given" do
|
38
|
+
expect(Slack::URL).to receive(:get).
|
39
|
+
with(post_message_url + "&text=omg")
|
40
|
+
chat.post_message "omg", channel: "lol"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#post_im" do
|
46
|
+
let(:im_open_url) {
|
47
|
+
"https://slack.com/api/im.open?"+
|
48
|
+
"token=#{ENV['SLACK_BOT_API_TOKEN']}&user=U1234"
|
49
|
+
}
|
50
|
+
|
51
|
+
before do
|
52
|
+
allow(Slack::URL).to receive(:get).with(im_open_url).
|
53
|
+
and_return("channel" => { "id" => "C4321" })
|
54
|
+
allow(chat).to receive(:post_message)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "calls `#im.open` to open the channel" do
|
58
|
+
expect(chat.im).to receive(:open).with("U1234").
|
59
|
+
and_return Channel.new(id: "C4321", info: {})
|
60
|
+
|
61
|
+
chat.post_im "U1234", "message"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "sends the message to the im channel returned by `#im.open`" do
|
65
|
+
expect(chat).to receive(:post_message).
|
66
|
+
with "message", channel: "C4321"
|
67
|
+
|
68
|
+
chat.post_im "U1234", "message"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Boty
|
4
|
+
module Slack
|
5
|
+
RSpec.describe IM do
|
6
|
+
subject(:im) { described_class.new }
|
7
|
+
|
8
|
+
let(:action) { :open }
|
9
|
+
|
10
|
+
let(:im_url) {
|
11
|
+
"https://slack.com/api/im.#{action}?"+
|
12
|
+
"token=#{ENV['SLACK_BOT_API_TOKEN']}"
|
13
|
+
}
|
14
|
+
|
15
|
+
describe "#open" do
|
16
|
+
it "calls Slack::URL get with token and user" do
|
17
|
+
expect(Slack::URL).to receive(:get).with(im_url + "&user=U1234")
|
18
|
+
|
19
|
+
im.open "U1234"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns a channel object with the im channel information" do
|
23
|
+
expect(Slack::URL).to receive(:get).with(im_url + "&user=U1234").
|
24
|
+
and_return(
|
25
|
+
"ok" => true,
|
26
|
+
"channel" => { "id" => "D024BFF1M" }
|
27
|
+
)
|
28
|
+
|
29
|
+
expect(im.open("U1234").id).to eq "D024BFF1M"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Boty
|
2
|
+
module Slack
|
3
|
+
RSpec.describe RTM do
|
4
|
+
subject(:rtm) { described_class.new }
|
5
|
+
|
6
|
+
let(:url_with_default_parameters) {
|
7
|
+
"https://#{ENV["SLACK_COMPANY"]}.slack.com/api/rtm.start?"+
|
8
|
+
"token=#{ENV["SLACK_BOT_API_TOKEN"]}&"+
|
9
|
+
"simple_latest=true&no_unreads=true"
|
10
|
+
}
|
11
|
+
|
12
|
+
describe "#start" do
|
13
|
+
it "uses api to start the session" do
|
14
|
+
expect(Slack::URL).to receive(:get).with(url_with_default_parameters)
|
15
|
+
rtm.start
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Boty
|
2
|
+
module Slack
|
3
|
+
RSpec.describe URL do
|
4
|
+
class Pseudo
|
5
|
+
include URL
|
6
|
+
url "http://example.org"
|
7
|
+
|
8
|
+
def omg(parameters: {}, path: nil)
|
9
|
+
parameterize parameters, path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when included" do
|
14
|
+
subject(:client_class) { Pseudo }
|
15
|
+
|
16
|
+
it "injects the configuration method .url" do
|
17
|
+
expect(client_class).to respond_to :url
|
18
|
+
end
|
19
|
+
|
20
|
+
it "injects the #parameterize" do
|
21
|
+
expect(client_class.new.respond_to?(:parameterize, true)).to eq true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".get" do
|
26
|
+
subject(:url) { described_class }
|
27
|
+
|
28
|
+
it "sends the http request" do
|
29
|
+
expect(Net::HTTP).to receive(:get).with(URI("http://example.org"))
|
30
|
+
url.get "http://example.org"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "parses the json response" do
|
34
|
+
expect(Net::HTTP).to receive(:get).with(URI("http://example.org")).
|
35
|
+
and_return "{\"it\": \"works\"}"
|
36
|
+
response = url.get "http://example.org"
|
37
|
+
expect(response).to eq "it" => "works"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#parameterize" do
|
42
|
+
subject(:client) { Pseudo.new }
|
43
|
+
|
44
|
+
it "appends a path to the configured url" do
|
45
|
+
url = client.send :parameterize, {}, path: "/omg"
|
46
|
+
expect(url).to include "/omg?"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "appends the api token" do
|
50
|
+
url = client.send :parameterize, {}
|
51
|
+
expect(url).to include "token=#{ENV["SLACK_BOT_API_TOKEN"]}"
|
52
|
+
end
|
53
|
+
|
54
|
+
it "add extra parameters" do
|
55
|
+
url = client.send :parameterize, {really: "omg"}
|
56
|
+
expect(url).to include "really=omg"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "uses the url configured by #url" do
|
60
|
+
url = client.send :parameterize, {}
|
61
|
+
expect(url).to include "http://example.org"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "applies URI.encode to parameter values" do
|
65
|
+
url = client.send :parameterize, {really: "omg lol"}
|
66
|
+
expect(url).to include "really=omg%20lol"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|