walruz 0.0.3

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,99 @@
1
+ module Walruz
2
+ module Subject
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+
7
+ def self._walruz_policies=(policies)
8
+ @_walruz_policies = policies
9
+ end
10
+
11
+ def self._walruz_policies
12
+ @_walruz_policies
13
+ end
14
+
15
+ extend ClassMethods
16
+ end
17
+ end
18
+
19
+ # @private
20
+ def can_be?(action, actor)
21
+ check_authorization_actions_are_setted(action)
22
+ action = if self.class._walruz_policies.key?(:default)
23
+ self.class._walruz_policies.key?(action) ? action : :default
24
+ else
25
+ if self.class._walruz_policies.key?(action)
26
+ action
27
+ else
28
+ raise ActionNotFound.new(:subject_action, :subject => self,
29
+ :action => action)
30
+ end
31
+ end
32
+
33
+ result = self.class._walruz_policies[action].
34
+ return_policy.
35
+ new.
36
+ safe_authorized?(actor, self)
37
+
38
+ result
39
+ end
40
+
41
+ # @private
42
+ def check_authorization_actions_are_setted(action)
43
+ if self.class._walruz_policies.nil?
44
+ message =<<BEGIN
45
+ You need to invoke `check_authorizations :#{action} => Policies::SomePolicy` on the #{self.class.name} class
46
+ BEGIN
47
+ raise AuthorizationActionsNotDefined.new(message)
48
+ end
49
+ end
50
+
51
+ module ClassMethods
52
+
53
+ #
54
+ # Stablishes the actions that can be made with a subject. You may
55
+ # specify as many actions as you like, and also you may have a default
56
+ # policy, that will get execute if a specified flag doesn't exist.
57
+ # You just have to pass the action :default, or just the policy class.
58
+ #
59
+ # Example:
60
+ # # Without :default key
61
+ # class UserProfile
62
+ # check_authorizations :read => Policies::FriendPolicy,
63
+ # :write => Policies::OwnerPolicy
64
+ # end
65
+ #
66
+ # # With :default key
67
+ # class UserProfile
68
+ # check_authorizations :read => Policies::FriendPolicy,
69
+ # :write => Policies::OwnerPolicy,
70
+ # :default => Policies::AdminPolicy
71
+ # end
72
+ #
73
+ # # Without any key at all
74
+ # class UserProfile
75
+ # # this policy is the default one
76
+ # check_authorizations Policies::OwnerPolicy
77
+ # end
78
+ #
79
+ # Once you stablish the authorizations policies on a subject, you can
80
+ # check if an actor is able to interact with it via the Actor#can? method
81
+ #
82
+ # Example: current_user.can?(:read, profile)
83
+ #
84
+ # It's recommended (but not mandatory) that a policy specified to the action
85
+ # is inherting from Walruz::Policy
86
+ #
87
+ def check_authorizations(policy_map)
88
+ case policy_map
89
+ when Hash
90
+ self._walruz_policies = policy_map
91
+ else
92
+ self._walruz_policies = { :default => policy_map }
93
+ end
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,119 @@
1
+ module Walruz
2
+ module Utils
3
+
4
+ module PolicyCompositionHelper
5
+
6
+ # NOTE: Not using cattr_accessor to avoid dependencies with ActiveSupport
7
+
8
+ def policies=(policies)
9
+ @policies = policies
10
+ end
11
+
12
+ def policies
13
+ @policies
14
+ end
15
+
16
+ def policy=(policy)
17
+ @policy = policy
18
+ end
19
+
20
+ def policy
21
+ @policy
22
+ end
23
+
24
+ def set_params(params = {})
25
+ @params ||= {}
26
+ @params.merge!(params)
27
+ end
28
+
29
+ def params
30
+ @params
31
+ end
32
+
33
+ end
34
+
35
+ def orP(*policies)
36
+ clazz = Class.new(Walruz::Policy) do
37
+ extend PolicyCompositionHelper
38
+
39
+ def authorized?(actor, subject)
40
+ result = nil
41
+ self.class.policies.detect do |policy|
42
+ result = policy.new.safe_authorized?(actor, subject)
43
+ result[0]
44
+ end
45
+ result[0] ? result : result[0]
46
+ end
47
+
48
+ end
49
+ clazz.policies = policies
50
+ clazz
51
+ end
52
+
53
+ def andP(*policies)
54
+ clazz = Class.new(Walruz::Policy) do
55
+ extend PolicyCompositionHelper
56
+
57
+ def authorized?(actor, subject)
58
+ acum = [true, {}]
59
+ self.class.policies.each do |policy|
60
+ break unless acum[0]
61
+ policy_instance = policy.new
62
+ policy_instance.set_params(acum[1])
63
+ result = policy_instance.safe_authorized?(actor, subject)
64
+ acum[0] &&= result[0]
65
+ acum[1].merge!(result[1])
66
+ end
67
+ acum[0] ? acum : acum[0]
68
+ end
69
+
70
+ def self.policy_keyword
71
+ (self.policies.map { |p| p.policy_keyword.to_s[0..-2] }.join('_and_') + "?").to_sym
72
+ end
73
+
74
+ end
75
+ clazz.policies = policies
76
+ clazz
77
+ end
78
+
79
+ def notP(policy)
80
+ clazz = Class.new(Walruz::Policy) do
81
+ extend PolicyCompositionHelper
82
+
83
+ def authorized?(actor, subject)
84
+ result = self.class.policy.new.safe_authorized?(actor, subject)
85
+ !result[0]
86
+ end
87
+
88
+ def self.policy_keyword
89
+ keyword = self.policy.policy_keyword.to_s[0..-2]
90
+ :"not(#{keyword})?"
91
+ end
92
+
93
+ end
94
+ clazz.policy = policy
95
+ clazz
96
+ end
97
+
98
+ def lift_subject(key, policy, &block)
99
+ clazz = Class.new(Walruz::Policy) do
100
+ extend PolicyCompositionHelper
101
+
102
+ def authorized?(actor, subject)
103
+ params = self.class.params
104
+ new_subject = subject.send(params[:key])
105
+ result = self.class.policy.new.safe_authorized?(actor, new_subject)
106
+ params[:callback].call(result[0], result[1], actor, subject) if params[:callback]
107
+ result
108
+ end
109
+
110
+ end
111
+ clazz.policy = policy
112
+ clazz.set_params(:key => key, :callback => block)
113
+ clazz
114
+ end
115
+
116
+ module_function(:orP, :andP, :notP, :lift_subject)
117
+
118
+ end
119
+ end
data/lib/walruz.rb ADDED
@@ -0,0 +1,54 @@
1
+ module Walruz
2
+
3
+ class NotAuthorized < Exception
4
+ end
5
+
6
+ class AuthorizationActionsNotDefined < Exception
7
+ end
8
+
9
+ class ActionNotFound < Exception
10
+
11
+ def initialize(failure, params = {})
12
+ case failure
13
+ when :subject_action
14
+ super("%s class doesn't have an authorization action called :%s nor a :default policy" % [params[:subject].class.name, params[:action]])
15
+ when :policy_label
16
+ super("There is no Policy with the label %s" % params[:label])
17
+ end
18
+ end
19
+
20
+ end
21
+
22
+ base_path = File.dirname(__FILE__)
23
+ autoload :Actor, base_path + '/walruz/actor'
24
+ autoload :Subject, base_path + '/walruz/subject'
25
+ autoload :Policy, base_path + '/walruz/policy'
26
+ autoload :Utils, base_path + '/walruz/utils'
27
+
28
+ def self.setup
29
+ config = Config.new
30
+ yield config
31
+ end
32
+
33
+ def self.policies
34
+ Walruz::Policy.policies
35
+ end
36
+
37
+ class Config
38
+
39
+ def actors=(actors)
40
+ Array(actors).each do |actor|
41
+ actor.send(:include, Actor)
42
+ end
43
+ end
44
+
45
+ def subjects=(subjects)
46
+ Array(subjects).each do |subject|
47
+ subject.send(:include, Subject)
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+
54
+ end
data/spec/scenario.rb ADDED
@@ -0,0 +1,133 @@
1
+ class Beatle
2
+ include Walruz::Actor
3
+ include Walruz::Subject
4
+
5
+ attr_reader :name
6
+ attr_accessor :songs
7
+ attr_accessor :colaborations
8
+
9
+ def initialize(name)
10
+ @name = name
11
+ @songs = []
12
+ @colaborations = []
13
+ end
14
+
15
+ def sing_the_song(song)
16
+ response = can!(:sing, song)
17
+ case response[:owner]
18
+ when Colaboration
19
+ authors = response[:owner].authors.dup
20
+ authors.delete(self)
21
+ authors.map! { |author| author.name }
22
+ "I need %s to play this song properly" % authors.join(', ')
23
+ when Beatle
24
+ "I just need myself, Let's Rock! \\m/"
25
+ end
26
+ end
27
+
28
+ def sing_with_john(song)
29
+ can!(:sing_with_john, song)
30
+ "Ok John, Let's Play '%s'" % song.name
31
+ end
32
+
33
+
34
+ JOHN = self.new("John")
35
+ PAUL = self.new("Paul")
36
+ RINGO = self.new("Ringo")
37
+ GEORGE = self.new("George")
38
+ end
39
+
40
+ class Colaboration
41
+
42
+ attr_accessor :authors
43
+ attr_accessor :songs
44
+
45
+ def initialize(*authors)
46
+ authors.each do |author|
47
+ author.colaborations << self
48
+ end
49
+ @authors = authors
50
+ @songs = []
51
+ end
52
+
53
+ JOHN_PAUL = self.new(Beatle::JOHN, Beatle::PAUL)
54
+ JOHN_PAUL_GEORGE = self.new(Beatle::JOHN, Beatle::PAUL, Beatle::GEORGE)
55
+ JOHN_GEORGE = self.new(Beatle::JOHN, Beatle::GEORGE)
56
+ end
57
+
58
+ class SubjectIsActorPolicy < Walruz::Policy
59
+
60
+ def authorized?(actor, subject)
61
+ actor == subject
62
+ end
63
+
64
+ end
65
+
66
+ # class AuthorPolicy < Walruz::Policy
67
+ #
68
+ # def authorized?(beatle, song)
69
+ # if song.author == beatle
70
+ # [true, { :owner => beatle }]
71
+ # else
72
+ # false
73
+ # end
74
+ # end
75
+ #
76
+ # end
77
+
78
+ AuthorPolicy = Walruz::Utils.lift_subject(:author, SubjectIsActorPolicy) do |authorized, params, actor, subject|
79
+ params.merge!(:owner => actor) if authorized
80
+ end
81
+
82
+ class AuthorInColaborationPolicy < Walruz::Policy
83
+
84
+ def authorized?(beatle, song)
85
+ return false unless song.colaboration
86
+ if song.colaboration.authors.include?(beatle)
87
+ [true, { :owner => song.colaboration }]
88
+ else
89
+ false
90
+ end
91
+ end
92
+
93
+ end
94
+
95
+ class ColaboratingWithJohnPolicy < Walruz::Policy
96
+ depends_on AuthorInColaborationPolicy
97
+
98
+ def authorized?(beatle, song)
99
+ params[:owner].authors.include?(Beatle::JOHN)
100
+ end
101
+
102
+ end
103
+
104
+ class Song
105
+ include Walruz::Subject
106
+ extend Walruz::Utils
107
+
108
+ check_authorizations :sing => orP(AuthorPolicy, AuthorInColaborationPolicy),
109
+ :sell => andP(AuthorPolicy, notP(AuthorInColaborationPolicy)),
110
+ :sing_with_john => ColaboratingWithJohnPolicy
111
+ attr_accessor :name
112
+ attr_accessor :colaboration
113
+ attr_accessor :author
114
+
115
+ def initialize(name, owner)
116
+ @name = name
117
+ case owner
118
+ when Colaboration
119
+ @colaboration = owner
120
+ when Beatle
121
+ @author = owner
122
+ end
123
+ owner.songs << self
124
+ end
125
+
126
+ A_DAY_IN_LIFE = self.new("A Day In Life", Colaboration::JOHN_PAUL)
127
+ YELLOW_SUBMARINE = self.new("Yellow Submarine", Colaboration::JOHN_PAUL)
128
+ TAXMAN = self.new("Taxman", Colaboration::JOHN_GEORGE)
129
+ YESTERDAY = self.new("Yesterday", Beatle::PAUL)
130
+ ALL_YOU_NEED_IS_LOVE = self.new("All You Need Is Love", Beatle::JOHN)
131
+ BLUE_JAY_WAY = self.new("Blue Jay Way", Beatle::GEORGE)
132
+ end
133
+
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format specdoc
3
+ --loadby mtime
4
+ --reverse
5
+ --backtrace
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'pp'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'walruz'
8
+ require File.dirname(__FILE__) + '/scenario'
9
+
10
+ Spec::Runner.configure do |config|
11
+ end
@@ -0,0 +1,123 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe 'Walruz::Actor' do
4
+
5
+ it "should add an instance method `can!` to included classes" do
6
+ Beatle::JOHN.should respond_to(:can!)
7
+ end
8
+
9
+ it "should add an instance method `can?` to included classes" do
10
+ Beatle::JOHN.should respond_to(:can?)
11
+ end
12
+
13
+ it "should add an instance method `satisfies?` to included classes" do
14
+ Beatle::JOHN.should respond_to(:satisfies?)
15
+ end
16
+
17
+
18
+ describe "can!" do
19
+
20
+ it "should raise a Walruz::NotAuthorized error when the actor is not authorized" do
21
+ lambda do
22
+ Beatle::RINGO.sing_the_song(Song::ALL_YOU_NEED_IS_LOVE)
23
+ end.should raise_error(Walruz::NotAuthorized)
24
+ end
25
+
26
+ it "should not raise a Walruz::NotAuthorized error when the actor is authorized" do
27
+ lambda do
28
+ Beatle::JOHN.sing_the_song(Song::ALL_YOU_NEED_IS_LOVE)
29
+ end.should_not raise_error(Walruz::NotAuthorized)
30
+ end
31
+
32
+ it "should provide parameteres for the invokator correctly" do
33
+ Beatle::JOHN.sing_the_song(Song::ALL_YOU_NEED_IS_LOVE).should == "I just need myself, Let's Rock! \\m/"
34
+ Beatle::JOHN.sing_the_song(Song::YELLOW_SUBMARINE).should == "I need Paul to play this song properly"
35
+ end
36
+
37
+ end
38
+
39
+ describe '#can?' do
40
+
41
+ it "should be invoked only the first time and then return a cached solution" do
42
+ Song::ALL_YOU_NEED_IS_LOVE.should_receive(:can_be?).once.and_return([true, {}])
43
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE)
44
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE)
45
+ end
46
+
47
+ # @deprecated functionality
48
+ # WHY: When you execute `can?` you should probably have already executed `can!`
49
+ # it "should execute a given block if the condition is true" do
50
+ # proc_called = lambda { raise "Is being called" }
51
+ # lambda do
52
+ # Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE, &proc_called)
53
+ # end.should raise_error
54
+ # end
55
+
56
+ it "if a boolean third parameter is received it should not use the cached result" do
57
+ Beatle::JOHN.stub!(:can_without_caching?).and_return(true)
58
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE).should be_true
59
+
60
+ Beatle::JOHN.stub!(:can_without_caching?).and_return(false)
61
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE).should be_true
62
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE, true).should be_false
63
+ end
64
+
65
+ it "should receive at least 2 parameters" do
66
+ lambda do
67
+ Beatle::JOHN.can?(:sing)
68
+ end.should raise_error(ArgumentError)
69
+ end
70
+
71
+ it "should receive at most 3 parameters" do
72
+ lambda do
73
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE, true, false)
74
+ end.should raise_error(ArgumentError)
75
+ end
76
+
77
+
78
+ it "should execute a given block that receives a hash of return parameters of the policy" do
79
+ proc_called = lambda do |params|
80
+ params.should_not be_nil
81
+ params.should be_kind_of(Hash)
82
+ params[:author_policy?].should be_true
83
+ end
84
+ Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE, &proc_called)
85
+ end
86
+
87
+ end
88
+
89
+ describe '#satisfies?' do
90
+
91
+ it "should work with the symbol representation of the policy" do
92
+ Beatle::PAUL.satisfies?(:colaborating_with_john_policy, Song::TAXMAN).should be_false
93
+ end
94
+
95
+ it "should check only the specified policy" do
96
+ Beatle::PAUL.satisfies?(:colaborating_with_john_policy, Song::TAXMAN).should be_false
97
+ end
98
+
99
+ it "should raise a Walruz::ActionNotFound error if the policy is not found" do
100
+ lambda do
101
+ Beatle::GEORGE.satisfies?(:unknown_policy, Song::TAXMAN)
102
+ end.should raise_error(Walruz::ActionNotFound)
103
+ end
104
+
105
+ it "should execute the block if the condition is true" do
106
+ proc_called = Proc.new { raise "Is being called" }
107
+ lambda do
108
+ Beatle::GEORGE.satisfies?(:colaborating_with_john_policy, Song::TAXMAN, &proc_called)
109
+ end.should raise_error
110
+ end
111
+
112
+ it "should execute the block that receives a hash of return parameters of the policy" do
113
+ proc_called = lambda do |params|
114
+ params.should_not be_nil
115
+ params.should be_kind_of(Hash)
116
+ params[:author_in_colaboration_policy?].should be_true
117
+ end
118
+ Beatle::GEORGE.satisfies?(:colaborating_with_john_policy, Song::TAXMAN, &proc_called)
119
+ end
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Walruz::Policy do
4
+
5
+ it "should provide the with_actor utility" do
6
+ AuthorPolicy.should respond_to(:with_actor)
7
+ end
8
+
9
+ it "should generate an indicator that the policy was executed after authorization queries" do
10
+ policy = Beatle::PAUL.can!(:sing, Song::YESTERDAY)
11
+ policy[:author_policy?].should be_true
12
+ end
13
+
14
+ it "should have a default label" do
15
+ AuthorPolicy.policy_label.should == :author_policy
16
+ end
17
+
18
+ it "should prioritize a label that is setted over the default one" do
19
+ AuthorPolicy.set_policy_label :is_author
20
+ AuthorPolicy.policy_label.should == :is_author
21
+ AuthorPolicy.set_policy_label(nil)
22
+ end
23
+
24
+ it "should raise an Walruz::ActionNotFound exception when the action is not specified, and there is no default one" do
25
+ lambda do
26
+ Beatle::RINGO.can!(:sing_drunk, Song::TAXMAN)
27
+ end.should raise_error(Walruz::ActionNotFound)
28
+ end
29
+
30
+ describe "when using the #with_actor method" do
31
+
32
+ before(:each) do
33
+ @songs = [Song::A_DAY_IN_LIFE, Song::YELLOW_SUBMARINE, Song::TAXMAN,
34
+ Song::YESTERDAY, Song::ALL_YOU_NEED_IS_LOVE, Song::BLUE_JAY_WAY]
35
+ end
36
+
37
+ it "should work properly" do
38
+ george_authorship_songs = @songs.select(&AuthorPolicy.with_actor(Beatle::GEORGE))
39
+ george_authorship_songs.should have(1).song
40
+ george_authorship_songs.should == [Song::BLUE_JAY_WAY]
41
+
42
+
43
+ john_and_paul_songs = @songs.select(&AuthorInColaborationPolicy.with_actor(Beatle::JOHN))
44
+ john_and_paul_songs.should have(3).songs
45
+ john_and_paul_songs.should == [Song::A_DAY_IN_LIFE, Song::YELLOW_SUBMARINE, Song::TAXMAN]
46
+ end
47
+
48
+ end
49
+
50
+ describe "when using dependence_on macro" do
51
+
52
+ it "should work properly" do
53
+ lambda do
54
+ Beatle::PAUL.sing_with_john(Song::YESTERDAY)
55
+ end.should raise_error(Walruz::NotAuthorized)
56
+
57
+ Beatle::PAUL.sing_with_john(Song::A_DAY_IN_LIFE).should == "Ok John, Let's Play 'A Day In Life'"
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Walruz::Subject do
4
+
5
+ it "should add a can_be? method" do
6
+ Song::A_DAY_IN_LIFE.should respond_to(:can_be?)
7
+ end
8
+
9
+ it "should add a class method called check_authorizations" do
10
+ Song.should respond_to(:check_authorizations)
11
+ end
12
+
13
+
14
+ describe "when executing validations on an invalid subject" do
15
+
16
+ it "should raise an Walruz::AuthorizationActionsNotDefined error" do
17
+ lambda do
18
+ Beatle::JOHN.can_be?(:talk_with, Beatle::PAUL)
19
+ end.should raise_error(Walruz::AuthorizationActionsNotDefined)
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Walruz::Utils do
4
+
5
+ def check_actor_can_on_subject(label, actor, subject)
6
+ lambda do
7
+ actor.can!(label, subject)
8
+ end.should_not raise_error(Walruz::NotAuthorized)
9
+ end
10
+
11
+ def check_actor_can_not_on_subject(label, actor, subject)
12
+ lambda do
13
+ actor.can!(label, subject)
14
+ end.should raise_error(Walruz::NotAuthorized)
15
+ end
16
+
17
+ describe "when using combinators `orP`, `andP` or `notP`" do
18
+
19
+ it "should work properly" do
20
+ check_actor_can_not_on_subject(:sell, Beatle::JOHN, Song::A_DAY_IN_LIFE)
21
+ check_actor_can_on_subject(:sell, Beatle::JOHN, Song::ALL_YOU_NEED_IS_LOVE)
22
+ end
23
+
24
+ end
25
+
26
+ describe "when using andP" do
27
+
28
+ it "should return as policy keyword, the name of the original policies keywords concatenated with `_and_`" do
29
+ Beatle::JOHN.can?(:sell, Song::ALL_YOU_NEED_IS_LOVE) do |policy_params|
30
+ policy_params[:"author_policy_and_not(author_in_colaboration_policy)?"].should be_true
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ describe "when using notP" do
37
+
38
+ it "should return as policy keyword, the name of the original policy keyword with a `not()` around" do
39
+ Beatle::JOHN.can?(:sell, Song::ALL_YOU_NEED_IS_LOVE) do |policy_params|
40
+ policy_params[:"not(author_in_colaboration_policy)?"].should be_true
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Walruz do
4
+
5
+ it "should have a policies method" do
6
+ Walruz.should respond_to(:policies)
7
+ end
8
+
9
+ describe '#policies' do
10
+
11
+ it "should return all the policies created that have a label" do
12
+ Walruz.policies.should_not be_nil
13
+ Walruz.policies[:author_policy].should be_nil
14
+ Walruz.policies[:author_in_colaboration_policy].should == AuthorInColaborationPolicy
15
+ Walruz.policies[:colaborating_with_john_policy].should == ColaboratingWithJohnPolicy
16
+ end
17
+
18
+ end
19
+
20
+ end