lita 2.2.0 → 2.2.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 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