airbrake-ruby 4.15.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +4 -2
  3. data/lib/airbrake-ruby/backtrace.rb +6 -5
  4. data/lib/airbrake-ruby/config/processor.rb +77 -0
  5. data/lib/airbrake-ruby/config/validator.rb +6 -0
  6. data/lib/airbrake-ruby/config.rb +44 -35
  7. data/lib/airbrake-ruby/context.rb +51 -0
  8. data/lib/airbrake-ruby/file_cache.rb +1 -1
  9. data/lib/airbrake-ruby/filter_chain.rb +3 -0
  10. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  11. data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
  12. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  13. data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
  14. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +3 -4
  15. data/lib/airbrake-ruby/filters/git_repository_filter.rb +11 -2
  16. data/lib/airbrake-ruby/filters/git_revision_filter.rb +3 -1
  17. data/lib/airbrake-ruby/filters/keys_filter.rb +23 -15
  18. data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
  19. data/lib/airbrake-ruby/filters/sql_filter.rb +11 -11
  20. data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
  21. data/lib/airbrake-ruby/filters/thread_filter.rb +4 -3
  22. data/lib/airbrake-ruby/grouppable.rb +1 -1
  23. data/lib/airbrake-ruby/ignorable.rb +1 -2
  24. data/lib/airbrake-ruby/mergeable.rb +1 -1
  25. data/lib/airbrake-ruby/monotonic_time.rb +1 -1
  26. data/lib/airbrake-ruby/notice.rb +1 -8
  27. data/lib/airbrake-ruby/notice_notifier.rb +4 -4
  28. data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
  29. data/lib/airbrake-ruby/performance_notifier.rb +40 -54
  30. data/lib/airbrake-ruby/promise.rb +1 -0
  31. data/lib/airbrake-ruby/query.rb +1 -6
  32. data/lib/airbrake-ruby/queue.rb +1 -8
  33. data/lib/airbrake-ruby/remote_settings/callback.rb +44 -0
  34. data/lib/airbrake-ruby/remote_settings/settings_data.rb +116 -0
  35. data/lib/airbrake-ruby/remote_settings.rb +128 -0
  36. data/lib/airbrake-ruby/request.rb +1 -8
  37. data/lib/airbrake-ruby/stat.rb +2 -13
  38. data/lib/airbrake-ruby/sync_sender.rb +3 -2
  39. data/lib/airbrake-ruby/tdigest.rb +12 -9
  40. data/lib/airbrake-ruby/thread_pool.rb +9 -6
  41. data/lib/airbrake-ruby/time_truncate.rb +2 -2
  42. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  43. data/lib/airbrake-ruby/truncator.rb +8 -2
  44. data/lib/airbrake-ruby/version.rb +11 -1
  45. data/lib/airbrake-ruby.rb +44 -54
  46. data/spec/airbrake_spec.rb +178 -92
  47. data/spec/async_sender_spec.rb +10 -8
  48. data/spec/backtrace_spec.rb +39 -36
  49. data/spec/benchmark_spec.rb +7 -5
  50. data/spec/code_hunk_spec.rb +26 -17
  51. data/spec/config/processor_spec.rb +167 -0
  52. data/spec/config/validator_spec.rb +23 -3
  53. data/spec/config_spec.rb +43 -55
  54. data/spec/context_spec.rb +54 -0
  55. data/spec/deploy_notifier_spec.rb +6 -4
  56. data/spec/file_cache_spec.rb +1 -0
  57. data/spec/filter_chain_spec.rb +29 -24
  58. data/spec/filters/context_filter_spec.rb +14 -5
  59. data/spec/filters/dependency_filter_spec.rb +3 -1
  60. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  61. data/spec/filters/gem_root_filter_spec.rb +9 -6
  62. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  63. data/spec/filters/{git_repository_filter.rb → git_repository_filter_spec.rb} +26 -15
  64. data/spec/filters/git_revision_filter_spec.rb +20 -20
  65. data/spec/filters/keys_allowlist_spec.rb +26 -16
  66. data/spec/filters/keys_blocklist_spec.rb +35 -18
  67. data/spec/filters/root_directory_filter_spec.rb +7 -7
  68. data/spec/filters/sql_filter_spec.rb +28 -28
  69. data/spec/filters/system_exit_filter_spec.rb +4 -2
  70. data/spec/filters/thread_filter_spec.rb +16 -14
  71. data/spec/loggable_spec.rb +2 -2
  72. data/spec/monotonic_time_spec.rb +8 -6
  73. data/spec/nested_exception_spec.rb +46 -46
  74. data/spec/notice_notifier/options_spec.rb +25 -15
  75. data/spec/notice_notifier_spec.rb +54 -49
  76. data/spec/notice_spec.rb +7 -3
  77. data/spec/performance_breakdown_spec.rb +0 -12
  78. data/spec/performance_notifier_spec.rb +69 -87
  79. data/spec/promise_spec.rb +38 -32
  80. data/spec/query_spec.rb +1 -11
  81. data/spec/queue_spec.rb +1 -13
  82. data/spec/remote_settings/callback_spec.rb +162 -0
  83. data/spec/remote_settings/settings_data_spec.rb +348 -0
  84. data/spec/remote_settings_spec.rb +201 -0
  85. data/spec/request_spec.rb +1 -13
  86. data/spec/response_spec.rb +34 -12
  87. data/spec/spec_helper.rb +4 -4
  88. data/spec/stashable_spec.rb +5 -5
  89. data/spec/stat_spec.rb +7 -14
  90. data/spec/sync_sender_spec.rb +52 -17
  91. data/spec/tdigest_spec.rb +61 -56
  92. data/spec/thread_pool_spec.rb +67 -58
  93. data/spec/time_truncate_spec.rb +23 -6
  94. data/spec/timed_trace_spec.rb +32 -30
  95. data/spec/truncator_spec.rb +72 -43
  96. metadata +67 -51
