web-console 2.1.3 → 2.2.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.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +45 -0
  3. data/README.markdown +26 -6
  4. data/Rakefile +37 -0
  5. data/lib/web_console/extensions.rb +2 -1
  6. data/lib/web_console/integration/cruby.rb +2 -1
  7. data/lib/web_console/integration/rubinius.rb +2 -1
  8. data/lib/web_console/railtie.rb +19 -1
  9. data/lib/web_console/session.rb +4 -3
  10. data/lib/web_console/templates/_inner_console_markup.html.erb +8 -3
  11. data/lib/web_console/templates/console.js.erb +169 -46
  12. data/lib/web_console/templates/error_page.js.erb +2 -15
  13. data/lib/web_console/templates/main.js.erb +1 -24
  14. data/lib/web_console/templates/style.css.erb +22 -9
  15. data/lib/web_console/tracer.rb +11 -0
  16. data/lib/web_console/version.rb +1 -1
  17. metadata +5 -155
  18. data/test/dummy/README.rdoc +0 -28
  19. data/test/dummy/Rakefile +0 -6
  20. data/test/dummy/app/assets/javascripts/application.js +0 -13
  21. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  22. data/test/dummy/app/controllers/application_controller.rb +0 -5
  23. data/test/dummy/app/controllers/controller_helper_test_controller.rb +0 -7
  24. data/test/dummy/app/controllers/exception_test_controller.rb +0 -15
  25. data/test/dummy/app/controllers/helper_error_controller.rb +0 -4
  26. data/test/dummy/app/controllers/helper_test_controller.rb +0 -5
  27. data/test/dummy/app/controllers/tests_controller.rb +0 -16
  28. data/test/dummy/app/helpers/application_helper.rb +0 -2
  29. data/test/dummy/app/views/controller_helper_test/index.html.erb +0 -1
  30. data/test/dummy/app/views/exception_test/xhr.html.erb +0 -1
  31. data/test/dummy/app/views/helper_error/index.html.erb +0 -2
  32. data/test/dummy/app/views/helper_test/index.html.erb +0 -220
  33. data/test/dummy/app/views/layouts/application.html.erb +0 -16
  34. data/test/dummy/bin/bundle +0 -3
  35. data/test/dummy/bin/rails +0 -4
  36. data/test/dummy/bin/rake +0 -4
  37. data/test/dummy/config.ru +0 -4
  38. data/test/dummy/config/application.rb +0 -19
  39. data/test/dummy/config/boot.rb +0 -5
  40. data/test/dummy/config/database.yml +0 -25
  41. data/test/dummy/config/environment.rb +0 -5
  42. data/test/dummy/config/environments/development.rb +0 -29
  43. data/test/dummy/config/environments/production.rb +0 -80
  44. data/test/dummy/config/environments/test.rb +0 -34
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  46. data/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  47. data/test/dummy/config/initializers/inflections.rb +0 -16
  48. data/test/dummy/config/initializers/mime_types.rb +0 -5
  49. data/test/dummy/config/initializers/secret_token.rb +0 -12
  50. data/test/dummy/config/initializers/session_store.rb +0 -3
  51. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  52. data/test/dummy/config/locales/en.yml +0 -23
  53. data/test/dummy/config/routes.rb +0 -15
  54. data/test/dummy/db/schema.rb +0 -16
  55. data/test/dummy/db/test.sqlite3 +0 -0
  56. data/test/dummy/log/test.log +0 -808
  57. data/test/dummy/public/404.html +0 -58
  58. data/test/dummy/public/422.html +0 -58
  59. data/test/dummy/public/500.html +0 -57
  60. data/test/dummy/public/favicon.ico +0 -0
  61. data/test/dummy/tmp/cache/assets/test/sprockets/0c9b99b1b975b36a5b686845ae729db3 +0 -0
  62. data/test/dummy/tmp/cache/assets/test/sprockets/12e9f58adcf819cf65fd68b6859a438f +0 -0
  63. data/test/dummy/tmp/cache/assets/test/sprockets/1fd6abead3df36a4e4a2cb042a551b39 +0 -0
  64. data/test/dummy/tmp/cache/assets/test/sprockets/33b5eb81b5aaaa1e6dd5dcb6517792b4 +0 -0
  65. data/test/dummy/tmp/cache/assets/test/sprockets/3e460b2e021085f88b5597b38d194932 +0 -0
  66. data/test/dummy/tmp/cache/assets/test/sprockets/52f04b2ea6e461f4661b6d0be393fa94 +0 -0
  67. data/test/dummy/tmp/cache/assets/test/sprockets/688c344c2919f882338f06c5daaea209 +0 -0
  68. data/test/dummy/tmp/cache/assets/test/sprockets/7f079298e19bbef40a5d6a37dc03033a +0 -0
  69. data/test/dummy/tmp/cache/assets/test/sprockets/91aa709f89e465f58056fabe5f75eef4 +0 -0
  70. data/test/dummy/tmp/cache/assets/test/sprockets/95f4e4e5217aec9f71b2c1a65a9a9231 +0 -0
  71. data/test/dummy/tmp/cache/assets/test/sprockets/9c41be9b6625756fbb6d05b7665dd911 +0 -0
  72. data/test/dummy/tmp/cache/assets/test/sprockets/a95f64d41fcf8244b8f5b84a55f07822 +0 -0
  73. data/test/dummy/tmp/cache/assets/test/sprockets/c5e6bf1efd5929bee63e28ad7c9f6f83 +0 -0
  74. data/test/dummy/tmp/cache/assets/test/sprockets/d863259e9eeca657a1624135cfe24446 +0 -0
  75. data/test/dummy/tmp/cache/assets/test/sprockets/e1d2fc4601b6423ec8a42415ee05dd14 +0 -0
  76. data/test/dummy/tmp/cache/assets/test/sprockets/e82616536a759c2e87d703adc77d65da +0 -0
  77. data/test/support/scenarios/bad_custom_error_scenario.rb +0 -17
  78. data/test/support/scenarios/basic_nested_scenario.rb +0 -15
  79. data/test/support/scenarios/custom_error_scenario.rb +0 -11
  80. data/test/support/scenarios/eval_nested_scenario.rb +0 -15
  81. data/test/support/scenarios/flat_scenario.rb +0 -9
  82. data/test/support/scenarios/reraised_scenario.rb +0 -21
  83. data/test/test_helper.rb +0 -78
  84. data/test/web_console/evaluator_test.rb +0 -73
  85. data/test/web_console/extensions_test.rb +0 -28
  86. data/test/web_console/helper_test.rb +0 -76
  87. data/test/web_console/integration_test.rb +0 -47
  88. data/test/web_console/middleware_test.rb +0 -116
  89. data/test/web_console/railtie_test.rb +0 -99
  90. data/test/web_console/request_test.rb +0 -82
  91. data/test/web_console/session_test.rb +0 -59
  92. data/test/web_console/whiny_request_test.rb +0 -33
  93. data/test/web_console/whitelist_test.rb +0 -43
