simple_authorize 0.1.0 โ†’ 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79902cf5162234cb48b57c7a0584265292141771e59594199c7adee9dea7b1c7
4
- data.tar.gz: 3022a11895f81c9a02918d88bb1929c4c75afb13eec0b0315e36cbdbaecc0745
3
+ metadata.gz: 705f75951bbd55e8352217a91088812ddb17a0914f5674c2e04c3ff5623d0f28
4
+ data.tar.gz: 94af211cac4be86bac47e46d1f2e06ae6342d4d5fbc7bf0e41fe5e9f82591287
5
5
  SHA512:
6
- metadata.gz: 24db25e4450b4f5cb060b902f6bb99b9544aaf39397757ad0403b2feeb4ee99a678632219eec710cce36c0923fad9cb0da9465e85fa9edf60de7028e99a524a9
7
- data.tar.gz: 2cffd9ff55d8a33d6093297d8c2beea976403cdf5c2d0c5b77a1f40990fff673ee43c763264964d721be1d97c68d74190bbf35c4674419ee6da999ea19a25262
6
+ metadata.gz: 56b1be714196ca98cdced6ea2556e64c5086be5b4ed923eee1434cc939252fea1ac72fe905cb0b2e035db45075d3b91f373f139b64b32d78a3449d558f481374
7
+ data.tar.gz: bd6f0bb6cf73dfcfbd8dde7e0be6a08d0073fa3f23ca7c18121a626c84c83692fc0f3bd2e1efb25131a132e22c188682eb30f99aa5370e05303104526eaecc0d
data/.simplecov ADDED
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ SimpleCov.start do
4
+ add_filter "/test/"
5
+ add_filter "/spec/"
6
+ add_filter "/lib/generators/"
7
+ add_filter "/lib/simple_authorize/railtie.rb"
8
+
9
+ # Merge results from multiple test runs
10
+ use_merging true
11
+ merge_timeout 3600 # 1 hour
12
+
13
+ # Don't enforce minimum yet
14
+ # minimum_coverage line: 95, branch: 90
15
+ end
data/CHANGELOG.md CHANGED
@@ -8,6 +8,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
  ### Added
11
+ - Policy generator (`rails g simple_authorize:policy ModelName`) with support for:
12
+ - Namespaced models (e.g., `Admin::Post`)
13
+ - RSpec or Minitest test generation
14
+ - Automatic test scaffolding with CRUD and scope tests
15
+ - Policy caching for performance optimization:
16
+ - Request-level memoization of policy instances
17
+ - Automatic scoping by user, record, and policy class
18
+ - Configurable via `config.enable_policy_cache`
19
+ - `clear_policy_cache` method for manual cache clearing
20
+ - Automatic cache clearing in `reset_authorization` for tests
21
+ - Instrumentation and audit logging via ActiveSupport::Notifications:
22
+ - Emits events for `authorize`, `authorize_headless`, and `policy_scope` calls
23
+ - Rich payload with user, record, query, result, and timing information
24
+ - Enabled by default, configurable via `config.enable_instrumentation`
25
+ - Perfect for security audits, debugging, and monitoring
11
26
  - Initial release of SimpleAuthorize
12
27
  - Policy-based authorization system