@@ -1,4 +1,13 @@
1
1
  RSpec.describe Airbrake do
2
+ let(:remote_settings) { instance_double(Airbrake::RemoteSettings) }
3
+
4
+ before do
5
+ allow(Airbrake::RemoteSettings).to receive(:poll).and_return(remote_settings)
6
+ allow(remote_settings).to receive(:stop_polling)
7
+ end
8
+
9
+ after { described_class.instance_variable_set(:@remote_settings, nil) }
10
+
2
11
  it "gets initialized with a performance notifier" do
3
12
  expect(described_class.performance_notifier).not_to be_nil
4
13
  end
@@ -21,11 +30,9 @@ RSpec.describe Airbrake do
21
30
 
22
31
  it "yields the config" do
23
32
  expect do |b|
24
- begin
25
- described_class.configure(&b)
26
- rescue Airbrake::Error
27
- nil
28
- end
33
+ described_class.configure(&b)
34
+ rescue Airbrake::Error
35
+ nil
29
36
  end.to yield_with_args(Airbrake::Config)
30
37
  end
31
38
 
@@ -53,26 +60,26 @@ RSpec.describe Airbrake do
53
60
 
54
61
  context "when called multiple times" do
55
62
  it "doesn't overwrite performance notifier" do
56
- described_class.configure {}
63
+ described_class.configure { anything }
57
64
  performance_notifier = described_class.performance_notifier
58
65
 
59
- described_class.configure {}
66
+ described_class.configure { anything }
60
67
  expect(described_class.performance_notifier).to eql(performance_notifier)
61
68
  end
62
69
 
63
70
  it "doesn't overwrite notice notifier" do
64
- described_class.configure {}
71
+ described_class.configure { anything }
65
72
  notice_notifier = described_class.notice_notifier
66
73
 
67
- described_class.configure {}
74
+ described_class.configure { anything }
68
75
  expect(described_class.notice_notifier).to eql(notice_notifier)
69
76
  end
70
77
 
71
78
  it "doesn't overwrite deploy notifier" do
72
- described_class.configure {}
79
+ described_class.configure { anything }
73
80
  deploy_notifier = described_class.deploy_notifier
74
81
 
