airbrake-ruby 5.2.0-java → 6.0.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +3 -1
  3. data/lib/airbrake-ruby/config.rb +3 -3
  4. data/lib/airbrake-ruby/context.rb +51 -0
  5. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  6. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  7. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  8. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -2
  9. data/lib/airbrake-ruby/filters/git_repository_filter.rb +1 -1
  10. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  12. data/lib/airbrake-ruby/filters/sql_filter.rb +8 -8
  13. data/lib/airbrake-ruby/filters/thread_filter.rb +1 -1
  14. data/lib/airbrake-ruby/ignorable.rb +0 -2
  15. data/lib/airbrake-ruby/monotonic_time.rb +1 -1
  16. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  17. data/lib/airbrake-ruby/performance_notifier.rb +39 -40
  18. data/lib/airbrake-ruby/remote_settings/settings_data.rb +1 -1
  19. data/lib/airbrake-ruby/remote_settings.rb +26 -3
  20. data/lib/airbrake-ruby/stat.rb +1 -1
  21. data/lib/airbrake-ruby/tdigest.rb +10 -9
  22. data/lib/airbrake-ruby/thread_pool.rb +8 -6
  23. data/lib/airbrake-ruby/time_truncate.rb +2 -2
  24. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  25. data/lib/airbrake-ruby/version.rb +1 -1
  26. data/lib/airbrake-ruby.rb +24 -23
  27. data/spec/airbrake_spec.rb +139 -76
  28. data/spec/async_sender_spec.rb +10 -8
  29. data/spec/backtrace_spec.rb +13 -10
  30. data/spec/benchmark_spec.rb +5 -3
  31. data/spec/code_hunk_spec.rb +24 -15
  32. data/spec/config/processor_spec.rb +12 -4
  33. data/spec/config/validator_spec.rb +5 -2
  34. data/spec/config_spec.rb +28 -20
  35. data/spec/context_spec.rb +54 -0
  36. data/spec/deploy_notifier_spec.rb +6 -4
  37. data/spec/file_cache_spec.rb +1 -0
  38. data/spec/filter_chain_spec.rb +29 -24
  39. data/spec/filters/context_filter_spec.rb +14 -5
  40. data/spec/filters/dependency_filter_spec.rb +3 -1
  41. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  42. data/spec/filters/gem_root_filter_spec.rb +5 -2
  43. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  44. data/spec/filters/git_repository_filter.rb +9 -9
  45. data/spec/filters/git_revision_filter_spec.rb +20 -20
  46. data/spec/filters/keys_allowlist_spec.rb +25 -16
  47. data/spec/filters/keys_blocklist_spec.rb +25 -18
  48. data/spec/filters/root_directory_filter_spec.rb +3 -3
  49. data/spec/filters/sql_filter_spec.rb +26 -26
  50. data/spec/filters/system_exit_filter_spec.rb +4 -2
  51. data/spec/filters/thread_filter_spec.rb +15 -13
  52. data/spec/loggable_spec.rb +2 -2
  53. data/spec/monotonic_time_spec.rb +8 -6
  54. data/spec/nested_exception_spec.rb +46 -46
  55. data/spec/notice_notifier/options_spec.rb +23 -13
  56. data/spec/notice_notifier_spec.rb +52 -47
  57. data/spec/notice_spec.rb +6 -2
  58. data/spec/performance_notifier_spec.rb +69 -62
  59. data/spec/promise_spec.rb +38 -32
  60. data/spec/remote_settings/callback_spec.rb +27 -8
  61. data/spec/remote_settings/settings_data_spec.rb +4 -4
  62. data/spec/remote_settings_spec.rb +23 -9
  63. data/spec/response_spec.rb +34 -12
  64. data/spec/stashable_spec.rb +5 -5
  65. data/spec/stat_spec.rb +7 -5
  66. data/spec/sync_sender_spec.rb +49 -16
  67. data/spec/tdigest_spec.rb +60 -55
  68. data/spec/thread_pool_spec.rb +65 -56
  69. data/spec/time_truncate_spec.rb +23 -6
  70. data/spec/timed_trace_spec.rb +32 -30
  71. data/spec/truncator_spec.rb +72 -43
  72. metadata +54 -50
