web-console 1.0.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of web-console might be problematic. Click here for more details.

Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.markdown +26 -247
  3. data/lib/action_dispatch/debug_exceptions.rb +115 -0
  4. data/lib/action_dispatch/exception_wrapper.rb +15 -0
  5. data/lib/action_dispatch/templates/rescues/_request_and_response.html.erb +34 -0
  6. data/lib/action_dispatch/templates/rescues/_request_and_response.text.erb +23 -0
  7. data/lib/action_dispatch/templates/rescues/_source.erb +27 -0
  8. data/lib/action_dispatch/templates/rescues/_trace.html.erb +76 -0
  9. data/lib/action_dispatch/templates/rescues/_trace.text.erb +15 -0
  10. data/lib/action_dispatch/templates/rescues/_web_console.html.erb +382 -0
  11. data/lib/action_dispatch/templates/rescues/diagnostics.html.erb +18 -0
  12. data/lib/action_dispatch/templates/rescues/diagnostics.text.erb +9 -0
  13. data/lib/action_dispatch/templates/rescues/layout.erb +162 -0
  14. data/lib/action_dispatch/templates/rescues/missing_template.html.erb +7 -0
  15. data/lib/action_dispatch/templates/rescues/missing_template.text.erb +3 -0
  16. data/lib/action_dispatch/templates/rescues/routing_error.html.erb +30 -0
  17. data/lib/action_dispatch/templates/rescues/routing_error.text.erb +11 -0
  18. data/lib/action_dispatch/templates/rescues/template_error.html.erb +22 -0
  19. data/lib/action_dispatch/templates/rescues/template_error.text.erb +8 -0
  20. data/lib/action_dispatch/templates/rescues/unknown_action.html.erb +6 -0
  21. data/lib/action_dispatch/templates/rescues/unknown_action.text.erb +3 -0
  22. data/lib/web_console.rb +17 -7
  23. data/lib/web_console/exception_extension.rb +22 -0
  24. data/lib/web_console/railtie.rb +15 -0
  25. data/lib/web_console/repl.rb +24 -0
  26. data/lib/web_console/repl_session.rb +90 -0
  27. data/lib/web_console/version.rb +1 -1
  28. data/lib/web_console/view_helpers.rb +21 -0
  29. data/test/action_pack/exception_wrapper_test.rb +26 -0
  30. data/test/dummy/app/controllers/exception_test_controller.rb +11 -0
  31. data/test/dummy/app/controllers/helper_test_controller.rb +5 -0
  32. data/test/dummy/app/views/helper_test/index.html.erb +220 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +2 -0
  34. data/test/dummy/config/application.rb +0 -34
  35. data/test/dummy/config/routes.rb +3 -0
  36. data/test/dummy/db/development.sqlite3 +0 -0
  37. data/test/dummy/log/development.log +61270 -0
  38. data/test/dummy/log/test.log +3917 -0
  39. data/test/dummy/tmp/cache/assets/development/sprockets/038461854af2e8bccdb29768efd4768f +0 -0
  40. data/test/dummy/tmp/cache/assets/development/sprockets/0ec396634a5f6808b026257fd107c355 +0 -0
  41. data/test/dummy/tmp/cache/assets/development/sprockets/127a54171eea8d294e4673599861787d +0 -0
  42. data/{app/assets/stylesheets/web_console/application.css → test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705} +0 -0
  43. data/test/dummy/tmp/cache/assets/development/sprockets/17c571144b4e44da39bddb2d2c412414 +0 -0
  44. data/test/dummy/tmp/cache/assets/development/sprockets/1cb77d8cf661ccbc9de08f347c89b9f1 +0 -0
  45. data/test/dummy/tmp/cache/assets/development/sprockets/204edd12a29660722d4e0d8de9bd6652 +0 -0
  46. data/test/dummy/tmp/cache/assets/development/sprockets/2b96b037f3dfeccfe27113eb95b06ea1 +0 -0
  47. data/test/dummy/tmp/cache/assets/development/sprockets/2c853768baf811357d81d41bdfd05dcf +0 -0
  48. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  49. data/test/dummy/tmp/cache/assets/development/sprockets/314d48e543146f617c4d3439a4d8d40d +0 -0
  50. data/test/dummy/tmp/cache/assets/development/sprockets/34f21019a876722b8c24a6da4f0ef50b +0 -0
  51. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  52. data/{vendor/assets/javascripts/term.js → test/dummy/tmp/cache/assets/development/sprockets/36341e42f23669574fa1027d0958ff3e} +0 -0
  53. data/test/dummy/tmp/cache/assets/development/sprockets/44117154e909436e7eeaf10cdb18d2b4 +0 -0
  54. data/test/dummy/tmp/cache/assets/development/sprockets/496864a905d53afd8e176f29500f96a8 +0 -0
  55. data/test/dummy/tmp/cache/assets/development/sprockets/55b7b76605fdffe31d737d4ac1f1ef7b +0 -0
  56. data/test/dummy/tmp/cache/assets/development/sprockets/5ac98782fe3dfd0a766f75ce1801f0a0 +0 -0
  57. data/test/dummy/tmp/cache/assets/development/sprockets/6088d6f344b38303cc8028057d69e0f9 +0 -0
  58. data/test/dummy/tmp/cache/assets/development/sprockets/676dcf9b2d01b9dc7bd3183d8da88463 +0 -0
  59. data/test/dummy/tmp/cache/assets/development/sprockets/680381170dc160e358fc28076ea6886c +0 -0
  60. data/test/dummy/tmp/cache/assets/development/sprockets/6ad7acc9a22fe2a67ec24a1fc866c20e +0 -0
  61. data/test/dummy/tmp/cache/assets/development/sprockets/6bdb0d0c602e0e1bc304dc697e2cc6de +0 -0
  62. data/test/dummy/tmp/cache/assets/development/sprockets/6dc8d7aa69668fce85683aaad6615432 +0 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/6e4d5b32cc444226f6597198994ccd5e +0 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/74db0ca5cb8c8c347c9131a3ff516748 +0 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/7999e525c88173c1beb785f002effc1d +0 -0
  66. data/{lib/assets/javascripts/web_console.js → test/dummy/tmp/cache/assets/development/sprockets/7a50a9e605754e99783de95715b976b0} +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/806b0e33a2fe8e1245534345fa27c30a +0 -0
  68. data/{app/assets/javascripts/web_console/console_sessions.js → test/dummy/tmp/cache/assets/development/sprockets/8aa4c7aabff23c8089d41e9e54193483} +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/90396626cba6cbec37e32038e6c54e76 +0 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/976b28910aa72c90a3b30c6e940f51df +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/99e1bd7cbc437505bc8f07bc528c721c +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/aaccf2c9ae2add0863c9a49e0042a097 +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/ae4677d24a79d9411f2fced5011d5807 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/b2401118729720034b6f3eda0b4c5025 +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/c649837df826fc310cb80f1adafd6b8d +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/cac185d59612fae451a12df3fc21bb51 +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/cb0065359d3b5b296f71d673f4b276e9 +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/cee8c6b09c33d2b276753e959712724e +0 -0
  79. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  80. data/test/dummy/tmp/cache/assets/development/sprockets/d1f6e06bc2f112c4ec3a4c3f68351878 +0 -0
  81. data/test/dummy/tmp/cache/assets/development/sprockets/d20d83fd7ffa378b1b2b901786d640f3 +0 -0
  82. data/test/dummy/tmp/cache/assets/development/sprockets/d38c7c3aa1e72b55769ccb3607641ef4 +0 -0
  83. data/test/dummy/tmp/cache/assets/development/sprockets/d6b85d8b0b5c569388b89e56e9f6fed7 +0 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/d982412def520c434e2240eae6d29cf2 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/df048a8b0897b9c04acdf59c8f95b18f +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/df600f50f002512c95d93bcfbab891ed +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/e6d6b8bde546349764be7b44ffcf5807 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/eb25265794d2f7afd1684779d84efdac +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/ee8826b12b7d9bfd717df950b58f82ab +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/ef9824789c6ed3483590e0564a12e1d1 +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/fc7201c6cbef32453aa4175c520c8eae +0 -0
  94. data/test/dummy/tmp/cache/assets/test/sprockets/17c571144b4e44da39bddb2d2c412414 +0 -0
  95. data/test/dummy/tmp/cache/assets/test/sprockets/36341e42f23669574fa1027d0958ff3e +0 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/55b7b76605fdffe31d737d4ac1f1ef7b +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/5ac98782fe3dfd0a766f75ce1801f0a0 +0 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/680381170dc160e358fc28076ea6886c +0 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/6ad7acc9a22fe2a67ec24a1fc866c20e +0 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/6e4d5b32cc444226f6597198994ccd5e +0 -0
  101. data/test/dummy/tmp/cache/assets/test/sprockets/7a50a9e605754e99783de95715b976b0 +0 -0
  102. data/test/dummy/tmp/cache/assets/test/sprockets/8aa4c7aabff23c8089d41e9e54193483 +0 -0
  103. data/test/dummy/tmp/cache/assets/test/sprockets/b2401118729720034b6f3eda0b4c5025 +0 -0
  104. data/test/dummy/tmp/cache/assets/test/sprockets/cb0065359d3b5b296f71d673f4b276e9 +0 -0
  105. data/test/dummy/tmp/cache/assets/test/sprockets/d1f6e06bc2f112c4ec3a4c3f68351878 +0 -0
  106. data/test/dummy/tmp/cache/assets/test/sprockets/d6b85d8b0b5c569388b89e56e9f6fed7 +0 -0
  107. data/test/dummy/tmp/cache/assets/test/sprockets/d982412def520c434e2240eae6d29cf2 +0 -0
  108. data/test/dummy/tmp/cache/assets/test/sprockets/df048a8b0897b9c04acdf59c8f95b18f +0 -0
  109. data/test/dummy/tmp/cache/assets/test/sprockets/e6d6b8bde546349764be7b44ffcf5807 +0 -0
  110. data/test/web_console/exception_extention_test.rb +16 -0
  111. data/test/web_console/repl_session_test.rb +32 -0
  112. data/test/web_console/repl_test.rb +26 -0
  113. metadata +191 -58
  114. data/app/assets/javascripts/web_console/application.js +0 -1
  115. data/app/assets/stylesheets/web_console/console_sessions.css.erb +0 -6
  116. data/app/controllers/web_console/application_controller.rb +0 -13
  117. data/app/controllers/web_console/console_sessions_controller.rb +0 -43
  118. data/app/helpers/web_console/application_helper.rb +0 -4
  119. data/app/helpers/web_console/console_session_helper.rb +0 -4
  120. data/app/models/web_console/console_session.rb +0 -96
  121. data/app/views/layouts/web_console/application.html.erb +0 -14
  122. data/app/views/web_console/console_sessions/index.html.erb +0 -15
  123. data/config/routes.rb +0 -11
  124. data/lib/assets/javascripts/web-console.js +0 -1
  125. data/lib/web_console/colors.rb +0 -87
  126. data/lib/web_console/colors/light.rb +0 -24
  127. data/lib/web_console/colors/monokai.rb +0 -24
  128. data/lib/web_console/colors/solarized.rb +0 -47
  129. data/lib/web_console/colors/tango.rb +0 -24
  130. data/lib/web_console/colors/xterm.rb +0 -24
  131. data/lib/web_console/engine.rb +0 -77
  132. data/lib/web_console/slave.rb +0 -139
  133. data/test/controllers/web_console/console_sessions_controller_test.rb +0 -95
  134. data/test/helpers/web_console/console_session_helper_test.rb +0 -6
  135. data/test/models/console_session_test.rb +0 -58
  136. data/test/web_console/colors_test.rb +0 -58
  137. data/test/web_console/engine_test.rb +0 -136
  138. data/test/web_console/slave_test.rb +0 -71
