rollbar 2.10.0 → 2.11.0

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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -2
  3. data/CHANGELOG.md +20 -0
  4. data/README.md +73 -16
  5. data/docs/configuration.md +10 -0
  6. data/gemfiles/rails30.gemfile +2 -0
  7. data/gemfiles/rails31.gemfile +2 -0
  8. data/gemfiles/rails32.gemfile +2 -0
  9. data/gemfiles/rails40.gemfile +2 -0
  10. data/gemfiles/rails41.gemfile +2 -0
  11. data/gemfiles/rails42.gemfile +2 -0
  12. data/gemfiles/rails50.gemfile +2 -0
  13. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +43 -0
  14. data/lib/rollbar.rb +139 -353
  15. data/lib/rollbar/configuration.rb +4 -0
  16. data/lib/rollbar/item.rb +225 -0
  17. data/lib/rollbar/item/backtrace.rb +97 -0
  18. data/lib/rollbar/js.rb +0 -28
  19. data/lib/rollbar/language_support.rb +10 -0
  20. data/lib/rollbar/{js/middleware.rb → middleware/js.rb} +3 -4
  21. data/lib/rollbar/plugin.rb +63 -0
  22. data/lib/rollbar/plugins.rb +41 -0
  23. data/lib/rollbar/{active_job.rb → plugins/active_job.rb} +0 -0
  24. data/lib/rollbar/plugins/basic_socket.rb +16 -0
  25. data/lib/rollbar/plugins/delayed_job.rb +12 -0
  26. data/lib/rollbar/plugins/delayed_job/job_data.rb +16 -0
  27. data/lib/rollbar/{delayed_job.rb → plugins/delayed_job/plugin.rb} +1 -17
  28. data/lib/rollbar/plugins/goalie.rb +46 -0
  29. data/lib/rollbar/plugins/rack.rb +16 -0
  30. data/lib/rollbar/plugins/rails.rb +77 -0
  31. data/lib/rollbar/{rails → plugins/rails}/controller_methods.rb +0 -0
  32. data/lib/rollbar/plugins/rails/railtie30.rb +17 -0
  33. data/lib/rollbar/plugins/rails/railtie32.rb +18 -0
  34. data/lib/rollbar/plugins/rails/railtie_mixin.rb +33 -0
  35. data/lib/rollbar/plugins/rake.rb +45 -0
  36. data/lib/rollbar/plugins/sidekiq.rb +35 -0
  37. data/lib/rollbar/{sidekiq.rb → plugins/sidekiq/plugin.rb} +0 -18
  38. data/lib/rollbar/plugins/thread.rb +13 -0
  39. data/lib/rollbar/plugins/validations.rb +33 -0
  40. data/lib/rollbar/request_data_extractor.rb +30 -18
  41. data/lib/rollbar/scrubbers/params.rb +4 -2
  42. data/lib/rollbar/scrubbers/url.rb +30 -28
  43. data/lib/rollbar/util.rb +10 -0
  44. data/lib/rollbar/version.rb +1 -1
  45. data/spec/controllers/home_controller_spec.rb +4 -3
  46. data/spec/dummyapp/app/models/post.rb +9 -0
  47. data/spec/dummyapp/app/models/user.rb +2 -0
  48. data/spec/dummyapp/config/initializers/rollbar.rb +1 -0
  49. data/spec/fixtures/plugins/dummy1.rb +5 -0
  50. data/spec/fixtures/plugins/dummy2.rb +5 -0
  51. data/spec/rollbar/item_spec.rb +635 -0
  52. data/spec/rollbar/logger_proxy_spec.rb +4 -0
  53. data/spec/rollbar/{js/middleware_spec.rb → middleware/js_spec.rb} +32 -3
  54. data/spec/rollbar/plugin_spec.rb +147 -0
  55. data/spec/rollbar/{active_job_spec.rb → plugins/active_job_spec.rb} +0 -1
  56. data/spec/rollbar/{delayed_job → plugins/delayed_job}/job_data.rb +0 -0
  57. data/spec/rollbar/{delayed_job_spec.rb → plugins/delayed_job_spec.rb} +3 -6
  58. data/spec/rollbar/{middleware/rack/builder_spec.rb → plugins/rack_spec.rb} +2 -1
  59. data/spec/rollbar/{js/frameworks/rails_spec.rb → plugins/rails_js_spec.rb} +1 -1
  60. data/spec/rollbar/{rake_spec.rb → plugins/rake_spec.rb} +2 -1
  61. data/spec/rollbar/{sidekiq_spec.rb → plugins/sidekiq_spec.rb} +2 -1
  62. data/spec/rollbar/plugins/validations_spec.rb +43 -0
  63. data/spec/rollbar/plugins_spec.rb +68 -0
  64. data/spec/rollbar/request_data_extractor_spec.rb +56 -10
  65. data/spec/rollbar/scrubbers/params_spec.rb +13 -10
  66. data/spec/rollbar/scrubbers/url_spec.rb +17 -12
  67. data/spec/rollbar/sidekig/clear_scope_spec.rb +2 -1
  68. data/spec/rollbar/util_spec.rb +61 -0
  69. data/spec/rollbar_bc_spec.rb +10 -10
  70. data/spec/rollbar_spec.rb +57 -706
  71. data/spec/spec_helper.rb +8 -0
  72. data/spec/support/notifier_helpers.rb +1 -0
  73. data/spec/support/rollbar_api.rb +57 -0
  74. metadata +57 -33
  75. data/lib/rollbar/active_record_extension.rb +0 -14
  76. data/lib/rollbar/core_ext/basic_socket.rb +0 -7
  77. data/lib/rollbar/core_ext/thread.rb +0 -9
  78. data/lib/rollbar/goalie.rb +0 -33
  79. data/lib/rollbar/js/frameworks.rb +0 -6
  80. data/lib/rollbar/js/frameworks/rails.rb +0 -49
  81. data/lib/rollbar/js/version.rb +0 -5
  82. data/lib/rollbar/rack.rb +0 -9
  83. data/lib/rollbar/railtie.rb +0 -46
  84. data/lib/rollbar/rake.rb +0 -40
@@ -15,8 +15,11 @@ describe Rollbar::Scrubbers::Params do
15
15
  end
16
16
 
17
17
  describe '#call' do
18
- before do
19
- allow(Rollbar.configuration).to receive(:scrub_fields).and_return(scrub_config)
18
+ let(:options) do
19
+ {
20
+ :params => params,
21
+ :config => scrub_config
22
+ }
20
23
  end
21
24
 
22
25
  context 'with scrub fields configured' do
@@ -43,7 +46,7 @@ describe Rollbar::Scrubbers::Params do
43
46
  end
44
47
 
45
48
  it 'scrubs the required parameters' do
46
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
49
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
47
50
  end
48
51
  end
49
52
 
