web-console 2.1.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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