pundit 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 371516754ff155f90b2093a0ce80aacf097ab555027b19ea22b7c823de72a66a
4
- data.tar.gz: 41e69a7d6a317b46ad35d1d1485d2119b443b8a430e5c78e62935ec502c7d08f
3
+ metadata.gz: def6c710d9f9d1705ca43cdad9364bb34ce5d878b8a3a9bf26d336802e40efeb
4
+ data.tar.gz: 0d6618cb61dfef8ae18f811a73b3f059d9945f8def7f9b2f794ae095b3a0f0cf
5
5
  SHA512:
6
- metadata.gz: c77a792bec5d87f487fd3ee419d00745dcab754bd1bd38504d9987b71d80be3bd32fb1aab8419a8e63ef3c3718e1bd8a255ff0117be8f8a5c743c221d87fccdd
7
- data.tar.gz: 3086b4036cdbafb499f462f22405f185c83d12c8d8175136531dd053733320574b3d5d05c8379895940d854d54d7abb59d6a0958a9d0e6fdfc03f7691883c3ab
6
+ metadata.gz: 7105cd0a84469071de9211e19f7e7a31f4ea8b5283d7b1ed007b6533805de18d105c09128a9936144612f3daa8fadfdf0698f7448d8db94e47bb459efaa11c4b
7
+ data.tar.gz: 3805e2664f21f30c66e9a9a05606f0d0d18b1607137e794948c7907bd33c6d6e64a45b9abb97d2f1a21df0d46497ff708679442807e152fa167abc461c8c0abe
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .coverage
5
6
  .yardoc
6
7
  Gemfile.lock
7
8
  InstalledFiles
data/.rubocop.yml CHANGED
@@ -1,10 +1,7 @@
1
1
  AllCops:
2
- DisplayCopNames: true
3
- TargetRubyVersion: 2.2
2
+ TargetRubyVersion: 2.6
4
3
  Exclude:
5
- - "gemfiles/**/*"
6
- - "vendor/**/*"
7
- - "lib/generators/**/*"
4
+ - "lib/generators/**/templates/**/*"
8
5
 
9
6
  Metrics/BlockLength:
10
7
  Exclude:
@@ -40,15 +37,9 @@ Layout/CaseIndentation:
40
37
  - end
41
38
  IndentOneStep: true
42
39
 
43
- Layout/AccessModifierIndentation:
44
- EnforcedStyle: outdent
45
-
46
40
  Layout/EndAlignment:
47
41
  EnforcedStyleAlignWith: variable
48
42
 
49
- Style/FrozenStringLiteralComment:
50
- Enabled: true
51
-
52
43
  Style/PercentLiteralDelimiters:
53
44
  PreferredDelimiters:
54
45
  '%w': "[]"
data/.travis.yml CHANGED
@@ -1,21 +1,25 @@
1
1
  language: ruby
2
- before_install:
3
- - gem install bundler -v 1.17.3
2
+ dist: focal
4
3
 
5
4
  matrix:
6
5
  include:
7
- - rvm: 2.5.1 # Pre-installed Ruby version
6
+ - name: "RuboCop lint on pre-installed Ruby version"
7
+ rvm: 2.7.1 # Pre-installed Ruby version
8
+ before_install:
9
+ - gem install bundler
8
10
  script: bundle exec rake rubocop # ONLY lint once, first
9
- - rvm: 2.1
10
- - rvm: 2.2
11
- - rvm: 2.3.5
12
- - rvm: 2.4.6
13
- - rvm: 2.5.5
14
- - rvm: 2.6.3
15
- - rvm: jruby-9.1.8.0
16
- env:
17
- - JRUBY_OPTS="--debug"
18
- jdk: openjdk8
19
- - rvm: jruby-9.2.8.0
11
+ - rvm: 2.6.7
12
+ before_script:
13
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
14
+ - chmod +x ./cc-test-reporter
15
+ - ./cc-test-reporter before-build
16
+ after_script:
17
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
18
+ - rvm: 2.7.3
19
+ - rvm: 3.0.1
20
+ - rvm: jruby-9.2.17.0
20
21
  env:
