bullet 5.7.5 → 6.1.4

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.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +22 -1
  3. data/CHANGELOG.md +49 -12
  4. data/Gemfile.mongoid-7.0 +15 -0
  5. data/Gemfile.rails-4.0 +1 -1
  6. data/Gemfile.rails-4.1 +1 -1
  7. data/Gemfile.rails-4.2 +1 -1
  8. data/Gemfile.rails-5.0 +1 -1
  9. data/Gemfile.rails-5.1 +1 -1
  10. data/Gemfile.rails-5.2 +2 -2
  11. data/Gemfile.rails-6.0 +15 -0
  12. data/Gemfile.rails-6.1 +15 -0
  13. data/README.md +38 -13
  14. data/Rakefile +1 -1
  15. data/bullet.gemspec +8 -3
  16. data/lib/bullet.rb +50 -22
  17. data/lib/bullet/active_job.rb +13 -0
  18. data/lib/bullet/active_record4.rb +12 -35
  19. data/lib/bullet/active_record41.rb +10 -30
  20. data/lib/bullet/active_record42.rb +12 -27
  21. data/lib/bullet/active_record5.rb +197 -177
  22. data/lib/bullet/active_record52.rb +191 -166
  23. data/lib/bullet/active_record60.rb +278 -0
  24. data/lib/bullet/active_record61.rb +278 -0
  25. data/lib/bullet/bullet_xhr.js +63 -0
  26. data/lib/bullet/dependency.rb +54 -34
  27. data/lib/bullet/detector/association.rb +26 -20
  28. data/lib/bullet/detector/base.rb +1 -2
  29. data/lib/bullet/detector/counter_cache.rb +14 -9
  30. data/lib/bullet/detector/n_plus_one_query.rb +27 -17
  31. data/lib/bullet/detector/unused_eager_loading.rb +7 -3
  32. data/lib/bullet/ext/object.rb +5 -3
  33. data/lib/bullet/ext/string.rb +1 -1
  34. data/lib/bullet/mongoid4x.rb +4 -7
  35. data/lib/bullet/mongoid5x.rb +4 -7
  36. data/lib/bullet/mongoid6x.rb +8 -11
  37. data/lib/bullet/mongoid7x.rb +57 -0
  38. data/lib/bullet/notification/base.rb +15 -19
  39. data/lib/bullet/notification/n_plus_one_query.rb +2 -4
  40. data/lib/bullet/notification/unused_eager_loading.rb +2 -4
  41. data/lib/bullet/rack.rb +54 -28
  42. data/lib/bullet/stack_trace_filter.rb +39 -30
  43. data/lib/bullet/version.rb +1 -1
  44. data/lib/generators/bullet/install_generator.rb +26 -26
  45. data/perf/benchmark.rb +8 -14
  46. data/spec/bullet/detector/counter_cache_spec.rb +6 -6
  47. data/spec/bullet/detector/n_plus_one_query_spec.rb +30 -3
  48. data/spec/bullet/detector/unused_eager_loading_spec.rb +19 -6
  49. data/spec/bullet/ext/object_spec.rb +9 -4
  50. data/spec/bullet/notification/base_spec.rb +1 -3
  51. data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
  52. data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
  53. data/spec/bullet/rack_spec.rb +140 -5
  54. data/spec/bullet/registry/association_spec.rb +2 -2
  55. data/spec/bullet/registry/base_spec.rb +1 -1
  56. data/spec/bullet_spec.rb +10 -29
  57. data/spec/integration/active_record/association_spec.rb +122 -118
  58. data/spec/integration/counter_cache_spec.rb +11 -31
  59. data/spec/integration/mongoid/association_spec.rb +18 -32
  60. data/spec/models/attachment.rb +5 -0
  61. data/spec/models/client.rb +2 -0
  62. data/spec/models/firm.rb +1 -0
  63. data/spec/models/folder.rb +1 -2
  64. data/spec/models/group.rb +3 -0
  65. data/spec/models/page.rb +1 -2
  66. data/spec/models/post.rb +15 -0
  67. data/spec/models/submission.rb +1 -0
  68. data/spec/models/user.rb +1 -0
  69. data/spec/models/writer.rb +1 -2
  70. data/spec/spec_helper.rb +6 -10
  71. data/spec/support/bullet_ext.rb +8 -9
  72. data/spec/support/mongo_seed.rb +2 -16
  73. data/spec/support/sqlite_seed.rb +17 -2
  74. data/test.sh +2 -0
  75. data/update.sh +1 -0
  76. metadata +24 -11
