thwart 0.0.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.
- data/.document +5 -0
- data/.gitignore +24 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/examples/a_complete_example.rb +56 -0
- data/examples/example_helper.rb +45 -0
- data/lib/thwart/action_group_builder.rb +62 -0
- data/lib/thwart/actions_store.rb +89 -0
- data/lib/thwart/actor.rb +36 -0
- data/lib/thwart/canable.rb +30 -0
- data/lib/thwart/dsl.rb +43 -0
- data/lib/thwart/enforcer.rb +15 -0
- data/lib/thwart/resource.rb +27 -0
- data/lib/thwart/role.rb +81 -0
- data/lib/thwart/role_builder.rb +143 -0
- data/lib/thwart/role_registry.rb +75 -0
- data/lib/thwart.rb +67 -0
- data/spec/action_group_builder_spec.rb +68 -0
- data/spec/actions_store_spec.rb +74 -0
- data/spec/actor_spec.rb +45 -0
- data/spec/canable_spec.rb +41 -0
- data/spec/dsl_spec.rb +103 -0
- data/spec/enforcer_spec.rb +17 -0
- data/spec/resource_spec.rb +42 -0
- data/spec/role_builder_spec.rb +197 -0
- data/spec/role_registry_spec.rb +137 -0
- data/spec/role_spec.rb +146 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/thwart_spec.rb +60 -0
- metadata +139 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Thwart::RoleBuilder do
|
4
|
+
before do
|
5
|
+
@example_actions = double("Actionables Store", :actionables => {:view => [:view], :update => [:update], :manage => [:view, :update]})
|
6
|
+
@builder = Thwart::RoleBuilder.new(@example_actions)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should build roles" do
|
10
|
+
role = @builder.create_role :a_name
|
11
|
+
role.class.include?(Thwart::Role).should == true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should fire the build callback" do
|
15
|
+
receiver = double("receiver")
|
16
|
+
receiver.should_receive(:after_build_role)
|
17
|
+
klass = Thwart::RoleBuilder.clone
|
18
|
+
klass.set_callback :build_role, :after, receiver
|
19
|
+
role = klass.new(@example_actions).create_role :a_name
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should apply the default action to built roles" do
|
23
|
+
role = @builder.create_role :a_name do
|
24
|
+
default false
|
25
|
+
end
|
26
|
+
role2 = @builder.create_role :another_name do
|
27
|
+
default true
|
28
|
+
end
|
29
|
+
role.responses.should == {}
|
30
|
+
role.default_response.should == false
|
31
|
+
role.query(nil, nil, nil).should == false
|
32
|
+
|
33
|
+
role2.responses.should == {}
|
34
|
+
role2.default_response.should == true
|
35
|
+
role2.query(nil, nil, nil).should == true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should only allow permissions to be defined using recognizable actions" do
|
39
|
+
lambda {
|
40
|
+
@builder.create_role :name do
|
41
|
+
define_permission :non_existant_action, :resource
|
42
|
+
end
|
43
|
+
}.should raise_error(ArgumentError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should default to allowing actions" do
|
47
|
+
role1 = @builder.create_role :name do
|
48
|
+
view :foo
|
49
|
+
update :bar
|
50
|
+
end
|
51
|
+
role2 = @builder.create_role :a_name do
|
52
|
+
allow do
|
53
|
+
view :foo
|
54
|
+
update :bar
|
55
|
+
end
|
56
|
+
end
|
57
|
+
role1.responses.should == role2.responses
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should provide deny blocks" do
|
61
|
+
role = @builder.create_role :name do
|
62
|
+
deny do
|
63
|
+
view :foo
|
64
|
+
update :bar
|
65
|
+
end
|
66
|
+
end
|
67
|
+
role.responses.should == {:view => {:foo => false}, :update => {:bar => false}}
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should accept permissions outside of deny blocks as allows on both sides" do
|
71
|
+
role = @builder.create_role :name do
|
72
|
+
view :foo
|
73
|
+
deny do
|
74
|
+
update :foo
|
75
|
+
end
|
76
|
+
view :bar
|
77
|
+
end
|
78
|
+
role.responses.should == {:view => {:foo => true, :bar => true}, :update => {:foo => false}}
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should build responses with :all" do
|
82
|
+
role = @builder.create_role :a_name do
|
83
|
+
view :all
|
84
|
+
end
|
85
|
+
role.responses.should == {:view => {:_other => true}}
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should build :all responses without arguments" do
|
89
|
+
role = @builder.create_role :a_name do
|
90
|
+
view
|
91
|
+
end
|
92
|
+
role.responses.should == {:view => {:_other => true}}
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should build roles which respond to simple actions" do
|
96
|
+
role = @builder.create_role :a_name do
|
97
|
+
update :this, :that
|
98
|
+
end
|
99
|
+
role.responses.should == {:update => {:this => true, :that => true}}
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should build roles which respond to simple actions" do
|
103
|
+
role = @builder.create_role :a_name do
|
104
|
+
update :this, :that
|
105
|
+
end
|
106
|
+
role.responses.should == {:update => {:this => true, :that => true}}
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should build roles which respond to action groups" do
|
110
|
+
role = @builder.create_role :a_name do
|
111
|
+
manage :this, :that
|
112
|
+
end
|
113
|
+
role.responses.should == {:view => {:this => true, :that => true}, :update => {:this => true, :that => true}}
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should merge all declarations with others" do
|
117
|
+
role = @builder.create_role :a_name do
|
118
|
+
update :this, :that
|
119
|
+
deny do
|
120
|
+
update :all
|
121
|
+
end
|
122
|
+
end
|
123
|
+
role.responses.should == {:update => {:this => true, :that => true, :_other => false}}
|
124
|
+
end
|
125
|
+
|
126
|
+
context "passed conditions" do
|
127
|
+
before do
|
128
|
+
@good_actor = double("actor", :is_allowed => true)
|
129
|
+
@bad_actor = double("actor", :is_allowed => false)
|
130
|
+
end
|
131
|
+
|
132
|
+
context "at the resource level" do
|
133
|
+
before do
|
134
|
+
@role = @builder.create_role :a_name do
|
135
|
+
update :foo, :if => lambda {|actor| actor.is_allowed == true }
|
136
|
+
update :bar, :unless => lambda {|actor| actor.is_allowed == true }
|
137
|
+
update :baz do |actor| actor.is_allowed == true end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
it "should build procs using the :if option" do
|
141
|
+
@role.responses[:update][:foo].call(@good_actor).should == true
|
142
|
+
@role.responses[:update][:foo].call(@bad_actor).should == false
|
143
|
+
end
|
144
|
+
it "should build procs using the :unless option" do
|
145
|
+
@role.responses[:update][:bar].call(@good_actor).should == false
|
146
|
+
@role.responses[:update][:bar].call(@bad_actor).should == true
|
147
|
+
end
|
148
|
+
it "should build procs using action level blocks" do
|
149
|
+
@role.responses[:update][:baz].call(@good_actor).should == true
|
150
|
+
@role.responses[:update][:baz].call(@bad_actor).should == false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "at the action level" do
|
155
|
+
it "should build procs using the :if option" do
|
156
|
+
@role = @builder.create_role :a_name do
|
157
|
+
update :if => lambda {|actor| actor.is_allowed == true }
|
158
|
+
end
|
159
|
+
@role.responses[:update][:_other].call(@good_actor).should == true
|
160
|
+
@role.responses[:update][:_other].call(@bad_actor).should == false
|
161
|
+
end
|
162
|
+
it "should build procs using the :unless option" do
|
163
|
+
@role = @builder.create_role :a_name do
|
164
|
+
update :unless => lambda {|actor| actor.is_allowed == true }
|
165
|
+
end
|
166
|
+
@role.responses[:update][:_other].call(@good_actor).should == false
|
167
|
+
@role.responses[:update][:_other].call(@bad_actor).should == true
|
168
|
+
end
|
169
|
+
it "should build procs using action level blocks" do
|
170
|
+
@role = @builder.create_role :a_name do
|
171
|
+
update do |actor| actor.is_allowed == true end
|
172
|
+
end
|
173
|
+
@role.responses[:update][:_other].call(@good_actor).should == true
|
174
|
+
@role.responses[:update][:_other].call(@bad_actor).should == false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "building roles which include other roles" do
|
180
|
+
it "should allow parents to be specified as options to the role" do
|
181
|
+
@role = @builder.create_role :name, :parents => [:foo, :bar]
|
182
|
+
@role.parents.should == [:foo, :bar]
|
183
|
+
end
|
184
|
+
it "should allow parents to be included in the role definition" do
|
185
|
+
@role = @builder.create_role :name do
|
186
|
+
include :foo
|
187
|
+
include :bar
|
188
|
+
end
|
189
|
+
end
|
190
|
+
it "should allow parents to be included on the same line in the role definition" do
|
191
|
+
@role = @builder.create_role :name do
|
192
|
+
include :foo, :bar
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
def actor_with_role(a_role)
|
4
|
+
double("Actor", :thwart_role => a_role.name)
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Thwart::RoleRegistry do
|
8
|
+
before do
|
9
|
+
@role_builder = double("Role Builder")
|
10
|
+
@role_builder.class.stub(:set_callback => true)
|
11
|
+
@registry = Thwart::RoleRegistry.new(@role_builder)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should initialize a callback on the action creator" do
|
15
|
+
store_class = Class.new do
|
16
|
+
include ActiveSupport::Callbacks
|
17
|
+
end
|
18
|
+
store_class.should_receive(:set_callback)
|
19
|
+
Thwart::RoleRegistry.new(store_class.new)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should add roles to the registry" do
|
23
|
+
role = double("Role")
|
24
|
+
@registry.add(role)
|
25
|
+
@registry.roles.should include(role)
|
26
|
+
@registry.has_role?(role).should == true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should prevent addition of duplicate roles" do
|
30
|
+
role = double("Role")
|
31
|
+
@registry.add(role)
|
32
|
+
lambda {
|
33
|
+
@registry.add(role)
|
34
|
+
}.should raise_error(Thwart::DuplicateRoleError)
|
35
|
+
end
|
36
|
+
context "role finding" do
|
37
|
+
before do
|
38
|
+
@role = double("A Role", :name => :role1)
|
39
|
+
@registry.add(@role)
|
40
|
+
end
|
41
|
+
it "should find nil for nil" do
|
42
|
+
@registry.find_actor_role(nil).should == nil
|
43
|
+
end
|
44
|
+
it "should use the thwart_role attribute" do
|
45
|
+
actor = double("Actor", :thwart_role => @role)
|
46
|
+
@registry.find_actor_role(actor).should == @role
|
47
|
+
end
|
48
|
+
it "should convert symbols to roles" do
|
49
|
+
actor = double("Actor", :thwart_role => :role1)
|
50
|
+
@registry.find_actor_role(actor).should == @role
|
51
|
+
end
|
52
|
+
it "should find nil for symbols pointing to non registered roles " do
|
53
|
+
actor = double("Actor", :thwart_role => :role2)
|
54
|
+
@registry.find_actor_role(actor).should == nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context "resource finding" do
|
58
|
+
it "should find nil for nil" do
|
59
|
+
@registry.find_resource_identifier(nil).should == nil
|
60
|
+
end
|
61
|
+
it "should find using the thwart_name attribute" do
|
62
|
+
resource = double("Resource", :thwart_name => :balls)
|
63
|
+
@registry.find_resource_identifier(resource).should == :balls
|
64
|
+
end
|
65
|
+
it "should find using the class thwart_name attribute" do
|
66
|
+
klass = Class.new do
|
67
|
+
def thwart_name
|
68
|
+
:balls
|
69
|
+
end
|
70
|
+
end
|
71
|
+
@registry.find_resource_identifier(klass.new).should == :balls
|
72
|
+
end
|
73
|
+
it "should find using the class name if the gem wide setting is set" do
|
74
|
+
Thwart.all_classes_are_resources = true
|
75
|
+
class Bollocks; end
|
76
|
+
@registry.find_resource_identifier(Bollocks.new).should == :bollocks
|
77
|
+
Thwart.all_classes_are_resources = false
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
context "querying" do
|
82
|
+
it "should return the default if the role can't be found and the gem wide setting is set" do
|
83
|
+
Thwart.actor_must_play_role = false
|
84
|
+
resp = double("A Bool")
|
85
|
+
Thwart.should_receive(:default_query_response).and_return(resp)
|
86
|
+
@registry.query(nil, nil, nil).should == resp
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should raise an error if the role can't be found and the gem wide setting is set" do
|
90
|
+
Thwart.actor_must_play_role = true
|
91
|
+
lambda {
|
92
|
+
@registry.query(nil, nil, nil)
|
93
|
+
}.should raise_error(Thwart::MissingRoleError)
|
94
|
+
end
|
95
|
+
|
96
|
+
context "with roles in the registry" do
|
97
|
+
before do
|
98
|
+
Thwart.actor_must_play_role = true
|
99
|
+
Thwart.default_query_response = false
|
100
|
+
@role1 = double("Low Level Role", :name => :role1, :query => false)
|
101
|
+
@role2 = double("High Level Role", :name => :role2, :query => true)
|
102
|
+
@role3 = double("No Rules Role", :name => :role3, :query => nil, :parents => [@role2, @role1])
|
103
|
+
@role4 = double("Really low role", :name => :role4, :query => nil, :parents => [@role3])
|
104
|
+
[@role1, @role2, @role3, @role4].each do |r|
|
105
|
+
@registry.add(r)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should query the role" do
|
110
|
+
@registry.query(actor_with_role(@role1), nil, nil).should == false
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should query the parents in a breadth first order if the role query is unsuccessful" do
|
114
|
+
@role3.should_receive(:parents)
|
115
|
+
@registry.query(actor_with_role(@role3), nil, nil).should == true # this ensures role2 is checked before role1
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should query more than one level of parents" do
|
119
|
+
@role3.should_receive(:parents)
|
120
|
+
@role4.should_receive(:parents)
|
121
|
+
@registry.query(actor_with_role(@role4), nil, nil).should == true # this ensures role2 is checked before role1
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should return the default if the role can't be found and the gem wide setting is set" do
|
125
|
+
Thwart.actor_must_play_role = false
|
126
|
+
@registry.query(actor_with_role(double("A role not in the registry", :name => :not_present)), nil, nil).should == false
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should raise an error if the role can't be found and the gem wide setting is set" do
|
130
|
+
Thwart.actor_must_play_role = true
|
131
|
+
lambda {
|
132
|
+
@registry.query(actor_with_role(double("A role not in the registry", :name => :not_present)), nil, nil)
|
133
|
+
}.should raise_error(Thwart::MissingRoleError)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/spec/role_spec.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Thwart::Role do
|
4
|
+
it "should be queryable" do
|
5
|
+
instance_with_module(Thwart::Role).respond_to?(:query).should == true
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should respond with nil if no rule applies" do
|
9
|
+
instance_with_role_definition.query(nil, nil, nil).should == nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should respond to queries with its role level default" do
|
13
|
+
a_val = mock('default query response')
|
14
|
+
@role1 = instance_with_role_definition do
|
15
|
+
self.default_response = a_val
|
16
|
+
end
|
17
|
+
@role1.query(nil, nil, nil).should == a_val
|
18
|
+
@role1.query(:foo, :bar, :baz).should == a_val
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should uniqueify its parents upon assignment" do
|
22
|
+
@role = instance_with_role_definition
|
23
|
+
@role.parents = [:a, :b]
|
24
|
+
@role.parents += [:a, :c]
|
25
|
+
@role.parents.should == [:a, :b, :c]
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with simple responses set" do
|
29
|
+
before do
|
30
|
+
@role = instance_with_role_definition do
|
31
|
+
self.responses = {:view => true, :update => false}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
it "should respond to simple queries with actions" do
|
35
|
+
@role.query(nil, nil, :view).should == true
|
36
|
+
@role.query(nil, nil, :update).should == false
|
37
|
+
end
|
38
|
+
it "shouldn't respond to queries it has no rules for" do
|
39
|
+
@role.query(nil, nil, nil).should == nil
|
40
|
+
end
|
41
|
+
it "should return the default if it is set" do
|
42
|
+
@role.default_response = true
|
43
|
+
@role.query(nil, nil, nil).should == true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "with response sets scoped by resource" do
|
48
|
+
before do
|
49
|
+
@role = instance_with_role_definition do
|
50
|
+
self.responses = {:view => {:foo => true, :bar => false}, :update => false, :destroy => {:foo => true, :_other => false}}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
it "should respond to simple queries with actions" do
|
54
|
+
@role.query(nil, :foo, :view).should == true
|
55
|
+
@role.query(nil, :bar, :view).should == false
|
56
|
+
@role.query(nil, :baz, :view).should == nil
|
57
|
+
|
58
|
+
@role.query(nil, :foo, :update).should == false
|
59
|
+
@role.query(nil, :bar, :update).should == false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with defaults at all levels" do
|
64
|
+
before do
|
65
|
+
@role = instance_with_role_definition do
|
66
|
+
self.default_response = true
|
67
|
+
self.responses = {:view => nil, :update => false, :destroy => {:foo => true, :_other => false}}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
it "should respond with the role level default for an unknown action" do
|
71
|
+
@role.query(nil, :foo, :create).should == true
|
72
|
+
end
|
73
|
+
it "should respond with the action level default for known actions" do
|
74
|
+
@role.query(nil, :foo, :view).should == nil
|
75
|
+
@role.query(nil, :foo, :update).should == false
|
76
|
+
end
|
77
|
+
it "should respond with the resource level default for known action and unknown permissions" do
|
78
|
+
@role.query(nil, :foo, :destroy).should == true # Known permission
|
79
|
+
@role.query(nil, :bar, :destroy).should == false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "with response sets with procs" do
|
84
|
+
before do
|
85
|
+
@good_actor = double("actor", :is_allowed => true)
|
86
|
+
@bad_actor = double("actor", :is_allowed => false)
|
87
|
+
end
|
88
|
+
context "procs at action level" do
|
89
|
+
before do
|
90
|
+
@role = instance_with_role_definition do
|
91
|
+
self.responses = {:view => Proc.new {|actor, resource| actor.is_allowed == true}, :update => false}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
it "should run the proc" do
|
95
|
+
@good_actor.should_receive(:is_allowed).twice
|
96
|
+
@role.query(@good_actor, :foo, :view).should == true
|
97
|
+
@role.query(@good_actor, :bar, :view).should == true
|
98
|
+
@role.query(@good_actor, :foo, :update).should == false
|
99
|
+
@role.query(@good_actor, :bar, :update).should == false
|
100
|
+
|
101
|
+
@bad_actor.should_receive(:is_allowed).twice
|
102
|
+
@role.query(@bad_actor, :foo, :view).should == false
|
103
|
+
@role.query(@bad_actor, :bar, :view).should == false
|
104
|
+
@role.query(@bad_actor, :foo, :update).should == false
|
105
|
+
@role.query(@bad_actor, :bar, :update).should == false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "procs at resource level" do
|
110
|
+
before do
|
111
|
+
@role = instance_with_role_definition do
|
112
|
+
self.responses = {:view => {:foo => true,
|
113
|
+
:bar => Proc.new {|actor, resource| actor.is_allowed == true},
|
114
|
+
:_other => Proc.new {|actor, resource| actor.is_allowed == true}},
|
115
|
+
:update => false
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should respond to other actions without procs" do
|
121
|
+
@role.query(nil, :foo, :view).should == true
|
122
|
+
@role.query(nil, :foo, :update).should == false
|
123
|
+
@role.query(nil, :bar, :update).should == false
|
124
|
+
@role.query(nil, :baz, :update).should == false
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should respond to actions with procs by calling them" do
|
128
|
+
@role.query(@good_actor, :bar, :view).should == true
|
129
|
+
@role.query(@bad_actor, :bar, :view).should == false
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should respond to unknown resources by calling the :_other proc" do
|
133
|
+
@role.query(@good_actor, :baz, :view).should == true
|
134
|
+
@role.query(@bad_actor, :baz, :view).should == false
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe Thwart::DefaultRole do
|
141
|
+
it "should respond to queries with the Thwart response default" do
|
142
|
+
a_val = mock('default query')
|
143
|
+
Thwart.should_receive(:default_query_response).and_return(a_val)
|
144
|
+
subject.query(nil, nil, nil).should == a_val
|
145
|
+
end
|
146
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'thwart'
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
RSpec.configure do |c|
|
8
|
+
end
|
9
|
+
|
10
|
+
class User
|
11
|
+
include Thwart::Actor
|
12
|
+
attr_accessor :name
|
13
|
+
end
|
14
|
+
|
15
|
+
class Post
|
16
|
+
include Thwart::Resource
|
17
|
+
attr_accessor :title
|
18
|
+
end
|
19
|
+
|
20
|
+
def generic_model(name=nil, &block)
|
21
|
+
klass = Class.new do
|
22
|
+
def self.table_name
|
23
|
+
"generics"
|
24
|
+
end
|
25
|
+
if name
|
26
|
+
class_eval "def self.name; '#{name}' end"
|
27
|
+
class_eval "def self.to_s; '#{name}' end"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
klass.class_eval(&block) if block_given?
|
32
|
+
klass
|
33
|
+
end
|
34
|
+
|
35
|
+
def class_with_module(mod)
|
36
|
+
Class.new do
|
37
|
+
include mod
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def instance_with_module(mod)
|
42
|
+
class_with_module(mod).new
|
43
|
+
end
|
44
|
+
|
45
|
+
def instance_with_role_definition(&block)
|
46
|
+
role = instance_with_module(Thwart::Role)
|
47
|
+
role.instance_eval(&block) if block_given?
|
48
|
+
role
|
49
|
+
end
|
data/spec/thwart_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Thwart do
|
4
|
+
it "should autoload all the classes" do
|
5
|
+
lambda {
|
6
|
+
Thwart::Actor
|
7
|
+
Thwart::Role
|
8
|
+
Thwart::DefaultRole
|
9
|
+
Thwart::Resource
|
10
|
+
Thwart::Dsl
|
11
|
+
Thwart::Cans
|
12
|
+
Thwart::Ables
|
13
|
+
Thwart::ActionsStore
|
14
|
+
Thwart::ActionGroupBuilder
|
15
|
+
Thwart::RoleRegistry
|
16
|
+
Thwart::RoleBuilder
|
17
|
+
}.should_not raise_error
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "configuration" do
|
21
|
+
it "should realize the configured values" do
|
22
|
+
Thwart.configure do
|
23
|
+
role_registry 'role_registry'
|
24
|
+
default_query_response 'false'
|
25
|
+
end
|
26
|
+
Thwart.role_registry.should == 'role_registry'
|
27
|
+
Thwart.default_query_response.should == 'false'
|
28
|
+
end
|
29
|
+
it "should create new actions" do
|
30
|
+
Thwart::Actions.should_receive(:create_action).with(:add, :addable)
|
31
|
+
Thwart.configure do
|
32
|
+
action :add, :addable
|
33
|
+
end
|
34
|
+
end
|
35
|
+
it "should create new roles" do
|
36
|
+
role_dsl = double("dsl")
|
37
|
+
Thwart::RoleBuilder.should_receive(:new).and_return(role_dsl)
|
38
|
+
role_dsl.should_receive(:create_role).with(:a)
|
39
|
+
role_dsl.should_receive(:create_role).with(:b, 'something else')
|
40
|
+
role_dsl.class.stub(:set_callback)
|
41
|
+
role_dsl.class.stub(:reset_callbacks)
|
42
|
+
Thwart.configure do
|
43
|
+
role :a
|
44
|
+
role :b, 'something else'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
it "should create new action groups" do
|
48
|
+
actionables = double("actionables")
|
49
|
+
Thwart::ActionGroupBuilder.should_receive(:new).and_return(actionables)
|
50
|
+
actionables.should_receive(:create_action_group).with(:manage)
|
51
|
+
actionables.should_receive(:create_action_group).with(:inspect, [])
|
52
|
+
Thwart.configure do
|
53
|
+
action_group :manage
|
54
|
+
action_group :inspect, []
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
describe "query" do
|
59
|
+
end
|
60
|
+
end
|