21
22
  - JRUBY_OPTS="--debug"
23
+ - rvm: truffleruby-head
24
+ allow_failures:
25
+ - rvm: truffleruby-head
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Pundit
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 2.1.1 (2021-08-13)
6
+
7
+ Friday 13th-release!
8
+
9
+ Careful! The bugfix below (#626) could break existing code. If you rely on the
10
+ return value for `authorize` and namespaced policies you might need to do some
11
+ changes.
12
+
13
+ ### Fixed
14
+
15
+ - `.authorize` and `#authorize` return the instance, even for namespaced
16
+ policies (#626)
17
+
18
+ ### Changed
19
+
20
+ - Generate application scope with `protected` attr_readers. (#616)
21
+
22
+ ### Removed
23
+
24
+ - Dropped support for Ruby end-of-life versions: 2.1 and 2.2. (#604)
25
+ - Dropped support for Ruby end-of-life versions: 2.3 (#633)
26
+ - Dropped support for Ruby end-of-life versions: 2.4, 2.5 and JRuby 9.1 (#676)
27
+ - Dropped support for RSpec 2 (#615)
28
+
29
+ ## 2.1.0 (2019-08-14)
30
+
3
31
  ### Fixed
4
32
 
5
33
  - Avoid name clashes with the Error class. (#590)
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  Pundit provides a set of helpers which guide you in leveraging regular Ruby
9
9
  classes and object oriented design patterns to build a simple, robust and
10
- scaleable authorization system.
10
+ scalable authorization system.
11
11
 
12
12
  Links:
13
13
 
@@ -31,7 +31,6 @@ Include Pundit in your application controller:
31
31
  ``` ruby
32
32
  class ApplicationController < ActionController::Base
33
33
  include Pundit
34
- protect_from_forgery
35
34
  end
36
35
  ```
37
36
 
@@ -61,7 +60,7 @@ class PostPolicy
61
60
  end
62
61
 
63
62
  def update?
64
- user.admin? or not post.published?
63
+ user.admin? || !post.published?
65
64
  end
66
65
  end
67
66
  ```
@@ -165,13 +164,18 @@ def admin_list
165
164
  end
166
165
  ```
167
166
 
168
- `authorize` returns the object passed to it, so you can chain it like this:
167
+ `authorize` returns the instance passed to it, so you can chain it like this:
169
168
 
170
169
  Controller:
171
170
  ```ruby
172
171
  def show
173
172
  @user = authorize User.find(params[:id])
174
173
  end
174
+
175
+ # return the record even for namespaced policies
176
+ def show
177
+ @user = authorize [:admin, User.find(params[:id])]
178
+ end
175
179
  ```
176
180
 
177
181
  You can easily get a hold of an instance of the policy through the `policy`
@@ -220,8 +224,6 @@ define a class called a policy scope. It can look something like this:
220
224
  ``` ruby
221
225
  class PostPolicy < ApplicationPolicy
222
226
  class Scope
223
- attr_reader :user, :scope
224
-
225
227
  def initialize(user, scope)
226
228
  @user = user
227
229
  @scope = scope
@@ -234,6 +236,10 @@ class PostPolicy < ApplicationPolicy
234
236
  scope.where(published: true)
235
237
  end
236
238
  end
239
+
240
+ private
241
+
242
+ attr_reader :user, :scope
237
243
  end
238
244
 
239
245
  def update?
@@ -296,13 +302,11 @@ def index
296
302
  end
297
303
  ```
298
304
 
299
- Just as with your policy, this will automatically infer that you want to use
300
- the `PostPolicy::Scope` class, it will instantiate this class and call
301
- `resolve` on the instance. In this case it is a shortcut for doing:
305
+ In this case it is a shortcut for doing:
302
306
 
303
307
  ``` ruby
304
308
  def index
305
- @posts = PostPolicy::Scope.new(current_user, Post).resolve
309
+ @publications = PublicationPolicy::Scope.new(current_user, Post).resolve
306
310
  end
307
311
  ```
308
312
 
@@ -391,6 +395,16 @@ class Post
391
395
  end
392
396
  ```
393
397
 
398
+ Alternatively, you can declare an instance method:
399
+
400
+ ``` ruby
401
+ class Post
402
+ def policy_class
403
+ PostablePolicy
404
+ end
405
+ end
406
+ ```
407
+
394
408
  ## Just plain old Ruby
395
409
 
396
410
  As you can see, Pundit doesn't do anything you couldn't have easily done
@@ -476,7 +490,6 @@ method in every controller.
476
490
 
477
491
  ```ruby
478
492
  class ApplicationController < ActionController::Base
479
- protect_from_forgery
480
493
  include Pundit
481
494
 
482
495
  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
@@ -597,8 +610,7 @@ class Admin::PostController < AdminController
597
610
  end
598
611
 
599
612
  def show
600
- post = Post.find(params[:id])
601
- authorize(post)
613
+ post = authorize Post.find(params[:id])
602
614
  end
603
615
  end
604
616
  ```
@@ -641,9 +653,8 @@ end
641
653
 
642
654
  ## Strong parameters
643
655
 
644
- In Rails 4 (or Rails 3.2 with the
645
- [strong_parameters](https://github.com/rails/strong_parameters) gem),
646
- mass-assignment protection is handled in the controller. With Pundit you can
656
+ In Rails,
657
+ mass-assignment protection is handled in the controller. With Pundit you can
647
658
  control which attributes a user has access to update via your policies. You can
648
659
  set up a `permitted_attributes` method in your policy like this:
649
660
 
@@ -782,6 +793,7 @@ Pundit does not provide a DSL for testing scopes. Just test it like a regular Ru
782
793
  - [RailsApps Example Application: Pundit and Devise](https://github.com/RailsApps/rails-devise-pundit)
783
794
  - [Migrating to Pundit from CanCan](http://blog.carbonfive.com/2013/10/21/migrating-to-pundit-from-cancan/)
784
795
  - [Testing Pundit Policies with RSpec](http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)
796
+ - [Testing Pundit with Minitest](https://github.com/varvet/pundit/issues/204#issuecomment-60166450)
785
797
  - [Using Pundit outside of a Rails controller](https://github.com/varvet/pundit/pull/136)
786
798
  - [Straightforward Rails Authorization with Pundit](http://www.sitepoint.com/straightforward-rails-authorization-with-pundit/)
787
799
 
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pundit
2
4
  module Generators
3
5
  class InstallGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def copy_application_policy
7
- template 'application_policy.rb', 'app/policies/application_policy.rb'
9
+ template "application_policy.rb", "app/policies/application_policy.rb"
8
10
  end
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class ApplicationPolicy
2
4
  attr_reader :user, :record
3
5
 
@@ -35,8 +37,6 @@ class ApplicationPolicy
35
37
  end
36
38
 
37
39
  class Scope
38
- attr_reader :user, :scope
39
-
40
40
  def initialize(user, scope)
41
41
  @user = user
42
42
  @scope = scope
@@ -45,5 +45,9 @@ class ApplicationPolicy
45
45
  def resolve
46
46
  scope.all
47
47
  end
48
+
49
+ private
50
+
51
+ attr_reader :user, :scope
48
52
  end
49
53
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Pundit
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy
7
- template 'policy.rb', File.join('app/policies', class_path, "#{file_name}_policy.rb")
9
+ template "policy.rb", File.join("app/policies", class_path, "#{file_name}_policy.rb")
8
10
  end
9
11
 
10
12
  hook_for :test_framework
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rspec
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy_spec
7
- template 'policy_spec.rb', File.join('spec/policies', class_path, "#{file_name}_policy_spec.rb")
9
+ template "policy_spec.rb", File.join("spec/policies", class_path, "#{file_name}_policy_spec.rb")
8
10
  end
9
11
  end
10
12
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TestUnit
2
4
  module Generators
3
5
  class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path('templates', __dir__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  def create_policy_test
7
- template 'policy_test.rb', File.join('test/policies', class_path, "#{file_name}_policy_test.rb")
9
+ template "policy_test.rb", File.join("test/policies", class_path, "#{file_name}_policy_test.rb")
8
10
  end
9
11
  end
10
12
  end
data/lib/pundit.rb CHANGED
@@ -15,7 +15,7 @@ class Pundit::Error < StandardError; end # rubocop:disable Style/ClassAndModuleC
15
15
 
16
16
  # @api public
17
17
  module Pundit
18
- SUFFIX = "Policy".freeze
18
+ SUFFIX = "Policy"
19
19
 
20
20
  # @api private
21
21
  module Generators; end
@@ -71,7 +71,7 @@ module Pundit
71
71
 
72
72
  raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
73
73
 
74
- record
74
+ record.is_a?(Array) ? record.last : record
75
75
  end
76
76
 
77
77
  # Retrieves the policy scope for the given record.
@@ -124,7 +124,7 @@ module Pundit
124
124
  # @return [Object, nil] instance of policy class with query methods
125
125
  def policy(user, record)
126
126
  policy = PolicyFinder.new(record).policy
127
- policy.new(user, pundit_model(record)) if policy
127
+ policy&.new(user, pundit_model(record))
128
128
  rescue ArgumentError
129
129
  raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
130
130
  end
@@ -144,7 +144,7 @@ module Pundit
144
144
  raise InvalidConstructorError, "Invalid #<#{policy}> constructor is called"
145
145
  end
146
146
 
147
- private
147
+ private
148
148
 
149
149
  def pundit_model(record)
150
150
  record.is_a?(Array) ? record.last : record
@@ -167,7 +167,7 @@ module Pundit
167
167
  end
168
168
  end
169
169
 
170
- protected
170
+ protected
171
171
 
172
172
  # @return [Boolean] whether authorization has been performed, i.e. whether
173
173
  # one {#authorize} or {#skip_authorization} has been called
@@ -222,7 +222,7 @@ protected
222
222
 
223
223
  raise NotAuthorizedError, query: query, record: record, policy: policy unless policy.public_send(query)
224
224
 
225
- record
225
+ record.is_a?(Array) ? record.last : record
226
226
  end
227
227
 
228
228
  # Allow this action not to perform authorization.
@@ -317,7 +317,7 @@ protected
317
317
  current_user
318
318
  end
319
319
 
320
- private
320
+ private
321
321
 
322
322
  def pundit_policy_scope(scope)
323
323
  policy_scopes[scope] ||= Pundit.policy_scope!(pundit_user, scope)
@@ -68,7 +68,7 @@ module Pundit
68
68
  end
69
69
  end
70
70
 
71
- private
71
+ private
72
72
 
73
73
  def find(subject)
74
74
  if subject.is_a?(Array)
data/lib/pundit/rspec.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "active_support/core_ext/array/conversions"
4
-
5
3
  module Pundit
6
4
  module RSpec
7
5
  module Matchers
@@ -74,17 +72,9 @@ module Pundit
74
72
  end
75
73
 
76
74
  RSpec.configure do |config|
77
- if RSpec::Core::Version::STRING.split(".").first.to_i >= 3
78
- config.include(
79
- Pundit::RSpec::PolicyExampleGroup,
80
- type: :policy,
81
- file_path: %r{spec/policies}
82
- )
83
- else
84
- config.include(
85
- Pundit::RSpec::PolicyExampleGroup,
86
- type: :policy,
87
- example_group: { file_path: %r{spec/policies} }
88
- )
89
- end
75
+ config.include(
76
+ Pundit::RSpec::PolicyExampleGroup,
77
+ type: :policy,
78
+ file_path: %r{spec/policies}
79
+ )
90
80
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pundit
4
- VERSION = "2.1.0".freeze
4
+ VERSION = "2.1.1"
5
5
  end
data/pundit.gemspec CHANGED
@@ -25,7 +25,8 @@ Gem::Specification.new do |gem|
25
25
  gem.add_development_dependency "bundler"
26
26
  gem.add_development_dependency "pry"
27
27
  gem.add_development_dependency "rake"
28
- gem.add_development_dependency "rspec", ">= 2.0.0"
29
- gem.add_development_dependency "rubocop", "0.57.2"
28
+ gem.add_development_dependency "rspec", ">= 3.0.0"
29
+ gem.add_development_dependency "rubocop", "0.74.0"
30
+ gem.add_development_dependency "simplecov", ">= 0.17.0"
30
31
  gem.add_development_dependency "yard"
31
32
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe PostPolicy do
5
+ RSpec.describe PostPolicy do
6
6
  let(:user) { double }
7
7
  let(:own_post) { double(user: user) }
8
8
  let(:other_post) { double(user: double) }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Pundit::PolicyFinder do
5
+ RSpec.describe Pundit::PolicyFinder do
6
6
  let(:user) { double }
7
7
  let(:post) { Post.new(user) }
8
8
  let(:comment) { CommentFourFiveSix.new }
@@ -24,37 +24,100 @@ describe Pundit::PolicyFinder do
24
24
  end
25
25
 
26
26
  describe "#policy" do
27
- subject { described_class.new(post) }
27
+ context "with an instance" do
28
+ it "returns the associated policy" do
29
+ object = described_class.new(post)
30
+
31
+ expect(object.policy).to eq PostPolicy
32
+ end
33
+ end
34
+
35
+ context "with an array of symbols" do
36
+ it "returns the associated namespaced policy" do
37
+ object = described_class.new(%i[project post])
38
+
39
+ expect(object.policy).to eq Project::PostPolicy
40
+ end
41
+ end
42
+
43
+ context "with an array of a symbol and an instance" do
44
+ it "returns the associated namespaced policy" do
45
+ object = described_class.new([:project, post])
28
46
 
29
- it "returns a policy" do
30
- expect(subject.policy).to eq PostPolicy
47
+ expect(object.policy).to eq Project::PostPolicy
48
+ end
31
49
  end
32
50
 
33
- context "with a string" do
34
- it "returns a policy" do
35
- allow(subject).to receive(:find).and_return "PostPolicy"
36
- expect(subject.policy).to eq PostPolicy
51
+ context "with an array of a symbol and a class with a specified policy class" do
52
+ it "returns the associated namespaced policy" do
53
+ object = described_class.new([:project, Customer::Post])
54
+
55
+ expect(object.policy).to eq Project::PostPolicy
56
+ end
57
+ end
58
+
59
+ context "with an array of a symbol and a class with a specified model name" do
60
+ it "returns the associated namespaced policy" do
61
+ object = described_class.new([:project, CommentsRelation])
62
+
63
+ expect(object.policy).to eq Project::CommentPolicy
37
64
  end
38
65
  end
39
66
 
40
67
  context "with a class" do
41
- it "returns a policy" do
42
- allow(subject).to receive(:find).and_return PostPolicy
43
- expect(subject.policy).to eq PostPolicy
68
+ it "returns the associated policy" do
69
+ object = described_class.new(Post)
70
+
71
+ expect(object.policy).to eq PostPolicy
72
+ end
73
+ end
74
+
75
+ context "with a class which has a specified policy class" do
76
+ it "returns the associated policy" do
77
+ object = described_class.new(Customer::Post)
78
+
79
+ expect(object.policy).to eq PostPolicy
80
+ end
81
+ end
82
+
83
+ context "with an instance which has a specified policy class" do
84
+ it "returns the associated policy" do
85
+ object = described_class.new(Customer::Post.new(user))
86
+
87
+ expect(object.policy).to eq PostPolicy
88
+ end
89
+ end
90
+
91
+ context "with a class which has a specified model name" do
92
+ it "returns the associated policy" do
93
+ object = described_class.new(CommentsRelation)
94
+
95
+ expect(object.policy).to eq CommentPolicy
96
+ end
97
+ end
98
+
99
+ context "with an instance which has a specified policy class" do
100
+ it "returns the associated policy" do
101
+ object = described_class.new(CommentsRelation.new)
102
+
103
+ expect(object.policy).to eq CommentPolicy
44
104
  end
45
105
  end
46
106
 
47
107
  context "with nil" do
48
- it "returns nil" do
49
- allow(subject).to receive(:find).and_return nil
50
- expect(subject.policy).to eq nil
108
+ it "returns a NilClassPolicy" do
109
+ object = described_class.new(nil)
110
+
111
+ expect(object.policy).to eq NilClassPolicy
51
112
  end
52
113
  end
53
114
 
54
- context "with a string that can't be constantized" do
115
+ context "with a class that doesn't have an associated policy" do
55
116
  it "returns nil" do
56
- allow(subject).to receive(:find).and_return "FooPolicy"
57
- expect(subject.policy).to eq nil
117
+ class Foo; end
118
+ object = described_class.new(Foo)
119
+
120
+ expect(object.policy).to eq nil
58
121
  end
59
122
  end
60
123
  end
data/spec/pundit_spec.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- describe Pundit do
5
+ RSpec.describe Pundit do
6
6
  let(:user) { double }
7
7
  let(:post) { Post.new(user) }
8
8
  let(:customer_post) { Customer::Post.new(user) }
@@ -25,6 +25,26 @@ describe Pundit do
25
25
  expect(Pundit.authorize(user, post, :update?)).to be_truthy
26
26
  end
27
27
 
28
+ it "returns the record on successful authorization" do
29
+ expect(Pundit.authorize(user, post, :update?)).to eq(post)
30
+ end
31
+
32
+ it "returns the record when passed record with namespace " do
33
+ expect(Pundit.authorize(user, [:project, comment], :update?)).to eq(comment)
34
+ end
35
+
36
+ it "returns the record when passed record with nested namespace " do
37
+ expect(Pundit.authorize(user, [:project, :admin, comment], :update?)).to eq(comment)
38
+ end
39
+
40
+ it "returns the policy name symbol when passed record with headless policy" do
41
+ expect(Pundit.authorize(user, :publication, :create?)).to eq(:publication)
42
+ end
43
+
44
+ it "returns the class when passed record not a particular instance" do
45
+ expect(Pundit.authorize(user, Post, :show?)).to eq(Post)
46
+ end
47
+
28
48
  it "can be given a different policy class" do
29
49
  expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
30
50
  end
@@ -410,7 +430,23 @@ describe Pundit do
410
430
  end
411
431
 
412
432
  it "returns the record on successful authorization" do
413
- expect(controller.authorize(post)).to be(post)
433
+ expect(controller.authorize(post)).to eq(post)
434
+ end
435
+
436
+ it "returns the record when passed record with namespace " do
437
+ expect(controller.authorize([:project, comment], :update?)).to eq(comment)
438
+ end
439
+
440
+ it "returns the record when passed record with nested namespace " do
441
+ expect(controller.authorize([:project, :admin, comment], :update?)).to eq(comment)
442
+ end
443
+
444
+ it "returns the policy name symbol when passed record with headless policy" do
445
+ expect(controller.authorize(:publication, :create?)).to eq(:publication)
446
+ end
447
+
448
+ it "returns the class when passed record not a particular instance" do
449
+ expect(controller.authorize(Post, :show?)).to eq(Post)
414
450
  end
415
451
 
416
452
  it "can be given a different permission to check" do
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "simplecov"
4
+ SimpleCov.start do
5
+ add_filter "/spec/"
6
+ end
7
+
3
8
  require "pundit"
4
9
  require "pundit/rspec"
5
10
 
@@ -11,22 +16,6 @@ require "active_support/core_ext"
11
16
  require "active_model/naming"
12
17
  require "action_controller/metal/strong_parameters"
13
18
 
14
- I18n.enforce_available_locales = false
15
-
16
- module PunditSpecHelper
17
- extend RSpec::Matchers::DSL
18
-
19
- matcher :be_truthy do
20
- match do |actual|
21
- actual
22
- end
23
- end
24
- end
25
-
26
- RSpec.configure do |config|
27
- config.include PunditSpecHelper
28
- end
29
-
30
19
  class PostPolicy < Struct.new(:user, :post)
31
20
  class Scope < Struct.new(:user, :scope)
32
21
  def resolve
@@ -86,10 +75,6 @@ module Customer
86
75
  def self.policy_class
87
76
  PostPolicy
88
77
  end
89
-
90
- def policy_class
91
- self.class.policy_class
92
- end
93
78
  end
94
79
  end
95
80
 
@@ -137,7 +122,7 @@ class CommentsRelation
137
122
  @empty
138
123
  end
139
124
 
140
- def model_name
125
+ def self.model_name
141
126
  Comment.model_name
142
127
  end
143
128
  end
@@ -174,6 +159,10 @@ class CriteriaPolicy < Struct.new(:user, :criteria); end
174
159
 
175
160
  module Project
176
161
  class CommentPolicy < Struct.new(:user, :comment)
162
+ def update?
163
+ true
164
+ end
165
+
177
166
  class Scope < Struct.new(:user, :scope)
178
167
  def resolve
179
168
  scope
@@ -190,6 +179,14 @@ module Project
190
179
  end
191
180
  end
192
181
  end
182
+
183
+ module Admin
184
+ class CommentPolicy < Struct.new(:user, :comment)
185
+ def update?
186
+ true
187
+ end
188
+ end
189
+ end
193
190
  end
194
191
 
195
192
  class DenierPolicy < Struct.new(:user, :record)
@@ -201,9 +198,9 @@ end
201
198
  class Controller
202
199
  include Pundit
203
200
  # Mark protected methods public so they may be called in test
204
- # rubocop:disable Layout/AccessModifierIndentation, Style/AccessModifierDeclarations
201
+ # rubocop:disable Style/AccessModifierDeclarations
205
202
  public(*Pundit.protected_instance_methods)
206
- # rubocop:enable Layout/AccessModifierIndentation, Style/AccessModifierDeclarations
203
+ # rubocop:enable Style/AccessModifierDeclarations
207
204
 
208
205
  attr_reader :current_user, :action_name, :params
209
206
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pundit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Nicklas
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-08-14 00:00:00.000000000 Z
12
+ date: 2021-08-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -101,28 +101,42 @@ dependencies:
101
101
  requirements:
102
102
  - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: 2.0.0
104
+ version: 3.0.0
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: 2.0.0
111
+ version: 3.0.0
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: rubocop
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - '='
117
117
  - !ruby/object:Gem::Version
118
- version: 0.57.2
118
+ version: 0.74.0
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - '='
124
124
  - !ruby/object:Gem::Version
125
- version: 0.57.2
125
+ version: 0.74.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: simplecov
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 0.17.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 0.17.0
126
140
  - !ruby/object:Gem::Dependency
127
141
  name: yard
128
142
  requirement: !ruby/object:Gem::Requirement
@@ -194,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
208
  - !ruby/object:Gem::Version
195
209
  version: '0'
196
210
  requirements: []
197
- rubygems_version: 3.0.3
211
+ rubygems_version: 3.2.25
198
212
  signing_key:
199
213
  specification_version: 4
200
214
  summary: OO authorization for Rails