75
- described_class.configure {}
82
+ described_class.configure { anything }
76
83
  expect(described_class.deploy_notifier).to eql(deploy_notifier)
77
84
  end
78
85
 
@@ -82,128 +89,155 @@ RSpec.describe Airbrake do
82
89
  c.project_key = '2'
83
90
  end
84
91
 
85
- expect(described_class.notice_notifier).not_to receive(:add_filter)
86
- 10.times { described_class.configure {} }
92
+ allow(described_class.notice_notifier).to receive(:add_filter)
93
+
94
+ 10.times { described_class.configure { anything } }
95
+
96
+ expect(described_class.notice_notifier).not_to have_received(:add_filter)
87
97
  end
88
98
 
89
99
  it "appends some default filters" do
90
100
  allow(described_class.notice_notifier).to receive(:add_filter)
91
- expect(described_class.notice_notifier).to receive(:add_filter).with(
92
- an_instance_of(Airbrake::Filters::RootDirectoryFilter),
93
- )
94
101
 
95
102
  described_class.configure do |c|
96
103
  c.project_id = 1
97
104
  c.project_key = '2'
98
105
  end
106
+
107
+ expect(described_class.notice_notifier).to have_received(:add_filter).with(
108
+ an_instance_of(Airbrake::Filters::RootDirectoryFilter),
109
+ )
99
110
  end
100
111
  end
101
112
 
102
113
  context "when blocklist_keys gets configured" do
103
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
114
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
104
115
 
105
116
  it "adds blocklist filter" do
106
- expect(Airbrake.notice_notifier).to receive(:add_filter)
107
- .with(an_instance_of(Airbrake::Filters::KeysBlocklist))
117
+ allow(described_class.notice_notifier).to receive(:add_filter)
118
+
108
119
  described_class.configure { |c| c.blocklist_keys = %w[password] }
120
+
121
+ expect(described_class.notice_notifier).to have_received(:add_filter)
122
+ .with(an_instance_of(Airbrake::Filters::KeysBlocklist))
109
123
  end
110
124
 
111
125
  it "initializes blocklist with specified parameters" do
112
- expect(Airbrake::Filters::KeysBlocklist).to receive(:new).with(%w[password])
126
+ allow(Airbrake::Filters::KeysBlocklist).to receive(:new)
127
+
113
128
  described_class.configure { |c| c.blocklist_keys = %w[password] }
129
+
130
+ expect(Airbrake::Filters::KeysBlocklist)
131
+ .to have_received(:new).with(%w[password])
114
132
  end
115
133
  end
116
134
 
117
135
  context "when allowlist_keys gets configured" do
118
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
136
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
119
137
 
120
138
  it "adds allowlist filter" do
121
- expect(Airbrake.notice_notifier).to receive(:add_filter)
122
- .with(an_instance_of(Airbrake::Filters::KeysAllowlist))
123
139
  described_class.configure { |c| c.allowlist_keys = %w[banana] }
140
+ expect(described_class.notice_notifier).to have_received(:add_filter)
141
+ .with(an_instance_of(Airbrake::Filters::KeysAllowlist))
124
142
  end
125
143
 
126
144
  it "initializes allowlist with specified parameters" do
127
- expect(Airbrake::Filters::KeysAllowlist).to receive(:new).with(%w[banana])
145
+ allow(Airbrake::Filters::KeysAllowlist).to receive(:new)
146
+
128
147
  described_class.configure { |c| c.allowlist_keys = %w[banana] }
148
+ expect(Airbrake::Filters::KeysAllowlist)
149
+ .to have_received(:new).with(%w[banana])
129
150
  end
130
151
  end
131
152
 
132
153
  context "when root_directory gets configured" do
133
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
154
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
134
155
 
135
156
  it "adds root directory filter" do
136
- expect(Airbrake.notice_notifier).to receive(:add_filter)
137
- .with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
138
157
  described_class.configure { |c| c.root_directory = '/my/path' }
158
+
159
+ expect(described_class.notice_notifier).to have_received(:add_filter)
160
+ .with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
139
161
  end
140
162
 
141
163
  it "initializes root directory filter with specified path" do
