rita 0.1.0 → 5.0.0.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +19 -0
- data/.rubocop.yml +51 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +5 -0
- data/{LICENSE.txt → LICENSE} +1 -3
- data/README.md +17 -24
- data/Rakefile +5 -5
- data/bin/lita +7 -0
- data/lib/lita/adapter.rb +147 -0
- data/lib/lita/adapters/shell.rb +126 -0
- data/lib/lita/adapters/test.rb +62 -0
- data/lib/lita/authorization.rb +112 -0
- data/lib/lita/callback.rb +39 -0
- data/lib/lita/cli.rb +218 -0
- data/lib/lita/configurable.rb +47 -0
- data/lib/lita/configuration_builder.rb +247 -0
- data/lib/lita/configuration_validator.rb +95 -0
- data/lib/lita/default_configuration.rb +122 -0
- data/lib/lita/errors.rb +25 -0
- data/lib/lita/handler/chat_router.rb +141 -0
- data/lib/lita/handler/common.rb +208 -0
- data/lib/lita/handler/event_router.rb +84 -0
- data/lib/lita/handler/http_router.rb +31 -0
- data/lib/lita/handler.rb +15 -0
- data/lib/lita/handlers/authorization.rb +129 -0
- data/lib/lita/handlers/help.rb +171 -0
- data/lib/lita/handlers/info.rb +66 -0
- data/lib/lita/handlers/room.rb +36 -0
- data/lib/lita/handlers/users.rb +37 -0
- data/lib/lita/http_callback.rb +46 -0
- data/lib/lita/http_route.rb +83 -0
- data/lib/lita/logger.rb +43 -0
- data/lib/lita/message.rb +124 -0
- data/lib/lita/middleware_registry.rb +39 -0
- data/lib/lita/namespace.rb +29 -0
- data/lib/lita/plugin_builder.rb +43 -0
- data/lib/lita/rack_app.rb +100 -0
- data/lib/lita/registry.rb +164 -0
- data/lib/lita/response.rb +65 -0
- data/lib/lita/robot.rb +273 -0
- data/lib/lita/room.rb +119 -0
- data/lib/lita/route_validator.rb +82 -0
- data/lib/lita/rspec/handler.rb +127 -0
- data/lib/lita/rspec/matchers/chat_route_matcher.rb +53 -0
- data/lib/lita/rspec/matchers/event_route_matcher.rb +29 -0
- data/lib/lita/rspec/matchers/http_route_matcher.rb +34 -0
- data/lib/lita/rspec.rb +48 -0
- data/lib/lita/source.rb +81 -0
- data/lib/lita/store.rb +23 -0
- data/lib/lita/target.rb +3 -0
- data/lib/lita/template.rb +71 -0
- data/lib/lita/template_resolver.rb +52 -0
- data/lib/lita/timer.rb +49 -0
- data/lib/lita/user.rb +157 -0
- data/lib/lita/util.rb +31 -0
- data/lib/lita/version.rb +6 -0
- data/lib/lita.rb +166 -0
- data/lib/rita.rb +2 -7
- data/rita.gemspec +50 -0
- data/spec/lita/adapter_spec.rb +54 -0
- data/spec/lita/adapters/shell_spec.rb +99 -0
- data/spec/lita/authorization_spec.rb +122 -0
- data/spec/lita/configuration_builder_spec.rb +247 -0
- data/spec/lita/configuration_validator_spec.rb +114 -0
- data/spec/lita/default_configuration_spec.rb +242 -0
- data/spec/lita/handler/chat_router_spec.rb +236 -0
- data/spec/lita/handler/common_spec.rb +289 -0
- data/spec/lita/handler/event_router_spec.rb +121 -0
- data/spec/lita/handler/http_router_spec.rb +155 -0
- data/spec/lita/handler_spec.rb +62 -0
- data/spec/lita/handlers/authorization_spec.rb +111 -0
- data/spec/lita/handlers/help_spec.rb +124 -0
- data/spec/lita/handlers/info_spec.rb +67 -0
- data/spec/lita/handlers/room_spec.rb +24 -0
- data/spec/lita/handlers/users_spec.rb +35 -0
- data/spec/lita/logger_spec.rb +28 -0
- data/spec/lita/message_spec.rb +178 -0
- data/spec/lita/plugin_builder_spec.rb +41 -0
- data/spec/lita/response_spec.rb +62 -0
- data/spec/lita/robot_spec.rb +285 -0
- data/spec/lita/room_spec.rb +136 -0
- data/spec/lita/rspec/handler_spec.rb +33 -0
- data/spec/lita/rspec_spec.rb +162 -0
- data/spec/lita/source_spec.rb +68 -0
- data/spec/lita/store_spec.rb +23 -0
- data/spec/lita/template_resolver_spec.rb +42 -0
- data/spec/lita/template_spec.rb +52 -0
- data/spec/lita/timer_spec.rb +32 -0
- data/spec/lita/user_spec.rb +167 -0
- data/spec/lita/util_spec.rb +18 -0
- data/spec/lita_spec.rb +227 -0
- data/spec/spec_helper.rb +35 -0
- data/spec/templates/basic.erb +1 -0
- data/spec/templates/basic.irc.erb +1 -0
- data/spec/templates/helpers.erb +1 -0
- data/spec/templates/interpolated.erb +1 -0
- data/templates/locales/en.yml +137 -0
- data/templates/plugin/Gemfile +5 -0
- data/templates/plugin/README.tt +29 -0
- data/templates/plugin/Rakefile +8 -0
- data/templates/plugin/gemspec.tt +27 -0
- data/templates/plugin/gitignore +18 -0
- data/templates/plugin/lib/lita/plugin_type/plugin.tt +19 -0
- data/templates/plugin/lib/plugin.tt +16 -0
- data/templates/plugin/locales/en.yml.tt +4 -0
- data/templates/plugin/spec/lita/plugin_type/plugin_spec.tt +6 -0
- data/templates/plugin/spec/spec_helper.tt +8 -0
- data/templates/plugin/templates/gitkeep +0 -0
- data/templates/robot/Gemfile +5 -0
- data/templates/robot/lita_config.rb +28 -0
- metadata +386 -20
- data/.standard.yml +0 -3
- data/CHANGELOG.md +0 -5
- data/CODE_OF_CONDUCT.md +0 -132
- data/lib/rita/version.rb +0 -5
- data/sig/rita.rbs +0 -4
data/lib/lita.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
require "i18n"
|
6
|
+
require "i18n/backend/fallbacks"
|
7
|
+
require "redis-namespace"
|
8
|
+
|
9
|
+
require_relative "lita/configuration_builder"
|
10
|
+
require_relative "lita/configuration_validator"
|
11
|
+
require_relative "lita/errors"
|
12
|
+
require_relative "lita/logger"
|
13
|
+
require_relative "lita/registry"
|
14
|
+
require_relative "lita/robot"
|
15
|
+
|
16
|
+
# The main namespace for Lita. Provides a global registry of adapters and
|
17
|
+
# handlers, as well as global configuration, logger, and Redis store.
|
18
|
+
module Lita
|
19
|
+
class << self
|
20
|
+
include Registry::Mixins
|
21
|
+
|
22
|
+
# A mode that makes minor changes to the Lita runtime to improve testability.
|
23
|
+
# @return [Boolean] Whether or not test mode is active.
|
24
|
+
# @since 4.0.0
|
25
|
+
attr_reader :test_mode
|
26
|
+
alias test_mode? test_mode
|
27
|
+
|
28
|
+
# Sets both I18n.default_locale and I18n.locale to the provided locale, if any.
|
29
|
+
# @api private
|
30
|
+
# @since 5.0.0
|
31
|
+
def configure_i18n(new_locale)
|
32
|
+
unless new_locale.nil?
|
33
|
+
self.default_locale = new_locale
|
34
|
+
self.locale = new_locale
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Lita's global +Logger+.
|
39
|
+
#
|
40
|
+
# The log level is initially set according to the environment variable +LITA_LOG+, defaulting to
|
41
|
+
# +info+ if the variable is not set. Once the user configuration is loaded, the log level will
|
42
|
+
# be reset to whatever is specified in the configuration file.
|
43
|
+
# @return [::Logger] A +Logger+ object.
|
44
|
+
def logger
|
45
|
+
@logger ||= Logger.get_logger(
|
46
|
+
ENV["LITA_LOG"],
|
47
|
+
io: test_mode? ? StringIO.new : $stderr,
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Adds one or more paths to the I18n load path and reloads I18n.
|
52
|
+
# @param paths [String, Array<String>] The path(s) to add.
|
53
|
+
# @return [void]
|
54
|
+
# @since 3.0.0
|
55
|
+
def load_locales(paths)
|
56
|
+
I18n.load_path.concat(Array(paths))
|
57
|
+
I18n.reload!
|
58
|
+
end
|
59
|
+
|
60
|
+
# Sets +I18n.locale+, normalizing the provided locale name.
|
61
|
+
#
|
62
|
+
# Note that setting this only affects the current thread. Since handler
|
63
|
+
# methods are dispatched in new threads, changing the locale globally will
|
64
|
+
# require calling this method at the start of every handler method.
|
65
|
+
# Alternatively, use {Lita#default_locale=} which will affect all threads.
|
66
|
+
# @param new_locale [Symbol, String] The code of the locale to use.
|
67
|
+
# @return [void]
|
68
|
+
# @since 3.0.0
|
69
|
+
def locale=(new_locale)
|
70
|
+
I18n.locale = new_locale.to_s.tr("_", "-")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets +I18n.default_locale+, normalizing the provided locale name.
|
74
|
+
#
|
75
|
+
# This is preferred over {Lita#locale=} as it affects all threads.
|
76
|
+
# @param new_locale [Symbol, String] The code of the locale to use.
|
77
|
+
# @return [void]
|
78
|
+
# @since 4.8.0
|
79
|
+
def default_locale=(new_locale)
|
80
|
+
I18n.default_locale = new_locale.to_s.tr("_", "-")
|
81
|
+
end
|
82
|
+
|
83
|
+
# The absolute path to Lita's templates directory.
|
84
|
+
# @return [String] The path.
|
85
|
+
# @since 3.0.0
|
86
|
+
def template_root
|
87
|
+
File.expand_path("../templates", __dir__)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Loads user configuration.
|
91
|
+
# @param config_path [String] The path to the user configuration file.
|
92
|
+
# @return [void]
|
93
|
+
def load_config(config_path = nil)
|
94
|
+
hooks[:before_run].each { |hook| hook.call(config_path: config_path) }
|
95
|
+
ConfigurationBuilder.load_user_config(config_path)
|
96
|
+
ConfigurationBuilder.freeze_config(config)
|
97
|
+
recreate_logger # Pick up value of `config.robot.log_level` and `config.robot.log_formatter`.
|
98
|
+
ConfigurationValidator.new(self).call
|
99
|
+
hooks[:config_finalized].each { |hook| hook.call(config_path: config_path) }
|
100
|
+
|
101
|
+
if config.robot.default_locale || config.robot.locale
|
102
|
+
logger.warn I18n.t("lita.config.locale_deprecated")
|
103
|
+
self.default_locale = config.robot.default_locale if config.robot.default_locale
|
104
|
+
self.locale = config.robot.locale if config.robot.locale
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Loads user configuration and starts the robot.
|
109
|
+
# @param config_path [String] The path to the user configuration file.
|
110
|
+
# @return [void]
|
111
|
+
def run(config_path = nil)
|
112
|
+
load_config(config_path)
|
113
|
+
Robot.new.run
|
114
|
+
end
|
115
|
+
|
116
|
+
# Turns test mode on or off.
|
117
|
+
# @param mode [Boolean] Whether or not test mode should be enabled.
|
118
|
+
# @return [void]
|
119
|
+
# @see #test_mode
|
120
|
+
def test_mode=(mode)
|
121
|
+
@test_mode = mode
|
122
|
+
# Reset the logger because its IO stream is determined by test mode.
|
123
|
+
recreate_logger
|
124
|
+
end
|
125
|
+
|
126
|
+
# A special mode to ensure that tests written for Lita 3 plugins continue to work. Has no effect
|
127
|
+
# in Lita 5+.
|
128
|
+
# @return [Boolean] Whether or not version 3 compatibility mode is active.
|
129
|
+
# @since 4.0.0
|
130
|
+
# @deprecated Will be removed in Lita 6.0.
|
131
|
+
def version_3_compatibility_mode(_value = nil)
|
132
|
+
warn I18n.t("lita.rspec.lita_3_compatibility_mode")
|
133
|
+
false
|
134
|
+
end
|
135
|
+
alias version_3_compatibility_mode? version_3_compatibility_mode
|
136
|
+
alias version_3_compatibility_mode= version_3_compatibility_mode
|
137
|
+
|
138
|
+
private
|
139
|
+
|
140
|
+
# Recreate the logger, specifying the configured log level and output stream. Should be called
|
141
|
+
# manually after user configuration has been loaded and whenever test mode is changed. This is
|
142
|
+
# necessary because {#logger} does not access the config so as not to accidentally build the
|
143
|
+
# {DefaultConfiguration} before all plugins have been loaded and registered.
|
144
|
+
def recreate_logger
|
145
|
+
@logger = Logger.get_logger(
|
146
|
+
config.robot.log_level,
|
147
|
+
formatter: config.robot.log_formatter,
|
148
|
+
io: test_mode? ? StringIO.new : $stderr,
|
149
|
+
)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
I18n::Backend::Simple.include(I18n::Backend::Fallbacks)
|
155
|
+
I18n.enforce_available_locales = false
|
156
|
+
Lita.load_locales(Dir[File.join(Lita.template_root, "locales", "*.yml")])
|
157
|
+
Lita.configure_i18n(ENV["LC_ALL"] || ENV["LC_MESSAGES"] || ENV["LANG"])
|
158
|
+
|
159
|
+
require_relative "lita/adapters/shell"
|
160
|
+
require_relative "lita/adapters/test"
|
161
|
+
|
162
|
+
require_relative "lita/handlers/authorization"
|
163
|
+
require_relative "lita/handlers/help"
|
164
|
+
require_relative "lita/handlers/info"
|
165
|
+
require_relative "lita/handlers/room"
|
166
|
+
require_relative "lita/handlers/users"
|
data/lib/rita.rb
CHANGED
data/rita.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "lita/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "rita"
|
9
|
+
spec.version = Lita::VERSION
|
10
|
+
spec.authors = ["Jimmy Cuadra"]
|
11
|
+
spec.email = ["jimmy@jimmycuadra.com"]
|
12
|
+
spec.description = "ChatOps for Ruby."
|
13
|
+
spec.summary = "ChatOps framework for Ruby. Rita is a robot companion for your chat room."
|
14
|
+
spec.homepage = "https://github.com/ritaio/rita"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files`.split($/)
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.required_ruby_version = ">= 3.0.0"
|
23
|
+
|
24
|
+
spec.metadata = {
|
25
|
+
"bug_tracker_uri" => "https://github.com/ritaio/rita/issues",
|
26
|
+
"changelog_uri" => "https://github.com/ritaio/rita/releases",
|
27
|
+
# "documentation_uri" => "https://docs.lita.io/",
|
28
|
+
# "homepage_uri" => "https://www.lita.io/",
|
29
|
+
# "mailing_list_uri" => "https://groups.google.com/group/litaio",
|
30
|
+
"source_code_uri" => "https://github.com/ritaio/rita",
|
31
|
+
}
|
32
|
+
|
33
|
+
spec.add_runtime_dependency "bundler"
|
34
|
+
spec.add_runtime_dependency "faraday", "~> 1.6.0"
|
35
|
+
spec.add_runtime_dependency "http_router", "~> 0.11.2"
|
36
|
+
spec.add_runtime_dependency "i18n", "~> 1.8.10"
|
37
|
+
spec.add_runtime_dependency "ice_nine", "~> 0.11.2"
|
38
|
+
spec.add_runtime_dependency "puma", "~> 5.4.0"
|
39
|
+
spec.add_runtime_dependency "rack", "~> 2.2.3"
|
40
|
+
spec.add_runtime_dependency "rb-readline", "~> 0.5.5"
|
41
|
+
spec.add_runtime_dependency "redis-namespace", "~> 1.8.1"
|
42
|
+
spec.add_runtime_dependency "thor", "~> 1.1.0"
|
43
|
+
|
44
|
+
spec.add_development_dependency "pry-byebug", "~> 3.9.0"
|
45
|
+
spec.add_development_dependency "rack-test", "~> 1.1.0"
|
46
|
+
spec.add_development_dependency "rake", "~> 13.0.3"
|
47
|
+
spec.add_development_dependency "rspec", "~> 3.10.0"
|
48
|
+
spec.add_development_dependency "rubocop", "~> 1.17.0"
|
49
|
+
spec.add_development_dependency "simplecov", "~> 0.21.2"
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Lita::Adapter, lita: true do
|
6
|
+
let(:robot) { Lita::Robot.new(registry) }
|
7
|
+
|
8
|
+
let(:required_methods) { described_class::REQUIRED_METHODS }
|
9
|
+
|
10
|
+
subject { described_class.new(robot) }
|
11
|
+
|
12
|
+
it "stores a Robot" do
|
13
|
+
expect(subject.robot).to eql(robot)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "logs a warning if a required method has not been implemented" do
|
17
|
+
expect(robot.logger).to receive(:warn).exactly(required_methods.size).times
|
18
|
+
required_methods.each do |method|
|
19
|
+
subject.public_send(method)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#config" do
|
24
|
+
let(:adapter) do
|
25
|
+
Class.new(described_class) do
|
26
|
+
namespace "test"
|
27
|
+
|
28
|
+
config :foo, default: :bar
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:robot) { Lita::Robot.new(registry) }
|
33
|
+
|
34
|
+
before { registry.register_adapter(:test, adapter) }
|
35
|
+
|
36
|
+
subject { adapter.new(robot) }
|
37
|
+
|
38
|
+
it "provides access to the adapter's configuration object" do
|
39
|
+
expect(subject.config.foo).to eq(:bar)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#log" do
|
44
|
+
it "returns the robot's logger" do
|
45
|
+
expect(subject.log).to eq(robot.logger)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#mention_format" do
|
50
|
+
it "formats the provided name for mentioning the user" do
|
51
|
+
expect(subject.mention_format("carl")).to eq("carl:")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Lita::Adapters::Shell, lita: true do
|
6
|
+
let(:robot) do
|
7
|
+
instance_double(
|
8
|
+
"Lita::Robot",
|
9
|
+
name: "Lita",
|
10
|
+
mention_name: "LitaBot",
|
11
|
+
alias: "/",
|
12
|
+
config: registry.config
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
subject { described_class.new(robot) }
|
17
|
+
|
18
|
+
describe "#roster" do
|
19
|
+
let(:room) { instance_double("Lita::Room") }
|
20
|
+
|
21
|
+
it "returns the shell user" do
|
22
|
+
expect(subject.roster(room).first.name).to eq("Shell User")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#run" do
|
27
|
+
let(:user) { Lita::User.create(1, name: "Shell User") }
|
28
|
+
|
29
|
+
before do
|
30
|
+
registry.register_adapter(:shell, described_class)
|
31
|
+
allow(subject).to receive(:puts)
|
32
|
+
allow(Readline).to receive(:readline).and_return("foo", "exit")
|
33
|
+
allow(robot).to receive(:trigger)
|
34
|
+
allow(robot).to receive(:receive)
|
35
|
+
allow(Lita::User).to receive(:create).and_return(user)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "passes input to the Robot and breaks on an exit message" do
|
39
|
+
expect(Readline).to receive(:readline).with("#{robot.name} > ", true).twice
|
40
|
+
expect(robot).to receive(:receive).with(an_instance_of(Lita::Message))
|
41
|
+
subject.run
|
42
|
+
end
|
43
|
+
|
44
|
+
it "marks messages as commands if config.adapters.shell.private_chat is true" do
|
45
|
+
registry.config.adapters.shell.private_chat = true
|
46
|
+
expect_any_instance_of(Lita::Message).to receive(:command!)
|
47
|
+
subject.run
|
48
|
+
end
|
49
|
+
|
50
|
+
it "sets the room to 'shell' if config.adapters.shell.private_chat is false" do
|
51
|
+
registry.config.adapters.shell.private_chat = false
|
52
|
+
expect(Lita::Source).to receive(:new).with(user: user, room: "shell")
|
53
|
+
subject.run
|
54
|
+
end
|
55
|
+
|
56
|
+
it "sets the room to nil if config.adapters.shell.private_chat is true" do
|
57
|
+
registry.config.adapters.shell.private_chat = true
|
58
|
+
expect(Lita::Source).to receive(:new).with(user: user, room: nil)
|
59
|
+
subject.run
|
60
|
+
end
|
61
|
+
|
62
|
+
it "triggers a connected event" do
|
63
|
+
expect(robot).to receive(:trigger).with(:connected)
|
64
|
+
subject.run
|
65
|
+
end
|
66
|
+
|
67
|
+
it "exits cleanly when EOF is received" do
|
68
|
+
allow(Readline).to receive(:readline).and_return(nil)
|
69
|
+
subject.run
|
70
|
+
end
|
71
|
+
|
72
|
+
it "removes empty input from readline history" do
|
73
|
+
allow(Readline).to receive(:readline).and_return("", "exit")
|
74
|
+
expect(Readline::HISTORY).to receive(:pop)
|
75
|
+
subject.run
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#send_message" do
|
80
|
+
it "prints its input" do
|
81
|
+
expect(subject).to receive(:puts) do |messages|
|
82
|
+
expect(messages.first).to include("bar")
|
83
|
+
end
|
84
|
+
subject.send_messages(instance_double("Lita::Source"), "bar")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "doesn't output empty messages" do
|
88
|
+
expect(subject).to receive(:puts).with([])
|
89
|
+
subject.send_messages(instance_double("Lita::Source"), "")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "#shut_down" do
|
94
|
+
it "outputs a blank line" do
|
95
|
+
expect(subject).to receive(:puts)
|
96
|
+
subject.shut_down
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Lita::Authorization, lita: true do
|
6
|
+
let(:requesting_user) { instance_double("Lita::User", id: "1") }
|
7
|
+
let(:robot) { Lita::Robot.new(registry) }
|
8
|
+
let(:user) { instance_double("Lita::User", id: "2") }
|
9
|
+
|
10
|
+
subject { described_class.new(robot) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
registry.config.robot.admins = ["1"]
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#add_user_to_group" do
|
17
|
+
it "adds users to an auth group" do
|
18
|
+
subject.add_user_to_group(requesting_user, user, "employees")
|
19
|
+
expect(subject.user_in_group?(user, "employees")).to be true
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can only be called by admins" do
|
23
|
+
registry.config.robot.admins = nil
|
24
|
+
result = subject.add_user_to_group(
|
25
|
+
requesting_user,
|
26
|
+
user,
|
27
|
+
"employees"
|
28
|
+
)
|
29
|
+
expect(result).to eq(:unauthorized)
|
30
|
+
expect(subject.user_in_group?(user, "employees")).to be false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "normalizes the group name" do
|
34
|
+
subject.add_user_to_group(requesting_user, user, "eMPLoYeeS")
|
35
|
+
expect(subject.user_in_group?(user, " EmplOyEEs ")).to be true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#remove_user_from_group" do
|
40
|
+
it "removes users from an auth group" do
|
41
|
+
subject.add_user_to_group(requesting_user, user, "employees")
|
42
|
+
subject.remove_user_from_group(requesting_user, user, "employees")
|
43
|
+
expect(subject.user_in_group?(user, "employees")).to be false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "can only be called by admins" do
|
47
|
+
subject.add_user_to_group(requesting_user, user, "employees")
|
48
|
+
registry.config.robot.admins = nil
|
49
|
+
result = subject.remove_user_from_group(
|
50
|
+
requesting_user,
|
51
|
+
user,
|
52
|
+
"employees"
|
53
|
+
)
|
54
|
+
expect(result).to eq(:unauthorized)
|
55
|
+
expect(subject.user_in_group?(user, "employees")).to be true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "normalizes the group name" do
|
59
|
+
subject.add_user_to_group(requesting_user, user, "eMPLoYeeS")
|
60
|
+
subject.remove_user_from_group(requesting_user, user, "EmployeeS")
|
61
|
+
expect(subject.user_in_group?(user, " EmplOyEEs ")).to be false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#user_in_group?" do
|
66
|
+
it "returns false if the user is in the group" do
|
67
|
+
expect(subject.user_in_group?(user, "employees")).to be false
|
68
|
+
end
|
69
|
+
|
70
|
+
it "delegates to .user_is_admin? if the group is admins" do
|
71
|
+
expect(subject).to receive(:user_is_admin?)
|
72
|
+
subject.user_in_group?(user, "admins")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#user_is_admin?" do
|
77
|
+
it "returns true if the user's ID is in the config" do
|
78
|
+
expect(subject.user_is_admin?(requesting_user)).to be true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns false if the user's ID is not in the config" do
|
82
|
+
registry.config.robot.admins = nil
|
83
|
+
expect(subject.user_is_admin?(user)).to be false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#groups" do
|
88
|
+
before do
|
89
|
+
%i[foo bar baz].each do |group|
|
90
|
+
subject.add_user_to_group(requesting_user, user, group)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns a list of all authorization groups" do
|
95
|
+
expect(subject.groups).to match_array(%i[foo bar baz])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#groups_with_users" do
|
100
|
+
before do
|
101
|
+
%i[foo bar baz].each do |group|
|
102
|
+
subject.add_user_to_group(requesting_user, user, group)
|
103
|
+
subject.add_user_to_group(
|
104
|
+
requesting_user,
|
105
|
+
requesting_user,
|
106
|
+
group
|
107
|
+
)
|
108
|
+
end
|
109
|
+
allow(Lita::User).to receive(:find_by_id).with("1").and_return(requesting_user)
|
110
|
+
allow(Lita::User).to receive(:find_by_id).with("2").and_return(user)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns a hash of all authorization groups and their members" do
|
114
|
+
groups = %i[foo bar baz]
|
115
|
+
groups_with_users = subject.groups_with_users
|
116
|
+
expect(groups_with_users.keys).to match_array(groups)
|
117
|
+
groups.each do |group|
|
118
|
+
expect(groups_with_users[group]).to match_array([user, requesting_user])
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|