pundit 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Pundit::Authorization do
6
+ let(:controller) { Controller.new(user, "update", {}) }
7
+ let(:user) { double }
8
+ let(:post) { Post.new(user) }
9
+ let(:customer_post) { Customer::Post.new(user) }
10
+ let(:comment) { Comment.new }
11
+ let(:article) { Article.new }
12
+ let(:article_tag) { ArticleTag.new }
13
+ let(:wiki) { Wiki.new }
14
+
15
+ describe "#verify_authorized" do
16
+ it "does nothing when authorized" do
17
+ controller.authorize(post)
18
+ controller.verify_authorized
19
+ end
20
+
21
+ it "raises an exception when not authorized" do
22
+ expect { controller.verify_authorized }.to raise_error(Pundit::AuthorizationNotPerformedError)
23
+ end
24
+ end
25
+
26
+ describe "#verify_policy_scoped" do
27
+ it "does nothing when policy_scope is used" do
28
+ controller.policy_scope(Post)
29
+ controller.verify_policy_scoped
30
+ end
31
+
32
+ it "raises an exception when policy_scope is not used" do
33
+ expect { controller.verify_policy_scoped }.to raise_error(Pundit::PolicyScopingNotPerformedError)
34
+ end
35
+ end
36
+
37
+ describe "#pundit_policy_authorized?" do
38
+ it "is true when authorized" do
39
+ controller.authorize(post)
40
+ expect(controller.pundit_policy_authorized?).to be true
41
+ end
42
+
43
+ it "is false when not authorized" do
44
+ expect(controller.pundit_policy_authorized?).to be false
45
+ end
46
+ end
47
+
48
+ describe "#pundit_policy_scoped?" do
49
+ it "is true when policy_scope is used" do
50
+ controller.policy_scope(Post)
51
+ expect(controller.pundit_policy_scoped?).to be true
52
+ end
53
+
54
+ it "is false when policy scope is not used" do
55
+ expect(controller.pundit_policy_scoped?).to be false
56
+ end
57
+ end
58
+
59
+ describe "#authorize" do
60
+ it "infers the policy name and authorizes based on it" do
61
+ expect(controller.authorize(post)).to be_truthy
62
+ end
63
+
64
+ it "returns the record on successful authorization" do
65
+ expect(controller.authorize(post)).to eq(post)
66
+ end
67
+
68
+ it "returns the record when passed record with namespace " do
69
+ expect(controller.authorize([:project, comment], :update?)).to eq(comment)
70
+ end
71
+
72
+ it "returns the record when passed record with nested namespace " do
73
+ expect(controller.authorize([:project, :admin, comment], :update?)).to eq(comment)
74
+ end
75
+
76
+ it "returns the policy name symbol when passed record with headless policy" do
77
+ expect(controller.authorize(:publication, :create?)).to eq(:publication)
78
+ end
79
+
80
+ it "returns the class when passed record not a particular instance" do
81
+ expect(controller.authorize(Post, :show?)).to eq(Post)
82
+ end
83
+
84
+ it "can be given a different permission to check" do
85
+ expect(controller.authorize(post, :show?)).to be_truthy
86
+ expect { controller.authorize(post, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
87
+ end
88
+
89
+ it "can be given a different policy class" do
90
+ expect(controller.authorize(post, :create?, policy_class: PublicationPolicy)).to be_truthy
91
+ end
92
+
93
+ it "works with anonymous class policies" do
94
+ expect(controller.authorize(article_tag, :show?)).to be_truthy
95
+ expect { controller.authorize(article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
96
+ end
97
+
98
+ it "throws an exception when the permission check fails" do
99
+ expect { controller.authorize(Post.new) }.to raise_error(Pundit::NotAuthorizedError)
100
+ end
101
+
102
+ it "throws an exception when a policy cannot be found" do
103
+ expect { controller.authorize(Article) }.to raise_error(Pundit::NotDefinedError)
104
+ end
105
+
106
+ it "caches the policy" do
107
+ expect(controller.policies[post]).to be_nil
108
+ controller.authorize(post)
109
+ expect(controller.policies[post]).not_to be_nil
110
+ end
111
+
112
+ it "raises an error when the given record is nil" do
113
+ expect { controller.authorize(nil, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
114
+ end
115
+
116
+ it "raises an error with a invalid policy constructor" do
117
+ expect { controller.authorize(wiki, :destroy?) }.to raise_error(Pundit::InvalidConstructorError)
118
+ end
119
+ end
120
+
121
+ describe "#skip_authorization" do
122
+ it "disables authorization verification" do
123
+ controller.skip_authorization
124
+ expect { controller.verify_authorized }.not_to raise_error
125
+ end
126
+ end
127
+
128
+ describe "#skip_policy_scope" do
129
+ it "disables policy scope verification" do
130
+ controller.skip_policy_scope
131
+ expect { controller.verify_policy_scoped }.not_to raise_error
132
+ end
133
+ end
134
+
135
+ describe "#pundit_user" do
136
+ it "returns the same thing as current_user" do
137
+ expect(controller.pundit_user).to eq controller.current_user
138
+ end
139
+ end
140
+
141
+ describe "#policy" do
142
+ it "returns an instantiated policy" do
143
+ policy = controller.policy(post)
144
+ expect(policy.user).to eq user
145
+ expect(policy.post).to eq post
146
+ end
147
+
148
+ it "throws an exception if the given policy can't be found" do
149
+ expect { controller.policy(article) }.to raise_error(Pundit::NotDefinedError)
150
+ end
151
+
152
+ it "raises an error with a invalid policy constructor" do
153
+ expect { controller.policy(wiki) }.to raise_error(Pundit::InvalidConstructorError)
154
+ end
155
+
156
+ it "allows policy to be injected" do
157
+ new_policy = OpenStruct.new
158
+ controller.policies[post] = new_policy
159
+
160
+ expect(controller.policy(post)).to eq new_policy
161
+ end
162
+ end
163
+
164
+ describe "#policy_scope" do
165
+ it "returns an instantiated policy scope" do
166
+ expect(controller.policy_scope(Post)).to eq :published
167
+ end
168
+
169
+ it "allows policy scope class to be overriden" do
170
+ expect(controller.policy_scope(Post, policy_scope_class: PublicationPolicy::Scope)).to eq :published
171
+ end
172
+
173
+ it "throws an exception if the given policy can't be found" do
174
+ expect { controller.policy_scope(Article) }.to raise_error(Pundit::NotDefinedError)
175
+ end
176
+
177
+ it "raises an error with a invalid policy scope constructor" do
178
+ expect { controller.policy_scope(Wiki) }.to raise_error(Pundit::InvalidConstructorError)
179
+ end
180
+
181
+ it "allows policy_scope to be injected" do
182
+ new_scope = OpenStruct.new
183
+ controller.policy_scopes[Post] = new_scope
184
+
185
+ expect(controller.policy_scope(Post)).to eq new_scope
186
+ end
187
+ end
188
+
189
+ describe "#permitted_attributes" do
190
+ it "checks policy for permitted attributes" do
191
+ params = ActionController::Parameters.new(
192
+ post: {
193
+ title: "Hello",
194
+ votes: 5,
195
+ admin: true
196
+ }
197
+ )
198
+
199
+ action = "update"
200
+
201
+ expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq(
202
+ "title" => "Hello",
203
+ "votes" => 5
204
+ )
205
+ expect(Controller.new(double, action, params).permitted_attributes(post).to_h).to eq("votes" => 5)
206
+ end
207
+
208
+ it "checks policy for permitted attributes for record of a ActiveModel type" do
209
+ params = ActionController::Parameters.new(
210
+ customer_post: {
211
+ title: "Hello",
212
+ votes: 5,
213
+ admin: true
214
+ }
215
+ )
216
+
217
+ action = "update"
218
+
219
+ expect(Controller.new(user, action, params).permitted_attributes(customer_post).to_h).to eq(
220
+ "title" => "Hello",
221
+ "votes" => 5
222
+ )
223
+ expect(Controller.new(double, action, params).permitted_attributes(customer_post).to_h).to eq(
224
+ "votes" => 5
225
+ )
226
+ end
227
+ end
228
+
229
+ describe "#permitted_attributes_for_action" do
230
+ it "is checked if it is defined in the policy" do
231
+ params = ActionController::Parameters.new(
232
+ post: {
233
+ title: "Hello",
234
+ body: "blah",
235
+ votes: 5,
236
+ admin: true
237
+ }
238
+ )
239
+
240
+ action = "revise"
241
+ expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq("body" => "blah")
242
+ end
243
+
244
+ it "can be explicitly set" do
245
+ params = ActionController::Parameters.new(
246
+ post: {
247
+ title: "Hello",
248
+ body: "blah",
249
+ votes: 5,
250
+ admin: true
251
+ }
252
+ )
253
+
254
+ action = "update"
255
+ expect(Controller.new(user, action, params).permitted_attributes(post, :revise).to_h).to eq("body" => "blah")
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "tmpdir"
5
+
6
+ require "rails/generators"
7
+ require "generators/pundit/install/install_generator"
8
+ require "generators/pundit/policy/policy_generator"
9
+
10
+ RSpec.describe "generators" do
11
+ before(:all) do
12
+ @tmpdir = Dir.mktmpdir
13
+
14
+ Dir.chdir(@tmpdir) do
15
+ Pundit::Generators::InstallGenerator.new([], { quiet: true }).invoke_all
16
+ Pundit::Generators::PolicyGenerator.new(%w[Widget], { quiet: true }).invoke_all
17
+
18
+ require "./app/policies/application_policy"
19
+ require "./app/policies/widget_policy"
20
+ end
21
+ end
22
+
23
+ after(:all) do
24
+ FileUtils.remove_entry(@tmpdir)
25
+ end
26
+
27
+ describe "WidgetPolicy", type: :policy do
28
+ permissions :index?, :show?, :create?, :new?, :update?, :edit?, :destroy? do
29
+ it "has safe defaults" do
30
+ expect(WidgetPolicy).not_to permit(double("User"), double("Widget"))
31
+ end
32
+ end
33
+
34
+ describe "WidgetPolicy::Scope" do
35
+ describe "#resolve" do
36
+ it "raises a descriptive error" do
37
+ scope = WidgetPolicy::Scope.new(double("User"), double("User.all"))
38
+ expect { scope.resolve }.to raise_error(NotImplementedError, /WidgetPolicy::Scope/)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ class Foo; end
5
6
  RSpec.describe Pundit::PolicyFinder do
6
7
  let(:user) { double }
7
8
  let(:post) { Post.new(user) }
@@ -114,7 +115,6 @@ RSpec.describe Pundit::PolicyFinder do
114
115
 
115
116
  context "with a class that doesn't have an associated policy" do
116
117
  it "returns nil" do
117
- class Foo; end
118
118
  object = described_class.new(Foo)
119
119
 
120
120
  expect(object.policy).to eq nil
data/spec/pundit_spec.rb CHANGED
@@ -10,15 +10,13 @@ RSpec.describe Pundit do
10
10
  let(:comment) { Comment.new }
11
11
  let(:comment_four_five_six) { CommentFourFiveSix.new }
12
12
  let(:article) { Article.new }
13
- let(:controller) { Controller.new(user, "update", {}) }
14
13
  let(:artificial_blog) { ArtificialBlog.new }
15
14
  let(:article_tag) { ArticleTag.new }
16
- let(:comments_relation) { CommentsRelation.new }
17
- let(:empty_comments_relation) { CommentsRelation.new(true) }
15
+ let(:comments_relation) { CommentsRelation.new(empty: false) }
16
+ let(:empty_comments_relation) { CommentsRelation.new(empty: true) }
18
17
  let(:tag_four_five_six) { ProjectOneTwoThree::TagFourFiveSix.new(user) }
19
18
  let(:avatar_four_five_six) { ProjectOneTwoThree::AvatarFourFiveSix.new }
20
19
  let(:wiki) { Wiki.new }
21
- let(:thread) { Thread.new }
22
20
 
23
21
  describe ".authorize" do
24
22
  it "infers the policy and authorizes based on it" do
@@ -49,6 +47,11 @@ RSpec.describe Pundit do
49
47
  expect(Pundit.authorize(user, post, :create?, policy_class: PublicationPolicy)).to be_truthy
50
48
  end
51
49
 
50
+ it "can be given a different policy class using namespaces" do
51
+ expect(PublicationPolicy).to receive(:new).with(user, comment).and_call_original
52
+ expect(Pundit.authorize(user, [:project, comment], :create?, policy_class: PublicationPolicy)).to be_truthy
53
+ end
54
+
52
55
  it "works with anonymous class policies" do
53
56
  expect(Pundit.authorize(user, article_tag, :show?)).to be_truthy
54
57
  expect { Pundit.authorize(user, article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
@@ -66,6 +69,18 @@ RSpec.describe Pundit do
66
69
  # rubocop:enable Style/MultilineBlockChain
67
70
  end
68
71
 
72
+ it "raises an error with a the record, query and action when the record is namespaced" do
73
+ # rubocop:disable Style/MultilineBlockChain
74
+ expect do
75
+ Pundit.authorize(user, [:project, :admin, comment], :destroy?)
76
+ end.to raise_error(Pundit::NotAuthorizedError, "not allowed to destroy? this Comment") do |error|
77
+ expect(error.query).to eq :destroy?
78
+ expect(error.record).to eq comment
79
+ expect(error.policy).to eq Pundit.policy(user, [:project, :admin, comment])
80
+ end
81
+ # rubocop:enable Style/MultilineBlockChain
82
+ end
83
+
69
84
  it "raises an error with a invalid policy constructor" do
70
85
  expect do
71
86
  Pundit.authorize(user, wiki, :update?)
@@ -380,247 +395,26 @@ RSpec.describe Pundit do
380
395
  end
381
396
  end
382
397
 
383
- describe "#verify_authorized" do
384
- it "does nothing when authorized" do
385
- controller.authorize(post)
386
- controller.verify_authorized
387
- end
388
-
389
- it "raises an exception when not authorized" do
390
- expect { controller.verify_authorized }.to raise_error(Pundit::AuthorizationNotPerformedError)
391
- end
392
- end
393
-
394
- describe "#verify_policy_scoped" do
395
- it "does nothing when policy_scope is used" do
396
- controller.policy_scope(Post)
397
- controller.verify_policy_scoped
398
- end
399
-
400
- it "raises an exception when policy_scope is not used" do
401
- expect { controller.verify_policy_scoped }.to raise_error(Pundit::PolicyScopingNotPerformedError)
402
- end
403
- end
404
-
405
- describe "#pundit_policy_authorized?" do
406
- it "is true when authorized" do
407
- controller.authorize(post)
408
- expect(controller.pundit_policy_authorized?).to be true
409
- end
410
-
411
- it "is false when not authorized" do
412
- expect(controller.pundit_policy_authorized?).to be false
413
- end
414
- end
415
-
416
- describe "#pundit_policy_scoped?" do
417
- it "is true when policy_scope is used" do
418
- controller.policy_scope(Post)
419
- expect(controller.pundit_policy_scoped?).to be true
420
- end
421
-
422
- it "is false when policy scope is not used" do
423
- expect(controller.pundit_policy_scoped?).to be false
424
- end
425
- end
426
-
427
- describe "#authorize" do
428
- it "infers the policy name and authorizes based on it" do
429
- expect(controller.authorize(post)).to be_truthy
430
- end
431
-
432
- it "returns the record on successful authorization" do
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)
450
- end
451
-
452
- it "can be given a different permission to check" do
453
- expect(controller.authorize(post, :show?)).to be_truthy
454
- expect { controller.authorize(post, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
455
- end
456
-
457
- it "can be given a different policy class" do
458
- expect(controller.authorize(post, :create?, policy_class: PublicationPolicy)).to be_truthy
459
- end
460
-
461
- it "works with anonymous class policies" do
462
- expect(controller.authorize(article_tag, :show?)).to be_truthy
463
- expect { controller.authorize(article_tag, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
464
- end
465
-
466
- it "throws an exception when the permission check fails" do
467
- expect { controller.authorize(Post.new) }.to raise_error(Pundit::NotAuthorizedError)
468
- end
469
-
470
- it "throws an exception when a policy cannot be found" do
471
- expect { controller.authorize(Article) }.to raise_error(Pundit::NotDefinedError)
472
- end
473
-
474
- it "caches the policy" do
475
- expect(controller.policies[post]).to be_nil
476
- controller.authorize(post)
477
- expect(controller.policies[post]).not_to be_nil
478
- end
479
-
480
- it "raises an error when the given record is nil" do
481
- expect { controller.authorize(nil, :destroy?) }.to raise_error(Pundit::NotAuthorizedError)
482
- end
483
-
484
- it "raises an error with a invalid policy constructor" do
485
- expect { controller.authorize(wiki, :destroy?) }.to raise_error(Pundit::InvalidConstructorError)
486
- end
487
- end
488
-
489
- describe "#skip_authorization" do
490
- it "disables authorization verification" do
491
- controller.skip_authorization
492
- expect { controller.verify_authorized }.not_to raise_error
493
- end
494
- end
495
-
496
- describe "#skip_policy_scope" do
497
- it "disables policy scope verification" do
498
- controller.skip_policy_scope
499
- expect { controller.verify_policy_scoped }.not_to raise_error
500
- end
501
- end
398
+ describe ".included" do
399
+ it "includes Authorization module" do
400
+ klass = Class.new
502
401
 
503
- describe "#pundit_user" do
504
- it "returns the same thing as current_user" do
505
- expect(controller.pundit_user).to eq controller.current_user
506
- end
507
- end
508
-
509
- describe "#policy" do
510
- it "returns an instantiated policy" do
511
- policy = controller.policy(post)
512
- expect(policy.user).to eq user
513
- expect(policy.post).to eq post
514
- end
515
-
516
- it "throws an exception if the given policy can't be found" do
517
- expect { controller.policy(article) }.to raise_error(Pundit::NotDefinedError)
518
- end
519
-
520
- it "raises an error with a invalid policy constructor" do
521
- expect { controller.policy(wiki) }.to raise_error(Pundit::InvalidConstructorError)
522
- end
523
-
524
- it "allows policy to be injected" do
525
- new_policy = OpenStruct.new
526
- controller.policies[post] = new_policy
527
-
528
- expect(controller.policy(post)).to eq new_policy
529
- end
530
- end
531
-
532
- describe "#policy_scope" do
533
- it "returns an instantiated policy scope" do
534
- expect(controller.policy_scope(Post)).to eq :published
535
- end
536
-
537
- it "allows policy scope class to be overriden" do
538
- expect(controller.policy_scope(Post, policy_scope_class: PublicationPolicy::Scope)).to eq :published
539
- end
540
-
541
- it "throws an exception if the given policy can't be found" do
542
- expect { controller.policy_scope(Article) }.to raise_error(Pundit::NotDefinedError)
543
- end
402
+ ActiveSupport::Deprecation.silence do
403
+ klass.include Pundit
404
+ end
544
405
 
545
- it "raises an error with a invalid policy scope constructor" do
546
- expect { controller.policy_scope(Wiki) }.to raise_error(Pundit::InvalidConstructorError)
406
+ expect(klass).to include Pundit::Authorization
547
407
  end
548
408
 
549
- it "allows policy_scope to be injected" do
550
- new_scope = OpenStruct.new
551
- controller.policy_scopes[Post] = new_scope
409
+ it "warns about deprecation" do
410
+ klass = Class.new
411
+ allow(ActiveSupport::Deprecation).to receive(:warn)
552
412
 
553
- expect(controller.policy_scope(Post)).to eq new_scope
554
- end
555
- end
556
-
557
- describe "#permitted_attributes" do
558
- it "checks policy for permitted attributes" do
559
- params = ActionController::Parameters.new(
560
- post: {
561
- title: "Hello",
562
- votes: 5,
563
- admin: true
564
- }
565
- )
566
-
567
- action = "update"
568
-
569
- expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq(
570
- "title" => "Hello",
571
- "votes" => 5
572
- )
573
- expect(Controller.new(double, action, params).permitted_attributes(post).to_h).to eq("votes" => 5)
574
- end
575
-
576
- it "checks policy for permitted attributes for record of a ActiveModel type" do
577
- params = ActionController::Parameters.new(
578
- customer_post: {
579
- title: "Hello",
580
- votes: 5,
581
- admin: true
582
- }
583
- )
584
-
585
- action = "update"
586
-
587
- expect(Controller.new(user, action, params).permitted_attributes(customer_post).to_h).to eq(
588
- "title" => "Hello",
589
- "votes" => 5
590
- )
591
- expect(Controller.new(double, action, params).permitted_attributes(customer_post).to_h).to eq(
592
- "votes" => 5
593
- )
594
- end
595
- end
413
+ ActiveSupport::Deprecation.silence do
414
+ klass.include Pundit
415
+ end
596
416
 
597
- describe "#permitted_attributes_for_action" do
598
- it "is checked if it is defined in the policy" do
599
- params = ActionController::Parameters.new(
600
- post: {
601
- title: "Hello",
602
- body: "blah",
603
- votes: 5,
604
- admin: true
605
- }
606
- )
607
-
608
- action = "revise"
609
- expect(Controller.new(user, action, params).permitted_attributes(post).to_h).to eq("body" => "blah")
610
- end
611
-
612
- it "can be explicitly set" do
613
- params = ActionController::Parameters.new(
614
- post: {
615
- title: "Hello",
616
- body: "blah",
617
- votes: 5,
618
- admin: true
619
- }
620
- )
621
-
622
- action = "update"
623
- expect(Controller.new(user, action, params).permitted_attributes(post, :revise).to_h).to eq("body" => "blah")
417
+ expect(ActiveSupport::Deprecation).to have_received(:warn).with start_with("'include Pundit' is deprecated")
624
418
  end
625
419
  end
626
420
 
data/spec/spec_helper.rb CHANGED
@@ -80,6 +80,7 @@ end
80
80
 
81
81
  class CommentScope
82
82
  attr_reader :original_object
83
+
83
84
  def initialize(original_object)
84
85
  @original_object = original_object
85
86
  end
@@ -114,7 +115,7 @@ class Comment
114
115
  end
115
116
 
116
117
  class CommentsRelation
117
- def initialize(empty = false)
118
+ def initialize(empty: false)
118
119
  @empty = empty
119
120
  end
120
121
 
@@ -185,6 +186,10 @@ module Project
185
186
  def update?
186
187
  true
187
188
  end
189
+
190
+ def destroy?
191
+ false
192
+ end
188
193
  end
189
194
  end
190
195
  end
@@ -196,10 +201,10 @@ class DenierPolicy < Struct.new(:user, :record)
196
201
  end
197
202
 
198
203
  class Controller
199
- include Pundit
204
+ include Pundit::Authorization
200
205
  # Mark protected methods public so they may be called in test
201
206
  # rubocop:disable Style/AccessModifierDeclarations
202
- public(*Pundit.protected_instance_methods)
207
+ public(*Pundit::Authorization.protected_instance_methods)
203
208
  # rubocop:enable Style/AccessModifierDeclarations
204
209
 
205
210
  attr_reader :current_user, :action_name, :params
@@ -228,6 +233,7 @@ class NilClassPolicy < Struct.new(:user, :record)
228
233
  end
229
234
 
230
235
  class Wiki; end
236
+
231
237
  class WikiPolicy
232
238
  class Scope
233
239
  # deliberate typo method
@@ -238,6 +244,7 @@ end
238
244
  class Thread
239
245
  def self.all; end
240
246
  end
247
+
241
248
  class ThreadPolicy < Struct.new(:user, :thread)
242
249
  class Scope < Struct.new(:user, :scope)
243
250
  def resolve