142
- expect(Airbrake::Filters::RootDirectoryFilter)
143
- .to receive(:new).with('/my/path')
164
+ allow(Airbrake::Filters::RootDirectoryFilter).to receive(:new)
144
165
  described_class.configure { |c| c.root_directory = '/my/path' }
166
+
167
+ expect(Airbrake::Filters::RootDirectoryFilter)
168
+ .to have_received(:new).with('/my/path')
145
169
  end
146
170
 
147
171
  it "adds git revision filter" do
148
- expect(Airbrake.notice_notifier).to receive(:add_filter)
149
- .with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
150
172
  described_class.configure { |c| c.root_directory = '/my/path' }
173
+ expect(described_class.notice_notifier).to have_received(:add_filter)
174
+ .with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
151
175
  end
152
176
 
153
177
  it "initializes git revision filter with correct root directory" do
154
- expect(Airbrake::Filters::GitRevisionFilter)
155
- .to receive(:new).with('/my/path')
178
+ allow(Airbrake::Filters::GitRevisionFilter).to receive(:new)
156
179
  described_class.configure { |c| c.root_directory = '/my/path' }
180
+
181
+ expect(Airbrake::Filters::GitRevisionFilter)
182
+ .to have_received(:new).with('/my/path')
157
183
  end
158
184
 
159
185
  it "adds git repository filter" do
160
- expect(Airbrake.notice_notifier).to receive(:add_filter)
161
- .with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
162
186
  described_class.configure { |c| c.root_directory = '/my/path' }
187
+
188
+ expect(described_class.notice_notifier).to have_received(:add_filter)
189
+ .with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
163
190
  end
164
191
 
165
192
  it "initializes git repository filter with correct root directory" do
166
- expect(Airbrake::Filters::GitRepositoryFilter)
167
- .to receive(:new).with('/my/path')
193
+ allow(Airbrake::Filters::GitRepositoryFilter).to receive(:new)
194
+
168
195
  described_class.configure { |c| c.root_directory = '/my/path' }
196
+
197
+ expect(Airbrake::Filters::GitRepositoryFilter)
198
+ .to have_received(:new).with('/my/path')
169
199
  end
170
200
 
171
201
  it "adds git last checkout filter" do
172
- expect(Airbrake.notice_notifier).to receive(:add_filter)
173
- .with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
174
202
  described_class.configure { |c| c.root_directory = '/my/path' }
203
+ expect(described_class.notice_notifier).to have_received(:add_filter)
204
+ .with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
175
205
  end
176
206
 
177
207
  it "initializes git last checkout filter with correct root directory" do
178
- expect(Airbrake::Filters::GitLastCheckoutFilter)
179
- .to receive(:new).with('/my/path')
208
+ allow(Airbrake::Filters::GitLastCheckoutFilter).to receive(:new)
180
209
  described_class.configure { |c| c.root_directory = '/my/path' }
210
+
211
+ expect(Airbrake::Filters::GitLastCheckoutFilter)
212
+ .to have_received(:new).with('/my/path')
181
213
  end
182
214
  end
183
215
  end
184
216
 
185
- describe "#notify_request" do
217
+ describe ".notify_request" do
218
+ before do
219
+ allow(described_class.performance_notifier).to receive(:notify)
220
+ end
221
+
186
222
  context "when :stash key is not provided" do
187
223
  it "doesn't add anything to the stash of the request" do
188
- expect(described_class.performance_notifier).to receive(:notify) do |request|
189
- expect(request.stash).to be_empty
190
- end
191
-
192
224
  described_class.notify_request(
193
225
  method: 'GET',
194
226
  route: '/',
195
227
  status_code: 200,
196
228
  timing: 1,
197
229
  )
230
+
231
+ expect(
232
+ described_class.performance_notifier,
233
+ ).to have_received(:notify) do |request|
234
+ expect(request.stash).to be_empty
235
+ end
198
236
  end
199
237
  end
200
238
 
201
239
  context "when :stash key is provided" do
202
240
  it "adds the value as the stash of the request" do
