Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixes for mongo_mapper adapter. Add specs

  • Loading branch information...
commit 0a2556bf557334a8b2e002ad573692d47dc9d54a 1 parent ea1b60d
@maxprokopiev authored
View
3  Gemfile
@@ -13,6 +13,9 @@ when "data_mapper"
when "mongoid"
gem "bson_ext", "~> 1.1"
gem "mongoid", "~> 2.0.0.beta.20"
+when "mongo_mapper"
+ gem "bson_ext"
+ gem "mongo_mapper"
else
raise "Unknown model adapter: #{ENV["MODEL_ADAPTER"]}"
end
View
11 lib/cancan/model_adapters/mongo_mapper_adapter.rb
@@ -17,14 +17,12 @@ def self.override_conditions_hash_matching?(subject, conditions)
end
def self.matches_conditions_hash?(subject, conditions)
- # To avoid hitting the db, retrieve the raw Mongo selector from
- # the Mongoid Criteria and use Mongoid::Matchers#matches?
- subject.matches?( subject.class.where(conditions).selector )
+ subject.class.where(conditions).include? subject
end
def database_records
if @rules.size == 0
- []
+ @model_class.where(:_id => {:$exists => false, :$type => 7}) # return no records
elsif @rules.size == 1
@model_class.where(@rules[0].conditions)
else
@@ -34,9 +32,10 @@ def database_records
process_can_rules = @rules.count == rules.count
rules.inject(@model_class.where) do |records, rule|
if process_can_rules && rule.base_behavior
- records.or rule.conditions
+ records.where rule.conditions
elsif !rule.base_behavior
- records.excludes rule.conditions
+ records.remove rule.conditions

***DANGER, huge issue!
Plucky::Query.remove() actually calls collection.remove()
This will remove all the records matching rule.conditions from the database - which is not intended, I guess ... ;)

@maxprokopiev Owner

oops, I'll check this

Me too. Expect a pull request today.
Also thanks for all the specs! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ records
else
records
end
View
108 spec/cancan/model_adapters/mongo_mapper_adapter_spec.rb
@@ -0,0 +1,108 @@
+if ENV["MODEL_ADAPTER"] == "mongo_mapper"
+ require "spec_helper"
+
+ MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
+ MongoMapper.database = "cancan_mongomapper_spec"
+
+ class MongoMapperProject
+ include MongoMapper::Document
+ end
+
+ describe CanCan::ModelAdapters::MongoMapperAdapter, :focus => true do
+ context "MongoMapper defined" do
+ before(:each) do
+ @ability = Object.new
+ @ability.extend(CanCan::Ability)
+ end
+
+ after(:each) do
+ MongoMapperProject.destroy_all
+ end
+
+ it "should be for only MongoMapper classes" do
+ CanCan::ModelAdapters::MongoMapperAdapter.should_not be_for_class(Object)
+ CanCan::ModelAdapters::MongoMapperAdapter.should be_for_class(MongoMapperProject)
+ CanCan::ModelAdapters::AbstractAdapter.adapter_class(MongoMapperProject).should == CanCan::ModelAdapters::MongoMapperAdapter
+ end
+
+ it "should find record" do
+ project = MongoMapperProject.create
+ CanCan::ModelAdapters::MongoMapperAdapter.find(MongoMapperProject, project.id).should == project
+ end
+
+ it "should compare properties on mongomapper documents with the conditions hash" do
+ model = MongoMapperProject.new
+ @ability.can :read, MongoMapperProject, :id => model.id
+ @ability.should be_able_to(:read, model)
+ end
+
+ it "should be able to read hashes when field is array" do
+ one_to_three = MongoMapperProject.create(:numbers => ['one', 'two', 'three'])
+ two_to_five = MongoMapperProject.create(:numbers => ['two', 'three', 'four', 'five'])
+
+ @ability.can :foo, MongoMapperProject, :numbers => 'one'
+ @ability.should be_able_to(:foo, one_to_three)
+ @ability.should_not be_able_to(:foo, two_to_five)
+ end
+
+ it "should return [] when no ability is defined so no records are found" do
+ MongoMapperProject.create
+ MongoMapperProject.create
+ MongoMapperProject.create
+
+ MongoMapperProject.accessible_by(@ability, :read).entries.should == []
+ end
+
+ it "should return the correct records based on the defined ability" do
+ @ability.can :read, MongoMapperProject, :title => "Sir"
+ sir = MongoMapperProject.create(:title => 'Sir')
+ lord = MongoMapperProject.create(:title => 'Lord')
+ dude = MongoMapperProject.create(:title => 'Dude')
+
+ MongoMapperProject.accessible_by(@ability, :read).entries.should == [sir]
+ end
+
+ it "should be able to mix empty conditions and hashes" do
+ @ability.can :read, MongoMapperProject
+ @ability.can :read, MongoMapperProject, :title => 'Sir'
+ sir = MongoMapperProject.create(:title => 'Sir')
+ lord = MongoMapperProject.create(:title => 'Lord')
+
+ MongoMapperProject.accessible_by(@ability, :read).count.should == 2
+ end
+
+ it "should return everything when the defined ability is manage all" do
+ @ability.can :manage, :all
+ sir = MongoMapperProject.create(:title => 'Sir')
+ lord = MongoMapperProject.create(:title => 'Lord')
+ dude = MongoMapperProject.create(:title => 'Dude')
+
+ MongoMapperProject.accessible_by(@ability, :read).entries.should == [sir, lord, dude]
+ end
+
+ it "should call where with matching ability conditions" do
+ obj = MongoMapperProject.create(:foo => {:bar => 1})
+ @ability.can :read, MongoMapperProject, :foo => {:bar => 1}
+ MongoMapperProject.accessible_by(@ability, :read).entries.first.should == obj
+ end
+
+ it "should exclude from the result if set to cannot" do
+ obj = MongoMapperProject.create(:bar => 1)
+ obj2 = MongoMapperProject.create(:bar => 2)
+ @ability.can :read, MongoMapperProject
+ @ability.cannot :read, MongoMapperProject, :bar => 2
+ MongoMapperProject.accessible_by(@ability, :read).entries.should == [obj]
+ end
+
+ it "should combine the rules" do
+ obj = MongoMapperProject.create(:bar => 1)
+ obj2 = MongoMapperProject.create(:bar => 2)
+ obj3 = MongoMapperProject.create(:bar => 3)
+ @ability.can :read, MongoMapperProject, :bar => 1
+ @ability.can :read, MongoMapperProject, :bar => 2
+ MongoMapperProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2]
+ end
+
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.