moulin_rouge 0.0.1.beta1 → 0.0.1.beta2

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,46 @@
1
+ module MoulinRouge
2
+ # Creates a common scope to register roles and abilities
3
+ class Authorization
4
+ # Avoid direct initialization, just act as a singleton
5
+ private_class_method :new
6
+
7
+ class << self
8
+ # Delegates the missing method for the main ability
9
+ def method_missing(name, *args, &block)
10
+ main.send(name, *args, &block)
11
+ end
12
+
13
+ # The instance of the main ability
14
+ def main
15
+ @@main ||= MoulinRouge::Ability.new(:main)
16
+ end
17
+
18
+ # Returns an array with the name of all roles created
19
+ def roles
20
+ @@roles ||= []
21
+ end
22
+
23
+ # Returns an hash with all permissions defined
24
+ def abilities
25
+ @@abilities ||= {}
26
+ end
27
+
28
+ # Register an ability in the singleton
29
+ def register(instance)
30
+ name = instance.name
31
+ self.abilities[name] = instance
32
+ self.roles << name unless self.roles.include?(name)
33
+ end
34
+
35
+ # Load and initialize all authorization files in the configuration path
36
+ def compile!
37
+ Dir[MoulinRouge.configuration.path].each { |file| Kernel.load(file) }
38
+ end
39
+
40
+ # Reset all constants
41
+ def reset! #:nodoc:
42
+ @@main, @@roles, @@abilities = nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -9,14 +9,14 @@ module MoulinRouge
9
9
  model = MoulinRouge.configuration.model.new if model.nil? and not MoulinRouge.configuration.model.nil?
10
10
  # Reload all permissions if cache is disabled
11
11
  MoulinRouge.reload! unless MoulinRouge.configuration.cache
12
- # Set all permissions in main
13
- MoulinRouge::Permission.main.abilities.each do |ability|
12
+ # Set all abilities in main
13
+ MoulinRouge::Authorization.main.abilities.each do |ability|
14
14
  ability.send_to(self, model)
15
15
  end
16
- # Set all permissions by roles
17
- MoulinRouge::Permission.all.each do |role, permission|
18
- permission.abilities.each do |ability|
19
- ability.send_to(self, model)
16
+ # Set all abilities by role
17
+ MoulinRouge::Authorization.abilities.each do |role, ability|
18
+ ability.abilities.each do |cancan_ability|
19
+ cancan_ability.send_to(self, model)
20
20
  end if model.send(MoulinRouge.configuration.test_method, role)
21
21
  end
22
22
  end
@@ -1,3 +1,3 @@
1
1
  module MoulinRouge
2
- VERSION = "0.0.1.beta1"
2
+ VERSION = "0.0.1.beta2"
3
3
  end
