danwrong-evil 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -0
- data/Manifest +11 -1
- data/README.textile +48 -10
- data/Rakefile +2 -1
- data/assets/evil-lib.js +306 -7
- data/assets/evil.css +9 -1
- data/assets/evil.js +22 -1
- data/evil.gemspec +5 -5
- data/lib/evil/application.rb +17 -1
- data/lib/evil/helpers.rb +1 -1
- data/lib/evil/models/template.rb +1 -1
- data/lib/evil/plugin.rb +4 -0
- data/lib/evil/plugin/base.rb +2 -2
- data/lib/evil/plugin/block_tag.rb +48 -0
- data/lib/evil/plugin/configuration.rb +4 -8
- data/lib/evil/plugin/filesystem.rb +1 -1
- data/lib/evil/plugin/singleton_tag.rb +18 -0
- data/lib/evil/plugin/tag.rb +18 -52
- data/test/application/frontend_test.rb +52 -0
- data/test/{app/evil_test.rb → application/openid_test.rb} +5 -23
- data/test/application/plugin_config_test.rb +73 -0
- data/test/application/template_test.rb +119 -0
- data/test/test_helper.rb +26 -1
- data/test/units/models/template_test.rb +16 -0
- data/test/units/models/whitelist_test.rb +31 -0
- data/test/units/plugin/base_test.rb +27 -2
- data/test/units/plugin/configuration_test.rb +60 -0
- data/test/units/plugin/environment_test.rb +13 -0
- data/test/units/plugin/filesystem_test.rb +22 -0
- data/test/units/plugin/tag_test.rb +36 -7
- data/views/index.haml +2 -2
- metadata +24 -4
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
require 'evil/application'
|
3
|
+
|
4
|
+
class PluginConfigTest < Test::Unit::TestCase
|
5
|
+
include Sinatra::Test
|
6
|
+
|
7
|
+
context 'running the evil application' do
|
8
|
+
setup do
|
9
|
+
@app = Evil::Application
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'and some loaded plugins ' do
|
13
|
+
setup do
|
14
|
+
Evil::Plugin::Environment.stubs(:plugins).returns([
|
15
|
+
@plugin1 = Evil::Plugin::Base.new('Test Plugin') { |p|
|
16
|
+
p.configure do |c|
|
17
|
+
c.text :username
|
18
|
+
c.password :password
|
19
|
+
end
|
20
|
+
},
|
21
|
+
@plugin2 = Evil::Plugin::Base.new('Another Plugin') {}
|
22
|
+
])
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'while logged in' do
|
26
|
+
setup do
|
27
|
+
Factory.create(:whitelist)
|
28
|
+
@env = { 'rack.session' => { :identity_url => 'www.example.com' } }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'GET /admin/plugins/new' do
|
32
|
+
setup do
|
33
|
+
get '/admin/plugins/new', {}, @env
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'be successful' do
|
37
|
+
assert_equal 200, response.status
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'display a list of plugins that are configurable' do
|
41
|
+
assert_match /Test Plugin/, response.body
|
42
|
+
assert_match /Another Plugin/, response.body
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'GET to /admin/plugins/name' do
|
47
|
+
setup do
|
48
|
+
get "/admin/plugins/#{URI.escape(@plugin1.name)}", {}, @env
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'be successful' do
|
52
|
+
assert_equal 200, response.status
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'render form elements' do
|
56
|
+
assert_match /name='config\[username\]'/, response.body
|
57
|
+
assert_match /name='config\[password\]'/, response.body
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'POST to /admin/plugins/name' do
|
62
|
+
should 'update plugins config then redirect to home' do
|
63
|
+
@plugin1.config.expects(:set).with({ 'username' => 'testies' })
|
64
|
+
post "/admin/plugins/#{URI.escape(@plugin1.name)}", { :config => { :username => 'testies' } }, @env
|
65
|
+
assert_equal 302, response.status
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
require 'evil/application'
|
3
|
+
|
4
|
+
class TemplateTest < Test::Unit::TestCase
|
5
|
+
include Sinatra::Test
|
6
|
+
|
7
|
+
context 'running the evil application' do
|
8
|
+
setup do
|
9
|
+
@app = Evil::Application
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'while logged in' do
|
13
|
+
setup do
|
14
|
+
Factory.create(:whitelist)
|
15
|
+
@env = { 'rack.session' => { :identity_url => 'www.example.com' } }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'GET /admin/templates/id with existing template' do
|
19
|
+
setup do
|
20
|
+
@template = Factory.create(:template)
|
21
|
+
get "/admin/templates/#{@template.id}", {}, @env
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'be successful' do
|
25
|
+
assert_equal 200, response.status
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'GET /admin/templates/nothinghere with non-existing template' do
|
30
|
+
setup do
|
31
|
+
get '/admin/templates/nothinghere', {}, @env
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'be not found' do
|
35
|
+
assert_equal 404, response.status
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'GET /admin/templates/new' do
|
40
|
+
setup do
|
41
|
+
get '/admin/templates/new', {}, @env
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'be successful' do
|
45
|
+
assert_equal 200, response.status
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'POST /admin/templates/id with valid updated attributes' do
|
50
|
+
setup do
|
51
|
+
@template = Factory.create(:template)
|
52
|
+
post "/admin/templates/#{@template.id}", { :template => { :title => 'thing' } }, @env
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'redirect to admin home' do
|
56
|
+
assert_equal 302, response.status
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'update values' do
|
60
|
+
assert_equal 'thing', @template.reload.title
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'reload app on POST /admin/templates/id with valid updated attributes' do
|
65
|
+
@template = Factory.create(:template)
|
66
|
+
@app.expects(:reload!)
|
67
|
+
post "/admin/templates/#{@template.id}", { :template => { :title => 'thing' } }, @env
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'POST /admin/templates/id with invalid updated attributes' do
|
71
|
+
setup do
|
72
|
+
@template = Factory.create(:template)
|
73
|
+
post "/admin/templates/#{@template.id}", { :template => { :title => '' } }, @env
|
74
|
+
end
|
75
|
+
|
76
|
+
should 'render form' do
|
77
|
+
assert_equal 200, response.status
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'POST /admin/templates with valid attributes' do
|
82
|
+
setup do
|
83
|
+
post "/admin/templates", { :template => {
|
84
|
+
:title => 'just created',
|
85
|
+
:source => 'some stuff',
|
86
|
+
:ttl => 10
|
87
|
+
} }, @env
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'create record' do
|
91
|
+
assert Evil::Models::Template.find_by_title('just created')
|
92
|
+
end
|
93
|
+
|
94
|
+
should 'redirect to admin home' do
|
95
|
+
assert_equal 302, response.status
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'POST /admin/templates with valid attributes' do
|
100
|
+
setup do
|
101
|
+
post "/admin/templates", { :template => {
|
102
|
+
:title => nil,
|
103
|
+
:source => 'some stuff',
|
104
|
+
:ttl => 10
|
105
|
+
} }, @env
|
106
|
+
end
|
107
|
+
|
108
|
+
should 'render form' do
|
109
|
+
assert_match /template\[source\]/, response.body
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'be successful' do
|
113
|
+
assert_equal 200, response.status
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,10 +3,35 @@ require 'rubygems'
|
|
3
3
|
require 'evil'
|
4
4
|
require 'test/unit'
|
5
5
|
require 'shoulda'
|
6
|
+
require 'factory_girl'
|
6
7
|
require 'sinatra/test'
|
7
8
|
require 'mocha'
|
8
9
|
|
9
10
|
require 'redgreen' rescue nil
|
10
11
|
|
11
12
|
Sinatra::Default.set :environment, 'test'
|
12
|
-
Evil.app_root = File.
|
13
|
+
Evil.app_root = File.dirname(__FILE__)
|
14
|
+
FileUtils.rm(File.join(File.dirname(__FILE__), 'evil.db')) rescue nil
|
15
|
+
Evil::Setup::Generator.new(Evil.app_root).create_database!
|
16
|
+
|
17
|
+
Factory.sequence :number do |n|
|
18
|
+
n.to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
Factory.define :whitelist, :class => Evil::Models::Whitelist do |f|
|
22
|
+
f.pattern 'www.example.com'
|
23
|
+
end
|
24
|
+
|
25
|
+
Factory.define :template, :class => Evil::Models::Template do |f|
|
26
|
+
f.ttl 10
|
27
|
+
f.position 1
|
28
|
+
f.title { "test#{Factory.next(:number)}" }
|
29
|
+
f.route { "/test#{Factory.next(:number)}/thing" }
|
30
|
+
f.source 'some stuff'
|
31
|
+
end
|
32
|
+
|
33
|
+
Factory.define :config_pair, :class => Evil::Models::ConfigPair do |f|
|
34
|
+
f.plugin 'Test'
|
35
|
+
f.key { "test#{Factory.next(:number)}" }
|
36
|
+
f.value 'test'
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
3
|
+
class TemplateTest < Test::Unit::TestCase
|
4
|
+
include Evil::Models
|
5
|
+
|
6
|
+
context 'with a template with a liquid syntax error' do
|
7
|
+
setup do
|
8
|
+
@template = Factory.build(:template, :source => '{% amissing tag %} sdkljsdh slkjdh skjldh')
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'not be valid' do
|
12
|
+
assert !@template.valid?
|
13
|
+
assert !@template.errors[:source].nil?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
3
|
+
class WhitelistTest < Test::Unit::TestCase
|
4
|
+
include Evil::Models
|
5
|
+
|
6
|
+
context 'with whitelist with a non wildcarded patterm' do
|
7
|
+
setup do
|
8
|
+
@wl = Factory.create(:whitelist)
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'only authorize that exact identity url' do
|
12
|
+
assert !Whitelist.authorize('wwwwww.example.com')
|
13
|
+
assert Whitelist.authorize('www.example.com')
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'ignore http://' do
|
17
|
+
assert Whitelist.authorize('http://www.example.com')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with whitelist with a wildcarded patterm' do
|
22
|
+
setup do
|
23
|
+
@wl = Factory.create(:whitelist, :pattern => '*.example2.com')
|
24
|
+
end
|
25
|
+
|
26
|
+
should 'authorize any identity url ending in .example2.com' do
|
27
|
+
assert Whitelist.authorize('bob.example2.com')
|
28
|
+
assert Whitelist.authorize('www.example2.com')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,4 +1,17 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
1
3
|
class BaseTest < Test::Unit::TestCase
|
4
|
+
should 'module eval given source when Evil::Plugin.evaluate called' do
|
5
|
+
Evil::Plugin::Environment.expects(:module_eval).with('some code')
|
6
|
+
Evil::Plugin.evaluate('some code')
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'not raise if Evil::Plugin.evaluate called with dodgy code' do
|
10
|
+
assert_nothing_raised do
|
11
|
+
Evil::Plugin.evaluate('some code that wont work')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
2
15
|
should 'initialize with a name and a block that recieves the new instance' do
|
3
16
|
plugin = Evil::Plugin::Base.new 'Test Plugin' do |p|
|
4
17
|
assert_instance_of Evil::Plugin::Base, p
|
@@ -31,8 +44,20 @@ class BaseTest < Test::Unit::TestCase
|
|
31
44
|
|
32
45
|
end
|
33
46
|
|
34
|
-
should 'create and register a tag instance when plugin initialize with a tag call' do
|
35
|
-
Evil::Plugin::
|
47
|
+
should 'create and register a block tag instance when plugin initialize with a tag call' do
|
48
|
+
Evil::Plugin::BlockTag.expects(:from).returns(t = Class.new(Evil::Plugin::BlockTag))
|
49
|
+
Liquid::Template.expects(:register_tag).with(:thing, t)
|
50
|
+
|
51
|
+
Evil::Plugin::Base.new 'Test Plugin' do |p|
|
52
|
+
p.tag :thing, :block => true do
|
53
|
+
'a tag'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
should 'create and register a singleton tag instance when plugin initialize with a tag call that passed the :block option' do
|
60
|
+
Evil::Plugin::SingletonTag.expects(:from).returns(t = Class.new(Evil::Plugin::SingletonTag))
|
36
61
|
Liquid::Template.expects(:register_tag).with(:thing, t)
|
37
62
|
|
38
63
|
Evil::Plugin::Base.new 'Test Plugin' do |p|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
3
|
+
class ConfigurationTest < Test::Unit::TestCase
|
4
|
+
include Evil::Plugin
|
5
|
+
|
6
|
+
context 'with an instance of Config' do
|
7
|
+
setup do
|
8
|
+
Evil::Models::ConfigPair.destroy_all
|
9
|
+
|
10
|
+
Factory.create(:config_pair, :key => 'boob', :value => 'test')
|
11
|
+
Factory.create(:config_pair, :key => 'beeb', :value => 'hello')
|
12
|
+
|
13
|
+
@plugin = Base.new('Test') do |p|
|
14
|
+
p.configure do |c|
|
15
|
+
c.text :username
|
16
|
+
c.password :password
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
@config = Configuration::Config.new(@plugin)
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'return a value for an existing key' do
|
24
|
+
assert_equal 'test', @config['boob']
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'also allow access through symbols' do
|
28
|
+
assert_equal 'test', @config[:boob]
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'return an empty string for unset values' do
|
32
|
+
assert_equal '', @config['nothinghere']
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'allow you to set values with a hash' do
|
36
|
+
@config.set( :new => 'blah' )
|
37
|
+
|
38
|
+
assert_equal 'blah', @config[:new]
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'allow you to update values with a hash' do
|
42
|
+
@config.set( :beeb => 'not test' )
|
43
|
+
|
44
|
+
assert_equal 'not test', @config[:beeb]
|
45
|
+
end
|
46
|
+
|
47
|
+
should 'return empty strings for an unconfigured plugin' do
|
48
|
+
plugin2 = Base.new('Splange') do |p|
|
49
|
+
p.configure do |c|
|
50
|
+
c.text :username
|
51
|
+
c.password :password
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
config2 = Configuration::Config.new(plugin2)
|
56
|
+
|
57
|
+
assert_equal '', config2[:something]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
3
|
+
class EnvironmentTest < Test::Unit::TestCase
|
4
|
+
include Evil::Plugin
|
5
|
+
|
6
|
+
should 'take a name and block and add to plugins array' do
|
7
|
+
Environment.plugin :test do
|
8
|
+
end
|
9
|
+
|
10
|
+
assert_equal 1, Environment.plugins.size
|
11
|
+
assert_kind_of Base, Environment.plugins.first
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../../test_helper')
|
2
|
+
|
3
|
+
class FilesystemTest < Test::Unit::TestCase
|
4
|
+
include Evil::Plugin
|
5
|
+
|
6
|
+
context 'given an instance of the filesystem' do
|
7
|
+
setup do
|
8
|
+
@template = Factory.create(:template, :title => 'boom', :source => 'boom source')
|
9
|
+
@fs = Filesystem.new
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'return source of a template with the given title' do
|
13
|
+
assert_equal 'boom source', @fs.read_template_file('boom')
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'raise an exception of template not found' do
|
17
|
+
assert_raises(Liquid::FileSystemError) do
|
18
|
+
@fs.read_template_file('nothinghere')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -2,9 +2,9 @@ require File.join(File.dirname(__FILE__), '../../test_helper')
|
|
2
2
|
require 'liquid'
|
3
3
|
|
4
4
|
class TagTest < Test::Unit::TestCase
|
5
|
-
context 'with a custom tag defined that returns a string' do
|
5
|
+
context 'with a custom block tag defined that returns a string' do
|
6
6
|
setup do
|
7
|
-
Liquid::Template.register_tag('test', Evil::Plugin::
|
7
|
+
Liquid::Template.register_tag('test', Evil::Plugin::BlockTag.from { |params|
|
8
8
|
'hello'
|
9
9
|
})
|
10
10
|
end
|
@@ -18,7 +18,7 @@ class TagTest < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
context 'with a custom tag defined that returns a parameter' do
|
20
20
|
setup do
|
21
|
-
Liquid::Template.register_tag('test', Evil::Plugin::
|
21
|
+
Liquid::Template.register_tag('test', Evil::Plugin::BlockTag.from { |params|
|
22
22
|
params[:a]
|
23
23
|
})
|
24
24
|
end
|
@@ -38,7 +38,7 @@ class TagTest < Test::Unit::TestCase
|
|
38
38
|
|
39
39
|
context 'with a custom tag defined that uses the body method' do
|
40
40
|
setup do
|
41
|
-
Liquid::Template.register_tag('test', Evil::Plugin::
|
41
|
+
Liquid::Template.register_tag('test', Evil::Plugin::BlockTag.from { |params|
|
42
42
|
times = params[:times] || 1
|
43
43
|
out = ''
|
44
44
|
times.times { |i| out << body(:i => i) }
|
@@ -67,14 +67,14 @@ class TagTest < Test::Unit::TestCase
|
|
67
67
|
|
68
68
|
context 'with 2 custom tags defined' do
|
69
69
|
setup do
|
70
|
-
Liquid::Template.register_tag('test', Evil::Plugin::
|
70
|
+
Liquid::Template.register_tag('test', Evil::Plugin::BlockTag.from { |params|
|
71
71
|
times = params[:times] || 1
|
72
72
|
out = ''
|
73
73
|
times.times { |i| out << body(:i => i) }
|
74
74
|
out
|
75
75
|
})
|
76
76
|
|
77
|
-
Liquid::Template.register_tag('test2', Evil::Plugin::
|
77
|
+
Liquid::Template.register_tag('test2', Evil::Plugin::BlockTag.from { |params|
|
78
78
|
params[:a]
|
79
79
|
})
|
80
80
|
end
|
@@ -94,7 +94,7 @@ class TagTest < Test::Unit::TestCase
|
|
94
94
|
|
95
95
|
context 'with a custom tag with more than one parameter defined' do
|
96
96
|
setup do
|
97
|
-
Liquid::Template.register_tag('test', Evil::Plugin::
|
97
|
+
Liquid::Template.register_tag('test', Evil::Plugin::BlockTag.from { |params|
|
98
98
|
[params[:a], params[:b]].join('|')
|
99
99
|
})
|
100
100
|
end
|
@@ -105,4 +105,33 @@ class TagTest < Test::Unit::TestCase
|
|
105
105
|
assert_equal 'g|a', template.render
|
106
106
|
end
|
107
107
|
end
|
108
|
+
|
109
|
+
|
110
|
+
context 'with a custom singleton tag defined that returns a string' do
|
111
|
+
setup do
|
112
|
+
Liquid::Template.register_tag('tests', Evil::Plugin::SingletonTag.from { |params|
|
113
|
+
'hello'
|
114
|
+
})
|
115
|
+
end
|
116
|
+
|
117
|
+
should 'output the string' do
|
118
|
+
template = Liquid::Template.parse('{% tests %}')
|
119
|
+
|
120
|
+
assert_equal 'hello', template.render
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'with a custom singleton tag defined that uses a parameter' do
|
125
|
+
setup do
|
126
|
+
Liquid::Template.register_tag('tests', Evil::Plugin::SingletonTag.from { |params|
|
127
|
+
params[:thing]
|
128
|
+
})
|
129
|
+
end
|
130
|
+
|
131
|
+
should 'output the parameter' do
|
132
|
+
template = Liquid::Template.parse('{% tests thing: "boo" %}')
|
133
|
+
|
134
|
+
assert_equal 'boo', template.render
|
135
|
+
end
|
136
|
+
end
|
108
137
|
end
|