@@ -12,15 +12,15 @@ module Bullet
12
12
 
13
13
  context '.add_counter_cache' do
14
14
  it 'should create notification if conditions met' do
15
- expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(true)
16
- expect(CounterCache).to receive(:create_notification).with('Post', [:comments])
17
- CounterCache.add_counter_cache(@post1, [:comments])
15
+ expect(CounterCache).to receive(:conditions_met?).with(@post1, %i[comments]).and_return(true)
16
+ expect(CounterCache).to receive(:create_notification).with('Post', %i[comments])
17
+ CounterCache.add_counter_cache(@post1, %i[comments])
18
18
  end
19
19
 
20
20
  it 'should not create notification if conditions not met' do
21
- expect(CounterCache).to receive(:conditions_met?).with(@post1, [:comments]).and_return(false)
21
+ expect(CounterCache).to receive(:conditions_met?).with(@post1, %i[comments]).and_return(false)
22
22
  expect(CounterCache).to receive(:create_notification).never
23
- CounterCache.add_counter_cache(@post1, [:comments])
23
+ CounterCache.add_counter_cache(@post1, %i[comments])
24
24
  end
25
25
  end
26
26
 
@@ -47,7 +47,7 @@ module Bullet
47
47
  expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
48
48
  end
49
49
 
50
- it 'should be true when object is possible, and impossible' do
50
+ it 'should be false when object is possible, and impossible' do
51
51
  CounterCache.add_possible_objects(@post1)
52
52
  CounterCache.add_impossible_object(@post1)
53
53
  expect(CounterCache.conditions_met?(@post1, :associations)).to eq false
@@ -76,8 +76,8 @@ module Bullet
76
76
  context '.call_association' do
77
77
  it 'should create notification if conditions met' do
78
78
  expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
79
- expect(NPlusOneQuery).to receive(:caller_in_project).and_return(['caller'])
80
- expect(NPlusOneQuery).to receive(:create_notification).with(['caller'], 'Post', :association)
79
+ expect(NPlusOneQuery).to receive(:caller_in_project).and_return(%w[caller])
80
+ expect(NPlusOneQuery).to receive(:create_notification).with(%w[caller], 'Post', :association)
81
81
  NPlusOneQuery.call_association(@post, :association)
82
82
  end
83
83
 
@@ -101,6 +101,29 @@ module Bullet
101
101
  expect(NPlusOneQuery).to_not receive(:create_notification)
102
102
  NPlusOneQuery.call_association(@post, :association)
103
103
  end
104
+
105
+ # just a sanity spec to make sure the following spec works correctly
106
+ it "should create notification when stacktrace contains methods that aren't in the exclude list" do
107
+ method = NPlusOneQuery.method(:excluded_stacktrace_path?).source_location
108
+ in_project = OpenStruct.new(absolute_path: File.join(Dir.pwd, 'abc', 'abc.rb'))
109
+ excluded_path = OpenStruct.new(absolute_path: method.first, lineno: method.last)
110
+
111
+ expect(NPlusOneQuery).to receive(:caller_locations).at_least(1).and_return([in_project, excluded_path])
112
+ expect(NPlusOneQuery).to receive(:conditions_met?).and_return(true)
113
+ expect(NPlusOneQuery).to receive(:create_notification)
114
+ NPlusOneQuery.call_association(@post, :association)
115
+ end
116
+
117
+ it 'should not create notification when stacktrace contains methods that are in the exclude list' do
118
+ method = NPlusOneQuery.method(:excluded_stacktrace_path?).source_location
119
+ Bullet.stacktrace_excludes = [method]
120
+ in_project = OpenStruct.new(absolute_path: File.join(Dir.pwd, 'abc', 'abc.rb'))
121
+ excluded_path = OpenStruct.new(absolute_path: method.first, lineno: method.last)
122
+
123
+ expect(NPlusOneQuery).to receive(:caller_locations).and_return([in_project, excluded_path])
124
+ expect(NPlusOneQuery).to_not receive(:create_notification)
125
+ NPlusOneQuery.call_association(@post, :association)
126
+ end
104
127
  end
