bullet 6.1.0 → 7.0.3
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 +4 -4
- data/.github/workflows/main.yml +82 -0
- data/CHANGELOG.md +45 -0
- data/Gemfile.rails-6.0 +1 -1
- data/Gemfile.rails-6.1 +15 -0
- data/Gemfile.rails-7.0 +10 -0
- data/README.md +37 -25
- data/lib/bullet/active_job.rb +5 -1
- data/lib/bullet/active_record41.rb +1 -0
- data/lib/bullet/active_record42.rb +1 -0
- data/lib/bullet/active_record5.rb +1 -1
- data/lib/bullet/active_record52.rb +23 -18
- data/lib/bullet/active_record60.rb +23 -18
- data/lib/bullet/active_record61.rb +272 -0
- data/lib/bullet/active_record70.rb +275 -0
- data/lib/bullet/bullet_xhr.js +18 -17
- data/lib/bullet/dependency.rb +16 -0
- data/lib/bullet/detector/base.rb +2 -1
- data/lib/bullet/detector/counter_cache.rb +2 -2
- data/lib/bullet/detector/n_plus_one_query.rb +5 -5
- data/lib/bullet/detector/unused_eager_loading.rb +2 -2
- data/lib/bullet/mongoid4x.rb +1 -1
- data/lib/bullet/mongoid5x.rb +1 -1
- data/lib/bullet/mongoid6x.rb +1 -1
- data/lib/bullet/mongoid7x.rb +24 -7
- data/lib/bullet/notification.rb +2 -1
- data/lib/bullet/rack.rb +28 -19
- data/lib/bullet/stack_trace_filter.rb +7 -9
- data/lib/bullet/version.rb +1 -1
- data/lib/bullet.rb +29 -28
- data/lib/generators/bullet/install_generator.rb +22 -25
- data/perf/benchmark.rb +4 -1
- data/spec/bullet/detector/counter_cache_spec.rb +1 -1
- data/spec/bullet/detector/n_plus_one_query_spec.rb +1 -1
- data/spec/bullet/detector/unused_eager_loading_spec.rb +10 -10
- data/spec/bullet/ext/object_spec.rb +1 -1
- data/spec/bullet/notification/base_spec.rb +4 -4
- data/spec/bullet/notification/n_plus_one_query_spec.rb +1 -3
- data/spec/bullet/rack_spec.rb +135 -9
- data/spec/bullet_spec.rb +15 -15
- data/spec/integration/active_record/association_spec.rb +64 -10
- data/spec/integration/counter_cache_spec.rb +4 -4
- data/spec/integration/mongoid/association_spec.rb +4 -4
- data/spec/models/attachment.rb +5 -0
- data/spec/models/deal.rb +5 -0
- data/spec/models/folder.rb +2 -1
- data/spec/models/group.rb +2 -1
- data/spec/models/page.rb +2 -1
- data/spec/models/post.rb +2 -0
- data/spec/models/role.rb +7 -0
- data/spec/models/submission.rb +1 -0
- data/spec/models/user.rb +2 -0
- data/spec/models/writer.rb +2 -1
- data/spec/spec_helper.rb +0 -2
- data/spec/support/mongo_seed.rb +1 -0
- data/spec/support/sqlite_seed.rb +38 -0
- data/test.sh +2 -0
- metadata +17 -7
- data/.travis.yml +0 -33
data/spec/bullet/rack_spec.rb
CHANGED
@@ -31,12 +31,6 @@ module Bullet
|
|
31
31
|
response = double(body: '<html><head></head><body></body></html>')
|
32
32
|
expect(middleware).not_to be_html_request(headers, response)
|
33
33
|
end
|
34
|
-
|
35
|
-
it "should be false if response body doesn't contain html tag" do
|
36
|
-
headers = { 'Content-Type' => 'text/html' }
|
37
|
-
response = double(body: '<div>Partial</div>')
|
38
|
-
expect(middleware).not_to be_html_request(headers, response)
|
39
|
-
end
|
40
34
|
end
|
41
35
|
|
42
36
|
context 'empty?' do
|
@@ -54,6 +48,11 @@ module Bullet
|
|
54
48
|
response = double(body: '')
|
55
49
|
expect(middleware).to be_empty(response)
|
56
50
|
end
|
51
|
+
|
52
|
+
it 'should be true if no response body' do
|
53
|
+
response = double()
|
54
|
+
expect(middleware).to be_empty(response)
|
55
|
+
end
|
57
56
|
end
|
58
57
|
|
59
58
|
context '#call' do
|
@@ -67,9 +66,8 @@ module Bullet
|
|
67
66
|
|
68
67
|
it 'should change response body if notification is active' do
|
69
68
|
expect(Bullet).to receive(:notification?).and_return(true)
|
70
|
-
|
69
|
+
expect(Bullet).to receive(:console_enabled?).and_return(true)
|
71
70
|
expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
|
72
|
-
expect(middleware).to receive(:xhr_script).and_return('')
|
73
71
|
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
74
72
|
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
75
73
|
expect(headers['Content-Length']).to eq('56')
|
@@ -81,9 +79,123 @@ module Bullet
|
|
81
79
|
response.body = '<html><head></head><body>é</body></html>'
|
82
80
|
app.response = response
|
83
81
|
expect(Bullet).to receive(:notification?).and_return(true)
|
82
|
+
allow(Bullet).to receive(:console_enabled?).and_return(true)
|
84
83
|
expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
|
85
84
|
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
86
|
-
expect(headers['Content-Length']).to eq(
|
85
|
+
expect(headers['Content-Length']).to eq('58')
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'with injection notifiers' do
|
89
|
+
before do
|
90
|
+
expect(Bullet).to receive(:notification?).and_return(true)
|
91
|
+
allow(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
|
92
|
+
allow(middleware).to receive(:xhr_script).and_return('<script></script>')
|
93
|
+
allow(middleware).to receive(:footer_note).and_return('footer')
|
94
|
+
expect(Bullet).to receive(:perform_out_of_channel_notifications)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should change response body if add_footer is true' do
|
98
|
+
expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
|
99
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
100
|
+
|
101
|
+
expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
|
102
|
+
expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet><script></script></body></html>])
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should change response body for html safe string if add_footer is true' do
|
106
|
+
expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
|
107
|
+
app.response =
|
108
|
+
Support::ResponseDouble.new.tap do |response|
|
109
|
+
response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
|
110
|
+
end
|
111
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
112
|
+
|
113
|
+
expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
|
114
|
+
expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet><script></script></body></html>])
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should add the footer-text header for non-html requests when add_footer is true' do
|
118
|
+
allow(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
|
119
|
+
allow(Bullet).to receive(:footer_info).and_return(['footer text'])
|
120
|
+
app.headers = { 'Content-Type' => 'application/json' }
|
121
|
+
_, headers, _response = middleware.call({})
|
122
|
+
expect(headers).to include('X-bullet-footer-text' => '["footer text"]')
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should change response body if console_enabled is true' do
|
126
|
+
expect(Bullet).to receive(:console_enabled?).and_return(true)
|
127
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
128
|
+
expect(headers['Content-Length']).to eq('56')
|
129
|
+
expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should change response body for html safe string if console_enabled is true' do
|
133
|
+
expect(Bullet).to receive(:console_enabled?).and_return(true)
|
134
|
+
app.response =
|
135
|
+
Support::ResponseDouble.new.tap do |response|
|
136
|
+
response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
|
137
|
+
end
|
138
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
139
|
+
expect(headers['Content-Length']).to eq('56')
|
140
|
+
expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should add headers for non-html requests when console_enabled is true' do
|
144
|
+
allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
|
145
|
+
allow(Bullet).to receive(:text_notifications).and_return(['text notifications'])
|
146
|
+
app.headers = { 'Content-Type' => 'application/json' }
|
147
|
+
_, headers, _response = middleware.call({})
|
148
|
+
expect(headers).to include('X-bullet-console-text' => '["text notifications"]')
|
149
|
+
end
|
150
|
+
|
151
|
+
it "shouldn't change response body unnecessarily" do
|
152
|
+
expected_response = Support::ResponseDouble.new 'Actual body'
|
153
|
+
app.response = expected_response
|
154
|
+
_, _, response = middleware.call({})
|
155
|
+
expect(response).to eq(expected_response)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "shouldn't add headers unnecessarily" do
|
159
|
+
app.headers = { 'Content-Type' => 'application/json' }
|
160
|
+
_, headers, _response = middleware.call({})
|
161
|
+
expect(headers).not_to include('X-bullet-footer-text')
|
162
|
+
expect(headers).not_to include('X-bullet-console-text')
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when skip_http_headers is enabled' do
|
166
|
+
before do
|
167
|
+
allow(Bullet).to receive(:skip_http_headers).and_return(true)
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should include the footer but not the xhr script tag if add_footer is true' do
|
171
|
+
expect(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
|
172
|
+
_, headers, response = middleware.call({})
|
173
|
+
|
174
|
+
expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
|
175
|
+
expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet></body></html>])
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should not include the xhr script tag if console_enabled is true' do
|
179
|
+
expect(Bullet).to receive(:console_enabled?).and_return(true)
|
180
|
+
_, headers, response = middleware.call({})
|
181
|
+
expect(headers['Content-Length']).to eq('56')
|
182
|
+
expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should not add the footer-text header for non-html requests when add_footer is true' do
|
186
|
+
allow(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
|
187
|
+
app.headers = { 'Content-Type' => 'application/json' }
|
188
|
+
_, headers, _response = middleware.call({})
|
189
|
+
expect(headers).not_to include('X-bullet-footer-text')
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should not add headers for non-html requests when console_enabled is true' do
|
193
|
+
allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
|
194
|
+
app.headers = { 'Content-Type' => 'application/json' }
|
195
|
+
_, headers, _response = middleware.call({})
|
196
|
+
expect(headers).not_to include('X-bullet-console-text')
|
197
|
+
end
|
198
|
+
end
|
87
199
|
end
|
88
200
|
|
89
201
|
context 'when skip_html_injection is enabled' do
|
@@ -148,6 +260,20 @@ module Bullet
|
|
148
260
|
expect(middleware.response_body(response)).to eq body_string
|
149
261
|
end
|
150
262
|
end
|
263
|
+
|
264
|
+
begin
|
265
|
+
require 'rack/files'
|
266
|
+
|
267
|
+
context 'when `response` is a Rack::Files::Iterator' do
|
268
|
+
let(:response) { instance_double(::Rack::Files::Iterator) }
|
269
|
+
before { allow(response).to receive(:is_a?).with(::Rack::Files::Iterator) { true } }
|
270
|
+
|
271
|
+
it 'should return nil' do
|
272
|
+
expect(middleware.response_body(response)).to be_nil
|
273
|
+
end
|
274
|
+
end
|
275
|
+
rescue LoadError
|
276
|
+
end
|
151
277
|
end
|
152
278
|
end
|
153
279
|
end
|
data/spec/bullet_spec.rb
CHANGED
@@ -74,31 +74,31 @@ describe Bullet, focused: true do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe '#
|
77
|
+
describe '#add_safelist' do
|
78
78
|
context "for 'special' class names" do
|
79
|
-
it 'is added to the
|
80
|
-
Bullet.
|
81
|
-
expect(Bullet.
|
79
|
+
it 'is added to the safelist successfully' do
|
80
|
+
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
81
|
+
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to include :department
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
describe '#
|
86
|
+
describe '#delete_safelist' do
|
87
87
|
context "for 'special' class names" do
|
88
|
-
it 'is deleted from the
|
89
|
-
Bullet.
|
90
|
-
Bullet.
|
91
|
-
expect(Bullet.
|
88
|
+
it 'is deleted from the safelist successfully' do
|
89
|
+
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
90
|
+
Bullet.delete_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
91
|
+
expect(Bullet.safelist[:n_plus_one_query]).to eq({})
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
context 'when exists multiple definitions' do
|
96
|
-
it 'is deleted from the
|
97
|
-
Bullet.
|
98
|
-
Bullet.
|
99
|
-
Bullet.
|
100
|
-
expect(Bullet.
|
101
|
-
expect(Bullet.
|
96
|
+
it 'is deleted from the safelist successfully' do
|
97
|
+
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :department)
|
98
|
+
Bullet.add_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :team)
|
99
|
+
Bullet.delete_safelist(type: :n_plus_one_query, class_name: 'Klass', association: :team)
|
100
|
+
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to include :department
|
101
|
+
expect(Bullet.get_safelist_associations(:n_plus_one_query, 'Klass')).to_not include :team
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
@@ -129,7 +129,7 @@ if active_record?
|
|
129
129
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
130
130
|
end
|
131
131
|
|
132
|
-
it 'should detect unused preload with post =>
|
132
|
+
it 'should detect unused preload with post => comments, no category => posts' do
|
133
133
|
Category.includes(posts: :comments).each { |category| category.posts.map(&:name) }
|
134
134
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
135
135
|
expect(Bullet::Detector::Association).to be_unused_preload_associations_for(Post, :comments)
|
@@ -202,7 +202,7 @@ if active_record?
|
|
202
202
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
203
203
|
end
|
204
204
|
|
205
|
-
it 'should detect preload with post =>
|
205
|
+
it 'should detect preload with post => comments' do
|
206
206
|
Post.first.comments.map(&:name)
|
207
207
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
208
208
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
@@ -377,8 +377,7 @@ if active_record?
|
|
377
377
|
it 'should detect unused preload with comment => author' do
|
378
378
|
Comment.includes([:author, { post: :writer }]).where(['base_users.id = ?', BaseUser.first]).references(
|
379
379
|
:base_users
|
380
|
-
)
|
381
|
-
.each { |comment| comment.post.writer.name }
|
380
|
+
).each { |comment| comment.post.writer.name }
|
382
381
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
383
382
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
384
383
|
|
@@ -402,6 +401,15 @@ if active_record?
|
|
402
401
|
end
|
403
402
|
|
404
403
|
describe Bullet::Detector::Association, 'has_and_belongs_to_many' do
|
404
|
+
context 'posts <=> deals' do
|
405
|
+
it 'should detect preload associations with join tables that have identifier' do
|
406
|
+
Post.includes(:deals).each { |post| post.deals.map(&:name) }
|
407
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
408
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
409
|
+
|
410
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
411
|
+
end
|
412
|
+
end
|
405
413
|
context 'students <=> teachers' do
|
406
414
|
it 'should detect non preload associations' do
|
407
415
|
Student.all.each { |student| student.teachers.map(&:name) }
|
@@ -443,6 +451,16 @@ if active_record?
|
|
443
451
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Student, :teachers)
|
444
452
|
end
|
445
453
|
end
|
454
|
+
|
455
|
+
context 'user => roles' do
|
456
|
+
it 'should detect preload associations' do
|
457
|
+
User.first.roles.includes(:resource).each { |role| role.resource }
|
458
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
459
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
460
|
+
|
461
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
462
|
+
end
|
463
|
+
end
|
446
464
|
end
|
447
465
|
|
448
466
|
describe Bullet::Detector::Association, 'has_many :through' do
|
@@ -562,6 +580,42 @@ if active_record?
|
|
562
580
|
end
|
563
581
|
end
|
564
582
|
|
583
|
+
describe Bullet::Detector::Association, 'has_one :through' do
|
584
|
+
context 'user => attachment' do
|
585
|
+
it 'should detect non preload associations' do
|
586
|
+
User.all.each { |user| user.submission_attachment.file_name }
|
587
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
588
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
589
|
+
|
590
|
+
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(User, :submission_attachment)
|
591
|
+
end
|
592
|
+
|
593
|
+
it 'should detect preload associations' do
|
594
|
+
User.includes(:submission_attachment).each { |user| user.submission_attachment.file_name }
|
595
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
596
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
597
|
+
|
598
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
599
|
+
end
|
600
|
+
|
601
|
+
it 'should not detect preload associations' do
|
602
|
+
User.all.map(&:name)
|
603
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
604
|
+
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
605
|
+
|
606
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'should detect unused preload associations' do
|
610
|
+
User.includes(:submission_attachment).map(&:name)
|
611
|
+
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
612
|
+
expect(Bullet::Detector::Association).to be_unused_preload_associations_for(User, :submission_attachment)
|
613
|
+
|
614
|
+
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
615
|
+
end
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
565
619
|
describe Bullet::Detector::Association, 'call one association that in possible objects' do
|
566
620
|
it 'should not detect preload association' do
|
567
621
|
Post.all
|
@@ -694,9 +748,9 @@ if active_record?
|
|
694
748
|
end
|
695
749
|
end
|
696
750
|
|
697
|
-
context '
|
698
|
-
before { Bullet.
|
699
|
-
after { Bullet.
|
751
|
+
context 'add n plus one query to safelist' do
|
752
|
+
before { Bullet.add_safelist type: :n_plus_one_query, class_name: 'Post', association: :comments }
|
753
|
+
after { Bullet.clear_safelist }
|
700
754
|
|
701
755
|
it 'should not detect n plus one query' do
|
702
756
|
Post.all.each { |post| post.comments.map(&:name) }
|
@@ -715,9 +769,9 @@ if active_record?
|
|
715
769
|
end
|
716
770
|
end
|
717
771
|
|
718
|
-
context '
|
719
|
-
before { Bullet.
|
720
|
-
after { Bullet.
|
772
|
+
context 'add unused eager loading to safelist' do
|
773
|
+
before { Bullet.add_safelist type: :unused_eager_loading, class_name: 'Post', association: :comments }
|
774
|
+
after { Bullet.clear_safelist }
|
721
775
|
|
722
776
|
it 'should not detect unused eager loading' do
|
723
777
|
Post.includes(:comments).map(&:name)
|
@@ -28,7 +28,7 @@ if !mongoid? && active_record?
|
|
28
28
|
expect(Bullet.collected_counter_cache_notifications).to be_empty
|
29
29
|
end
|
30
30
|
|
31
|
-
if
|
31
|
+
if ActiveRecord::VERSION::MAJOR > 4
|
32
32
|
it 'should not need counter cache for has_many through' do
|
33
33
|
Client.all.each { |client| client.firms.size }
|
34
34
|
expect(Bullet.collected_counter_cache_notifications).to be_empty
|
@@ -55,9 +55,9 @@ if !mongoid? && active_record?
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
context '
|
59
|
-
before { Bullet.
|
60
|
-
after { Bullet.
|
58
|
+
context 'safelist' do
|
59
|
+
before { Bullet.add_safelist type: :counter_cache, class_name: 'Country', association: :cities }
|
60
|
+
after { Bullet.clear_safelist }
|
61
61
|
|
62
62
|
it 'should not detect counter cache' do
|
63
63
|
Country.all.each { |country| country.cities.size }
|
@@ -73,9 +73,9 @@ if mongoid?
|
|
73
73
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
74
74
|
|
75
75
|
expect(Bullet::Detector::Association).not_to be_detecting_unpreloaded_association_for(
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
Mongoid::Category,
|
77
|
+
:posts
|
78
|
+
)
|
79
79
|
expect(Bullet::Detector::Association).to be_detecting_unpreloaded_association_for(Mongoid::Category, :entries)
|
80
80
|
end
|
81
81
|
|
@@ -118,7 +118,7 @@ if mongoid?
|
|
118
118
|
expect(Bullet::Detector::Association).to be_completely_preloading_associations
|
119
119
|
end
|
120
120
|
|
121
|
-
it 'should detect preload with post =>
|
121
|
+
it 'should detect preload with post => comments' do
|
122
122
|
Mongoid::Post.first.comments.map(&:name)
|
123
123
|
Bullet::Detector::UnusedEagerLoading.check_unused_preload_associations
|
124
124
|
expect(Bullet::Detector::Association).not_to be_has_unused_preload_associations
|
data/spec/models/deal.rb
ADDED
data/spec/models/folder.rb
CHANGED
data/spec/models/group.rb
CHANGED
data/spec/models/page.rb
CHANGED
data/spec/models/post.rb
CHANGED
@@ -4,6 +4,7 @@ class Post < ActiveRecord::Base
|
|
4
4
|
belongs_to :category, inverse_of: :posts
|
5
5
|
belongs_to :writer
|
6
6
|
has_many :comments, inverse_of: :post
|
7
|
+
has_and_belongs_to_many :deals
|
7
8
|
|
8
9
|
validates :category, presence: true
|
9
10
|
|
@@ -21,6 +22,7 @@ class Post < ActiveRecord::Base
|
|
21
22
|
next unless trigger_after_save
|
22
23
|
|
23
24
|
temp_comment = Comment.new(post: self)
|
25
|
+
|
24
26
|
# this triggers self to be "possible", even though it's
|
25
27
|
# not saved yet
|
26
28
|
temp_comment.post
|
data/spec/models/role.rb
ADDED
data/spec/models/submission.rb
CHANGED
data/spec/models/user.rb
CHANGED
data/spec/models/writer.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/support/mongo_seed.rb
CHANGED
@@ -45,6 +45,7 @@ module Support
|
|
45
45
|
Mongoid.configure do |config|
|
46
46
|
config.load_configuration(clients: { default: { database: 'bullet', hosts: %w[localhost:27017] } })
|
47
47
|
end
|
48
|
+
|
48
49
|
# Increase the level from DEBUG in order to avoid excessive logging to the screen
|
49
50
|
Mongo::Logger.logger.level = Logger::WARN
|
50
51
|
end
|
data/spec/support/sqlite_seed.rb
CHANGED
@@ -21,6 +21,13 @@ module Support
|
|
21
21
|
post2 = category2.posts.create(name: 'second', writer: writer2)
|
22
22
|
post3 = category2.posts.create(name: 'third', writer: writer2)
|
23
23
|
|
24
|
+
deal1 = Deal.new(name: 'Deal 1')
|
25
|
+
deal1.posts << post1
|
26
|
+
deal1.posts << post2
|
27
|
+
deal2 = Deal.new(name: 'Deal 2')
|
28
|
+
post1.deals << deal1
|
29
|
+
post1.deals << deal2
|
30
|
+
|
24
31
|
comment1 = post1.comments.create(name: 'first', author: writer1)
|
25
32
|
comment2 = post1.comments.create(name: 'first2', author: writer1)
|
26
33
|
comment3 = post1.comments.create(name: 'first3', author: writer1)
|
@@ -85,9 +92,16 @@ module Support
|
|
85
92
|
page3 = Page.create(name: 'page3', parent_id: folder2.id, author_id: author2.id)
|
86
93
|
page4 = Page.create(name: 'page4', parent_id: folder2.id, author_id: author2.id)
|
87
94
|
|
95
|
+
role1 = Role.create(name: 'Admin')
|
96
|
+
role2 = Role.create(name: 'User')
|
97
|
+
|
88
98
|
user1 = User.create(name: 'user1', category: category1)
|
89
99
|
user2 = User.create(name: 'user2', category: category1)
|
90
100
|
|
101
|
+
user1.roles << role1
|
102
|
+
user1.roles << role2
|
103
|
+
user2.roles << role2
|
104
|
+
|
91
105
|
submission1 = user1.create_submission(name: 'submission1')
|
92
106
|
submission2 = user2.create_submission(name: 'submission2')
|
93
107
|
|
@@ -95,6 +109,9 @@ module Support
|
|
95
109
|
submission1.replies.create(name: 'reply2')
|
96
110
|
submission2.replies.create(name: 'reply3')
|
97
111
|
submission2.replies.create(name: 'reply4')
|
112
|
+
|
113
|
+
submission1.create_attachment(file_name: 'submission1 file')
|
114
|
+
submission2.create_attachment(file_name: 'submission2 file')
|
98
115
|
end
|
99
116
|
|
100
117
|
def setup_db
|
@@ -153,6 +170,11 @@ module Support
|
|
153
170
|
t.column :hotel_id, :integer
|
154
171
|
end
|
155
172
|
|
173
|
+
create_table :deals_posts do |t|
|
174
|
+
t.column :deal_id, :integer
|
175
|
+
t.column :post_id, :integer
|
176
|
+
end
|
177
|
+
|
156
178
|
create_table :documents do |t|
|
157
179
|
t.string :name
|
158
180
|
t.string :type
|
@@ -231,6 +253,17 @@ module Support
|
|
231
253
|
t.column :submission_id, :integer
|
232
254
|
end
|
233
255
|
|
256
|
+
create_table :roles do |t|
|
257
|
+
t.column :name, :string
|
258
|
+
t.column :resource_id, :integer
|
259
|
+
t.column :resource_type, :string
|
260
|
+
end
|
261
|
+
|
262
|
+
create_table :roles_users do |t|
|
263
|
+
t.column :role_id, :integer
|
264
|
+
t.column :user_id, :integer
|
265
|
+
end
|
266
|
+
|
234
267
|
create_table :submissions do |t|
|
235
268
|
t.column :name, :string
|
236
269
|
t.column :user_id, :integer
|
@@ -240,6 +273,11 @@ module Support
|
|
240
273
|
t.column :name, :string
|
241
274
|
t.column :category_id, :integer
|
242
275
|
end
|
276
|
+
|
277
|
+
create_table :attachments do |t|
|
278
|
+
t.column :file_name, :string
|
279
|
+
t.column :submission_id, :integer
|
280
|
+
end
|
243
281
|
end
|
244
282
|
end
|
245
283
|
end
|
data/test.sh
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
#bundle update rails && bundle exec rspec spec
|
2
2
|
#BUNDLE_GEMFILE=Gemfile.mongoid bundle update mongoid && BUNDLE_GEMFILE=Gemfile.mongoid bundle exec rspec spec
|
3
|
+
BUNDLE_GEMFILE=Gemfile.rails-7.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-7.0 bundle exec rspec spec
|
4
|
+
BUNDLE_GEMFILE=Gemfile.rails-6.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-6.1 bundle exec rspec spec
|
3
5
|
BUNDLE_GEMFILE=Gemfile.rails-6.0 bundle && BUNDLE_GEMFILE=Gemfile.rails-6.0 bundle exec rspec spec
|
4
6
|
BUNDLE_GEMFILE=Gemfile.rails-5.2 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.2 bundle exec rspec spec
|
5
7
|
BUNDLE_GEMFILE=Gemfile.rails-5.1 bundle && BUNDLE_GEMFILE=Gemfile.rails-5.1 bundle exec rspec spec
|