203
- expect(described_class.performance_notifier).to receive(:notify) do |request|
204
- expect(request.stash).to eq(request_id: 1)
205
- end
206
-
207
241
  described_class.notify_request(
208
242
  {
209
243
  method: 'GET',
@@ -213,13 +247,19 @@ RSpec.describe Airbrake do
213
247
  },
214
248
  request_id: 1,
215
249
  )
250
+
251
+ expect(
252
+ described_class.performance_notifier,
253
+ ).to have_received(:notify) do |request|
254
+ expect(request.stash).to eq(request_id: 1)
255
+ end
216
256
  end
217
257
  end
218
258
  end
219
259
 
220
- describe "#notify_request_sync" do
260
+ describe ".notify_request_sync" do
221
261
  it "notifies request synchronously" do
222
- expect(described_class.performance_notifier).to receive(:notify_sync)
262
+ allow(described_class.performance_notifier).to receive(:notify_sync)
223
263
 
224
264
  described_class.notify_request_sync(
225
265
  {
@@ -230,31 +270,35 @@ RSpec.describe Airbrake do
230
270
  },
231
271
  request_id: 1,
232
272
  )
273
+
274
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
233
275
  end
234
276
  end
235
277
 
236
- describe "#notify_query" do
278
+ describe ".notify_query" do
279
+ before do
280
+ allow(described_class.performance_notifier).to receive(:notify)
281
+ end
282
+
237
283
  context "when :stash key is not provided" do
238
284
  it "doesn't add anything to the stash of the query" do
239
- expect(described_class.performance_notifier).to receive(:notify) do |query|
240
- expect(query.stash).to be_empty
241
- end
242
-
243
285
  described_class.notify_query(
244
286
  method: 'GET',
245
287
  route: '/',
246
288
  query: '',
247
289
  timing: 1,
248
290
  )
291
+
292
+ expect(
293
+ described_class.performance_notifier,
294
+ ).to have_received(:notify) do |query|
295
+ expect(query.stash).to be_empty
296
+ end
249
297
  end
250
298
  end
251
299
 
252
300
  context "when :stash key is provided" do
253
301
  it "adds the value as the stash of the query" do
254
- expect(described_class.performance_notifier).to receive(:notify) do |query|
255
- expect(query.stash).to eq(request_id: 1)
256
- end
257
-
258
302
  described_class.notify_query(
259
303
  {
260
304
  method: 'GET',
@@ -264,13 +308,19 @@ RSpec.describe Airbrake do
264
308
  },
265
309
  request_id: 1,
266
310
  )
311
+
312
+ expect(
313
+ described_class.performance_notifier,
314
+ ).to have_received(:notify) do |query|
315
+ expect(query.stash).to eq(request_id: 1)
316
+ end
267
317
  end
268
318
  end
269
319
  end
270
320
 
271
- describe "#notify_query_sync" do
321
+ describe ".notify_query_sync" do
272
322
  it "notifies query synchronously" do
273
- expect(described_class.performance_notifier).to receive(:notify_sync)
323
+ allow(described_class.performance_notifier).to receive(:notify_sync)
274
324
 
275
325
  described_class.notify_query_sync(
276
326
  {
@@ -281,33 +331,35 @@ RSpec.describe Airbrake do
281
331
  },
282
332
  request_id: 1,
283
333
  )
334
+
335
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
284
336
  end
285
337
  end
286
338
 
287
- describe "#notify_performance_breakdown" do
339
+ describe ".notify_performance_breakdown" do
340
+ before do
341
+ allow(described_class.performance_notifier).to receive(:notify)
342
+ end
343
+
288
344
  context "when :stash key is not provided" do
289
345
  it "doesn't add anything to the stash of the performance breakdown" do
290
- expect(described_class.performance_notifier).to receive(:notify) do |query|
291
- expect(query.stash).to be_empty
292
- end
293
-
294
346
  described_class.notify_query(
295
347
  method: 'GET',
296
348
  route: '/',
297
349
  query: '',
298
350
  timing: 1,
299
351
  )
300
- end
301
- end
302
352
 
