cancancan 1.7.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -3
- data/Appraisals +50 -4
- data/CHANGELOG.rdoc +12 -1
- data/README.rdoc +12 -2
- data/Rakefile +0 -2
- data/cancancan.gemspec +3 -2
- data/gemfiles/activerecord_3.0.gemfile +18 -0
- data/gemfiles/{rails_3.0.gemfile → activerecord_3.1.gemfile} +2 -4
- data/gemfiles/activerecord_3.2.gemfile +16 -0
- data/gemfiles/{rails_3.0_datamapper.gemfile → datamapper_1.x.gemfile} +2 -1
- data/gemfiles/{rails_3.0_mongoid.gemfile → mongoid_2.x.gemfile} +6 -1
- data/gemfiles/sequel_3.x.gemfile +17 -0
- data/lib/cancan.rb +1 -0
- data/lib/cancan/ability.rb +24 -4
- data/lib/cancan/controller_resource.rb +6 -2
- data/lib/cancan/model_adapters/sequel_adapter.rb +87 -0
- data/lib/cancan/rule.rb +29 -24
- data/lib/cancan/version.rb +1 -1
- data/lib/cancancan.rb +3 -0
- data/spec/cancan/ability_spec.rb +26 -0
- data/spec/cancan/controller_resource_spec.rb +520 -447
- data/spec/cancan/inherited_resource_spec.rb +49 -38
- data/spec/cancan/model_adapters/active_record_adapter_spec.rb +106 -92
- data/spec/cancan/model_adapters/sequel_adapter_spec.rb +148 -0
- data/spec/spec_helper.rb +6 -61
- data/spec/support/ability.rb +7 -0
- metadata +41 -16
@@ -1,60 +1,71 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe CanCan::InheritedResource do
|
4
|
+
let(:ability) { Ability.new(nil) }
|
5
|
+
let(:params) { HashWithIndifferentAccess.new(:controller => "models") }
|
6
|
+
let(:controller_class) { Class.new }
|
7
|
+
let(:controller) { controller_class.new }
|
8
|
+
|
4
9
|
before(:each) do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
class Model
|
11
|
+
attr_accessor :name
|
12
|
+
|
13
|
+
def initialize(attributes={})
|
14
|
+
attributes.each do |attribute, value|
|
15
|
+
send("#{attribute}=", value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
allow(controller).to receive(:params) { params }
|
21
|
+
allow(controller).to receive(:current_ability) { ability }
|
22
|
+
allow(controller_class).to receive(:cancan_skipper) { {:authorize => {}, :load => {}} }
|
12
23
|
end
|
13
24
|
|
14
|
-
it "show loads resource through
|
15
|
-
|
16
|
-
allow(
|
17
|
-
CanCan::InheritedResource.new(
|
18
|
-
expect(
|
25
|
+
it "show loads resource through controller.resource" do
|
26
|
+
params.merge!(:action => "show", :id => 123)
|
27
|
+
allow(controller).to receive(:resource) { :model_resource }
|
28
|
+
CanCan::InheritedResource.new(controller).load_resource
|
29
|
+
expect(controller.instance_variable_get(:@model)).to eq(:model_resource)
|
19
30
|
end
|
20
31
|
|
21
|
-
it "new loads through
|
22
|
-
|
23
|
-
allow(
|
24
|
-
CanCan::InheritedResource.new(
|
25
|
-
expect(
|
32
|
+
it "new loads through controller.build_resource" do
|
33
|
+
params[:action] = "new"
|
34
|
+
allow(controller).to receive(:build_resource) { :model_resource }
|
35
|
+
CanCan::InheritedResource.new(controller).load_resource
|
36
|
+
expect(controller.instance_variable_get(:@model)).to eq(:model_resource)
|
26
37
|
end
|
27
38
|
|
28
|
-
it "index loads through
|
29
|
-
|
30
|
-
allow(
|
31
|
-
CanCan::InheritedResource.new(
|
32
|
-
expect(
|
39
|
+
it "index loads through controller.association_chain when parent" do
|
40
|
+
params[:action] = "index"
|
41
|
+
allow(controller).to receive(:association_chain) { controller.instance_variable_set(:@model, :model_resource) }
|
42
|
+
CanCan::InheritedResource.new(controller, :parent => true).load_resource
|
43
|
+
expect(controller.instance_variable_get(:@model)).to eq(:model_resource)
|
33
44
|
end
|
34
45
|
|
35
|
-
it "index loads through
|
36
|
-
|
37
|
-
allow(
|
38
|
-
allow(
|
39
|
-
CanCan::InheritedResource.new(
|
40
|
-
expect(
|
46
|
+
it "index loads through controller.end_of_association_chain" do
|
47
|
+
params[:action] = "index"
|
48
|
+
allow(Model).to receive(:accessible_by).with(ability, :index) { :projects }
|
49
|
+
allow(controller).to receive(:end_of_association_chain) { Model }
|
50
|
+
CanCan::InheritedResource.new(controller).load_resource
|
51
|
+
expect(controller.instance_variable_get(:@models)).to eq(:projects)
|
41
52
|
end
|
42
53
|
|
43
54
|
it "builds a new resource with attributes from current ability" do
|
44
|
-
|
45
|
-
|
46
|
-
allow(
|
47
|
-
resource = CanCan::InheritedResource.new(
|
55
|
+
params[:action] = "new"
|
56
|
+
ability.can(:create, Model, :name => "from conditions")
|
57
|
+
allow(controller).to receive(:build_resource) { Struct.new(:name).new }
|
58
|
+
resource = CanCan::InheritedResource.new(controller)
|
48
59
|
resource.load_resource
|
49
|
-
expect(
|
60
|
+
expect(controller.instance_variable_get(:@model).name).to eq("from conditions")
|
50
61
|
end
|
51
62
|
|
52
63
|
it "overrides initial attributes with params" do
|
53
|
-
|
54
|
-
|
55
|
-
allow(
|
56
|
-
resource = CanCan::ControllerResource.new(
|
64
|
+
params.merge!(:action => "new", :model => {:name => "from params"})
|
65
|
+
ability.can(:create, Model, :name => "from conditions")
|
66
|
+
allow(controller).to receive(:build_resource) { Struct.new(:name).new }
|
67
|
+
resource = CanCan::ControllerResource.new(controller)
|
57
68
|
resource.load_resource
|
58
|
-
expect(
|
69
|
+
expect(controller.instance_variable_get(:@model).name).to eq("from params")
|
59
70
|
end
|
60
71
|
end
|
@@ -2,61 +2,65 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
if defined? CanCan::ModelAdapters::ActiveRecordAdapter
|
4
4
|
|
5
|
-
|
6
|
-
config.extend WithModel
|
7
|
-
end
|
5
|
+
describe CanCan::ModelAdapters::ActiveRecordAdapter do
|
8
6
|
|
9
|
-
|
7
|
+
before :each do
|
8
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
9
|
+
ActiveRecord::Migration.verbose = false
|
10
|
+
ActiveRecord::Schema.define do
|
11
|
+
create_table(:categories) do |t|
|
12
|
+
t.string :name
|
13
|
+
t.boolean :visible
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table(:projects) do |t|
|
18
|
+
t.string :name
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
|
22
|
+
create_table(:articles) do |t|
|
23
|
+
t.string :name
|
24
|
+
t.timestamps
|
25
|
+
t.boolean :published
|
26
|
+
t.boolean :secret
|
27
|
+
t.integer :priority
|
28
|
+
t.integer :category_id
|
29
|
+
t.integer :user_id
|
30
|
+
end
|
31
|
+
|
32
|
+
create_table(:comments) do |t|
|
33
|
+
t.boolean :spam
|
34
|
+
t.integer :article_id
|
35
|
+
t.timestamps
|
36
|
+
end
|
37
|
+
|
38
|
+
create_table(:users) do |t|
|
39
|
+
t.timestamps
|
40
|
+
end
|
41
|
+
end
|
10
42
|
|
11
|
-
|
12
|
-
with_model :category do
|
13
|
-
table do |t|
|
14
|
-
t.string "name"
|
15
|
-
t.boolean "visible"
|
43
|
+
class Project < ActiveRecord::Base
|
16
44
|
end
|
17
|
-
|
45
|
+
|
46
|
+
class Category < ActiveRecord::Base
|
18
47
|
has_many :articles
|
19
48
|
end
|
20
|
-
end
|
21
49
|
|
22
|
-
|
23
|
-
table do |t|
|
24
|
-
t.string "name"
|
25
|
-
t.boolean "published"
|
26
|
-
t.boolean "secret"
|
27
|
-
t.integer "priority"
|
28
|
-
t.integer "category_id"
|
29
|
-
t.integer "user_id"
|
30
|
-
end
|
31
|
-
model do
|
50
|
+
class Article < ActiveRecord::Base
|
32
51
|
belongs_to :category
|
33
52
|
has_many :comments
|
34
53
|
belongs_to :user
|
35
54
|
end
|
36
|
-
end
|
37
55
|
|
38
|
-
|
39
|
-
table do |t|
|
40
|
-
t.boolean "spam"
|
41
|
-
t.integer "article_id"
|
42
|
-
end
|
43
|
-
model do
|
56
|
+
class Comment < ActiveRecord::Base
|
44
57
|
belongs_to :article
|
45
58
|
end
|
46
|
-
end
|
47
59
|
|
48
|
-
|
49
|
-
table do |t|
|
50
|
-
|
51
|
-
end
|
52
|
-
model do
|
60
|
+
class User < ActiveRecord::Base
|
53
61
|
has_many :articles
|
54
62
|
end
|
55
|
-
end
|
56
63
|
|
57
|
-
before(:each) do
|
58
|
-
Article.delete_all
|
59
|
-
Comment.delete_all
|
60
64
|
(@ability = double).extend(CanCan::Ability)
|
61
65
|
@article_table = Article.table_name
|
62
66
|
@comment_table = Comment.table_name
|
@@ -295,60 +299,6 @@ if defined? CanCan::ModelAdapters::ActiveRecordAdapter
|
|
295
299
|
expect(Article.accessible_by(ability)).to eq([article])
|
296
300
|
end
|
297
301
|
|
298
|
-
it "restricts articles given a MetaWhere condition" do
|
299
|
-
@ability.can :read, Article, :priority.lt => 2
|
300
|
-
article1 = Article.create!(:priority => 1)
|
301
|
-
article2 = Article.create!(:priority => 3)
|
302
|
-
expect(Article.accessible_by(@ability)).to eq([article1])
|
303
|
-
expect(@ability).to be_able_to(:read, article1)
|
304
|
-
expect(@ability).to_not be_able_to(:read, article2)
|
305
|
-
end
|
306
|
-
|
307
|
-
it "merges MetaWhere and non-MetaWhere conditions" do
|
308
|
-
@ability.can :read, Article, :priority.lt => 2
|
309
|
-
@ability.can :read, Article, :priority => 1
|
310
|
-
article1 = Article.create!(:priority => 1)
|
311
|
-
article2 = Article.create!(:priority => 3)
|
312
|
-
expect(Article.accessible_by(@ability)).to eq([article1])
|
313
|
-
expect(@ability).to be_able_to(:read, article1)
|
314
|
-
expect(@ability).to_not be_able_to(:read, article2)
|
315
|
-
end
|
316
|
-
|
317
|
-
it "matches any MetaWhere condition" do
|
318
|
-
adapter = CanCan::ModelAdapters::ActiveRecordAdapter
|
319
|
-
article1 = Article.new(:priority => 1, :name => "Hello World")
|
320
|
-
expect(adapter.matches_condition?(article1, :priority.eq, 1)).to be_true
|
321
|
-
expect(adapter.matches_condition?(article1, :priority.eq, 2)).to be_false
|
322
|
-
expect(adapter.matches_condition?(article1, :priority.eq_any, [1, 2])).to be_true
|
323
|
-
expect(adapter.matches_condition?(article1, :priority.eq_any, [2, 3])).to be_false
|
324
|
-
expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 1])).to be_true
|
325
|
-
expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 2])).to be_false
|
326
|
-
expect(adapter.matches_condition?(article1, :priority.ne, 2)).to be_true
|
327
|
-
expect(adapter.matches_condition?(article1, :priority.ne, 1)).to be_false
|
328
|
-
expect(adapter.matches_condition?(article1, :priority.in, [1, 2])).to be_true
|
329
|
-
expect(adapter.matches_condition?(article1, :priority.in, [2, 3])).to be_false
|
330
|
-
expect(adapter.matches_condition?(article1, :priority.nin, [2, 3])).to be_true
|
331
|
-
expect(adapter.matches_condition?(article1, :priority.nin, [1, 2])).to be_false
|
332
|
-
expect(adapter.matches_condition?(article1, :priority.lt, 2)).to be_true
|
333
|
-
expect(adapter.matches_condition?(article1, :priority.lt, 1)).to be_false
|
334
|
-
expect(adapter.matches_condition?(article1, :priority.lteq, 1)).to be_true
|
335
|
-
expect(adapter.matches_condition?(article1, :priority.lteq, 0)).to be_false
|
336
|
-
expect(adapter.matches_condition?(article1, :priority.gt, 0)).to be_true
|
337
|
-
expect(adapter.matches_condition?(article1, :priority.gt, 1)).to be_false
|
338
|
-
expect(adapter.matches_condition?(article1, :priority.gteq, 1)).to be_true
|
339
|
-
expect(adapter.matches_condition?(article1, :priority.gteq, 2)).to be_false
|
340
|
-
expect(adapter.matches_condition?(article1, :name.like, "%ello worl%")).to be_true
|
341
|
-
expect(adapter.matches_condition?(article1, :name.like, "hello world")).to be_true
|
342
|
-
expect(adapter.matches_condition?(article1, :name.like, "hello%")).to be_true
|
343
|
-
expect(adapter.matches_condition?(article1, :name.like, "h%d")).to be_true
|
344
|
-
expect(adapter.matches_condition?(article1, :name.like, "%helo%")).to be_false
|
345
|
-
expect(adapter.matches_condition?(article1, :name.like, "hello")).to be_false
|
346
|
-
expect(adapter.matches_condition?(article1, :name.like, "hello.world")).to be_false
|
347
|
-
# For some reason this is reporting "The not_matches MetaWhere condition is not supported."
|
348
|
-
# expect(adapter.matches_condition?(article1, :name.nlike, "%helo%")).to be_true
|
349
|
-
# expect(adapter.matches_condition?(article1, :name.nlike, "%ello worl%")).to be_false
|
350
|
-
end
|
351
|
-
|
352
302
|
it 'should not execute a scope when checking ability on the class' do
|
353
303
|
relation = Article.where(:secret => true)
|
354
304
|
@ability.can :read, Article, relation do |article|
|
@@ -359,5 +309,69 @@ if defined? CanCan::ModelAdapters::ActiveRecordAdapter
|
|
359
309
|
|
360
310
|
expect { @ability.can? :read, Article }.not_to raise_error
|
361
311
|
end
|
312
|
+
|
313
|
+
context "when MetaWhere is defined" do
|
314
|
+
|
315
|
+
before :each do
|
316
|
+
pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
|
317
|
+
end
|
318
|
+
|
319
|
+
it "restricts articles given a MetaWhere condition" do
|
320
|
+
# pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
|
321
|
+
@ability.can :read, Article, :priority.lt => 2
|
322
|
+
article1 = Article.create!(:priority => 1)
|
323
|
+
article2 = Article.create!(:priority => 3)
|
324
|
+
expect(Article.accessible_by(@ability)).to eq([article1])
|
325
|
+
expect(@ability).to be_able_to(:read, article1)
|
326
|
+
expect(@ability).to_not be_able_to(:read, article2)
|
327
|
+
end
|
328
|
+
|
329
|
+
it "merges MetaWhere and non-MetaWhere conditions" do
|
330
|
+
# pending "[Deprecated] MetaWhere support is being removed" unless defined? MetaWhere
|
331
|
+
@ability.can :read, Article, :priority.lt => 2
|
332
|
+
@ability.can :read, Article, :priority => 1
|
333
|
+
article1 = Article.create!(:priority => 1)
|
334
|
+
article2 = Article.create!(:priority => 3)
|
335
|
+
expect(Article.accessible_by(@ability)).to eq([article1])
|
336
|
+
expect(@ability).to be_able_to(:read, article1)
|
337
|
+
expect(@ability).to_not be_able_to(:read, article2)
|
338
|
+
end
|
339
|
+
|
340
|
+
it "matches any MetaWhere condition" do
|
341
|
+
|
342
|
+
adapter = CanCan::ModelAdapters::ActiveRecordAdapter
|
343
|
+
article1 = Article.new(:priority => 1, :name => "Hello World")
|
344
|
+
expect(adapter.matches_condition?(article1, :priority.eq, 1)).to be_true
|
345
|
+
expect(adapter.matches_condition?(article1, :priority.eq, 2)).to be_false
|
346
|
+
expect(adapter.matches_condition?(article1, :priority.eq_any, [1, 2])).to be_true
|
347
|
+
expect(adapter.matches_condition?(article1, :priority.eq_any, [2, 3])).to be_false
|
348
|
+
expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 1])).to be_true
|
349
|
+
expect(adapter.matches_condition?(article1, :priority.eq_all, [1, 2])).to be_false
|
350
|
+
expect(adapter.matches_condition?(article1, :priority.ne, 2)).to be_true
|
351
|
+
expect(adapter.matches_condition?(article1, :priority.ne, 1)).to be_false
|
352
|
+
expect(adapter.matches_condition?(article1, :priority.in, [1, 2])).to be_true
|
353
|
+
expect(adapter.matches_condition?(article1, :priority.in, [2, 3])).to be_false
|
354
|
+
expect(adapter.matches_condition?(article1, :priority.nin, [2, 3])).to be_true
|
355
|
+
expect(adapter.matches_condition?(article1, :priority.nin, [1, 2])).to be_false
|
356
|
+
expect(adapter.matches_condition?(article1, :priority.lt, 2)).to be_true
|
357
|
+
expect(adapter.matches_condition?(article1, :priority.lt, 1)).to be_false
|
358
|
+
expect(adapter.matches_condition?(article1, :priority.lteq, 1)).to be_true
|
359
|
+
expect(adapter.matches_condition?(article1, :priority.lteq, 0)).to be_false
|
360
|
+
expect(adapter.matches_condition?(article1, :priority.gt, 0)).to be_true
|
361
|
+
expect(adapter.matches_condition?(article1, :priority.gt, 1)).to be_false
|
362
|
+
expect(adapter.matches_condition?(article1, :priority.gteq, 1)).to be_true
|
363
|
+
expect(adapter.matches_condition?(article1, :priority.gteq, 2)).to be_false
|
364
|
+
expect(adapter.matches_condition?(article1, :name.like, "%ello worl%")).to be_true
|
365
|
+
expect(adapter.matches_condition?(article1, :name.like, "hello world")).to be_true
|
366
|
+
expect(adapter.matches_condition?(article1, :name.like, "hello%")).to be_true
|
367
|
+
expect(adapter.matches_condition?(article1, :name.like, "h%d")).to be_true
|
368
|
+
expect(adapter.matches_condition?(article1, :name.like, "%helo%")).to be_false
|
369
|
+
expect(adapter.matches_condition?(article1, :name.like, "hello")).to be_false
|
370
|
+
expect(adapter.matches_condition?(article1, :name.like, "hello.world")).to be_false
|
371
|
+
# For some reason this is reporting "The not_matches MetaWhere condition is not supported."
|
372
|
+
# expect(adapter.matches_condition?(article1, :name.nlike, "%helo%")).to be_true
|
373
|
+
# expect(adapter.matches_condition?(article1, :name.nlike, "%ello worl%")).to be_false
|
374
|
+
end
|
375
|
+
end
|
362
376
|
end
|
363
377
|
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
if ENV["MODEL_ADAPTER"] == "sequel"
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
DB = Sequel.sqlite
|
5
|
+
|
6
|
+
DB.create_table :users do
|
7
|
+
primary_key :id
|
8
|
+
String :name
|
9
|
+
end
|
10
|
+
|
11
|
+
class User < Sequel::Model
|
12
|
+
one_to_many :articles
|
13
|
+
end
|
14
|
+
|
15
|
+
DB.create_table :articles do
|
16
|
+
primary_key :id
|
17
|
+
String :name
|
18
|
+
TrueClass :published
|
19
|
+
TrueClass :secret
|
20
|
+
Integer :priority
|
21
|
+
foreign_key :user_id, :users
|
22
|
+
end
|
23
|
+
|
24
|
+
class Article < Sequel::Model
|
25
|
+
many_to_one :user
|
26
|
+
one_to_many :comments
|
27
|
+
end
|
28
|
+
|
29
|
+
DB.create_table :comments do
|
30
|
+
primary_key :id
|
31
|
+
TrueClass :spam
|
32
|
+
foreign_key :article_id, :articles
|
33
|
+
end
|
34
|
+
|
35
|
+
class Comment < Sequel::Model
|
36
|
+
many_to_one :article
|
37
|
+
end
|
38
|
+
|
39
|
+
describe CanCan::ModelAdapters::SequelAdapter do
|
40
|
+
before(:each) do
|
41
|
+
Comment.dataset.delete
|
42
|
+
Article.dataset.delete
|
43
|
+
User.dataset.delete
|
44
|
+
@ability = Object.new
|
45
|
+
@ability.extend(CanCan::Ability)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be for only sequel model classes" do
|
49
|
+
CanCan::ModelAdapters::SequelAdapter.should_not be_for_class(Object)
|
50
|
+
CanCan::ModelAdapters::SequelAdapter.should be_for_class(Article)
|
51
|
+
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::SequelAdapter
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should find record" do
|
55
|
+
article = Article.create
|
56
|
+
CanCan::ModelAdapters::SequelAdapter.find(Article, article.id).should == article
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not fetch any records when no abilities are defined" do
|
60
|
+
Article.create
|
61
|
+
Article.accessible_by(@ability).all.should be_empty
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should fetch all articles when one can read all" do
|
65
|
+
@ability.can :read, Article
|
66
|
+
article = Article.create
|
67
|
+
@ability.should be_able_to(:read, article)
|
68
|
+
Article.accessible_by(@ability).all.should == [article]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should fetch only the articles that are published" do
|
72
|
+
@ability.can :read, Article, :published => true
|
73
|
+
article1 = Article.create(:published => true)
|
74
|
+
article2 = Article.create(:published => false)
|
75
|
+
@ability.should be_able_to(:read, article1)
|
76
|
+
@ability.should_not be_able_to(:read, article2)
|
77
|
+
Article.accessible_by(@ability).all.should == [article1]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should fetch any articles which are published or secret" do
|
81
|
+
@ability.can :read, Article, :published => true
|
82
|
+
@ability.can :read, Article, :secret => true
|
83
|
+
article1 = Article.create(:published => true, :secret => false)
|
84
|
+
article2 = Article.create(:published => true, :secret => true)
|
85
|
+
article3 = Article.create(:published => false, :secret => true)
|
86
|
+
article4 = Article.create(:published => false, :secret => false)
|
87
|
+
@ability.should be_able_to(:read, article1)
|
88
|
+
@ability.should be_able_to(:read, article2)
|
89
|
+
@ability.should be_able_to(:read, article3)
|
90
|
+
@ability.should_not be_able_to(:read, article4)
|
91
|
+
Article.accessible_by(@ability).all.should == [article1, article2, article3]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should fetch only the articles that are published and not secret" do
|
95
|
+
@ability.can :read, Article, :published => true
|
96
|
+
@ability.cannot :read, Article, :secret => true
|
97
|
+
article1 = Article.create(:published => true, :secret => false)
|
98
|
+
article2 = Article.create(:published => true, :secret => true)
|
99
|
+
article3 = Article.create(:published => false, :secret => true)
|
100
|
+
article4 = Article.create(:published => false, :secret => false)
|
101
|
+
@ability.should be_able_to(:read, article1)
|
102
|
+
@ability.should_not be_able_to(:read, article2)
|
103
|
+
@ability.should_not be_able_to(:read, article3)
|
104
|
+
@ability.should_not be_able_to(:read, article4)
|
105
|
+
Article.accessible_by(@ability).all.should == [article1]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should only read comments for articles which are published" do
|
109
|
+
@ability.can :read, Comment, :article => { :published => true }
|
110
|
+
comment1 = Comment.create(:article => Article.create(:published => true))
|
111
|
+
comment2 = Comment.create(:article => Article.create(:published => false))
|
112
|
+
@ability.should be_able_to(:read, comment1)
|
113
|
+
@ability.should_not be_able_to(:read, comment2)
|
114
|
+
Comment.accessible_by(@ability).all.should == [comment1]
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should only read comments for articles which are published and user is 'me'" do
|
118
|
+
@ability.can :read, Comment, :article => { :user => { :name => 'me' }, :published => true }
|
119
|
+
user1 = User.create(:name => 'me')
|
120
|
+
comment1 = Comment.create(:article => Article.create(:published => true, :user => user1))
|
121
|
+
comment2 = Comment.create(:article => Article.create(:published => true))
|
122
|
+
comment3 = Comment.create(:article => Article.create(:published => false, :user => user1))
|
123
|
+
@ability.should be_able_to(:read, comment1)
|
124
|
+
@ability.should_not be_able_to(:read, comment2)
|
125
|
+
@ability.should_not be_able_to(:read, comment3)
|
126
|
+
Comment.accessible_by(@ability).all.should == [comment1]
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should allow conditions in SQL and merge with hash conditions" do
|
130
|
+
@ability.can :read, Article, :published => true
|
131
|
+
@ability.can :read, Article, ["secret=?", true] do |article|
|
132
|
+
article.secret
|
133
|
+
end
|
134
|
+
@ability.cannot :read, Article, "priority > 1" do |article|
|
135
|
+
article.priority > 1
|
136
|
+
end
|
137
|
+
article1 = Article.create(:published => true, :secret => false, :priority => 1)
|
138
|
+
article2 = Article.create(:published => true, :secret => true, :priority => 1)
|
139
|
+
article3 = Article.create(:published => true, :secret => true, :priority => 2)
|
140
|
+
article4 = Article.create(:published => false, :secret => false, :priority => 2)
|
141
|
+
@ability.should be_able_to(:read, article1)
|
142
|
+
@ability.should be_able_to(:read, article2)
|
143
|
+
@ability.should_not be_able_to(:read, article3)
|
144
|
+
@ability.should_not be_able_to(:read, article4)
|
145
|
+
Article.accessible_by(@ability).all.should == [article1, article2]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|