consider specificity when finding relevant rules so generic rules will not override specific ones - closes #321

This commit is contained in:
Ryan Bates
2011-09-28 15:34:08 -07:00
parent 1fb2c0160c
commit 6de9e4675a
5 changed files with 37 additions and 10 deletions
+7
View File
@@ -138,6 +138,13 @@ describe CanCan::Ability do
@ability.can?(:read, 4..6).should be_false
end
it "takes presedence over rule defined without a condition" do
@ability.can :read, :ranges
@ability.can :read, :ranges, :begin => 1
@ability.can?(:read, 1..5).should be_true
@ability.can?(:read, 4..6).should be_false
end
# Block Conditions
@@ -176,7 +176,7 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
it "should return true condition for single `can` definition in front of default `can` condition" do
@ability.can :read, :articles
@ability.can :read, :articles, :published => false, :secret => true
@ability.model_adapter(Article, :read).conditions.should == "'t'='t'"
@ability.model_adapter(Article, :read).conditions.should eq(:secret => true, :published => false)
end
it "should return `false condition` for single `cannot` definition in front of default `cannot` condition" do
@@ -198,7 +198,7 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
@ability.cannot :update, :articles, :secret => true
@ability.model_adapter(Article, :update).conditions.should == %Q[not ("#{@article_table}"."secret" = 't') AND (("#{@article_table}"."published" = 't') OR ("#{@article_table}"."id" = 1))]
@ability.model_adapter(Article, :access).conditions.should == {:id => 1}
@ability.model_adapter(Article, :read).conditions.should == "'t'='t'"
@ability.model_adapter(Article, :read).conditions.should == {:id => 1} # used to be "t=t" but changed with new specificity rule (issue #321)
end
it "should not forget conditions when calling with SQL string" do
+9
View File
@@ -36,4 +36,13 @@ describe CanCan::Rule do
rule = CanCan::Rule.new(true, :read, :integers)
rule.associations_hash.should == {}
end
it "should have higher specificity for attributes/conditions" do
CanCan::Rule.new(true, :read, :integers).specificity.should eq(1)
CanCan::Rule.new(true, :read, :integers, :foo => :bar).specificity.should eq(2)
CanCan::Rule.new(true, :read, :integers, :foo).specificity.should eq(2)
CanCan::Rule.new(false, :read, :integers).specificity.should eq(3)
CanCan::Rule.new(false, :read, :integers, :foo => :bar).specificity.should eq(4)
CanCan::Rule.new(false, :read, :integers, :foo).specificity.should eq(4)
end
end