pundit 1.1.0 → 2.0.0.beta1
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 +5 -5
- data/.rubocop.yml +18 -10
- data/.travis.yml +19 -9
- data/CHANGELOG.md +13 -0
- data/Gemfile +13 -1
- data/README.md +233 -60
- data/Rakefile +0 -1
- data/lib/generators/pundit/install/install_generator.rb +1 -1
- data/lib/generators/pundit/install/templates/application_policy.rb +2 -6
- data/lib/generators/pundit/policy/policy_generator.rb +1 -1
- data/lib/generators/pundit/policy/templates/policy.rb +1 -1
- data/lib/generators/rspec/policy_generator.rb +1 -1
- data/lib/generators/rspec/templates/policy_spec.rb +0 -1
- data/lib/generators/test_unit/policy_generator.rb +1 -1
- data/lib/generators/test_unit/templates/policy_test.rb +0 -1
- data/lib/pundit.rb +84 -59
- data/lib/pundit/policy_finder.rb +25 -31
- data/lib/pundit/rspec.rb +11 -7
- data/lib/pundit/version.rb +3 -1
- data/pundit.gemspec +2 -11
- data/spec/policy_finder_spec.rb +122 -0
- data/spec/pundit_spec.rb +136 -32
- data/spec/spec_helper.rb +73 -11
- metadata +8 -119
data/lib/pundit/rspec.rb
CHANGED
@@ -5,10 +5,11 @@ module Pundit
|
|
5
5
|
module Matchers
|
6
6
|
extend ::RSpec::Matchers::DSL
|
7
7
|
|
8
|
+
# rubocop:disable Metrics/BlockLength
|
8
9
|
matcher :permit do |user, record|
|
9
10
|
match_proc = lambda do |policy|
|
10
11
|
@violating_permissions = permissions.find_all do |permission|
|
11
|
-
|
12
|
+
!policy.new(user, record).public_send(permission)
|
12
13
|
end
|
13
14
|
@violating_permissions.empty?
|
14
15
|
end
|
@@ -22,14 +23,14 @@ module Pundit
|
|
22
23
|
|
23
24
|
failure_message_proc = lambda do |policy|
|
24
25
|
was_were = @violating_permissions.count > 1 ? "were" : "was"
|
25
|
-
"Expected #{policy} to grant #{permissions.to_sentence} on \
|
26
|
-
#{record} but #{@violating_permissions.to_sentence} #{was_were} not granted"
|
26
|
+
"Expected #{policy} to grant #{permissions.to_sentence} on " \
|
27
|
+
"#{record} but #{@violating_permissions.to_sentence} #{was_were} not granted"
|
27
28
|
end
|
28
29
|
|
29
30
|
failure_message_when_negated_proc = lambda do |policy|
|
30
31
|
was_were = @violating_permissions.count > 1 ? "were" : "was"
|
31
|
-
"Expected #{policy} not to grant #{permissions.to_sentence} on \
|
32
|
-
#{record} but #{@violating_permissions.to_sentence} #{was_were} granted"
|
32
|
+
"Expected #{policy} not to grant #{permissions.to_sentence} on " \
|
33
|
+
"#{record} but #{@violating_permissions.to_sentence} #{was_were} granted"
|
33
34
|
end
|
34
35
|
|
35
36
|
if respond_to?(:match_when_negated)
|
@@ -49,6 +50,7 @@ module Pundit
|
|
49
50
|
current_example.metadata[:permissions]
|
50
51
|
end
|
51
52
|
end
|
53
|
+
# rubocop:enable Metrics/BlockLength
|
52
54
|
end
|
53
55
|
|
54
56
|
module DSL
|
@@ -71,12 +73,14 @@ end
|
|
71
73
|
|
72
74
|
RSpec.configure do |config|
|
73
75
|
if RSpec::Core::Version::STRING.split(".").first.to_i >= 3
|
74
|
-
config.include(
|
76
|
+
config.include(
|
77
|
+
Pundit::RSpec::PolicyExampleGroup,
|
75
78
|
type: :policy,
|
76
79
|
file_path: %r{spec/policies}
|
77
80
|
)
|
78
81
|
else
|
79
|
-
config.include(
|
82
|
+
config.include(
|
83
|
+
Pundit::RSpec::PolicyExampleGroup,
|
80
84
|
type: :policy,
|
81
85
|
example_group: { file_path: %r{spec/policies} }
|
82
86
|
)
|
data/lib/pundit/version.rb
CHANGED
data/pundit.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require "pundit/version"
|
5
4
|
|
@@ -10,7 +9,7 @@ Gem::Specification.new do |gem|
|
|
10
9
|
gem.email = ["jonas.nicklas@gmail.com", "dev@elabs.se"]
|
11
10
|
gem.description = "Object oriented authorization for Rails applications"
|
12
11
|
gem.summary = "OO authorization for Rails"
|
13
|
-
gem.homepage = "https://github.com/
|
12
|
+
gem.homepage = "https://github.com/varvet/pundit"
|
14
13
|
gem.license = "MIT"
|
15
14
|
|
16
15
|
gem.files = `git ls-files`.split($/)
|
@@ -19,12 +18,4 @@ Gem::Specification.new do |gem|
|
|
19
18
|
gem.require_paths = ["lib"]
|
20
19
|
|
21
20
|
gem.add_dependency "activesupport", ">= 3.0.0"
|
22
|
-
gem.add_development_dependency "activemodel", ">= 3.0.0"
|
23
|
-
gem.add_development_dependency "actionpack", ">= 3.0.0"
|
24
|
-
gem.add_development_dependency "bundler", "~> 1.3"
|
25
|
-
gem.add_development_dependency "rspec", ">=2.0.0"
|
26
|
-
gem.add_development_dependency "pry"
|
27
|
-
gem.add_development_dependency "rake"
|
28
|
-
gem.add_development_dependency "yard"
|
29
|
-
gem.add_development_dependency "rubocop"
|
30
21
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Pundit::PolicyFinder do
|
4
|
+
let(:user) { double }
|
5
|
+
let(:post) { Post.new(user) }
|
6
|
+
let(:comment) { CommentFourFiveSix.new }
|
7
|
+
let(:article) { Article.new }
|
8
|
+
|
9
|
+
describe "#scope" do
|
10
|
+
subject { described_class.new(post) }
|
11
|
+
|
12
|
+
it "returns a policy scope" do
|
13
|
+
expect(subject.scope).to eq PostPolicy::Scope
|
14
|
+
end
|
15
|
+
|
16
|
+
context "policy is nil" do
|
17
|
+
it "returns nil" do
|
18
|
+
allow(subject).to receive(:policy).and_return nil
|
19
|
+
expect(subject.scope).to eq nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#policy" do
|
25
|
+
subject { described_class.new(post) }
|
26
|
+
|
27
|
+
it "returns a policy" do
|
28
|
+
expect(subject.policy).to eq PostPolicy
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a string" do
|
32
|
+
it "returns a policy" do
|
33
|
+
allow(subject).to receive(:find).and_return "PostPolicy"
|
34
|
+
expect(subject.policy).to eq PostPolicy
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with a class" do
|
39
|
+
it "returns a policy" do
|
40
|
+
allow(subject).to receive(:find).and_return PostPolicy
|
41
|
+
expect(subject.policy).to eq PostPolicy
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with nil" do
|
46
|
+
it "returns nil" do
|
47
|
+
allow(subject).to receive(:find).and_return nil
|
48
|
+
expect(subject.policy).to eq nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "with a string that can't be constantized" do
|
53
|
+
it "returns nil" do
|
54
|
+
allow(subject).to receive(:find).and_return "FooPolicy"
|
55
|
+
expect(subject.policy).to eq nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#scope!" do
|
61
|
+
context "@object is nil" do
|
62
|
+
subject { described_class.new(nil) }
|
63
|
+
|
64
|
+
it "returns the NilClass policy's scope class" do
|
65
|
+
expect(subject.scope!).to eq NilClassPolicy::Scope
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "@object is defined" do
|
70
|
+
subject { described_class.new(post) }
|
71
|
+
|
72
|
+
it "returns the scope" do
|
73
|
+
expect(subject.scope!).to eq PostPolicy::Scope
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#param_key" do
|
79
|
+
context "object responds to model_name" do
|
80
|
+
subject { described_class.new(comment) }
|
81
|
+
|
82
|
+
it "returns the param_key" do
|
83
|
+
expect(subject.object).to respond_to(:model_name)
|
84
|
+
expect(subject.param_key).to eq "comment_four_five_six"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "object is a class" do
|
89
|
+
subject { described_class.new(Article) }
|
90
|
+
|
91
|
+
it "returns the param_key" do
|
92
|
+
expect(subject.object).not_to respond_to(:model_name)
|
93
|
+
expect(subject.object).to be_a Class
|
94
|
+
expect(subject.param_key).to eq "article"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "object is an instance of a class" do
|
99
|
+
subject { described_class.new(article) }
|
100
|
+
|
101
|
+
it "returns the param_key" do
|
102
|
+
expect(subject.object).not_to respond_to(:model_name)
|
103
|
+
expect(subject.object).not_to be_a Class
|
104
|
+
expect(subject.object).to be_an_instance_of Article
|
105
|
+
|
106
|
+
expect(subject.param_key).to eq "article"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "object is an array" do
|
111
|
+
subject { described_class.new([:project, article]) }
|
112
|
+
|
113
|
+
it "returns the param_key for the last element of the array" do
|
114
|
+
expect(subject.object).not_to respond_to(:model_name)
|
115
|
+
expect(subject.object).not_to be_a Class
|
116
|
+
expect(subject.object).to be_an_instance_of Array
|
117
|
+
|
118
|
+
expect(subject.param_key).to eq "article"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/spec/pundit_spec.rb
CHANGED
@@ -8,19 +8,24 @@ describe Pundit do
|
|
8
8
|
let(:comment) { Comment.new }
|
9
9
|
let(:comment_four_five_six) { CommentFourFiveSix.new }
|
10
10
|
let(:article) { Article.new }
|
11
|
-
let(:controller) { Controller.new(user,
|
11
|
+
let(:controller) { Controller.new(user, "update", {}) }
|
12
12
|
let(:artificial_blog) { ArtificialBlog.new }
|
13
13
|
let(:article_tag) { ArticleTag.new }
|
14
14
|
let(:comments_relation) { CommentsRelation.new }
|
15
15
|
let(:empty_comments_relation) { CommentsRelation.new(true) }
|
16
16
|
let(:tag_four_five_six) { ProjectOneTwoThree::TagFourFiveSix.new(user) }
|
17
17
|
let(:avatar_four_five_six) { ProjectOneTwoThree::AvatarFourFiveSix.new }
|
18
|
+
let(:wiki) { Wiki.new }
|
18
19
|
|
19
20
|
describe ".authorize" do
|
20
21
|
it "infers the policy and authorizes based on it" do
|
21
22
|
expect(Pundit.authorize(user, post, :update?)).to be_truthy
|
22
23
|
end
|
23
24
|
|
25
|
+
it "can be given a different policy class" do
|
26
|
+
expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
|
27
|
+
end
|
28
|
+
|
24
29
|
it "works with anonymous class policies" do
|
25
30
|
expect(Pundit.authorize(user, article_tag, :show?)).to be_truthy
|
26
31
|
expect { Pundit.authorize(user, article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
|
@@ -35,6 +40,13 @@ describe Pundit do
|
|
35
40
|
expect(error.record).to eq post
|
36
41
|
expect(error.policy).to eq Pundit.policy(user, post)
|
37
42
|
end
|
43
|
+
# rubocop:enable Style/MultilineBlockChain
|
44
|
+
end
|
45
|
+
|
46
|
+
it "raises an error with a invalid policy constructor" do
|
47
|
+
expect do
|
48
|
+
Pundit.authorize(user, wiki, :update?)
|
49
|
+
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy> constructor is called")
|
38
50
|
end
|
39
51
|
end
|
40
52
|
|
@@ -44,23 +56,37 @@ describe Pundit do
|
|
44
56
|
end
|
45
57
|
|
46
58
|
it "returns an instantiated policy scope given an active model class" do
|
47
|
-
expect(Pundit.policy_scope(user, Comment)).to eq Comment
|
59
|
+
expect(Pundit.policy_scope(user, Comment)).to eq CommentScope.new(Comment)
|
48
60
|
end
|
49
61
|
|
50
62
|
it "returns an instantiated policy scope given an active record relation" do
|
51
|
-
expect(Pundit.policy_scope(user, comments_relation)).to eq comments_relation
|
63
|
+
expect(Pundit.policy_scope(user, comments_relation)).to eq CommentScope.new(comments_relation)
|
52
64
|
end
|
53
65
|
|
54
66
|
it "returns an instantiated policy scope given an empty active record relation" do
|
55
|
-
expect(Pundit.policy_scope(user, empty_comments_relation)).to eq empty_comments_relation
|
67
|
+
expect(Pundit.policy_scope(user, empty_comments_relation)).to eq CommentScope.new(empty_comments_relation)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns an instantiated policy scope given an array of a symbol and plain model class" do
|
71
|
+
expect(Pundit.policy_scope(user, [:project, Post])).to eq :read
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns an instantiated policy scope given an array of a symbol and active model class" do
|
75
|
+
expect(Pundit.policy_scope(user, [:project, Comment])).to eq Comment
|
56
76
|
end
|
57
77
|
|
58
78
|
it "returns nil if the given policy scope can't be found" do
|
59
79
|
expect(Pundit.policy_scope(user, Article)).to be_nil
|
60
80
|
end
|
61
81
|
|
62
|
-
it "
|
63
|
-
expect
|
82
|
+
it "raises an exception if nil object given" do
|
83
|
+
expect { Pundit.policy_scope(user, nil) }.to raise_error(Pundit::NotDefinedError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "raises an error with a invalid policy scope constructor" do
|
87
|
+
expect do
|
88
|
+
Pundit.policy_scope(user, Wiki)
|
89
|
+
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy::Scope> constructor is called")
|
64
90
|
end
|
65
91
|
end
|
66
92
|
|
@@ -70,7 +96,7 @@ describe Pundit do
|
|
70
96
|
end
|
71
97
|
|
72
98
|
it "returns an instantiated policy scope given an active model class" do
|
73
|
-
expect(Pundit.policy_scope!(user, Comment)).to eq Comment
|
99
|
+
expect(Pundit.policy_scope!(user, Comment)).to eq CommentScope.new(Comment)
|
74
100
|
end
|
75
101
|
|
76
102
|
it "throws an exception if the given policy scope can't be found" do
|
@@ -84,7 +110,21 @@ describe Pundit do
|
|
84
110
|
it "throws an exception if the given policy scope is nil" do
|
85
111
|
expect do
|
86
112
|
Pundit.policy_scope!(user, nil)
|
87
|
-
end.to raise_error(Pundit::NotDefinedError, "
|
113
|
+
end.to raise_error(Pundit::NotDefinedError, "Cannot scope NilClass")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns an instantiated policy scope given an array of a symbol and plain model class" do
|
117
|
+
expect(Pundit.policy_scope!(user, [:project, Post])).to eq :read
|
118
|
+
end
|
119
|
+
|
120
|
+
it "returns an instantiated policy scope given an array of a symbol and active model class" do
|
121
|
+
expect(Pundit.policy_scope!(user, [:project, Comment])).to eq Comment
|
122
|
+
end
|
123
|
+
|
124
|
+
it "raises an error with a invalid policy scope constructor" do
|
125
|
+
expect do
|
126
|
+
Pundit.policy_scope(user, Wiki)
|
127
|
+
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy::Scope> constructor is called")
|
88
128
|
end
|
89
129
|
end
|
90
130
|
|
@@ -121,42 +161,62 @@ describe Pundit do
|
|
121
161
|
end
|
122
162
|
|
123
163
|
it "returns an instantiated policy given an array of symbols" do
|
124
|
-
policy = Pundit.policy(user, [
|
164
|
+
policy = Pundit.policy(user, %i[project criteria])
|
125
165
|
expect(policy.class).to eq Project::CriteriaPolicy
|
126
166
|
expect(policy.user).to eq user
|
127
|
-
expect(policy.criteria).to eq
|
167
|
+
expect(policy.criteria).to eq :criteria
|
128
168
|
end
|
129
169
|
|
130
170
|
it "returns an instantiated policy given an array of a symbol and plain model instance" do
|
131
171
|
policy = Pundit.policy(user, [:project, post])
|
132
172
|
expect(policy.class).to eq Project::PostPolicy
|
133
173
|
expect(policy.user).to eq user
|
134
|
-
expect(policy.post).to eq
|
174
|
+
expect(policy.post).to eq post
|
175
|
+
end
|
176
|
+
|
177
|
+
it "returns an instantiated policy given an array of a symbol and a model instance with policy_class override" do
|
178
|
+
policy = Pundit.policy(user, [:project, customer_post])
|
179
|
+
expect(policy.class).to eq Project::PostPolicy
|
180
|
+
expect(policy.user).to eq user
|
181
|
+
expect(policy.post).to eq customer_post
|
135
182
|
end
|
136
183
|
|
137
184
|
it "returns an instantiated policy given an array of a symbol and an active model instance" do
|
138
185
|
policy = Pundit.policy(user, [:project, comment])
|
139
186
|
expect(policy.class).to eq Project::CommentPolicy
|
140
187
|
expect(policy.user).to eq user
|
141
|
-
expect(policy.
|
188
|
+
expect(policy.comment).to eq comment
|
142
189
|
end
|
143
190
|
|
144
191
|
it "returns an instantiated policy given an array of a symbol and a plain model class" do
|
145
192
|
policy = Pundit.policy(user, [:project, Post])
|
146
193
|
expect(policy.class).to eq Project::PostPolicy
|
147
194
|
expect(policy.user).to eq user
|
148
|
-
expect(policy.post).to eq
|
195
|
+
expect(policy.post).to eq Post
|
196
|
+
end
|
197
|
+
|
198
|
+
it "raises an error with a invalid policy constructor" do
|
199
|
+
expect do
|
200
|
+
Pundit.policy(user, Wiki)
|
201
|
+
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy> constructor is called")
|
149
202
|
end
|
150
203
|
|
151
204
|
it "returns an instantiated policy given an array of a symbol and an active model class" do
|
152
205
|
policy = Pundit.policy(user, [:project, Comment])
|
153
206
|
expect(policy.class).to eq Project::CommentPolicy
|
154
207
|
expect(policy.user).to eq user
|
155
|
-
expect(policy.
|
208
|
+
expect(policy.comment).to eq Comment
|
209
|
+
end
|
210
|
+
|
211
|
+
it "returns an instantiated policy given an array of a symbol and a class with policy_class override" do
|
212
|
+
policy = Pundit.policy(user, [:project, Customer::Post])
|
213
|
+
expect(policy.class).to eq Project::PostPolicy
|
214
|
+
expect(policy.user).to eq user
|
215
|
+
expect(policy.post).to eq Customer::Post
|
156
216
|
end
|
157
217
|
|
158
218
|
it "returns correct policy class for an array of a multi-word symbols" do
|
159
|
-
policy = Pundit.policy(user, [
|
219
|
+
policy = Pundit.policy(user, %i[project_one_two_three criteria_four_five_six])
|
160
220
|
expect(policy.class).to eq ProjectOneTwoThree::CriteriaFourFiveSixPolicy
|
161
221
|
end
|
162
222
|
|
@@ -205,8 +265,8 @@ describe Pundit do
|
|
205
265
|
expect(Pundit.policy(user, Article)).to be_nil
|
206
266
|
end
|
207
267
|
|
208
|
-
it "returns
|
209
|
-
expect(Pundit.policy(user, nil)).to
|
268
|
+
it "returns the specified NilClassPolicy for nil" do
|
269
|
+
expect(Pundit.policy(user, nil)).to be_a NilClassPolicy
|
210
270
|
end
|
211
271
|
|
212
272
|
describe "with .policy_class set on the model" do
|
@@ -269,10 +329,10 @@ describe Pundit do
|
|
269
329
|
end
|
270
330
|
|
271
331
|
it "returns an instantiated policy given an array of symbols" do
|
272
|
-
policy = Pundit.policy!(user, [
|
332
|
+
policy = Pundit.policy!(user, %i[project criteria])
|
273
333
|
expect(policy.class).to eq Project::CriteriaPolicy
|
274
334
|
expect(policy.user).to eq user
|
275
|
-
expect(policy.criteria).to eq
|
335
|
+
expect(policy.criteria).to eq :criteria
|
276
336
|
end
|
277
337
|
|
278
338
|
it "throws an exception if the given policy can't be found" do
|
@@ -280,8 +340,14 @@ describe Pundit do
|
|
280
340
|
expect { Pundit.policy!(user, Article) }.to raise_error(Pundit::NotDefinedError)
|
281
341
|
end
|
282
342
|
|
283
|
-
it "
|
284
|
-
expect
|
343
|
+
it "returns the specified NilClassPolicy for nil" do
|
344
|
+
expect(Pundit.policy!(user, nil)).to be_a NilClassPolicy
|
345
|
+
end
|
346
|
+
|
347
|
+
it "raises an error with a invalid policy constructor" do
|
348
|
+
expect do
|
349
|
+
Pundit.policy(user, Wiki)
|
350
|
+
end.to raise_error(Pundit::InvalidConstructorError, "Invalid #<WikiPolicy> constructor is called")
|
285
351
|
end
|
286
352
|
end
|
287
353
|
|
@@ -334,11 +400,19 @@ describe Pundit do
|
|
334
400
|
expect(controller.authorize(post)).to be_truthy
|
335
401
|
end
|
336
402
|
|
403
|
+
it "returns the record on successful authorization" do
|
404
|
+
expect(controller.authorize(post)).to be(post)
|
405
|
+
end
|
406
|
+
|
337
407
|
it "can be given a different permission to check" do
|
338
408
|
expect(controller.authorize(post, :show?)).to be_truthy
|
339
409
|
expect { controller.authorize(post, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
|
340
410
|
end
|
341
411
|
|
412
|
+
it "can be given a different policy class" do
|
413
|
+
expect(controller.authorize(post, :create?, policy_class: PublicationPolicy)).to be_truthy
|
414
|
+
end
|
415
|
+
|
342
416
|
it "works with anonymous class policies" do
|
343
417
|
expect(controller.authorize(article_tag, :show?)).to be_truthy
|
344
418
|
expect { controller.authorize(article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
|
@@ -359,7 +433,11 @@ describe Pundit do
|
|
359
433
|
end
|
360
434
|
|
361
435
|
it "raises an error when the given record is nil" do
|
362
|
-
expect { controller.authorize(nil, :destroy?) }.to raise_error(Pundit::
|
436
|
+
expect { controller.authorize(nil, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
|
437
|
+
end
|
438
|
+
|
439
|
+
it "raises an error with a invalid policy constructor" do
|
440
|
+
expect { controller.authorize(wiki, :destroy?) }.to raise_error(Pundit::InvalidConstructorError)
|
363
441
|
end
|
364
442
|
end
|
365
443
|
|
@@ -394,6 +472,10 @@ describe Pundit do
|
|
394
472
|
expect { controller.policy(article) }.to raise_error(Pundit::NotDefinedError)
|
395
473
|
end
|
396
474
|
|
475
|
+
it "raises an error with a invalid policy constructor" do
|
476
|
+
expect { controller.policy(wiki) }.to raise_error(Pundit::InvalidConstructorError)
|
477
|
+
end
|
478
|
+
|
397
479
|
it "allows policy to be injected" do
|
398
480
|
new_policy = OpenStruct.new
|
399
481
|
controller.policies[post] = new_policy
|
@@ -407,10 +489,18 @@ describe Pundit do
|
|
407
489
|
expect(controller.policy_scope(Post)).to eq :published
|
408
490
|
end
|
409
491
|
|
492
|
+
it "allows policy scope class to be overriden" do
|
493
|
+
expect(controller.policy_scope(Post, policy_scope_class: PublicationPolicy::Scope)).to eq :published
|
494
|
+
end
|
495
|
+
|
410
496
|
it "throws an exception if the given policy can't be found" do
|
411
497
|
expect { controller.policy_scope(Article) }.to raise_error(Pundit::NotDefinedError)
|
412
498
|
end
|
413
499
|
|
500
|
+
it "raises an error with a invalid policy scope constructor" do
|
501
|
+
expect { controller.policy_scope(Wiki) }.to raise_error(Pundit::InvalidConstructorError)
|
502
|
+
end
|
503
|
+
|
414
504
|
it "allows policy_scope to be injected" do
|
415
505
|
new_scope = OpenStruct.new
|
416
506
|
controller.policy_scopes[Post] = new_scope
|
@@ -421,49 +511,63 @@ describe Pundit do
|
|
421
511
|
|
422
512
|
describe "#permitted_attributes" do
|
423
513
|
it "checks policy for permitted attributes" do
|
424
|
-
params = ActionController::Parameters.new(
|
514
|
+
params = ActionController::Parameters.new(post: {
|
425
515
|
title: "Hello",
|
426
516
|
votes: 5,
|
427
517
|
admin: true
|
428
518
|
})
|
429
519
|
|
430
|
-
|
431
|
-
|
520
|
+
action = "update"
|
521
|
+
|
522
|
+
expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq(
|
523
|
+
"title" => "Hello",
|
524
|
+
"votes" => 5
|
525
|
+
)
|
526
|
+
expect(Controller.new(double, action, params).permitted_attributes(post).to_h).to eq("votes" => 5)
|
432
527
|
end
|
433
528
|
|
434
529
|
it "checks policy for permitted attributes for record of a ActiveModel type" do
|
435
|
-
params = ActionController::Parameters.new(
|
530
|
+
params = ActionController::Parameters.new(customer_post: {
|
436
531
|
title: "Hello",
|
437
532
|
votes: 5,
|
438
533
|
admin: true
|
439
534
|
})
|
440
535
|
|
441
|
-
|
442
|
-
|
536
|
+
action = "update"
|
537
|
+
|
538
|
+
expect(Controller.new(user, action, params).permitted_attributes(customer_post).to_h).to eq(
|
539
|
+
"title" => "Hello",
|
540
|
+
"votes" => 5
|
541
|
+
)
|
542
|
+
expect(Controller.new(double, action, params).permitted_attributes(customer_post).to_h).to eq(
|
543
|
+
"votes" => 5
|
544
|
+
)
|
443
545
|
end
|
444
546
|
end
|
445
547
|
|
446
548
|
describe "#permitted_attributes_for_action" do
|
447
549
|
it "is checked if it is defined in the policy" do
|
448
|
-
params = ActionController::Parameters.new(
|
550
|
+
params = ActionController::Parameters.new(post: {
|
449
551
|
title: "Hello",
|
450
552
|
body: "blah",
|
451
553
|
votes: 5,
|
452
554
|
admin: true
|
453
555
|
})
|
454
556
|
|
455
|
-
|
557
|
+
action = "revise"
|
558
|
+
expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq("body" => "blah")
|
456
559
|
end
|
457
560
|
|
458
561
|
it "can be explicitly set" do
|
459
|
-
params = ActionController::Parameters.new(
|
562
|
+
params = ActionController::Parameters.new(post: {
|
460
563
|
title: "Hello",
|
461
564
|
body: "blah",
|
462
565
|
votes: 5,
|
463
566
|
admin: true
|
464
567
|
})
|
465
568
|
|
466
|
-
|
569
|
+
action = "update"
|
570
|
+
expect(Controller.new(user, action, params).permitted_attributes(post, :revise).to_h).to eq("body" => "blah")
|
467
571
|
end
|
468
572
|
end
|
469
573
|
|