303
- context "when :stash key is provided" do
304
- it "adds the value as the stash of the performance breakdown" do
305
353
  expect(
306
354
  described_class.performance_notifier,
307
- ).to receive(:notify) do |performance_breakdown|
308
- expect(performance_breakdown.stash).to eq(request_id: 1)
355
+ ).to have_received(:notify) do |query|
356
+ expect(query.stash).to be_empty
309
357
  end
358
+ end
359
+ end
310
360
 
361
+ context "when :stash key is provided" do
362
+ it "adds the value as the stash of the performance breakdown" do
311
363
  described_class.notify_performance_breakdown(
312
364
  {
313
365
  method: 'GET',
@@ -318,13 +370,19 @@ RSpec.describe Airbrake do
318
370
  },
319
371
  request_id: 1,
320
372
  )
373
+
374
+ expect(
375
+ described_class.performance_notifier,
376
+ ).to have_received(:notify) do |performance_breakdown|
377
+ expect(performance_breakdown.stash).to eq(request_id: 1)
378
+ end
321
379
  end
322
380
  end
323
381
  end
324
382
 
325
- describe "#notify_performance_breakdown_sync" do
383
+ describe ".notify_performance_breakdown_sync" do
326
384
  it "notifies performance breakdown synchronously" do
327
- expect(described_class.performance_notifier).to receive(:notify_sync)
385
+ allow(described_class.performance_notifier).to receive(:notify_sync)
328
386
 
329
387
  described_class.notify_performance_breakdown_sync(
330
388
  {
@@ -336,29 +394,33 @@ RSpec.describe Airbrake do
336
394
  },
337
395
  request_id: 1,
338
396
  )
397
+
398
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
339
399
  end
340
400
  end
341
401
 
342
- describe "#notify_queue" do
402
+ describe ".notify_queue" do
403
+ before do
404
+ allow(described_class.performance_notifier).to receive(:notify)
405
+ end
406
+
343
407
  context "when :stash key is not provided" do
344
408
  it "doesn't add anything to the stash of the queue" do
345
- expect(described_class.performance_notifier).to receive(:notify) do |queue|
346
- expect(queue.stash).to be_empty
347
- end
348
-
349
409
  described_class.notify_queue(
350
410
  queue: 'bananas',
351
411
  error_count: 10,
352
412
  )
413
+
414
+ expect(
415
+ described_class.performance_notifier,
416
+ ).to have_received(:notify) do |queue|
417
+ expect(queue.stash).to be_empty
418
+ end
353
419
  end
354
420
  end
355
421
 
356
422
  context "when :stash key is provided" do
357
423
  it "adds the value as the stash of the queue" do
358
- expect(described_class.performance_notifier).to receive(:notify) do |queue|
359
- expect(queue.stash).to eq(request_id: 1)
360
- end
361
-
362
424
  described_class.notify_queue(
363
425
  {
364
426
  queue: 'bananas',
@@ -366,13 +428,19 @@ RSpec.describe Airbrake do
366
428
  },
367
429
  request_id: 1,
368
430
  )
431
+
432
+ expect(
433
+ described_class.performance_notifier,
434
+ ).to have_received(:notify) do |queue|
435
+ expect(queue.stash).to eq(request_id: 1)
436
+ end
369
437
  end
370
438
  end
371
439
  end
372
440
 
373
- describe "#notify_queue_sync" do
441
+ describe ".notify_queue_sync" do
374
442
  it "notifies queue synchronously" do
375
- expect(described_class.performance_notifier).to receive(:notify_sync)
443
+ allow(described_class.performance_notifier).to receive(:notify_sync)
376
444
 
377
445
  described_class.notify_queue_sync(
378
446
  {
@@ -381,6 +449,8 @@ RSpec.describe Airbrake do
381
449
  },
382
450
  request_id: 1,
383
451
  )
452
+
453
+ expect(described_class.performance_notifier).to have_received(:notify_sync)
384
454
  end
385
455
  end
386
456
 
@@ -403,34 +473,50 @@ RSpec.describe Airbrake do
403
473
  end
404
474
  end
405
475
 
476
+ # rubocop:disable RSpec/MessageSpies
406
477
  describe ".close" do
