lita 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b61601772ee2c0a0822f137d838dd8f2b2aed2b
4
- data.tar.gz: a035716200ec7451d45e4b9cc6bf633200718a30
3
+ metadata.gz: ffbba6c703174e7a6984339b41e1b6b3ce01e617
4
+ data.tar.gz: 5d30f8db3d352fd2dacf9e3fb752d434ab6230d4
5
5
  SHA512:
6
- metadata.gz: 0088d680d6ded0dbeabfc979401010675d6e5d2b296dfdd66e06cadcfcf760d2db22ba480f9830a7d8eb05d3b81f1773bbe7ec8c6d20e4bb0820699eff90c195
7
- data.tar.gz: 7225377452adbde322b4a9a1a62d2abb30721dee7b719b62e9d41c62ede19116b0979942374bfb195ea8eb2ebdec8efcbbe6ab1ba360927c17b42f065526775f
6
+ metadata.gz: e5d699a894adf21dd032822f4b3e03b1271e4f49d1330abe1cef0a99d4af9f710aa2934277474ae6a72700b16fc48abee34777f6ca9bec34fc19a7fb6c421009
7
+ data.tar.gz: 62e5a1586f950a4385d40c0cab802d7e9eef5dd07900657ef8640dc59ad9c4a9a3972b402c327f6cff2c83be9ad933ce2f4adc7ef4a5699093fb3b9ffcb2870d
@@ -1,6 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
- script: bundle exec rspec
4
+ script: bundle exec rake
5
5
  before_install:
6
6
  - gem update --system
data/README.md CHANGED
@@ -258,7 +258,7 @@ module Lita
258
258
  class Echo < Handler
259
259
  route /^echo\s+(.+)/, :echo, help: { "echo FOO" => "Echoes back FOO." }
260
260
 
261
- def echo(matches)
261
+ def echo(response)
262
262
  response.reply(response.matches)
263
263
  end
264
264
  end
data/Rakefile CHANGED
@@ -1 +1,8 @@
1
1
  require "bundler/gem_tasks"
2
+ require "cane/rake_task"
3
+ require "rspec/core/rake_task"
4
+
5
+ Cane::RakeTask.new
6
+ RSpec::Core::RakeTask.new
7
+
8
+ task default: [:spec, :cane]
@@ -100,7 +100,7 @@ require "lita/authorization"
100
100
  require "lita/message"
101
101
  require "lita/response"
102
102
  require "lita/http_route"
103
- require "lita/rack_app_builder"
103
+ require "lita/rack_app"
104
104
  require "lita/robot"
105
105
  require "lita/adapter"
106
106
  require "lita/adapters/shell"
@@ -14,9 +14,7 @@ module Lita
14
14
  print "#{robot.name} > "
15
15
  input = $stdin.gets.chomp.strip
16
16
  break if input == "exit" || input == "quit"
17
- message = Message.new(robot, input, source)
18
- message.command! if Lita.config.adapter.private_chat
19
- robot.receive(message)
17
+ robot.receive(build_message(robot, input, source))
20
18
  end
21
19
  end
22
20
 
@@ -34,6 +32,14 @@ module Lita
34
32
  def shut_down
35
33
  puts
36
34
  end
35
+
36
+ private
37
+
38
+ def build_message(robot, input, source)
39
+ message = Message.new(robot, input, source)
40
+ message.command! if Lita.config.adapter.private_chat
41
+ message
42
+ end
37
43
  end
38
44
 
39
45
  Lita.register_adapter(:shell, Shell)
@@ -31,7 +31,9 @@ module Lita
31
31
  # @param group [Symbol, String] The name of the group.
32
32
  # @return [Boolean] Whether or not the user is in the group.
33
33
  def user_in_group?(user, group)
34
- redis.sismember(normalize_group(group), user.id)
34
+ group = normalize_group(group)
35
+ return user_is_admin?(user) if group == "admins"
36
+ redis.sismember(group, user.id)
35
37
  end
