airbrake-ruby 5.1.0-java → 6.0.0-java

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +3 -1
  3. data/lib/airbrake-ruby/config/processor.rb +2 -1
  4. data/lib/airbrake-ruby/config.rb +15 -6
  5. data/lib/airbrake-ruby/context.rb +51 -0
  6. data/lib/airbrake-ruby/file_cache.rb +1 -1
  7. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  8. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  9. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  10. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
  11. data/lib/airbrake-ruby/filters/git_repository_filter.rb +1 -1
  12. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  13. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  14. data/lib/airbrake-ruby/filters/sql_filter.rb +2 -2
  15. data/lib/airbrake-ruby/filters/thread_filter.rb +2 -3
  16. data/lib/airbrake-ruby/grouppable.rb +1 -1
  17. data/lib/airbrake-ruby/ignorable.rb +0 -2
  18. data/lib/airbrake-ruby/mergeable.rb +1 -1
  19. data/lib/airbrake-ruby/monotonic_time.rb +1 -1
  20. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  21. data/lib/airbrake-ruby/performance_notifier.rb +1 -2
  22. data/lib/airbrake-ruby/remote_settings/callback.rb +1 -1
  23. data/lib/airbrake-ruby/remote_settings/settings_data.rb +2 -2
  24. data/lib/airbrake-ruby/remote_settings.rb +8 -7
  25. data/lib/airbrake-ruby/tdigest.rb +10 -9
  26. data/lib/airbrake-ruby/thread_pool.rb +5 -3
  27. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  28. data/lib/airbrake-ruby/version.rb +2 -2
  29. data/lib/airbrake-ruby.rb +3 -2
  30. data/spec/airbrake_spec.rb +139 -76
  31. data/spec/async_sender_spec.rb +10 -8
  32. data/spec/backtrace_spec.rb +13 -10
  33. data/spec/benchmark_spec.rb +5 -3
  34. data/spec/code_hunk_spec.rb +24 -15
  35. data/spec/config/processor_spec.rb +20 -3
  36. data/spec/config/validator_spec.rb +5 -2
  37. data/spec/config_spec.rb +26 -17
  38. data/spec/context_spec.rb +54 -0
  39. data/spec/deploy_notifier_spec.rb +6 -4
  40. data/spec/file_cache_spec.rb +1 -0
  41. data/spec/filter_chain_spec.rb +29 -24
  42. data/spec/filters/context_filter_spec.rb +14 -5
  43. data/spec/filters/dependency_filter_spec.rb +3 -1
  44. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  45. data/spec/filters/gem_root_filter_spec.rb +5 -2
  46. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  47. data/spec/filters/git_repository_filter.rb +9 -9
  48. data/spec/filters/git_revision_filter_spec.rb +19 -19
  49. data/spec/filters/keys_allowlist_spec.rb +25 -16
  50. data/spec/filters/keys_blocklist_spec.rb +25 -18
  51. data/spec/filters/root_directory_filter_spec.rb +3 -3
  52. data/spec/filters/sql_filter_spec.rb +26 -26
  53. data/spec/filters/system_exit_filter_spec.rb +4 -2
  54. data/spec/filters/thread_filter_spec.rb +16 -14
  55. data/spec/loggable_spec.rb +2 -2
  56. data/spec/monotonic_time_spec.rb +8 -6
  57. data/spec/nested_exception_spec.rb +46 -46
  58. data/spec/notice_notifier/options_spec.rb +23 -13
  59. data/spec/notice_notifier_spec.rb +52 -47
  60. data/spec/notice_spec.rb +6 -2
  61. data/spec/performance_notifier_spec.rb +67 -60
  62. data/spec/promise_spec.rb +38 -32
  63. data/spec/remote_settings/callback_spec.rb +27 -8
  64. data/spec/remote_settings/settings_data_spec.rb +4 -4
  65. data/spec/remote_settings_spec.rb +40 -7
  66. data/spec/response_spec.rb +34 -12
  67. data/spec/stashable_spec.rb +5 -5
  68. data/spec/stat_spec.rb +7 -5
  69. data/spec/sync_sender_spec.rb +49 -16
  70. data/spec/tdigest_spec.rb +61 -56
  71. data/spec/thread_pool_spec.rb +65 -55
  72. data/spec/time_truncate_spec.rb +4 -2
  73. data/spec/timed_trace_spec.rb +32 -30
  74. data/spec/truncator_spec.rb +72 -43
  75. metadata +52 -49
@@ -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,12 @@ 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
85
88
  before do
86
- allow(Net::HTTP).to receive(:get).and_raise(StandardError)
89
+ allow(Net::HTTP).to receive(:get_response).and_raise(StandardError)
87
90
  end
88
91
 
89
92
  it "doesn't fetch remote settings" do
@@ -117,10 +120,10 @@ RSpec.describe Airbrake::RemoteSettings do
117
120
  end
118
121
  end
119
122
 
120
- context "when API returns an XML response" do
123
+ context "when API returns a non-200 response" do
121
124
  let!(:stub) do
122
125
  stub_request(:get, Regexp.new(endpoint))
123
- .to_return(status: 200, body: '<?xml ...')
126
+ .to_return(status: 201, body: body.to_json)
124
127
  end
125
128
 
126
129
  it "doesn't update settings data" do
@@ -134,8 +137,37 @@ RSpec.describe Airbrake::RemoteSettings do
134
137
  expect(stub).to have_been_requested.once
135
138
  expect(settings.interval).to eq(600)
136
139
  end
140
+
141
+ it "logs error" do
142
+ allow(Airbrake::Loggable.instance).to receive(:error)
143
+
144
+ remote_settings = described_class.poll(project_id, host) { anything }
145
+ sleep(0.1)
146
+ remote_settings.stop_polling
147
+
148
+ expect(Airbrake::Loggable.instance).to have_received(:error).with(body.to_json)
149
+ end
150
+ end
151
+
152
+ context "when API returns a 200 response" do
153
+ let!(:stub) do
154
+ stub_request(:get, Regexp.new(endpoint))
155
+ .to_return(status: 200, body: body.to_json)
156
+ end
157
+
158
+ it "doesn't log errors" do
159
+ allow(Airbrake::Loggable.instance).to receive(:error)
160
+
161
+ remote_settings = described_class.poll(project_id, host) { anything }
162
+ sleep(0.1)
163
+ remote_settings.stop_polling
164
+
165
+ expect(Airbrake::Loggable.instance).not_to have_received(:error)
166
+ expect(stub).to have_been_requested.once
167
+ end
137
168
  end
138
169
 
170
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
139
171
  context "when a config route is specified in the returned data" do
140
172
  let(:new_config_route) do
141
173
  '213/config/111/config.json'
@@ -151,7 +183,7 @@ RSpec.describe Airbrake::RemoteSettings do
151
183
  end
152
184
 
153
185
  it "makes the next request to the specified config route" do
154
- remote_settings = described_class.poll(project_id, host) {}
186
+ remote_settings = described_class.poll(project_id, host) { anything }
155
187
  sleep(0.2)
156
188
 
157
189
  remote_settings.stop_polling
@@ -160,5 +192,6 @@ RSpec.describe Airbrake::RemoteSettings do
160
192
  expect(new_stub).to have_been_requested.once
161
193
  end
162
194
  end
195
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
163
196
  end
164
197
  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