airbrake-ruby 4.15.0 → 5.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,7 +23,7 @@ module Airbrake
23
23
  # @param [#to_json] data
24
24
  # @param [URI::HTTPS] endpoint
25
25
  # @return [Hash{String=>String}] the parsed HTTP response
26
- def send(data, promise, endpoint = @config.endpoint)
26
+ def send(data, promise, endpoint = @config.error_endpoint)
27
27
  return promise if rate_limited_ip?(promise)
28
28
 
29
29
  response = nil
@@ -2,5 +2,5 @@
2
2
  # More information: http://semver.org/
3
3
  module Airbrake
4
4
  # @return [String] the library version
5
- AIRBRAKE_RUBY_VERSION = '4.15.0'.freeze
5
+ AIRBRAKE_RUBY_VERSION = '5.0.0.rc.1'.freeze
6
6
  end
@@ -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
@@ -100,10 +109,10 @@ RSpec.describe Airbrake do
100
109
  end
101
110
 
102
111
  context "when blocklist_keys gets configured" do
103
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
112
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
104
113
 
105
114
  it "adds blocklist filter" do
106
- expect(Airbrake.notice_notifier).to receive(:add_filter)
115
+ expect(described_class.notice_notifier).to receive(:add_filter)
107
116
  .with(an_instance_of(Airbrake::Filters::KeysBlocklist))
108
117
  described_class.configure { |c| c.blocklist_keys = %w[password] }
109
118
  end
@@ -115,10 +124,10 @@ RSpec.describe Airbrake do
115
124
  end
116
125
 
117
126
  context "when allowlist_keys gets configured" do
118
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
127
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
119
128
 
120
129
  it "adds allowlist filter" do
121
- expect(Airbrake.notice_notifier).to receive(:add_filter)
130
+ expect(described_class.notice_notifier).to receive(:add_filter)
122
131
  .with(an_instance_of(Airbrake::Filters::KeysAllowlist))
123
132
  described_class.configure { |c| c.allowlist_keys = %w[banana] }
124
133
  end
@@ -130,10 +139,10 @@ RSpec.describe Airbrake do
130
139
  end
131
140
 
132
141
  context "when root_directory gets configured" do
133
- before { allow(Airbrake.notice_notifier).to receive(:add_filter) }
142
+ before { allow(described_class.notice_notifier).to receive(:add_filter) }
134
143
 
135
144
  it "adds root directory filter" do
136
- expect(Airbrake.notice_notifier).to receive(:add_filter)
145
+ expect(described_class.notice_notifier).to receive(:add_filter)
137
146
  .with(an_instance_of(Airbrake::Filters::RootDirectoryFilter))
138
147
  described_class.configure { |c| c.root_directory = '/my/path' }
139
148
  end
@@ -145,7 +154,7 @@ RSpec.describe Airbrake do
145
154
  end
146
155
 
147
156
  it "adds git revision filter" do
148
- expect(Airbrake.notice_notifier).to receive(:add_filter)
157
+ expect(described_class.notice_notifier).to receive(:add_filter)
149
158
  .with(an_instance_of(Airbrake::Filters::GitRevisionFilter))
150
159
  described_class.configure { |c| c.root_directory = '/my/path' }
151
160
  end
@@ -157,7 +166,7 @@ RSpec.describe Airbrake do
157
166
  end
158
167
 
159
168
  it "adds git repository filter" do
160
- expect(Airbrake.notice_notifier).to receive(:add_filter)
169
+ expect(described_class.notice_notifier).to receive(:add_filter)
161
170
  .with(an_instance_of(Airbrake::Filters::GitRepositoryFilter))
162
171
  described_class.configure { |c| c.root_directory = '/my/path' }
163
172
  end
@@ -169,7 +178,7 @@ RSpec.describe Airbrake do
169
178
  end
170
179
 
171
180
  it "adds git last checkout filter" do
172
- expect(Airbrake.notice_notifier).to receive(:add_filter)
181
+ expect(described_class.notice_notifier).to receive(:add_filter)
173
182
  .with(an_instance_of(Airbrake::Filters::GitLastCheckoutFilter))
174
183
  described_class.configure { |c| c.root_directory = '/my/path' }
175
184
  end
@@ -182,7 +191,7 @@ RSpec.describe Airbrake do
182
191
  end
183
192
  end
184
193
 
185
- describe "#notify_request" do
194
+ describe ".notify_request" do
186
195
  context "when :stash key is not provided" do
187
196
  it "doesn't add anything to the stash of the request" do
188
197
  expect(described_class.performance_notifier).to receive(:notify) do |request|
