web-console 1.0.4 → 2.0.0.beta1

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.
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