walruz 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/lib/walruz/policy.rb CHANGED
@@ -1,42 +1,42 @@
1
1
  module Walruz
2
2
 
3
3
  #
4
- # One of the cores of the framework, it's purpuse is to encapsulate
5
- # some authorization logic with a given actor and subject.
6
- # It's main method `authorized?(actor, subject)` verifies that
7
- # an actor is actually authorized to manage the subject.
4
+ # One of the cores of the framework, its purpose is to encapsulate an authorization logic
5
+ # with a given actor and subject. It's main method <tt>authorized?(actor, subject)</tt>
6
+ # verifies that an actor is authorized to manage the subject.
8
7
  #
9
8
  class Policy
10
9
  extend Walruz::Utils
11
10
 
12
- # @private
13
- # :nodoc:
14
- def self.inherited(child)
11
+
12
+ def self.inherited(child) # :nodoc:
15
13
  @policies ||= {}
16
14
  unless child.policy_label.nil?
17
15
  @policies[child.policy_label] = child
18
16
  end
19
17
  end
20
18
 
21
- #
22
- # See +Walruz.policies+.
23
- #
19
+
20
+ # @see Walruz.policies
24
21
  def self.policies
25
22
  @policies || {}
26
23
  end
27
24
 
28
- # Creates a new policy class based on an existing one, this method is used
29
- # when you want to reuse a Policy class for a subject association
25
+ #
26
+ # Creates a new policy class based on an existing one, you may use this method
27
+ # when you want to reuse a Policy class for a subject's association.
28
+ #
29
+ # @param [Symbol] Name of the association that will be the subject of the policy.
30
+ # @return [Walruz::Policy] New generated policy that will pass the association as the subject of the original <em>policy</em>.
30
31
  #
31
- # See the "Policy Combinators" section on the README for more info
32
+ # @see http://github.com/noomii/walruz See the "Policy Combinators" section on the README for more info and examples.
32
33
  #
33
34
  def self.for_subject(key, &block)
34
- # :nodoc:
35
- clazz = Class.new(Walruz::Policy) do
35
+
36
+ clazz = Class.new(Walruz::Policy) do # :nodoc:
36
37
  extend Walruz::Utils::PolicyCompositionHelper
37
38
 
38
- # :nodoc:
39
- def authorized?(actor, subject)
39
+ def authorized?(actor, subject) # :nodoc:
40
40
  params = self.class.params
41
41
  new_subject = subject.send(params[:key])
42
42
  result = self.class.policy.new.safe_authorized?(actor, new_subject)
@@ -51,16 +51,17 @@ module Walruz
51
51
  end
52
52
 
53
53
  #
54
- # Returns a Proc with a curried actor, making it easier
55
- # to perform validations of a policy in an Array of subjects
56
- # Params:
57
- # - actor: The actor who checks if it is authorized
58
- #
59
- # Returns: (subject -> [Bool, Hash])
54
+ # Returns a Proc with a curried actor, making it easier to perform validations of a policy
55
+ # in an Array of subjects.
60
56
  #
61
- # Example:
62
- # subjects.filter(&PolicyXYZ.with_actor(some_user))
57
+ # @param [Walruz::Actor] The actor who checks if he is authorized.
58
+ # @return [Proc] A proc that receives as a parameter subject and returns what the <tt>authorized?</tt>
59
+ # method returns.
60
+ #
61
+ # @example
62
+ # subjects.select(&PolicyXYZ.with_actor(some_user))
63
63
  #
64
+ # @see Walruz::CoreExt::Array#only_authorized_for
64
65
  def self.with_actor(actor)
65
66
  policy_instance = self.new
66
67
  lambda do |subject|
@@ -71,13 +72,18 @@ module Walruz
71
72
  #
72
73
  # Stablish other Policy dependencies, so that they are executed
73
74
  # before the current one, giving chances to receive the previous
74
- # policies return parameters
75
+ # policies return parameters.
76
+ #
77
+ # @param [Array<Walruz::Policies>] Policies in wich this policy depends on.
78
+ # @return self
75
79
  #
76
- # Example:
80
+ # @example
77
81
  # class FriendEditProfilePolicy
78
82
  # depends_on FriendPolicy
79
83
  #
80
84
  # def authorized?(actor, subject)
85
+ # # The FriendPolicy returns a hash with a key of :friend_relationship
86
+ # # this will be available via the params method.
81
87
  # params[:friend_relationship].can_edit? # for friend metadata
82
88
  # end
83
89
  #