105
128
  end
106
129
 
@@ -126,7 +149,11 @@ module Bullet
126
149
 
127
150
  expect(NPlusOneQuery).to receive(:caller_locations).and_return([in_project, *included_gems, excluded_gem])
128
151
  expect(NPlusOneQuery).to receive(:conditions_met?).with(@post, :association).and_return(true)
129
- expect(NPlusOneQuery).to receive(:create_notification).with([in_project, *included_gems], 'Post', :association)
152
+ expect(NPlusOneQuery).to receive(:create_notification).with(
153
+ [in_project, *included_gems],
154
+ 'Post',
155
+ :association
156
+ )
130
157
  NPlusOneQuery.call_association(@post, :association)
131
158
  end
132
159
  end
@@ -36,12 +36,14 @@ module Bullet
36
36
  it 'should return empty if associations exist in call_association' do
37
37
  UnusedEagerLoading.add_eager_loadings([@post], :association)
38
38
  UnusedEagerLoading.add_call_object_associations(@post, :association)
39
- expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
39
+ expect(
40
+ UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))
41
+ ).to be_empty
40
42
  end
41
43
  end
42
44
 
43
45
  context '.check_unused_preload_associations' do
44
- let(:paths) { ['/dir1', '/dir1/subdir'] }
46
+ let(:paths) { %w[/dir1 /dir1/subdir] }
45
47
  it 'should create notification if object_association_diff is not empty' do
46
48
  UnusedEagerLoading.add_object_associations(@post, :association)
47
49
  allow(UnusedEagerLoading).to receive(:caller_in_project).and_return(paths)
@@ -53,7 +55,9 @@ module Bullet
53
55
  UnusedEagerLoading.add_object_associations(@post, :association)
54
56
  UnusedEagerLoading.add_eager_loadings([@post], :association)
55
57
  UnusedEagerLoading.add_call_object_associations(@post, :association)
56
- expect(UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))).to be_empty
58
+ expect(
59
+ UnusedEagerLoading.send(:diff_object_associations, @post.bullet_key, Set.new([:association]))
60
+ ).to be_empty
57
61
  expect(UnusedEagerLoading).not_to receive(:create_notification).with('Post', [:association])
58
62
  UnusedEagerLoading.check_unused_preload_associations
59
63
  end
@@ -62,14 +66,23 @@ module Bullet
62
66
  context '.add_eager_loadings' do
63
67
  it 'should add objects, associations pair when eager_loadings are empty' do
64
68
  UnusedEagerLoading.add_eager_loadings([@post, @post2], :associations)
65
- expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :associations)
69
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
70
+ [@post.bullet_key, @post2.bullet_key],
71
+ :associations
72
+ )
66
73
  end
67
74
 
68
75
  it 'should add objects, associations pair for existing eager_loadings' do
69
76
  UnusedEagerLoading.add_eager_loadings([@post, @post2], :association1)
70
77
  UnusedEagerLoading.add_eager_loadings([@post, @post2], :association2)
71
- expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association1)
72
- expect(UnusedEagerLoading.send(:eager_loadings)).to be_include([@post.bullet_key, @post2.bullet_key], :association2)
78
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
79
+ [@post.bullet_key, @post2.bullet_key],
80
+ :association1
81
+ )
82
+ expect(UnusedEagerLoading.send(:eager_loadings)).to be_include(
83
+ [@post.bullet_key, @post2.bullet_key],
84
+ :association2
85
+ )
73
86
  end