@@ -22,10 +22,13 @@ RSpec.describe Airbrake::RemoteSettings::Callback do
22
22
  end
23
23
 
24
24
  it "logs given data" do
25
- expect(logger).to receive(:debug) do |&block|
25
+ allow(logger).to receive(:debug)
26
+
27
+ described_class.new(config).call(data)
28
+
29
+ expect(logger).to have_received(:debug) do |&block|
26
30
  expect(block.call).to match(/applying remote settings/)
27
31
  end
28
- described_class.new(config).call(data)
29
32
  end
30
33
 
31
34
  context "when the config disables error notifications" do
@@ -34,6 +37,7 @@ RSpec.describe Airbrake::RemoteSettings::Callback do
34
37
  allow(data).to receive(:error_notifications?).and_return(true)
35
38
  end
36
39
 
40
+ # rubocop:disable RSpec/MultipleExpectations
37
41
  it "keeps the option disabled forever" do
38
42
  callback = described_class.new(config)
39
43
 
@@ -46,22 +50,29 @@ RSpec.describe Airbrake::RemoteSettings::Callback do
46
50
  callback.call(data)
47
51
  expect(config.error_notifications).to eq(false)
48
52
  end
53
+ # rubocop:enable RSpec/MultipleExpectations
49
54
  end
50
55
 
51
56
  context "when the config enables error notifications" do
52
57
  before { config.error_notifications = true }
53
58
 
59
+ # rubocop:disable RSpec/MultipleExpectations
54
60
  it "can disable and enable error notifications" do
55
- expect(data).to receive(:error_notifications?).and_return(false)
56
-
57
61
  callback = described_class.new(config)
62
+
63
+ allow(data).to receive(:error_notifications?).and_return(false)
64
+
58
65
  callback.call(data)
59
66
  expect(config.error_notifications).to eq(false)
60
67
 
61
- expect(data).to receive(:error_notifications?).and_return(true)
68
+ allow(data).to receive(:error_notifications?).and_return(true)
69
+
62
70
  callback.call(data)
63
71
  expect(config.error_notifications).to eq(true)
72
+
73
+ expect(data).to have_received(:error_notifications?).twice
64
74
  end
75
+ # rubocop:enable RSpec/MultipleExpectations
65
76
  end
66
77
 
67
78
  context "when the config disables performance_stats" do
@@ -70,6 +81,7 @@ RSpec.describe Airbrake::RemoteSettings::Callback do
70
81
  allow(data).to receive(:performance_stats?).and_return(true)
71
82
  end
72
83
 
84
+ # rubocop:disable RSpec/MultipleExpectations
73
85
  it "keeps the option disabled forever" do
74
86
  callback = described_class.new(config)
75
87
 
@@ -82,22 +94,29 @@ RSpec.describe Airbrake::RemoteSettings::Callback do
82
94
  callback.call(data)
83
95
  expect(config.performance_stats).to eq(false)
84
96
  end
97
+ # rubocop:enable RSpec/MultipleExpectations
85
98
  end
86
99
 
87
100
  context "when the config enables performance stats" do
88
101
  before { config.performance_stats = true }
89
102
 
103
+ # rubocop:disable RSpec/MultipleExpectations
90
104
  it "can disable and enable performance_stats" do
91
- expect(data).to receive(:performance_stats?).and_return(false)
92
-
93
105
  callback = described_class.new(config)
106
+
107
+ allow(data).to receive(:performance_stats?).and_return(false)
108
+
94
109
  callback.call(data)
95
110
  expect(config.performance_stats).to eq(false)