@@ -88,23 +94,17 @@ module Walruz
88
94
  end
89
95
 
90
96
  # Utility for depends_on macro
91
- # @private
92
- # :nodoc:
93
- def self.policy_dependencies=(dependencies)
97
+ def self.policy_dependencies=(dependencies) # :nodoc:
94
98
  @_policy_dependencies = dependencies
95
99
  end
96
100
 
97
101
  # Utility for depends_on macro
98
- # @private
99
- # :nodoc:
100
- def self.policy_dependencies
102
+ def self.policy_dependencies # :nodoc:
101
103
  @_policy_dependencies
102
104
  end
103
105
 
104
106
  # Utility for depends_on macro
105
- # @private
106
- # :nodoc:
107
- def self.return_policy
107
+ def self.return_policy # :nodoc:
108
108
  if policy_dependencies.nil?
109
109
  self
110
110
  else
@@ -112,10 +112,8 @@ module Walruz
112
112
  end
113
113
  end
114
114
 
115
- # Utility method (copied from ActiveSupport)
116
- # @private
117
- # :nodoc:
118
- def self.underscore(camel_cased_word)
115
+ # Utility method (from ActiveSupport)
116
+ def self.underscore(camel_cased_word) # :nodoc:
119
117
  if camel_cased_word.empty?
120
118
  camel_cased_word
121
119
  else
@@ -130,11 +128,12 @@ module Walruz
130
128
 
131
129
  #
132
130
  # Verifies if the actor is authorized to interact with the subject
133
- # Params:
134
- # - actor: The object who checks if it is authorized
135
- # - subject: The object that is going to be accesed
131
+ # @param [Walruz::Actor] The object who checks if it is authorized
132
+ # @param [Walruz::Subject] The object that is going to be accesed
133
+ # @return It may return a Boolean, or an Array with the first position being a boolean and the second
134
+ # being a Hash of parameters returned from the policy.
135
+ #
136
136
  #
137
- # Returns: [Bool, Hash]
138
137
  #
139
138
  def authorized?(actor, subject)
140
139
  raise NotImplementedError.new("You need to implement policy")
@@ -144,9 +143,8 @@ module Walruz
144
143
  # Returns the identifier of the Policy that will be setted on the
145
144
  # policy params hash once the authorization is executed.
146
145
  #
147
- # Returns:
148
- # By default it will return a symbol with the name of the Policy class in underscore (unless the policy label
149
- # was setted, in that case the policy label will be used) with an '?' appended
146
+ # @return [Symbol] By default it will return a symbol with the name of the Policy class in underscore (unless the policy label
147
+ # was setted, in that case the policy label will be used) with an '?' appended.
150
148
  #
151
149
  def self.policy_keyword
152
150
  if self.policy_label.nil?
@@ -171,21 +169,18 @@ module Walruz
171
169
  # - label: Symbol that represents the policy
172
170
  #
173
171
  def self.set_policy_label(label)
172
+ Walruz.policies[label] = Walruz.policies.delete(self.policy_label)
174
173
  @policy_label = label
175
174
  end
176
175
 
177
- # @private
178
- # :nodoc:
179
- def safe_authorized?(actor, subject)
176
+ def safe_authorized?(actor, subject) # :nodoc:
180
177
  result = Array(authorized?(actor, subject))
181
178
  result[1] ||= {}
182
179
  result[1][self.class.policy_keyword] = result[0] unless self.class.policy_keyword.nil?
183
180
  result
184
181
  end
185
182
 
186
- # @private
187
- # :nodoc:
188
- def set_params(params)
183
+ def set_params(params) # :nodoc:
189
184
  @params = params
190
185
  self
191
186
  end
@@ -1,7 +1,30 @@
1
1
  module Walruz
2
+
3
+ #
4
+ # This module provides the methods that enable a <em>subject</em> to register
5
+ # the diferent actions that can be performed to it, and associates the policies
6
+ # that apply to each of these actions.
7
+ #
8
+ # == Associating policies with actions on the <em>subject</em>.
9
+ #
10
+ # To associate policies and actions related to a <em>subject</em>, we use the <tt>check_authorizations</tt>
11
+ # method, this will receive a Hash, where the keys are the name of the actions, and the values are the policies
12
+ # associated to this actions.
13
+ #
14
+ # === Example:
15
+ # class Profile < ActiveRecord::Base
16
+ # include Walruz::Subject
17
+ # belongs_to :user
18
+ # check_authorizations :read => ProfileReadPolicy,
19
+ # :update => ProfileUpdatePolicy
20
+ # end
21
+ #
22
+ # Once the actions are registered on the <em>subject</em>, you can check if an <em>actor</em> can perform
23
+ # an action on it, using the <tt>Walruz::Actor</tt> methods
24
+ #
2
25
  module Subject