407
- after { Airbrake.reset }
478
+ after { described_class.reset }
408
479
 
409
480
  context "when notice_notifier is defined" do
410
481
  it "gets closed" do
411
- expect(Airbrake.notice_notifier).to receive(:close)
482
+ expect(described_class.notice_notifier).to receive(:close)
412
483
  end
413
484
  end
414
485
 
415
486
  context "when notice_notifier is undefined" do
416
487
  it "doesn't get closed (because it wasn't initialized)" do
417
- Airbrake.instance_variable_set(:@notice_notifier, nil)
488
+ described_class.instance_variable_set(:@notice_notifier, nil)
418
489
  expect_any_instance_of(Airbrake::NoticeNotifier).not_to receive(:close)
419
490
  end
420
491
  end
421
492
 
422
493
  context "when performance_notifier is defined" do
423
494
  it "gets closed" do
424
- expect(Airbrake.performance_notifier).to receive(:close)
495
+ expect(described_class.performance_notifier).to receive(:close)
425
496
  end
426
497
  end
427
498
 
428
499
  context "when perforance_notifier is undefined" do
429
500
  it "doesn't get closed (because it wasn't initialized)" do
430
- Airbrake.instance_variable_set(:@performance_notifier, nil)
501
+ described_class.instance_variable_set(:@performance_notifier, nil)
431
502
  expect_any_instance_of(Airbrake::PerformanceNotifier)
432
503
  .not_to receive(:close)
433
504
  end
434
505
  end
506
+
507
+ context "when remote settings are defined" do
508
+ it "stops polling" do
509
+ described_class.instance_variable_set(:@remote_settings, remote_settings)
510
+ expect(remote_settings).to receive(:stop_polling)
511
+ end
512
+ end
513
+
514
+ context "when remote settings are undefined" do
515
+ it "doesn't stop polling (because they weren't initialized)" do
516
+ described_class.instance_variable_set(:@remote_settings, nil)
517
+ expect(remote_settings).not_to receive(:stop_polling)
518
+ end
519
+ end
435
520
  end
521
+ # rubocop:enable RSpec/MessageSpies
436
522
  end
@@ -13,18 +13,20 @@ RSpec.describe Airbrake::AsyncSender do
13
13
  end
14
14
 
15
15
  describe "#send" do
16
+ subject(:async_sender) { described_class.new }
17
+
16
18
  context "when sender has the capacity to send" do
17
19
  it "sends notices to Airbrake" do
18
- 2.times { subject.send(notice, Airbrake::Promise.new) }
19
- subject.close
20
+ 2.times { async_sender.send(notice, Airbrake::Promise.new) }
21
+ async_sender.close
20
22
 
21
23
  expect(a_request(:post, endpoint)).to have_been_made.twice
22
24
  end
23
25
 
24
26
  it "returns a resolved promise" do
25
27
  promise = Airbrake::Promise.new
26
- subject.send(notice, promise)
27
- subject.close
28
+ async_sender.send(notice, promise)
29
+ async_sender.close
28
30
 
29
31
  expect(promise).to be_resolved
30
32
  end
@@ -40,8 +42,8 @@ RSpec.describe Airbrake::AsyncSender do
40
42
  end
41
43
 
42
44
  it "doesn't send the exceeded notices to Airbrake" do
43
- 15.times { subject.send(notice, Airbrake::Promise.new) }
44
- subject.close
45
+ 15.times { async_sender.send(notice, Airbrake::Promise.new) }
46
+ async_sender.close
45
47
 
46
48
  expect(a_request(:post, endpoint)).not_to have_been_made
47
49
  end
@@ -49,9 +51,9 @@ RSpec.describe Airbrake::AsyncSender do
49
51
  it "returns a rejected promise" do
50
52
  promise = nil
51
53
  15.times do
52
- promise = subject.send(notice, Airbrake::Promise.new)
54
+ promise = async_sender.send(notice, Airbrake::Promise.new)
53
55
  end
54
- subject.close
56
+ async_sender.close
55
57
 
56
58
  expect(promise).to be_rejected
57
59
  expect(promise.value).to eq(