add tests for merging conditions and joins

This commit is contained in:
Yura Sokolov 2010-05-25 14:02:26 +04:00
parent 9c0346b90b
commit ac19422a90
2 changed files with 37 additions and 2 deletions

View File

@ -2,7 +2,7 @@ require "spec_helper"
describe CanCan::ActiveRecordAdditions do describe CanCan::ActiveRecordAdditions do
before(:each) do before(:each) do
@model_class = Class.new @model_class = Class.new(SqlSanitizer)
stub(@model_class).scoped { :scoped_stub } stub(@model_class).scoped { :scoped_stub }
@model_class.send(:include, CanCan::ActiveRecordAdditions) @model_class.send(:include, CanCan::ActiveRecordAdditions)
@ability = Object.new @ability = Object.new
@ -25,4 +25,27 @@ describe CanCan::ActiveRecordAdditions do
stub(@model_class).scoped(:conditions => {:foos => {:bar => 1}}, :joins => [:foo]) { :found_records } stub(@model_class).scoped(:conditions => {:foos => {:bar => 1}}, :joins => [:foo]) { :found_records }
@model_class.accessible_by(@ability).should == :found_records @model_class.accessible_by(@ability).should == :found_records
end end
it "should merge association joins and sanitize conditions" do
@ability.can :read, @model_class, :foo => {:bar => 1}
@ability.can :read, @model_class, :too => {:car => 1, :far => {:bar => 1}}
condition_variants = [
'(toos.far.bar=1 AND toos.car=1) OR (foos.bar=1)', # faked sql sanitizer is stupid ;-)
'(toos.car=1 AND toos.far.bar=1) OR (foos.bar=1)'
]
joins_variants = [
[:foo, {:too => [:far]}],
[{:too => [:far]}, :foo]
]
condition_variants.each do |condition|
joins_variants.each do |joins|
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]
@model_class.accessible_by(@ability).should == :found_records
end
end end

View File

@ -25,10 +25,22 @@ end
class SqlSanitizer class SqlSanitizer
def self.sanitize_sql(hash_cond) def self.sanitize_sql(hash_cond)
case hash_cond case hash_cond
when Hash then hash_cond.map{|name, value| "#{name}=#{value}"}.join(' AND ') when Hash
sanitize_hash(hash_cond).join(' AND ')
when Array when Array
hash_cond.shift.gsub('?'){"#{hash_cond.shift.inspect}"} hash_cond.shift.gsub('?'){"#{hash_cond.shift.inspect}"}
when String then hash_cond when String then hash_cond
end end
end end
private
def self.sanitize_hash(hash)
hash.map do |name, value|
if Hash === value
sanitize_hash(value).map{|cond| "#{name}.#{cond}"}
else
"#{name}=#{value}"
end
end.flatten
end
end end