3
26
 
4
- def self.included(base)
27
+ def self.included(base) # :nodoc:
5
28
  base.class_eval do
6
29
 
7
30
  def self._walruz_policies=(policies)
@@ -16,9 +39,7 @@ module Walruz
16
39
  end
17
40
  end
18
41
 
19
- # @private
20
- # :nodoc:
21
- def can_be?(action, actor)
42
+ def can_be?(action, actor) # :nodoc:
22
43
  check_authorization_actions_are_setted(action)
23
44
  action = if self.class._walruz_policies.key?(:default)
24
45
  self.class._walruz_policies.key?(action) ? action : :default
@@ -39,9 +60,7 @@ module Walruz
39
60
  result
40
61
  end
41
62
 
42
- # @private
43
- # :nodoc:
44
- def check_authorization_actions_are_setted(action)
63
+ def check_authorization_actions_are_setted(action) # :nodoc:
45
64
  if self.class._walruz_policies.nil?
46
65
  message =<<BEGIN
47
66
  You need to invoke `check_authorizations :#{action} => Policies::SomePolicy` on the #{self.class.name} class
@@ -55,10 +74,16 @@ BEGIN
55
74
  #
56
75
  # Stablishes the actions that can be made with a subject. You may
57
76
  # specify as many actions as you like, and also you may have a default
58
- # policy, that will get execute if a specified flag doesn't exist.
59
- # You just have to pass the action :default, or just the policy class.
77
+ # policy, that will get executed if a specified flag doesn't exist.
78
+ # You just have to pass the action :default, or the policy class only.
60
79
  #
61
- # Example:
80
+ # Once you stablish the authorizations policies on a subject, you can
81
+ # check if an actor is able to interact with it via the Walruz::Actor methods
82
+ #
83
+ # @param [Hash] Set of actions with associated policies
84
+ # @return self
85
+ #
86
+ # @example
62
87
  # # Without :default key
63
88
  # class UserProfile
64
89
  # check_authorizations :read => Policies::FriendPolicy,
@@ -78,13 +103,8 @@ BEGIN
78
103
  # check_authorizations Policies::OwnerPolicy
79
104
  # end
80
105
  #
81
- # Once you stablish the authorizations policies on a subject, you can
82
- # check if an actor is able to interact with it via the Actor#can? method
83
- #
84
- # Example: current_user.can?(:read, profile)
85
- #
86
- # It's recommended (but not mandatory) that a policy specified to the action
87
- # is inherting from Walruz::Policy
106
+ # @example Invoking the actions from the actor
107
+ # current_user.can?(:read, profile)
88
108
  #
89
109
  def check_authorizations(policy_map)
90
110
  case policy_map
data/lib/walruz/utils.rb CHANGED
@@ -1,9 +1,45 @@
1
1
  module Walruz
2
+ #
3
+ # This module provides pretty handy methods to do compositions of basic policies to create
4
+ # more complex ones.
5
+ #
6
+ # === Using a policies file to manage complex policies
7
+ #
8
+ # It's always a good idea to keep the policy composition in one place, you may place a file in your
9
+ # project where you manage all the authorization policies, and then you use them on your models.
10
+ #
11
+ # Say for example you have a <tt>lib/policies.rb</tt> in your project where you manage the composition of policies,
12
+ # and a <tt>lib/policies</tt> folder where you create your custom policies.
13
+ #
14
+ # The <tt>lib/policies.rb</tt> file could be something like this:
15
+ #
16
+ # module Policies
17
+ # include Walruz::Utils
18
+ #
19
+ # # Requiring basic Walruz::Policy classes
20
+ # BASE = File.join(File.dirname(__FILE__), "policies") unless defined?(BASE)
21
+ # require File.join(BASE, "actor_is_admin")
22
+ # require File.join(BASE, "user_is_owner")
23
+ # require File.join(BASE, "user_is_friend")
24
+ #
25
+ # #####
26
+ # # User Policies
27
+ # #
28
+ # UserCreatePolicy = ActorIsAdmin
29
+ # UserReadPolicy = any(UserIsOwner, UserIsFriend, ActorIsAdmin)
30
+ # UserUpdatePolicy = any(UserIsOwner, ActorIsAdmin)
31
+ # UserDestroyPolicy = ActorIsAdmin
32
+ #
33
+ # end
34
+ #
35
+ # Using a policies file on your project, keeps all your authorization logic just in one place
36
+ # that way, when you change the authorizations you just have to go to one place only.
37
+ #
2
38
  module Utils