@@ -217,7 +226,7 @@ RSpec.describe Airbrake do
217
226
  end
218
227
  end
219
228
 
220
- describe "#notify_request_sync" do
229
+ describe ".notify_request_sync" do
221
230
  it "notifies request synchronously" do
222
231
  expect(described_class.performance_notifier).to receive(:notify_sync)
223
232
 
@@ -233,7 +242,7 @@ RSpec.describe Airbrake do
233
242
  end
234
243
  end
235
244
 
236
- describe "#notify_query" do
245
+ describe ".notify_query" do
237
246
  context "when :stash key is not provided" do
238
247
  it "doesn't add anything to the stash of the query" do
239
248
  expect(described_class.performance_notifier).to receive(:notify) do |query|
@@ -268,7 +277,7 @@ RSpec.describe Airbrake do
268
277
  end
269
278
  end
270
279
 
271
- describe "#notify_query_sync" do
280
+ describe ".notify_query_sync" do
272
281
  it "notifies query synchronously" do
273
282
  expect(described_class.performance_notifier).to receive(:notify_sync)
274
283
 
@@ -284,7 +293,7 @@ RSpec.describe Airbrake do
284
293
  end
285
294
  end
286
295
 
287
- describe "#notify_performance_breakdown" do
296
+ describe ".notify_performance_breakdown" do
288
297
  context "when :stash key is not provided" do
289
298
  it "doesn't add anything to the stash of the performance breakdown" do
290
299
  expect(described_class.performance_notifier).to receive(:notify) do |query|
@@ -322,7 +331,7 @@ RSpec.describe Airbrake do
322
331
  end
323
332
  end
324
333
 
325
- describe "#notify_performance_breakdown_sync" do
334
+ describe ".notify_performance_breakdown_sync" do
326
335
  it "notifies performance breakdown synchronously" do
327
336
  expect(described_class.performance_notifier).to receive(:notify_sync)
328
337
 
@@ -339,7 +348,7 @@ RSpec.describe Airbrake do
339
348
  end
340
349
  end
341
350
 
342
- describe "#notify_queue" do
351
+ describe ".notify_queue" do
343
352
  context "when :stash key is not provided" do
344
353
  it "doesn't add anything to the stash of the queue" do
345
354
  expect(described_class.performance_notifier).to receive(:notify) do |queue|
@@ -370,7 +379,7 @@ RSpec.describe Airbrake do
370
379
  end
371
380
  end
372
381
 
373
- describe "#notify_queue_sync" do
382
+ describe ".notify_queue_sync" do
374
383
  it "notifies queue synchronously" do
375
384
  expect(described_class.performance_notifier).to receive(:notify_sync)
376
385
 
@@ -404,33 +413,47 @@ RSpec.describe Airbrake do
404
413
  end
405
414
 
406
415
  describe ".close" do
407
- after { Airbrake.reset }
416
+ after { described_class.reset }
408
417
 
409
418
  context "when notice_notifier is defined" do
410
419
  it "gets closed" do
411
- expect(Airbrake.notice_notifier).to receive(:close)
420
+ expect(described_class.notice_notifier).to receive(:close)
412
421
  end
413
422
  end
414
423
 
415
424
  context "when notice_notifier is undefined" do
416
425
  it "doesn't get closed (because it wasn't initialized)" do
417
- Airbrake.instance_variable_set(:@notice_notifier, nil)
426
+ described_class.instance_variable_set(:@notice_notifier, nil)
418
427
  expect_any_instance_of(Airbrake::NoticeNotifier).not_to receive(:close)
419
428
  end
420
429
  end
421
430
 
422
431
  context "when performance_notifier is defined" do
423
432
  it "gets closed" do
424
- expect(Airbrake.performance_notifier).to receive(:close)
433
+ expect(described_class.performance_notifier).to receive(:close)
425
434
  end
426
435
  end
427
436
 
428
437
  context "when perforance_notifier is undefined" do
429
438
  it "doesn't get closed (because it wasn't initialized)" do
430
- Airbrake.instance_variable_set(:@performance_notifier, nil)
439
+ described_class.instance_variable_set(:@performance_notifier, nil)
431
440
  expect_any_instance_of(Airbrake::PerformanceNotifier)
432
441
  .not_to receive(:close)
433
442
  end
434
443
  end
444
+
445
+ context "when remote settings are defined" do
446
+ it "stops polling" do
447
+ described_class.instance_variable_set(:@remote_settings, remote_settings)
448
+ expect(remote_settings).to receive(:stop_polling)
449
+ end
450
+ end
451
+
452
+ context "when remote settings are undefined" do
453
+ it "doesn't stop polling (because they weren't initialized)" do
454
+ described_class.instance_variable_set(:@remote_settings, nil)
455
+ expect(remote_settings).not_to receive(:stop_polling)
456
+ end
457
+ end
435
458
  end
