pepito 0.0.2 → 0.0.3

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: b765db41f66cec333a433f4af03b7d0027174402
4
- data.tar.gz: 22d589c8034f06dd5b86a554c0e54ac93d548aa7
3
+ metadata.gz: 6df931c406711b8ff0167baf10b00cc7bc8142ff
4
+ data.tar.gz: 396e1fc731cd469d9c56034f65e8dbb93c23aa7e
5
5
  SHA512:
6
- metadata.gz: d0a1cd4baab73d27ce0d0b1293d72543fd2664de1e9a7d438ce27b96e4b1d3feb3006bae8647fca5fa2761bacd0e1a32ff01af2233e232d55ea9486363be1eef
7
- data.tar.gz: 8ba4898f785b4d9e1f4990496167d22707476202e2b88550fc67f6c4b833f53d3a2f0fff2cef622ad37cee1582cf1fff9887b9431cabfbad3106ff092d52f382
6
+ metadata.gz: 25aa6bacb406a0d808510575aac07daf714bc747c517b1b001267a24f8aeb5d129821863271c24b4d6c39d2166d96ef85f97343c27e9ac9b38414c02c4e7f693
7
+ data.tar.gz: 36c9d51a7a2538a36229018e9f4448444aa7ae76c080f714ad6c83dc60c602533f0dc0b8d53b5a05d44b6b7d6a0e09598bd593ca01399d2c279d1bec52b7dfd0
data/Gemfile CHANGED
@@ -1,3 +1,6 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
+ # gem 'pepito-queenbee', path: '../pepito-queenbee'
4
+ gem 'queenbee', '~> 0.0.5'
5
+
3
6
  gemspec
@@ -1,4 +1,5 @@
1
1
  module Pepito
2
+ # Adapters module placeholder, required to use const_get because we have no default adapters
2
3
  module Adapters
3
4
  end
4
5
  end
@@ -8,15 +8,35 @@ module Pepito
8
8
  include Handler::HTTPRouter
9
9
  include Handler::ChatRouter
10
10
 
11
+ class << self
12
+ # Configs for the handler, method should be overriden in the handler if
13
+ # parameters are necessary
14
+ # @return [Array<Hash>] Array of hashes with the config parameters
15
+ def configs
16
+ [{}]
17
+ end
18
+ end
19
+
11
20
  # Currently running robot
12
21
  # @return [Pepito::Robot]
13
22
  attr_reader :robot
14
23
 
24
+ # Config
25
+ # @return [Hash<>]
26
+ attr_reader :config
27
+
15
28
  # Initializes the Adapter class
16
29
  # @param robot [Pepito::Robot] The currently running robot
17
30
  # @return [void]
18
- def initialize(robot)
31
+ def initialize(robot, config)
19
32
  @robot = robot
33
+ @config = config
34
+
35
+ begin
36
+ missing_configuration_values
37
+ rescue => e
38
+ raise e
39
+ end
20
40
  end
21
41
 
22
42
  # Starts the handler
@@ -34,5 +54,22 @@ module Pepito
34
54
  @robot.http_api.router.add_route(route.route)
35
55
  end if @http_routes
36
56
  end
57
+
58
+ # Check whether all required configuration values exist
59
+ # Raises a [Pepito::Errors::MissingConfigurationValueError] if methods are missing
60
+ # @return [void]
61
+ def missing_configuration_values
62
+ confs = []
63
+ self.class.configs.each do |c|
64
+ confs << c[:name] if c[:required] && !configuration_value?(c[:name])
65
+ end
66
+ raise Errors::MissingConfigurationValueError.new(confs), 'missing required configuration values' unless confs.empty?
67
+ end
68
+
69
+ # Whether a configuration_value is present or not.
70
+ # @return [Boolean] True if is present, False otherwise.
71
+ def configuration_value?(name)
72
+ !@config.nil? && @config.keys.include?(name) && !@config[name].nil? && !@config[name].empty?
73
+ end
37
74
  end
38
75
  end
@@ -0,0 +1,45 @@
1
+ require 'rubygems/dependency_installer'
2
+ require 'rubygems/uninstaller'
3
+
4
+ module Pepito
5
+ # Class with helper functions
6
+ module Helpers
7
+ # Method to install gem
8
+ # @param gem_name[String]
9
+ # @return void
10
+ def gem_install(gem_name)
11
+ inst = Gem::DependencyInstaller.new
12
+ inst.install gem_name
13
+ require gem_name
14
+ rescue => e
15
+ raise e
16
+ end
17
+
18
+ def gem_uninstall(gem_name)
19
+ uninst = Gem::Uninstaller.new gem_name
20
+ uninst.uninstall
21
+ rescue => e
22
+ raise e
23
+ end
24
+
25
+ def gem_installed?(gem_name)
26
+ Gem::Specification.find_by_name gem_name
27
+ return true
28
+ rescue LoadError
29
+ return false
30
+ end
31
+
32
+ def gem_load(gem_name)
33
+ if gem_installed?(gem_name)
34
+ require gem_name
35
+ else
36
+ begin
37
+ gem_install gem_name
38
+ require gem_name
39
+ rescue => e
40
+ raise e
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,21 +2,27 @@ require 'logger'
2
2
  require 'puma'
3
3
  require 'rubygems'
4
4
  require 'rubygems/dependency_installer'
5
+ require 'rest-client'
6
+ require 'multi_json'
5
7
 
6
8
  require_relative 'http_api/rack_app'
7
9
  require_relative 'web_app/app'
8
10
  require_relative 'handlers/info'
9
11
  require_relative 'handlers/extensions_catalog'
10
12
  require_relative 'handlers/help'
13
+ require_relative 'handlers/queenbee'
11
14
  require_relative 'handlers/room'
12
15
  require_relative 'database'
13
16
  require_relative 'adapters'
17
+ require_relative 'helpers'
14
18
  require_relative 'errors/required_methods_error'