3
39
 
4
- module PolicyCompositionHelper
40
+ module PolicyCompositionHelper # :nodoc: all
5
41
 
6
- # NOTE: Not using cattr_accessor to avoid dependencies with ActiveSupport
42
+ #-- NOTE: Not using cattr_accessor to avoid dependencies with ActiveSupport
7
43
 
8
44
  def policies=(policies)
9
45
  @policies = policies
@@ -32,13 +68,21 @@ module Walruz
32
68
 
33
69
  end
34
70
 
71
+ #
72
+ # Generates a new policy that merges together different policies by an <em>OR</em> association.
73
+ # As soon as one of the policies succeed, the parameters of that policy will be returned.
74
+ #
75
+ # @param [Array<Walruz::Policy>] A set of policies that will be merged by an <em>OR</em> association.
76
+ # @return [Walruz::Policy] A new policy class that will execute each policy until one of them succeeds.
77
+ #
78
+ # @example
79
+ # UserReadPolicy = any(UserIsOwner, UserIsAdmin)
80
+ #
35
81
  def any(*policies)
36
- # :nodoc:
37
- clazz = Class.new(Walruz::Policy) do
82
+ clazz = Class.new(Walruz::Policy) do # :nodoc:
38
83
  extend PolicyCompositionHelper
39
84
 
40
- # :nodoc:
41
- def authorized?(actor, subject)
85
+ def authorized?(actor, subject) # :nodoc:
42
86
  result = nil
43
87
  self.class.policies.detect do |policy|
44
88
  result = policy.new.set_params(params).safe_authorized?(actor, subject)
@@ -52,13 +96,20 @@ module Walruz
52
96
  clazz
53
97
  end
54
98
 
99
+ #
100
+ # Generates a new policy that merges together different policies by an <em>AND</em> association.
101
+ # This will execute every <em>policy</em> on the list, if all of them return true then the policy will
102
+ # succeed. This process will merge the parameters of each policy, so you may be able to use the parameters
103
+ # of previous policies, and at the end it will return all the parameters from every policy.
104
+ #
105
+ # @param [Array<Walruz::Policy>] A set of policies that will be merged by an <em>AND</em> association.
106
+ # @return [Walruz::Policy] A new policy class that will check true for each policy.
107
+ #
55
108
  def all(*policies)
56
- # :nodoc:
57
- clazz = Class.new(Walruz::Policy) do
109
+ clazz = Class.new(Walruz::Policy) do # :nodoc:
58
110
  extend PolicyCompositionHelper
59
111
 
60
- # :nodoc:
61
- def authorized?(actor, subject)
112
+ def authorized?(actor, subject) # :nodoc:
62
113
  acum = [true, self.params || {}]
63
114
  self.class.policies.each do |policy|
64
115
  break unless acum[0]
@@ -69,8 +120,7 @@ module Walruz
69
120
  acum[0] ? acum : acum[0]
70
121
  end
71
122
 
72
- # :nodoc:
73
- def self.policy_keyword
123
+ def self.policy_keyword # :nodoc:
74
124
  (self.policies.map { |p| p.policy_keyword.to_s[0..-2] }.join('_and_') + "?").to_sym
75
125
  end
76
126
 
@@ -79,20 +129,24 @@ module Walruz
79
129
  clazz
80
130
  end
81
131
 
132
+ #
133
+ # Generates a new policy that negates the result of the given policy.
134
+ # @param [Walruz::Policy] The policy which result is going to be negated.
135
+ # @param [Walruz::Policy] A new policy that will negate the result of the given policy.
136
+ #
82
137
  def negate(policy)
83
- # :nodoc:
84
- clazz = Class.new(Walruz::Policy) do
138
+ clazz = Class.new(Walruz::Policy) do # :nodoc:
85
139
  extend PolicyCompositionHelper
86
140
 
87
141
  # :nodoc:
88
142
  def authorized?(actor, subject)
89
- self.class.policy.set_params(params)
90
- result = self.class.policy.new.safe_authorized?(actor, subject)
91
- !result[0]
143
+ result = self.class.policy.new.set_params(params).safe_authorized?(actor, subject)
144
+ result[0] = !result[0]
145
+ result
92
146
  end