436
459
  end
@@ -0,0 +1,223 @@
1
+ RSpec.describe Airbrake::Config::Processor do
2
+ let(:notifier) { Airbrake::NoticeNotifier.new }
3
+
4
+ describe "#process_blocklist" do
5
+ let(:config) { Airbrake::Config.new(blocklist_keys: %w[a b c]) }
6
+
7
+ context "when there ARE blocklist keys" do
8
+ it "adds the blocklist filter" do
9
+ described_class.new(config).process_blocklist(notifier)
10
+ expect(notifier.has_filter?(Airbrake::Filters::KeysBlocklist)).to eq(true)
11
+ end
12
+ end
13
+
14
+ context "when there are NO blocklist keys" do
15
+ let(:config) { Airbrake::Config.new(blocklist_keys: %w[]) }
16
+
17
+ it "doesn't add the blocklist filter" do
18
+ described_class.new(config).process_blocklist(notifier)
19
+ expect(notifier.has_filter?(Airbrake::Filters::KeysBlocklist))
20
+ .to eq(false)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe "#process_allowlist" do
26
+ let(:config) { Airbrake::Config.new(allowlist_keys: %w[a b c]) }
27
+
28
+ context "when there ARE allowlist keys" do
29
+ it "adds the allowlist filter" do
30
+ described_class.new(config).process_allowlist(notifier)
31
+ expect(notifier.has_filter?(Airbrake::Filters::KeysAllowlist)).to eq(true)
32
+ end
33
+ end
34
+
35
+ context "when there are NO allowlist keys" do
36
+ let(:config) { Airbrake::Config.new(allowlist_keys: %w[]) }
37
+
38
+ it "doesn't add the allowlist filter" do
39
+ described_class.new(config).process_allowlist(notifier)
40
+ expect(notifier.has_filter?(Airbrake::Filters::KeysAllowlist))
41
+ .to eq(false)
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "#process_remote_configuration" do
47
+ context "when the config doesn't define a project_id" do
48
+ let(:config) { Airbrake::Config.new(project_id: nil) }
49
+
50
+ it "doesn't set remote settings" do
51
+ expect(Airbrake::RemoteSettings).not_to receive(:poll)
52
+ described_class.new(config).process_remote_configuration
53
+ end
54
+ end
55
+
56
+ context "when the config defines a project_id" do
57
+ context "and when remote configuration is false" do
58
+ let(:config) do
59
+ Airbrake::Config.new(project_id: 123, __remote_configuration: false)
60
+ end
61
+
62
+ it "doesn't set remote settings" do
63
+ expect(Airbrake::RemoteSettings).not_to receive(:poll)
64
+ described_class.new(config).process_remote_configuration
65
+ end
66
+ end
67
+
68
+ context "and when remote configuration is true" do
69
+ let(:config) do
70
+ Airbrake::Config.new(project_id: 123, __remote_configuration: true)
71
+ end
72
+
73
+ it "sets remote settings" do
74
+ expect(Airbrake::RemoteSettings).to receive(:poll)
75
+ described_class.new(config).process_remote_configuration
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "#add_filters" do
82
+ context "when there's a root directory" do
83
+ let(:config) { Airbrake::Config.new(root_directory: '/abc') }
84
+
85
+ it "adds RootDirectoryFilter" do
86
+ described_class.new(config).add_filters(notifier)
87
+ expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
88
+ .to eq(true)
89
+ end
90
+
91
+ it "adds GitRevisionFilter" do
92
+ described_class.new(config).add_filters(notifier)
93
+ expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
94
+ .to eq(true)
95
+ end
96
+
97
+ it "adds GitRepositoryFilter" do
98
+ described_class.new(config).add_filters(notifier)
99
+ expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
100
+ .to eq(true)
101
+ end
102
+
103
+ it "adds GitLastCheckoutFilter" do
104
+ described_class.new(config).add_filters(notifier)
105
+ expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
106
+ .to eq(true)
107
+ end
108
+ end
109
+
110
+ context "when there's NO root directory" do
111
+ let(:config) { Airbrake::Config.new(root_directory: nil) }
112
+
113
+ it "doesn't add RootDirectoryFilter" do
114
+ described_class.new(config).add_filters(notifier)
115
+ expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
116
+ .to eq(false)
117
+ end
118
+
119
+ it "doesn't add GitRevisionFilter" do
120
+ described_class.new(config).add_filters(notifier)
121
+ expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
122
+ .to eq(false)
123
+ end
124
+
125
+ it "doesn't add GitRepositoryFilter" do
126
+ described_class.new(config).add_filters(notifier)
127
+ expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
128
+ .to eq(false)
129
+ end
130
+
131
+ it "doesn't add GitLastCheckoutFilter" do
132
+ described_class.new(config).add_filters(notifier)
133
+ expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
134
+ .to eq(false)
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "#poll_callback" do
140
+ let(:logger) { Logger.new(File::NULL) }
141
+
142
+ let(:config) do
143
+ Airbrake::Config.new(
144
+ project_id: 123,
145
+ __remote_configuration: true,
146
+ logger: logger,
147
+ )
148
+ end
149
+
150
+ let(:data) do
151
+ instance_double(Airbrake::RemoteSettings::SettingsData)
152
+ end
153
+
154
+ before do
155
+ allow(data).to receive(:to_h)
156
+ allow(data).to receive(:error_host)
157
+ allow(data).to receive(:apm_host)
158
+ allow(data).to receive(:error_notifications?)
159
+ allow(data).to receive(:performance_stats?)
160
+ end
161
+
162
+ it "logs given data" do
163
+ expect(logger).to receive(:debug).with(/applying remote settings/)
164
+ described_class.new(config).poll_callback(data)
165
+ end
166
+
167
+ it "sets the error_notifications option" do
168
+ config.error_notifications = false
169
+ expect(data).to receive(:error_notifications?).and_return(true)
170
+
171
+ described_class.new(config).poll_callback(data)
172
+ expect(config.error_notifications).to eq(true)
173
+ end
174
+
175
+ it "sets the performance_stats option" do
176
+ config.performance_stats = false
177
+ expect(data).to receive(:performance_stats?).and_return(true)
178
+
179
+ described_class.new(config).poll_callback(data)
180
+ expect(config.performance_stats).to eq(true)
181
+ end
182
+
183
+ context "when error_host returns a value" do
184
+ it "sets the error_host option" do
185
+ config.error_host = 'http://api.airbrake.io'
186
+ allow(data).to receive(:error_host).and_return('https://api.example.com')
187
+
188
+ described_class.new(config).poll_callback(data)
189
+ expect(config.error_host).to eq('https://api.example.com')
190
+ end
191
+ end
192
+
193
+ context "when error_host returns nil" do
194
+ it "doesn't modify the error_host option" do
195
+ config.error_host = 'http://api.airbrake.io'
196
+ allow(data).to receive(:error_host).and_return(nil)
197
+
198
+ described_class.new(config).poll_callback(data)
199
+ expect(config.error_host).to eq('http://api.airbrake.io')
200
+ end
201
+ end
202
+
203
+ context "when apm_host returns a value" do
204
+ it "sets the apm_host option" do
205
+ config.apm_host = 'http://api.airbrake.io'
206
+ allow(data).to receive(:apm_host).and_return('https://api.example.com')
207
+
208
+ described_class.new(config).poll_callback(data)
209
+ expect(config.apm_host).to eq('https://api.example.com')
210
+ end
211
+ end
212
+
213
+ context "when apm_host returns nil" do
214
+ it "doesn't modify the apm_host option" do
215
+ config.apm_host = 'http://api.airbrake.io'
216
+ allow(data).to receive(:apm_host).and_return(nil)
217
+
218
+ described_class.new(config).poll_callback(data)
219
+ expect(config.apm_host).to eq('http://api.airbrake.io')
220
+ end
221
+ end
222
+ end
223
+ end
@@ -169,7 +169,7 @@ RSpec.describe Airbrake::Config::Validator do
169
169
  }
170
170
  end
171
171
 
172
- it "returns a rejected promise" do
172
+ it "returns a resolved promise" do
173
173
  promise = described_class.check_notify_ability(config)
174
174
  expect(promise).to be_resolved
175
175
  end
@@ -180,5 +180,22 @@ RSpec.describe Airbrake::Config::Validator do
180
180
  described_class.check_notify_ability(config)
181
181
  end
182
182
  end
183
+
184
+ context "when the error_notifications option is false" do
185
+ let(:config_params) do
186
+ {
187
+ project_id: valid_id,
188
+ project_key: valid_key,
189
+ error_notifications: false,
190
+ }
191
+ end
192
+
193
+ it "returns a rejected promise" do
194
+ promise = described_class.check_notify_ability(config)
195
+ expect(promise.value).to eq(
196
+ 'error' => "error notifications are disabled",
197
+ )
198
+ end
199
+ end
183
200
  end
184
201
  end