15
19
  require_relative 'errors/missing_configuration_value_error'
16
20
 
17
21
  module Pepito
18
22
  # The robot component of the bot.
19
23
  class Robot
24
+ include Pepito::Helpers
25
+
20
26
  # The running http_api.
21
27
  # @return [Pepito::HTTPApi::RackApp]
22
28
  attr_reader :http_api
@@ -80,7 +86,7 @@ module Pepito
80
86
 
81
87
  @web_app = WebApp::App
82
88
 
83
- @default_handlers = %w(Info Help Room)
89
+ @default_handlers = %w(Info Help Room ExtensionsCatalog Queenbee)
84
90
  @handlers = {}
85
91
 
86
92
  @default_adapters = []
@@ -122,24 +128,19 @@ module Pepito
122
128
  # Retrieve the list of possible handlers to install from server
123
129
  # @return [Array<String>]
124
130
  def handlers_list
125
- %w(Info Help ExtensionsCatalog Room)
131
+ catalog_url = 'https://raw.githubusercontent.com/yafoy/pepito-catalog/master/all.json'
132
+ response = RestClient.get(catalog_url)
133
+ integrations = MultiJson.load(response.body, symbolize_keys: true)
134
+ integrations[:handlers]
126
135
  end
127
136
 
128
137
  # Retrieve the list of possible adapters to install from server
129
138
  # @return [Array<String>]
130
139
  def adapters_list
131
- [
132
- {
133
- name: 'Slack',
134
- gem: 'pepito-slack',
135
- configs: [
136
- {
137
- name: 'SLACK_API_TOKEN',
138
- required: true
139
- }
140
- ]
141
- }
142
- ]
140
+ catalog_url = 'https://raw.githubusercontent.com/yafoy/pepito-catalog/master/all.json'
141
+ response = RestClient.get(catalog_url)
142
+ integrations = MultiJson.load(response.body, symbolize_keys: true)
143
+ integrations[:adapters]
143
144
  end
144
145
 
145
146
  # Starts an handler.
@@ -148,27 +149,46 @@ module Pepito
148
149
  # 0 - If success
149
150
  # 1 - If failed because handler is already running
150
151
  # 2 - If handler can't be found
151
- # 3 - Other errors
152
- def start_handler(handler)
152
+ # 3 - If handler is missing configuration values
153
+ # 4 - Other errors
154
+ def start_handler(handler, gem_name, config)
153
155
  @logger.info('"' + handler.to_s + '" handler starting')
154
156
  if @handlers.key?(handler)
155
157
  @logger.warn('"' + handler.to_s + '" handler is already running')
156
158
  return 1
157
159
  else
160
+ # Installing gem
161
+ begin
162
+ gem_load gem_name
163
+ rescue => e
164
+ @logger.error(e)
165
+ return 2
166
+ end
167
+
158
168
  begin
159
- @handlers[handler] = Handlers.const_get(handler).new(self)
169
+ @handlers[handler] = Handlers.const_get(handler).new(self, config)
160
170
  rescue NameError
161
171
  @logger.error('"' + handler.to_s + '" handler does not exist')
162
172
  return 2
173
+ rescue Pepito::Errors::MissingConfigurationValueError => e
174
+ @logger.error('"' + handler.to_s + '" handler failed to start. ' + e.message + ': ' + e.configuration_values.to_s)
175
+ return 3
163
176
  rescue => e
164
177
  @logger.error('"' + handler.to_s + '" handler failed to start. Error: ' + e.message.to_s)
165
178
  @logger.error(e)
166
- return 3
179
+ return 4
167
180
  end
181
+
168
182
  @http_api.router.uncompile
169
183
  @handlers[handler].run
170
184
  @handlers[handler].start
171
185
  @database.sadd('handlers', handler)
186
+ @database.set(handler + ':gem', gem_name)
187
+ # Setup new config in database
188
+ config.each do |key, value|
189
+ @database.hset(handler + ':config', key, value)
190
+ end
191
+
172
192
  @logger.info('"' + handler.to_s + '" handler started successfully')
173
193
  return 0
174
194
  end
@@ -191,6 +211,8 @@ module Pepito
191
211
  else
192
212
  @handlers.delete(handler)
193
213
  @database.srem('handlers', handler)
214
+ @database.del(handler + ':config')
215
+ @database.del(handler + ':gem')
194
216
  @http_api.router.reset!
195
217
  @handlers.each do |_, h|
196
218
  h.start
@@ -224,17 +246,12 @@ module Pepito
224
246
  @logger.warn('"' + adapter.to_s + '" adapter already running')
225
247
  return 1
226
248
  else
249
+ # Installing gem
227
250
  begin
228
- require gem_name
229
- rescue LoadError
230
- begin
231
- inst = Gem::DependencyInstaller.new
232
- inst.install gem_name
233
- require gem_name
234
- rescue => e
235
- @logger.error(e)
236
- return 2
237
- end
251
+ gem_load gem_name
252
+ rescue => e
253
+ @logger.error(e)
254
+ return 2
238
255
  end
239
256
 
240
257
  begin
@@ -343,11 +360,11 @@ module Pepito
343
360
  def run_handlers
344
361
  @logger.info('Starting the handlers')
345
362
  @default_handlers.each do |handler|
346
- start_handler(handler)
363
+ start_handler(handler, 'pepito', [])
347
364
  end
348
365
 
349
366
  @database.smembers('handlers').each do |handler|
350
- start_handler(handler) unless @default_handlers.include?(handler)
367
+ start_handler(handler, @database.get(handler + ':gem'), @database.hgetall(handler + ':config')) unless @default_handlers.include?(handler)
351
368
  end
352
369
  end
353
370
 
@@ -1,4 +1,4 @@
1
1
  module Pepito
2
2
  # The current version of Pepito
3
- VERSION = '0.0.2'.freeze
3
+ VERSION = '0.0.3'.freeze
4
4
  end
