honeybadger 1.16.7 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +19 -0
  3. data/README.md +37 -16
  4. data/bin/honeybadger +5 -0
  5. data/lib/honeybadger.rb +167 -191
  6. data/lib/honeybadger/agent.rb +136 -0
  7. data/lib/honeybadger/backend.rb +26 -0
  8. data/lib/honeybadger/backend/base.rb +66 -0
  9. data/lib/honeybadger/backend/debug.rb +12 -0
  10. data/lib/honeybadger/backend/null.rb +16 -0
  11. data/lib/honeybadger/backend/server.rb +51 -0
  12. data/lib/honeybadger/backend/test.rb +24 -0
  13. data/lib/honeybadger/backtrace.rb +29 -24
  14. data/lib/honeybadger/cli.rb +367 -0
  15. data/lib/honeybadger/config.rb +333 -0
  16. data/lib/honeybadger/config/callbacks.rb +70 -0
  17. data/lib/honeybadger/config/defaults.rb +175 -0
  18. data/lib/honeybadger/config/env.rb +40 -0
  19. data/lib/honeybadger/config/yaml.rb +43 -0
  20. data/lib/honeybadger/const.rb +28 -0
  21. data/lib/honeybadger/init/rails.rb +84 -0
  22. data/lib/honeybadger/init/sinatra.rb +27 -0
  23. data/lib/honeybadger/logging.rb +133 -0
  24. data/lib/honeybadger/notice.rb +243 -280
  25. data/lib/honeybadger/plugin.rb +110 -0
  26. data/lib/honeybadger/plugins/delayed_job.rb +22 -0
  27. data/lib/honeybadger/{integrations → plugins}/delayed_job/plugin.rb +6 -7
  28. data/lib/honeybadger/{integrations → plugins}/local_variables.rb +7 -8
  29. data/lib/honeybadger/{integrations → plugins}/net_http.rb +10 -8
  30. data/lib/honeybadger/plugins/passenger.rb +24 -0
  31. data/lib/honeybadger/plugins/rails.rb +61 -0
  32. data/lib/honeybadger/plugins/sidekiq.rb +35 -0
  33. data/lib/honeybadger/{integrations → plugins}/thor.rb +9 -8
  34. data/lib/honeybadger/{integrations → plugins}/unicorn.rb +10 -9
  35. data/lib/honeybadger/rack/error_notifier.rb +44 -27
  36. data/lib/honeybadger/rack/metrics_reporter.rb +41 -0
  37. data/lib/honeybadger/rack/request_hash.rb +50 -0
  38. data/lib/honeybadger/rack/user_feedback.rb +15 -10
  39. data/lib/honeybadger/rack/user_informer.rb +14 -3
  40. data/lib/honeybadger/trace.rb +185 -0
  41. data/lib/honeybadger/util/http.rb +79 -0
  42. data/lib/honeybadger/util/request_sanitizer.rb +35 -0
  43. data/lib/honeybadger/util/sanitizer.rb +71 -0
  44. data/lib/honeybadger/util/stats.rb +31 -0
  45. data/lib/honeybadger/version.rb +4 -0
  46. data/lib/honeybadger/worker.rb +224 -0
  47. data/lib/honeybadger/worker/batch.rb +50 -0
  48. data/lib/honeybadger/worker/metered_queue.rb +80 -0
  49. data/lib/honeybadger/worker/metrics_collection.rb +61 -0
  50. data/lib/honeybadger/worker/metrics_collector.rb +96 -0
  51. data/{lib/honeybadger/capistrano.rb → vendor/capistrano-honeybadger/lib/capistrano/honeybadger.rb} +1 -3
  52. data/vendor/capistrano-honeybadger/lib/capistrano/tasks/deploy.cap +76 -0
  53. data/vendor/capistrano-honeybadger/lib/honeybadger/capistrano.rb +2 -0
  54. data/{lib → vendor/capistrano-honeybadger/lib}/honeybadger/capistrano/legacy.rb +16 -15
  55. data/vendor/thor/lib/thor.rb +484 -0
  56. data/vendor/thor/lib/thor/actions.rb +319 -0
  57. data/vendor/thor/lib/thor/actions/create_file.rb +103 -0
  58. data/vendor/thor/lib/thor/actions/create_link.rb +59 -0
  59. data/vendor/thor/lib/thor/actions/directory.rb +118 -0
  60. data/vendor/thor/lib/thor/actions/empty_directory.rb +135 -0
  61. data/vendor/thor/lib/thor/actions/file_manipulation.rb +316 -0
  62. data/vendor/thor/lib/thor/actions/inject_into_file.rb +107 -0
  63. data/vendor/thor/lib/thor/base.rb +656 -0
  64. data/vendor/thor/lib/thor/command.rb +133 -0
  65. data/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +77 -0
  66. data/vendor/thor/lib/thor/core_ext/io_binary_read.rb +10 -0
  67. data/vendor/thor/lib/thor/core_ext/ordered_hash.rb +98 -0
  68. data/vendor/thor/lib/thor/error.rb +32 -0
  69. data/vendor/thor/lib/thor/group.rb +281 -0
  70. data/vendor/thor/lib/thor/invocation.rb +178 -0
  71. data/vendor/thor/lib/thor/line_editor.rb +17 -0
  72. data/vendor/thor/lib/thor/line_editor/basic.rb +35 -0
  73. data/vendor/thor/lib/thor/line_editor/readline.rb +88 -0
  74. data/vendor/thor/lib/thor/parser.rb +4 -0
  75. data/vendor/thor/lib/thor/parser/argument.rb +73 -0
  76. data/vendor/thor/lib/thor/parser/arguments.rb +175 -0
  77. data/vendor/thor/lib/thor/parser/option.rb +125 -0
  78. data/vendor/thor/lib/thor/parser/options.rb +218 -0
  79. data/vendor/thor/lib/thor/rake_compat.rb +71 -0
  80. data/vendor/thor/lib/thor/runner.rb +322 -0
  81. data/vendor/thor/lib/thor/shell.rb +81 -0
  82. data/vendor/thor/lib/thor/shell/basic.rb +421 -0
  83. data/vendor/thor/lib/thor/shell/color.rb +149 -0
  84. data/vendor/thor/lib/thor/shell/html.rb +126 -0
  85. data/vendor/thor/lib/thor/util.rb +267 -0
  86. data/vendor/thor/lib/thor/version.rb +3 -0
  87. metadata +97 -305
  88. data/Appraisals +0 -95
  89. data/CHANGELOG.md +0 -422
  90. data/Gemfile +0 -8
  91. data/Gemfile.lock +0 -136
  92. data/Guardfile +0 -5
  93. data/MIT-LICENSE +0 -32
  94. data/Rakefile +0 -159
  95. data/features/metal.feature +0 -20
  96. data/features/rack.feature +0 -55
  97. data/features/rails.feature +0 -343
  98. data/features/rails3.x.feature +0 -26
  99. data/features/rake.feature +0 -25
  100. data/features/sinatra.feature +0 -27
  101. data/features/standalone.feature +0 -73
  102. data/features/step_definitions/metal_steps.rb +0 -24
  103. data/features/step_definitions/rack_steps.rb +0 -18
  104. data/features/step_definitions/rails_steps.rb +0 -270
  105. data/features/step_definitions/rake_steps.rb +0 -17
  106. data/features/step_definitions/standalone_steps.rb +0 -12
  107. data/features/step_definitions/thor_steps.rb +0 -4
  108. data/features/support/env.rb +0 -22
  109. data/features/support/honeybadger_failure_shim.rb.template +0 -5
  110. data/features/support/honeybadger_shim.rb.template +0 -6
  111. data/features/support/rails.rb +0 -202
  112. data/features/support/rake/Rakefile +0 -68
  113. data/features/support/test.thor +0 -22
  114. data/features/thor.feature +0 -5
  115. data/gemfiles/binding_of_caller.gemfile +0 -13
  116. data/gemfiles/delayed_job.gemfile +0 -13
  117. data/gemfiles/rack.gemfile +0 -13
  118. data/gemfiles/rails.gemfile +0 -16
  119. data/gemfiles/rails2.3.gemfile +0 -15
  120. data/gemfiles/rails3.0.gemfile +0 -16
  121. data/gemfiles/rails3.1.gemfile +0 -16
  122. data/gemfiles/rails3.2.gemfile +0 -16
  123. data/gemfiles/rails4.0.gemfile +0 -16
  124. data/gemfiles/rails4.1.gemfile +0 -16
  125. data/gemfiles/rake.gemfile +0 -13
  126. data/gemfiles/sinatra.gemfile +0 -13
  127. data/gemfiles/standalone.gemfile +0 -12
  128. data/gemfiles/thor.gemfile +0 -13
  129. data/generators/honeybadger/honeybadger_generator.rb +0 -95
  130. data/generators/honeybadger/lib/insert_commands.rb +0 -34
  131. data/generators/honeybadger/lib/rake_commands.rb +0 -24
  132. data/generators/honeybadger/templates/capistrano_hook.rb +0 -6
  133. data/generators/honeybadger/templates/honeybadger_tasks.rake +0 -25
  134. data/generators/honeybadger/templates/initializer.rb +0 -6
  135. data/honeybadger.gemspec +0 -174
  136. data/lib/honeybadger/array.rb +0 -53
  137. data/lib/honeybadger/capistrano/tasks.rake +0 -73
  138. data/lib/honeybadger/configuration.rb +0 -397
  139. data/lib/honeybadger/dependency.rb +0 -65
  140. data/lib/honeybadger/integrations.rb +0 -9
  141. data/lib/honeybadger/integrations/delayed_job.rb +0 -20
  142. data/lib/honeybadger/integrations/passenger.rb +0 -18
  143. data/lib/honeybadger/integrations/sidekiq.rb +0 -37
  144. data/lib/honeybadger/monitor.rb +0 -17
  145. data/lib/honeybadger/monitor/railtie.rb +0 -53
  146. data/lib/honeybadger/monitor/sender.rb +0 -44
  147. data/lib/honeybadger/monitor/trace.rb +0 -187
  148. data/lib/honeybadger/monitor/worker.rb +0 -169
  149. data/lib/honeybadger/payload.rb +0 -101
  150. data/lib/honeybadger/rack.rb +0 -12
  151. data/lib/honeybadger/rails.rb +0 -45
  152. data/lib/honeybadger/rails/action_controller_catcher.rb +0 -30
  153. data/lib/honeybadger/rails/controller_methods.rb +0 -78
  154. data/lib/honeybadger/rails/middleware/exceptions_catcher.rb +0 -29
  155. data/lib/honeybadger/rails3_tasks.rb +0 -94
  156. data/lib/honeybadger/railtie.rb +0 -52
  157. data/lib/honeybadger/rake_handler.rb +0 -66
  158. data/lib/honeybadger/sender.rb +0 -185
  159. data/lib/honeybadger/shared_tasks.rb +0 -56
  160. data/lib/honeybadger/stats.rb +0 -29
  161. data/lib/honeybadger/tasks.rb +0 -95
  162. data/lib/honeybadger/user_feedback.rb +0 -8
  163. data/lib/honeybadger/user_informer.rb +0 -8
  164. data/lib/honeybadger_tasks.rb +0 -69
  165. data/lib/rails/generators/honeybadger/honeybadger_generator.rb +0 -99
  166. data/rails/init.rb +0 -1
  167. data/resources/README.md +0 -34
  168. data/script/integration_test.rb +0 -38
  169. data/spec/allocation_stats.rb +0 -32
  170. data/spec/honeybadger/backtrace_spec.rb +0 -242
  171. data/spec/honeybadger/capistrano_spec.rb +0 -36
  172. data/spec/honeybadger/configuration_spec.rb +0 -328
  173. data/spec/honeybadger/dependency_spec.rb +0 -134
  174. data/spec/honeybadger/integrations/delayed_job_spec.rb +0 -82
  175. data/spec/honeybadger/integrations/local_variables_spec.rb +0 -60
  176. data/spec/honeybadger/integrations/net_http_spec.rb +0 -29
  177. data/spec/honeybadger/integrations/passenger_spec.rb +0 -29
  178. data/spec/honeybadger/integrations/sidekiq_spec.rb +0 -60
  179. data/spec/honeybadger/integrations/thor_spec.rb +0 -32
  180. data/spec/honeybadger/integrations/unicorn_spec.rb +0 -40
  181. data/spec/honeybadger/logger_spec.rb +0 -79
  182. data/spec/honeybadger/monitor/trace_spec.rb +0 -65
  183. data/spec/honeybadger/monitor/worker_spec.rb +0 -274
  184. data/spec/honeybadger/notice_spec.rb +0 -669
  185. data/spec/honeybadger/notifier_spec.rb +0 -328
  186. data/spec/honeybadger/payload_spec.rb +0 -162
  187. data/spec/honeybadger/rack_spec.rb +0 -85
  188. data/spec/honeybadger/rails/action_controller_spec.rb +0 -328
  189. data/spec/honeybadger/rails_spec.rb +0 -37
  190. data/spec/honeybadger/sender_spec.rb +0 -317
  191. data/spec/honeybadger/stats_spec.rb +0 -57
  192. data/spec/honeybadger/user_feedback_spec.rb +0 -80
  193. data/spec/honeybadger/user_informer_spec.rb +0 -30
  194. data/spec/honeybadger_tasks_spec.rb +0 -171
  195. data/spec/spec_helper.rb +0 -24
  196. data/spec/support/array_including.rb +0 -31
  197. data/spec/support/backtraced_exception.rb +0 -9
  198. data/spec/support/collected_sender.rb +0 -12
  199. data/spec/support/defines_constants.rb +0 -18
  200. data/spec/support/helpers.rb +0 -101