@@ -0,0 +1,5 @@
1
+ class FixtureAuthorization < MoulinRouge::Authorization
2
+ role(:fixture) do
3
+ can(:be, :used, :for, :testing)
4
+ end
5
+ end
@@ -0,0 +1,229 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoulinRouge::Ability do
4
+ let(:ability) { MoulinRouge::Ability.new(:name) }
5
+
6
+ describe "#initialize" do
7
+ it "evaluate the groups and authorizations to the class scope" do
8
+ ability = MoulinRouge::Ability.new(:scope) do
9
+ self.class.should == MoulinRouge::Ability
10
+ can :do, :something
11
+ role :for
12
+ end
13
+ end
14
+
15
+ it "registers the ability instance into authorization" do
16
+ MoulinRouge::Authorization.should_receive(:register).at_least(:once)
17
+ MoulinRouge::Ability.new(:main) do
18
+ role(:one)
19
+ end
20
+ end
21
+
22
+ it "inherits all abilities from parent if this is a group" do
23
+ role = nil
24
+ MoulinRouge::Ability.new(:main) do
25
+ group(:group) do
26
+ can :do, :this
27
+ role = role(:role)
28
+ end
29
+ end
30
+ role.abilities.first.args.should include(:do, :this)
31
+ end
32
+ end
33
+
34
+ describe "#name" do
35
+ it "returns the given name on class initialization" do
36
+ ability.name.should be(:name)
37
+ end
38
+ end
39
+
40
+ describe "#parent" do
41
+ it "returns nil when for main" do
42
+ ability.parent.should be_nil
43
+ end
44
+
45
+ it "returns a instance of the MoulinRouge::Ability" do
46
+ another = MoulinRouge::Ability.new(:another, :parent => ability)
47
+ another.parent.should be_a(MoulinRouge::Ability)
48
+ another.parent.should be(ability)
49
+ end
50
+ end
51
+
52
+ describe "#childrens" do
53
+ it "returns an array" do
54
+ ability.childrens.should be_an(Array)
55
+ end
56
+ end
57
+
58
+ describe "#abilities" do
59
+ it "returns an array" do
60
+ ability.abilities.should be_a(Array)
61
+ end
62
+ end
63
+
64
+ describe "#inherithed_abilities" do
65
+ it "returns all abilities from self and their childrens" do
66
+ ability.can :do, :this
67
+ # First nested level
68
+ one = ability.role(:one) do
69
+ can :do, :one
70
+ end
71
+ # Second nested level
72
+ two = one.role(:two) do
73
+ can :do, :two
74
+ end
75
+ ability.inherithed_abilities.should be_an(Array)
76
+ ability.inherithed_abilities.length.should be(3)
77
+ one.inherithed_abilities.length.should be(2)
78
+ two.inherithed_abilities.length.should be(1)
79
+ end
80
+ end
81
+
82
+ describe "#role" do
83
+ it "returns a new ability with the parent setted to the class that are calling" do
84
+ role = ability.role(:test)
85
+ role.should be_a(MoulinRouge::Ability)
86
+ role.parent.should be(ability)
87
+ end
88
+
89
+ it "adds a new instance on children" do
90
+ ability.childrens.should be_empty
91
+ ability.role(:name)
92
+ ability.childrens.should_not be_empty
93
+ end
94
+
95
+ it "appends the content if the name is already present" do
96
+ ability.role(:test) { can :do, :this }
97
+ # should create one children ...
98
+ ability.childrens.length.should be(1)
99
+ # ... and one ability
100
+ ability.childrens.first.abilities.length.should be(1)
101
+
102
+ ability.role(:test) { can :do, :this }
103
+ # should not create other children ...
104
+ ability.childrens.length.should be(1)
105
+ # ... and append the new ability
106
+ ability.childrens.first.abilities.length.should be(2)
107
+ end
108
+ end
109
+
110
+ describe "#group" do
111
+ it "not add the group name to ability list" do
112
+ ability.group(:test)
113
+ MoulinRouge::Authorization.abilities.should_not include(:test)
114
+ end
115
+ end
116
+
117
+ describe "#group?" do
118
+ it "returns true if is a group and false otherwise" do
119
+ role = ability.role(:role)
120
+ group = ability.group(:group)
121
+ role.group?.should be_false
122
+ group.group?.should be_true
123
+ end
124
+ end
125
+
126
+ describe "#role?" do
127
+ it "returns true if is a group and false otherwise" do
128
+ role = ability.role(:role)
129
+ group = ability.group(:group)
130
+ role.role?.should be_true
131
+ group.role?.should be_false
132
+ end
133
+ end
134
+
135
+ describe "#method_missing" do
136
+ let(:args) { [:one, :two] }
137
+ let(:proc) { Proc.new { :block } }
138
+
139
+ context "collect all cancan methods and store under abilities" do
140
+ MoulinRouge::Ability::CANCAN_METHODS.each do |method_name|
141
+ describe "##{method_name}" do
142
+ it "adds a new ability to this ability" do
143
+ ability.abilities.should be_empty
144
+ ability.send(method_name, *args, &proc)
145
+ ability.abilities.should_not be_empty
146
+ end
147
+
148
+ it "stores nil on block attribute when no block is given" do
149
+ ability.send(method_name, *args)
150
+ ability.abilities.first.block.should be_nil
151
+ end
152
+
153
+ it "stores the method" do
154
+ ability.abilities.should be_empty
155
+ ability.send(method_name, *args, &proc)
156
+ ability.abilities.should_not be_empty
157
+
158
+ method = ability.abilities.first
159
+ method.should be_a(MoulinRouge::CanCan::Method)
160
+ # Evaluate the class of the arguments and block
161
+ method.args.should be_a(Array)
162
+ method.block.should be_a(Proc)
163
+ # Just check the value
164
+ method.args.should eq(args)
165
+ method.block.call.should be(:block)
166
+ end
167
+ end
168
+ end
169
+ end
170
+
171
+ it "receives and stores in a proc calls on the model object" do
172
+ cancan_ability = nil
173
+ ability.role(:test) do
174
+ cancan_ability = can :do, :this, :user_id => current_user.id
175
+ end
176
+ cancan_ability.args.last[:user_id].should be_a(Proc)
177
+ end
178
+
179
+ it "raise an error if the method is not registered has a cancan method" do
180
+ lambda { ability.send(:abcdefg, *args, &proc) }.should raise_error(NoMethodError)
181
+ end
182
+ end
183
+
184
+ describe "#find" do
185
+ it "returns the instance of the ability if there is children with this name and nil otherwise" do
186
+ role = ability.role(:test)
187
+ ability.find(:test).should be(role)
188
+ ability.find(:bad).should be_nil
189
+ end
190
+ end
191
+
192
+ describe "#name" do
193
+ it "returns an symbol containing the name with the parents separeted by a underscore" do
194
+ first_children, second_children = nil
195
+ MoulinRouge::Ability.new(:main) do
196
+ first_children = role(:one) do
197
+ second_children = role(:two)
198
+ end
199
+ end
200
+ first_children.name.should be(:one)
201
+ second_children.name.should be(:one_two)
202
+ end
203
+ end
204
+
205
+ describe "#include" do
206
+ it "appends all childrens and abilities from one object to another" do
207
+ one, another = nil
208
+ one = ability.role(:one) do
209
+ role(:nested)
210
+ can :do, :something
211
+ end
212
+ another = ability.role(:another) do
213
+ include :one
214
+ end
215
+ another.childrens.should_not be_empty
216
+ another.abilities.should_not be_empty
217
+ another.childrens.first.singular_name.should be(:nested)
218
+ another.abilities.first.args.should include(:do, :something)
219
+ end
220
+
221
+ it "raises an error if could not find the requested ability" do
222
+ lambda {
223
+ ability.role(:name) do
224
+ include :not_found
225
+ end
226
+ }.should raise_error(MoulinRouge::RoleNotFound)
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe MoulinRouge::Authorization do
4
+ let(:ability) { MoulinRouge::Ability.new(:name) }
5
+
6
+ context "self" do
7
+ describe "#method_missing" do
8
+ it "delegates any missing method to the main ability class" do
9
+ MoulinRouge::Authorization.main.should_receive(:role).with(:test)
10
+ MoulinRouge::Authorization.main.should_receive(:can).with(:test)
11
+ MoulinRouge::Authorization.role(:test)
12
+ MoulinRouge::Authorization.can(:test)
13
+ end
14
+ end
15
+
16
+ describe "#main" do
17
+ it "returns the main MoulinRouge::Authorization instance" do
18
+ MoulinRouge::Authorization.main.should be_instance_of(ability.class)
19
+ end
20
+ end
21
+
22
+ describe "#roles" do
23
+ it "returns an array" do
24
+ MoulinRouge::Authorization.roles.should be_a(Array)
25
+ end
26
+ end
27
+
28
+ describe "#abilities" do
29
+ it "returns a hash with all registered roles with assigned abilities" do
30
+ MoulinRouge::Authorization.abilities.should be_a(Hash)
31
+ end
32
+
33
+ it "store all abilities instantiated unless the main one" do
34
+ hello_world = ability.role(:hello_world) do
35
+ can :do
36
+ end
37
+ MoulinRouge::Authorization.abilities[hello_world.name].should be(hello_world)
38
+ end
39
+ end
40
+
41
+ describe "#register" do
42
+ it "should append the object instance on Authorization.all and Authorization.names" do
43
+ object = double(:name => :foo)
44
+ MoulinRouge::Authorization.abilities.should_receive(:'[]=').with(object.name, object)
45
+ MoulinRouge::Authorization.roles.should_receive(:'<<').with(object.name)
46
+ MoulinRouge::Authorization.register(object)
47
+ end
48
+ end
49
+
50
+ describe "#compile!" do
51
+ let(:files_loaded) { [] }
52
+
53
+ it "load all files in the configuration path" do
54
+ Kernel.stub(:load) { |file| files_loaded << file }
55
+ MoulinRouge::Authorization.compile!
56
+ files_loaded.should include(*Dir[MoulinRouge.configuration.path])
57
+ end
58
+
59
+ it "should load all roles defined into the Authorization abilities" do
60
+ MoulinRouge::Authorization.roles.should be_empty
61
+ MoulinRouge::Authorization.compile!
62
+ MoulinRouge::Authorization.roles.should_not be_empty
63
+ MoulinRouge::Authorization.roles.should include(:fixture)
64
+ end
65
+
66
+ it "let raise exceptions when there are syntax errors" do
67
+ tests = []
68
+ tests << %|
69
+ # Wrong method name
70
+ roe :name do
71
+ end
72
+ |
73
+ tests << %|
74
+ # Wrong method name
75
+ groups :name do
76
+ end
77
+ |
78
+ tests << %|
79
+ # Wrong method name
80
+ cn :
81
+ |
82
+ tests << %|
83
+ # Wrong method name
84
+ role do
85
+ end
86
+ |
87
+ # Execute them all
88
+ tests.each do |test|
89
+ create_authorization test
90
+ lambda { ability.import(MoulinRouge.configuration.path) }.should raise_error
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "#reset!" do
96
+ it "sets to nil the main, role and abilities instance variables" do
97
+ # Create some
98
+ ability.role(:one)
99
+ ability.role(:two)
100
+ MoulinRouge::Authorization.abilities.should_not be_empty
101
+ MoulinRouge::Authorization.roles.should_not be_empty
102
+ # Apply
103
+ MoulinRouge::Authorization.reset!
104
+ # Evaluate constants
105
+ MoulinRouge::Authorization.class_variable_get(:'@@main').should be_nil
106
+ MoulinRouge::Authorization.class_variable_get(:'@@abilities').should be_nil
107
+ MoulinRouge::Authorization.class_variable_get(:'@@roles').should be_nil
108
+ # Evaluate has arrays
109
+ MoulinRouge::Authorization.abilities.should be_empty
110
+ MoulinRouge::Authorization.roles.should be_empty
111
+ end
112
+ end
113
+
114
+ describe "#new" do
115
+ it "raises an error because the class only act as a singleton" do
116
+ lambda { MoulinRouge::Authorization.new }.should raise_error(NoMethodError)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -4,7 +4,7 @@ describe MoulinRouge::CanCan::Ability do
4
4
  let(:test_method) { MoulinRouge.configuration.test_method.to_sym }