@@ -1,14 +1,33 @@
1
1
  require 'sinatra/base'
2
2
  require 'tilt/erb'
3
+ require 'rest-client'
4
+
5
+ require_relative '../helpers'
3
6
 
4
7
  module Pepito
5
8
  module WebApp
6
9
  # Web App to control the bot
7
10
  class App < Sinatra::Base
11
+ include Pepito::Helpers
12
+
8
13
  get '/' do
9
14
  @handlers = settings.robot.handlers_list
15
+ @handlers.each do |h|
16
+ if gem_installed?(h[:gem])
17
+ gem_load h[:gem]
18
+ h[:configs] = Pepito::Handlers.const_get(h[:name].to_s).configs
19
+ end
20
+ end
21
+
10
22
  @adapters = settings.robot.adapters_list
11
- erb :index
23
+ @adapters.each do |a|
24
+ if gem_installed?(a[:gem].to_s)
25
+ gem_load a[:gem].to_s
26
+ a[:configs] = Pepito::Adapters.const_get(a[:name].to_s).configs
27
+ end
28
+ end
29
+
30
+ erb :index, layout: :layout
12
31
  end
13
32
 
14
33
  post '/deactivate/handler/:handler' do
@@ -17,7 +36,13 @@ module Pepito
17
36
  end
18
37
 
19
38
  post '/activate/handler/:handler' do
20
- settings.robot.start_handler(params['handler'])
39
+ c = {}
40
+ params.each do |key, value|
41
+ if key.start_with?(params['handler'] + ':config:')
42
+ c[key.split(params['handler'] + ':config:')[1]] = value
43
+ end
44
+ end
45
+ settings.robot.start_handler(params['handler'], params[params['handler'] + ':gem_name'], c)
21
46
  redirect to('/')
22
47
  end
23
48
 
@@ -36,6 +61,28 @@ module Pepito
36
61
  settings.robot.start_adapter(params['adapter'], params[params['adapter'] + ':gem_name'], c)
37
62
  redirect to('/')
38
63
  end
64
+
65
+ post '/install/:gem' do
66
+ gem_install params['gem']
67
+ redirect to('/')
68
+ end
69
+
70
+ post '/uninstall/:gem' do
71
+ gem_uninstall params['gem']
72
+ redirect to('/')
73
+ end
74
+
75
+ get '/integrations' do
76
+ begin
77
+ catalog_url = 'https://raw.githubusercontent.com/yafoy/pepito-catalog/master/all.json'
78
+ response = RestClient.get(catalog_url)
79
+ @integrations = JSON.parse response.body
80
+ rescue RestClient::ExceptionWithResponse => err
81
+ err.response
82
+ @integrations = []
83
+ end
84
+ erb :integrations, layout: :layout
85
+ end
39
86
  end
40
87
  end
41
88
  end