74
87
 
75
88
  it 'should merge objects, associations pair for existing eager_loadings' do
@@ -17,23 +17,28 @@ describe Object do
17
17
  end
18
18
  end
19
19
 
20
- context 'primary_key_value' do
20
+ context 'bullet_primary_key_value' do
21
21
  it 'should return id' do
22
22
  post = Post.first
23
- expect(post.primary_key_value).to eq(post.id)
23
+ expect(post.bullet_primary_key_value).to eq(post.id)
24
24
  end
25
25
 
26
26
  it 'should return primary key value' do
27
27
  post = Post.first
28
28
  Post.primary_key = 'name'
29
- expect(post.primary_key_value).to eq(post.name)
29
+ expect(post.bullet_primary_key_value).to eq(post.name)
30
30
  Post.primary_key = 'id'
31
31
  end
32
32
 
33
33
  it 'should return value for multiple primary keys' do
34
34
  post = Post.first
35
35
  allow(Post).to receive(:primary_keys).and_return(%i[category_id writer_id])
36
- expect(post.primary_key_value).to eq("#{post.category_id},#{post.writer_id}")
36
+ expect(post.bullet_primary_key_value).to eq("#{post.category_id},#{post.writer_id}")
37
+ end
38
+
39
+ it 'it should return nil for unpersisted records' do
40
+ post = Post.new(id: 123)
41
+ expect(post.bullet_primary_key_value).to be_nil
37
42
  end
38
43
  end
39
44
  end
@@ -26,9 +26,7 @@ module Bullet
26
26
  end
27
27
 
28
28
  it 'should leverage ENV parameter' do
29
- temp_env_variable('USER', 'bogus') do
30
- expect(subject.whoami).to eq('user: bogus')
31
- end
29
+ temp_env_variable('USER', 'bogus') { expect(subject.whoami).to eq('user: bogus') }
32
30
  end
33
31
 
34
32
  it 'should return blank if no user available' do
@@ -7,9 +7,22 @@ module Bullet
7
7
  describe NPlusOneQuery do
8
8
  subject { NPlusOneQuery.new([%w[caller1 caller2]], Post, %i[comments votes], 'path') }
9
9
 
