lita 1.1.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +202 -45
- data/lib/lita.rb +45 -24
- data/lib/lita/adapter.rb +35 -0
- data/lib/lita/adapters/shell.rb +14 -3
- data/lib/lita/authorization.rb +24 -0
- data/lib/lita/cli.rb +1 -0
- data/lib/lita/config.rb +52 -19
- data/lib/lita/handler.rb +100 -36
- data/lib/lita/handlers/authorization.rb +38 -27
- data/lib/lita/handlers/help.rb +25 -22
- data/lib/lita/handlers/web.rb +25 -0
- data/lib/lita/http_route.rb +64 -0
- data/lib/lita/logger.rb +34 -0
- data/lib/lita/message.rb +41 -7
- data/lib/lita/rack_app_builder.rb +110 -0
- data/lib/lita/response.rb +30 -0
- data/lib/lita/robot.rb +56 -1
- data/lib/lita/rspec.rb +23 -50
- data/lib/lita/rspec/handler.rb +168 -0
- data/lib/lita/source.rb +19 -1
- data/lib/lita/user.rb +37 -1
- data/lib/lita/util.rb +26 -0
- data/lib/lita/version.rb +2 -1
- data/lita.gemspec +5 -0
- data/spec/lita/adapters/shell_spec.rb +12 -4
- data/spec/lita/config_spec.rb +18 -2
- data/spec/lita/handler_spec.rb +43 -46
- data/spec/lita/handlers/authorization_spec.rb +24 -31
- data/spec/lita/handlers/help_spec.rb +10 -8
- data/spec/lita/handlers/web_spec.rb +19 -0
- data/spec/lita/logger_spec.rb +26 -0
- data/spec/lita/message_spec.rb +16 -11
- data/spec/lita/robot_spec.rb +25 -2
- data/spec/lita/rspec_spec.rb +32 -20
- data/spec/lita/util_spec.rb +9 -0
- data/spec/lita_spec.rb +0 -51
- data/spec/spec_helper.rb +2 -1
- metadata +85 -3
- data/CHANGELOG.md +0 -21
data/spec/lita/config_spec.rb
CHANGED
@@ -16,8 +16,24 @@ describe Lita::Config do
|
|
16
16
|
|
17
17
|
describe ".default_config" do
|
18
18
|
it "has predefined values for certain keys" do
|
19
|
-
|
20
|
-
expect(
|
19
|
+
default_config = described_class.default_config
|
20
|
+
expect(default_config.robot.name).to eq("Lita")
|
21
|
+
expect(default_config.robot.adapter).to eq(:shell)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "loads configuration from registered handlers" do
|
25
|
+
handler = Class.new(Lita::Handler) do
|
26
|
+
def self.default_config(handler_config)
|
27
|
+
handler_config.bar = :baz
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.name
|
31
|
+
"Lita::Handlers::Foo"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
allow(Lita).to receive(:handlers).and_return([handler])
|
35
|
+
default_config = described_class.default_config
|
36
|
+
expect(default_config.handlers.foo.bar).to eq(:baz)
|
21
37
|
end
|
22
38
|
end
|
23
39
|
|
data/spec/lita/handler_spec.rb
CHANGED
@@ -1,40 +1,33 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Lita::Handler do
|
4
|
-
let(:robot)
|
5
|
-
|
6
|
-
allow(robot).to receive(:name).and_return("Lita")
|
7
|
-
robot
|
8
|
-
end
|
4
|
+
let(:robot) { double("Lita::Robot", name: "Lita") }
|
5
|
+
let(:user) { double("Lita::User") }
|
9
6
|
|
10
7
|
let(:message) do
|
11
|
-
message = double("Message")
|
12
|
-
allow(message).to receive(:
|
13
|
-
allow(message).to receive(:command?).and_return(false)
|
14
|
-
allow(message).to receive(:source).and_return(source)
|
15
|
-
allow(message).to receive(:user).and_return(user)
|
8
|
+
message = double("Lita::Message", user: user, command?: false)
|
9
|
+
allow(message).to receive(:match)
|
16
10
|
message
|
17
11
|
end
|
18
12
|
|
19
|
-
let(:matches) { double("MatchData") }
|
20
|
-
|
21
|
-
let(:source) { double("Source") }
|
22
|
-
|
23
|
-
let(:user) { double("User") }
|
24
|
-
|
25
13
|
let(:handler_class) do
|
26
14
|
Class.new(described_class) do
|
27
|
-
route(/\w{3}/,
|
28
|
-
route(/\w{4}/,
|
29
|
-
route(/secret/,
|
15
|
+
route(/\w{3}/, :foo)
|
16
|
+
route(/\w{4}/, :blah, command: true)
|
17
|
+
route(/secret/, :secret, restrict_to: :admins)
|
18
|
+
|
19
|
+
http.get "web", :web
|
20
|
+
|
21
|
+
def foo(response)
|
22
|
+
end
|
30
23
|
|
31
|
-
def
|
24
|
+
def blah(response)
|
32
25
|
end
|
33
26
|
|
34
|
-
def
|
27
|
+
def secret(response)
|
35
28
|
end
|
36
29
|
|
37
|
-
def
|
30
|
+
def web(request, response)
|
38
31
|
end
|
39
32
|
|
40
33
|
def self.name
|
@@ -43,7 +36,7 @@ describe Lita::Handler do
|
|
43
36
|
end
|
44
37
|
end
|
45
38
|
|
46
|
-
subject { described_class.new(robot
|
39
|
+
subject { described_class.new(robot) }
|
47
40
|
|
48
41
|
describe ".dispatch" do
|
49
42
|
it "routes a matching message to the supplied method" do
|
@@ -94,38 +87,42 @@ describe Lita::Handler do
|
|
94
87
|
end
|
95
88
|
end
|
96
89
|
|
97
|
-
describe "
|
98
|
-
it "
|
99
|
-
|
100
|
-
|
90
|
+
describe ".namespace" do
|
91
|
+
it "provides a snake cased namespace for the handler" do
|
92
|
+
handler_class = Class.new(described_class) do
|
93
|
+
def self.name
|
94
|
+
"Lita::Handlers::FooBarBaz"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
expect(handler_class.namespace).to eq("foo_bar_baz")
|
101
98
|
end
|
102
|
-
end
|
103
99
|
|
104
|
-
|
105
|
-
|
106
|
-
expect
|
107
|
-
subject.command?
|
100
|
+
it "raises an exception if the handler doesn't define self.name" do
|
101
|
+
handler_class = Class.new(described_class)
|
102
|
+
expect { handler_class.namespace }.to raise_error
|
108
103
|
end
|
109
104
|
end
|
110
105
|
|
111
|
-
describe "#
|
112
|
-
it "
|
113
|
-
expect(
|
114
|
-
subject.message_body
|
106
|
+
describe "#http" do
|
107
|
+
it "returns a Faraday connection" do
|
108
|
+
expect(subject.http).to be_a(Faraday::Connection)
|
115
109
|
end
|
116
|
-
end
|
117
110
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
111
|
+
it "sets a default user agent" do
|
112
|
+
expect(subject.http.headers["User-Agent"]).to eq("Lita v#{Lita::VERSION}")
|
113
|
+
end
|
114
|
+
|
115
|
+
it "merges in user-supplied options" do
|
116
|
+
connection = subject.http(headers: {
|
117
|
+
"User-Agent" => "Foo", "X-Bar" => "Baz"
|
118
|
+
})
|
119
|
+
expect(connection.headers["User-Agent"]).to eq("Foo")
|
120
|
+
expect(connection.headers["X-Bar"]).to eq("Baz")
|
122
121
|
end
|
123
|
-
end
|
124
122
|
|
125
|
-
|
126
|
-
|
127
|
-
expect(
|
128
|
-
subject.scan
|
123
|
+
it "passes blocks on to Faraday" do
|
124
|
+
connection = subject.http { |builder| builder.response :logger }
|
125
|
+
expect(connection.builder.handlers).to include(Faraday::Response::Logger)
|
129
126
|
end
|
130
127
|
end
|
131
128
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe Lita::Handlers::Authorization,
|
3
|
+
describe Lita::Handlers::Authorization, lita_handler: true do
|
4
4
|
before do
|
5
|
-
allow(robot).to receive(:send_messages)
|
6
5
|
allow(Lita::Authorization).to receive(:user_is_admin?).with(
|
7
6
|
user
|
8
7
|
).and_return(true)
|
@@ -10,39 +9,33 @@ describe Lita::Handlers::Authorization, lita: true do
|
|
10
9
|
|
11
10
|
let(:target_user) { double("Lita::User", id: "1", name: "Carl") }
|
12
11
|
|
13
|
-
it {
|
14
|
-
it {
|
15
|
-
it {
|
16
|
-
it {
|
17
|
-
|
18
|
-
describe ".help" do
|
19
|
-
it "returns a hash of command help" do
|
20
|
-
expect(described_class.help).to be_a(Hash)
|
21
|
-
end
|
22
|
-
end
|
12
|
+
it { routes_command("auth add foo bar").to(:add) }
|
13
|
+
it { routes_command("auth add foo@bar.com baz").to(:add) }
|
14
|
+
it { routes_command("auth remove foo bar").to(:remove) }
|
15
|
+
it { routes_command("auth remove foo@bar.com baz").to(:remove) }
|
23
16
|
|
24
17
|
describe "#add" do
|
25
18
|
it "replies with the proper format if the require commands are missing" do
|
26
|
-
|
27
|
-
|
19
|
+
send_command("auth add foo")
|
20
|
+
expect(replies.last).to match(/^Format:/)
|
28
21
|
end
|
29
22
|
|
30
23
|
it "replies with a warning if target user is not known" do
|
31
|
-
|
32
|
-
|
24
|
+
send_command("auth add foo bar")
|
25
|
+
expect(replies.last).to match(/No user was found/)
|
33
26
|
end
|
34
27
|
|
35
28
|
it "replies with success if a valid user and group were supplied" do
|
36
29
|
allow(Lita::User).to receive(:find_by_id).and_return(target_user)
|
37
|
-
|
38
|
-
|
30
|
+
send_command("auth add foo bar")
|
31
|
+
expect(replies.last).to eq("#{target_user.name} was added to bar.")
|
39
32
|
end
|
40
33
|
|
41
34
|
it "replies with a warning if the user was already in the group" do
|
42
35
|
allow(Lita::User).to receive(:find_by_id).and_return(target_user)
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
send_command("auth add foo bar")
|
37
|
+
send_command("auth add foo bar")
|
38
|
+
expect(replies.last).to eq("#{target_user.name} was already in bar.")
|
46
39
|
end
|
47
40
|
|
48
41
|
it "replies with a warning if the requesting user is not an admin" do
|
@@ -50,34 +43,34 @@ describe Lita::Handlers::Authorization, lita: true do
|
|
50
43
|
allow(Lita::Authorization).to receive(:user_is_admin?).with(
|
51
44
|
user
|
52
45
|
).and_return(false)
|
53
|
-
|
54
|
-
|
46
|
+
send_command("auth add foo bar")
|
47
|
+
expect(replies.last).to match(/Only administrators can add/)
|
55
48
|
end
|
56
49
|
end
|
57
50
|
|
58
51
|
describe "#remove" do
|
59
52
|
before do
|
60
53
|
allow(Lita::User).to receive(:find_by_id).and_return(target_user)
|
61
|
-
|
54
|
+
send_command("auth add foo bar")
|
62
55
|
end
|
63
56
|
|
64
57
|
it "replies with success if a valid user and group were supplied" do
|
65
|
-
|
66
|
-
|
58
|
+
send_command("auth remove foo bar")
|
59
|
+
expect(replies.last).to eq("#{target_user.name} was removed from bar.")
|
67
60
|
end
|
68
61
|
|
69
62
|
it "replies with a warning if the user was already in the group" do
|
70
|
-
|
71
|
-
|
72
|
-
|
63
|
+
send_command("auth remove foo bar")
|
64
|
+
send_command("auth remove foo bar")
|
65
|
+
expect(replies.last).to eq("#{target_user.name} was not in bar.")
|
73
66
|
end
|
74
67
|
|
75
68
|
it "replies with a warning if the requesting user is not an admin" do
|
76
69
|
allow(Lita::Authorization).to receive(:user_is_admin?).with(
|
77
70
|
user
|
78
71
|
).and_return(false)
|
79
|
-
|
80
|
-
|
72
|
+
send_command("auth remove foo bar")
|
73
|
+
expect(replies.last).to match(/Only administrators can remove/)
|
81
74
|
end
|
82
75
|
end
|
83
76
|
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe Lita::Handlers::Help,
|
4
|
-
it {
|
5
|
-
it {
|
3
|
+
describe Lita::Handlers::Help, lita_handler: true do
|
4
|
+
it { routes_command("help").to(:help) }
|
5
|
+
it { routes_command("help foo").to(:help) }
|
6
6
|
|
7
7
|
describe "#help" do
|
8
8
|
it "sends help information for all commands" do
|
9
|
-
|
10
|
-
|
9
|
+
send_command("help")
|
10
|
+
expect(replies.last).to match(
|
11
|
+
/#{robot.mention_name}: help.+#{robot.mention_name}: help COMMAND/m
|
12
|
+
)
|
11
13
|
end
|
12
14
|
|
13
15
|
it "sends help information for commands starting with COMMAND" do
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
send_command("help help COMMAND")
|
17
|
+
expect(replies.last).to match(/help COMMAND - Lists/)
|
18
|
+
expect(replies.last).not_to match(/help - Lists/)
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Lita::Handlers::Web, lita_handler: true do
|
4
|
+
it { routes_http(:get, "/lita/info").to(:info) }
|
5
|
+
it { doesnt_route_http(:post, "/lita/info").to(:info) }
|
6
|
+
|
7
|
+
let(:request) { double("Rack::Request") }
|
8
|
+
let(:response) { Rack::Response.new }
|
9
|
+
|
10
|
+
describe "#info" do
|
11
|
+
it "returns JSON with info about the running robot" do
|
12
|
+
subject.info(request, response)
|
13
|
+
expect(response.headers["Content-Type"]).to eq("application/json")
|
14
|
+
expect(response.body.join).to include(
|
15
|
+
%{"lita_version":"#{Lita::VERSION}"}
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Lita::Logger do
|
4
|
+
it "uses a custom log level" do
|
5
|
+
logger = described_class.get_logger(:debug)
|
6
|
+
expect(logger.level).to eq(Logger::DEBUG)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "uses the info level if the config is nil" do
|
10
|
+
logger = described_class.get_logger(nil)
|
11
|
+
expect(logger.level).to eq(Logger::INFO)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "uses the info level if the config level is invalid" do
|
15
|
+
logger = described_class.get_logger(:foo)
|
16
|
+
expect(logger.level).to eq(Logger::INFO)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "logs messages with a custom format" do
|
20
|
+
stderr = StringIO.new
|
21
|
+
stub_const("STDERR", stderr)
|
22
|
+
logger = described_class.get_logger(:debug)
|
23
|
+
logger.fatal "foo"
|
24
|
+
expect(stderr.string).to match(%r{^\[.+\] FATAL: foo$})
|
25
|
+
end
|
26
|
+
end
|
data/spec/lita/message_spec.rb
CHANGED
@@ -11,10 +11,6 @@ describe Lita::Message do
|
|
11
11
|
expect(subject.body).to eq("Hello")
|
12
12
|
end
|
13
13
|
|
14
|
-
it "aliases #body with #message" do
|
15
|
-
expect(subject.message).to eq("Hello")
|
16
|
-
end
|
17
|
-
|
18
14
|
it "has a source" do
|
19
15
|
expect(subject.source).to eq("Carl")
|
20
16
|
end
|
@@ -48,15 +44,17 @@ describe Lita::Message do
|
|
48
44
|
expect(subject).to be_a_command
|
49
45
|
end
|
50
46
|
|
51
|
-
it "is
|
52
|
-
|
47
|
+
it "is true when the Robot's name is capitalized differently" do
|
48
|
+
subject = described_class.new(
|
49
|
+
robot,
|
50
|
+
"#{robot.mention_name.upcase}: hello",
|
51
|
+
"Carl"
|
52
|
+
)
|
53
|
+
expect(subject).to be_a_command
|
53
54
|
end
|
54
|
-
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
expect(subject.body).to receive(:scan)
|
59
|
-
subject.scan
|
56
|
+
it "is false when the message is not addressed to the Robot" do
|
57
|
+
expect(subject).not_to be_a_command
|
60
58
|
end
|
61
59
|
end
|
62
60
|
|
@@ -66,4 +64,11 @@ describe Lita::Message do
|
|
66
64
|
subject.user
|
67
65
|
end
|
68
66
|
end
|
67
|
+
|
68
|
+
describe "#reply" do
|
69
|
+
it "sends strings back to the source through the robot" do
|
70
|
+
expect(robot).to receive(:send_messages).with("Carl", "foo", "bar")
|
71
|
+
subject.reply("foo", "bar")
|
72
|
+
end
|
73
|
+
end
|
69
74
|
end
|
data/spec/lita/robot_spec.rb
CHANGED
@@ -10,8 +10,8 @@ describe Lita::Robot do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "#receive" do
|
13
|
-
let(:handler1) { double("Handler 1") }
|
14
|
-
let(:handler2) { double("Handler 2") }
|
13
|
+
let(:handler1) { double("Handler 1").as_null_object }
|
14
|
+
let(:handler2) { double("Handler 2").as_null_object }
|
15
15
|
|
16
16
|
it "dispatches messages to every registered handler" do
|
17
17
|
allow(Lita).to receive(:handlers).and_return([handler1, handler2])
|
@@ -22,11 +22,34 @@ describe Lita::Robot do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "#run" do
|
25
|
+
let(:thread) { double("Thread", :abort_on_exception= => true, join: nil) }
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow_any_instance_of(Lita::Adapters::Shell).to receive(:run)
|
29
|
+
allow_any_instance_of(Thin::Server).to receive(:start)
|
30
|
+
|
31
|
+
allow(Thread).to receive(:new) do |&block|
|
32
|
+
block.call
|
33
|
+
thread
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
it "starts the adapter" do
|
26
38
|
expect_any_instance_of(Lita::Adapters::Shell).to receive(:run)
|
27
39
|
subject.run
|
28
40
|
end
|
29
41
|
|
42
|
+
it "starts the web server" do
|
43
|
+
expect_any_instance_of(Thin::Server).to receive(:start)
|
44
|
+
subject.run
|
45
|
+
end
|
46
|
+
|
47
|
+
it "doesn't silence thin if config.http.debug is true" do
|
48
|
+
Lita.config.http.debug = true
|
49
|
+
expect_any_instance_of(Thin::Server).not_to receive(:silent=)
|
50
|
+
subject.run
|
51
|
+
end
|
52
|
+
|
30
53
|
it "rescues interrupts and calls #shut_down" do
|
31
54
|
allow_any_instance_of(
|
32
55
|
Lita::Adapters::Shell
|
data/spec/lita/rspec_spec.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
handler_class = Class.new(Lita::Handler) do
|
4
|
-
route(
|
5
|
-
route(
|
4
|
+
route(/^\w{3}$/, :foo)
|
5
|
+
route(/^\w{4}$/, :blah, command: true)
|
6
|
+
route("restricted", :restricted, restrict_to: :some_group)
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
http.get "web", :web
|
9
|
+
|
10
|
+
def foo(response)
|
11
|
+
response.reply "baz"
|
12
|
+
end
|
13
|
+
|
14
|
+
def blah(response)
|
15
|
+
response.reply "bongo", "wongo"
|
16
|
+
end
|
17
|
+
|
18
|
+
def restricted(response)
|
9
19
|
end
|
10
20
|
|
11
|
-
def
|
12
|
-
reply "bongo", "wongo"
|
21
|
+
def web(request, response)
|
13
22
|
end
|
14
23
|
|
15
24
|
def self.name
|
@@ -17,33 +26,36 @@ handler_class = Class.new(Lita::Handler) do
|
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
|
-
describe handler_class,
|
29
|
+
describe handler_class, lita_handler: true do
|
21
30
|
it { routes("foo").to(:foo) }
|
22
|
-
it {
|
31
|
+
it { routes_command("blah").to(:blah) }
|
23
32
|
it { doesnt_route("blah").to(:blah) }
|
24
33
|
it { does_not_route("blah").to(:blah) }
|
34
|
+
it { doesnt_route_command("yo").to(:foo) }
|
35
|
+
it { does_not_route_command("yo").to(:foo) }
|
36
|
+
it { routes("restricted").to(:restricted) }
|
37
|
+
it { routes_http(:get, "web").to(:web) }
|
38
|
+
it { doesnt_route_http(:post, "web").to(:web) }
|
25
39
|
|
26
40
|
describe "#foo" do
|
27
41
|
it "replies with baz" do
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
it "doesn't reply with blam" do
|
33
|
-
expect_no_reply("blam")
|
34
|
-
send_test_message("foo")
|
42
|
+
send_message("foo")
|
43
|
+
expect(replies).to eq(["baz"])
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
38
47
|
describe "#blah" do
|
39
48
|
it "replies with bongo and wongo" do
|
40
|
-
|
41
|
-
|
49
|
+
send_command("blah")
|
50
|
+
expect(replies).to eq(["bongo", "wongo"])
|
42
51
|
end
|
52
|
+
end
|
43
53
|
|
44
|
-
|
45
|
-
|
46
|
-
|
54
|
+
it "allows the sending user to be specified" do
|
55
|
+
another_user = Lita::User.create(2, name: "Another User")
|
56
|
+
expect(robot).to receive(:receive) do |message|
|
57
|
+
expect(message.source.user).to eq(another_user)
|
47
58
|
end
|
59
|
+
send_message("foo", as: another_user)
|
48
60
|
end
|
49
61
|
end
|