@@ -0,0 +1 @@
1
+ body{margin:0}aside,details,main,summary{display:block}template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}.grd{padding-left:1rem;padding-right:1rem}.grd-row{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-width:100%}.grd-row-col-1-6{max-width:16.66667%;-webkit-flex-basis:16.66667%;-ms-flex-preferred-size:16.66667%;flex-basis:16.66667%}.grd-row-col-2-6{max-width:33.33333%;-webkit-flex-basis:33.33333%;-ms-flex-preferred-size:33.33333%;flex-basis:33.33333%}.grd-row-col-3-6{max-width:50%;-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%}.grd-row-col-4-6{max-width:66.66667%;-webkit-flex-basis:66.66667%;-ms-flex-preferred-size:66.66667%;flex-basis:66.66667%}.grd-row-col-5-6{max-width:83.33333%;-webkit-flex-basis:83.33333%;-ms-flex-preferred-size:83.33333%;flex-basis:83.33333%}.grd-row-col-6{max-width:100%;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%}.grd-row-col-1-6,.grd-row-col-1-6--lg,.grd-row-col-1-6--md,.grd-row-col-1-6--sm,.grd-row-col-2-6,.grd-row-col-2-6--lg,.grd-row-col-2-6--md,.grd-row-col-2-6--sm,.grd-row-col-3-6,.grd-row-col-3-6--lg,.grd-row-col-3-6--md,.grd-row-col-3-6--sm,.grd-row-col-4-6,.grd-row-col-4-6--lg,.grd-row-col-4-6--md,.grd-row-col-4-6--sm,.grd-row-col-5-6,.grd-row-col-5-6--lg,.grd-row-col-5-6--md,.grd-row-col-5-6--sm,.grd-row-col-6,.grd-row-col-6--lg,.grd-row-col-6--md,.grd-row-col-6--sm{-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;box-sizing:border-box}.grd-row-col-1-6--lg,.grd-row-col-1-6--md,.grd-row-col-1-6--sm,.grd-row-col-2-6--lg,.grd-row-col-2-6--md,.grd-row-col-2-6--sm,.grd-row-col-3-6--lg,.grd-row-col-3-6--md,.grd-row-col-3-6--sm,.grd-row-col-4-6--lg,.grd-row-col-4-6--md,.grd-row-col-4-6--sm,.grd-row-col-5-6--lg,.grd-row-col-5-6--md,.grd-row-col-5-6--sm,.grd-row-col-6--lg,.grd-row-col-6--md,.grd-row-col-6--sm{max-width:100%;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%}@media screen and (min-width:32rem){.grd-row-col-1-6--sm{max-width:16.66667%;-webkit-flex-basis:16.66667%;-ms-flex-preferred-size:16.66667%;flex-basis:16.66667%}.grd-row-col-2-6--sm{max-width:33.33333%;-webkit-flex-basis:33.33333%;-ms-flex-preferred-size:33.33333%;flex-basis:33.33333%}.grd-row-col-3-6--sm{max-width:50%;-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%}.grd-row-col-4-6--sm{max-width:66.66667%;-webkit-flex-basis:66.66667%;-ms-flex-preferred-size:66.66667%;flex-basis:66.66667%}.grd-row-col-5-6--sm{max-width:83.33333%;-webkit-flex-basis:83.33333%;-ms-flex-preferred-size:83.33333%;flex-basis:83.33333%}.grd-row-col-6--sm{max-width:100%;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%}}@media screen and (min-width:48rem){.grd-row-col-1-6--md{max-width:16.66667%;-webkit-flex-basis:16.66667%;-ms-flex-preferred-size:16.66667%;flex-basis:16.66667%}.grd-row-col-2-6--md{max-width:33.33333%;-webkit-flex-basis:33.33333%;-ms-flex-preferred-size:33.33333%;flex-basis:33.33333%}.grd-row-col-3-6--md{max-width:50%;-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%}.grd-row-col-4-6--md{max-width:66.66667%;-webkit-flex-basis:66.66667%;-ms-flex-preferred-size:66.66667%;flex-basis:66.66667%}.grd-row-col-5-6--md{max-width:83.33333%;-webkit-flex-basis:83.33333%;-ms-flex-preferred-size:83.33333%;flex-basis:83.33333%}.grd-row-col-6--md{max-width:100%;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%}}@media screen and (min-width:64rem){.grd-row-col-1-6--lg{max-width:16.66667%;-webkit-flex-basis:16.66667%;-ms-flex-preferred-size:16.66667%;flex-basis:16.66667%}.grd-row-col-2-6--lg{max-width:33.33333%;-webkit-flex-basis:33.33333%;-ms-flex-preferred-size:33.33333%;flex-basis:33.33333%}.grd-row-col-3-6--lg{max-width:50%;-webkit-flex-basis:50%;-ms-flex-preferred-size:50%;flex-basis:50%}.grd-row-col-4-6--lg{max-width:66.66667%;-webkit-flex-basis:66.66667%;-ms-flex-preferred-size:66.66667%;flex-basis:66.66667%}.grd-row-col-5-6--lg{max-width:83.33333%;-webkit-flex-basis:83.33333%;-ms-flex-preferred-size:83.33333%;flex-basis:83.33333%}.grd-row-col-6--lg{max-width:100%;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%}}*,::after,::before{box-sizing:border-box}.measure{max-width:48rem;margin:0 auto}a{color:#3498db}a:active,a:focus,a:hover{color:#217dbb}.bg--red{background-color:#e74c3c}.bg--orange{background-color:#f39c12}.bg--blue{background-color:#3498db}.bg--green{background-color:#25ba84}.bg--white{background-color:#fff}.bg--light-gray{background-color:rgba(216,216,216,.99)}.bg--mid-gray{background-color:rgba(144,144,144,.99)}.bg--dark-gray{background-color:rgba(72,72,72,.99)}.bg--off-white{background-color:rgba(250,250,250,.99)}.fnt--red{color:#e74c3c}.fnt--orange{color:#f39c12}.fnt--blue{color:#3498db}.fnt--green{color:#25ba84}.fnt--white{color:#fff}.fnt--light-gray{color:rgba(216,216,216,.99)}.fnt--mid-gray{color:rgba(144,144,144,.99)}.fnt--dark-gray{color:rgba(72,72,72,.99)}.fnt--off-white{color:rgba(250,250,250,.99)}.m0{margin:0}.mx0{margin-left:0;margin-right:0}.my0{margin-top:0;margin-bottom:0}.m1{margin:1rem}.mx1{margin-left:1rem;margin-right:1rem}.my1{margin-top:1rem;margin-bottom:1rem}.m2{margin:2rem}.mx2{margin-left:2rem;margin-right:2rem}.my2{margin-top:2rem;margin-bottom:2rem}.p0{padding:0}.px0{padding-left:0;padding-right:0}.py0{padding-top:0;padding-bottom:0}.p1{padding:1rem}.px1{padding-left:1rem;padding-right:1rem}.py1{padding-top:1rem;padding-bottom:1rem}.p2{padding:2rem}.px2{padding-left:2rem;padding-right:2rem}.py2{padding-top:2rem;padding-bottom:2rem}html{font-size:12px}@media screen and (min-width:32rem) and (max-width:48rem){html{font-size:15px}}@media screen and (min-width:48rem){html{font-size:16px}}body{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:400;line-height:1.85;color:#333}.p,p{font-size:1rem;margin-bottom:1.3rem}.h1,.h2,.h3,.h4,h1,h2,h3,h4{margin:1.414rem 0 .5rem;font-weight:inherit;line-height:1.42}.h1,h1{margin-top:0;font-size:3.998rem}.h2,h2{font-size:2.827rem}.h3,h3{font-size:1.999rem}.h4,h4{font-size:1.414rem}.h5,h5,table th{font-size:1.121rem}.h6,h6{font-size:.88rem}.btn--s,.small,small{font-size:.707em}code,pre{font-family:Monaco,"Lucida Console",Courier,monospace}.italic{font-style:italic}.thin{font-weight:100}.bold{font-weight:700}.caps,table th{font-variant:small-caps}.justify{text-align:justify}.ellipsis{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.muted{opacity:.7}.clearfix:after{content:"";display:table;clear:both}.flt--left{float:left}.flt--right{float:right}.flt--none{float:none}.center{margin:auto}.txt--center{text-align:center}.txt--right{text-align:right}.txt--left,table th{text-align:left}.oflow-y--scroll{overflow-y:scroll}.w100,.w100--s{width:100%;display:block}@media screen and (min-width:32rem){.w100--s{width:auto;display:inline-block}}canvas,iframe,img,select,svg,textarea,video{max-width:100%}.brdr--rounded,.btn,.btn--blue,.btn--gray,.btn--green,.btn--link,.btn--red{border-radius:3px}.brdr--light-gray{border:thin solid rgba(216,216,216,.99)}.brdr--mid-gray{border:thin solid rgba(144,144,144,.99)}.brdr--dark-gray{border:thin solid rgba(72,72,72,.99)}.brdr--off-white{border:thin solid rgba(250,250,250,.99)}.btn,.btn--blue,.btn--gray,.btn--green,.btn--link,.btn--red{padding:.5rem 1rem;border:2px solid #ccc;color:#333;text-decoration:none;text-align:center}.btn:active,.btn:focus,.btn:hover{background-color:rgba(0,0,0,.05);color:#000}.btn--link{border-color:transparent;color:#3498db}.btn--link:hover{background-color:transparent;color:#1d6fa5}.btn--blue{border-color:#2792d9;background-color:#3498db;color:#fff}.btn--blue:active,.btn--blue:focus,.btn--blue:hover{color:#fff;background-color:#217dbb}.btn--green{border-color:#22a977;background-color:#25ba84;color:#fff}.btn--green:active,.btn--green:focus,.btn--green:hover{color:#fff;background-color:#1d8f65}.btn--gray{border-color:rgba(59,59,59,.99);background-color:rgba(72,72,72,.99);color:#fff}.btn--gray:active,.btn--gray:focus,.btn--gray:hover{color:#fff;background-color:rgba(46,46,46,.99)}.btn--red{border-color:#e43525;background-color:#e74c3c;color:#fff}.btn--red:active,.btn--red:focus,.btn--red:hover{color:#fff;background-color:#d62a1a}.btn--s{padding:.5rem}.list--unstyled{list-style-type:none}input,textarea{padding:.5rem;margin-bottom:.5rem;display:block;width:100%;box-shadow:none;border:thin solid rgba(216,216,216,.99)}input[type=submit]{margin-top:.85rem}.media{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.media .media-figure{margin-right:1em}.media .media-body{-webkit-flex:1 0 0;-ms-flex:1 0 0;flex:1 0 0}table>thead{border-bottom:thin solid rgba(250,250,250,.99)}table td,table th{padding:.25rem;word-wrap:normal;line-height:1}
@@ -0,0 +1,31 @@
1
+ .container {
2
+ max-width: 48rem;
3
+ margin: 4rem auto
4
+ }
5
+
6
+ table {
7
+ width: 100%;
8
+ max-width: 100%;
9
+ margin-bottom: 2rem;
10
+ }
11
+
12
+ .table > thead > tr > th,
13
+ .table > tbody > tr > th,
14
+ .table > tfoot > tr > th,
15
+ .table > thead > tr > td,
16
+ .table > tbody > tr > td,
17
+ .table > tfoot > tr > td {
18
+ padding: 8px;
19
+ line-height: 1.25rem;
20
+ vertical-align: top;
21
+ }
22
+
23
+ .table > thead > tr > th {
24
+ vertical-align: bottom;
25
+ }
26
+
27
+
28
+ /* Furtive override */
29
+ .btn--s {
30
+ font-size: 0.95em;
31
+ }
@@ -1,69 +1,122 @@
1
- <h1><%= settings.robot.name.capitalize %> bot!</h1>
1
+ <h1>Manage <%= settings.robot.name.capitalize %> bot</h1>
2
2
 
3
- <h3>Handlers List</h3>
4
- <table border=1 style="text-align: left; min-width: 200px">
5
- <tr>
6
- <th>Handler</th>
7
- <th>Action</th>
8
- </tr>
9
- <% settings.robot.default_handlers.each do |handler| %>
3
+ <h3>Adapters</h3>
4
+
5
+ <p class="h5">Adapters connect to chat service. Only Slack is supported at the moment but we're planning to add more. A valid adapter must be configured for the bot to work.</p>
6
+
7
+ <table class="table">
8
+ <thead>
10
9
  <tr>
11
- <td><%= handler.to_s %></td>
12
- <td>Default Handler, can not be deactivated.</td>
10
+ <th>Adapter</th>
11
+ <th>Action</th>
13
12
  </tr>
14
- <% end %>
15
- <% @handlers.each do |handler| %>
16
- <% if !settings.robot.default_handlers.include?(handler) %>
13
+ </thead>
14
+ <tbody>
15
+ <% settings.robot.default_adapters.each do |adapter| %>
17
16
  <tr>
18
- <td><%= handler.to_s %></td>
19
- <td>
20
- <% if settings.robot.handlers.keys.include?(handler) %>
21
- <form action="/deactivate/handler/<%= handler.to_s %>" method="POST">
22
- <input type="submit" value="Deactivate">
23
- </form>
24
- <% else %>
25
- <form action="/activate/handler/<%= handler.to_s %>" method="POST">
26
- <input type="submit" value="Activate">
27
- </form>
28
- <% end %>
29
- </td>
17
+ <td><%= adapter[:name].to_s %></td>
18
+ <td>Default Adapter, can not be deactivated.</td>
30
19
  </tr>
31
20
  <% end %>
32
- <% end %>
21
+ <% @adapters.each do |adapter| %>
22
+ <% if !settings.robot.default_adapters.include?(adapter[:name]) %>
23
+ <tr>
24
+ <td><%= adapter[:name].to_s %></td>
25
+ <td>
26
+ <% if gem_installed? adapter[:gem] %>
27
+ <% if settings.robot.adapters.keys.include?(adapter[:name]) %>
28
+ <form action="/deactivate/adapter/<%= adapter[:name].to_s %>" method="POST">
29
+ <input type="submit" value="Deactivate" class="btn--gray btn--s">
30
+ </form>
31
+ <% else %>
32
+ <form action="/activate/adapter/<%= adapter[:name].to_s %>" method="POST">
33
+ <input type="hidden" name="<%= adapter[:name].to_s %>:gem_name" value="<%= adapter[:gem].to_s %>">
34
+ <% adapter[:configs].each do |c| %>
35
+ <label for="<%= c[:name].to_s %>">
36
+ <%= c[:name].to_s %>
37
+ <% if !c[:required] %>(optional)<% end %>:
38
+ </label>
39
+ <input type="text" name="<%= adapter[:name].to_s %>:config:<%= c[:name].to_s %>">
40
+ <% end %>
41
+ <input type="submit" value="Activate" class="btn--green btn--s">
42
+ </form>
43
+
44
+ <form action="/uninstall/<%= adapter[:gem].to_s %>" method="POST">
45
+ <input type="submit" value="Uninstall Adapter" class="btn--green btn--s">
46
+ </form>
47
+ <% end %>
48
+ <% else %>
49
+ <form action="/install/<%= adapter[:gem].to_s %>" method="POST">
50
+ <input type="submit" value="Install Adapter" class="btn--gray btn--s">
51
+ </form>
52
+ <% end %>
53
+ </td>
54
+ </tr>
55
+ <% end %>
56
+ <% end %>
57
+ </tbody>
33
58
  </table>
34
59
 
35
- <h3>Adapters List</h3>
36
- <table border=1 style="text-align: left; min-width: 200px;">
37
- <tr>
38
- <th>Handler</th>
39
- <th>Action</th>
40
- </tr>
41
- <% settings.robot.default_adapters.each do |adapter| %>
60
+ <h3>Core Handlers</h3>
61
+
62
+ <p class="h5">Built-in handlers provide basic information about the bot and extend its capabilites. Interact with those handlers through the active chat service.</p>
63
+
64
+ <table class="table">
65
+ <thead>
42
66
  <tr>
43
- <td><%= adapter[:name].to_s %></td>
44
- <td>Default Adapter, can not be deactivated.</td>
67
+ <th>Handler</th>
68
+ <th>Action</th>
45
69
  </tr>
46
- <% end %>
47
- <% @adapters.each do |adapter| %>
48
- <% if !settings.robot.default_adapters.include?(adapter[:name]) %>
70
+ </thead>
71
+ <tbody>
72
+ <% settings.robot.default_handlers.each do |handler| %>
49
73
  <tr>
50
- <td><%= adapter[:name].to_s %></td>
51
- <td>
52
- <% if settings.robot.adapters.keys.include?(adapter[:name]) %>
53
- <form action="/deactivate/adapter/<%= adapter[:name].to_s %>" method="POST">
54
- <input type="submit" value="Deactivate">
55
- </form>
56
- <% else %>
57
- <form action="/activate/adapter/<%= adapter[:name].to_s %>" method="POST">
58
- <input type="hidden" name="<%= adapter[:name].to_s %>:gem_name" value="<%= adapter[:gem].to_s %>">
59
- <% adapter[:configs].each do |c| %>
60
- <%= c[:name].to_s %><% if !c[:required] %>(optional)<% end %>: <input type="text" name="<%= adapter[:name].to_s %>:config:<%= c[:name].to_s %>"><br>
61
- <% end %>
62
- <input type="submit" value="Activate">
63
- </form>
64
- <% end %>
65
- </td>
74
+ <td><%= handler.to_s %></td>
75
+ <td>Default Handler, can not be deactivated.</td>
66
76
  </tr>
67
77
  <% end %>
68
- <% end %>
78
+ <% @handlers.each do |handler| %>
79
+ <% if !settings.robot.default_handlers.include?(handler[:name]) %>
80
+ <tr>
81
+ <td><%= handler[:name].to_s %></td>
82
+ <td>
83
+ <% if gem_installed? handler[:gem] %>
84
+ <% if settings.robot.handlers.keys.include?(handler[:name]) %>
85
+ <form action="/deactivate/handler/<%= handler[:name].to_s %>" method="POST">
86
+ <input type="submit" value="Deactivate" class="btn--gray btn--s">
87
+ </form>
88
+ <% else %>
89
+ <form action="/activate/handler/<%= handler[:name].to_s %>" method="POST">
90
+ <input type="hidden" name="<%= handler[:name].to_s %>:gem_name" value="<%= handler[:gem].to_s %>">
91
+ <% handler[:configs].each do |c| %>
92
+ <label for="<%= c[:name].to_s %>">
93
+ <%= c[:name].to_s %>
94
+ <% if !c[:required] %>(optional)<% end %>:
95
+ </label>
96
+ <input type="text" name="<%= handler[:name].to_s %>:config:<%= c[:name].to_s %>">
97
+ <% end %>
98
+ <input type="submit" value="Activate" class="btn--green btn--s">
99
+ </form>
100
+ <% end %>
101
+
102
+ <form action="/uninstall/<%= handler[:gem].to_s %>" method="POST">
103
+ <input type="submit" value="Uninstall Adapter" class="btn--green btn--s">
104
+ </form>
105
+ <% else %>
106
+ <form action="/install/<%= handler[:gem].to_s %>" method="POST">
107
+ <input type="submit" value="Install Adapter" class="btn--gray btn--s">
108
+ </form>
109
+ <% end %>
110
+ </td>
111
+ </tr>
112
+ <% end %>
113
+ <% end %>
114
+ </tbody>
69
115
  </table>
116
+
117
+ <h3>Extensions</h3>
118
+
119
+ <p class="h5">Extensions adds new functionality to the bot. They are tailored to respond to specific commands and perform task. Browse through the list of available extensions or build your own.</p>
120
+
121
+ <a href="/integrations">View public extensions</a> or
122
+ <a href="https://github.com/yafoy/pepito">build one</a>
@@ -0,0 +1,19 @@
1
+ <h1>Integration</h1>
2
+
3
+ <% if @integrations.any? %>
4
+ <% @integrations["extensions"].each do |integration| %>
5
+ <div class="media py2">
6
+ <div class="media-figure">
7
+ <img src="<%= integration['image_url'] %>" alt="<%= integration['name'] %>" width="90px" height="90px">
8
+ </div>
9
+ <div class="media-body">
10
+ <h6 class="m0 p0">
11
+ <a href="<%= integration['url'] %>" target="_blank" class="p"><%= integration['name'] %></a>
12
+ </h6>
13
+ <p class="m0 p0">
14
+ <%= integration['description'] %>
15
+ </p>
16
+ </div>
17
+ </div>
18
+ <% end %>
19
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= settings.robot.name.capitalize %></title>
5
+ <meta charset="utf-8">
6
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1">
8
+ <link rel="stylesheet" href="stylesheets/furtive.min.css">
9
+ <link rel="stylesheet" href="stylesheets/layout.css">
10
+ <style>
11
+ </style>
12
+ </head>
13
+ <body>
14
+ <div class='container my2'>
15
+ <%= yield %>
16
+ </div>
17
+ </body>
18
+ </html>
@@ -28,8 +28,11 @@ Gem::Specification.new do |s|
28
28
  s.add_runtime_dependency 'sinatra', '~> 1.4.6', '>= 1.4.6'
29
29
  s.add_runtime_dependency 'tilt', '~> 2.0.2', '>= 2.0.2'
30
30
  s.add_runtime_dependency 'puma', '~> 2.15.3', '>= 2.15.3'
31
+ s.add_runtime_dependency 'rest-client', '~> 1.8', '>= 1.8'
32
+ # s.add_runtime_dependency 'pepito-queenbee'
31
33
 
32
34
  s.add_development_dependency 'rake', '~> 10.5'
33
35
  s.add_development_dependency 'minitest', '~> 5.8'
36
+ s.add_development_dependency 'minitest-reporters', '~> 1.0'
34
37
  s.add_development_dependency 'rubocop', '~> 0.37'
35
38
  end
@@ -3,7 +3,7 @@ require 'pepito/handlers/room'
3
3
 
4
4
  class TestPepitoHandlersExtensionsCatalog < MiniTest::Test
5
5
  def setup
6
- @handler = Pepito::Handlers::ExtensionsCatalog.new(nil)
6
+ @handler = Pepito::Handlers::ExtensionsCatalog.new(nil, {})
7
7
  @handler.run
8
8
  end
9
9
 
@@ -8,7 +8,7 @@ class TestPepitoHandlersHelp < MiniTest::Test
8
8
 
9
9
  def setup
10
10
  @mock_robot = Struct::Robot.new('pepito', [])
11
- @handler = Pepito::Handlers::Help.new(@mock_robot)
11
+ @handler = Pepito::Handlers::Help.new(@mock_robot, {})
12
12
  @handler.run
13
13
  end
14
14
 
@@ -4,7 +4,7 @@ require 'pepito/version'
4
4
 
5
5
  class TestPepitoHandlersInfo < MiniTest::Test
6
6
  def setup
7
- @handler = Pepito::Handlers::Info.new(nil)
7
+ @handler = Pepito::Handlers::Info.new(nil, {})
8
8
  @handler.run
9
9
  end
10
10
 
@@ -3,7 +3,7 @@ require 'pepito/handlers/room'
3
3
 
4
4
  class TestPepitoHandlersRoom < MiniTest::Test
5
5
  def setup
6
- @handler = Pepito::Handlers::Room.new(nil)
6
+ @handler = Pepito::Handlers::Room.new(nil, {})
7
7
  @handler.run
8
8
  end
9
9
 
@@ -16,7 +16,7 @@ class TestPepitoHandler < MiniTest::Test
16
16
  mock_robot = MiniTest::Mock.new
17
17
  mock_robot.expect(:http_api, mock_http_api)
18
18
 
19
- handler = Pepito::Handler.new(mock_robot)
19
+ handler = Pepito::Handler.new(mock_robot, {})
20
20
  handler.http_routes << mock_route
21
21
  handler.start
22
22
 
@@ -0,0 +1,37 @@
1
+ require 'minitest/autorun'
2
+ require 'pepito/helpers'
3
+
4
+ class TestPepitoHelpers < MiniTest::Test
5
+ include Pepito::Helpers
6
+
7
+ def test_install_gem
8
+ gem_name = 'pepito'
9
+
10
+ mock_dependency_installer = MiniTest::Mock.new
11
+ mock_dependency_installer.expect(:install, nil, [gem_name])
12
+
13
+ Gem::DependencyInstaller.stub :new, mock_dependency_installer do
14
+ gem_install gem_name
15
+ end
16
+
17
+ assert mock_dependency_installer.verify
18
+ end
19
+
20
+ def test_uninstall_gem
21
+ gem_name = 'pepito'
22
+
23
+ mock_uninstaller = MiniTest::Mock.new
24
+ mock_uninstaller.expect(:uninstall, nil, [])
25
+
26
+ Gem::Uninstaller.stub :new, mock_uninstaller do
27
+ gem_uninstall gem_name
28
+ end
29
+
30
+ assert mock_uninstaller.verify
31
+ end
32
+
33
+ def test_gem_installed
34
+ assert gem_installed? 'pepito'
35
+ refute gem_installed? ''
36
+ end
37
+ end
@@ -52,45 +52,51 @@ class TestPepitoRobot < MiniTest::Test
52
52
  def test_start_handler
53
53
  # Fail to start if handler is running
54
54
  @robot.handlers.stub :key?, true do
55
- assert_equal 1, @robot.start_handler('')
55
+ assert_equal 1, @robot.start_handler('', 'pepito', {})
56
56
  end
57
57
 
58
58
  # Fail to start if handler does not exist
59
59
  @robot.handlers.stub :key?, false do
60
- assert_equal 2, @robot.start_handler('')
60
+ assert_equal 2, @robot.start_handler('', 'pepito', {})
61
61
  end
62
62
 
63
63
  # Fail with other errors
64
64
  @robot.handlers.stub :key?, false do
65
65
  mock_handler = Class.new do
66
- def initialize(_robot)
66
+ def initialize(_robot, _config)
67
67
  raise 'error'
68
68
  end
69
69
  end
70
70
  Pepito::Handlers.stub :const_get, mock_handler do
71
- assert_equal 3, @robot.start_handler('')
71
+ assert_equal 4, @robot.start_handler('', 'pepito', {})
72
72
  end
73
73
  end
74
74
 
75
75
  # Start handler successfully
76
76
  @robot.handlers.stub :key?, false do
77
77
  name = 'handler_name'
78
+ gem_name = 'pepito'
79
+ config = { 'name' => 'option' }
78
80
 
79
81
  mock_handler = MiniTest::Mock.new
80
82
  mock_handler.expect(:run, nil)
81
83
  mock_handler.expect(:start, nil)
82
84
 
83
85
  mock_handler_klass = MiniTest::Mock.new
84
- mock_handler_klass.expect(:new, mock_handler, [@robot])
86
+ mock_handler_klass.expect(:new, mock_handler, [@robot, config])
85
87
 
86
88
  mock_router = MiniTest::Mock.new
87
89
  mock_router.expect(:uncompile, nil)
88
90
 
89
91
  @mock_http_api.expect(:router, mock_router)
90
92
  @mock_database.expect(:sadd, nil, ['handlers', name])
93
+ @mock_database.expect(:set, nil, [name + ':gem', gem_name])
94
+ config.each do |k, v|
95
+ @mock_database.expect(:hset, nil, [name + ':config', k, v])
96
+ end
91
97
 
92
98
  Pepito::Handlers.stub :const_get, mock_handler_klass do
93
- assert_equal 0, @robot.start_handler(name)
99
+ assert_equal 0, @robot.start_handler(name, gem_name, config)
94
100
  assert mock_handler.verify
95
101
  assert mock_router.verify
96
102
  assert mock_handler_klass.verify
@@ -121,6 +127,8 @@ class TestPepitoRobot < MiniTest::Test
121
127
  mock_router = MiniTest::Mock.new
122
128
  mock_router.expect(:reset!, nil)
123
129
  @mock_database.expect(:srem, nil, ['handlers', name])
130
+ @mock_database.expect(:del, nil, [name + ':config'])
131
+ @mock_database.expect(:del, nil, [name + ':gem'])
124
132
  @mock_http_api.expect(:router, mock_router)
125
133
 
126
134
  assert_equal 0, @robot.stop_handler(name)
@@ -1,6 +1,13 @@
1
1
  require 'minitest/autorun'
2
+ require 'minitest/reporters'
2
3
  require 'pepito'
3
4
 
5
+ Minitest::Reporters.use!(
6
+ Minitest::Reporters::SpecReporter.new,
7
+ ENV,
8
+ Minitest.backtrace_filter
9
+ )
10
+
4
11
  class TestPepito < MiniTest::Test
5
12
  def test_redis_namespace_is_pepito
6
13
  assert_equal :pepito, Pepito::REDIS_NAMESPACE
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pepito
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Olivier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-15 00:00:00.000000000 Z
11
+ date: 2016-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-namespace
@@ -170,6 +170,26 @@ dependencies:
170
170
  - - ">="
171
171
  - !ruby/object:Gem::Version
172
172
  version: 2.15.3
173
+ - !ruby/object:Gem::Dependency
174
+ name: rest-client
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '1.8'
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '1.8'
183
+ type: :runtime
184
+ prerelease: false
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: '1.8'
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '1.8'
173
193
  - !ruby/object:Gem::Dependency
174
194
  name: rake
175
195
  requirement: !ruby/object:Gem::Requirement
@@ -198,6 +218,20 @@ dependencies:
198
218
  - - "~>"
199
219
  - !ruby/object:Gem::Version
200
220
  version: '5.8'
221
+ - !ruby/object:Gem::Dependency
222
+ name: minitest-reporters
223
+ requirement: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - "~>"
226
+ - !ruby/object:Gem::Version
227
+ version: '1.0'
228
+ type: :development
229
+ prerelease: false
230
+ version_requirements: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - "~>"
233
+ - !ruby/object:Gem::Version
234
+ version: '1.0'
201
235
  - !ruby/object:Gem::Dependency
202
236
  name: rubocop
203
237
  requirement: !ruby/object:Gem::Requirement
@@ -239,6 +273,7 @@ files:
239
273
  - lib/pepito/handlers/help.rb
240
274
  - lib/pepito/handlers/info.rb
241
275
  - lib/pepito/handlers/room.rb
276
+ - lib/pepito/helpers.rb
242
277
  - lib/pepito/http_api/http_callback.rb
243
278
  - lib/pepito/http_api/http_route.rb
244
279
  - lib/pepito/http_api/rack_app.rb
@@ -247,7 +282,11 @@ files:
247
282
  - lib/pepito/source.rb
248
283
  - lib/pepito/version.rb
249
284
  - lib/pepito/web_app/app.rb
285
+ - lib/pepito/web_app/public/stylesheets/furtive.min.css
286
+ - lib/pepito/web_app/public/stylesheets/layout.css
250
287
  - lib/pepito/web_app/views/index.erb
288
+ - lib/pepito/web_app/views/integrations.erb
289
+ - lib/pepito/web_app/views/layout.erb
251
290
  - pepito.gemspec
252
291
  - test/pepito/handler/test_chat_router.rb
253
292
  - test/pepito/handler/test_http_router.rb
@@ -257,6 +296,7 @@ files:
257
296
  - test/pepito/handlers/test_room.rb
258
297
  - test/pepito/test_adapter.rb
259
298
  - test/pepito/test_handler.rb
299
+ - test/pepito/test_helpers.rb
260
300
  - test/pepito/test_message.rb
261
301
  - test/pepito/test_robot.rb
262
302
  - test/pepito/test_source.rb
@@ -294,6 +334,7 @@ test_files:
294
334
  - test/pepito/handlers/test_room.rb
295
335
  - test/pepito/test_adapter.rb
296
336
  - test/pepito/test_handler.rb
337
+ - test/pepito/test_helpers.rb
297
338
  - test/pepito/test_message.rb
298
339
  - test/pepito/test_robot.rb
299
340
  - test/pepito/test_source.rb