@@ -1,328 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'Honeybadger' do
4
- class OriginalException < Exception
5
- end
6
-
7
- class ContinuedException < Exception
8
- end
9
-
10
- def assert_sends(notice, notice_args)
11
- Honeybadger::Notice.should_receive(:new).with(hash_including(notice_args))
12
- Honeybadger.sender.should_receive(:send_to_honeybadger).with(notice)
13
- end
14
-
15
- def set_public_env
16
- Honeybadger.configure { |config| config.environment_name = 'production' }
17
- end
18
-
19
- def set_development_env
20
- Honeybadger.configure { |config| config.environment_name = 'development' }
21
- end
22
-
23
- before(:each) { reset_config }
24
-
25
- describe "#ping" do
26
- let(:config) { Honeybadger::Configuration.new }
27
- let(:sender) { double() }
28
-
29
- let(:invoke_subject) { Honeybadger.ping(config) }
30
- subject { invoke_subject }
31
-
32
- before do
33
- config.framework = 'Rails 4.1.0'
34
- config.environment_name = 'production'
35
- config.hostname = 'twix'
36
- stub_const('Honeybadger::VERSION', '1.11.0')
37
-
38
- Honeybadger.stub(:sender).and_return(sender)
39
- end
40
-
41
- context "configuration is public" do
42
- before { config.stub(:public?).and_return(true) }
43
-
44
- it "pings the sender" do
45
- sender.should_receive(:ping).with(hash_including(:version => '1.11.0', :framework => 'Rails 4.1.0', :environment => 'production', :hostname => 'twix'))
46
- invoke_subject
47
- end
48
-
49
- context "result is truthy" do
50
- before { sender.should_receive(:ping).and_return(result) }
51
- before { Honeybadger.stub(:write_verbose_log) }
52
-
53
- context "result does not contain features" do
54
- let(:result) { {} }
55
- it { should be_nil }
56
- specify { expect { subject }.not_to change(config, :features) }
57
- end
58
-
59
- context "result contains features" do
60
- let(:result) { {'features' => {'notices' => true, 'metrics' => true}} }
61
- it { should eq result['features'] }
62
- specify { expect { subject }.to change(config, :features).to(result['features']) }
63
- end
64
-
65
- context "metrics are disabled by service" do
66
- let(:result) { {'features' => {'metrics' => false}} }
67
- specify { expect { invoke_subject }.to change(config, :metrics).to(false) }
68
- end
69
-
70
- context "traces are disabled by service" do
71
- let(:result) { {'features' => {'traces' => false}} }
72
- specify { expect { invoke_subject }.to change(config, :traces).to(false) }
73
- end
74
- end
75
-
76
- context "result is falsey" do
77
- before { sender.should_receive(:ping) }
78
- it { should be_nil }
79
- specify { expect { invoke_subject }.not_to change(config, :features) }
80
- end
81
- end
82
-
83
- context "configuration is not public" do
84
- before { config.stub(:public?).and_return(false) }
85
- it { should be_nil }
86
-
87
- it "doesn't attempt to ping sender" do
88
- sender.should_not_receive(:ping)
89
- invoke_subject
90
- end
91
- end
92
- end
93
-
94
- it "yields and save a configuration when configuring" do
95
- yielded_configuration = nil
96
- Honeybadger.configure do |config|
97
- yielded_configuration = config
98
- end
99
-
100
- expect(yielded_configuration).to be_a Honeybadger::Configuration
101
- expect(yielded_configuration).to be Honeybadger.configuration
102
- end
103
-
104
- it "does not remove existing config options when configuring twice" do
105
- first_config = nil
106
- Honeybadger.configure do |config|
107
- first_config = config
108
- end
109
- Honeybadger.configure do |config|
110
- expect(config).to be first_config
111
- end
112
- end
113
-
114
- it "configures the sender" do
115
- sender = stub_sender
116
- Honeybadger::Sender.stub(:new => sender)
117
-
118
- Honeybadger.configure { |yielded_config| Honeybadger::Sender.should_receive(:new).with(yielded_config) }
119
- expect(Honeybadger.sender).to be sender
120
- end
121
-
122
- it "creates and send a notice asynchronously" do
123
- set_public_env
124
- notice = stub_notice!
125
- notice_args = { :error_message => 'uh oh' }
126
-
127
- async_expectation = double(:received => true)
128
- async_handler = Proc.new do |n|
129
- async_expectation.received
130
- n.deliver
131
- end
132
-
133
- Honeybadger.configure do |config|
134
- config.async = async_handler
135
- end
136
-
137
- stub_sender!
138
-
139
- async_expectation.should_receive(:received)
140
- assert_sends(notice, notice_args)
141
-
142
- Honeybadger.notify(notice_args)
143
- end
144
-
145
- it "creates and send a notice for an exception" do
146
- set_public_env
147
- exception = build_exception
148
- stub_sender!
149
- notice = stub_notice!
150
-
151
- assert_sends notice, :exception => exception
152
- Honeybadger.notify(exception)
153
- end
154
-
155
- it "creates and send a notice for a hash" do
156
- set_public_env
157
- notice = stub_notice!
158
- notice_args = { :error_message => 'uh oh' }
159
- stub_sender!
160
-
161
- assert_sends(notice, notice_args)
162
- Honeybadger.notify(notice_args)
163
- end
164
-
165
- it "does not pass the hash as an exception when sending a notice for it" do
166
- set_public_env
167
- stub_notice!
168
- notice_args = { :error_message => 'uh oh' }
169
- stub_sender!
170
-
171
- Honeybadger::Notice.should_receive(:new).with(hash_excluding(:exception))
172
- Honeybadger.notify(notice_args)
173
- end
174
-
175
- it "creates and send a notice for an exception that responds to to_hash" do
176
- set_public_env
177
- exception = build_exception
178
- notice = stub_notice!
179
- notice_args = { :error_message => 'uh oh' }
180
- exception.stub(:to_hash).and_return(notice_args)
181
- stub_sender!
182
-
183
- assert_sends(notice, notice_args.merge(:exception => exception))
184
- Honeybadger.notify(exception)
185
- end
186
-
187
- it "creates and sent a notice for an exception and hash" do
188
- set_public_env
189
- exception = build_exception
190
- notice = stub_notice!
191
- notice_args = { :error_message => 'uh oh' }
192
- stub_sender!
193
-
194
- assert_sends(notice, notice_args.merge(:exception => exception))
195
- Honeybadger.notify(exception, notice_args)
196
- end
197
-
198
- it "does not create a notice in a development environment" do
199
- set_development_env
200
- sender = stub_sender!
201
-
202
- sender.should_receive(:send_to_honeybadger).never
203
-
204
- Honeybadger.notify(build_exception)
205
- Honeybadger.notify_or_ignore(build_exception)
206
- end
207
-
208
- it "does not deliver an ignored exception when notifying implicitly" do
209
- set_public_env
210
- exception = build_exception
211
- sender = stub_sender!
212
- notice = stub_notice!
213
- notice.stub(:ignore? => true)
214
-
215
- sender.should_receive(:send_to_honeybadger).never
216
-
217
- Honeybadger.notify_or_ignore(exception)
218
- end
219
-
220
- it "delivers an ignored exception when notifying manually" do
221
- set_public_env
222
- exception = build_exception
223
- stub_sender!
224
- notice = stub_notice!
225
- notice.stub(:ignore? => true)
226
-
227
- assert_sends(notice, :exception => exception)
228
- Honeybadger.notify(exception)
229
- end
230
-
231
- it "passes config to created notices" do
232
- exception = build_exception
233
- config_opts = { 'one' => 'two', 'three' => 'four' }
234
- stub_notice!
235
- stub_sender!
236
- Honeybadger.configuration = double('config', :merge => config_opts, :public? => true, :async? => false, :unwrap_exceptions => false)
237
-
238
- Honeybadger::Notice.should_receive(:new).with(hash_including(config_opts))
239
- Honeybadger.notify(exception)
240
- end
241
-
242
- context "building notice JSON for an exception" do
243
- before(:each) do
244
- @params = { :controller => "users", :action => "create" }
245
- @exception = build_exception
246
- @hash = Honeybadger.build_lookup_hash_for(@exception, @params)
247
- end
248
-
249
- it "sets action" do
250
- expect(@hash[:action]).to eq @params[:action]
251
- end
252
-
253
- it "sets controller" do
254
- expect(@hash[:component]).to eq @params[:controller]
255
- end
256
-
257
- it "sets line number" do
258
- expect(@hash[:line_number]).to match /\d+/
259
- end
260
-
261
- it "sets file" do
262
- expect(@hash[:file]).to match /honeybadger\/rack_test\.rb$/
263
- end
264
-
265
- it "sets environment_name to production" do
266
- expect(@hash[:environment_name]).to eq 'production'
267
- end
268
-
269
- it "sets error class" do
270
- expect(@hash[:error_class]).to eq @exception.class.to_s
271
- end
272
-
273
- it "does not set file or line number with no backtrace" do
274
- @exception.stub(:backtrace).and_return([])
275
-
276
- @hash = Honeybadger.build_lookup_hash_for(@exception)
277
-
278
- @hash[:line_number].should be_nil
279
- @hash[:file].should be_nil
280
- end
281
-
282
- it "does not set action or controller when not provided" do
283
- @hash = Honeybadger.build_lookup_hash_for(@exception)
284
-
285
- @hash[:action].should be_nil
286
- @hash[:controller].should be_nil
287
- end
288
-
289
- context "when an exception that provides #original_exception is raised" do
290
- before(:each) do
291
- @exception.stub(:original_exception).and_return(begin
292
- raise OriginalException.new
293
- rescue Exception => e
294
- e
295
- end)
296
- end
297
-
298
- it "unwraps exceptions that provide #original_exception" do
299
- @hash = Honeybadger.build_lookup_hash_for(@exception)
300
- expect(@hash[:error_class]).to eq "OriginalException"
301
- end
302
-
303
- context "but unwrapping exceptions is disabled" do
304
- before { Honeybadger.configuration.unwrap_exceptions = false }
305
-
306
- it "doesn't unwrap the exception" do
307
- @hash = Honeybadger.build_lookup_hash_for(@exception)
308
- expect(@hash[:error_class]).not_to eq "OriginalException"
309
- end
310
- end
311
- end
312
-
313
- context "when an exception that provides #continued_exception is raised" do
314
- before(:each) do
315
- @exception.stub(:continued_exception).and_return(begin
316
- raise ContinuedException.new
317
- rescue Exception => e
318
- e
319
- end)
320
- end
321
-
322
- it "unwraps exceptions that provide #continued_exception" do
323
- @hash = Honeybadger.build_lookup_hash_for(@exception)
324
- expect(@hash[:error_class]).to eq "ContinuedException"
325
- end
326
- end
327
- end
328
- end
@@ -1,162 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Honeybadger::Payload do
4
- its(:max_depth) { should eq 20 }
5
-
6
- context "when max_depth option is passed to #initialize" do
7
- subject { described_class.new({}, :max_depth => 5) }
8
- its(:max_depth) { should eq 5 }
9
-
10
- context "when initialized with a bad object" do
11
- it "raises ArgumentError" do
12
- expect { described_class.new([], :max_depth => 5) }.to raise_error(ArgumentError)
13
- end
14
- end
15
- end
16
-
17
- describe "#sanitize" do
18
- let(:deep_hash) { {}.tap {|h| 30.times.each {|i| h = h[i.to_s] = {:string => 'string'} }} }
19
- let(:expected_hash) { {}.tap {|h| max_depth.times.each {|i| h = h[i.to_s] = (i < max_depth-1 ? {:string => 'string'} : '[max depth reached]') }} }
20
- let(:sanitized_hash) { described_class.new(deep_hash, :max_depth => max_depth) }
21
- let(:max_depth) { 10 }
22
-
23
- it "truncates nested hashes to max_depth" do
24
- expect(sanitized_hash['0']).to eq(expected_hash['0'])
25
- end
26
-
27
- it "does not allow infinite recursion" do
28
- hash = {:a => :a}
29
- hash[:hash] = hash
30
- payload = described_class.new(:request => {:params => hash})
31
- expect(payload.request[:params][:hash]).to eq "[possible infinite recursion halted]"
32
- end
33
-
34
- it "converts unserializable objects to strings" do
35
- assert_serializes(:request, :parameters)
36
- assert_serializes(:request, :cgi_data)
37
- assert_serializes(:request, :session_data)
38
- assert_serializes(:request, :local_variables)
39
- end
40
-
41
- it "ensures #to_hash is called on objects that support it" do
42
- expect { described_class.new(:session => { :object => double(:to_hash => {}) }) }.not_to raise_error
43
- end
44
-
45
- it "ensures #to_ary is called on objects that support it" do
46
- expect { described_class.new(:session => { :object => double(:to_ary => {}) }) }.not_to raise_error
47
- end
48
- end
49
-
50
- it "filters parameters" do
51
- assert_filters_request(:params)
52
- end
53
-
54
- it "filters cgi data" do
55
- assert_filters_request(:cgi_data)
56
- end
57
-
58
- it "filters session" do
59
- assert_filters_request(:session)
60
- end
61
-
62
- it "filters local_variables" do
63
- assert_filters_request(:local_variables)
64
- end
65
-
66
- context 'filtered parameters in query string' do
67
- let(:params_filters) { [:foo, :bar] }
68
-
69
- describe '#url' do
70
- subject { described_class.new({:request => {:url => 'https://www.honeybadger.io/?foo=1&bar=2&baz=3'}}, :filters => params_filters).request[:url] }
71
-
72
- it 'filters query' do
73
- expect(subject).to eq 'https://www.honeybadger.io/?foo=[FILTERED]&bar=[FILTERED]&baz=3'
74
- end
75
- end
76
-
77
- describe '#cgi_data' do
78
- let(:cgi_data) { { 'QUERY_STRING' => 'foo=1&bar=2&baz=3', 'ORIGINAL_FULLPATH' => '/?foo=1&bar=2&baz=3' } }
79
-
80
- subject { described_class.new({:request => {:cgi_data => cgi_data}}, :filters => params_filters).request[:cgi_data] }
81
-
82
- it 'filters QUERY_STRING key' do
83
- expect(subject['QUERY_STRING']).to eq 'foo=[FILTERED]&bar=[FILTERED]&baz=3'
84
- end
85
-
86
- it 'filters ORIGINAL_FULLPATH key' do
87
- expect(subject['ORIGINAL_FULLPATH']).to eq '/?foo=[FILTERED]&bar=[FILTERED]&baz=3'
88
- end
89
- end
90
- end
91
-
92
- describe '#filter_url!' do
93
- subject { described_class.new.send(:filter_url!, url) }
94
-
95
- context 'malformed query' do
96
- let(:url) { 'https://www.honeybadger.io/?foobar12' }
97
- it { should eq url }
98
- end
99
-
100
- context 'no query' do
101
- let(:url) { 'https://www.honeybadger.io' }
102
- it { should eq url }
103
- end
104
-
105
- context 'malformed url' do
106
- let(:url) { 'http s ! honeybadger' }
107
- before { expect { URI.parse(url) }.to raise_error }
108
- it { should eq url }
109
- end
110
-
111
- context 'complex url' do
112
- let(:url) { 'https://foo:bar@www.honeybadger.io:123/asdf/?foo=1&bar=2&baz=3' }
113
- it { should eq url }
114
- end
115
- end
116
-
117
- def assert_serializes(*keys)
118
- [File.open(__FILE__), Proc.new { puts "boo!" }, Module.new].each do |object|
119
- hash = {
120
- :strange_object => object,
121
- :sub_hash => {
122
- :sub_object => object
123
- },
124
- :array => [object]
125
- }
126
-
127
- payload_keys = keys.dup
128
- last_key = payload_keys.pop
129
- payload = described_class.new(payload_keys.reverse.reduce({last_key => hash}) { |a,k| {k => a} })
130
-
131
- first_key = keys.shift
132
- hash = keys.reduce(payload[first_key]) {|a,k| a[k] }
133
-
134
- expect(hash[:strange_object]).to eq object.to_s # objects should be serialized
135
- expect(hash[:sub_hash]).to be_a Hash # subhashes should be kept
136
- expect(hash[:sub_hash][:sub_object]).to eq object.to_s # subhash members should be serialized
137
- expect(hash[:array]).to be_a Array # arrays should be kept
138
- expect(hash[:array].first).to eq object.to_s # array members should be serialized
139
- end
140
- end
141
-
142
- def assert_filters_request(attribute)
143
- filters = ["abc", :def, /private/, /^foo_.*$/]
144
- original = { 'abc' => "123", 'def' => "456", 'ghi' => "789", 'nested' => { 'abc' => '100' },
145
- 'something_with_abc' => 'match the entire string', 'private_param' => 'prra',
146
- 'foo_param' => 'bar', 'not_foo_param' => 'baz', 'nested_foo' => { 'foo_nested' => 'bla'} }
147
- filtered = { 'abc' => "[FILTERED]",
148
- 'def' => "[FILTERED]",
149
- 'something_with_abc' => "match the entire string",
150
- 'ghi' => "789",
151
- 'nested' => { 'abc' => '[FILTERED]' },
152
- 'private_param' => '[FILTERED]',
153
- 'foo_param' => '[FILTERED]',
154
- 'not_foo_param' => 'baz',
155
- 'nested_foo' => { 'foo_nested' => '[FILTERED]'}
156
- }
157
-
158
- payload = described_class.new({:request => {attribute => original}}, {:filters => filters})
159
-
160
- expect(payload.request[attribute]).to eq filtered
161
- end
162
- end