@@ -1,28 +0,0 @@
1
- require 'test_helper'
2
- require 'web_console/extensions'
3
-
4
- module ActionDispatch
5
- class DebugExceptionsTest < ActionDispatch::IntegrationTest
6
- class Application
7
- def call(env)
8
- ActionView::Base.new.render(inline: '<% @ivar = 42 %> <%= nil.raise %></h1')
9
- end
10
- end
11
-
12
- setup do
13
- Request.stubs(:whitelisted_ips).returns(IPAddr.new('0.0.0.0/0'))
14
-
15
- @app = DebugExceptions.new(Application.new)
16
- end
17
-
18
- test "follows ActionView::Template::Error original error in env['web_console.exception']" do
19
- get "/", {}, {
20
- 'action_dispatch.show_detailed_exceptions' => true,
21
- 'action_dispatch.show_exceptions' => true,
22
- 'action_dispatch.logger' => Logger.new(StringIO.new)
23
- }
24
-
25
- assert_equal 42, request.env['web_console.exception'].bindings.first.eval('@ivar')
26
- end
27
- end
28
- end
@@ -1,76 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class HelperTest < ActionDispatch::IntegrationTest
5
- class BaseApplication
6
- include Helper
7
-
8
- def call(env)
9
- Rack::Response.new(<<-HTML.strip_heredoc).finish
10
- <html>
11
- <head>
12
- <title>Hello world</title>
13
- </head>
14
- <body>
15
- <p id="hello-world">Hello world</p>
16
- </body>
17
- </html>
18
- HTML
19
- end
20
-
21
- private
22
-
23
- def request
24
- Request.new(@env)
25
- end
26
- end
27
-
28
- class SingleConsoleApplication < BaseApplication
29
- def call(env)
30
- @env = env
31
-
32
- console
33
-
34
- super
35
- end
36
- end
37
-
38
- class MultipleConsolesApplication < BaseApplication
39
- def call(env)
40
- @env = env
41
-
42
- console
43
- console
44
-
45
- super
46
- end
47
- end
48
-
49
- setup do
50
- Request.stubs(:whitelisted_ips).returns(IPAddr.new('0.0.0.0/0'))
51
-
52
- @app = Middleware.new(SingleConsoleApplication.new)
53
- end
54
-
55
- test 'renders a console into a view' do
56
- get '/', nil, 'CONTENT_TYPE' => 'text/html'
57
-
58
- assert_select '#console'
59
- end
60
-
61
- test 'raises an error when trying to spawn a console more than once' do
62
- @app = Middleware.new(MultipleConsolesApplication.new)
63
-
64
- assert_raises(DoubleRenderError) do
65
- get '/', nil, 'CONTENT_TYPE' => 'text/html'
66
- end
67
- end
68
-
69
- test "doesn't hijack current view" do
70
- get '/', nil, 'CONTENT_TYPE' => 'text/html'
71
-
72
- assert_select '#hello-world'
73
- assert_select '#console'
74
- end
75
- end
76
- end
@@ -1,47 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class IntegrationTest < ActiveSupport::TestCase
5
- test 'Exception#bindings returns all the bindings of where the error originated' do
6
- exc = FlatScenario.new.call
7
-
8
- assert_equal 4, exc.bindings.first.eval('__LINE__')
9
- end
10
-
11
- test 'Exception#bindings returns all the bindings for a custom error' do
12
- exc = CustomErrorScenario.new.call
13
-
14
- assert_equal 6, exc.bindings.first.eval('__LINE__')
15
- end
16
-
17
- test 'Exception#bindings returns all the bindings for a bad custom error' do
18
- exc = BadCustomErrorScenario.new.call
19
-
20
- assert_equal 11, exc.bindings.first.eval('__LINE__')
21
- end
22
-
23
- test 'Exception#bindings goes down the stack' do
24
- exc = BasicNestedScenario.new.call
25
-
26
- assert_equal 12, exc.bindings.first.eval('__LINE__')
27
- end
28
-
29
- test 'Exception#bindings inside of an eval' do
30
- exc = EvalNestedScenario.new.call
31
-
32
- assert_equal 12, exc.bindings.first.eval('__LINE__')
33
- end
34
-
35
- test "re-raising doesn't lose Exception#bindings information" do
36
- exc = ReraisedScenario.new.call
37
-
38
- assert_equal 4, exc.bindings.first.eval('__LINE__')
39
- end
40
-
41
- test 'Exception#bindings is empty when exception is still not raised' do
42
- exc = RuntimeError.new
43
-
44
- assert_equal [], exc.bindings
45
- end
46
- end
47
- end
@@ -1,116 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class MiddlewareTest < ActionDispatch::IntegrationTest
5
- class Application
6
- def call(env)
7
- Rack::Response.new(<<-HTML.strip_heredoc).finish
8
- <html>
9
- <head>
10
- <title>Hello world</title>
11
- </head>
12
- <body>
13
- <p id="hello-world">Hello world</p>
14
- </body>
15
- </html>
16
- HTML
17
- end
18
- end
19
-
20
- setup do
21
- Request.stubs(:whitelisted_ips).returns(IPAddr.new('0.0.0.0/0'))
22
-
23
- @app = Middleware.new(Application.new)
24
- end
25
-
26
- test 'render console in an html application from web_console.binding' do
27
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'web_console.binding' => binding
28
-
29
- assert_select '#console'
30
- end
31
-
32
- test 'render console in an html application from web_console.exception' do
33
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'web_console.exception' => raise_exception
34
-
35
- assert_select '#console'
36
- end
37
-
38
- test 'prioritizes web_console.exception over web_console.binding' do
39
- exception = raise_exception
40
-
41
- Session.expects(:from_exception).with(exception)
42
-
43
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'web_console.binding' => binding, 'web_console.exception' => exception
44
- end
45
-
46
- test 'render console in an html application with non text/html' do
47
- get '/', nil, 'CONTENT_TYPE' => 'application/xhtml+xml', 'web_console.binding' => binding
48
-
49
- assert_select '#console'
50
- end
51
-
52
- test "doesn't render console in non html application" do
53
- get '/', nil, 'CONTENT_TYPE' => 'application/json', 'web-console.binding' => binding
54
-
55
- assert_select '#console', 0
56
- end
57
-
58
- test "doesn't render console from non whitelisted IP" do
59
- Request.stubs(:whitelisted_ips).returns(IPAddr.new('127.0.0.1'))
60
-
61
- silence(:stderr) do
62
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'REMOTE_ADDR' => '1.1.1.1', 'web-console.binding' => binding
63
- end
64
-
65
- assert_select '#console', 0
66
- end
67
-
68
- test "doesn't render console without a web_console.binding or web_console.exception" do
69
- get '/', nil, 'CONTENT_TYPE' => 'text/html'
70
-
71
- assert_select '#console', 0
72
- end
73
-
74
- test 'can evaluate code and return it as a JSON' do
75
- session, line = Session.new(binding), __LINE__
76
-
77
- Session.stubs(:from_binding).returns(session)
78
-
79
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'web-console.binding' => binding
80
- xhr :put, "/repl_sessions/#{session.id}", { input: '__LINE__' }
81
-
82
- assert_equal({ output: "=> #{line}\n" }.to_json, response.body)
83
- end
84
-
85
- test 'can switch bindings on error pages' do
86
- session = Session.new(exception = raise_exception)
87
-
88
- Session.stubs(:from_exception).returns(session)
89
-
90
- get '/', nil, 'CONTENT_TYPE' => 'text/html', 'web-console.exception' => exception
91
- xhr :post, "/repl_sessions/#{session.id}/trace", { frame_id: 1 }
92
-
93
- assert_equal({ ok: true }.to_json, response.body)
94
- end
95
-
96
- test 'unavailable sessions respond to the user with a message' do
97
- xhr :put, '/repl_sessions/no_such_session', { input: '__LINE__' }
98
-
99
- assert_equal(404, response.status)
100
- end
101
-
102
- test 'unavailable sessions can occur on binding switch' do
103
- xhr :post, "/repl_sessions/no_such_session/trace", { frame_id: 1 }
104
-
105
- assert_equal(404, response.status)
106
- end
107
-
108
- private
109
-
110
- def raise_exception
111
- raise
112
- rescue => exc
113
- exc
114
- end
115
- end
116
- end
@@ -1,99 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class RailtieTest < ActiveSupport::TestCase
5
- test 'config.whitelisted_ips sets whitelisted networks' do
6
- new_uninitialized_app do |app|
7
- app.config.web_console.whitelisted_ips = %w( 172.16.0.0/12 192.168.0.0/16 )
8
- app.initialize!
9
-
10
- 1.upto(255).each do |n|
11
- assert_includes Request.whitelisted_ips, "172.16.0.#{n}"
12
- assert_includes Request.whitelisted_ips, "192.168.0.#{n}"
13
- end
14
- end
15
- end
16
-
17
- test 'config.whitelisted_ips always includes localhost' do
18
- new_uninitialized_app do |app|
19
- app.config.web_console.whitelisted_ips = '8.8.8.8'
20
- app.initialize!
21
-
22
- assert_includes Request.whitelisted_ips, '127.0.0.1'
23
- assert_includes Request.whitelisted_ips, '::1'
24
- assert_includes Request.whitelisted_ips, '8.8.8.8'
25
- end
26
- end
27
-
28
- test 'config.template_paths prepend paths if it exists' do
29
- new_uninitialized_app do |app|
30
- dirname = File.expand_path('..', __FILE__)
31
-
32
- app.config.web_console.template_paths = dirname
33
- app.initialize!
34
-
35
- assert_equal dirname, Template.template_paths.first
36
- end
37
- end
38
-
39
- test 'config.whiny_request removes extra logging' do
40
- new_uninitialized_app do |app|
41
- app.config.web_console.whiny_requests = false
42
- app.initialize!
43
-
44
- assert_not Middleware.whiny_requests
45
- end
46
- end
47
-
48
- test 'config.acceptable_content_types adds extra content types' do
49
- preserving_acceptable_content_type do
50
- new_uninitialized_app do |app|
51
- app.config.web_console.acceptable_content_types = [Mime::ALL]
52
- app.initialize!
53
-
54
- assert_includes Request.acceptable_content_types, Mime::ALL
55
- end
56
- end
57
- end
58
-
59
- private
60
-
61
- def new_uninitialized_app(root = File.expand_path('../../dummy', __FILE__))
62
- old_app = Rails.application
63
-
64
- FileUtils.mkdir_p(root)
65
- Dir.chdir(root) do
66
- Rails.application = nil
67
-
68
- app = Class.new(Rails::Application)
69
- app.config.eager_load = false
70
- app.config.time_zone = 'UTC'
71
- app.config.middleware ||= Rails::Configuration::MiddlewareStackProxy.new
72
- app.config.active_support.deprecation = :notify
73
-
74
- yield app
75
- end
76
- ensure
77
- Rails.application = old_app
78
- end
79
-
80
- def preserving_acceptable_content_type
81
- acceptable_content_types = Request.acceptable_content_types.dup
82
- yield
83
- ensure
84
- Request.acceptable_content_types = acceptable_content_types
85
- end
86
-
87
- def teardown_fixtures(*)
88
- super
89
- rescue
90
- # This is nasty hack to prevent a connection to the database in JRuby's
91
- # activerecord-jdbcsqlite3-adapter. We don't really require a database
92
- # connection, for the tests to run.
93
- #
94
- # The sad thing is that I couldn't figure out why does it only happens
95
- # on activerecord-jdbcsqlite3-adapter and how to actually prevent it,
96
- # rather than work-around it.
97
- end
98
- end
99
- end
@@ -1,82 +0,0 @@
1
- require 'test_helper'
2
-
3
- module WebConsole
4
- class RequestTest < ActiveSupport::TestCase
5
- setup do
6
- Request.stubs(:whitelisted_ips).returns(IPAddr.new('127.0.0.1'))
7
- end
8
-
9
- test '#from_whitelited_ip? is falsy for blacklisted IPs' do
10
- req = request('http://example.com', 'REMOTE_ADDR' => '0.0.0.0')
11
-
12
- assert_not req.from_whitelited_ip?
13
- end
14
-
15
- test '#from_whitelited_ip? is truthy for whitelisted IPs' do
16
- req = request('http://example.com', 'REMOTE_ADDR' => '127.0.0.1')
17
-
18
- assert req.from_whitelited_ip?
19
- end
20
-
21
- test '#from_whitelisted_ip? is truthy for whitelisted IPs via whitelisted proxies' do
22
- req = request('http://example.com', 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_X_FORWARDED_FOR' => '127.0.0.0')
23
-
24
- assert req.from_whitelited_ip?
25
- end
26
-
27
- test '#from_whitelisted_ip? is falsy for blacklisted IPs via whitelisted proxies' do
28
- req = request('http://example.com', 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_X_FORWARDED_FOR' => '0.0.0.0')
29
-
30
- assert_not req.from_whitelited_ip?
31
- end
32
-
33
- test '#from_whitelisted_ip? is falsy for lying blacklisted IPs via whitelisted proxies' do
34
- req = request('http://example.com', 'REMOTE_ADDR' => '127.0.0.1', 'HTTP_X_FORWARDED_FOR' => '10.0.0.0, 127.0.0.0')
35
-
36
- assert_not req.from_whitelited_ip?
37
- end
38
-
39
- test '#from_whitelisted_ip? is falsy for whitelisted IPs via blacklisted proxies' do
40
- req = request('http://example.com', 'REMOTE_ADDR' => '10.0.0.0', 'HTTP_X_FORWARDED_FOR' => '127.0.0.0')
41
-
42
- assert_not req.from_whitelited_ip?
43
- end
44
-
45
- test '#acceptable_content_type? is truthy for explicit HTML content type' do
46
- html = request('http://example.com', 'CONTENT_TYPE' => 'text/html')
47
- xhtml = request('http://example.com', 'CONTENT_TYPE' => 'application/xhtml+xml')
48
-
49
- [ html, xhtml ].each { |req| assert req.acceptable_content_type? }
50
- end
51
-
52
- test '#acceptable_content_type? is truthy for plain text content type' do
53
- req = request('http://example.com', 'CONTENT_TYPE' => 'text/plain')
54
-
55
- assert req.acceptable_content_type?
56
- end
57
-
58
- test '#acceptable_content_type? is truthy during form submission' do
59
- req = request('http://example.com', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded')
60
-
61
- assert req.acceptable_content_type?
62
- end
63
-
64
- test '#acceptable_content_type? is truthy for blank content type' do
65
- req = request('http://example.com', 'CONTENT_TYPE' => '')
66
-
67
- assert req.acceptable_content_type?
68
- end
69
-
70
- test '#acceptable_content_type? is falsy for non blank and non HTML content type' do
71
- req = request('http://example.com', 'CONTENT_TYPE' => 'application/json')
72
-
73
- assert_not req.acceptable_content_type?
74
- end
75
-
76
- private
77
-
78
- def request(*args)
79
- Request.new(Rack::MockRequest.env_for(*args))
80
- end
81
- end
82
- end