13
28
  - Controller concern with authorization methods
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2025 Scott
3
+ Copyright (c) 2025 Scott LaPlant
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,32 +1,44 @@
1
1
  # SimpleAuthorize
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/simple_authorize.svg)](https://badge.fury.io/rb/simple_authorize)
3
+ [![Gem Version](https://img.shields.io/gem/v/simple_authorize.svg)](https://rubygems.org/gems/simple_authorize)
4
4
  [![Ruby](https://github.com/scottlaplant/simple_authorize/workflows/Ruby/badge.svg)](https://github.com/scottlaplant/simple_authorize/actions)
5
+ [![Downloads](https://img.shields.io/gem/dt/simple_authorize.svg)](https://rubygems.org/gems/simple_authorize)
5
6
 
6
7
  SimpleAuthorize is a lightweight, powerful authorization framework for Rails that provides policy-based access control without external dependencies. Inspired by Pundit, it offers a clean API for managing permissions in your Rails applications.
7
8
 
8
9
  ## Features
9
10
 
10
- - ๐Ÿ”’ **Policy-Based Authorization** - Define authorization rules in dedicated policy classes
11
- - ๐ŸŽฏ **Scope Filtering** - Automatically filter collections based on user permissions
12
- - ๐Ÿ”‘ **Role-Based Access** - Built-in support for role-based authorization
13
- - ๐Ÿš€ **Zero Dependencies** - No external gems required (only Rails)
14
- - โœ… **Strong Parameters Integration** - Automatically build permitted params from policies
15
- - ๐Ÿงช **Test Friendly** - Easy to test policies in isolation
16
- - ๐Ÿ“ **Rails Generators** - Quickly scaffold policies for your models
11
+ - **Policy-Based Authorization** - Define authorization rules in dedicated policy classes
12
+ - **Scope Filtering** - Automatically filter collections based on user permissions
13
+ - **Role-Based Access** - Built-in support for role-based authorization
14
+ - **Zero Dependencies** - No external gems required (only Rails)
15
+ - **Strong Parameters Integration** - Automatically build permitted params from policies
16
+ - **Test Friendly** - Easy to test policies in isolation
17
+ - **Rails Generators** - Quickly scaffold policies for your models
17
18
 
18
19
  ## Installation
19
20
 
20
- Add this line to your application's Gemfile:
21
+ Install the gem directly:
22
+
23
+ ```bash
24
+ gem install simple_authorize
25
+ ```
26
+
27
+ Or add this line to your application's Gemfile:
21
28
 
22
29
  ```ruby
23
30
  gem 'simple_authorize'
24
31
  ```
25
32
 
26
- And then execute:
33
+ Then execute:
27
34
 
28
35
  ```bash
29
36
  bundle install
37
+ ```
38
+
39
+ After installation, run the generator to set up your application:
40
+
41
+ ```bash
30
42
  rails generate simple_authorize:install
31
43
  ```
32
44
 
@@ -47,7 +59,17 @@ end
47
59
 
48
60
  ### 2. Create a Policy
49
61
 
50
- Create a policy class for your model in `app/policies/`:
62
+ Generate a policy for your model using the generator:
63
+
64
+ ```bash
65
+ rails generate simple_authorize:policy Post
66
+ ```
67
+
68
+ This creates:
69
+ - `app/policies/post_policy.rb` - Policy class with CRUD methods
70
+ - `test/policies/post_policy_test.rb` - Test file (or spec file with `--spec`)
71
+
72
+ Or create a policy class manually in `app/policies/`:
51
73
 
52
74
  ```ruby
53
75
  # app/policies/post_policy.rb
@@ -197,6 +219,181 @@ def post_params
197
219
  end
198
220
  ```
199
221
 
222
+ ## Generators
223
+
224
+ SimpleAuthorize provides Rails generators to quickly scaffold policies:
225
+
226
+ ### Install Generator
227
+
228
+ ```bash
229
+ rails generate simple_authorize:install
230
+ ```
231
+
232
+ Creates:
233
+ - `config/initializers/simple_authorize.rb` - Configuration file
234
+ - `app/policies/application_policy.rb` - Base policy class
235
+
236
+ ### Policy Generator
237
+
238
+ ```bash
239
+ rails generate simple_authorize:policy Post
240
+ ```
241
+
242
+ Creates:
243
+ - `app/policies/post_policy.rb` - Policy with CRUD methods and scope
244
+ - `test/policies/post_policy_test.rb` - Minitest tests
245
+
246
+ **Options:**
247
+ - `--spec` - Generate RSpec tests instead of Minitest
248
+ - `--skip-test` - Skip test file generation
249
+
250
+ **Examples:**
251
+
252
+ ```bash
253
+ # Generate policy with RSpec tests
254
+ rails generate simple_authorize:policy Post --spec
255
+
256
+ # Generate policy without tests
257
+ rails generate simple_authorize:policy Post --skip-test
258
+
259
+ # Generate namespaced policy
260
+ rails generate simple_authorize:policy Admin::Post
261
+ ```
262
+
263
+ ## Configuration
264
+
265
+ SimpleAuthorize can be configured in `config/initializers/simple_authorize.rb`:
266
+
267
+ ### Policy Caching
268
+
269
+ Enable policy caching to improve performance by caching policy instances per request:
270
+
271
+ ```ruby
272
+ SimpleAuthorize.configure do |config|
273
+ config.enable_policy_cache = true
274
+ end
275
+ ```
276
+
277
+ **How it works:**
278
+ - Policy instances are cached for the duration of a single request
279
+ - Cache is automatically scoped by user, record, and policy class
280
+ - Each unique combination gets its own cached instance
281
+ - Cache is automatically cleared between requests
282
+ - Particularly useful in views where the same policy may be checked multiple times
283
+
284
+ **Example performance impact:**
285
+
286
+ ```erb
287
+ <!-- Without caching: Creates 3 separate PostPolicy instances -->
288
+ <% if policy(@post).update? %>
289
+ <%= link_to "Edit", edit_post_path(@post) %>
290
+ <% end %>
291
+ <% if policy(@post).destroy? %>
292
+ <%= link_to "Delete", post_path(@post) %>
293
+ <% end %>
294
+ <% if policy(@post).publish? %>
295
+ <%= link_to "Publish", publish_post_path(@post) %>
296
+ <% end %>
297
+
298
+ <!-- With caching: Reuses the same PostPolicy instance -->
299
+ ```
300
+
301
+ **Testing:**
302
+ Use `clear_policy_cache` or `reset_authorization` to clear the cache in tests:
303
+
304
+ ```ruby
305
+ test "multiple checks use cached policy" do
306
+ SimpleAuthorize.configure { |config| config.enable_policy_cache = true }
307
+
308
+ policy1 = policy(@post)
309
+ policy2 = policy(@post)
310
+ assert_same policy1, policy2 # Same instance
311
+
312
+ clear_policy_cache
313
+ policy3 = policy(@post)
314
+ refute_same policy1, policy3 # New instance after clearing
315
+ end
316
+ ```
317
+
318
+ ### Instrumentation & Audit Logging
319
+
320
+ SimpleAuthorize emits `ActiveSupport::Notifications` events for all authorization checks, perfect for security auditing, debugging, and monitoring:
321
+
322
+ ```ruby
323
+ # Subscribe to authorization events
324
+ ActiveSupport::Notifications.subscribe("authorize.simple_authorize") do |name, start, finish, id, payload|
325
+ duration = finish - start
326
+
327
+ Rails.logger.info({
328
+ event: "authorization",
329
+ user_id: payload[:user_id],
330
+ action: payload[:query],
331
+ resource: "#{payload[:record_class]}##{payload[:record_id]}",
332
+ authorized: payload[:authorized],
333
+ duration_ms: (duration * 1000).round(2)
334
+ }.to_json)
335
+ end
336
+
337
+ # Subscribe to policy scope events
338
+ ActiveSupport::Notifications.subscribe("policy_scope.simple_authorize") do |name, start, finish, id, payload|
339
+ Rails.logger.info("Policy scope applied for #{payload[:scope]} by user #{payload[:user_id]}")
340
+ end
341
+ ```
342
+
343
+ **Event Payloads:**
344
+
345
+ Authorization events (`authorize.simple_authorize`):
346
+ - `user`: Current user object
347
+ - `user_id`: User ID
348
+ - `record`: The record being authorized
349
+ - `record_id`: Record ID
350
+ - `record_class`: Record class name
351
+ - `query`: Authorization method called (e.g., "update?")
352
+ - `policy_class`: Policy class used
353
+ - `authorized`: Boolean result
354
+ - `error`: Exception if authorization failed
355
+ - `controller`: Controller name (if available)
356
+ - `action`: Action name (if available)
357
+
358
+ Policy scope events (`policy_scope.simple_authorize`):
359
+ - `user`: Current user object
360
+ - `user_id`: User ID
361
+ - `scope`: The scope being filtered
362
+ - `policy_scope_class`: Scope class used
363
+ - `error`: Exception if scope failed
364
+ - `controller`: Controller name (if available)
365
+ - `action`: Action name (if available)
366
+
367
+ **Use Cases:**
368
+ - Security auditing and compliance
369
+ - Debugging authorization issues
370
+ - Monitoring authorization performance
371
+ - Sending failed authorization attempts to security services
372
+ - Tracking which users access sensitive resources
373
+
374
+ **Disable instrumentation** (if needed for performance in specific scenarios):
375
+
376
+ ```ruby
377
+ SimpleAuthorize.configure do |config|
378
+ config.enable_instrumentation = false
379
+ end
380
+ ```
381
+
382
+ ### Other Configuration Options
383
+
384
+ ```ruby
385
+ SimpleAuthorize.configure do |config|
386
+ # Custom error message for unauthorized access
387
+ config.default_error_message = "Access denied!"
388
+
389
+ # Custom redirect path for unauthorized users
390
+ config.unauthorized_redirect_path = "/access-denied"
391
+
392
+ # Custom method to get current user (default: current_user)
393
+ config.current_user_method = :authenticated_user
394
+ end
395
+ ```
396
+
200
397
  ## Advanced Features
201
398
 
202
399
  ### Headless Policies
@@ -284,7 +481,7 @@ end
284
481
 
285
482
  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.
286
483
 
287
- 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).
484
+ To install this gem onto your local machine, run `bundle exec rake install`.
288
485
 
289
486
  ## Comparison with Pundit
290
487
 
@@ -316,6 +513,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
316
513
 
317
514
  ## Credits
318
515
 
319
- Created by Scott LaPlant
320
-
321
- Inspired by [Pundit](https://github.com/varvet/pundit) by Elabs
516
+ SimpleAuthorize is heavily inspired by [Pundit](https://github.com/varvet/pundit) by Elabs. We're grateful to the Pundit team for pioneering this authorization pattern.
data/SECURITY.md ADDED
@@ -0,0 +1,73 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ We release patches for security vulnerabilities. Currently supported versions:
6
+
7
+ | Version | Supported |
8
+ | ------- | ------------------ |
9
+ | 0.1.x | :white_check_mark: |
10
+
11
+ ## Reporting a Vulnerability
12
+
13
+ We take the security of SimpleAuthorize seriously. If you discover a security vulnerability, please report it privately.
14
+
15
+ ### How to Report
16
+
17
+ 1. **DO NOT** open a public GitHub issue for security vulnerabilities
18
+ 2. Use GitHub's private vulnerability reporting feature (see "Security" tab in the repository)
19
+
20
+ ### What to Include
21
+
22
+ Please include the following information in your report:
23
+
24
+ - Type of vulnerability (e.g., authorization bypass, XSS, injection)
25
+ - Full paths of source files related to the vulnerability
26
+ - The location of the affected source code (tag/branch/commit or direct URL)
27
+ - Step-by-step instructions to reproduce the issue
28
+ - Proof-of-concept or exploit code (if possible)
29
+ - Impact of the issue, including how an attacker might exploit it
30
+
31
+ ### Response Timeline
32
+
33
+ - **Initial Response**: Within 48 hours of receiving your report
34
+ - **Status Update**: Within 5 business days with an initial assessment
35
+ - **Fix Timeline**: Critical vulnerabilities will be addressed within 30 days
36
+ - **Disclosure**: We will coordinate with you on the disclosure timeline
37
+
38
+ ### Security Update Process
39
+
40
+ 1. We will confirm the vulnerability and determine its severity
41
+ 2. We will develop and test a fix
42
+ 3. We will release a new version with the security patch
43
+ 4. We will publish a security advisory with details after the fix is released
44
+ 5. We will credit you for the discovery (unless you prefer to remain anonymous)
45
+
46
+ ## Security Best Practices
47
+
48
+ When using SimpleAuthorize in your application:
49
+
50
+ 1. **Always verify authorization**: Use `verify_authorized` in controllers to ensure authorization is checked
51
+ 2. **Secure policy defaults**: The default Policy class denies all actions - only permit what's necessary
52
+ 3. **Test your policies**: Write comprehensive tests for all authorization logic
53
+ 4. **Keep updated**: Regularly update to the latest version to get security patches
54
+ 5. **Review policies**: Periodically audit your policy classes for authorization holes
55
+
56
+ ## Known Security Considerations
57
+
58
+ ### Authorization Bypass Prevention
59
+
60
+ - Always call `authorize` before performing sensitive actions
61
+ - Use `skip_authorization` explicitly and only when intentional
62
+ - Be careful with `headless_policy` - ensure proper authorization for non-resource actions
63
+
64
+ ### Scope Security
65
+
66
+ - Always use `policy_scope` to filter collections
67
+ - Don't rely solely on view-level hiding - enforce at the data layer
68
+ - Test scope filtering with different user roles
69
+
70
+ ## Dependencies
71
+
72
+ SimpleAuthorize has minimal dependencies (only Rails/ActiveSupport). We monitor our dependencies for security vulnerabilities and update promptly.
73
+
@@ -4,6 +4,7 @@ require "rails/generators"
4
4
 
5
5
  module SimpleAuthorize
6
6
  module Generators
7
+ # Rails generator to install SimpleAuthorize configuration and base policy
7
8
  class InstallGenerator < Rails::Generators::Base
8
9
  source_root File.expand_path("templates", __dir__)
9
10
 
@@ -13,4 +13,12 @@ SimpleAuthorize.configure do |config|
13
13
 
14
14
  # Custom redirect path for unauthorized access (default: uses referrer or root_path)
15
15
  # config.unauthorized_redirect_path = "/unauthorized"
16
+
17
+ # Enable policy caching for performance optimization (default: false)
18
+ # When enabled, policy instances are cached per request, scoped by user, record, and policy class
19
+ # config.enable_policy_cache = true
20
+
21
+ # Enable instrumentation for authorization events (default: true)
22
+ # When enabled, emits ActiveSupport::Notifications events for all authorization checks
23
+ # config.enable_instrumentation = true
16
24
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/named_base"
4
+
5
+ module SimpleAuthorize
6
+ module Generators
7
+ # Rails generator to create a policy class for a model
8
+ class PolicyGenerator < Rails::Generators::NamedBase
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ desc "Creates a SimpleAuthorize policy class for a model"
12
+
13
+ argument :name, type: :string, required: true, banner: "ModelName"
14
+
15
+ class_option :spec, type: :boolean, default: false, desc: "Generate RSpec test file instead of Minitest"
16
+ class_option :skip_test, type: :boolean, default: false, desc: "Skip generating test file"
17
+
18
+ def create_policy_file
19
+ template "policy.rb.tt", File.join("app/policies", class_path, "#{file_name}_policy.rb")
20
+ end
21
+
22
+ def create_test_file
23
+ return if options[:skip_test]
24
+
25
+ if options[:spec]
26
+ template "policy_spec.rb.tt", File.join("spec/policies", class_path, "#{file_name}_policy_spec.rb")
27
+ else
28
+ template "policy_test.rb.tt", File.join("test/policies", class_path, "#{file_name}_policy_test.rb")
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def policy_class_name
35
+ "#{class_name}Policy"
36
+ end
37
+
38
+ def model_class_name
39
+ class_name
40
+ end
41
+
42
+ def model_instance_name
43
+ file_name
44
+ end
45
+
46
+ def namespaced_policy_class
47
+ if class_path.empty?
48
+ policy_class_name
49
+ else
50
+ "#{class_path.map(&:camelize).join("::")}::#{policy_class_name}"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ <% if class_path.any? -%>
4
+ module <%= class_path.map(&:camelize).join('::') %>
5
+ <% end -%>
6
+ class <%= policy_class_name %> < ApplicationPolicy
7
+ def index?
8
+ false
9
+ end
10
+
11
+ def show?
12
+ false
13
+ end
14
+
15
+ def create?
16
+ false
17
+ end
18
+
19
+ def update?
20
+ false
21
+ end
22
+
23
+ def destroy?
24
+ false
25
+ end
26
+
27
+ def permitted_attributes
28
+ []
29
+ end
30
+
31
+ class Scope < ApplicationPolicy::Scope
32
+ def resolve
33
+ scope.all
34
+ end
35
+ end
36
+ end
37
+ <% if class_path.any? -%>
38
+ end
39
+ <% end -%>
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+
5
+ <% if class_path.any? -%>
6
+ module <%= class_path.map(&:camelize).join('::') %>
7
+ <% end -%>
8
+ RSpec.describe <%= policy_class_name %>, type: :policy do
9
+ subject(:policy) { described_class.new(user, <%= model_instance_name %>) }
10
+
11
+ let(:user) { User.new }
12
+ let(:<%= model_instance_name %>) { <%= model_class_name %>.new }
13
+
14
+ describe "#index?" do
15
+ it "denies access by default" do
16
+ expect(policy).not_to permit_action(:index)
17
+ end
18
+
19
+ # TODO: Add your authorization logic tests
20
+ end
21
+
22
+ describe "#show?" do
23
+ it "denies access by default" do
24
+ expect(policy).not_to permit_action(:show)
25
+ end
26
+
27
+ # TODO: Add your authorization logic tests
28
+ end
29
+
30
+ describe "#create?" do
31
+ it "denies access by default" do
32
+ expect(policy).not_to permit_action(:create)
33
+ end
34
+
35
+ # TODO: Add your authorization logic tests
36
+ end
37
+
38
+ describe "#update?" do
39
+ it "denies access by default" do
40
+ expect(policy).not_to permit_action(:update)
41
+ end
42
+
43
+ # TODO: Add your authorization logic tests
44
+ end
45
+
46
+ describe "#destroy?" do
47
+ it "denies access by default" do
48
+ expect(policy).not_to permit_action(:destroy)
49
+ end
50
+
51
+ # TODO: Add your authorization logic tests
52
+ end
53
+
54
+ describe "#permitted_attributes" do
55
+ it "returns empty array by default" do
56
+ expect(policy.permitted_attributes).to eq([])
57
+ end
58
+
59
+ # TODO: Add your permitted attributes tests
60
+ end
61
+
62
+ describe "Scope" do
63
+ subject(:scope) { <%= namespaced_policy_class %>::Scope.new(user, <%= model_class_name %>.all) }
64
+
65
+ it "returns all records by default" do
66
+ # TODO: Add your scope tests
67
+ expect(scope.resolve).to eq(<%= model_class_name %>.all)
68
+ end
69
+ end
70
+ end
71
+ <% if class_path.any? -%>
72
+ end
73
+ <% end -%>
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ <% if class_path.any? -%>
6
+ module <%= class_path.map(&:camelize).join('::') %>
7
+ <% end -%>
8
+ class <%= policy_class_name %>Test < ActiveSupport::TestCase
9
+ def setup
10
+ @user = User.new
11
+ @<%= model_instance_name %> = <%= model_class_name %>.new
12
+ end
13
+
14
+ test "index?" do
15
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
16
+
17
+ # TODO: Add your authorization logic tests
18
+ refute policy.index?
19
+ end
20
+
21
+ test "show?" do
22
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
23
+
24
+ # TODO: Add your authorization logic tests
25
+ refute policy.show?
26
+ end
27
+
28
+ test "create?" do
29
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
30
+
31
+ # TODO: Add your authorization logic tests
32
+ refute policy.create?
33
+ end
34
+
35
+ test "update?" do
36
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
37
+
38
+ # TODO: Add your authorization logic tests
39
+ refute policy.update?
40
+ end
41
+
42
+ test "destroy?" do
43
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
44
+
45
+ # TODO: Add your authorization logic tests
46
+ refute policy.destroy?
47
+ end
48
+
49
+ test "scope" do
50
+ # TODO: Add your scope tests
51
+ # For example:
52
+ # scope = <%= namespaced_policy_class %>::Scope.new(@user, <%= model_class_name %>.all)
53
+ # assert_equal expected_records, scope.resolve
54
+ end
55
+
56
+ test "permitted_attributes" do
57
+ policy = <%= namespaced_policy_class %>.new(@user, @<%= model_instance_name %>)
58
+
59
+ # TODO: Add your permitted attributes tests
60
+ assert_equal [], policy.permitted_attributes
61
+ end
62
+ end
63
+ <% if class_path.any? -%>
64
+ end
65
+ <% end -%>