@@ -1,77 +0,0 @@
1
- require 'ipaddr'
2
- require 'active_support/core_ext/numeric/time'
3
- require 'rails/engine'
4
-
5
- require 'active_model'
6
- require 'sprockets/rails'
7
-
8
- module WebConsole
9
- class Engine < ::Rails::Engine
10
- isolate_namespace WebConsole
11
-
12
- config.web_console = ActiveSupport::OrderedOptions.new.tap do |c|
13
- c.automount = true
14
- c.command = nil
15
- c.default_mount_path = '/console'
16
- c.timeout = 0.seconds
17
- c.term = 'xterm-color'
18
- c.whitelisted_ips = '127.0.0.1'
19
-
20
- c.style = ActiveSupport::OrderedOptions.new.tap do |s|
21
- s.colors = 'light'
22
- s.font = 'large DejaVu Sans Mono, Liberation Mono, monospace'
23
- end
24
- end
25
-
26
- initializer 'web_console.add_default_route' do |app|
27
- # While we don't need the route in the test environment, we define it
28
- # there as well, so we can easily test it.
29
- if config.web_console.automount && (Rails.env.development? || Rails.env.test?)
30
- app.routes.append do
31
- mount WebConsole::Engine => app.config.web_console.default_mount_path
32
- end
33
- end
34
- end
35
-
36
- initializer 'web_console.process_whitelisted_ips' do
37
- config.web_console.tap do |c|
38
- # Ensure that it is an array of IPAddr instances and it is defaulted to
39
- # 127.0.0.1 if not precent. Only unique entries are left in the end.
40
- c.whitelisted_ips = Array(c.whitelisted_ips).map do |ip|
41
- ip.is_a?(IPAddr) ? ip : IPAddr.new(ip.presence || '127.0.0.1')
42
- end.uniq
43
-
44
- # IPAddr instances can cover whole networks, so simplify the #include?
45
- # check for the most common case.
46
- def (c.whitelisted_ips).include?(ip)
47
- ip.is_a?(IPAddr) ? super : any? { |net| net.include?(ip.to_s) }
48
- end
49
- end
50
- end
51
-
52
- initializer 'web_console.process_command' do
53
- config.web_console.tap do |c|
54
- # +Rails.root+ is not available while we set the default values of the
55
- # other options. Default it during initialization.
56
-
57
- # Not all people created their Rails 4 applications with the Rails 4
58
- # generator, so bin/rails may not be available.
59
- if c.command.blank?
60
- local_rails = Rails.root.join('bin/rails')
61
- c.command = "#{local_rails.executable? ? local_rails : 'rails'} console"
62
- end
63
- end
64
- end
65
-
66
- initializer 'web_console.process_colors' do
67
- config.web_console.style.tap do |c|
68
- case colors = c.colors
69
- when Symbol, String
70
- c.colors = Colors[colors] || Colors.default
71
- else
72
- c.colors = Colors.new(colors)
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,139 +0,0 @@
1
- require 'pty'
2
- require 'io/console'
3
-
4
- module WebConsole
5
- # = Slave\ Process\ Wrapper
6
- #
7
- # Creates and communicates with slave processses.
8
- #
9
- # The communication happens through an input with attached psuedo-terminal.
10
- # All of the communication is done in asynchrouns way, meaning that when you
11
- # send input to the process, you have get the output by polling for it.
12
- class Slave
13
- # Different OS' and platforms raises different errors when trying to read
14
- # on output end of a closed process.
15
- READING_ON_CLOSED_END_ERRORS = [ Errno::EIO, EOFError ]
16
-
17
- # Raised when trying to read from a closed (exited) process.
18
- Closed = Class.new(IOError)
19
-
20
- # The slave process id.
21
- attr_reader :pid
22
-
23
- def initialize(command = WebConsole.config.command, options = {})
24
- using_term(options[:term] || WebConsole.config.term) do
25
- @output, @input, @pid = PTY.spawn(command.to_s)
26
- end
27
- configure(options)
28
- end
29
-
30
- # Configure the psuedo terminal properties.
31
- #
32
- # Options:
33
- # :width The width of the terminal in number of columns.
34
- # :height The height of the terminal in number of rows.
35
- #
36
- # If any of the width or height is missing (or zero), the termininal size
37
- # won't be set.
38
- def configure(options = {})
39
- dimentions = options.values_at(:height, :width).collect(&:to_i)
40
- @input.winsize = dimentions unless dimentions.any?(&:zero?)
41
- end
42
-
43
- # Sends input to the slave process STDIN.
44
- #
45
- # Returns immediately.
46
- def send_input(input)
47
- raise ArgumentError if input.nil? or input.try(:empty?)
48
- input.each_char { |char| @input.putc(char) }
49
- end
50
-
51
- # Returns whether the slave process has any pending output in +wait+
52
- # seconds.
53
- #
54
- # By default, the +timeout+ follows +config.web_console.timeout+. Usually,
55
- # it is zero, making the response immediate.
56
- def pending_output?(timeout = WebConsole.config.timeout)
57
- # JRuby's select won't automatically coerce ActiveSupport::Duration.
58
- !!IO.select([@output], [], [], timeout.to_i)
59
- end
60
-
61
- # Gets the pending output of the process.
62
- #
63
- # The pending output is read in an non blocking way by chunks, in the size
64
- # of +chunk_len+. By default, +chunk_len+ is 49152 bytes.
65
- #
66
- # Returns +nil+, if there is no pending output at the moment. Otherwise,
67
- # returns the output that hasn't been read since the last invocation.
68
- #
69
- # Raises Errno:EIO on closed output stream. This can happen if the
70
- # underlying process exits.
71
- def pending_output(chunk_len = 49152)
72
- # Returns nil if there is no pending output.
73
- return unless pending_output?
74
-
75
- pending = String.new
76
- while chunk = @output.read_nonblock(chunk_len)
77
- pending << chunk
78
- end
79
- pending.force_encoding('UTF-8')
80
- rescue IO::WaitReadable
81
- pending.force_encoding('UTF-8')
82
- rescue
83
- raise Closed if READING_ON_CLOSED_END_ERRORS.any? { |exc| $!.is_a?(exc) }
84
- end
85
-
86
- # Dispose the underlying process, sending +SIGTERM+.
87
- #
88
- # After the process is disposed, it is detached from the parent to prevent
89
- # zombies.
90
- #
91
- # If the process is already disposed an Errno::ESRCH will be raised and
92
- # handled internally. If you want to handle Errno::ESRCH yourself, pass
93
- # +{raise: true}+ as options.
94
- #
95
- # Returns a thread, which can be used to wait for the process termination.
96
- def dispose(options = {})
97
- dispose_with(:SIGTERM, options)
98
- end
99
-
100
- # Dispose the underlying process, sending +SIGKILL+.
101
- #
102
- # After the process is disposed, it is detached from the parent to prevent
103
- # zombies.
104
- #
105
- # If the process is already disposed an Errno::ESRCH will be raised and
106
- # handled internally. If you want to handle Errno::ESRCH yourself, pass
107
- # +{raise: true}+ as options.
108
- #
109
- # Returns a thread, which can be used to wait for the process termination.
110
- def dispose!(options = {})
111
- dispose_with(:SIGKILL, options)
112
- end
113
-
114
- private
115
-
116
- LOCK = Mutex.new
117
-
118
- def using_term(term)
119
- if term.nil?
120
- yield
121
- else
122
- LOCK.synchronize do
123
- begin
124
- (previous_term, ENV['TERM'] = ENV['TERM'], term) and yield
125
- ensure
126
- ENV['TERM'] = previous_term
127
- end
128
- end
129
- end
130
- end
131
-
132
- def dispose_with(signal, options = {})
133
- Process.kill(signal, @pid)
134
- Process.detach(@pid)
135
- rescue Errno::ESRCH
136
- raise if options[:raise]
137
- end
138
- end
139
- end
@@ -1,95 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class ConsoleSessionsControllerTest < ActionController::TestCase
5
- setup do
6
- PTY.stubs(:spawn).returns([StringIO.new, StringIO.new, Random.rand(20000)])
7
- @request.stubs(:remote_ip).returns('127.0.0.1')
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 'GET 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 'PUT input validates for missing input' do
22
- get :index, use_route: 'web_console'
23
-
24
- assert_not_nil console_session = assigns(:console_session)
25
-
26
- console_session.instance_variable_get(:@slave).stubs(:send_input).raises(ArgumentError)
27
- put :input, id: console_session.pid, use_route: 'web_console'
28
-
29
- assert_response :unprocessable_entity
30
- end
31
-
32
- test 'PUT input sends input to the slave' do
33
- get :index, use_route: 'web_console'
34
-
35
- assert_not_nil console_session = assigns(:console_session)
36
-
37
- console_session.expects(:send_input)
38
- put :input, input: ' ', id: console_session.pid, use_route: 'web_console'
39
- end
40
-
41
- test 'GET pending_output gives the slave pending output' do
42
- get :index, use_route: 'web_console'
43
-
44
- assert_not_nil console_session = assigns(:console_session)
45
- console_session.expects(:pending_output)
46
-
47
- get :pending_output, id: console_session.pid, use_route: 'web_console'
48
- end
49
-
50
- test 'GET pending_output raises 410 on exitted slave processes' do
51
- get :index, use_route: 'web_console'
52
-
53
- assert_not_nil console_session = assigns(:console_session)
54
- console_session.stubs(:pending_output).raises(ConsoleSession::Unavailable)
55
-
56
- get :pending_output, id: console_session.pid, use_route: 'web_console'
57
- assert_response :gone
58
- end
59
-
60
- test 'PUT configuration adjust the terminal size' do
61
- get :index, use_route: 'web_console'
62
-
63
- assert_not_nil console_session = assigns(:console_session)
64
- console_session.expects(:configure).with('id' => console_session.pid.to_s, 'width' => '80', 'height' => '24')
65
-
66
- put :configuration, id: console_session.pid, width: 80, height: 24, use_route: 'web_console'
67
- assert_response :success
68
- end
69
-
70
- test 'blocks requests from non-whitelisted ips' do
71
- @request.stubs(:remote_ip).returns('128.0.0.1')
72
- get :index, use_route: 'web_console'
73
- assert_response :unauthorized
74
- end
75
-
76
- test 'allows requests from whitelisted ips' do
77
- @request.stubs(:remote_ip).returns('127.0.0.1')
78
- get :index, use_route: 'web_console'
79
- assert_response :success
80
- end
81
-
82
- test 'index generated path' do
83
- assert_generates mount_path, {
84
- use_route: 'web_console',
85
- controller: 'console_sessions'
86
- }, {}, {controller: 'console_sessions'}
87
- end
88
-
89
- private
90
-
91
- def mount_path
92
- WebConsole::Engine.config.web_console.default_mount_path
93
- end
94
- end
95
- end
@@ -1,6 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class ConsoleHelperTest < ActionView::TestCase
5
- end
6
- end
@@ -1,58 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class ConsoleSessionTest < ActionView::TestCase
5
- include ActiveModel::Lint::Tests
6
-
7
- setup do
8
- PTY.stubs(:spawn).returns([StringIO.new, StringIO.new, Random.rand(20000)])
9
- ConsoleSession::INMEMORY_STORAGE.clear
10
- @model1 = @model = ConsoleSession.new
11
- @model2 = ConsoleSession.new
12
- end
13
-
14
- test 'raises ConsoleSession::Unavailable on not found sessions' do
15
- assert_raises(ConsoleSession::Unavailable) { ConsoleSession.find(-1) }
16
- end
17
-
18
- test 'find coerces ids' do
19
- assert_equal @model.persist, ConsoleSession.find("#{@model.pid}")
20
- end
21
-
22
- test 'not found exceptions are json serializable' do
23
- exception = assert_raises(ConsoleSession::Unavailable) { ConsoleSession.find(-1) }
24
- assert_equal '{"error":"Session unavailable"}', exception.to_json
25
- end
26
-
27
- test 'can be used as slave as the methods are delegated' do
28
- slave_methods = Slave.instance_methods - @model.methods
29
- slave_methods.each { |method| assert @model.respond_to?(method) }
30
- end
31
-
32
- test 'slave methods are cached on the singleton' do
33
- assert_not @model.singleton_methods.include?(:pending_output?)
34
- @model.pending_output? rescue nil
35
- assert @model.singleton_methods.include?(:pending_output?)
36
- end
37
-
38
- test 'persisted models knows that they are in memory' do
39
- assert_not @model.persisted?
40
- @model.persist
41
- assert @model.persisted?
42
- end
43
-
44
- test 'persisted models knows about their keys' do
45
- assert_nil @model.to_key
46
- @model.persist
47
- assert_not_nil @model.to_key
48
- end
49
-
50
- test 'create gives already persisted models' do
51
- assert ConsoleSession.create.persisted?
52
- end
53
-
54
- test 'no gives not persisted models' do
55
- assert_not ConsoleSession.new.persisted?
56
- end
57
- end
58
- end
@@ -1,58 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class ColorsTest < ActiveSupport::TestCase
5
- setup do
6
- @colors = Colors.new %w( #7f7f7f #ff0000 #00ff00 #ffff00 #5c5cff #ff00ff #00ffff #ffffff )
7
- end
8
-
9
- test '.[] is an alias for .themes#[]' do
10
- @colors.class.themes.expects(:[]).with(:light).once
11
- @colors.class[:light]
12
- end
13
-
14
- test '.register_theme creates Colors instance for the block' do
15
- @colors.class.register_theme(:test) { |c| assert c.is_a?(Colors) }
16
- end
17
-
18
- test '#background is the first color if not specified' do
19
- assert_equal '#7f7f7f', @colors.background
20
- end
21
-
22
- test '#background can be explicitly specified' do
23
- @colors.background '#00ff00'
24
- assert_equal '#00ff00', @colors.background
25
- end
26
-
27
- test '#background= is an alias of #background' do
28
- @colors.background = '#00ff00'
29
- assert_equal '#00ff00', @colors.background
30
- end
31
-
32
- test '#foreground is the last color if not specified' do
33
- assert_equal '#ffffff', @colors.foreground
34
- end
35
-
36
- test '#foreground can be explicitly specified' do
37
- @colors.foreground '#f0f0f0'
38
- assert_equal '#f0f0f0', @colors.foreground
39
- end
40
-
41
- test '#foreground= is an alias of #foreground' do
42
- @colors.foreground = '#f0f0f0'
43
- assert_equal '#f0f0f0', @colors.foreground
44
- end
45
-
46
- test '#to_json includes the background and the foreground' do
47
- @colors.background = '#00ff00'
48
- @colors.foreground = '#f0f0f0'
49
-
50
- expected_json = '["#7f7f7f","#ff0000","#00ff00","#ffff00","#5c5cff","#ff00ff","#00ffff","#ffffff","#00ff00","#f0f0f0"]'
51
- assert_equal expected_json, @colors.to_json
52
- end
53
-
54
- test '#default is :light' do
55
- assert_equal @colors.class.default, @colors.class.themes[:light]
56
- end
57
- end
58
- end
@@ -1,136 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class EngineTest < ActiveSupport::TestCase
5
- test 'custom default_mount_path' do
6
- new_uninitialized_app do |app|
7
- app.config.web_console.default_mount_path = '/shell'
8
- app.initialize!
9
-
10
- assert app.routes.named_routes['web_console'].path.match('/shell')
11
- end
12
- end
13
-
14
- test 'disabling automounting' do
15
- new_uninitialized_app do |app|
16
- app.config.web_console.automount = false
17
- app.initialize!
18
-
19
- assert_not app.routes.named_routes['web_console']
20
- end
21
- end
22
-
23
- test 'blank commands are expanded to the rails console' do
24
- new_uninitialized_app do |app|
25
- app.config.web_console.command = ' '
26
- app.initialize!
27
-
28
- expected_path = Rails.root.join('bin/rails console').to_s
29
- assert_equal expected_path, app.config.web_console.command
30
- end
31
- end
32
-
33
- test 'present commands are not processed' do
34
- new_uninitialized_app do |app|
35
- app.config.web_console.command = '/bin/login'
36
- app.initialize!
37
-
38
- assert_equal '/bin/login', app.config.web_console.command
39
- end
40
- end
41
-
42
- test 'whitelisted ips are courced to IPAddr' do
43
- new_uninitialized_app do |app|
44
- app.config.web_console.whitelisted_ips = '127.0.0.1'
45
- app.initialize!
46
-
47
- assert_equal [ IPAddr.new('127.0.0.1') ], app.config.web_console.whitelisted_ips
48
- end
49
- end
50
-
51
- test 'whitelisted ips are normalized and unique IPAddr' do
52
- new_uninitialized_app do |app|
53
- app.config.web_console.whitelisted_ips = [ '127.0.0.1', '127.0.0.1', nil, '', ' ' ]
54
- app.initialize!
55
-
56
- assert_equal [ IPAddr.new('127.0.0.1') ], app.config.web_console.whitelisted_ips
57
- end
58
- end
59
-
60
- test 'whitelisted_ips.include? coerces to IPAddr' do
61
- new_uninitialized_app do |app|
62
- app.config.web_console.whitelisted_ips = '127.0.0.1'
63
- app.initialize!
64
-
65
- assert app.config.web_console.whitelisted_ips.include?('127.0.0.1')
66
- end
67
- end
68
-
69
- test 'whitelisted_ips.include? works with IPAddr' do
70
- new_uninitialized_app do |app|
71
- app.config.web_console.whitelisted_ips = '127.0.0.1'
72
- app.initialize!
73
-
74
- assert app.config.web_console.whitelisted_ips.include?(IPAddr.new('127.0.0.1'))
75
- end
76
- end
77
-
78
- test 'whitelist whole networks' do
79
- new_uninitialized_app do |app|
80
- app.config.web_console.whitelisted_ips = '172.16.0.0/12'
81
- app.initialize!
82
-
83
- 1.upto(255).each do |n|
84
- assert_includes app.config.web_console.whitelisted_ips, "172.16.0.#{n}"
85
- end
86
- end
87
- end
88
-
89
- test 'whitelist multiple networks' do
90
- new_uninitialized_app do |app|
91
- app.config.web_console.whitelisted_ips = %w( 172.16.0.0/12 192.168.0.0/16 )
92
- app.initialize!
93
-
94
- 1.upto(255).each do |n|
95
- assert_includes app.config.web_console.whitelisted_ips, "172.16.0.#{n}"
96
- assert_includes app.config.web_console.whitelisted_ips, "192.168.0.#{n}"
97
- end
98
- end
99
- end
100
-
101
- private
102
-
103
- def new_uninitialized_app(root = File.expand_path('../../dummy', __FILE__))
104
- skip if Rails::VERSION::MAJOR == 3
105
-
106
- old_app = Rails.application
107
-
108
- FileUtils.mkdir_p(root)
109
- Dir.chdir(root) do
110
- Rails.application = nil
111
-
112
- app = Class.new(Rails::Application)
113
- app.config.eager_load = false
114
- app.config.time_zone = 'UTC'
115
- app.config.middleware ||= Rails::Configuration::MiddlewareStackProxy.new
116
- app.config.active_support.deprecation = :notify
117
-
118
- yield app
119
- end
120
- ensure
121
- Rails.application = old_app
122
- end
123
-
124
- def teardown_fixtures(*)
125
- super
126
- rescue
127
- # This is nasty hack to prevent a connection to the database in JRuby's
128
- # activerecord-jdbcsqlite3-adapter. We don't really require a database
129
- # connection, for the tests to run.
130
- #
131
- # The sad thing is that I couldn't figure out why does it only happens
132
- # on activerecord-jdbcsqlite3-adapter and how to actually prevent it,
133
- # rather than work-around it.
134
- end
135
- end
136
- end