93
147
 
94
- # :nodoc:
95
- def self.policy_keyword
148
+
149
+ def self.policy_keyword # :nodoc:
96
150
  keyword = self.policy.policy_keyword.to_s[0..-2]
97
151
  :"not(#{keyword})?"
98
152
  end
data/lib/walruz.rb CHANGED
@@ -42,15 +42,33 @@ module Walruz
42
42
  autoload :Policy, base_path + '/walruz/policy'
43
43
  autoload :Utils, base_path + '/walruz/utils'
44
44
 
45
+
45
46
  def self.setup
46
47
  config = Config.new
47
48
  yield config
48
49
  end
49
50
 
51
+ # Holds all the policies declared on the system
52
+ # @return [Hash<Symbol, Walruz::Policy>] A hash of policies, each identified by it's policy label
53
+ # @todo Make this thread-safe
50
54
  def self.policies
51
55
  Walruz::Policy.policies
52
56
  end
53
57
 
58
+ # Returns a Walruz::Policy Class represented by the specified label
59
+ #
60
+ # @param [Symbol] policy_label The label that identifies a policy
61
+ # @return [Walruz::Policy] A Policy class.
62
+ # @raise [Walruz::ActionNotFound] if the policy label is not recognized.
63
+ # @example Fetching a policy with label :actor_is_admin
64
+ # Walruz.fetch_policy(:actor_is_admin) # => ActorIsAdmin
65
+ #
66
+ def self.fetch_policy(policy_label)
67
+ policy_clz = Walruz.policies[policy_label]
68
+ raise ActionNotFound.new(:policy_label, :label => policy_label) if policy_clz.nil?
69
+ policy_clz
70
+ end
71
+
54
72
  class Config
55
73
 
56
74
  def actors=(actors)
@@ -67,5 +85,7 @@ module Walruz
67
85
 
68
86
  end
69
87
 
88
+ end
70
89
 
71
- end
90
+ require File.dirname(__FILE__) + '/walruz/core_ext/array'
91
+ Array.send(:include, Walruz::CoreExt::Array)
data/spec/scenario.rb CHANGED
@@ -30,11 +30,12 @@ class Beatle
30
30
  "Ok John, Let's Play '%s'" % song.name
31
31
  end
32
32
 
33
-
34
- JOHN = self.new("John")
35
- PAUL = self.new("Paul")
36
- RINGO = self.new("Ringo")
37
- GEORGE = self.new("George")
33
+ unless defined?(RINGO)
34
+ JOHN = self.new("John")
35
+ PAUL = self.new("Paul")
36
+ RINGO = self.new("Ringo")
37
+ GEORGE = self.new("George")
38
+ end
38
39
  end
39
40
 
40
41
  class Colaboration
@@ -50,9 +51,12 @@ class Colaboration
50
51
  @songs = []
51
52
  end
52
53
 
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)
54
+ unless defined?(JOHN_PAUL)
55
+ JOHN_PAUL = self.new(Beatle::JOHN, Beatle::PAUL)
56
+ JOHN_PAUL_GEORGE = self.new(Beatle::JOHN, Beatle::PAUL, Beatle::GEORGE)
57
+ JOHN_GEORGE = self.new(Beatle::JOHN, Beatle::GEORGE)
58
+ end
59
+
56
60
  end
57
61
 
58
62
  class SubjectIsActorPolicy < Walruz::Policy
@@ -74,12 +78,14 @@ end
74
78
  # end
75
79
  #
76
80
  # end
77
-
78
- AuthorPolicy = SubjectIsActorPolicy.for_subject(:author) do |authorized, params, actor, subject|
79
- params.merge!(:owner => actor) if authorized
81
+ unless defined?(AuthorPolicy)
82
+ AuthorPolicy = SubjectIsActorPolicy.for_subject(:author) do |authorized, params, actor, subject|
83
+ params.merge!(:owner => actor) if authorized
84
+ end
80
85
  end
81
86
 
82
87
  class AuthorInColaborationPolicy < Walruz::Policy
88
+ set_policy_label :in_colaboration
83
89
 
84
90
  def authorized?(beatle, song)
85
91
  return false unless song.colaboration
@@ -123,11 +129,14 @@ class Song
123
129
  owner.songs << self
124
130
  end
