tobias-rack-webconsole 0.1.4

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.
@@ -0,0 +1,56 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ class AssetClass
5
+ include Rack::Webconsole::AssetHelpers
6
+ end
7
+
8
+ module Rack
9
+ describe Webconsole::AssetHelpers do
10
+
11
+ describe '#html_code' do
12
+ it 'loads the html code' do
13
+ asset_class = AssetClass.new
14
+ html = asset_class.html_code
15
+
16
+ html.must_match /console/
17
+ html.must_match /results/
18
+ html.must_match /form/
19
+ end
20
+ end
21
+
22
+ describe '#css_code' do
23
+ it 'loads the css code' do
24
+ asset_class = AssetClass.new
25
+ css = asset_class.css_code
26
+
27
+ css.must_match /<style/
28
+ css.must_match /text\/css/
29
+ css.must_match /#console/
30
+ end
31
+ end
32
+
33
+ describe '#js_code' do
34
+ it 'loads the js code' do
35
+ asset_class = AssetClass.new
36
+ js = asset_class.js_code
37
+
38
+ js.must_match /\$\("#rack-webconsole"\)/
39
+ js.must_match /escapeHTML/
40
+ end
41
+ end
42
+
43
+ describe '#render' do
44
+ it 'knows how to replace $ vars' do
45
+ asset_class = AssetClass.new
46
+
47
+ text = "test $test test $test"
48
+ asset_class.render(text, :test => "123").must_equal("test 123 test 123")
49
+
50
+ text = "test $var1 test $var2"
51
+ asset_class.render(text, :var1 => "123", :var2 => "321").must_equal("test 123 test 321")
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'ostruct'
4
+
5
+ module Rack
6
+ describe Webconsole::Assets do
7
+
8
+ it 'initializes with an app' do
9
+ @app = stub
10
+ @assets = Webconsole::Assets.new(@app)
11
+ @assets.instance_variable_get(:@app).must_equal @app
12
+ end
13
+
14
+ describe "#code" do
15
+ it 'injects the token, key_code, and context path' do
16
+ Webconsole::Repl.stubs(:token).returns('fake_generated_token')
17
+ Webconsole.key_code = "96"
18
+
19
+ @assets = Webconsole::Assets.new(nil)
20
+ assets_code = @assets.code('SCRIPT_NAME' => '/hambiscuit')
21
+
22
+ assets_code.must_match /fake_generated_token/
23
+ assets_code.must_match /event\.which == 96/
24
+ assets_code.must_match %r{/hambiscuit/webconsole}
25
+ end
26
+
27
+ end
28
+
29
+ describe "#call" do
30
+
31
+ describe 'when the call is not appropriate to inject the view code' do
32
+ # Different invalid cases
33
+ [
34
+ [200, {'Content-Type' => 'text/html'}, ['Whatever']],
35
+ [200, {'Content-Type' => 'text/plain'}, ['Hello World']],
36
+ [404, {'Content-Type' => 'text/html'}, ['Hello World']],
37
+ [404, {'Content-Type' => 'text/html'}, ['Hello, World']],
38
+
39
+ ].each do |invalid_response|
40
+ it 'passes the call untouched' do
41
+ @app = lambda { |env| invalid_response }
42
+
43
+ assets = Webconsole::Assets.new(@app)
44
+ assets.expects(:inject_code).never
45
+
46
+ assets.call({}).last.first.must_equal invalid_response.last.first
47
+ end
48
+ end
49
+ end
50
+
51
+ describe 'otherwise' do
52
+
53
+ it 'injects the view code before the body ending' do
54
+
55
+ valid_html = "<!DOCTYPE html>\n<html>\n<head>\n <title>Testapp</title>\n <link href=\"/assets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n <script src=\"/assets/application.js\" type=\"text/javascript\"></script>\n <meta content=\"authenticity_token\" name=\"csrf-param\" />\n<meta content=\"26Ls63zdKBiCXoqU5CuG6KqVbeMYydRqOuovP+DXx8g=\" name=\"csrf-token\" />\n</head>\n<body>\n\n<h1> Hello bitches </h1>\n\n<p> Lorem ipsum dolor sit amet. </p>\n\n\n</body>\n</html>\n"
56
+
57
+ html = [valid_html]
58
+
59
+ @app = lambda { |env| [200, {'Content-Type' => 'text/html'}, html] }
60
+
61
+ assets = Webconsole::Assets.new(@app)
62
+ response = assets.call({}).last.first
63
+
64
+ response.must_match /input name/m # html
65
+ response.must_match /text\/css/m # css
66
+ response.must_match /escapeHTML/m # js
67
+ end
68
+
69
+ it "works with Rails' particular conception of what a response is" do
70
+
71
+ valid_html = "<!DOCTYPE html>\n<html>\n<head>\n <title>Testapp</title>\n <link href=\"/assets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n <script src=\"/assets/application.js\" type=\"text/javascript\"></script>\n <meta content=\"authenticity_token\" name=\"csrf-param\" />\n<meta content=\"26Ls63zdKBiCXoqU5CuG6KqVbeMYydRqOuovP+DXx8g=\" name=\"csrf-token\" />\n</head>\n<body>\n\n<h1> Hello bitches </h1>\n\n<p> Lorem ipsum dolor sit amet. </p>\n\n\n</body>\n</html>\n"
72
+
73
+ @app = lambda { |env| [200, {'Content-Type' => 'text/html'}, OpenStruct.new({:body => valid_html})] }
74
+
75
+ assets = Webconsole::Assets.new(@app)
76
+
77
+ response = assets.call({}).last.first
78
+
79
+ response.must_match /input name/m # html
80
+ response.must_match /text\/css/m # css
81
+ response.must_match /escapeHTML/m # js
82
+ end
83
+
84
+ it 'exposes the request object to the console' do
85
+ valid_html = "<!DOCTYPE html>\n<html>\n<head>\n <title>Testapp</title>\n <link href=\"/assets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />\n <script src=\"/assets/application.js\" type=\"text/javascript\"></script>\n <meta content=\"authenticity_token\" name=\"csrf-param\" />\n<meta content=\"26Ls63zdKBiCXoqU5CuG6KqVbeMYydRqOuovP+DXx8g=\" name=\"csrf-token\" />\n</head>\n<body>\n\n<h1> Hello bitches </h1>\n\n<p> Lorem ipsum dolor sit amet. </p>\n\n\n</body>\n</html>\n"
86
+
87
+ @app = lambda { |env| [200, {'Content-Type' => 'text/html'}, OpenStruct.new({:body => valid_html})] }
88
+
89
+ env = {'PATH_INFO' => '/some_path'}
90
+ assets = Webconsole::Assets.new(@app)
91
+
92
+ assets.call(env)
93
+
94
+ Webconsole::Repl.request.env['PATH_INFO'].must_equal '/some_path'
95
+ end
96
+
97
+ end
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ module Rack
5
+ describe Webconsole::Repl do
6
+
7
+ it 'initializes with an app' do
8
+ @app = stub
9
+ @repl = Webconsole::Repl.new(@app)
10
+
11
+ @repl.instance_variable_get(:@app).must_equal @app
12
+ end
13
+
14
+ describe "#call" do
15
+ it 'evaluates the :query param in a sandbox and returns the result' do
16
+ @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
17
+ env = {}
18
+ Webconsole::Repl.stubs(:token).returns('abc')
19
+ request = OpenStruct.new(:params => {'query' => 'a = 4; a * 2', 'token' => 'abc'}, :post? => true)
20
+ Rack::Request.stubs(:new).returns request
21
+
22
+ @repl = Webconsole::Repl.new(@app)
23
+
24
+ response = @repl.call(env).last.first
25
+
26
+ MultiJson.decode(response)['result'].must_equal "8"
27
+ end
28
+
29
+ it 'maintains local state in subsequent calls thanks to an evil global variable' do
30
+ @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
31
+ env = {}
32
+ Webconsole::Repl.stubs(:token).returns('abc')
33
+ request = OpenStruct.new(:params => {'query' => 'a = 4', 'token' => 'abc'}, :post? => true)
34
+ Rack::Request.stubs(:new).returns request
35
+ @repl = Webconsole::Repl.new(@app)
36
+
37
+ @repl.call(env) # call 1 sets a to 4
38
+
39
+ request = OpenStruct.new(:params => {'query' => 'a * 8', 'token' => 'abc'}, :post? => true)
40
+ Rack::Request.stubs(:new).returns request
41
+
42
+ response = @repl.call(env).last.first # call 2 retrieves a and multiplies it by 8
43
+
44
+ MultiJson.decode(response)['result'].must_equal "32"
45
+ $sandbox.instance_variable_get(:@locals)[:a].must_equal 4
46
+ $sandbox.instance_variable_get(:@locals).size.must_equal 1
47
+ end
48
+
49
+ it "returns any found errors prepended with 'Error:'" do
50
+ @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
51
+ env = {}
52
+ Webconsole::Repl.stubs(:token).returns('abc')
53
+ request = OpenStruct.new(:params => {'query' => 'unknown_method', 'token' => 'abc'}, :post? => true)
54
+ Rack::Request.stubs(:new).returns request
55
+ @repl = Webconsole::Repl.new(@app)
56
+
57
+ response = @repl.call(env).last.first
58
+
59
+ MultiJson.decode(response)['result'].must_match /Error:/
60
+ end
61
+
62
+ it 'rejects non-post requests' do
63
+ @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
64
+ env = {}
65
+ Webconsole::Repl.stubs(:token).returns('abc')
66
+ request = OpenStruct.new(:params => {'query' => 'unknown_method', 'token' => 'abc'}, :post? => false)
67
+ Rack::Request.stubs(:new).returns request
68
+ @repl = Webconsole::Repl.new(@app)
69
+
70
+ $sandbox.expects(:instance_eval).never
71
+
72
+ @repl.call(env).must_equal @app.call(env)
73
+ end
74
+
75
+ it 'rejects requests with invalid token' do
76
+ @app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['hello world']] }
77
+ env = {}
78
+ Webconsole::Repl.stubs(:token).returns('abc')
79
+ request = OpenStruct.new(:params => {'query' => 'unknown_method', 'token' => 'cba'}, :post? => true)
80
+ Rack::Request.stubs(:new).returns request
81
+ @repl = Webconsole::Repl.new(@app)
82
+
83
+ $sandbox.expects(:instance_eval).never
84
+
85
+ @repl.call(env).must_equal @app.call(env)
86
+ end
87
+ end
88
+
89
+ describe 'class methods' do
90
+ describe '#reset_token and #token' do
91
+ it 'returns the security token' do
92
+ Webconsole::Repl.reset_token
93
+ Webconsole::Repl.token.must_be_kind_of String
94
+ end
95
+ end
96
+ describe '#request= and #request' do
97
+ it 'returns the request object' do
98
+ request = stub
99
+ Webconsole::Repl.request = request
100
+ Webconsole::Repl.request.must_equal request
101
+ end
102
+ end
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack
4
+ describe Webconsole::Sandbox do
5
+
6
+ describe "#method_missing" do
7
+ describe 'when the method exists in @locals' do
8
+ it 'retrieves it' do
9
+ @sandbox = Webconsole::Sandbox.new
10
+ @sandbox.instance_variable_set(:@locals, {:a => 123})
11
+
12
+ @sandbox.a.must_equal 123
13
+ end
14
+ end
15
+ describe 'otherwise' do
16
+ it 'raises a NoMethodError' do
17
+ @sandbox = Webconsole::Sandbox.new
18
+
19
+ lambda {
20
+ @sandbox.a
21
+ }.must_raise NoMethodError
22
+ end
23
+ end
24
+ end
25
+
26
+ describe "#reload!" do
27
+ it 'assigns a new, fresh Sandbox to the global variable' do
28
+ old_sandbox = $sandbox = Webconsole::Sandbox.new
29
+
30
+ $sandbox.reload!
31
+
32
+ $sandbox.wont_equal old_sandbox
33
+ end
34
+ it 'returns a feedback string' do
35
+ Webconsole::Sandbox.new.reload!.must_equal 'ok'
36
+ end
37
+ end
38
+
39
+ describe "request" do
40
+ it 'returns the request object' do
41
+ @sandbox = Webconsole::Sandbox.new
42
+ request = Rack::Request.new({'PATH_INFO' => '/some_path'})
43
+ Webconsole::Repl.request = request
44
+
45
+ @sandbox.request.must_equal request
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack
4
+ describe Webconsole::Shell do
5
+ before do
6
+ Ripl.instance_variable_set(:@shell, nil)
7
+ end
8
+
9
+ describe ".eval_query" do
10
+ describe "sets Ripl::Shell" do
11
+ before { Webconsole::Shell.eval_query('2 + 2') }
12
+
13
+ it "#input" do
14
+ Ripl.shell.input.must_equal '2 + 2'
15
+ end
16
+
17
+ it "#result" do
18
+ Ripl.shell.result.must_equal 4
19
+ end
20
+
21
+ it "#history" do
22
+ Ripl.shell.history.must_equal ['2 + 2']
23
+ end
24
+ end
25
+
26
+ describe "for one line input" do
27
+ def response
28
+ Webconsole::Shell.eval_query("'input'")
29
+ end
30
+
31
+ it ":result returns inspected result" do
32
+ response[:result].must_equal '"input"'
33
+ end
34
+
35
+ it ":prompt returns normal prompt" do
36
+ response[:prompt] = '>> '
37
+ end
38
+
39
+ it "returns false for multi_line keys" do
40
+ response[:multi_line].must_equal false
41
+ response[:previous_multi_line].must_equal false
42
+ end
43
+
44
+ it "with an error :result returns error raised" do
45
+ Webconsole::Shell.eval_query("blah")[:result].must_match /^Error:/
46
+ end
47
+ end
48
+
49
+ describe "for multi line input" do
50
+ def response
51
+ [
52
+ Webconsole::Shell.eval_query("[1,2,3].map do |num|"),
53
+ Webconsole::Shell.eval_query("num ** 2"),
54
+ Webconsole::Shell.eval_query("end")
55
+ ]
56
+ end
57
+
58
+ it "returns correct results" do
59
+ response.map {|e| e[:result] }.must_equal [nil, nil, "[1, 4, 9]"]
60
+ end
61
+
62
+ it "returns correct prompts" do
63
+ response.map {|e| e[:prompt] }.must_equal ['>> ', '|| ', '|| ']
64
+ end
65
+
66
+ it "returns correct multi_line keys" do
67
+ response.map {|e| e[:multi_line] }.must_equal [true, true, false]
68
+ response.map {|e| e[:previous_multi_line] }.must_equal [false, true, true]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ module Rack
4
+ describe Webconsole do
5
+
6
+ it 'initializes with an app' do
7
+ @app = stub
8
+ @webconsole = Webconsole.new(@app)
9
+
10
+ @webconsole.instance_variable_get(:@app).must_equal @app
11
+ end
12
+
13
+ describe "#call" do
14
+ it 'delegates the call to the Repl middleware when the path is /webconsole' do
15
+ @app = stub
16
+ @webconsole = Webconsole.new(@app)
17
+ @env = {'PATH_INFO' => '/webconsole'}
18
+
19
+ repl = stub
20
+ Webconsole::Repl.expects(:new).with(@app).returns repl
21
+ repl.expects(:call).with @env
22
+
23
+ @webconsole.call(@env)
24
+ end
25
+
26
+ it 'passes the call to the Assets middleware otherwise' do
27
+ @app = stub
28
+ @webconsole = Webconsole.new(@app)
29
+ @env = {'PATH_INFO' => '/whatever'}
30
+
31
+ assets = stub
32
+ Webconsole::Assets.expects(:new).with(@app).returns assets
33
+ assets.expects(:call).with @env
34
+
35
+ @webconsole.call(@env)
36
+ end
37
+ end
38
+
39
+ describe 'class methods' do
40
+ it '#inject_jquery accessors' do
41
+ Webconsole.inject_jquery.must_equal false
42
+ Webconsole.inject_jquery = true
43
+ Webconsole.inject_jquery.must_equal true
44
+ end
45
+ it '#key_code accessors' do
46
+ Webconsole.key_code.must_equal "96"
47
+ Webconsole.key_code = "97"
48
+ Webconsole.key_code.must_equal "97"
49
+ end
50
+ it '#key_code setter cast parameter type' do
51
+ Webconsole.key_code = 96
52
+ Webconsole.key_code.must_equal "96"
53
+ end
54
+ end
55
+ end
56
+ end