moulin_rouge 0.0.1.alpha
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/CHANGELOG.md +2 -0
- data/MIT-LICENSE +20 -0
- data/README.md +215 -0
- data/init.rb +3 -0
- data/lib/moulin_rouge.rb +44 -0
- data/lib/moulin_rouge/cancan/ability.rb +25 -0
- data/lib/moulin_rouge/cancan/method.rb +24 -0
- data/lib/moulin_rouge/cancan/responder.rb +7 -0
- data/lib/moulin_rouge/configuration.rb +15 -0
- data/lib/moulin_rouge/model_double.rb +10 -0
- data/lib/moulin_rouge/permission.rb +140 -0
- data/lib/moulin_rouge/version.rb +3 -0
- data/lib/tasks/moulin_rouge_tasks.rake +4 -0
- data/spec/fixtures/role.rb +3 -0
- data/spec/moulin_rouge/cancan/ability_spec.rb +89 -0
- data/spec/moulin_rouge/cancan/method_spec.rb +40 -0
- data/spec/moulin_rouge/cancan/responder_spec.rb +5 -0
- data/spec/moulin_rouge/configuration_spec.rb +71 -0
- data/spec/moulin_rouge/model_double_spec.rb +16 -0
- data/spec/moulin_rouge/permission_spec.rb +316 -0
- data/spec/moulin_rouge_spec.rb +77 -0
- data/spec/spec_helper.rb +40 -0
- metadata +132 -0
data/CHANGELOG.md
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
Moulin Rouge
|
2
|
+
============
|
3
|
+
|
4
|
+
**Moulin Rouge** is a DSL to manage your permissions and groups of access outside the [CanCan](https://github.com/ryanb/cancan) Ability class. It will help you organize and declare your permissions with has much ruby files you judge necessary, that are automatically pushed to CanCan authorization system. It is also decoupled from the role system.
|
5
|
+
|
6
|
+
There are a bunch of examples bellow to show you how to implement.
|
7
|
+
|
8
|
+
Installation
|
9
|
+
------------
|
10
|
+
|
11
|
+
Add the gem to your Gemfile:
|
12
|
+
|
13
|
+
gem 'moulin_rouge'
|
14
|
+
|
15
|
+
And install it
|
16
|
+
|
17
|
+
bundle install
|
18
|
+
|
19
|
+
Run the generator to install the roles and permissions structure:
|
20
|
+
|
21
|
+
rails g moulinrouge:install
|
22
|
+
|
23
|
+
Generate a permission file:
|
24
|
+
|
25
|
+
rails g moulinrouge:permission <name>
|
26
|
+
|
27
|
+
Add your permissions to newly created file:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
role :name do
|
31
|
+
can :read, :something
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
By default your `current_user` method should respond to `is?`, but you can change this method to match your role system at the configuration.
|
36
|
+
|
37
|
+
Usage
|
38
|
+
-----
|
39
|
+
|
40
|
+
First of all, you have to accept that the role registering belongs to the ruby code. Organizing this ruby files it's a really important issue to any large application.
|
41
|
+
|
42
|
+
When you run:
|
43
|
+
|
44
|
+
bundle g moulinrouge:install
|
45
|
+
|
46
|
+
This will create the following folder structure:
|
47
|
+
|
48
|
+
root
|
49
|
+
| app/
|
50
|
+
| | permissions/
|
51
|
+
| config/
|
52
|
+
| | initalizers
|
53
|
+
| | | moulin_rouge.rb
|
54
|
+
|
55
|
+
### Defining roles ###
|
56
|
+
|
57
|
+
All your permission files will be stored inside the `app/permissions` folder. Just create a ruby file inside and the definitions will be automatically defined.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
role :superuser do
|
61
|
+
can :manage, :all
|
62
|
+
end
|
63
|
+
|
64
|
+
role :editors do
|
65
|
+
can :manage, Articles
|
66
|
+
end
|
67
|
+
|
68
|
+
role :authors do
|
69
|
+
can :manage, Article do |article|
|
70
|
+
article.user_id == current_user.id
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Note that the `can` method is the **same** for defining abilities in CanCan, and will be passed as they are on the Ability class. See [Defining Abilities](https://github.com/ryanb/cancan/wiki/defining-abilities) for more information on what you `can` do.
|
76
|
+
|
77
|
+
Also, the others CanCan methods are avaliable (`cannot`, `can?`, `cannot?`) and will act like expected.
|
78
|
+
|
79
|
+
### Groups ###
|
80
|
+
|
81
|
+
A group is an easy way to organize your permissions, no matter where file the definition is. All groups with the same name, will have their abilities and permissions nested together.
|
82
|
+
|
83
|
+
The group will delegate all abilities defined into, to their childrens, so any children role or group will have the abilities defined in the parent. Also the group is not an avaliable role, they only serve has namespaces.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
group :marketing do
|
87
|
+
can :read, Dashboard
|
88
|
+
|
89
|
+
role :manager do
|
90
|
+
can :manage, Proposal
|
91
|
+
end
|
92
|
+
|
93
|
+
role :salesman do
|
94
|
+
can :manage, Proposal, :user_id => current_user.id
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
To avoid name conflicts, whenever you have a nested roles or groups, their name will be prefixed with the parent name separeted by a `_` underscore just like they were namespaced.
|
100
|
+
|
101
|
+
Following the example above, will generate two roles:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
MoulinRouge::Permission.list
|
105
|
+
# => [:marketing_manager, :marketing_salesman]
|
106
|
+
# => :marketing_manager => can :read, Dashboard, can :manage, Proposal
|
107
|
+
# => :marketing_salesman => can :read, Dashboard, can :manage, Proposal, :user_id => current_user.id
|
108
|
+
```
|
109
|
+
|
110
|
+
### Nested roles ###
|
111
|
+
|
112
|
+
When you have nested rules, they will act has namespaces, no ability will be shared unless is explicited with the `include` method.
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
role :marketing do
|
116
|
+
can :manage, Proposal
|
117
|
+
|
118
|
+
role :salesman do
|
119
|
+
can :read, Proposal
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
Following the example above, this will generate two roles with the abilities:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
MoulinRouge::Permission.list
|
128
|
+
# => [:marketing, :marketing_salesman]
|
129
|
+
# => :marketing => can :manage, Proposal
|
130
|
+
# => :marketing_salesman => can :read, Proposal
|
131
|
+
```
|
132
|
+
|
133
|
+
### Extending ###
|
134
|
+
|
135
|
+
Many times you want to extend a role from another one, **MoulinRouge** let you `include` the abilities from one role to another, all the abilities from the target will be appended to the caller.
|
136
|
+
|
137
|
+
Only roles can be included, and if you provide a name that isn't defined, a `RoleNotFound` will be raised. Notice by the example bellow, that you should provide the full name of the role in order to find the correct one.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
group :marketing do
|
141
|
+
role :admin do
|
142
|
+
can :do, :something
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
role :super do
|
147
|
+
include :marketing_admin
|
148
|
+
end
|
149
|
+
```
|
150
|
+
|
151
|
+
Configuration
|
152
|
+
-------------
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
MoulinRouge.configure do |config|
|
156
|
+
# Cache permissions
|
157
|
+
config.cache = Rails.env.production?
|
158
|
+
# The search path for permissions
|
159
|
+
config.path = 'app/permissions/**/*.rb'
|
160
|
+
# The method that will test the permission
|
161
|
+
config.test_method = :is?
|
162
|
+
# The class of the model
|
163
|
+
config.model = User
|
164
|
+
# How you like to call the active user model
|
165
|
+
config.model_instance = :current_user
|
166
|
+
end
|
167
|
+
```
|
168
|
+
|
169
|
+
Goodies
|
170
|
+
-------
|
171
|
+
|
172
|
+
For those who like I dislikes the `load_and_authorize_resource` method from CanCan, here is provided a cleaner and more flexible solution through `ActionController::Responder`, the `MoulinRouge::CanCan::Responder` bellow there are instruction to activate them.
|
173
|
+
|
174
|
+
Create the file `lib/application_responder.rb` with the following:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
require 'moulin_rouge/cancan/responder'
|
178
|
+
|
179
|
+
class ApplicationResponder < ActionController::Responder
|
180
|
+
include MoulinRouge::CanCan::Responder
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
And on your `application_controller.rb` just add the responder:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
require 'application_responder'
|
188
|
+
|
189
|
+
class ApplicationController < ActionController::Base
|
190
|
+
protect_from_forgery
|
191
|
+
self.responder = ApplicationResponder
|
192
|
+
...
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
More about the `Responder` class:
|
197
|
+
|
198
|
+
* http://blog.plataformatec.com.br/2009/08/embracing-rest-with-mind-body-and-soul/
|
199
|
+
* http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with/
|
200
|
+
|
201
|
+
Thanks
|
202
|
+
=======
|
203
|
+
|
204
|
+
* [Troles](https://github.com/kristianmandrup/trole)
|
205
|
+
* [CanTango](https://github.com/kristianmandrup/cantango)
|
206
|
+
* [Declarative Authorization](https://github.com/stffn/declarative_authorization)
|
207
|
+
|
208
|
+
### A little of history ###
|
209
|
+
|
210
|
+
Mouling Rouge is a cabaret in Paris best know as the birthplace on modern [CanCan](https://github.com/ryanb/cancan) second to [Wikipedia](http://en.wikipedia.org/wiki/Moulin_Rouge).
|
211
|
+
|
212
|
+
Credits
|
213
|
+
=======
|
214
|
+
|
215
|
+
**Edson Hilios** <edson (at) hilios (dot) com (dot) br>
|
data/init.rb
ADDED
data/lib/moulin_rouge.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Dir[File.expand_path("moulin_rouge/**/*.rb", File.dirname(__FILE__))].each {|f| require f;}
|
2
|
+
|
3
|
+
module MoulinRouge
|
4
|
+
# Returns the global Configuration object.
|
5
|
+
def self.configuration
|
6
|
+
@configuration ||= MoulinRouge::Configuration.new
|
7
|
+
end
|
8
|
+
|
9
|
+
# Yields the global configuration to a block.
|
10
|
+
def self.configure
|
11
|
+
yield configuration if block_given?
|
12
|
+
end
|
13
|
+
|
14
|
+
# Create the main permission, import all permission files and
|
15
|
+
# define the Ability class require for CanCan
|
16
|
+
def self.run!
|
17
|
+
self.load!
|
18
|
+
# Create the ability class
|
19
|
+
Object.const_set 'Ability', Class.new(MoulinRouge::CanCan::Ability) unless Object.const_defined? 'Ability'
|
20
|
+
# Change flag
|
21
|
+
@@run = true
|
22
|
+
end
|
23
|
+
|
24
|
+
# Import all permission files in the configuration
|
25
|
+
def self.load!
|
26
|
+
MoulinRouge::Permission.main.import(MoulinRouge.configuration.path)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns true if the run! method was called and false oterwise
|
30
|
+
def self.run?
|
31
|
+
@@run ||= false
|
32
|
+
end
|
33
|
+
|
34
|
+
# Reset all permission and load them again
|
35
|
+
def self.reload!
|
36
|
+
reset!
|
37
|
+
load!
|
38
|
+
end
|
39
|
+
|
40
|
+
# Reset all constants
|
41
|
+
def self.reset! #:nodoc:
|
42
|
+
MoulinRouge::Permission.reset!
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cancan'
|
2
|
+
|
3
|
+
module MoulinRouge
|
4
|
+
module CanCan
|
5
|
+
class Ability
|
6
|
+
include ::CanCan::Ability
|
7
|
+
# Define all permissions collect by MoulinRouge
|
8
|
+
def initialize(model)
|
9
|
+
model = MoulinRouge.configuration.model.new if model.nil? and not MoulinRouge.configuration.model.nil?
|
10
|
+
# Reload all permissions if cache is disabled
|
11
|
+
MoulinRouge.reload! unless MoulinRouge.configuration.cache
|
12
|
+
# Set all permissions in main
|
13
|
+
MoulinRouge::Permission.main.abilities.each do |ability|
|
14
|
+
ability.send_to(self, model)
|
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)
|
20
|
+
end if model.send(MoulinRouge.configuration.test_method, role)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MoulinRouge
|
2
|
+
module CanCan
|
3
|
+
class Method
|
4
|
+
attr_reader :name, :args, :block
|
5
|
+
def initialize(name, *args, &block)
|
6
|
+
@name, @args, @block = name, args, block
|
7
|
+
end
|
8
|
+
|
9
|
+
# Send this method to the given object
|
10
|
+
def send_to(object, proc_scope = nil)
|
11
|
+
# Evaluate any proc in args
|
12
|
+
if args.last.is_a?(Hash)
|
13
|
+
args.last.each do |key, value|
|
14
|
+
if value.is_a?(Proc)
|
15
|
+
args.last[key] = value.call(proc_scope || object)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
# Send
|
20
|
+
object.send(name, *args, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module MoulinRouge
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :path, :test_method, :cache, :model_instance, :model
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@path = "app/permissions/**/*.rb"
|
9
|
+
@test_method = :is?
|
10
|
+
@cache = true
|
11
|
+
@model = nil
|
12
|
+
@model_instance = :current_user
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module MoulinRouge
|
2
|
+
class RoleNotFound < Exception; end
|
3
|
+
# A wrapper to catch and store the DSL methods
|
4
|
+
class Permission
|
5
|
+
CANCAN_METHODS = [:can, :cannot, :can?, :cannot?]
|
6
|
+
# Returns a string with the given name
|
7
|
+
attr_reader :singular_name
|
8
|
+
|
9
|
+
# Returns a instance of the parent permission.
|
10
|
+
# When nil this is the main permission.
|
11
|
+
attr_reader :parent
|
12
|
+
|
13
|
+
# Returns true if it's a group or flase otherwise
|
14
|
+
attr_reader :is_a_group
|
15
|
+
|
16
|
+
# Creates a new permission and evaluate the given block
|
17
|
+
# with roles, groups and abilities on this scope.
|
18
|
+
# If the parent is a group append all their abilities to self
|
19
|
+
def initialize(name, options = {}, &block)
|
20
|
+
@singular_name = name
|
21
|
+
@parent = options.delete(:parent)
|
22
|
+
@is_group = options.delete(:group)
|
23
|
+
abilities.concat(parent.abilities) if not parent.nil? and parent.group?
|
24
|
+
instance_eval(&block) if block_given?
|
25
|
+
# Store this permission
|
26
|
+
self.class.add(self) unless parent.nil? or @is_group
|
27
|
+
end
|
28
|
+
|
29
|
+
def method_missing(name, *args, &block)
|
30
|
+
return store_method(name, *args, &block) if CANCAN_METHODS.include?(name)
|
31
|
+
return MoulinRouge::ModelDouble.new if MoulinRouge.configuration.model_instance == name
|
32
|
+
super(name, *args, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Define a new role inside this scope. If exists a role with the
|
36
|
+
# same name evaluate the block inside them instead of create a new one
|
37
|
+
def role(name, options = {}, &block)
|
38
|
+
if children = find(name)
|
39
|
+
children.instance_eval(&block)
|
40
|
+
children
|
41
|
+
else
|
42
|
+
childrens << self.class.new(name, options.merge!({:parent => self}), &block)
|
43
|
+
childrens.last
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Define a group inside this scope
|
48
|
+
def group(name, options = {}, &block)
|
49
|
+
options.merge!({:group => true})
|
50
|
+
role(name, options, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns true if is a group
|
54
|
+
def group?
|
55
|
+
@is_group
|
56
|
+
end
|
57
|
+
|
58
|
+
# Add the given parameters to the authorizations list
|
59
|
+
def store_method(name, *args, &block)
|
60
|
+
abilities << MoulinRouge::CanCan::Method.new(name, *args, &block)
|
61
|
+
abilities.last
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns an array with all childrens
|
65
|
+
def childrens
|
66
|
+
@childrens ||= []
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns an array with all authorizations declared on this permission
|
70
|
+
def abilities
|
71
|
+
@abilities ||= []
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns all abilities for this permission.
|
75
|
+
# If this is a group, grab the abilities from parent.
|
76
|
+
def inherithed_abilities
|
77
|
+
abilities.concat(childrens.map(&:inherithed_abilities).flatten).uniq
|
78
|
+
end
|
79
|
+
|
80
|
+
# Execute all files in the given path in the class scope
|
81
|
+
def import(path)
|
82
|
+
Dir[path].each { |file| instance_eval(File.open(file).read) }
|
83
|
+
end
|
84
|
+
|
85
|
+
# Returns the instance of the children with the given name if exists and nil otherwise
|
86
|
+
def find(name)
|
87
|
+
childrens.each { |children| return children if children.name == name or children.singular_name == name }
|
88
|
+
return nil
|
89
|
+
end
|
90
|
+
|
91
|
+
# Appends all childrens and abilities from one object to another,
|
92
|
+
# raises an error if could not found a match.
|
93
|
+
def include(name)
|
94
|
+
unless from = self.class.all[name]
|
95
|
+
raise RoleNotFound
|
96
|
+
end
|
97
|
+
from.childrens.each { |children| childrens << children.dup }
|
98
|
+
from.abilities.each { |ability| abilities << ability.dup }
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns a symbol with the name appended with the parents separeted by a underscore
|
102
|
+
def name
|
103
|
+
unless @name
|
104
|
+
@name = []
|
105
|
+
@name << self.parent.name.to_s if not self.parent.nil? and not self.parent.parent.nil?
|
106
|
+
@name << self.singular_name.to_s
|
107
|
+
@name = @name.join('_')
|
108
|
+
end
|
109
|
+
@name.to_sym
|
110
|
+
end
|
111
|
+
|
112
|
+
class << self
|
113
|
+
# The instance of the main container, if don't exist create one
|
114
|
+
def main
|
115
|
+
@main ||= self.new(:main)
|
116
|
+
end
|
117
|
+
# Returns an array with the name of all roles created
|
118
|
+
def list
|
119
|
+
@list ||= []
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns an hash with all permissions defined
|
123
|
+
def all
|
124
|
+
@all ||= {}
|
125
|
+
end
|
126
|
+
|
127
|
+
# Stores the instance on the all hash and add the name to the list
|
128
|
+
def add(instance)
|
129
|
+
name = instance.name
|
130
|
+
self.all[name] = instance
|
131
|
+
self.list << name unless self.list.include?(name)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Reset all constants
|
135
|
+
def reset! #:nodoc:
|
136
|
+
@main, @list, @all = nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge::CanCan::Ability do
|
4
|
+
let(:test_method) { MoulinRouge.configuration.test_method.to_sym }
|
5
|
+
let(:model) { double("model", test_method => true) }
|
6
|
+
let(:ability) { MoulinRouge::CanCan::Ability.new(model) }
|
7
|
+
let(:permission) { MoulinRouge::Permission.main }
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
MoulinRouge::CanCan::Ability.any_instance.stub(:can) { true }
|
11
|
+
# The current permission will create the following abilities
|
12
|
+
# for each role because of nested rules:
|
13
|
+
# => can(:do, :this) # for everybody
|
14
|
+
# :role => can(:do, :something)
|
15
|
+
# :role_nested => can(:create, :something)
|
16
|
+
# :group_nested => can(:read, :something), can(:edit, :something)
|
17
|
+
permission.can(:do, :this)
|
18
|
+
permission.role(:role) do
|
19
|
+
can(:do, :something)
|
20
|
+
|
21
|
+
role(:nested) do
|
22
|
+
can(:create, :something)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
permission.group(:group) do
|
26
|
+
can :read, :something
|
27
|
+
|
28
|
+
role(:nested) do
|
29
|
+
can :edit, :something
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "includes the CanCan::Ability module" do
|
35
|
+
ability.should be_a(CanCan::Ability)
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#initialize" do
|
39
|
+
it "call test_method in model for each permission" do
|
40
|
+
model.should_receive(test_method).with(:role)
|
41
|
+
model.should_receive(test_method).with(:role_nested)
|
42
|
+
model.should_receive(test_method).with(:group_nested)
|
43
|
+
ability
|
44
|
+
end
|
45
|
+
|
46
|
+
it "call can method for each ability of the permission" do
|
47
|
+
# First all permissions in main
|
48
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(:do, :this).once
|
49
|
+
# Please read the expetations explanation at before(:each) method
|
50
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(:do, :something).once
|
51
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(:create, :something).once
|
52
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(:read, :something).once
|
53
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(:edit, :something).once
|
54
|
+
ability # Execute
|
55
|
+
end
|
56
|
+
|
57
|
+
it "executes the can method with exactly the same arguments and block that was stored" do
|
58
|
+
# Concat permissions from main and from all defined classes
|
59
|
+
abilities = permission.abilities + MoulinRouge::Permission.all.values.map(&:abilities)
|
60
|
+
abilities.flatten.each do |ability|
|
61
|
+
MoulinRouge::CanCan::Ability.any_instance.should_receive(:can).with(*ability.args, &ability.block).at_least(:once)
|
62
|
+
end
|
63
|
+
ability # Execute
|
64
|
+
end
|
65
|
+
|
66
|
+
it "reloads all permissions when cache is set to false" do
|
67
|
+
MoulinRouge.configuration.cache = false
|
68
|
+
MoulinRouge.should_receive(:reload!).once
|
69
|
+
ability # Execute
|
70
|
+
end
|
71
|
+
|
72
|
+
it "creates a new instance of model if the config is not nil and the initializer argument is also nil" do
|
73
|
+
klass = Class.new
|
74
|
+
klass.stub(:new) { model }
|
75
|
+
# Test
|
76
|
+
klass.should_receive(:new).once
|
77
|
+
MoulinRouge.configuration.model = klass
|
78
|
+
MoulinRouge::CanCan::Ability.new(nil)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "executes any proc on the model object" do
|
82
|
+
MoulinRouge::Permission.reset!
|
83
|
+
####
|
84
|
+
MoulinRouge::Permission.main.can(:do, :this, :user_id => MoulinRouge::ModelDouble.new.id)
|
85
|
+
model.should_receive(:id)
|
86
|
+
ability # Execute
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge::CanCan::Method do
|
4
|
+
let(:name) { :can }
|
5
|
+
let(:args) { [:one, :two] }
|
6
|
+
let(:proc) { Proc.new { :block } }
|
7
|
+
let(:object) { double(method.name => true) }
|
8
|
+
let(:method) { MoulinRouge::CanCan::Method.new(name, *args, &proc) }
|
9
|
+
|
10
|
+
describe "#args" do
|
11
|
+
it "is a reader attribute" do
|
12
|
+
method.args.should eq(args)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#block" do
|
17
|
+
it "is a reader attribute" do
|
18
|
+
method.block.should eq(proc)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#name" do
|
23
|
+
it "is a reader attribute" do
|
24
|
+
method.name.should eq(name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#send_to" do
|
29
|
+
it "sends this method to the given object" do
|
30
|
+
object.should_receive(method.name).with(*method.args, &method.block)
|
31
|
+
method.send_to(object)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "evaluate any arguments that are proc" do
|
35
|
+
method = MoulinRouge::CanCan::Method.new(:can, :do, :something, :on => proc)
|
36
|
+
method.send_to(object)
|
37
|
+
method.args.last[:on].should be(:block)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge::Configuration do
|
4
|
+
let(:config) { MoulinRouge::Configuration.new }
|
5
|
+
|
6
|
+
describe "#path" do
|
7
|
+
it "returns a string" do
|
8
|
+
config.path.should be_a(String)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#path=" do
|
13
|
+
it "sets the value" do
|
14
|
+
config.path = "test"
|
15
|
+
config.path.should eq("test")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#test_method" do
|
20
|
+
it "returns a symbol" do
|
21
|
+
config.test_method.should be_a(Symbol)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#test_method=" do
|
26
|
+
it "sets the value" do
|
27
|
+
config.test_method = :"test"
|
28
|
+
config.test_method.should eq(:"test")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#cache" do
|
33
|
+
it "returns a boolean" do
|
34
|
+
config.cache.should be_true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#cache=" do
|
39
|
+
it "sets the value" do
|
40
|
+
config.cache = false
|
41
|
+
config.cache.should eq(false)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#model_instance" do
|
46
|
+
it "returns a boolean" do
|
47
|
+
config.model_instance.should be_a(Symbol)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#model_instance=" do
|
52
|
+
it "sets the value" do
|
53
|
+
config.model_instance = :user
|
54
|
+
config.model_instance.should eq(:user)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#model" do
|
59
|
+
it "returns an class or nil" do
|
60
|
+
config.model.should be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#model=" do
|
65
|
+
it "sets the class" do
|
66
|
+
klass = Class.new
|
67
|
+
config.model = klass
|
68
|
+
config.model.should eq(klass)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge::ModelDouble do
|
4
|
+
let(:model) { MoulinRouge::ModelDouble.new }
|
5
|
+
|
6
|
+
it "returns an proc for every method called in this class" do
|
7
|
+
model.id.should be_a(Proc)
|
8
|
+
model.abc.should be_a(Proc)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "the proc sends the methods to the given scope with all arguments" do
|
12
|
+
object = double(:id => true)
|
13
|
+
object.should_receive(:id).with(:this).once
|
14
|
+
model.id(:this).call(object)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,316 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge::Permission do
|
4
|
+
let(:permission) { MoulinRouge::Permission.new(:name) }
|
5
|
+
|
6
|
+
describe "#initialize" do
|
7
|
+
it "evaluate the groups and authorizations to the class scope" do
|
8
|
+
permission = MoulinRouge::Permission.new(:scope) do
|
9
|
+
self.class.should == MoulinRouge::Permission
|
10
|
+
can :do, :something
|
11
|
+
role :for
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "append the new instance to #all and #list if it's a role" do
|
16
|
+
MoulinRouge::Permission.new(:main) do
|
17
|
+
role(:one)
|
18
|
+
end
|
19
|
+
MoulinRouge::Permission.all.should include(:one)
|
20
|
+
MoulinRouge::Permission.list.should include(:one)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "inherits all abilities from parent if this is a group" do
|
24
|
+
role = nil
|
25
|
+
MoulinRouge::Permission.new(:main) do
|
26
|
+
group(:group) do
|
27
|
+
can :do, :this
|
28
|
+
role = role(:role)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
role.abilities.first.args.should include(:do, :this)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#name" do
|
36
|
+
it "returns the given name on class initialization" do
|
37
|
+
permission.name.should be(:name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#parent" do
|
42
|
+
it "returns nil when for main" do
|
43
|
+
permission.parent.should be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns a instance of the MoulinRouge::Permission" do
|
47
|
+
another = MoulinRouge::Permission.new(:another, :parent => permission)
|
48
|
+
another.parent.should be_a(MoulinRouge::Permission)
|
49
|
+
another.parent.should be(permission)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#childrens" do
|
54
|
+
it "returns an array" do
|
55
|
+
permission.childrens.should be_an(Array)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#abilities" do
|
60
|
+
it "returns an array" do
|
61
|
+
permission.abilities.should be_a(Array)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#inherithed_abilities" do
|
66
|
+
it "returns all abilities from self and their childrens" do
|
67
|
+
permission.can :do, :this
|
68
|
+
# First nested level
|
69
|
+
one = permission.role(:one) do
|
70
|
+
can :do, :one
|
71
|
+
end
|
72
|
+
# Second nested level
|
73
|
+
two = one.role(:two) do
|
74
|
+
can :do, :two
|
75
|
+
end
|
76
|
+
permission.inherithed_abilities.should be_an(Array)
|
77
|
+
permission.inherithed_abilities.length.should be(3)
|
78
|
+
one.inherithed_abilities.length.should be(2)
|
79
|
+
two.inherithed_abilities.length.should be(1)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#role" do
|
84
|
+
it "returns a new permission with the parent setted to the class that are calling" do
|
85
|
+
role = permission.role(:test)
|
86
|
+
role.should be_a(MoulinRouge::Permission)
|
87
|
+
role.parent.should be(permission)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "adds a new instance on children" do
|
91
|
+
permission.childrens.should be_empty
|
92
|
+
permission.role(:name)
|
93
|
+
permission.childrens.should_not be_empty
|
94
|
+
end
|
95
|
+
|
96
|
+
it "appends the content if the name is already present" do
|
97
|
+
permission.role(:test) { can :do, :this }
|
98
|
+
# should create one children ...
|
99
|
+
permission.childrens.length.should be(1)
|
100
|
+
# ... and one ability
|
101
|
+
permission.childrens.first.abilities.length.should be(1)
|
102
|
+
|
103
|
+
permission.role(:test) { can :do, :this }
|
104
|
+
# should not create other children ...
|
105
|
+
permission.childrens.length.should be(1)
|
106
|
+
# ... and append the new ability
|
107
|
+
permission.childrens.first.abilities.length.should be(2)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#group" do
|
112
|
+
it "not add the group name to permission list" do
|
113
|
+
permission.group(:test)
|
114
|
+
MoulinRouge::Permission.list.should_not include(:test)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "#group?" do
|
119
|
+
it "returns true if is a group and false otherwise" do
|
120
|
+
role = permission.role(:role)
|
121
|
+
group = permission.group(:group)
|
122
|
+
role.group?.should be_false
|
123
|
+
group.group?.should be_true
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "#method_missing" do
|
128
|
+
let(:args) { [:one, :two] }
|
129
|
+
let(:proc) { Proc.new { :block } }
|
130
|
+
|
131
|
+
context "collect all cancan methods and store under abilities" do
|
132
|
+
MoulinRouge::Permission::CANCAN_METHODS.each do |method_name|
|
133
|
+
describe "##{method_name}" do
|
134
|
+
it "adds a new ability to this permission" do
|
135
|
+
permission.abilities.should be_empty
|
136
|
+
permission.send(method_name, *args, &proc)
|
137
|
+
permission.abilities.should_not be_empty
|
138
|
+
end
|
139
|
+
|
140
|
+
it "stores nil on block attribute when no block is given" do
|
141
|
+
permission.send(method_name, *args)
|
142
|
+
permission.abilities.first.block.should be_nil
|
143
|
+
end
|
144
|
+
|
145
|
+
it "stores the method" do
|
146
|
+
permission.abilities.should be_empty
|
147
|
+
permission.send(method_name, *args, &proc)
|
148
|
+
permission.abilities.should_not be_empty
|
149
|
+
|
150
|
+
method = permission.abilities.first
|
151
|
+
method.should be_a(MoulinRouge::CanCan::Method)
|
152
|
+
# Evaluate the class of the arguments and block
|
153
|
+
method.args.should be_a(Array)
|
154
|
+
method.block.should be_a(Proc)
|
155
|
+
# Just check the value
|
156
|
+
method.args.should eq(args)
|
157
|
+
method.block.call.should be(:block)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it "receives and stores in a proc calls on the model object" do
|
164
|
+
ability = nil
|
165
|
+
permission.role(:test) do
|
166
|
+
ability = can :do, :this, :user_id => current_user.id
|
167
|
+
end
|
168
|
+
ability.args.last[:user_id].should be_a(Proc)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "raise an error if the method is not registered has a cancan method" do
|
172
|
+
lambda { permission.send(:abcdefg, *args, &proc) }.should raise_error(NoMethodError)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "#import" do
|
177
|
+
let(:files_opened) { [] }
|
178
|
+
|
179
|
+
it "glob all files in the given path and evaluate their content in the class scope" do
|
180
|
+
File.stub(:open) { |file| files_opened << file; double("file", :read => "") }
|
181
|
+
permission.import(MoulinRouge.configuration.path)
|
182
|
+
files_opened.should include(*Dir[MoulinRouge.configuration.path])
|
183
|
+
end
|
184
|
+
|
185
|
+
it "let raise exceptions when there are syntax errors" do
|
186
|
+
tests = []
|
187
|
+
tests << %|
|
188
|
+
# Wrong method name
|
189
|
+
roe :name do
|
190
|
+
end
|
191
|
+
|
|
192
|
+
tests << %|
|
193
|
+
# Wrong method name
|
194
|
+
groups :name do
|
195
|
+
end
|
196
|
+
|
|
197
|
+
tests << %|
|
198
|
+
# Wrong method name
|
199
|
+
cn :
|
200
|
+
|
|
201
|
+
tests << %|
|
202
|
+
# Wrong method name
|
203
|
+
role do
|
204
|
+
end
|
205
|
+
|
|
206
|
+
# Execute them all
|
207
|
+
tests.each do |test|
|
208
|
+
create_permission test
|
209
|
+
lambda { permission.import(MoulinRouge.configuration.path) }.should raise_error
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#find" do
|
215
|
+
it "returns the instance of the permission if there is children with this name and nil otherwise" do
|
216
|
+
role = permission.role(:test)
|
217
|
+
permission.find(:test).should be(role)
|
218
|
+
permission.find(:bad).should be_nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "#name" do
|
223
|
+
it "returns an symbol containing the name with the parents separeted by a underscore" do
|
224
|
+
first_children, second_children = nil
|
225
|
+
MoulinRouge::Permission.new(:main) do
|
226
|
+
first_children = role(:one) do
|
227
|
+
second_children = role(:two)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
first_children.name.should be(:one)
|
231
|
+
second_children.name.should be(:one_two)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "#include" do
|
236
|
+
it "appends all childrens and abilities from one object to another" do
|
237
|
+
one, another = nil
|
238
|
+
one = permission.role(:one) do
|
239
|
+
role(:nested)
|
240
|
+
can :do, :something
|
241
|
+
end
|
242
|
+
another = permission.role(:another) do
|
243
|
+
include :one
|
244
|
+
end
|
245
|
+
another.childrens.should_not be_empty
|
246
|
+
another.abilities.should_not be_empty
|
247
|
+
another.childrens.first.singular_name.should be(:nested)
|
248
|
+
another.abilities.first.args.should include(:do, :something)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "raises an error if could not find the requested permission" do
|
252
|
+
lambda {
|
253
|
+
permission.role(:name) do
|
254
|
+
include :not_found
|
255
|
+
end
|
256
|
+
}.should raise_error(MoulinRouge::RoleNotFound)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "self" do
|
261
|
+
describe "#main" do
|
262
|
+
it "returns the main MoulinRouge::Permission instance" do
|
263
|
+
MoulinRouge::Permission.main.should be_instance_of(permission.class)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "#list" do
|
268
|
+
it "returns an array" do
|
269
|
+
MoulinRouge::Permission.list.should be_a(Array)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
describe "#all" do
|
274
|
+
it "returns an hash with all created permissions" do
|
275
|
+
MoulinRouge::Permission.all.should be_a(Hash)
|
276
|
+
end
|
277
|
+
|
278
|
+
it "store all permissions instantiated unless the main one" do
|
279
|
+
hello_world = permission.role(:hello_world) do
|
280
|
+
can :do
|
281
|
+
end
|
282
|
+
MoulinRouge::Permission.all[hello_world.name].should be(hello_world)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "#add" do
|
287
|
+
it "should append the object instance on Permission.all and Permission.names" do
|
288
|
+
object = double(:name => :foo)
|
289
|
+
MoulinRouge::Permission.stub(:all) { @all ||= double() }
|
290
|
+
MoulinRouge::Permission.stub(:list) { @list ||= double(:include? => false) }
|
291
|
+
MoulinRouge::Permission.list.should_receive(:'<<').with(object.name)
|
292
|
+
MoulinRouge::Permission.all.should_receive(:'[]=').with(object.name, object)
|
293
|
+
MoulinRouge::Permission.add(object)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe "#reset!" do
|
298
|
+
it "sets to nil the main, list and all constants" do
|
299
|
+
# Create some
|
300
|
+
permission.role(:one)
|
301
|
+
permission.role(:two)
|
302
|
+
MoulinRouge::Permission.all.should_not be_empty
|
303
|
+
MoulinRouge::Permission.list.should_not be_empty
|
304
|
+
# Apply
|
305
|
+
MoulinRouge::Permission.reset!
|
306
|
+
# Evaluate constants
|
307
|
+
MoulinRouge::Permission.instance_variable_get(:'@main').should be_nil
|
308
|
+
MoulinRouge::Permission.instance_variable_get(:'@all').should be_nil
|
309
|
+
MoulinRouge::Permission.instance_variable_get(:'@list').should be_nil
|
310
|
+
# Evaluate has arrays
|
311
|
+
MoulinRouge::Permission.all.should be_empty
|
312
|
+
MoulinRouge::Permission.list.should be_empty
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MoulinRouge do
|
4
|
+
it "should be a module" do
|
5
|
+
MoulinRouge.should be_a(Module)
|
6
|
+
end
|
7
|
+
|
8
|
+
context "self" do
|
9
|
+
describe "#configuration" do
|
10
|
+
it "returns the same object every time" do
|
11
|
+
MoulinRouge.configuration.should equal(MoulinRouge.configuration)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#configure" do
|
16
|
+
it "yields the current configuration" do
|
17
|
+
MoulinRouge.configure do |config|
|
18
|
+
config.should eq(MoulinRouge::configuration)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#run!" do
|
24
|
+
it "calls the load! method" do
|
25
|
+
MoulinRouge.should_receive(:load!).once
|
26
|
+
MoulinRouge.run!
|
27
|
+
end
|
28
|
+
|
29
|
+
it "creates a class named Ability inherited from MoulinRouge::CanCan::Ability" do
|
30
|
+
MoulinRouge.run!
|
31
|
+
Object.const_get('Ability').should_not be_nil
|
32
|
+
Object.const_get('Ability').ancestors.should include(MoulinRouge::CanCan::Ability)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#run?" do
|
37
|
+
it "returns true if the run! method was called and false oterwise" do
|
38
|
+
MoulinRouge.class_variable_set(:'@@run', false)
|
39
|
+
MoulinRouge.run?.should be_false
|
40
|
+
MoulinRouge.run!
|
41
|
+
MoulinRouge.run?.should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#load!" do
|
46
|
+
context "(with stubs)" do
|
47
|
+
it "call import the config path on the main permission" do
|
48
|
+
MoulinRouge::Permission.main.should_receive(:import).with(MoulinRouge.configuration.path).once
|
49
|
+
MoulinRouge.load!
|
50
|
+
MoulinRouge::Permission.main.should_not be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "(without stubs)" do
|
55
|
+
it "evaluate all permissions in the path" do
|
56
|
+
MoulinRouge.load!
|
57
|
+
MoulinRouge::Permission.main.childrens.should_not be_empty
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "reset!" do
|
63
|
+
it "calls the reset! method on Permission" do
|
64
|
+
MoulinRouge::Permission.should_receive(:reset!).twice # One in the before(:each) in spec_helper.rb and another here
|
65
|
+
MoulinRouge.reset!
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#reload!" do
|
70
|
+
it "Reset all permissions and load them again" do
|
71
|
+
MoulinRouge.should_receive(:reset!).twice # One in the before(:each) in spec_helper.rb and another here
|
72
|
+
MoulinRouge.should_receive(:load!).once
|
73
|
+
MoulinRouge.reload!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
9
|
+
# in spec/support/ and its subdirectories.
|
10
|
+
Dir[File.expand_path("spec/support/**/*.rb")].each {|f| require f}
|
11
|
+
|
12
|
+
# Require all files from the project
|
13
|
+
Dir[File.expand_path("lib/**/*.rb")].each {|f| require f}
|
14
|
+
|
15
|
+
def permission_file
|
16
|
+
File.expand_path("spec/fixtures/spec_permission.rb")
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_permission(content)
|
20
|
+
f = File.open(permission_file, 'w')
|
21
|
+
f.write(content)
|
22
|
+
ensure
|
23
|
+
f.close
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
config.mock_with :rspec
|
28
|
+
config.before do
|
29
|
+
MoulinRouge.configure do |config|
|
30
|
+
config.path = File.join(File.expand_path(File.dirname(__FILE__)), "/fixtures/**/*.rb")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
# Reset the MoulinRouge global variables
|
34
|
+
# Remove the permission file created by the helper
|
35
|
+
config.after(:each) do
|
36
|
+
MoulinRouge.reset!
|
37
|
+
MoulinRouge.configuration.cache = true
|
38
|
+
FileUtils.rm_rf(permission_file) if File.exists?(permission_file)
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moulin_rouge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.alpha
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Edson Hilios
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-16 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cancan
|
16
|
+
requirement: &19713720 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *19713720
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rdoc
|
27
|
+
requirement: &19713280 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *19713280
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &19712860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *19712860
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: guard-rspec
|
49
|
+
requirement: &19712420 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *19712420
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: simplecov
|
60
|
+
requirement: &19712000 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *19712000
|
69
|
+
description: A wrapper to CanCan authorization system, allowing you to define permissions
|
70
|
+
in many ruby files. Add new functionality allowing you do more with less.
|
71
|
+
email:
|
72
|
+
- edson.hilios@gmail.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- CHANGELOG.md
|
78
|
+
- MIT-LICENSE
|
79
|
+
- README.md
|
80
|
+
- lib/tasks/moulin_rouge_tasks.rake
|
81
|
+
- lib/moulin_rouge.rb
|
82
|
+
- lib/moulin_rouge/model_double.rb
|
83
|
+
- lib/moulin_rouge/permission.rb
|
84
|
+
- lib/moulin_rouge/version.rb
|
85
|
+
- lib/moulin_rouge/cancan/responder.rb
|
86
|
+
- lib/moulin_rouge/cancan/ability.rb
|
87
|
+
- lib/moulin_rouge/cancan/method.rb
|
88
|
+
- lib/moulin_rouge/configuration.rb
|
89
|
+
- init.rb
|
90
|
+
- spec/fixtures/role.rb
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
- spec/moulin_rouge_spec.rb
|
93
|
+
- spec/moulin_rouge/permission_spec.rb
|
94
|
+
- spec/moulin_rouge/configuration_spec.rb
|
95
|
+
- spec/moulin_rouge/cancan/method_spec.rb
|
96
|
+
- spec/moulin_rouge/cancan/responder_spec.rb
|
97
|
+
- spec/moulin_rouge/cancan/ability_spec.rb
|
98
|
+
- spec/moulin_rouge/model_double_spec.rb
|
99
|
+
homepage: https://github.com/hilios/moulin_rouge
|
100
|
+
licenses: []
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
none: false
|
113
|
+
requirements:
|
114
|
+
- - ! '>'
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 1.3.1
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 1.8.10
|
120
|
+
signing_key:
|
121
|
+
specification_version: 3
|
122
|
+
summary: Organize your CanCan permissions in many files.
|
123
|
+
test_files:
|
124
|
+
- spec/fixtures/role.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
- spec/moulin_rouge_spec.rb
|
127
|
+
- spec/moulin_rouge/permission_spec.rb
|
128
|
+
- spec/moulin_rouge/configuration_spec.rb
|
129
|
+
- spec/moulin_rouge/cancan/method_spec.rb
|
130
|
+
- spec/moulin_rouge/cancan/responder_spec.rb
|
131
|
+
- spec/moulin_rouge/cancan/ability_spec.rb
|
132
|
+
- spec/moulin_rouge/model_double_spec.rb
|