36
38
 
37
39
  # Checks if a user is an administrator.
@@ -5,7 +5,7 @@ module Lita
5
5
  # Initializes a new Config object with the default settings.
6
6
  # @return [Lita::Config] The default configuration.
7
7
  def default_config
8
- config = new.tap do |c|
8
+ new.tap do |c|
9
9
  c.robot = new
10
10
  c.robot.name = "Lita"
11
11
  c.robot.adapter = :shell
@@ -17,9 +17,8 @@ module Lita
17
17
  c.http.debug = false
18
18
  c.adapter = new
19
19
  c.handlers = new
20
+ load_handler_configs(c)
20
21
  end
21
- load_handler_configs(config)
22
- config
23
22
  end
24
23
 
25
24
  # Loads configuration from a user configuration file.
@@ -51,24 +51,17 @@ module Lita
51
51
  # @param message [Lita::Message] The incoming message.
52
52
  # @return [void]
53
53
  def dispatch(robot, message)
54
- routes.each do |route|
55
- if route_applies?(route, message, robot)
56
- Lita.logger.debug <<-LOG.chomp
57
- Dispatching message to #{self}##{route.method_name}.
58
- LOG
59
- begin
60
- new(robot).public_send(route.method_name, Response.new(
61
- message,
62
- matches: message.match(route.pattern)
63
- ))
64
- rescue Exception => e
65
- Lita.logger.error <<-ERROR.chomp
66
- #{name} crashed. The exception was:
67
- #{e.message}
68
- #{e.backtrace.join("\n")}
69
- ERROR
70
- raise e if rspec_loaded?
71
- end
54
+ routes.select { |r| route_applies?(r, message, robot) }.each do |route|
55
+ log_dispatch(route)
56
+
57
+ begin
58
+ new(robot).public_send(
59
+ route.method_name,
60
+ build_response(message, route)
61
+ )
62
+ rescue Exception => e
63
+ log_dispatch_error(e)
64
+ raise e if rspec_loaded?
72
65
  end
73
66
  end
74
67
  end
@@ -102,6 +95,11 @@ ERROR
102
95
 
103
96
  private
104
97
 
98
+ # Builds a response object for an incoming message.
99
+ def build_response(message, route)
100
+ Response.new(message, matches: message.match(route.pattern))
101
+ end
102
+
105
103
  # Determines whether or not an incoming messages should trigger a route.
106
104
  def route_applies?(route, message, robot)
107
105
  # Message must match the pattern
@@ -114,9 +112,7 @@ ERROR
114
112
  return if message.user.name == robot.name
115
113
 
116
114
  # User must be in auth group if route is restricted
117
- return if route.required_groups && route.required_groups.none? do |group|
118
- Authorization.user_in_group?(message.user, group)
119
- end
115
+ return unless authorized?(message.user, route.required_groups)
120
116
 
121
117
  true
122
118
  end
@@ -126,6 +122,28 @@ ERROR
126
122
  def rspec_loaded?
127
123
  defined?(::RSpec)
128
124
  end
125
+
126
+ # Checks if the user is authorized to at least one of the given groups.
127
+ def authorized?(user, required_groups)
128
+ required_groups.nil? || required_groups.any? do |group|
129
+ Authorization.user_in_group?(user, group)
130
+ end
131
+ end
132
+
133
+ # Logs the dispatch of message.
134
+ def log_dispatch(route)
135
+ Lita.logger.debug <<-LOG.chomp
136
+ Dispatching message to #{self}##{route.method_name}.
137
+ LOG
138
+ end
139
+
140
+ def log_dispatch_error(e)
141
+ Lita.logger.error <<-ERROR.chomp
142
+ #{name} crashed. The exception was:
143
+ #{e.message}
144
+ #{e.backtrace.join("\n")}
145
+ ERROR
146
+ end
129
147
  end
130
148
 
131
149
  # @param robot [Lita::Robot] The currently running robot.