96
111
 
97
- expect(data).to receive(:performance_stats?).and_return(true)
112
+ allow(data).to receive(:performance_stats?).and_return(true)
113
+
98
114
  callback.call(data)
99
115
  expect(config.performance_stats).to eq(true)
116
+
117
+ expect(data).to have_received(:performance_stats?).twice
100
118
  end
119
+ # rubocop:enable RSpec/MultipleExpectations
101
120
  end
102
121
 
103
122
  context "when error_host returns a value" do
@@ -312,6 +312,8 @@ RSpec.describe Airbrake::RemoteSettings::SettingsData do
312
312
  end
313
313
 
314
314
  describe "#to_h" do
315
+ subject(:settings_data) { described_class.new(project_id, data) }
316
+
315
317
  let(:data) do
316
318
  {
317
319
  'poll_sec' => 123,
@@ -324,17 +326,15 @@ RSpec.describe Airbrake::RemoteSettings::SettingsData do
324
326
  }
325
327
  end
326
328
 
327
- subject { described_class.new(project_id, data) }
328
-
329
329
  it "returns a hash representation of settings" do
330
330
  expect(described_class.new(project_id, data).to_h).to eq(data)
331
331
  end
332
332
 
333
333
  it "doesn't allow mutation of the original data object" do
334
- hash = subject.to_h
334
+ hash = settings_data.to_h
335
335
  hash['poll_sec'] = 0
336
336
 