@@ -70,7 +73,7 @@ describe Rollbar::Scrubbers::Params do
70
73
  end
71
74
 
72
75
  it 'scrubs the required parameters' do
73
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
76
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
74
77
  end
75
78
  end
76
79
 
@@ -97,7 +100,7 @@ describe Rollbar::Scrubbers::Params do
97
100
  end
98
101
 
99
102
  it 'scrubs the required parameters' do
100
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
103
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
101
104
  end
102
105
  end
103
106
 
@@ -129,7 +132,7 @@ describe Rollbar::Scrubbers::Params do
129
132
  after { tempfile.close }
130
133
 
131
134
  it 'scrubs the required parameters' do
132
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
135
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
133
136
  end
134
137
  end
135
138
 
@@ -169,7 +172,7 @@ describe Rollbar::Scrubbers::Params do
169
172
  end
170
173
 
171
174
  it 'scrubs the required parameters' do
172
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
175
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
173
176
  end
174
177
 
175
178
  context 'if getting the attachment values fails' do
@@ -204,7 +207,7 @@ describe Rollbar::Scrubbers::Params do
204
207
  end
205
208
 
206
209
  it 'scrubs the required parameters' do
207
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
210
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
208
211
  end
209
212
  end
210
213
  end
@@ -218,7 +221,7 @@ describe Rollbar::Scrubbers::Params do
218
221
  end
219
222
 
220
223
  it 'scrubs the required parameters' do
221
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
224
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
222
225
  end
223
226
  end
224
227
  end
@@ -249,7 +252,7 @@ describe Rollbar::Scrubbers::Params do
249
252
  end
250
253
 
251
254
  it 'scrubs the required parameters' do
252
- expect(subject.call(params)).to be_eql_hash_with_regexes(result)
255
+ expect(subject.call(options)).to be_eql_hash_with_regexes(result)
253
256
  end
254
257
  end
255
258
  end
@@ -4,15 +4,15 @@ require 'rollbar/scrubbers/url'
4
4
 
5
5
  describe Rollbar::Scrubbers::URL do
6
6
  let(:options) do
