web-console 0.1.0
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +121 -0
- data/Rakefile +48 -0
- data/app/assets/javascripts/web_console/application.js +4 -0
- data/app/assets/javascripts/web_console/console_sessions.js +24 -0
- data/app/assets/stylesheets/web_console/application.css +13 -0
- data/app/assets/stylesheets/web_console/console_sessions.css +8 -0
- data/app/controllers/web_console/application_controller.rb +12 -0
- data/app/controllers/web_console/console_sessions_controller.rb +23 -0
- data/app/helpers/web_console/application_helper.rb +4 -0
- data/app/helpers/web_console/console_session_helper.rb +4 -0
- data/app/models/web_console/console_session.rb +107 -0
- data/app/views/layouts/web_console/application.html.erb +14 -0
- data/app/views/web_console/console_sessions/index.html.erb +4 -0
- data/config/routes.rb +5 -0
- data/lib/web-console.rb +1 -0
- data/lib/web_console.rb +7 -0
- data/lib/web_console/engine.rb +38 -0
- data/lib/web_console/fiber.rb +48 -0
- data/lib/web_console/repl.rb +59 -0
- data/lib/web_console/repl/dummy.rb +38 -0
- data/lib/web_console/repl/irb.rb +61 -0
- data/lib/web_console/stream.rb +27 -0
- data/lib/web_console/version.rb +3 -0
- data/test/controllers/web_console/console_sessions_controller_test.rb +57 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +15 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +2 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +26591 -0
- data/test/dummy/log/test.log +78368 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/7ec0041a47c34b44e52e836c01454a1a +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/a1534e0c08b73ad82c2edb8c364caa66 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/a841a3af20a321912acfed87036438fb +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ad8eea7f774b674c29708ca90952764f +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b0741545b4917192ba7b5e803c2e323d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b3159b06164dd474ff8efc3c84aefbba +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/b40b7c5b2003544010f30f0bd3fb81b2 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c4e26d8dbebb3afd7013acfefa564dd1 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0280bb38c5058cc31c4fcd8c392a5ec4 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/05bd7b24c0a86010ebb28b50ac7cad52 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2a48be7daff14cf56911b263cbe017c7 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3824a9e25e846a4916b3ac1d67060782 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3a37adb5ebd079cf67dae597b8c2e4f8 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/4f79e5f341043e081becefe4952395c5 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/508ab3c25833ea537a5e3fc90df33595 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/5a8ab22e707dfc7ba00691f90e054d7e +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/5adcb7569cdd03204d650e285f19351f +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/632346eda030b596f513fff2de181743 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/654a1bde557d359b957dc0aa12b0dfa0 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/71f57313d6c92f5483915a6c2d79a506 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9b9aee85f29dc573732fbb4001ceda00 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/a841a3af20a321912acfed87036438fb +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/bbbe6a3ce382662666a355d708c83d2d +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/ca53fb2717d5aac2f1c3939d9444fe3b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d6b37d10680a997662c379d0ff7cad27 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e1d89809967e81220dca66770c50aa67 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e3d5cafc071e8f9a8efc88fddf721947 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f44e2a41bd51a92a84f99847ea675ba3 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f4a21ed9cebe2c83a9d988504dc6720b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f4d45273ff5b44879dab0a16805f4309 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f5deea0ae9671fdb035aefc6c4ba1109 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/helpers/web_console/console_session_helper_test.rb +6 -0
- data/test/models/console_session_test.rb +110 -0
- data/test/test_helper.rb +15 -0
- data/test/web_console/repl/dummy_test.rb +54 -0
- data/test/web_console/repl/irb_test.rb +108 -0
- data/test/web_console/repl_test.rb +15 -0
- data/test/web_console_test.rb +91 -0
- data/vendor/assets/javascripts/jquery.console.js +727 -0
- metadata +303 -0
data/lib/web_console.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'ipaddr'
|
|
2
|
+
require 'rails/engine'
|
|
3
|
+
require 'jquery-rails'
|
|
4
|
+
|
|
5
|
+
module WebConsole
|
|
6
|
+
class Engine < ::Rails::Engine
|
|
7
|
+
isolate_namespace WebConsole
|
|
8
|
+
|
|
9
|
+
config.web_console = ActiveSupport::OrderedOptions.new
|
|
10
|
+
config.web_console.default_mount_path = '/console'
|
|
11
|
+
config.web_console.whitelisted_ips = '127.0.0.1'
|
|
12
|
+
|
|
13
|
+
initializer 'web_console.add_default_route' do |app|
|
|
14
|
+
# While we don't need the route in the test environment, we define it
|
|
15
|
+
# there as well, so we can easily test it.
|
|
16
|
+
if Rails.env.development? || Rails.env.test?
|
|
17
|
+
app.routes.append do
|
|
18
|
+
mount WebConsole::Engine => app.config.web_console.default_mount_path
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
initializer 'web_console.process_whitelisted_ips' do
|
|
24
|
+
# Ensure that it is an array of IPAddr instances and it is defaulted to
|
|
25
|
+
# 127.0.0.1 if not precent. Only unique entries are left in the end.
|
|
26
|
+
config.web_console.whitelisted_ips = Array(config.web_console.whitelisted_ips)
|
|
27
|
+
config.web_console.whitelisted_ips.map! do |ip|
|
|
28
|
+
ip.is_a?(IPAddr) ? ip : IPAddr.new(ip.presence || '127.0.0.1')
|
|
29
|
+
end.uniq!
|
|
30
|
+
|
|
31
|
+
# IPAddr instances can cover whole networks, so simplify the #include?
|
|
32
|
+
# check for the most common case.
|
|
33
|
+
def (config.web_console.whitelisted_ips).include?(ip)
|
|
34
|
+
ip.is_a?(IPAddr) ? super : any? { |net| net.include?(ip.to_s) }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module WebConsole
|
|
2
|
+
# Poor Man's Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)
|
|
3
|
+
# (c) 2008 Aman Gupta (tmm1)
|
|
4
|
+
#
|
|
5
|
+
# For the purposes of our REPL adapters there is a need for fiber invocation
|
|
6
|
+
# across threads. The native implementation does not support that.
|
|
7
|
+
class FiberError < StandardError; end
|
|
8
|
+
|
|
9
|
+
class Fiber
|
|
10
|
+
def initialize
|
|
11
|
+
raise ArgumentError, 'new Fiber requires a block' unless block_given?
|
|
12
|
+
|
|
13
|
+
@yield = Queue.new
|
|
14
|
+
@resume = Queue.new
|
|
15
|
+
|
|
16
|
+
@thread = Thread.new { @yield.push [ *yield(*@resume.pop) ] }
|
|
17
|
+
@thread.abort_on_exception = true
|
|
18
|
+
@thread[:fiber] = self
|
|
19
|
+
end
|
|
20
|
+
attr_reader :thread
|
|
21
|
+
|
|
22
|
+
def resume(*args)
|
|
23
|
+
raise FiberError, 'dead fiber called' unless @thread.alive?
|
|
24
|
+
@resume.push(args)
|
|
25
|
+
result = @yield.pop
|
|
26
|
+
result.size > 1 ? result : result.first
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def yield(*args)
|
|
30
|
+
@yield.push(args)
|
|
31
|
+
result = @resume.pop
|
|
32
|
+
result.size > 1 ? result : result.first
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.yield(*args)
|
|
36
|
+
raise FiberError, "can't yield from root fiber" unless fiber = Thread.current[:fiber]
|
|
37
|
+
fiber.yield(*args)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.current
|
|
41
|
+
Thread.current[:fiber] or raise FiberError, 'not inside a fiber'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def inspect
|
|
45
|
+
"#<#{self.class}:0x#{self.object_id.to_s(16)}>"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
|
2
|
+
|
|
3
|
+
module WebConsole
|
|
4
|
+
module REPL
|
|
5
|
+
extend self
|
|
6
|
+
|
|
7
|
+
# Registry of REPL implementations mapped to their correspondent adapter
|
|
8
|
+
# classes.
|
|
9
|
+
#
|
|
10
|
+
# Don't manually alter the registry. Use WebConsole::REPL.register_adapter
|
|
11
|
+
# for adding entries.
|
|
12
|
+
def adapters
|
|
13
|
+
@adapters ||= {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Register an adapter into the adapters registry.
|
|
17
|
+
#
|
|
18
|
+
# Registration maps and adapter class to an existing REPL implementation,
|
|
19
|
+
# that we call an adaptee constant. If the adaptee constant is not given,
|
|
20
|
+
# it is automatically derived from the adapter class name.
|
|
21
|
+
#
|
|
22
|
+
# For example, adapter named +WebConsole::REPL::IRB+ will derive the
|
|
23
|
+
# adaptee constant to +::IRB+.
|
|
24
|
+
#
|
|
25
|
+
# If a block is given, it would be evaluated right after the adapter
|
|
26
|
+
# registration.
|
|
27
|
+
def register_adapter(adapter_class, adaptee_constant = nil, options = {})
|
|
28
|
+
if adaptee_constant.is_a?(Hash)
|
|
29
|
+
options = adaptee_constant
|
|
30
|
+
adaptee_constant = nil
|
|
31
|
+
end
|
|
32
|
+
adaptee_constant = adapter_class if options[:standalone]
|
|
33
|
+
adaptee_constant ||= derive_adaptee_constant_from(adapter_class)
|
|
34
|
+
adapters[adaptee_constant] = adapter_class
|
|
35
|
+
yield if block_given?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Get the default adapter for the given application.
|
|
39
|
+
#
|
|
40
|
+
# By default the application will be Rails.application and the adapter
|
|
41
|
+
# will be chosen from Rails.application.config.console.
|
|
42
|
+
#
|
|
43
|
+
# If no suitible adapter is found for the configured Rails console, a dummy
|
|
44
|
+
# adapter will be used. You can evaluate code in it, but it won't support
|
|
45
|
+
# any advanced features, like multiline code evaluation.
|
|
46
|
+
def default(app = Rails.application)
|
|
47
|
+
adapters[app.config.console || ::IRB] || adapters[Dummy]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
def derive_adaptee_constant_from(cls, suffix = 'REPL')
|
|
52
|
+
"::#{cls.name.split('::').last.gsub(/#{suffix}$/i, '')}".constantize
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Require the builtin adapters.
|
|
58
|
+
require 'web_console/repl/irb'
|
|
59
|
+
require 'web_console/repl/dummy'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'web_console/stream'
|
|
2
|
+
|
|
3
|
+
module WebConsole
|
|
4
|
+
module REPL
|
|
5
|
+
# == Dummy\ Adapter
|
|
6
|
+
#
|
|
7
|
+
# Dummy adapter that is used as a fallback for REPL with no adapters.
|
|
8
|
+
#
|
|
9
|
+
# It provides only the most basic code evaluation with no multiline code
|
|
10
|
+
# support.
|
|
11
|
+
class Dummy
|
|
12
|
+
def initialize(binding = TOPLEVEL_BINDING)
|
|
13
|
+
@binding = binding
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def prompt
|
|
17
|
+
'>> '
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def send_input(input)
|
|
21
|
+
eval_result = nil
|
|
22
|
+
streams_output = Stream.threadsafe_capture! do
|
|
23
|
+
eval_result = @binding.eval(input).inspect
|
|
24
|
+
end
|
|
25
|
+
"#{streams_output}=> #{eval_result}\n"
|
|
26
|
+
rescue Exception => exc
|
|
27
|
+
exc.backtrace.join("\n")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
register_adapter Dummy, standalone: true do
|
|
32
|
+
require 'rails/console/app'
|
|
33
|
+
require 'rails/console/helpers'
|
|
34
|
+
|
|
35
|
+
TOPLEVEL_BINDING.eval('self').send(:include, Rails::ConsoleMethods)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'irb'
|
|
2
|
+
require 'web_console/fiber'
|
|
3
|
+
require 'web_console/stream'
|
|
4
|
+
|
|
5
|
+
module WebConsole
|
|
6
|
+
module REPL
|
|
7
|
+
# == IRB\ Adapter
|
|
8
|
+
#
|
|
9
|
+
# Adapter for the IRB REPL, which is the default Ruby on Rails console.
|
|
10
|
+
class IRB
|
|
11
|
+
# For some reason™ we have to be ::IRB::StdioInputMethod subclass to get
|
|
12
|
+
# #prompt populated.
|
|
13
|
+
#
|
|
14
|
+
# Not a pretty OOP, but for now, we just have to deal with it.
|
|
15
|
+
class FiberInputMethod < ::IRB::StdioInputMethod
|
|
16
|
+
def initialize; end
|
|
17
|
+
|
|
18
|
+
def gets
|
|
19
|
+
@previous = Fiber.yield
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def encoding
|
|
23
|
+
(@previous || '').encoding
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(binding = TOPLEVEL_BINDING)
|
|
28
|
+
initialize_irb_session!
|
|
29
|
+
@input = FiberInputMethod.new
|
|
30
|
+
@irb = ::IRB::Irb.new(::IRB::WorkSpace.new(binding), @input)
|
|
31
|
+
@fiber = Fiber.new { @irb.eval_input }.tap(&:resume)
|
|
32
|
+
finalize_irb_session!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def prompt
|
|
36
|
+
@input.prompt
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def send_input(input)
|
|
40
|
+
Stream.threadsafe_capture! { @fiber.resume("#{input}\n") }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
def initialize_irb_session!(ap_path = nil)
|
|
45
|
+
::IRB.init_config(ap_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def finalize_irb_session!
|
|
49
|
+
::IRB.conf[:MAIN_CONTEXT] = @irb.context
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
register_adapter IRB do
|
|
54
|
+
require 'rails/console/app'
|
|
55
|
+
require 'rails/console/helpers'
|
|
56
|
+
|
|
57
|
+
# Include all of the rails console helpers in the IRB session.
|
|
58
|
+
::IRB::ExtendCommandBundle.send :include, Rails::ConsoleMethods
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module WebConsole
|
|
2
|
+
module Stream
|
|
3
|
+
extend Mutex_m
|
|
4
|
+
|
|
5
|
+
def self.threadsafe_capture!(*streams)
|
|
6
|
+
streams = [$stdout, $stderr] if streams.empty?
|
|
7
|
+
synchronize do
|
|
8
|
+
begin
|
|
9
|
+
streams_copy = streams.collect(&:dup)
|
|
10
|
+
replacement = Tempfile.new(name)
|
|
11
|
+
streams.each do |stream|
|
|
12
|
+
stream.reopen(replacement)
|
|
13
|
+
stream.sync = true
|
|
14
|
+
end
|
|
15
|
+
yield
|
|
16
|
+
streams.each(&:rewind)
|
|
17
|
+
replacement.read
|
|
18
|
+
ensure
|
|
19
|
+
replacement.unlink
|
|
20
|
+
streams.each_with_index do |stream, i|
|
|
21
|
+
stream.reopen(streams_copy[i])
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
module WebConsole
|
|
4
|
+
class ConsoleSessionsControllerTest < ActionController::TestCase
|
|
5
|
+
setup do
|
|
6
|
+
# Where does .stubs lives?
|
|
7
|
+
def @request.remote_ip; '127.0.0.1' end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
test 'index is successful' do
|
|
11
|
+
get :index, use_route: 'web_console'
|
|
12
|
+
assert_response :success
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
test 'index creates new console session' do
|
|
16
|
+
assert_difference 'ConsoleSession::INMEMORY_STORAGE.size' do
|
|
17
|
+
get :index, use_route: 'web_console'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test 'update updates new console session' do
|
|
22
|
+
get :index, use_route: 'web_console'
|
|
23
|
+
assert_not_nil console_session = assigns(:console_session)
|
|
24
|
+
|
|
25
|
+
put :update, id: console_session.id, input: 42, use_route: 'web_console'
|
|
26
|
+
assert_match %r{42}, console_session.output
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
test 'update failes when session is no longer available' do
|
|
30
|
+
get :index, use_route: 'web_console'
|
|
31
|
+
assert_not_nil console_session = assigns(:console_session)
|
|
32
|
+
|
|
33
|
+
ConsoleSession::INMEMORY_STORAGE.delete(console_session.id)
|
|
34
|
+
put :update, id: console_session.id, input: 42, use_route: 'web_console'
|
|
35
|
+
assert_response :gone
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
test 'blocks requests from non-whitelisted ips' do
|
|
39
|
+
def @request.remote_ip; '128.0.0.1' end
|
|
40
|
+
get :index, use_route: 'web_console'
|
|
41
|
+
assert_response :unauthorized
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test 'index generated path' do
|
|
45
|
+
assert_generates mount_path, {
|
|
46
|
+
use_route: 'web_console',
|
|
47
|
+
controller: 'console_sessions'
|
|
48
|
+
}, {}, {controller: 'console_sessions'}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def mount_path
|
|
54
|
+
WebConsole::Engine.config.web_console.default_mount_path
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
== README
|
|
2
|
+
|
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
|
4
|
+
application up and running.
|
|
5
|
+
|
|
6
|
+
Things you may want to cover:
|
|
7
|
+
|
|
8
|
+
* Ruby version
|
|
9
|
+
|
|
10
|
+
* System dependencies
|
|
11
|
+
|
|
12
|
+
* Configuration
|
|
13
|
+
|
|
14
|
+
* Database creation
|
|
15
|
+
|
|
16
|
+
* Database initialization
|
|
17
|
+
|
|
18
|
+
* How to run the test suite
|
|
19
|
+
|
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
|
21
|
+
|
|
22
|
+
* Deployment instructions
|
|
23
|
+
|
|
24
|
+
* ...
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
|
28
|
+
<tt>rake doc:app</tt>.
|
data/test/dummy/Rakefile
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
|
2
|
+
// listed below.
|
|
3
|
+
//
|
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
|
6
|
+
//
|
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
|
8
|
+
// compiled file.
|
|
9
|
+
//
|
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
|
12
|
+
//
|
|
13
|
+
//= require_tree .
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require_self
|
|
12
|
+
*= require_tree .
|
|
13
|
+
*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Dummy</title>
|
|
5
|
+
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
|
|
6
|
+
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
|
|
7
|
+
<%= csrf_meta_tags %>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
|
|
11
|
+
<%= yield %>
|
|
12
|
+
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|