337
- expect(subject.to_h).to eq(
337
+ expect(settings_data.to_h).to eq(
338
338
  'poll_sec' => 123,
339
339
  'settings' => [
340
340
  {
@@ -37,19 +37,20 @@ RSpec.describe Airbrake::RemoteSettings do
37
37
 
38
38
  it "yields the config to the block twice" do
39
39
  block = proc {}
40
- expect(block).to receive(:call).twice
40
+ allow(block).to receive(:call)
41
41
 
42
42
  remote_settings = described_class.poll(project_id, host, &block)
43
43
  sleep(0.2)
44
44
  remote_settings.stop_polling
45
45
 
46
46
  expect(stub).to have_been_requested.once
47
+ expect(block).to have_received(:call).twice
47
48
  end
48
49
  end
49
50
 
50
51
  context "when no errors are raised" do
51
52
  it "makes a request to AWS S3" do
52
- remote_settings = described_class.poll(project_id, host) {}
53
+ remote_settings = described_class.poll(project_id, host) { anything }
53
54
  sleep(0.1)
54
55
  remote_settings.stop_polling
55
56
 
@@ -57,7 +58,7 @@ RSpec.describe Airbrake::RemoteSettings do
57
58
  end
58
59
 
59
60
  it "sends params about the environment with the request" do
60
- remote_settings = described_class.poll(project_id, host) {}
61
+ remote_settings = described_class.poll(project_id, host) { anything }
61
62
  sleep(0.1)
62
63
  remote_settings.stop_polling
63
64
 
@@ -67,6 +68,7 @@ RSpec.describe Airbrake::RemoteSettings do
67
68
  expect(stub_with_query_params).to have_been_requested.at_least_once
68
69
  end
69
70
 
71
+ # rubocop:disable RSpec/MultipleExpectations
70
72
  it "fetches remote settings" do
71
73
  settings = nil
72
74
  remote_settings = described_class.poll(project_id, host) do |data|
@@ -79,11 +81,16 @@ RSpec.describe Airbrake::RemoteSettings do
79
81
  expect(settings.performance_stats?).to eq(false)
80
82
  expect(settings.interval).to eq(1)
81
83
  end
84
+ # rubocop:enable RSpec/MultipleExpectations
82
85
  end
83
86
 
84
87
  context "when an error is raised while making a HTTP request" do
88
+ let(:https) { instance_double(Net::HTTP) }
89
+
85
90
  before do
86
- allow(Net::HTTP).to receive(:get_response).and_raise(StandardError)
91
+ allow(Net::HTTP).to receive(:new).and_return(https)
92
+ allow(https).to receive(:use_ssl=).with(true)
93
+ allow(https).to receive(:request).and_raise(StandardError)
87
94
  end
88
95
 
89
96
  it "doesn't fetch remote settings" do
@@ -136,11 +143,13 @@ RSpec.describe Airbrake::RemoteSettings do
136
143
  end
137
144
 
138
145
  it "logs error" do
139
- expect(Airbrake::Loggable.instance).to receive(:error).with(body.to_json)
146
+ allow(Airbrake::Loggable.instance).to receive(:error)
140
147
 
141
- remote_settings = described_class.poll(project_id, host) {}
148
+ remote_settings = described_class.poll(project_id, host) { anything }
142
149
  sleep(0.1)
143
150
  remote_settings.stop_polling
151
+
152
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(body.to_json)
144
153
  end
145
154
  end
146
155
 
@@ -151,14 +160,18 @@ RSpec.describe Airbrake::RemoteSettings do
151
160
  end
152
161
 
153
162
  it "doesn't log errors" do
154
- expect(Airbrake::Loggable.instance).not_to receive(:error)
163
+ allow(Airbrake::Loggable.instance).to receive(:error)
155
164
 
156
- remote_settings = described_class.poll(project_id, host) {}
165
+ remote_settings = described_class.poll(project_id, host) { anything }
157
166
  sleep(0.1)
158
167
  remote_settings.stop_polling
168
+
169
+ expect(Airbrake::Loggable.instance).not_to have_received(:error)
170
+ expect(stub).to have_been_requested.once
159
171
  end
160
172
  end
161
173
 
174
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
162
175
  context "when a config route is specified in the returned data" do
163
176
  let(:new_config_route) do
164
177
  '213/config/111/config.json'
@@ -174,7 +187,7 @@ RSpec.describe Airbrake::RemoteSettings do
174
187
  end
175
188
 
176
189
  it "makes the next request to the specified config route" do
177
- remote_settings = described_class.poll(project_id, host) {}
190
+ remote_settings = described_class.poll(project_id, host) { anything }
178
191
  sleep(0.2)
179
192
 
180
193
  remote_settings.stop_polling
@@ -183,5 +196,6 @@ RSpec.describe Airbrake::RemoteSettings do
183
196
  expect(new_stub).to have_been_requested.once
184
197
  end
185
198
  end
199
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
186
200
  end
187
201
  end
@@ -2,24 +2,34 @@ RSpec.describe Airbrake::Response do
2
2
  describe ".parse" do
3
3
  [200, 201, 204].each do |code|
4
4
  context "when response code is #{code}" do
5
+ before do
6
+ allow(Airbrake::Loggable.instance).to receive(:debug)
7
+ end
8
+
5
9
  it "logs response body" do
6
- expect(Airbrake::Loggable.instance).to receive(:debug).with(
10
+ described_class.parse(OpenStruct.new(code: code, body: '{}'))
11
+
12
+ expect(Airbrake::Loggable.instance).to have_received(:debug).with(
7
13
  /Airbrake::Response \(#{code}\): {}/,
8
14
  )
9
- described_class.parse(OpenStruct.new(code: code, body: '{}'))
10
15
  end
11
16
  end
12
17
  end
13
18
 
14
19
  [400, 401, 403, 420].each do |code|
15
20
  context "when response code is #{code}" do
21
+ before do
22
+ allow(Airbrake::Loggable.instance).to receive(:error)
23
+ end
24
+
16
25
  it "logs response message" do
17
- expect(Airbrake::Loggable.instance).to receive(:error).with(
18
- /Airbrake: foo/,
19
- )
20
26
  described_class.parse(
21
27
  OpenStruct.new(code: code, body: '{"message":"foo"}'),
22
28
  )
29
+
30
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
31
+ /Airbrake: foo/,
32
+ )
23
33
  end
24
34
  end
25
35
  end
@@ -27,11 +37,15 @@ RSpec.describe Airbrake::Response do
27
37
  context "when response code is 429" do
28
38
  let(:response) { OpenStruct.new(code: 429, body: '{"message":"rate limited"}') }
29
39
 
40
+ before do
41
+ allow(Airbrake::Loggable.instance).to receive(:error)
42
+ end
43
+
30
44
  it "logs response message" do
31
- expect(Airbrake::Loggable.instance).to receive(:error).with(
45
+ described_class.parse(response)
46
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
32
47
  /Airbrake: rate limited/,
33
48
  )
34
- described_class.parse(response)
35
49
  end
36
50
 
37
51
  it "returns an error response" do
@@ -49,11 +63,15 @@ RSpec.describe Airbrake::Response do
49
63
  context "when response code is unhandled" do
50
64
  let(:response) { OpenStruct.new(code: 500, body: 'foo') }
51
65
 
66
+ before do
67
+ allow(Airbrake::Loggable.instance).to receive(:error)
68
+ end
69
+
52
70
  it "logs response body" do
53
- expect(Airbrake::Loggable.instance).to receive(:error).with(
71
+ described_class.parse(response)
72
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
54
73
  /Airbrake: unexpected code \(500\)\. Body: foo/,
55
74
  )
56
- described_class.parse(response)
57
75
  end
58
76
 
59
77
  it "returns an error response" do
@@ -64,18 +82,22 @@ RSpec.describe Airbrake::Response do
64
82
  it "truncates body" do
65
83
  response.body *= 1000
66
84
  resp = described_class.parse(response)
67
- expect(resp).to eq('error' => ('foo' * 33) + 'fo...')
85
+ expect(resp).to eq('error' => "#{'foo' * 33}fo...")
68
86
  end
69
87
  end
70
88
 
71
89
  context "when response body can't be parsed as JSON" do
72
90
  let(:response) { OpenStruct.new(code: 201, body: 'foo') }
73
91
 
92
+ before do
93
+ allow(Airbrake::Loggable.instance).to receive(:error)
94
+ end
95
+
74
96
  it "logs response body" do
75
- expect(Airbrake::Loggable.instance).to receive(:error).with(
97
+ described_class.parse(response)
98
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
76
99
  /Airbrake: error while parsing body \(.*unexpected token.*\)\. Body: foo/,
77
100
  )
78
- described_class.parse(response)
79
101
  end
80
102
 
81
103
  it "returns an error message" do
@@ -5,19 +5,19 @@ RSpec.describe Airbrake::Stashable do
5
5
  end
6
6
 
7
7
  describe "#stash" do
8
- subject { klass.new }
8
+ subject(:instance) { klass.new }
9
9
 
10
10
  it "returns a hash" do
11
- expect(subject.stash).to be_a(Hash)
11
+ expect(instance.stash).to be_a(Hash)
12
12
  end
13
13
 
14
14
  it "returns an empty hash" do
15
- expect(subject.stash).to be_empty
15
+ expect(instance.stash).to be_empty
16
16
  end
17
17
 
18
18
  it "remembers what was put in the stash" do
19
- subject.stash[:foo] = 1
20
- expect(subject.stash[:foo]).to eq(1)
19
+ instance.stash[:foo] = 1
20
+ expect(instance.stash[:foo]).to eq(1)
21
21
  end
22
22
  end
23
23
  end
data/spec/stat_spec.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  RSpec.describe Airbrake::Stat do
2
+ subject(:stat) { described_class.new }
3
+
2
4
  describe "#to_h" do
3
5
  it "converts to a hash" do
4
- expect(subject.to_h).to eq(
6
+ expect(stat.to_h).to eq(
5
7
  'count' => 0,
6
8
  'sum' => 0.0,
7
9
  'sumsq' => 0.0,
@@ -11,19 +13,19 @@ RSpec.describe Airbrake::Stat do
11
13
  end
12
14
 
13
15
  describe "#increment_ms" do
14
- before { subject.increment_ms(1000) }
16
+ before { stat.increment_ms(1000) }
15
17
 
16
18
  its(:sum) { is_expected.to eq(1000) }
17
19
  its(:sumsq) { is_expected.to eq(1000000) }
18
20
 
19
21
  it "updates tdigest" do
20
- expect(subject.tdigest.size).to eq(1)
22
+ expect(stat.tdigest.size).to eq(1)
21
23
  end
22
24
  end
23
25
 
24
26
  describe "#inspect" do
25
27
  it "provides custom inspect output" do
26
- expect(subject.inspect).to eq(
28
+ expect(stat.inspect).to eq(
27
29
  '#<struct Airbrake::Stat count=0, sum=0.0, sumsq=0.0>',
28
30
  )
29
31
  end
@@ -31,7 +33,7 @@ RSpec.describe Airbrake::Stat do
31
33
 
32
34
  describe "#pretty_print" do
33
35
  it "is an alias of #inspect" do
34
- expect(subject.method(:pretty_print)).to eql(subject.method(:inspect))
36
+ expect(stat.method(:pretty_print)).to eql(stat.method(:inspect))
35
37
  end
36
38
  end
37
39
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::SyncSender do
2
+ subject(:sync_sender) { described_class.new }
3
+
2
4
  before do
3
5
  Airbrake::Config.instance = Airbrake::Config.new(
4
6
  project_id: 1, project_key: 'banana',
@@ -14,7 +16,7 @@ RSpec.describe Airbrake::SyncSender do
14
16
  before { stub_request(:post, endpoint).to_return(body: '{}') }
15
17
 
16
18
  it "sets the Content-Type header to JSON" do
17
- subject.send({}, promise)
19
+ sync_sender.send({}, promise)
18
20
  expect(
19
21
  a_request(:post, endpoint).with(
20
22
  headers: { 'Content-Type' => 'application/json' },
@@ -23,7 +25,7 @@ RSpec.describe Airbrake::SyncSender do
23
25
  end
24
26
 
25
27
  it "sets the User-Agent header to the notifier slug" do
26
- subject.send({}, promise)
28
+ sync_sender.send({}, promise)
27
29
  expect(
28
30
  a_request(:post, endpoint).with(
29
31
  headers: {
@@ -36,7 +38,7 @@ RSpec.describe Airbrake::SyncSender do
36
38
  end
37
39
 
38
40
  it "sets the Authorization header to the project key" do
39
- subject.send({}, promise)
41
+ sync_sender.send({}, promise)
40
42
  expect(
41
43
  a_request(:post, endpoint).with(
42
44
  headers: { 'Authorization' => 'Bearer banana' },
@@ -45,19 +47,46 @@ RSpec.describe Airbrake::SyncSender do
45
47
  end
46
48
 
47
49
  it "catches exceptions raised while sending" do
50
+ # rubocop:disable RSpec/VerifiedDoubles
48
51
  https = double("foo")
49
- allow(subject).to receive(:build_https).and_return(https)
52
+ # rubocop:enable RSpec/VerifiedDoubles
53
+
54
+ # rubocop:disable RSpec/SubjectStub
55
+ allow(sync_sender).to receive(:build_https).and_return(https)
56
+ # rubocop:enable RSpec/SubjectStub
57
+
50
58
  allow(https).to receive(:request).and_raise(StandardError.new('foo'))
51
- expect(Airbrake::Loggable.instance).to receive(:error).with(
59
+
60
+ expect(sync_sender.send({}, promise)).to be_an(Airbrake::Promise)
61
+ expect(promise.value).to eq('error' => '**Airbrake: HTTP error: foo')
62
+ end
63
+
64
+ it "logs exceptions raised while sending" do
65
+ allow(Airbrake::Loggable.instance).to receive(:error)
66
+
67
+ # rubocop:disable RSpec/VerifiedDoubles
68
+ https = double("foo")
69
+ # rubocop:enable RSpec/VerifiedDoubles
70
+
71
+ # rubocop:disable RSpec/SubjectStub
72
+ allow(sync_sender).to receive(:build_https).and_return(https)
73
+ # rubocop:enable RSpec/SubjectStub
74
+
75
+ allow(https).to receive(:request).and_raise(StandardError.new('foo'))
76
+
77
+ sync_sender.send({}, promise)
78
+
79
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
52
80
  /HTTP error: foo/,
53
81
  )
54
- expect(subject.send({}, promise)).to be_an(Airbrake::Promise)
55
- expect(promise.value).to eq('error' => '**Airbrake: HTTP error: foo')
56
82
  end
57
83
 
58
84
  context "when request body is nil" do
85
+ # rubocop:disable RSpec/MultipleExpectations
59
86
  it "doesn't send data" do
60
- expect_any_instance_of(Airbrake::Truncator)
87
+ allow(Airbrake::Loggable.instance).to receive(:error)
88
+
89
+ allow_any_instance_of(Airbrake::Truncator)
61
90
  .to receive(:reduce_max_size).and_return(0)
62
91
 
63
92
  encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
@@ -70,16 +99,18 @@ RSpec.describe Airbrake::SyncSender do
70
99
 
71
100
  notice = Airbrake::Notice.new(ex)
72
101
 
73
- expect(Airbrake::Loggable.instance).to receive(:error).with(
102
+ expect(sync_sender.send(notice, promise)).to be_an(Airbrake::Promise)
103
+ expect(promise.value)
104
+ .to match('error' => '**Airbrake: data was not sent because of missing body')
105
+
106
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
74
107
  /data was not sent/,
75
108
  )
76
- expect(Airbrake::Loggable.instance).to receive(:error).with(
109
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(
77
110
  /truncation failed/,
78
111
  )
79
- expect(subject.send(notice, promise)).to be_an(Airbrake::Promise)
80
- expect(promise.value)
81
- .to match('error' => '**Airbrake: data was not sent because of missing body')
82
112
  end
113
+ # rubocop:enable RSpec/MultipleExpectations
83
114
  end
84
115
 
85
116
  context "when IP is rate limited" do
@@ -93,13 +124,14 @@ RSpec.describe Airbrake::SyncSender do
93
124
  )
94
125
  end
95
126
 
127
+ # rubocop:disable RSpec/MultipleExpectations
96
128
  it "returns error" do
97
129
  p1 = Airbrake::Promise.new
98
- subject.send({}, p1)
130
+ sync_sender.send({}, p1)
99
131
  expect(p1.value).to match('error' => '**Airbrake: IP is rate limited')
100
132
 
101
133
  p2 = Airbrake::Promise.new
102
- subject.send({}, p2)
134
+ sync_sender.send({}, p2)
103
135
  expect(p2.value).to match('error' => '**Airbrake: IP is rate limited')
104
136
 
105
137
  # Wait for X-RateLimit-Delay and then make a new request to make sure p2
@@ -107,11 +139,12 @@ RSpec.describe Airbrake::SyncSender do
107
139
  sleep 1
108
140
 
109
141
  p3 = Airbrake::Promise.new
110
- subject.send({}, p3)
142
+ sync_sender.send({}, p3)
111
143
  expect(p3.value).to match('error' => '**Airbrake: IP is rate limited')
112
144
 
113
145
  expect(a_request(:post, endpoint)).to have_been_made.twice
114
146
  end
147
+ # rubocop:enable RSpec/MultipleExpectations
115
148
  end
116
149
 
117
150
  context "when the provided method is :put" do