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.
- checksums.yaml +5 -5
- data/.travis.yml +22 -1
- data/CHANGELOG.md +49 -12
- data/Gemfile.mongoid-7.0 +15 -0
- data/Gemfile.rails-4.0 +1 -1
- data/Gemfile.rails-4.1 +1 -1
- data/Gemfile.rails-4.2 +1 -1
- data/Gemfile.rails-5.0 +1 -1
- data/Gemfile.rails-5.1 +1 -1
- data/Gemfile.rails-5.2 +2 -2
- data/Gemfile.rails-6.0 +15 -0
- data/Gemfile.rails-6.1 +15 -0
- data/README.md +38 -13
- data/Rakefile +1 -1
- data/bullet.gemspec +8 -3
- data/lib/bullet.rb +50 -22
- data/lib/bullet/active_job.rb +13 -0
- data/lib/bullet/active_record4.rb +12 -35
- data/lib/bullet/active_record41.rb +10 -30
- data/lib/bullet/active_record42.rb +12 -27
- data/lib/bullet/active_record5.rb +197 -177
- data/lib/bullet/active_record52.rb +191 -166
- data/lib/bullet/active_record60.rb +278 -0
- data/lib/bullet/active_record61.rb +278 -0
- data/lib/bullet/bullet_xhr.js +63 -0
- data/lib/bullet/dependency.rb +54 -34
- data/lib/bullet/detector/association.rb +26 -20
- data/lib/bullet/detector/base.rb +1 -2
- data/lib/bullet/detector/counter_cache.rb +14 -9
- data/lib/bullet/detector/n_plus_one_query.rb +27 -17
- data/lib/bullet/detector/unused_eager_loading.rb +7 -3
- data/lib/bullet/ext/object.rb +5 -3
- data/lib/bullet/ext/string.rb +1 -1
- data/lib/bullet/mongoid4x.rb +4 -7
- data/lib/bullet/mongoid5x.rb +4 -7
- data/lib/bullet/mongoid6x.rb +8 -11
- data/lib/bullet/mongoid7x.rb +57 -0
- data/lib/bullet/notification/base.rb +15 -19
- data/lib/bullet/notification/n_plus_one_query.rb +2 -4
- data/lib/bullet/notification/unused_eager_loading.rb +2 -4
- data/lib/bullet/rack.rb +54 -28
- data/lib/bullet/stack_trace_filter.rb +39 -30
- data/lib/bullet/version.rb +1 -1
- data/lib/generators/bullet/install_generator.rb +26 -26
- data/perf/benchmark.rb +8 -14
- data/spec/bullet/detector/counter_cache_spec.rb +6 -6
- data/spec/bullet/detector/n_plus_one_query_spec.rb +30 -3
- data/spec/bullet/detector/unused_eager_loading_spec.rb +19 -6
- data/spec/bullet/ext/object_spec.rb +9 -4
- data/spec/bullet/notification/base_spec.rb +1 -3
- data/spec/bullet/notification/n_plus_one_query_spec.rb +16 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +5 -1
- data/spec/bullet/rack_spec.rb +140 -5
- data/spec/bullet/registry/association_spec.rb +2 -2
- data/spec/bullet/registry/base_spec.rb +1 -1
- data/spec/bullet_spec.rb +10 -29
- data/spec/integration/active_record/association_spec.rb +122 -118
- data/spec/integration/counter_cache_spec.rb +11 -31
- data/spec/integration/mongoid/association_spec.rb +18 -32
- data/spec/models/attachment.rb +5 -0
- data/spec/models/client.rb +2 -0
- data/spec/models/firm.rb +1 -0
- data/spec/models/folder.rb +1 -2
- data/spec/models/group.rb +3 -0
- data/spec/models/page.rb +1 -2
- data/spec/models/post.rb +15 -0
- data/spec/models/submission.rb +1 -0
- data/spec/models/user.rb +1 -0
- data/spec/models/writer.rb +1 -2
- data/spec/spec_helper.rb +6 -10
- data/spec/support/bullet_ext.rb +8 -9
- data/spec/support/mongo_seed.rb +2 -16
- data/spec/support/sqlite_seed.rb +17 -2
- data/test.sh +2 -0
- data/update.sh +1 -0
- 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, [
|
16
|
-
expect(CounterCache).to receive(:create_notification).with('Post', [
|
17
|
-
CounterCache.add_counter_cache(@post1, [
|
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, [
|
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, [
|
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
|
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([
|
80
|
-
expect(NPlusOneQuery).to receive(:create_notification).with([
|
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(
|
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(
|
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) { [
|
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(
|
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(
|
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(
|
72
|
-
|
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 '
|
20
|
+
context 'bullet_primary_key_value' do
|
21
21
|
it 'should return id' do
|
22
22
|
post = Post.first
|
23
|
-
expect(post.
|
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.
|
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.
|
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')
|
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
|
11
|
-
|
12
|
-
|
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
|
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
|
data/spec/bullet/rack_spec.rb
CHANGED
@@ -45,9 +45,9 @@ module Bullet
|
|
45
45
|
expect(middleware).not_to be_empty(response)
|
46
46
|
end
|
47
47
|
|
48
|
-
it 'should be
|
48
|
+
it 'should be false if response is not found' do
|
49
49
|
response = ['Not Found']
|
50
|
-
expect(middleware).
|
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
|
-
|
73
|
+
_, headers, response = middleware.call('Content-Type' => 'text/html')
|
73
74
|
expect(headers['Content-Length']).to eq('56')
|
74
|
-
expect(response).to eq([
|
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
|
-
|
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([
|
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([
|
23
|
+
expect(subject.similarly_associated('key3', Set.new(%w[value]))).to be_empty
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
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
|
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?
|
31
|
-
expect(Bullet::ActiveRecord).not_to receive(:enable) if defined?
|
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)
|
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)
|
57
|
-
$stdout = StringIO.new
|
58
|
-
end
|
52
|
+
before(:each) { $stdout = StringIO.new }
|
59
53
|
|
60
|
-
after(:each)
|
61
|
-
$stdout = STDOUT
|
62
|
-
end
|
54
|
+
after(:each) { $stdout = STDOUT }
|
63
55
|
|
64
56
|
context 'when debug is enabled' do
|
65
|
-
before(:each)
|
66
|
-
ENV['BULLET_DEBUG'] = 'true'
|
67
|
-
end
|
57
|
+
before(:each) { ENV['BULLET_DEBUG'] = 'true' }
|
68
58
|
|
69
|
-
after(:each)
|
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 }
|