pundit_assertions 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0d5de5bdd6a032e18432811b7061fa42b20cb76b5e7a348177c825319ad4f672
4
+ data.tar.gz: d766c710ac4bd35985bab3cc57b069fda3dc981e19e090cfb87b9e2bcb3f39cb
5
+ SHA512:
6
+ metadata.gz: 96afe86a57e8fcab2a1ca56aebce5398b6d76f25cba3a11479786b4a562a1eb87be85ff59b465320f7218a4b2461588a926b2a0ef5ab70e9cc2c00634b9163b1
7
+ data.tar.gz: 68238d5f429a88c664d1695e042596c6a4c30a33f726b0abe7473cd394880a30f4566cae42ec848c99b24a0a28a787d7496570aa29e1cbb48e43eeef5444d048
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.1
3
+ NewCops: enable
4
+
5
+ Style/ClassAndModuleChildren:
6
+ Enabled: false
7
+ Style/HashEachMethods:
8
+ Enabled: true
9
+ Style/HashTransformKeys:
10
+ Enabled: true
11
+ Style/HashTransformValues:
12
+ Enabled: true
13
+ Style/ExponentialNotation:
14
+ Enabled: true
15
+ Style/SlicingWithRange:
16
+ Enabled: true
17
+ Style/RedundantFetchBlock:
18
+ Enabled: true
19
+ Style/RedundantRegexpCharacterClass:
20
+ Enabled: true
21
+ Style/RedundantRegexpEscape:
22
+ Enabled: true
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-11-26
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Tree company
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # PunditAssertions
2
+
3
+ A simple gem to make testing [Pundit](https://github.com/varvet/pundit) policies easier. This provides a set of assertions
4
+
5
+ We deduce the relevant based on the name of the test class: We assume that `CommentPolicy` gets tested in `CommentPolicyTest`, `Admin::CommentPolicy` in `Admin::CommentPolicyTest`, ...
6
+
7
+ ## Installation
8
+
9
+ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ ```bash
14
+ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
15
+ ```
16
+
17
+ If bundler is not being used to manage dependencies, install the gem by executing:
18
+
19
+ ```bash
20
+ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
21
+ ```
22
+
23
+ You can include the test helpers in all tests, or include this in a specific file:
24
+ ```ruby
25
+ require 'pundit_assertions'
26
+
27
+ module ActiveSupport
28
+ class TestCase
29
+ include PunditAssertions::TestHelpers
30
+ end
31
+ end
32
+ ```
33
+
34
+ ```ruby
35
+ require 'pundit_assertions'
36
+
37
+ class CommentPolicyTest < ActiveSupport::TestCase
38
+ include PunditAssertions::TestHelpers
39
+ end
40
+ ```
41
+
42
+ ## Usage
43
+ We provide a bunch of custom assertions to help you validate your policies:
44
+ ```ruby
45
+ class CommentPolicyTest < ActiveSupport::TestCase
46
+ setup do
47
+ @user = User.new
48
+ @comment = Comment.new
49
+ end
50
+
51
+ test 'should only allow index for user' do
52
+ assert_permitted @user, @comment, :index
53
+ assert_not_permitted nil, @comment, :index
54
+ end
55
+
56
+ test 'should allow permitted attributes for user' do
57
+ assert_permitted_attributes @user, @comment
58
+ assert_no_permitted_attributes nil, @comment
59
+ end
60
+
61
+ test 'should only allow private attribute on create' do
62
+ assert_attribute_permitted @user, @comment, :private, :create
63
+ assert_not_attribute_permitted @user, @comment, :private, :update
64
+ end
65
+
66
+ test 'should scope comments that belong to user' do
67
+ users_comment = Comment.create!(user: @user)
68
+ other_comment = Comment.create!(user: User.new)
69
+
70
+ assert_scope_includes @user, users_comment
71
+ assert_scope_not_includes @user, other_comment
72
+ assert_scope_empty @user, Comment
73
+ end
74
+ end
75
+ ```
76
+
77
+ For every `assert_not_`, there is also a `refute_` variant.
78
+
79
+ ## Development
80
+
81
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
82
+
83
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
84
+
85
+ ## Contributing
86
+
87
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tree-company/pundit_assertions.
88
+
89
+ ## License
90
+
91
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'minitest/test_task'
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test rubocop]
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PunditAssertions
4
+ ##
5
+ # A set of assertions to use in minitest
6
+ #
7
+ # This module should be included in your test class to use these assertions
8
+ module TestHelpers
9
+ ##
10
+ # Assert whether a user is permitted to perform an action
11
+ def assert_permitted(user, record, action)
12
+ msg = "User #{user.inspect} should be permitted to #{action} #{record}, but isn't permitted"
13
+
14
+ assert permitted?(user, record, action), msg
15
+ end
16
+
17
+ ##
18
+ # Assert whether a user is not permitted to perform an action
19
+ def assert_not_permitted(user, record, action)
20
+ msg = "User #{user.inspect} should NOT be permitted to #{action} #{record}, but is permitted"
21
+
22
+ refute permitted?(user, record, action), msg
23
+ end
24
+
25
+ alias refute_permitted assert_not_permitted
26
+
27
+ ##
28
+ # Return whether a user is permitted to perform an action
29
+ def permitted?(user, record, action)
30
+ policy_class.new(user, record).public_send(:"#{action}?")
31
+ end
32
+
33
+ ##
34
+ # Assert whether a user will have any attributes permitted
35
+ def assert_permitted_attributes(user, record, action = nil)
36
+ refute_empty permitted_attributes(user, record, action)
37
+ end
38
+
39
+ ##
40
+ # Assert whether a user will have no attributes permitted
41
+ def assert_no_permitted_attributes(user, record, action = nil)
42
+ assert_nil permitted_attributes(user, record, action)
43
+ end
44
+
45
+ ##
46
+ # Assert whether a user will have all of the specified attributes permitted
47
+ # You can specify a specific action
48
+ def assert_attributes_permitted(user, record, attributes, action = nil)
49
+ attributes = [attributes] unless attributes.is_a?(Array)
50
+ permitted = permitted_attributes(user, record, action)
51
+ permitted = [] if permitted.nil?
52
+
53
+ assert_empty attributes - permitted
54
+ end
55
+
56
+ ##
57
+ # Assert whether a user will not have any the specified attributes permitted
58
+ def assert_not_attributes_permitted(user, record, attributes, action = nil)
59
+ attributes = [attributes] unless attributes.is_a?(Array)
60
+ permitted = permitted_attributes(user, record, action)
61
+ permitted = [] if permitted.nil?
62
+
63
+ assert_equal attributes.length, (attributes - permitted).length
64
+ end
65
+
66
+ ##
67
+ # Return the permitted attributes
68
+ def permitted_attributes(user, record, action = nil)
69
+ policy = policy_class.new(user, record)
70
+ method = :permitted_attributes
71
+ if !action.nil? && policy.respond_to?(:"permitted_attributes_for_#{action}")
72
+ method = :"permitted_attributes_for_#{action}"
73
+ end
74
+
75
+ policy.send(method)
76
+ end
77
+
78
+ ##
79
+ # Return the scoped records for a user and a klass
80
+ def scope(user, klass)
81
+ result = scope_class.new(user, klass).resolve
82
+
83
+ refute_nil result
84
+ result
85
+ end
86
+
87
+ ##
88
+ # Assert whether a user will have the specified records in scope
89
+ def assert_scope_includes(user, *records)
90
+ records.flatten.each do |record|
91
+ assert_includes scope(user, record.class), record
92
+ end
93
+ end
94
+
95
+ ##
96
+ # Assert whether a user will not have the specified records in scope
97
+ def assert_scope_not_includes(user, *records)
98
+ records.flatten.each do |record|
99
+ result = scope(user, record.class)
100
+
101
+ assert result.nil? || !result.include?(record)
102
+ end
103
+ end
104
+
105
+ alias refute_scope_includes assert_scope_not_includes
106
+
107
+ ##
108
+ # Assert whether the scope for a user is empty
109
+ def assert_scope_empty(user, klass)
110
+ assert_empty scope(user, klass)
111
+ end
112
+
113
+ # This assumes this test is happening inside ModelPolicyTest
114
+ def policy_class
115
+ Object.const_get(self.class.to_s.gsub('Test', ''))
116
+ end
117
+
118
+ # This assumes this test is happening inside ModelPolicyTest or ModelPolicyTest::Scope
119
+ def scope_class
120
+ klass = self.class.to_s.gsub('Test', '')
121
+ klass << '::Scope' unless klass.match?(/::Scope$/)
122
+ Object.const_get(klass)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PunditAssertions
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'pundit_assertions/version'
4
+ require_relative 'pundit_assertions/test_helpers'
5
+
6
+ ##
7
+ # Set of assertions to test pundit policies
8
+ module PunditAssertions
9
+ end
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pundit_assertions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Robbe Van Petegem
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-11-26 00:00:00.000000000 Z
11
+ dependencies: []
12
+ email:
13
+ - git@robbevp.be
14
+ executables: []
15
+ extensions: []
16
+ extra_rdoc_files: []
17
+ files:
18
+ - ".rubocop.yml"
19
+ - CHANGELOG.md
20
+ - LICENSE.txt
21
+ - README.md
22
+ - Rakefile
23
+ - lib/pundit_assertions.rb
24
+ - lib/pundit_assertions/test_helpers.rb
25
+ - lib/pundit_assertions/version.rb
26
+ homepage: https://github.com/tree-company/pundit_assertions
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ homepage_uri: https://github.com/tree-company/pundit_assertions
31
+ source_code_uri: https://github.com/tree-company/pundit_assertions
32
+ changelog_uri: https://github.com/tree-company/pundit_assertions/blob/main/CHANGELOG.md
33
+ rubygems_mfa_required: 'true'
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 3.1.0
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubygems_version: 3.6.6
49
+ specification_version: 4
50
+ summary: A simple set of minitest assertion to help test pundit policies.
51
+ test_files: []