@@ -2,16 +2,32 @@ module Lita
2
2
  module Handlers
3
3
  # Provides a chat interface for administering authorization groups.
4
4
  class Authorization < Handler
5
- route(/^auth\s+add/, :add, command: true, help: {
6
- "auth add USER GROUP" => "Add USER to authorization group GROUP. Requires admin privileges."
7
- })
8
- route(/^auth\s+remove/, :remove, command: true, help: {
9
- "auth remove USER GROUP" => "Remove USER from authorization group GROUP. Requires admin privileges."
10
- })
11
- route(/^auth\s+list/, :list, command: true, help: {
12
- "auth list [GROUP]" => <<-HELP
5
+ route(
6
+ /^auth\s+add/,
7
+ :add,
8
+ command: true,
9
+ restrict_to: :admins,
10
+ help: {
11
+ "auth add USER GROUP" => <<-HELP.chomp
12
+ Add USER to authorization group GROUP. Requires admin privileges.
13
+ HELP
14
+ }
15
+ )
16
+ route(
17
+ /^auth\s+remove/,
18
+ :remove,
19
+ command: true,
20
+ restrict_to: :admins,
21
+ help: {
22
+ "auth remove USER GROUP" => <<-HELP.chomp
23
+ Remove USER from authorization group GROUP. Requires admin privileges.
24
+ HELP
25
+ }
26
+ )
27
+ route(/^auth\s+list/, :list, command: true, restrict_to: :admins, help: {
28
+ "auth list [GROUP]" => <<-HELP.chomp
13
29
  List authorization groups and the users in them. If GROUP is supplied, only \
14
- lists that group."
30
+ lists that group.
15
31
  HELP
16
32
  })
17
33
 
@@ -21,10 +37,7 @@ HELP
21
37
  def add(response)
22
38
  return unless valid_message?(response)
23
39
 
24
- case Lita::Authorization.add_user_to_group(response.user, @user, @group)
25
- when :unauthorized
26
- response.reply "Only administrators can add users to groups."
27
- when true
40
+ if Lita::Authorization.add_user_to_group(response.user, @user, @group)
28
41
  response.reply "#{@user.name} was added to #{@group}."
29
42
  else
30
43
  response.reply "#{@user.name} was already in #{@group}."
@@ -37,14 +50,11 @@ HELP
37
50
  def remove(response)
38
51
  return unless valid_message?(response)
39
52
 
40
- case Lita::Authorization.remove_user_from_group(
53
+ if Lita::Authorization.remove_user_from_group(
41
54
  response.user,
42
55
  @user,
43
56
  @group
44
57
  )
45
- when :unauthorized
46
- response.reply "Only administrators can remove users from groups."
47
- when true
48
58
  response.reply "#{@user.name} was removed from #{@group}."
49
59
  else
50
60
  response.reply "#{@user.name} was not in #{@group}."
@@ -96,6 +106,11 @@ HELP
96
106
  return
97
107
  end
98
108
 
109
+ if @group.downcase.strip == "admins"
110
+ response.reply "Administrators can only be managed via Lita config."
111
+ return
112
+ end
113
+
99
114
  @user = User.find_by_id(identifier)
100
115
  @user = User.find_by_name(identifier) unless @user
101
116
 
@@ -3,35 +3,60 @@ module Lita
3
3
  # Provides online help about Lita commands for users.
4
4
  class Help < Handler
5
5
  route(/^help\s*(.+)?/, :help, command: true, help: {
6
- "help" => "Lists help information for terms and command the robot will respond to.",
7
- "help COMMAND" => "Lists help information for terms or commands that begin with COMMAND."
6
+ "help" => %{
7
+ Lists help information for terms and command the robot will respond to.
8
+ }.gsub(/\n/, ""),
9
+ "help COMMAND" => %{
10
+ Lists help information for terms or commands that begin with COMMAND.
11
+ }.gsub(/\n/, "")
8
12
  })
9
13
 
10
14
  # Outputs help information about Lita commands.
11
15
  # @param response [Lita::Response] The response object.
12
16
  # @return [void]
13
17
  def help(response)
18
+ output = build_help(response)
19
+ output = filter_help(output, response)
20
+ response.reply output.join("\n")
21
+ end
22
+
23
+ private
24
+
25
+ # Checks if the user is authorized to at least one of the given groups.
26
+ def authorized?(user, required_groups)
27
+ required_groups.nil? || required_groups.any? do |group|
28
+ Lita::Authorization.user_in_group?(user, group)
29
+ end
30
+ end
31
+
32
+ # Creates an array of help info for all registered routes.
33
+ def build_help(response)
14
34
  output = []
15
35
 
16
36
  Lita.handlers.each do |handler|
17
37
  handler.routes.each do |route|
18
38
  route.help.each do |command, description|
39
+ next unless authorized?(response.user, route.required_groups)
19
40
  command = "#{name}: #{command}" if route.command?
20
41
  output << "#{command} - #{description}"
21
42
  end
22
43
  end
23
44
  end
24
45
 
46
+ output
47
+ end
48
+
49
+ # Filters the help output by an optional command.
50
+ def filter_help(output, response)
25
51
  filter = response.matches[0][0]
52
+
26
53
  if filter
27
- output.select! { |line| /(?:@?#{name}[:,]?)?#{filter}/i === line }
54
+ output.select { |line| /(?:@?#{name}[:,]?)?#{filter}/i === line }
55
+ else
56
+ output
28
57
  end
29
-
30
- response.reply output.join("\n")
31
58
  end
32
59
 
33
- private
34
-
35
60
  # The way the bot should be addressed in order to trigger a command.
36
61
  def name
37
62
  Lita.config.robot.mention_name || Lita.config.robot.name
@@ -1,6 +1,6 @@
1
1
  module Lita
2
- # Creates a +Rack+ application from all the routes registered by handlers.
3
- class RackAppBuilder
2
+ # A +Rack+ application to serve routes registered by handlers.
3
+ class RackApp
4
4
  # The character that separates the pieces of a URL's path component.
5
5
  PATH_SEPARATOR = "/"
6
6
 
@@ -26,44 +26,33 @@ module Lita
26
26
  compile
27
27
  end
28
28
 
29
+ def call(env)
30
+ request = Rack::Request.new(env)
31
+ mapping = get_mapping(request)
32
+
33
+ if mapping
34
+ serve(mapping, request)
35
+ elsif request.head? && all_paths.include?(request.path)
36
+ Lita.logger.info "HTTP HEAD #{request.path} was a 204."
37
+ [204, {}, []]
38
+ else
39
+ Lita.logger.info <<-LOG.chomp
40
+ HTTP #{request.request_method} #{request.path} was a 404.
41
+ LOG
42
+ [404, {}, ["Route not found."]]
43
+ end
44
+ end
45
+
29
46
  # Creates a +Rack+ application from the compiled routes.
30
47
  # @return [Rack::Builder] The +Rack+ application.
31
48
  def to_app
32
49
  app = Rack::Builder.new
33
- app.run(app_proc)
50
+ app.run(self)
34
51
  app
35
52
  end
36
53
 
37
54
  private
38
55
 
39
- # The proc that serves as the +Rack+ application.
40
- def app_proc
41
- -> (env) do
42
- request = Rack::Request.new(env)
43
-
44
- mapping = routes[request.request_method][request.path]
45
-
46
- if mapping
47
- Lita.logger.info <<-LOG.chomp
48
- Routing HTTP #{request.request_method} #{request.path} to \
49
- #{mapping.handler}##{mapping.method_name}.
50
- LOG
51
- response = Rack::Response.new
52
- instance = mapping.handler.new(robot)
53
- instance.public_send(mapping.method_name, request, response)
54
- response.finish
55
- elsif request.head? && all_paths.include?(request.path)
56
- Lita.logger.info "HTTP HEAD #{request.path} was a 204."
57
- [204, {}, []]
58
- else
59
- Lita.logger.info <<-LOG.chomp
60
- HTTP #{request.request_method} #{request.path} was a 404.
61
- LOG
62
- [404, {}, ["Route not found."]]
63
- end
64
- end
65
- end
66
-
67
56
  # Collect all registered paths. Used for responding to HEAD requests.
68
57
  def collect_paths
69
58
  @all_paths = routes.values.map { |hash| hash.keys.first }.uniq
@@ -77,6 +66,10 @@ LOG
77
66
  collect_paths
78
67
  end
79
68
 
69
+ def get_mapping(request)
70
+ routes[request.request_method][request.path]
71
+ end
72
+
80
73
  # Registers a route.
81
74
  def register_route(handler, route)
82
75
  cleaned_path = clean_path(route.path)
@@ -99,6 +92,17 @@ LOG
99
92
  )
100
93
  end
101
94
 
95
+ def serve(mapping, request)
96
+ Lita.logger.info <<-LOG.chomp
97
+ Routing HTTP #{request.request_method} #{request.path} to \
98
+ #{mapping.handler}##{mapping.method_name}.
99
+ LOG
100
+ response = Rack::Response.new
101
+ instance = mapping.handler.new(robot)
102
+ instance.public_send(mapping.method_name, request, response)
103
+ response.finish
104
+ end
105
+
102
106
  # Ensures that paths begin with one slash and do not end with one.
103
107
  def clean_path(path)
104
108
  path.strip!
@@ -20,7 +20,7 @@ module Lita
20
20
  def initialize
21
21
  @name = Lita.config.robot.name
22
22
  @mention_name = Lita.config.robot.mention_name || @name
23
- @app = RackAppBuilder.new(self).to_app
23
+ @app = RackApp.new(self).to_app
24
24
  load_adapter
25
25
  end
26
26
 
@@ -16,20 +16,36 @@ require "lita/rspec/handler"
16
16
  module Lita
17
17
  # Extras for +RSpec+ that facilitate the testing of Lita code.
18
18
  module RSpec
19
- # Causes all interaction with Redis to use a test-specific namespace. Clears
20
- # Redis before each example. Stubs the logger to prevent log messages from
21
- # cluttering test output. Clears Lita's global configuration.
22
- # @param base [Object] The class including the module.
23
- # @return [void]
24
- def self.included(base)
25
- base.class_eval do
26
- before do
27
- stub_const("Lita::REDIS_NAMESPACE", "lita.test")
28
- keys = Lita.redis.keys("*")
29
- Lita.redis.del(keys) unless keys.empty?
30
- logger = double("Logger").as_null_object
31
- allow(Lita).to receive(:logger).and_return(logger)
32
- Lita.clear_config
19
+ class << self
20
+ # Causes all interaction with Redis to use a test-specific namespace.
21
+ # Clears Redis before each example. Stubs the logger to prevent log
22
+ # messages from cluttering test output. Clears Lita's global
23
+ # configuration.
24
+ # @param base [Object] The class including the module.
25
+ # @return [void]
26
+ def included(base)
27
+ base.class_eval do
28
+ before do
29
+ logger = double("Logger").as_null_object
30
+ allow(Lita).to receive(:logger).and_return(logger)
31
+ Lita.clear_config
32
+ end
33
+ end
34
+
35
+ set_up_redis(base)
36
+ end
37
+
38
+ private
39
+
40
+ # Set up Redis to use the test namespace and clear out before each
41
+ # example.
42
+ def set_up_redis(base)
43
+ base.class_eval do
44
+ before do
45
+ stub_const("Lita::REDIS_NAMESPACE", "lita.test")
46
+ keys = Lita.redis.keys("*")
47
+ Lita.redis.del(keys) unless keys.empty?
48
+ end
33
49
  end
34
50
  end
35
51
  end
@@ -2,28 +2,50 @@ module Lita
2
2
  module RSpec
3
3
  # Extras for +RSpec+ to facilitate testing Lita handlers.
4
4
  module Handler
5
- # Sets up the RSpec environment to easily test Lita handlers.
6
- def self.included(base)
7
- base.class_eval do
8
- include Lita::RSpec
9
-
10
- let(:robot) { Robot.new }
11
- let(:source) { Source.new(user) }
12
- let(:user) { User.create("1", name: "Test User") }
13
- let(:replies) { [] }
14
-
15
- subject { described_class.new(robot) }
16
-
17
- before do
18
- allow(Lita).to receive(:handlers).and_return([described_class])
19
- allow(robot).to receive(:send_messages) do |target, *strings|
20
- replies.concat(strings)
21
- end
22
- allow(robot).to receive(:send_message) do |target, *strings|
23
- replies.concat(strings)
5
+ class << self
6
+ # Sets up the RSpec environment to easily test Lita handlers.
7
+ def included(base)
8
+ base.class_eval do
9
+ include Lita::RSpec
10
+ end
11
+
12
+ set_up_let_blocks(base)
13
+ set_up_subject(base)
14
+ set_up_before_block(base)
15
+ end
16
+
17
+ private
18
+
19
+ # Stub Lita.handlers and Lita::Robot#send_messages.
20
+ def set_up_before_block(base)
21
+ base.class_eval do
22
+ before do
23
+ allow(Lita).to receive(:handlers).and_return([described_class])
24
+ [:send_messages, :send_message].each do |message|
25
+ allow(robot).to receive(message) do |target, *strings|
26
+ replies.concat(strings)
27
+ end
28
+ end
24
29
  end
25
30
  end
26
31
  end
32
+
33
+ # Create common test objects.
34
+ def set_up_let_blocks(base)
35
+ base.class_eval do
36
+ let(:robot) { Robot.new }
37
+ let(:source) { Source.new(user) }
38
+ let(:user) { User.create("1", name: "Test User") }
39
+ let(:replies) { [] }
40
+ end
41
+ end
42
+
43
+ # Set up a working test subject.
44
+ def set_up_subject(base)
45
+ base.class_eval do
46
+ subject { described_class.new(robot) }
47
+ end
48
+ end
27
49
  end
28
50
 
29
51
  # Sends a message to the robot.
@@ -48,8 +70,8 @@ module Lita
48
70
  send_message("#{robot.mention_name}: #{body}", as: as)
49
71
  end
50
72
 
51
- # Starts a chat routing test chain, asserting that a message should trigger
52
- # a route.
73
+ # Starts a chat routing test chain, asserting that a message should
74
+ # trigger a route.
53
75
  # @param message [String] The message that should trigger the route.
54
76
  # @return [RouteMatcher] A {RouteMatcher} that should have +to+ called on
55
77
  # it to complete the test.
@@ -82,7 +104,11 @@ module Lita
82
104
  # @return [RouteMatcher] A {RouteMatcher} that should have +to+ called on
83
105
  # it to complete the test.
84
106
  def does_not_route_command(message)
85
- RouteMatcher.new(self, "#{robot.mention_name}: #{message}", invert: true)
107
+ RouteMatcher.new(
108
+ self,
109
+ "#{robot.mention_name}: #{message}",
110
+ invert: true
111
+ )
86
112
  end
87
113
  alias_method :doesnt_route_command, :does_not_route_command
88
114
 
@@ -1,4 +1,4 @@
1
1
  module Lita
2
2
  # The current version of Lita.
3
- VERSION = "2.2.0"
3
+ VERSION = "2.2.1"
4
4
  end
@@ -33,4 +33,5 @@ Gem::Specification.new do |spec|
33
33
  spec.add_development_dependency "simplecov"
34
34
  spec.add_development_dependency "coveralls"
35
35
  spec.add_development_dependency "pry"
36
+ spec.add_development_dependency "cane"
36
37
  end
@@ -61,6 +61,11 @@ describe Lita::Authorization, lita: true do
61
61
  it "returns false if the user is in the group" do
62
62
  expect(described_class.user_in_group?(user, "employees")).to be_false
63
63
  end
64
+
65
+ it "delegates to .user_is_admin? if the group is admins" do
66
+ expect(described_class).to receive(:user_is_admin?)
67
+ described_class.user_in_group?(user, "admins")
68
+ end
64
69
  end
65
70
 
66
71
  describe ".user_is_admin?" do
@@ -40,13 +40,9 @@ describe Lita::Handlers::Authorization, lita_handler: true do
40
40
  expect(replies.last).to eq("#{target_user.name} was already in bar.")
41
41
  end
42
42
 
43
- it "replies with a warning if the requesting user is not an admin" do
44
- allow(Lita::User).to receive(:find_by_id).and_return(target_user)
45
- allow(Lita::Authorization).to receive(:user_is_admin?).with(
46
- user
47
- ).and_return(false)
48
- send_command("auth add foo bar")
49
- expect(replies.last).to match(/Only administrators can add/)
43
+ it %{replies with a warning if the group was "admins"} do
44
+ send_command("auth add foo admins")
45
+ expect(replies.last).to match(/Administrators can only be managed/)
50
46
  end
51
47
  end
52
48
 
@@ -67,12 +63,9 @@ describe Lita::Handlers::Authorization, lita_handler: true do
67
63
  expect(replies.last).to eq("#{target_user.name} was not in bar.")
68
64
  end
69
65
 
70
- it "replies with a warning if the requesting user is not an admin" do
71
- allow(Lita::Authorization).to receive(:user_is_admin?).with(
72
- user
73
- ).and_return(false)
74
- send_command("auth remove foo bar")
75
- expect(replies.last).to match(/Only administrators can remove/)
66
+ it %{replies with a warning if the group was "admins"} do
67
+ send_command("auth add foo admins")
68
+ expect(replies.last).to match(/Administrators can only be managed/)
76
69
  end
77
70
  end
78
71
 
@@ -5,6 +5,13 @@ describe Lita::Handlers::Help, lita_handler: true do
5
5
  it { routes_command("help foo").to(:help) }
6
6
 
7
7
  describe "#help" do
8
+ let(:secret_handler_class) do
9
+ Class.new(Lita::Handler) do
10
+ route(/secret/, :secret, restrict_to: :the_nobodies, help: {
11
+ "secret" => "no one should ever see this help message"
12
+ })
13
+ end
14
+ end
8
15
  it "sends help information for all commands" do
9
16
  send_command("help")
10
17
  expect(replies.last).to match(
@@ -17,5 +24,14 @@ describe Lita::Handlers::Help, lita_handler: true do
17
24
  expect(replies.last).to match(/help COMMAND - Lists/)
18
25
  expect(replies.last).not_to match(/help - Lists/)
19
26
  end
27
+
28
+ it "doesn't show help for commands the user doesn't have access to" do
29
+ allow(Lita).to receive(:handlers).and_return([
30
+ described_class,
31
+ secret_handler_class
32
+ ])
33
+ send_command("help")
34
+ expect(replies.last).not_to include("secret")
35
+ end
20
36
  end
21
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmy Cuadra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-31 00:00:00.000000000 Z
11
+ date: 2013-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - '>='
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: cane
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - '>='
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
181
195
  description: A multi-service chat bot with extendable behavior.
182
196
  email:
183
197
  - jimmy@jimmycuadra.com
@@ -207,7 +221,7 @@ files:
207
221
  - lib/lita/http_route.rb
208
222
  - lib/lita/logger.rb
209
223
  - lib/lita/message.rb
210
- - lib/lita/rack_app_builder.rb
224
+ - lib/lita/rack_app.rb
211
225
  - lib/lita/response.rb
212
226
  - lib/lita/robot.rb
213
227
  - lib/lita/rspec.rb