7
- { :scrub_fields => [:password, :secret],
7
+ {
8
+ :url => url,
9
+ :scrub_fields => [:password, :secret],
8
10
  :scrub_user => false,
9
11
  :scrub_password => false,
10
12
  :randomize_scrub_length => true
11
13
  }
12
14
  end
13
15
 
14
- subject { described_class.new(options) }
15
-
16
16
  describe '#call' do
17
17
  context 'cannot scrub URLs' do
18
18
  next if Rollbar::LanguageSupport.can_scrub_url?
@@ -20,7 +20,7 @@ describe Rollbar::Scrubbers::URL do
20
20
  let(:url) { 'http://user:password@foo.com/some-interesting-path#fragment' }
21
21
 
22
22
  it 'returns the URL without any change' do
23
- expect(subject.call(url)).to be_eql(url)
23
+ expect(subject.call(options)).to be_eql(url)
24
24
  end
25
25
  end
26
26
 
@@ -31,14 +31,14 @@ describe Rollbar::Scrubbers::URL do
31
31
  let(:url) { 'http://user:password@foo.com/some-interesting-path#fragment' }
32
32
 
33
33
  it 'returns the URL without any change' do
34
- expect(subject.call(url)).to be_eql(url)
34
+ expect(subject.call(options)).to be_eql(url)
35
35
  end
36
36
 
37
37
  context 'with arrays in params' do
38
38
  let(:url) { 'http://user:password@foo.com/some-interesting-path?foo[]=1&foo[]=2' }
39
39
 
40
40
  it 'returns the URL without any change' do
41
- expect(subject.call(url)).to be_eql(url)
41
+ expect(subject.call(options)).to be_eql(url)
42
42
  end
43
43
  end
44
44
  end
@@ -46,6 +46,7 @@ describe Rollbar::Scrubbers::URL do
46
46
  context 'scrubbing user and password' do
47
47
  let(:options) do
48
48
  {
49
+ :url => url,
49
50
  :scrub_fields => [],
50
51
  :scrub_password => true,
51
52
  :scrub_user => true
@@ -57,7 +58,7 @@ describe Rollbar::Scrubbers::URL do
57
58
  it 'returns the URL without any change' do
58
59
  expected_url = /http:\/\/\*{3,8}:\*{3,8}@foo.com\/some-interesting\-path#fragment/
59
60
 
60
- expect(subject.call(url)).to match(expected_url)
61
+ expect(subject.call(options)).to match(expected_url)
61
62
  end
62
63
  end
63
64
 
@@ -67,7 +68,7 @@ describe Rollbar::Scrubbers::URL do
67
68
  it 'returns the URL with some params filtered' do
68
69
  expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password=\*{3,8}&secret=\*{3,8}#fragment/
69
70
 
70
- expect(subject.call(url)).to match(expected_url)
71
+ expect(subject.call(options)).to match(expected_url)
71
72
  end
72
73
 
73
74
  context 'having array params' do
@@ -76,14 +77,16 @@ describe Rollbar::Scrubbers::URL do
76
77
  it 'returns the URL with some params filtered' do
77
78
  expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password\[\]=\*{3,8}&password\[\]=\*{3,8}&secret=\*{3,8}#fragment/
78
79
 
79
- expect(subject.call(url)).to match(expected_url)
80
+ expect(subject.call(options)).to match(expected_url)
80
81
  end
81
82
  end
82
83
  end
83
84
 
84
85
  context 'with no-random scrub length' do
85
86
  let(:options) do
86
- { :scrub_fields => [:password, :secret],
87
+ {
88
+ :url => url,
89
+ :scrub_fields => [:password, :secret],
87
90
  :scrub_user => false,
88
91
  :scrub_password => false,
89
92
  :randomize_scrub_length => false
@@ -95,15 +98,17 @@ describe Rollbar::Scrubbers::URL do
95
98
  it 'scrubs with same length than the scrubbed param' do
96
99
  expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password=\*{#{password.length}}#fragment/
97
100
 
98
- expect(subject.call(url)).to match(expected_url)
101
+ expect(subject.call(options)).to match(expected_url)
99
102
  end
100
103
  end
101
104
 
102
105
  context 'with malformed URL or not able to be parsed' do
103
106
  let(:url) { '\this\is\not\a\valid\url' }
107
+ before { reconfigure_notifier }
104
108
 
105
109
  it 'return the same url' do
106
- expect(subject.call(url)).to be_eql(url)
110
+ expect(Rollbar.logger).to receive(:error).and_call_original
111
+ expect(subject.call(options)).to be_eql(url)
107
112
  end
108
113
  end
109
114
  end
@@ -2,9 +2,10 @@ require 'spec_helper'
2
2
 
3
3
  unless RUBY_VERSION == '1.8.7'
4
4
  require 'sidekiq'
5
- require 'rollbar/sidekiq'
6
5
  end
7
6
 
7
+ Rollbar.plugins.load!
8
+
8
9
  describe Rollbar::Sidekiq::ClearScope, :reconfigure_notifier => false do
9
10
  describe '#call' do
10
11
  let(:middleware_block) { proc{} }
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  require 'rollbar/util'
@@ -16,4 +18,63 @@ describe Rollbar::Util do
16
18
  end
17
19
  end
18
20
  end
21
+
22
+ describe '.enforce_valid_utf8' do
23
+ # TODO(jon): all these tests should be removed since they are in
24
+ # in spec/rollbar/encoding/encoder.rb.
25
+ #
26
+ # This should just check that in payload with simple values and
27
+ # nested values are each one passed through Rollbar::Encoding.encode
28
+ context 'with utf8 string and ruby > 1.8' do
29
+ next unless String.instance_methods.include?(:force_encoding)
30
+
31
+ let(:payload) { { :foo => 'Изменение' } }
32
+
33
+ it 'just returns the same string' do
34
+ payload_copy = payload.clone
35
+ described_class.enforce_valid_utf8(payload_copy)
36
+
37
+ expect(payload_copy[:foo]).to be_eql('Изменение')
38
+ end
39
+ end
40
+
41
+ it 'should replace invalid utf8 values' do
42
+ bad_key = force_to_ascii("inner \x92bad key")
43
+
44
+ payload = {
45
+ :bad_value => force_to_ascii("bad value 1\255"),
46
+ :bad_value_2 => force_to_ascii("bad\255 value 2"),
47
+ force_to_ascii("bad\255 key") => "good value",
48
+ :hash => {
49
+ :inner_bad_value => force_to_ascii("\255\255bad value 3"),
50
+ bad_key.to_sym => 'inner good value',
51
+ force_to_ascii("bad array key\255") => [
52
+ 'good array value 1',
53
+ force_to_ascii("bad\255 array value 1\255"),
54
+ {
55
+ :inner_inner_bad => force_to_ascii("bad inner \255inner value")
56
+ }
57
+ ]
58
+ }
59
+ }
60
+
61
+
62
+ payload_copy = payload.clone
63
+ described_class.enforce_valid_utf8(payload_copy)
64
+
65
+ payload_copy[:bad_value].should == "bad value 1"
66
+ payload_copy[:bad_value_2].should == "bad value 2"
67
+ payload_copy["bad key"].should == "good value"
68
+ payload_copy.keys.should_not include("bad\456 key")
69
+ payload_copy[:hash][:inner_bad_value].should == "bad value 3"
70
+ payload_copy[:hash][:"inner bad key"].should == 'inner good value'
71
+ payload_copy[:hash]["bad array key"].should == [
72
+ 'good array value 1',
73
+ 'bad array value 1',
74
+ {
75
+ :inner_inner_bad => 'bad inner inner value'
76
+ }
77
+ ]
78
+ end
79
+ end
19
80
  end
@@ -23,7 +23,7 @@ describe Rollbar do
23
23
  end
24
24
 
25
25
  it 'should report simple messages' do
26
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
26
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
27
27
  logger_mock.should_receive(:info).with('[Rollbar] Success')
28
28
 
29
29
  Rollbar.report_message('Test message')
@@ -87,7 +87,7 @@ describe Rollbar do
87
87
 
88
88
  it 'should report simple messages' do
89
89
  allow(Rollbar).to receive(:notifier).and_return(notifier)
90
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
90
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
91
91
  logger_mock.should_receive(:info).with('[Rollbar] Success')
92
92
  Rollbar.report_message_with_request('Test message')
93
93
 
@@ -98,7 +98,7 @@ describe Rollbar do
98
98
  it 'should report messages with request, person data and extra data' do
99
99
  Rollbar.last_report = nil
100
100
 
101
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
101
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
102
102
  logger_mock.should_receive(:info).with('[Rollbar] Success')
103
103
 
104
104
  request_data = {
@@ -206,7 +206,7 @@ describe Rollbar do
206
206
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && (not RUBY_VERSION =~ /^1\.9/)
207
207
  it 'should work with an IO object as rack.errors' do
208
208
  logger_mock.should_receive(:info).with('[Rollbar] Success')
209
-
209
+
210
210
  request_data = {
211
211
  :params => { :foo => 'bar' },
212
212
  :url => 'http://localhost/',
@@ -217,15 +217,15 @@ describe Rollbar do
217
217
  :method => 'GET',
218
218
  :env => { :'rack.errors' => IO.new(2, File::WRONLY) },
219
219
  }
220
-
220
+
221
221
  person_data = {
222
222
  :id => 1,
223
223
  :username => 'test',
224
224
  :email => 'test@example.com'
225
225
  }
226
-
226
+
227
227
  Rollbar.report_exception(@exception, request_data, person_data)
228
- end
228
+ end
229
229
  end
230
230
 
231
231
  it 'should ignore ignored exception classes' do
@@ -313,7 +313,7 @@ describe Rollbar do
313
313
 
314
314
  payload = nil
315
315
 
316
- notifier.stub(:schedule_payload) do |*args|
316
+ notifier.stub(:schedule_item) do |*args|
317
317
  payload = args[0]
318
318
  end
319
319
 
@@ -338,7 +338,7 @@ describe Rollbar do
338
338
 
339
339
  payload = nil
340
340
 
341
- notifier.stub(:schedule_payload) do |*args|
341
+ notifier.stub(:schedule_item) do |*args|
342
342
  payload = args[0]
343
343
  end
344
344
 
@@ -359,7 +359,7 @@ describe Rollbar do
359
359
  allow(Rollbar).to receive(:notifier).and_return(notifier)
360
360
  payload = nil
361
361
 
362
- notifier.stub(:schedule_payload) do |*args|
362
+ notifier.stub(:schedule_item) do |*args|
363
363
  payload = args[0]
364
364
  end
365
365
 
data/spec/rollbar_spec.rb CHANGED
@@ -7,6 +7,12 @@ require 'redis'
7
7
  require 'active_support/core_ext/object'
8
8
  require 'active_support/json/encoding'
9
9
 
10
+ require 'rollbar/item'
11
+ begin
12
+ require 'rollbar/delay/sidekiq'
13
+ rescue LoadError
14
+ end
15
+
10
16
  begin
11
17
  require 'sucker_punch'
12
18
  require 'sucker_punch/testing/inline'
@@ -109,6 +115,7 @@ describe Rollbar do
109
115
  let(:scope) { { :bar => :foo } }
110
116
  let(:configuration) do
111
117
  config = Rollbar::Configuration.new
118
+ config.access_token = test_access_token
112
119
  config.enabled = true
113
120
  config
114
121
  end
@@ -203,6 +210,7 @@ describe Rollbar do
203
210
  :message => message,
204
211
  :extra => extra
205
212
  }
213
+
206
214
  expect(handler1).to receive(:call).with(options).and_call_original
207
215
  expect(handler2).not_to receive(:call)
208
216
  expect(notifier).not_to receive(:report)
@@ -228,113 +236,6 @@ describe Rollbar do
228
236
  end
229
237
  end
230
238
 
231
- context 'with transform handlers in configuration' do
232
- let!(:notifier) { Rollbar::Notifier.new }
233
- let(:scope) { { :bar => :foo } }
234
- let(:configuration) do
235
- config = Rollbar::Configuration.new
236
- config.enabled = true
237
- config.access_token = test_access_token
238
- config
239
- end
240
- let(:message) { 'message' }
241
- let(:exception) { Exception.new }
242
- let(:extra) { {:foo => :bar } }
243
- let(:level) { 'error' }
244
-
245
- before do
246
- notifier.configuration = configuration
247
- notifier.scope!(scope)
248
- end
249
-
250
- context 'without mutation in payload' do
251
- let(:handler) do
252
- proc do |options|
253
-
254
- end
255
- end
256
-
257
- before do
258
- configuration.transform = handler
259
- end
260
-
261
- it 'calls the handler with the correct options' do
262
- options = {
263
- :level => level,
264
- :scope => Rollbar::LazyStore.new(scope),
265
- :exception => exception,
266
- :message => message,
267
- :extra => extra,
268
- :payload => kind_of(Hash)
269
- }
270
- expect(handler).to receive(:call).with(options).and_call_original
271
- expect(notifier).to receive(:schedule_payload).with(kind_of(Hash))
272
-
273
- notifier.log(level, message, exception, extra)
274
- end
275
- end
276
-
277
- context 'with mutation in payload' do
278
- let(:new_payload) do
279
- {
280
- 'access_token' => notifier.configuration.access_token,
281
- 'data' => {
282
- }
283
- }
284
- end
285
- let(:handler) do
286
- proc do |options|
287
- payload = options[:payload]
288
-
289
- payload.replace(new_payload)
290
- end
291
- end
292
-
293
- before do
294
- configuration.transform = handler
295
- end
296
-
297
- it 'calls the handler with the correct options' do
298
- options = {
299
- :level => level,
300
- :scope => Rollbar::LazyStore.new(scope),
301
- :exception => exception,
302
- :message => message,
303
- :extra => extra,
304
- :payload => kind_of(Hash)
305
- }
306
- expect(handler).to receive(:call).with(options).and_call_original
307
- expect(notifier).to receive(:schedule_payload).with(new_payload)
308
-
309
- notifier.log(level, message, exception, extra)
310
- end
311
- end
312
-
313
- context 'with two handlers' do
314
- let(:handler1) { proc { |options|} }
315
- let(:handler2) { proc { |options|} }
316
-
317
- before do
318
- configuration.transform << handler1
319
- configuration.transform << handler2
320
- end
321
-
322
- context 'and the first one fails' do
323
- let(:exception) { StandardError.new('foo') }
324
- let(:handler1) do
325
- proc { |options| raise exception }
326
- end
327
-
328
- it 'doesnt call the second handler and logs the error' do
329
- expect(handler2).not_to receive(:call)
330
- expect(notifier).to receive(:log_error).with("[Rollbar] Error calling the `transform` hook: #{exception}")
331
-
332
- notifier.log(level, message, exception, extra)
333
- end
334
- end
335
- end
336
- end
337
-
338
239
  context 'debug/info/warning/error/critical' do
339
240
  let(:exception) do
340
241
  begin
@@ -524,438 +425,6 @@ describe Rollbar do
524
425
  result.should == 'ignored'
525
426
  end
526
427
  end
527
-
528
- context 'build_payload' do
529
- context 'a basic payload' do
530
- let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
531
- let(:payload) { notifier.send(:build_payload, 'info', 'message', nil, extra_data) }
532
-
533
- it 'should have the correct root-level keys' do
534
- payload.keys.should match_array(['access_token', 'data'])
535
- end
536
-
537
- it 'should have the correct data keys' do
538
- payload['data'].keys.should include(:timestamp, :environment, :level, :language, :framework, :server,
539
- :notifier, :body)
540
- end
541
-
542
- it 'should have the correct notifier name and version' do
543
- payload['data'][:notifier][:name].should == 'rollbar-gem'
544
- payload['data'][:notifier][:version].should == Rollbar::VERSION
545
- end
546
-
547
- it 'should have the correct language and framework' do
548
- payload['data'][:language].should == 'ruby'
549
- payload['data'][:framework].should == Rollbar.configuration.framework
550
- payload['data'][:framework].should match(/^Rails/)
551
- end
552
-
553
- it 'should have the correct server keys' do
554
- payload['data'][:server].keys.should match_array([:host, :root, :pid])
555
- end
556
-
557
- it 'should have the correct level and message body' do
558
- payload['data'][:level].should == 'info'
559
- payload['data'][:body][:message][:body].should == 'message'
560
- end
561
- end
562
-
563
- it 'should merge in a new key from payload_options' do
564
- notifier.configure do |config|
565
- config.payload_options = { :some_new_key => 'some new value' }
566
- end
567
-
568
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
569
-
570
- payload['data'][:some_new_key].should == 'some new value'
571
- end
572
-
573
- it 'should overwrite existing keys from payload_options' do
574
- reconfigure_notifier
575
-
576
- payload_options = {
577
- :notifier => 'bad notifier',
578
- :server => { :host => 'new host', :new_server_key => 'value' }
579
- }
580
-
581
- notifier.configure do |config|
582
- config.payload_options = payload_options
583
- end
584
-
585
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
586
-
587
- payload['data'][:notifier].should == 'bad notifier'
588
- payload['data'][:server][:host].should == 'new host'
589
- payload['data'][:server][:root].should_not be_nil
590
- payload['data'][:server][:new_server_key].should == 'value'
591
- end
592
-
593
- it 'should have default environment "unspecified"' do
594
- Rollbar.unconfigure
595
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
596
- payload['data'][:environment].should == 'unspecified'
597
- end
598
-
599
- it 'should have an overridden environment' do
600
- Rollbar.configure do |config|
601
- config.environment = 'overridden'
602
- end
603
-
604
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
605
- payload['data'][:environment].should == 'overridden'
606
- end
607
-
608
- it 'should not have custom data under default configuration' do
609
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
610
- payload['data'][:body][:message][:extra].should be_nil
611
- end
612
-
613
- it 'should have custom message data when custom_data_method is configured' do
614
- Rollbar.configure do |config|
615
- config.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
616
- end
617
-
618
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
619
- payload['data'][:body][:message][:extra].should_not be_nil
620
- payload['data'][:body][:message][:extra][:a].should == 1
621
- payload['data'][:body][:message][:extra][:b][2].should == 4
622
- end
623
-
624
- it 'should merge extra data into custom message data' do
625
- custom_method = lambda do
626
- { :a => 1,
627
- :b => [2, 3, 4],
628
- :c => { :d => 'd', :e => 'e' },
629
- :f => ['1', '2']
630
- }
631
- end
632
-
633
- Rollbar.configure do |config|
634
- config.custom_data_method = custom_method
635
- end
636
-
637
- payload = notifier.send(:build_payload, 'info', 'message', nil, {:c => {:e => 'g'}, :f => 'f'})
638
- payload['data'][:body][:message][:extra].should_not be_nil
639
- payload['data'][:body][:message][:extra][:a].should == 1
640
- payload['data'][:body][:message][:extra][:b][2].should == 4
641
- payload['data'][:body][:message][:extra][:c][:d].should == 'd'
642
- payload['data'][:body][:message][:extra][:c][:e].should == 'g'
643
- payload['data'][:body][:message][:extra][:f].should == 'f'
644
- end
645
-
646
- context 'with custom_data_method crashing' do
647
- next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
648
-
649
- let(:crashing_exception) { StandardError.new }
650
- let(:custom_method) { proc { raise crashing_exception } }
651
- let(:extra) { { :foo => :bar } }
652
- let(:custom_data_report) do
653
- { :_error_in_custom_data_method => SecureRandom.uuid }
654
- end
655
- let(:expected_extra) { extra.merge(custom_data_report) }
656
-
657
- before do
658
- notifier.configure do |config|
659
- config.custom_data_method = custom_method
660
- end
661
- end
662
-
663
- it 'doesnt crash the report' do
664
- expect(notifier).to receive(:report_custom_data_error).once.and_return(custom_data_report)
665
- payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
666
-
667
- expect(payload['data'][:body][:message][:extra]).to be_eql(expected_extra)
668
- end
669
-
670
- context 'and for some reason the safely.error returns a String' do
671
- it 'returns an empty Hash' do
672
- allow_any_instance_of(Rollbar::Notifier).to receive(:error).and_return('ignored')
673
-
674
- payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
675
-
676
- expect(payload['data'][:body][:message][:extra]).to be_eql(extra)
677
- end
678
- end
679
- end
680
-
681
- it 'should include project_gem_paths' do
682
- gems = Gem::Specification.map(&:name)
683
- project_gems = ['rails']
684
- project_gems << 'rspec' if gems.include?('rspec')
685
- project_gems << 'rspec-core' if gems.include?('rspec-core')
686
-
687
- notifier.configure do |config|
688
- config.project_gems = project_gems
689
- end
690
-
691
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
692
- expect(payload['data'][:project_package_paths].count).to eq(project_gems.size)
693
- end
694
-
695
- it 'should include a code_version' do
696
- notifier.configure do |config|
697
- config.code_version = 'abcdef'
698
- end
699
-
700
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
701
-
702
- payload['data'][:code_version].should == 'abcdef'
703
- end
704
-
705
- it 'should have the right hostname' do
706
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
707
-
708
- payload['data'][:server][:host].should == Socket.gethostname
709
- end
710
-
711
- it 'should have root and branch set when configured' do
712
- configure
713
- Rollbar.configure do |config|
714
- config.root = '/path/to/root'
715
- config.branch = 'master'
716
- end
717
-
718
- payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
719
-
720
- payload['data'][:server][:root].should == '/path/to/root'
721
- payload['data'][:server][:branch].should == 'master'
722
- end
723
-
724
- context "with Redis instance in payload and ActiveSupport is enabled" do
725
- let(:redis) { ::Redis.new }
726
- let(:payload) do
727
- {
728
- :key => {
729
- :value => redis
730
- }
731
- }
732
- end
733
- it 'dumps to JSON correctly' do
734
- redis.set('foo', 'bar')
735
- json = notifier.send(:dump_payload, payload)
736
-
737
- expect(json).to be_kind_of(String)
738
- end
739
- end
740
- end
741
-
742
- context 'build_payload_body' do
743
- let(:exception) do
744
- begin
745
- foo = bar
746
- rescue => e
747
- e
748
- end
749
- end
750
-
751
- it 'should build a message body when no exception is passed in' do
752
- body = notifier.send(:build_payload_body, 'message', nil, nil)
753
- body[:message][:body].should == 'message'
754
- body[:message][:extra].should be_nil
755
- body[:trace].should be_nil
756
- end
757
-
758
- it 'should build a message body when no exception and extra data is passed in' do
759
- body = notifier.send(:build_payload_body, 'message', nil, {:a => 'b'})
760
- body[:message][:body].should == 'message'
761
- body[:message][:extra].should == {:a => 'b'}
762
- body[:trace].should be_nil
763
- end
764
-
765
- it 'should build an exception body when one is passed in' do
766
- body = notifier.send(:build_payload_body, 'message', exception, nil)
767
- body[:message].should be_nil
768
-
769
- trace = body[:trace]
770
- trace.should_not be_nil
771
- trace[:extra].should be_nil
772
-
773
- trace[:exception][:class].should_not be_nil
774
- trace[:exception][:message].should_not be_nil
775
- end
776
-
777
- it 'should build an exception body when one is passed in along with extra data' do
778
- body = notifier.send(:build_payload_body, 'message', exception, {:a => 'b'})
779
- body[:message].should be_nil
780
-
781
- trace = body[:trace]
782
- trace.should_not be_nil
783
-
784
- trace[:exception][:class].should_not be_nil
785
- trace[:exception][:message].should_not be_nil
786
- trace[:extra].should == {:a => 'b'}
787
- end
788
- end
789
-
790
- context 'build_payload_body_exception' do
791
- let(:exception) do
792
- begin
793
- foo = bar
794
- rescue => e
795
- e
796
- end
797
- end
798
-
799
- after(:each) do
800
- Rollbar.unconfigure
801
- configure
802
- end
803
-
804
- it 'should build valid exception data' do
805
- body = notifier.send(:build_payload_body_exception, nil, exception, nil)
806
- body[:message].should be_nil
807
-
808
- trace = body[:trace]
809
-
810
- frames = trace[:frames]
811
- frames.should be_a_kind_of(Array)
812
- frames.each do |frame|
813
- frame[:filename].should be_a_kind_of(String)
814
- frame[:lineno].should be_a_kind_of(Fixnum)
815
- if frame[:method]
816
- frame[:method].should be_a_kind_of(String)
817
- end
818
- end
819
-
820
- # should be NameError, but can be NoMethodError sometimes on rubinius 1.8
821
- # http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
822
- trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
823
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
824
- end
825
-
826
- it 'should build exception data with a description' do
827
- body = notifier.send(:build_payload_body_exception, 'exception description', exception, nil)
828
-
829
- trace = body[:trace]
830
-
831
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
832
- trace[:exception][:description].should == 'exception description'
833
- end
834
-
835
- it 'should build exception data with a description and extra data' do
836
- extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
837
- body = notifier.send(:build_payload_body_exception, 'exception description', exception, extra_data)
838
-
839
- trace = body[:trace]
840
-
841
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
842
- trace[:exception][:description].should == 'exception description'
843
- trace[:extra][:key].should == 'value'
844
- trace[:extra][:hash].should == {:inner_key => 'inner_value'}
845
- end
846
-
847
- it 'should build exception data with a extra data' do
848
- extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
849
- body = notifier.send(:build_payload_body_exception, nil, exception, extra_data)
850
-
851
- trace = body[:trace]
852
-
853
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
854
- trace[:extra][:key].should == 'value'
855
- trace[:extra][:hash].should == {:inner_key => 'inner_value'}
856
- end
857
-
858
- context 'with nested exceptions' do
859
- let(:crashing_code) do
860
- proc do
861
- begin
862
- begin
863
- fail CauseException.new('the cause')
864
- rescue
865
- fail StandardError.new('the error')
866
- end
867
- rescue => e
868
- e
869
- end
870
- end
871
- end
872
-
873
- let(:rescued_exception) { crashing_code.call }
874
- let(:message) { 'message' }
875
- let(:extra) { {} }
876
-
877
- context 'using ruby >= 2.1' do
878
- next unless Exception.instance_methods.include?(:cause)
879
-
880
- it 'sends the two exceptions in the trace_chain attribute' do
881
- body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
882
-
883
- body[:trace].should be_nil
884
- body[:trace_chain].should be_kind_of(Array)
885
-
886
- chain = body[:trace_chain]
887
- chain[0][:exception][:class].should match(/StandardError/)
888
- chain[0][:exception][:message].should match(/the error/)
889
-
890
- chain[1][:exception][:class].should match(/CauseException/)
891
- chain[1][:exception][:message].should match(/the cause/)
892
- end
893
-
894
- it 'ignores the cause when it is not an Exception' do
895
- exception_with_custom_cause = Exception.new('custom cause')
896
- allow(exception_with_custom_cause).to receive(:cause) { "Foo" }
897
- body = notifier.send(:build_payload_body_exception, message, exception_with_custom_cause, extra)
898
- body[:trace].should_not be_nil
899
- end
900
-
901
- context 'with cyclic nested exceptions' do
902
- let(:exception1) { Exception.new('exception1') }
903
- let(:exception2) { Exception.new('exception2') }
904
-
905
- before do
906
- allow(exception1).to receive(:cause).and_return(exception2)
907
- allow(exception2).to receive(:cause).and_return(exception1)
908
- end
909
-
910
- it 'doesnt loop for ever' do
911
- body = notifier.send(:build_payload_body_exception, message, exception1, extra)
912
- chain = body[:trace_chain]
913
-
914
- expect(chain[0][:exception][:message]).to be_eql('exception1')
915
- expect(chain[1][:exception][:message]).to be_eql('exception2')
916
- end
917
- end
918
- end
919
-
920
- context 'using ruby <= 2.1' do
921
- next if Exception.instance_methods.include?(:cause)
922
-
923
- it 'sends only the last exception in the trace attribute' do
924
- body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
925
-
926
- body[:trace].should be_kind_of(Hash)
927
- body[:trace_chain].should be_nil
928
-
929
- body[:trace][:exception][:class].should match(/StandardError/)
930
- body[:trace][:exception][:message].should match(/the error/)
931
- end
932
- end
933
- end
934
- end
935
-
936
- context 'build_payload_body_message' do
937
- it 'should build a message' do
938
- body = notifier.send(:build_payload_body_message, 'message', nil)
939
- body[:message][:body].should == 'message'
940
- body[:trace].should be_nil
941
- end
942
-
943
- it 'should build a message with extra data' do
944
- extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
945
- body = notifier.send(:build_payload_body_message, 'message', extra_data)
946
- body[:message][:body].should == 'message'
947
- body[:message][:extra][:key].should == 'value'
948
- body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
949
- end
950
-
951
- it 'should build an empty message with extra data' do
952
- extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
953
- body = notifier.send(:build_payload_body_message, nil, extra_data)
954
- body[:message][:body].should == 'Empty message'
955
- body[:message][:extra][:key].should == 'value'
956
- body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
957
- end
958
- end
959
428
  end
960
429
 
961
430
  context 'reporting' do
@@ -1089,7 +558,7 @@ describe Rollbar do
1089
558
  }
1090
559
 
1091
560
  Rollbar.configure do |config|
1092
- config.payload_options = {:person => person_data}
561
+ config.payload_options = { :person => person_data }
1093
562
  config.ignored_person_ids += [1]
1094
563
  end
1095
564
 
@@ -1168,7 +637,7 @@ describe Rollbar do
1168
637
  it 'should report exception objects with no backtrace' do
1169
638
  payload = nil
1170
639
 
1171
- notifier.stub(:schedule_payload) do |*args|
640
+ notifier.stub(:schedule_item) do |*args|
1172
641
  payload = args[0]
1173
642
  end
1174
643
 
@@ -1208,7 +677,7 @@ describe Rollbar do
1208
677
  it 'should report exception objects with nonstandard backtraces' do
1209
678
  payload = nil
1210
679
 
1211
- notifier.stub(:schedule_payload) do |*args|
680
+ notifier.stub(:schedule_item) do |*args|
1212
681
  payload = args[0]
1213
682
  end
1214
683
 
@@ -1228,7 +697,7 @@ describe Rollbar do
1228
697
  it 'should report exceptions with a custom level' do
1229
698
  payload = nil
1230
699
 
1231
- notifier.stub(:schedule_payload) do |*args|
700
+ notifier.stub(:schedule_item) do |*args|
1232
701
  payload = args[0]
1233
702
  end
1234
703
 
@@ -1268,7 +737,7 @@ describe Rollbar do
1268
737
  let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
1269
738
 
1270
739
  it 'should report simple messages' do
1271
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
740
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
1272
741
  logger_mock.should_receive(:info).with('[Rollbar] Success')
1273
742
  Rollbar.error('Test message')
1274
743
  end
@@ -1324,7 +793,7 @@ describe Rollbar do
1324
793
  end
1325
794
 
1326
795
  it 'should report messages with request, person data and extra data' do
1327
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
796
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
1328
797
  logger_mock.should_receive(:info).with('[Rollbar] Success')
1329
798
 
1330
799
  request_data = {
@@ -1381,14 +850,14 @@ describe Rollbar do
1381
850
 
1382
851
  it 'should send the payload over the network by default' do
1383
852
  logger_mock.should_not_receive(:info).with('[Rollbar] Writing payload to file')
1384
- logger_mock.should_receive(:info).with('[Rollbar] Sending payload').once
853
+ logger_mock.should_receive(:info).with('[Rollbar] Sending item').once
1385
854
  logger_mock.should_receive(:info).with('[Rollbar] Success').once
1386
855
  Rollbar.error(exception)
1387
856
  end
1388
857
 
1389
858
  it 'should save the payload to a file if set' do
1390
- logger_mock.should_not_receive(:info).with('[Rollbar] Sending payload')
1391
- logger_mock.should_receive(:info).with('[Rollbar] Writing payload to file').once
859
+ logger_mock.should_not_receive(:info).with('[Rollbar] Sending item')
860
+ logger_mock.should_receive(:info).with('[Rollbar] Writing item to file').once
1392
861
  logger_mock.should_receive(:info).with('[Rollbar] Success').once
1393
862
 
1394
863
  filepath = ''
@@ -1434,8 +903,8 @@ describe Rollbar do
1434
903
  let(:logger_mock) { double("Rails.logger").as_null_object }
1435
904
 
1436
905
  it 'should send the payload using the default asynchronous handler girl_friday' do
1437
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
1438
- logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
906
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
907
+ logger_mock.should_receive(:info).with('[Rollbar] Sending item')
1439
908
  logger_mock.should_receive(:info).with('[Rollbar] Success')
1440
909
 
1441
910
  Rollbar.configure do |config|
@@ -1453,14 +922,14 @@ describe Rollbar do
1453
922
 
1454
923
  it 'should send the payload using a user-supplied asynchronous handler' do
1455
924
  logger_mock.should_receive(:info).with('Custom async handler called')
1456
- logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
925
+ logger_mock.should_receive(:info).with('[Rollbar] Sending item')
1457
926
  logger_mock.should_receive(:info).with('[Rollbar] Success')
1458
927
 
1459
928
  Rollbar.configure do |config|
1460
929
  config.use_async = true
1461
930
  config.async_handler = Proc.new { |payload|
1462
931
  logger_mock.info 'Custom async handler called'
1463
- Rollbar.process_payload(payload)
932
+ Rollbar.process_from_async_handler(payload)
1464
933
  }
1465
934
  end
1466
935
 
@@ -1476,7 +945,7 @@ describe Rollbar do
1476
945
  # simulate previous gem version
1477
946
  string_payload = Rollbar::JSON.dump(payload)
1478
947
 
1479
- Rollbar.process_payload(string_payload)
948
+ Rollbar.process_from_async_handler(string_payload)
1480
949
  end
1481
950
  end
1482
951
 
@@ -1572,8 +1041,8 @@ describe Rollbar do
1572
1041
 
1573
1042
  describe "#use_sucker_punch", :if => defined?(SuckerPunch) do
1574
1043
  it "should send the payload to sucker_punch delayer" do
1575
- logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
1576
- logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
1044
+ logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
1045
+ logger_mock.should_receive(:info).with('[Rollbar] Sending item')
1577
1046
  logger_mock.should_receive(:info).with('[Rollbar] Success')
1578
1047
 
1579
1048
  Rollbar.configure do |config|
@@ -1635,119 +1104,6 @@ describe Rollbar do
1635
1104
  end
1636
1105
  end
1637
1106
 
1638
- context 'enforce_valid_utf8' do
1639
- # TODO(jon): all these tests should be removed since they are in
1640
- # in spec/rollbar/encoding/encoder.rb.
1641
- #
1642
- # This should just check that in payload with simple values and
1643
- # nested values are each one passed through Rollbar::Encoding.encode
1644
- context 'with utf8 string and ruby > 1.8' do
1645
- next unless String.instance_methods.include?(:force_encoding)
1646
-
1647
- let(:payload) { { :foo => 'Изменение' } }
1648
-
1649
- it 'just returns the same string' do
1650
- payload_copy = payload.clone
1651
- notifier.send(:enforce_valid_utf8, payload_copy)
1652
-
1653
- expect(payload_copy[:foo]).to be_eql('Изменение')
1654
- end
1655
- end
1656
-
1657
- it 'should replace invalid utf8 values' do
1658
- bad_key = force_to_ascii("inner \x92bad key")
1659
-
1660
- payload = {
1661
- :bad_value => force_to_ascii("bad value 1\255"),
1662
- :bad_value_2 => force_to_ascii("bad\255 value 2"),
1663
- force_to_ascii("bad\255 key") => "good value",
1664
- :hash => {
1665
- :inner_bad_value => force_to_ascii("\255\255bad value 3"),
1666
- bad_key.to_sym => 'inner good value',
1667
- force_to_ascii("bad array key\255") => [
1668
- 'good array value 1',
1669
- force_to_ascii("bad\255 array value 1\255"),
1670
- {
1671
- :inner_inner_bad => force_to_ascii("bad inner \255inner value")
1672
- }
1673
- ]
1674
- }
1675
- }
1676
-
1677
-
1678
- payload_copy = payload.clone
1679
- notifier.send(:enforce_valid_utf8, payload_copy)
1680
-
1681
- payload_copy[:bad_value].should == "bad value 1"
1682
- payload_copy[:bad_value_2].should == "bad value 2"
1683
- payload_copy["bad key"].should == "good value"
1684
- payload_copy.keys.should_not include("bad\456 key")
1685
- payload_copy[:hash][:inner_bad_value].should == "bad value 3"
1686
- payload_copy[:hash][:"inner bad key"].should == 'inner good value'
1687
- payload_copy[:hash]["bad array key"].should == [
1688
- 'good array value 1',
1689
- 'bad array value 1',
1690
- {
1691
- :inner_inner_bad => 'bad inner inner value'
1692
- }
1693
- ]
1694
- end
1695
- end
1696
-
1697
- context 'truncate_payload' do
1698
- it 'should truncate all nested strings in the payload' do
1699
- payload = {
1700
- :truncated => '1234567',
1701
- :not_truncated => '123456',
1702
- :hash => {
1703
- :inner_truncated => '123456789',
1704
- :inner_not_truncated => '567',
1705
- :array => ['12345678', '12', {:inner_inner => '123456789'}]
1706
- }
1707
- }
1708
-
1709
- payload_copy = payload.clone
1710
- notifier.send(:truncate_payload, payload_copy, 6)
1711
-
1712
- payload_copy[:truncated].should == '123...'
1713
- payload_copy[:not_truncated].should == '123456'
1714
- payload_copy[:hash][:inner_truncated].should == '123...'
1715
- payload_copy[:hash][:inner_not_truncated].should == '567'
1716
- payload_copy[:hash][:array].should == ['123...', '12', {:inner_inner => '123...'}]
1717
- end
1718
-
1719
- it 'should truncate utf8 strings properly' do
1720
- payload = {
1721
- :truncated => 'Ŝǻмρļẻ śţяịņģ',
1722
- :not_truncated => '123456',
1723
- }
1724
-
1725
- payload_copy = payload.clone
1726
- notifier.send(:truncate_payload, payload_copy, 6)
1727
-
1728
- payload_copy[:truncated].should == "Ŝǻм..."
1729
- payload_copy[:not_truncated].should == '123456'
1730
- end
1731
- end
1732
-
1733
- context 'server_data' do
1734
- it 'should have the right hostname' do
1735
- notifier.send(:server_data)[:host] == Socket.gethostname
1736
- end
1737
-
1738
- it 'should have root and branch set when configured' do
1739
- configure
1740
- Rollbar.configure do |config|
1741
- config.root = '/path/to/root'
1742
- config.branch = 'master'
1743
- end
1744
-
1745
- data = notifier.send(:server_data)
1746
- data[:root].should == '/path/to/root'
1747
- data[:branch].should == 'master'
1748
- end
1749
- end
1750
-
1751
1107
  context "project_gems" do
1752
1108
  it "should include gem paths for specified project gems in the payload" do
1753
1109
  gems = ['rack', 'rspec-rails']
@@ -1762,7 +1118,7 @@ describe Rollbar do
1762
1118
  gem_spec.gem_dir if gem_spec
1763
1119
  end.compact
1764
1120
 
1765
- data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
1121
+ data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
1766
1122
  data[:project_package_paths].kind_of?(Array).should == true
1767
1123
  data[:project_package_paths].length.should == gem_paths.length
1768
1124
 
@@ -1785,7 +1141,7 @@ describe Rollbar do
1785
1141
  gem_paths.any?{|path| path.include? 'rollbar-gem'}.should == true
1786
1142
  gem_paths.any?{|path| path.include? 'rspec-rails'}.should == true
1787
1143
 
1788
- data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
1144
+ data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
1789
1145
  data[:project_package_paths].kind_of?(Array).should == true
1790
1146
  data[:project_package_paths].length.should == gem_paths.length
1791
1147
  (data[:project_package_paths] - gem_paths).length.should == 0
@@ -1798,7 +1154,7 @@ describe Rollbar do
1798
1154
  config.project_gems = gems
1799
1155
  end
1800
1156
 
1801
- data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
1157
+ data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
1802
1158
  data[:project_package_paths].kind_of?(Array).should == true
1803
1159
  data[:project_package_paths].length.should == 1
1804
1160
  end
@@ -1881,7 +1237,7 @@ describe Rollbar do
1881
1237
  config.logger = logger_mock
1882
1238
  end
1883
1239
 
1884
- logger_mock.should_receive(:info).with('[Rollbar] Sending payload').once
1240
+ logger_mock.should_receive(:info).with('[Rollbar] Sending item').once
1885
1241
  logger_mock.should_receive(:info).with('[Rollbar] Success').once
1886
1242
  scoped_notifier.send(:report_internal_error, exception)
1887
1243
  end
@@ -1983,16 +1339,16 @@ describe Rollbar do
1983
1339
  end
1984
1340
  end
1985
1341
 
1986
- describe '.process_payload' do
1342
+ describe '.process_item' do
1987
1343
  context 'if there is an exception sending the payload' do
1988
1344
  let(:exception) { StandardError.new('error message') }
1989
- let(:payload) { { :foo => :bar } }
1345
+ let(:payload) { Rollbar::Item.build_with({ :foo => :bar }) }
1990
1346
 
1991
1347
  it 'logs the error and the payload' do
1992
- allow(Rollbar.notifier).to receive(:send_payload).and_raise(exception)
1348
+ allow(Rollbar.notifier).to receive(:send_item).and_raise(exception)
1993
1349
  expect(Rollbar.notifier).to receive(:log_error)
1994
1350
 
1995
- expect { Rollbar.notifier.process_payload(payload) }.to raise_error(exception)
1351
+ expect { Rollbar.notifier.process_item(payload) }.to raise_error(exception)
1996
1352
  end
1997
1353
  end
1998
1354
  end
@@ -2002,7 +1358,7 @@ describe Rollbar do
2002
1358
  let(:exception) { StandardError.new('the error') }
2003
1359
 
2004
1360
  it 'raises anything and sends internal error' do
2005
- allow(Rollbar.notifier).to receive(:process_payload).and_raise(exception)
1361
+ allow(Rollbar.notifier).to receive(:process_item).and_raise(exception)
2006
1362
  expect(Rollbar.notifier).to receive(:report_internal_error).with(exception)
2007
1363
 
2008
1364
  expect do
@@ -2015,35 +1371,6 @@ describe Rollbar do
2015
1371
  end
2016
1372
  end
2017
1373
 
2018
- describe '#custom_data' do
2019
- before do
2020
- Rollbar.configure do |config|
2021
- config.custom_data_method = proc { raise 'this-will-raise' }
2022
- end
2023
-
2024
- expect_any_instance_of(Rollbar::Notifier).to receive(:error).and_return(report_data)
2025
- end
2026
-
2027
- context 'with uuid in reported data' do
2028
- next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
2029
-
2030
- let(:report_data) { { :uuid => SecureRandom.uuid } }
2031
- let(:expected_url) { "https://rollbar.com/instance/uuid?uuid=#{report_data[:uuid]}" }
2032
-
2033
- it 'returns the uuid in :_error_in_custom_data_method' do
2034
- expect(notifier.custom_data).to be_eql(:_error_in_custom_data_method => expected_url)
2035
- end
2036
- end
2037
-
2038
- context 'without uuid in reported data' do
2039
- let(:report_data) { { :some => 'other-data' } }
2040
-
2041
- it 'returns the uuid in :_error_in_custom_data_method' do
2042
- expect(notifier.custom_data).to be_eql({})
2043
- end
2044
- end
2045
- end
2046
-
2047
1374
  describe '.preconfigure'do
2048
1375
  before do
2049
1376
  Rollbar.unconfigure
@@ -2066,6 +1393,30 @@ describe Rollbar do
2066
1393
  end
2067
1394
  end
2068
1395
 
1396
+ context 'having timeout issues (for ruby > 1.9.3)' do
1397
+ before do
1398
+ skip if Rollbar::LanguageSupport.ruby_18? || Rollbar::LanguageSupport.ruby_19?
1399
+ end
1400
+
1401
+ let(:exception_class) do
1402
+ Rollbar::LanguageSupport.timeout_exceptions.first
1403
+ end
1404
+ let(:net_exception) do
1405
+ exception_class.new
1406
+ end
1407
+
1408
+ before do
1409
+ allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(net_exception)
1410
+ end
1411
+
1412
+ it 'retries the request' do
1413
+ expect_any_instance_of(Net::HTTP).to receive(:request).exactly(3)
1414
+ expect(Rollbar.notifier).to receive(:report_internal_error).with(net_exception)
1415
+
1416
+ Rollbar.info('foo')
1417
+ end
1418
+ end
1419
+
2069
1420
  # configure with some basic params
2070
1421
  def configure
2071
1422
  reconfigure_notifier