10
- it { expect(subject.body_with_caller).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n") }
11
- it { expect([subject.body_with_caller, subject.body_with_caller]).to eq([" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n", " Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]\nCall stack\n caller1\n caller2\n"]) }
12
- it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your finder: :includes => [:comments, :votes]") }
10
+ it do
11
+ expect(subject.body_with_caller).to eq(
12
+ " Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n"
13
+ )
14
+ end
15
+ it do
16
+ expect([subject.body_with_caller, subject.body_with_caller]).to eq(
17
+ [
18
+ " Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n",
19
+ " Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])\nCall stack\n caller1\n caller2\n"
20
+ ]
21
+ )
22
+ end
23
+ it do
24
+ expect(subject.body).to eq(" Post => [:comments, :votes]\n Add to your query: .includes([:comments, :votes])")
25
+ end
13
26
  it { expect(subject.title).to eq('USE eager loading in path') }
14
27
  end
15
28
  end
@@ -7,7 +7,11 @@ module Bullet
7
7
  describe UnusedEagerLoading do
8
8
  subject { UnusedEagerLoading.new([''], Post, %i[comments votes], 'path') }
9
9
 
10
- it { expect(subject.body).to eq(" Post => [:comments, :votes]\n Remove from your finder: :includes => [:comments, :votes]") }
10
+ it do
11
+ expect(subject.body).to eq(
12
+ " Post => [:comments, :votes]\n Remove from your query: .includes([:comments, :votes])"
13
+ )
14
+ end
11
15
  it { expect(subject.title).to eq('AVOID eager loading in path') }
12
16
  end
13
17
  end
@@ -45,9 +45,9 @@ module Bullet
45
45
  expect(middleware).not_to be_empty(response)
46
46
  end
47
47
 
48
- it 'should be true if response is not found' do
48
+ it 'should be false if response is not found' do
49
49
  response = ['Not Found']
50
- expect(middleware).to be_empty(response)
50
+ expect(middleware).not_to be_empty(response)
51
51
  end
52
52
 
53
53
  it 'should be true if response body is empty' do
@@ -67,11 +67,12 @@ module Bullet
67
67
 
68
68
  it 'should change response body if notification is active' do
69
69
  expect(Bullet).to receive(:notification?).and_return(true)
70
+ expect(Bullet).to receive(:console_enabled?).and_return(true)
70
71
  expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
71
72
  expect(Bullet).to receive(:perform_out_of_channel_notifications)
72
- status, headers, response = middleware.call('Content-Type' => 'text/html')
73
+ _, headers, response = middleware.call('Content-Type' => 'text/html')
73
74
  expect(headers['Content-Length']).to eq('56')
74
- expect(response).to eq(['<html><head></head><body><bullet></bullet></body></html>'])
75
+ expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
75
76
  end
76
77
 
77
78
  it 'should set the right Content-Length if response body contains accents' do
@@ -79,10 +80,136 @@ module Bullet
79
80
  response.body = '<html><head></head><body>é</body></html>'
80
81
  app.response = response
81
82
  expect(Bullet).to receive(:notification?).and_return(true)
83
+ allow(Bullet).to receive(:console_enabled?).and_return(true)
82
84
  expect(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
83
- status, headers, response = middleware.call('Content-Type' => 'text/html')
85
+ _, headers, response = middleware.call('Content-Type' => 'text/html')
84
86
  expect(headers['Content-Length']).to eq('58')
85
87
  end
88
+
89
+ context 'with injection notifiers' do
90
+ before do
91
+ expect(Bullet).to receive(:notification?).and_return(true)
92
+ allow(Bullet).to receive(:gather_inline_notifications).and_return('<bullet></bullet>')
93
+ allow(middleware).to receive(:xhr_script).and_return('<script></script>')
94
+ allow(middleware).to receive(:footer_note).and_return('footer')
95
+ expect(Bullet).to receive(:perform_out_of_channel_notifications)
96
+ end
97
+
98
+ it 'should change response body if add_footer is true' do
99
+ expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
100
+ _, headers, response = middleware.call('Content-Type' => 'text/html')
101
+
102
+ expect(headers['Content-Length']).to eq((73 + middleware.send(:footer_note).length).to_s)
103
+ expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet><script></script></body></html>])
104
+ end
105
+
106
+ it 'should change response body for html safe string if add_footer is true' do
107
+ expect(Bullet).to receive(:add_footer).exactly(3).times.and_return(true)
108
+ app.response = 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 = Support::ResponseDouble.new.tap do |response|
135
+ response.body = ActiveSupport::SafeBuffer.new('<html><head></head><body></body></html>')
136
+ end
137
+ _, headers, response = middleware.call('Content-Type' => 'text/html')
138
+ expect(headers['Content-Length']).to eq('56')
139
+ expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
140
+ end
141
+
142
+ it 'should add headers for non-html requests when console_enabled is true' do
143
+ allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
144
+ allow(Bullet).to receive(:text_notifications).and_return(['text notifications'])
145
+ app.headers = {'Content-Type' => 'application/json'}
146
+ _, headers, _response = middleware.call({})
147
+ expect(headers).to include('X-bullet-console-text' => '["text notifications"]')
148
+ end
149
+
150
+ it "shouldn't change response body unnecessarily" do
151
+ expected_response = Support::ResponseDouble.new 'Actual body'
152
+ app.response = expected_response
153
+ _, _, response = middleware.call({})
154
+ expect(response).to eq(expected_response)
155
+ end
156
+
157
+ it "shouldn't add headers unnecessarily" do
158
+ app.headers = {'Content-Type' => 'application/json'}
159
+ _, headers, _response = middleware.call({})
160
+ expect(headers).not_to include('X-bullet-footer-text')
161
+ expect(headers).not_to include('X-bullet-console-text')
162
+ end
163
+
164
+ context "when skip_http_headers is enabled" do
165
+ before do
166
+ allow(Bullet).to receive(:skip_http_headers).and_return(true)
167
+ end
168
+
169
+ it 'should include the footer but not the xhr script tag if add_footer is true' do
170
+ expect(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
171
+ _, headers, response = middleware.call({})
172
+
173
+ expect(headers['Content-Length']).to eq((56 + middleware.send(:footer_note).length).to_s)
174
+ expect(response).to eq(%w[<html><head></head><body>footer<bullet></bullet></body></html>])
175
+ end
176
+
177
+ it 'should not include the xhr script tag if console_enabled is true' do
178
+ expect(Bullet).to receive(:console_enabled?).and_return(true)
179
+ _, headers, response = middleware.call({})
180
+ expect(headers['Content-Length']).to eq('56')
181
+ expect(response).to eq(%w[<html><head></head><body><bullet></bullet></body></html>])
182
+ end
183
+
184
+ it 'should not add the footer-text header for non-html requests when add_footer is true' do
185
+ allow(Bullet).to receive(:add_footer).at_least(:once).and_return(true)
186
+ app.headers = {'Content-Type' => 'application/json'}
187
+ _, headers, _response = middleware.call({})
188
+ expect(headers).not_to include('X-bullet-footer-text')
189
+ end
190
+
191
+ it 'should not add headers for non-html requests when console_enabled is true' do
192
+ allow(Bullet).to receive(:console_enabled?).at_least(:once).and_return(true)
193
+ app.headers = {'Content-Type' => 'application/json'}
194
+ _, headers, _response = middleware.call({})
195
+ expect(headers).not_to include('X-bullet-console-text')
196
+ end
197
+ end
198
+ end
199
+
200
+ context 'when skip_html_injection is enabled' do
201
+ it 'should not try to inject html' do
202
+ expected_response = Support::ResponseDouble.new 'Actual body'
203
+ app.response = expected_response
204
+ allow(Bullet).to receive(:notification?).and_return(true)
205
+ allow(Bullet).to receive(:skip_html_injection?).and_return(true)
206
+ expect(Bullet).to receive(:gather_inline_notifications).never
207
+ expect(middleware).to receive(:xhr_script).never
208
+ expect(Bullet).to receive(:perform_out_of_channel_notifications)
209
+ _, _, response = middleware.call('Content-Type' => 'text/html')
210
+ expect(response).to eq(expected_response)
211
+ end
212
+ end
86
213
  end
87
214
 
88
215
  context 'when Bullet is disabled' do
@@ -95,6 +222,14 @@ module Bullet
95
222
  end
96
223
  end
97
224
 
225
+ context '#set_header' do
226
+ it 'should truncate headers to under 8kb' do
227
+ long_header = ['a' * 1_024] * 10
228
+ expected_res = (['a' * 1_024] * 7).to_json
229
+ expect(middleware.set_header({}, 'Dummy-Header', long_header)).to eq(expected_res)
230
+ end
231
+ end
232
+
98
233
  describe '#response_body' do
99
234
  let(:response) { double }
100
235
  let(:body_string) { '<html><body>My Body</body></html>' }
@@ -16,11 +16,11 @@ module Bullet
16
16
 
17
17
  context '#similarly_associated' do
18
18
  it 'should return similarly associated keys' do
19
- expect(subject.similarly_associated('key1', Set.new(['value']))).to eq(%w[key1 key2])
19
+ expect(subject.similarly_associated('key1', Set.new(%w[value]))).to eq(%w[key1 key2])
20
20
  end
21
21
 
22
22
  it 'should return empty if key does not exist' do
23
- expect(subject.similarly_associated('key3', Set.new(['value']))).to be_empty
23
+ expect(subject.similarly_associated('key3', Set.new(%w[value]))).to be_empty
24
24
  end
25
25
  end
26
26
  end
@@ -9,7 +9,7 @@ module Bullet
9
9
 
10
10
  context '#[]' do
11
11
  it 'should get value by key' do
12
- expect(subject['key']).to eq(Set.new(['value']))
12
+ expect(subject['key']).to eq(Set.new(%w[value]))
13
13
  end
14
14
  end
15
15
 
data/spec/bullet_spec.rb CHANGED
@@ -17,9 +17,7 @@ describe Bullet, focused: true do
17
17
  end
18
18
 
19
19
  context 'disable Bullet' do
20
- before do
21
- Bullet.enable = false
22
- end
20
+ before { Bullet.enable = false }
23
21
 
24
22
  it 'should be disabled' do
25
23
  expect(subject).to_not be_enable
@@ -27,8 +25,8 @@ describe Bullet, focused: true do
27
25
 
28
26
  context 'enable Bullet again without patching again the orms' do
29
27
  before do
30
- expect(Bullet::Mongoid).not_to receive(:enable) if defined? Bullet::Mongoid
31
- expect(Bullet::ActiveRecord).not_to receive(:enable) if defined? Bullet::ActiveRecord
28
+ expect(Bullet::Mongoid).not_to receive(:enable) if defined?(Bullet::Mongoid)
29
+ expect(Bullet::ActiveRecord).not_to receive(:enable) if defined?(Bullet::ActiveRecord)
32
30
  Bullet.enable = true
33
31
  end
34
32
 
@@ -42,9 +40,7 @@ describe Bullet, focused: true do
42
40
 
43
41
  describe '#start?' do
44
42
  context 'when bullet is disabled' do
45
- before(:each) do
46
- Bullet.enable = false
47
- end
43
+ before(:each) { Bullet.enable = false }
48
44
 
49
45
  it 'should not be started' do
50
46
  expect(Bullet).not_to be_start
@@ -53,28 +49,19 @@ describe Bullet, focused: true do
53
49
  end
54
50
 
55
51
  describe '#debug' do
56
- before(:each) do
57
- $stdout = StringIO.new
58
- end
52
+ before(:each) { $stdout = StringIO.new }
59
53
 
60
- after(:each) do
61
- $stdout = STDOUT
62
- end
54
+ after(:each) { $stdout = STDOUT }
63
55
 
64
56
  context 'when debug is enabled' do
65
- before(:each) do
66
- ENV['BULLET_DEBUG'] = 'true'
67
- end
57
+ before(:each) { ENV['BULLET_DEBUG'] = 'true' }
68
58
 
69
- after(:each) do
70
- ENV['BULLET_DEBUG'] = 'false'
71
- end
59
+ after(:each) { ENV['BULLET_DEBUG'] = 'false' }
72
60
 
73
61
  it 'should output debug information' do
74
62
  Bullet.debug('debug_message', 'this is helpful information')
75
63
 
76
- expect($stdout.string)
77
- .to eq("[Bullet][debug_message] this is helpful information\n")
64
+ expect($stdout.string).to eq("[Bullet][debug_message] this is helpful information\n")
78
65
  end
79
66
  end
80
67
 
@@ -125,13 +112,7 @@ describe Bullet, focused: true do
125
112
  end
126
113
 
127
114
  context 'when called with Rack environment hash' do
128
- let(:env) {
129
- {
130
- 'REQUEST_METHOD' => 'GET',
131
- 'PATH_INFO' => '/path',
132
- 'QUERY_STRING' => 'foo=bar'
133
- }
134
- }
115
+ let(:env) { { 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/path', 'QUERY_STRING' => 'foo=bar' } }
135
116
 
136
117
  context "when env['REQUEST_URI'] is nil" do
137
118
  before { env['REQUEST_URI'] = nil }