5
5
  let(:model) { double("model", test_method => true) }
6
6
  let(:ability) { MoulinRouge::CanCan::Ability.new(model) }
7
- let(:permission) { MoulinRouge::Permission.main }
7
+ let(:permission) { MoulinRouge::Authorization.main }
8
8
 
9
9
  before(:each) do
10
10
  MoulinRouge::CanCan::Ability.any_instance.stub(:can) { true }
@@ -56,7 +56,7 @@ describe MoulinRouge::CanCan::Ability do
56
56
 
57
57
  it "executes the can method with exactly the same arguments and block that was stored" do
58
58
  # Concat permissions from main and from all defined classes
59
- abilities = permission.abilities + MoulinRouge::Permission.all.values.map(&:abilities)
59
+ abilities = permission.abilities + MoulinRouge::Authorization.abilities.values.map(&:abilities)
60
60
  abilities.flatten.each do |ability|
61
61
  MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(*ability.args, &ability.block).at_least(:once)
62
62
  end
@@ -65,7 +65,7 @@ describe MoulinRouge::CanCan::Ability do
65
65
 
66
66
  it "reloads all permissions when cache is set to false" do
67
67
  MoulinRouge.configuration.cache = false
68
- MoulinRouge.should_receive(:reload!).once
68
+ MoulinRouge.should_receive(:reload!).twice # Here and inside spec_helpe.rb before(:each)
69
69
  ability # Execute
70
70
  end
71
71
 
@@ -79,9 +79,9 @@ describe MoulinRouge::CanCan::Ability do
79
79
  end
80
80
 
81
81
  it "executes any proc on the model object" do
82
- MoulinRouge::Permission.reset!
82
+ MoulinRouge::Authorization.reset!
83
83
  ####
84
- MoulinRouge::Permission.main.can(:do, :this, :user_id => MoulinRouge::ModelDouble.new.id)
84
+ MoulinRouge::Authorization.main.can(:do, :this, :user_id => MoulinRouge::ModelDouble.new.id)
85
85
  model.should_receive(:id)
86
86
  ability # Execute
87
87
  end