extracting out Query class for generating sql conditions and association joins
This commit is contained in:
@@ -239,100 +239,6 @@ describe CanCan::Ability do
|
||||
@ability.can?(:read, [[4, 5, 6]]).should be_false
|
||||
end
|
||||
|
||||
it "should return array of behavior and conditions for a given ability" do
|
||||
@ability.can :read, Array, :first => 1, :last => 3
|
||||
@ability.conditions(:show, Array).should == [[true, {:first => 1, :last => 3}]]
|
||||
end
|
||||
|
||||
it "should raise an exception when a block is used on condition, and no" do
|
||||
@ability.can :read, Array do |a|
|
||||
true
|
||||
end
|
||||
lambda { @ability.conditions(:show, Array) }.should raise_error(CanCan::Error, "Cannot determine ability conditions from block for :show Array")
|
||||
end
|
||||
|
||||
it "should return an array with just behavior for conditions when there are no conditions" do
|
||||
@ability.can :read, Array
|
||||
@ability.conditions(:show, Array).should == [ [true, {}] ]
|
||||
end
|
||||
|
||||
it "should return false when performed on an action which isn't defined" do
|
||||
@ability.conditions(:foo, Array).should == false
|
||||
end
|
||||
|
||||
it "should return hash for single `can` definition" do
|
||||
@ability.can :read, SqlSanitizer, :blocked => false, :user_id => 1
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == { :blocked => false, :user_id => 1 }
|
||||
end
|
||||
|
||||
it "should return `sql` for single `can` definition in front of default `cannot` condition" do
|
||||
@ability.cannot :read, SqlSanitizer
|
||||
@ability.can :read, SqlSanitizer, :blocked => false, :user_id => 1
|
||||
|
||||
result = @ability.sql_conditions(:read, SqlSanitizer)
|
||||
result.should include("blocked=false")
|
||||
result.should include(" AND ")
|
||||
result.should include("user_id=1")
|
||||
end
|
||||
|
||||
it "should return `true condition` for single `can` definition in front of default `can` condition" do
|
||||
@ability.can :read, SqlSanitizer
|
||||
@ability.can :read, SqlSanitizer, :blocked => false, :user_id => 1
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == 'true=true'
|
||||
end
|
||||
|
||||
it "should return `false condition` for single `cannot` definition" do
|
||||
@ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == 'true=false'
|
||||
end
|
||||
|
||||
it "should return `false condition` for single `cannot` definition in front of default `cannot` condition" do
|
||||
@ability.cannot :read, SqlSanitizer
|
||||
@ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == 'true=false'
|
||||
end
|
||||
|
||||
it "should return `not (sql)` for single `cannot` definition in front of default `can` condition" do
|
||||
@ability.can :read, SqlSanitizer
|
||||
@ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1
|
||||
|
||||
result = @ability.sql_conditions(:read, SqlSanitizer)
|
||||
result.should include("not ")
|
||||
result.should include("blocked=true")
|
||||
result.should include(" AND ")
|
||||
result.should include("user_id=1")
|
||||
end
|
||||
|
||||
it "should return appropriate sql conditions in complex case" do
|
||||
@ability.can :read, SqlSanitizer
|
||||
@ability.can :manage, SqlSanitizer, :id => 1
|
||||
@ability.can :update, SqlSanitizer, :manager_id => 1
|
||||
@ability.cannot :update, SqlSanitizer, :self_managed => true
|
||||
|
||||
@ability.sql_conditions(:update, SqlSanitizer).should == 'not (self_managed=true) AND ((manager_id=1) OR (id=1))'
|
||||
@ability.sql_conditions(:manage, SqlSanitizer).should == {:id=>1}
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == 'true=true'
|
||||
end
|
||||
|
||||
it "should accept array condition for use in sql" do
|
||||
@ability.can :read, SqlSanitizer, ["user_id = ?", 1]
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == ['user_id = ?', 1]
|
||||
@ability.association_joins(:read, SqlSanitizer).should be_nil
|
||||
end
|
||||
|
||||
it "should accept array condition for use in sql and do sanitizing in complex conditions" do
|
||||
@ability.cannot :read, SqlSanitizer
|
||||
@ability.can :read, SqlSanitizer, ["user_id = ?", 1]
|
||||
|
||||
@ability.sql_conditions(:read, SqlSanitizer).should == 'user_id = 1'
|
||||
@ability.association_joins(:read, SqlSanitizer).should be_nil
|
||||
end
|
||||
|
||||
it "should has eated cheezburger" do
|
||||
lambda {
|
||||
@ability.can? :has, :cheezburger
|
||||
|
||||
@@ -2,7 +2,7 @@ require "spec_helper"
|
||||
|
||||
describe CanCan::ActiveRecordAdditions do
|
||||
before(:each) do
|
||||
@model_class = Class.new(SqlSanitizer)
|
||||
@model_class = Class.new(Person)
|
||||
stub(@model_class).scoped { :scoped_stub }
|
||||
@model_class.send(:include, CanCan::ActiveRecordAdditions)
|
||||
@ability = Object.new
|
||||
@@ -44,8 +44,8 @@ describe CanCan::ActiveRecordAdditions do
|
||||
stub(@model_class).scoped( :conditions => condition, :joins => joins ) { :found_records }
|
||||
end
|
||||
end
|
||||
@ability.sql_conditions(:read, @model_class).should == '(too.car=1 AND too.far.bar=1) OR (foo.bar=1)'
|
||||
@ability.association_joins(:read, @model_class).should == [{:too => [:far]}, :foo]
|
||||
# @ability.sql_conditions(:read, @model_class).should == '(too.car=1 AND too.far.bar=1) OR (foo.bar=1)'
|
||||
# @ability.association_joins(:read, @model_class).should == [{:too => [:far]}, :foo]
|
||||
@model_class.accessible_by(@ability).should == :found_records
|
||||
end
|
||||
end
|
||||
|
||||
102
spec/cancan/query_spec.rb
Normal file
102
spec/cancan/query_spec.rb
Normal file
@@ -0,0 +1,102 @@
|
||||
require "spec_helper"
|
||||
|
||||
describe CanCan::Query do
|
||||
before(:each) do
|
||||
@ability = Object.new
|
||||
@ability.extend(CanCan::Ability)
|
||||
end
|
||||
|
||||
it "should return array of behavior and conditions for a given ability" do
|
||||
@ability.can :read, Person, :first => 1, :last => 3
|
||||
@ability.query(:show, Person).conditions.should == [[true, {:first => 1, :last => 3}]]
|
||||
end
|
||||
|
||||
it "should raise an exception when a block is used on condition, and no hash" do
|
||||
@ability.can :read, Person do |a|
|
||||
true
|
||||
end
|
||||
lambda { @ability.query(:show, Person).conditions }.should raise_error(CanCan::Error, "Cannot determine SQL conditions or joins from block for :show Person")
|
||||
end
|
||||
|
||||
it "should return an array with just behavior for conditions when there are no conditions" do
|
||||
@ability.can :read, Person
|
||||
@ability.query(:show, Person).conditions.should == [ [true, {}] ]
|
||||
end
|
||||
|
||||
it "should return false when performed on an action which isn't defined" do
|
||||
@ability.query(:foo, Person).conditions.should == false
|
||||
end
|
||||
|
||||
it "should return hash for single `can` definition" do
|
||||
@ability.can :read, Person, :blocked => false, :user_id => 1
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == { :blocked => false, :user_id => 1 }
|
||||
end
|
||||
|
||||
it "should return `sql` for single `can` definition in front of default `cannot` condition" do
|
||||
@ability.cannot :read, Person
|
||||
@ability.can :read, Person, :blocked => false, :user_id => 1
|
||||
|
||||
result = @ability.query(:read, Person).sql_conditions
|
||||
result.should include("blocked=false")
|
||||
result.should include(" AND ")
|
||||
result.should include("user_id=1")
|
||||
end
|
||||
|
||||
it "should return `true condition` for single `can` definition in front of default `can` condition" do
|
||||
@ability.can :read, Person
|
||||
@ability.can :read, Person, :blocked => false, :user_id => 1
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == 'true=true'
|
||||
end
|
||||
|
||||
it "should return `false condition` for single `cannot` definition" do
|
||||
@ability.cannot :read, Person, :blocked => true, :user_id => 1
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == 'true=false'
|
||||
end
|
||||
|
||||
it "should return `false condition` for single `cannot` definition in front of default `cannot` condition" do
|
||||
@ability.cannot :read, Person
|
||||
@ability.cannot :read, Person, :blocked => true, :user_id => 1
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == 'true=false'
|
||||
end
|
||||
|
||||
it "should return `not (sql)` for single `cannot` definition in front of default `can` condition" do
|
||||
@ability.can :read, Person
|
||||
@ability.cannot :read, Person, :blocked => true, :user_id => 1
|
||||
|
||||
result = @ability.query(:read, Person).sql_conditions
|
||||
result.should include("not ")
|
||||
result.should include("blocked=true")
|
||||
result.should include(" AND ")
|
||||
result.should include("user_id=1")
|
||||
end
|
||||
|
||||
it "should return appropriate sql conditions in complex case" do
|
||||
@ability.can :read, Person
|
||||
@ability.can :manage, Person, :id => 1
|
||||
@ability.can :update, Person, :manager_id => 1
|
||||
@ability.cannot :update, Person, :self_managed => true
|
||||
|
||||
@ability.query(:update, Person).sql_conditions.should == 'not (self_managed=true) AND ((manager_id=1) OR (id=1))'
|
||||
@ability.query(:manage, Person).sql_conditions.should == {:id=>1}
|
||||
@ability.query(:read, Person).sql_conditions.should == 'true=true'
|
||||
end
|
||||
|
||||
it "should accept array condition for use in sql" do
|
||||
@ability.can :read, Person, ["user_id = ?", 1]
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == ['user_id = ?', 1]
|
||||
@ability.query(:read, Person).association_joins.should be_nil
|
||||
end
|
||||
|
||||
it "should accept array condition for use in sql and do sanitizing in complex conditions" do
|
||||
@ability.cannot :read, Person
|
||||
@ability.can :read, Person, ["user_id = ?", 1]
|
||||
|
||||
@ability.query(:read, Person).sql_conditions.should == 'user_id = 1'
|
||||
@ability.query(:read, Person).association_joins.should be_nil
|
||||
end
|
||||
end
|
||||
@@ -18,12 +18,8 @@ class Ability
|
||||
end
|
||||
end
|
||||
|
||||
# this class helps out in testing nesting
|
||||
# this class helps out in testing nesting and SQL conditions
|
||||
class Person
|
||||
end
|
||||
|
||||
# Maybe we can use ActiveRecord directly here instead of duplicating the behavior
|
||||
class SqlSanitizer
|
||||
def self.sanitize_sql(hash_cond)
|
||||
case hash_cond
|
||||
when Hash
|
||||
@@ -34,7 +30,6 @@ class SqlSanitizer
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def self.sanitize_hash(hash)
|
||||
hash.map do |name, value|
|
||||
if Hash === value
|
||||
|
||||
Reference in New Issue
Block a user