125
131
 
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
+ unless defined?(A_DAY_IN_LIFE)
133
+ A_DAY_IN_LIFE = self.new("A Day In Life", Colaboration::JOHN_PAUL)
134
+ YELLOW_SUBMARINE = self.new("Yellow Submarine", Colaboration::JOHN_PAUL)
135
+ TAXMAN = self.new("Taxman", Colaboration::JOHN_GEORGE)
136
+ YESTERDAY = self.new("Yesterday", Beatle::PAUL)
137
+ ALL_YOU_NEED_IS_LOVE = self.new("All You Need Is Love", Beatle::JOHN)
138
+ BLUE_JAY_WAY = self.new("Blue Jay Way", Beatle::GEORGE)
139
+ end
140
+
132
141
  end
133
142
 
@@ -68,9 +68,9 @@ describe 'Walruz::Actor' do
68
68
  describe '#can?' do
69
69
 
70
70
  it "should be invoked only the first time and then return a cached solution" do
71
- Song::ALL_YOU_NEED_IS_LOVE.should_receive(:can_be?).once.and_return([true, {}])
72
- Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE)
73
- Beatle::JOHN.can?(:sing, Song::ALL_YOU_NEED_IS_LOVE)
71
+ Song::YELLOW_SUBMARINE.should_receive(:can_be?).once.and_return([true, {}])
72
+ Beatle::JOHN.can?(:sing, Song::YELLOW_SUBMARINE, true)
73
+ Beatle::JOHN.can?(:sing, Song::YELLOW_SUBMARINE)
74
74
  end
75
75
 
76
76
  it "if a boolean third parameter is received it should not use the cached result" do
@@ -108,34 +108,38 @@ describe 'Walruz::Actor' do
108
108
 
109
109
  describe '#satisfies?' do
110
110
 
111
- it "should work with the symbol representation of the policy" do
112
- Beatle::PAUL.satisfies?(:colaborating_with_john_policy, Song::TAXMAN).should be_false
111
+ it "should raise a Walruz::ActionNotFound error if the policy is not found" do
112
+ lambda do
113
+ Beatle::GEORGE.satisfies?(:unknown_policy, Song::TAXMAN)
114
+ end.should raise_error(Walruz::ActionNotFound)
113
115
  end
114
116
 
115
- it "should check only the specified policy" do
117
+ it "should return false if the actor and the subject dont satisfy the given policy" do
116
118
  Beatle::PAUL.satisfies?(:colaborating_with_john_policy, Song::TAXMAN).should be_false
117
119
  end
118
120
 
119
- it "should raise a Walruz::ActionNotFound error if the policy is not found" do
120
- lambda do
121
- Beatle::GEORGE.satisfies?(:unknown_policy, Song::TAXMAN)
122
- end.should raise_error(Walruz::ActionNotFound)
121
+ it "should return true if the actor and the subject satisfy the given policy" do
122
+ Beatle::GEORGE.satisfies(:colaborating_with_john_policy, Song::TAXMAN).should be_true
123
123
  end
124
124
 
125
- it "should execute the block if the condition is true" do
126
- proc_called = Proc.new { raise "Is being called" }
127
- lambda do
128
- Beatle::GEORGE.satisfies?(:colaborating_with_john_policy, Song::TAXMAN, &proc_called)
129
- end.should raise_error
125
+ end
126
+
127
+ describe "#satisfies" do
128
+
129
+ it "should return nil if the actor and the subject do not satisfy the given policy" do
130
+ Beatle::PAUL.satisfies(:colaborating_with_john_policy, Song::TAXMAN).should be_nil
130
131
  end
131
132
 
132
- it "should execute the block that receives a hash of return parameters of the policy" do
133
- proc_called = lambda do |params|
134
- params.should_not be_nil
135
- params.should be_kind_of(Hash)
136
- params[:author_in_colaboration_policy?].should be_true
137
- end
138
- Beatle::GEORGE.satisfies?(:colaborating_with_john_policy, Song::TAXMAN, &proc_called)
133
+ it "should return the parameters from the policy if the actor and the subject satisfy the policy" do
134
+ policy_params = Beatle::GEORGE.satisfies(:colaborating_with_john_policy, Song::TAXMAN)
135
+ policy_params.should_not be_nil
136
+ policy_params[:in_colaboration?].should be_true
137
+ end
138
+
139
+ it "should raise a Walruz::ActionNotFound error if the policy is not found" do
140
+ lambda do
141
+ Beatle::GEORGE.satisfies(:unknown_policy, Song::TAXMAN)
142
+ end.should raise_error(Walruz::ActionNotFound)
139
143
  end
140
144
 
141
145
  end