airbrake-ruby 4.14.1 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +23 -35
  3. data/lib/airbrake-ruby/async_sender.rb +1 -1
  4. data/lib/airbrake-ruby/backtrace.rb +6 -5
  5. data/lib/airbrake-ruby/config.rb +37 -13
  6. data/lib/airbrake-ruby/config/processor.rb +84 -0
  7. data/lib/airbrake-ruby/config/validator.rb +6 -0
  8. data/lib/airbrake-ruby/file_cache.rb +1 -1
  9. data/lib/airbrake-ruby/filter_chain.rb +1 -0
  10. data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
  11. data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
  12. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -2
  13. data/lib/airbrake-ruby/filters/git_repository_filter.rb +3 -0
  14. data/lib/airbrake-ruby/filters/git_revision_filter.rb +2 -0
  15. data/lib/airbrake-ruby/filters/{keys_whitelist.rb → keys_allowlist.rb} +3 -3
  16. data/lib/airbrake-ruby/filters/{keys_blacklist.rb → keys_blocklist.rb} +3 -3
  17. data/lib/airbrake-ruby/filters/keys_filter.rb +26 -18
  18. data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
  19. data/lib/airbrake-ruby/filters/sql_filter.rb +4 -4
  20. data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
  21. data/lib/airbrake-ruby/filters/thread_filter.rb +2 -0
  22. data/lib/airbrake-ruby/ignorable.rb +1 -0
  23. data/lib/airbrake-ruby/notice.rb +1 -8
  24. data/lib/airbrake-ruby/notice_notifier.rb +1 -0
  25. data/lib/airbrake-ruby/performance_breakdown.rb +1 -6
  26. data/lib/airbrake-ruby/performance_notifier.rb +2 -15
  27. data/lib/airbrake-ruby/promise.rb +1 -0
  28. data/lib/airbrake-ruby/query.rb +1 -6
  29. data/lib/airbrake-ruby/queue.rb +1 -8
  30. data/lib/airbrake-ruby/remote_settings.rb +145 -0
  31. data/lib/airbrake-ruby/remote_settings/settings_data.rb +121 -0
  32. data/lib/airbrake-ruby/request.rb +1 -8
  33. data/lib/airbrake-ruby/stat.rb +1 -12
  34. data/lib/airbrake-ruby/sync_sender.rb +3 -2
  35. data/lib/airbrake-ruby/tdigest.rb +2 -0
  36. data/lib/airbrake-ruby/thread_pool.rb +1 -0
  37. data/lib/airbrake-ruby/truncator.rb +8 -2
  38. data/lib/airbrake-ruby/version.rb +11 -1
  39. data/spec/airbrake_spec.rb +59 -36
  40. data/spec/backtrace_spec.rb +26 -26
  41. data/spec/code_hunk_spec.rb +2 -2
  42. data/spec/config/processor_spec.rb +209 -0
  43. data/spec/config/validator_spec.rb +18 -1
  44. data/spec/config_spec.rb +13 -6
  45. data/spec/filters/gem_root_filter_spec.rb +4 -4
  46. data/spec/filters/{keys_whitelist_spec.rb → keys_allowlist_spec.rb} +11 -10
  47. data/spec/filters/{keys_blacklist_spec.rb → keys_blocklist_spec.rb} +20 -10
  48. data/spec/filters/root_directory_filter_spec.rb +4 -4
  49. data/spec/filters/sql_filter_spec.rb +5 -5
  50. data/spec/notice_notifier/options_spec.rb +6 -6
  51. data/spec/notice_notifier_spec.rb +2 -2
  52. data/spec/notice_spec.rb +1 -1
  53. data/spec/performance_breakdown_spec.rb +0 -12
  54. data/spec/performance_notifier_spec.rb +0 -25
  55. data/spec/query_spec.rb +1 -11
  56. data/spec/queue_spec.rb +1 -13
  57. data/spec/remote_settings/settings_data_spec.rb +378 -0
  58. data/spec/remote_settings_spec.rb +230 -0
  59. data/spec/request_spec.rb +1 -13
  60. data/spec/spec_helper.rb +4 -4
  61. data/spec/stat_spec.rb +0 -9
  62. data/spec/sync_sender_spec.rb +3 -1
  63. metadata +21 -12
@@ -2,7 +2,7 @@ RSpec.describe Airbrake::Backtrace do
2
2
  describe ".parse" do
3
3
  context "UNIX backtrace" do
4
4
  let(:parsed_backtrace) do
5
- # rubocop:disable Metrics/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
5
+ # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
6
6
  [{:file=>"/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb", :line=>23, :function=>"<top (required)>"},
7
7
  {:file=>"/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb", :line=>54, :function=>"require"},
8
8
  {:file=>"/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb", :line=>54, :function=>"require"},
@@ -16,7 +16,7 @@ RSpec.describe Airbrake::Backtrace do
16
16
  {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>73, :function=>"run"},
17
17
  {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/lib/rspec/core/runner.rb", :line=>41, :function=>"invoke"},
18
18
  {:file=>"/home/kyrylo/.gem/ruby/2.2.2/gems/rspec-core-3.3.2/exe/rspec", :line=>4, :function=>"<main>"}]
19
- # rubocop:enable Metrics/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
19
+ # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceAroundOperators, Layout/SpaceInsideHashLiteralBraces
20
20
  end
21
21
 
22
22
  it "returns a properly formatted array of hashes" do
@@ -34,10 +34,10 @@ RSpec.describe Airbrake::Backtrace do
34
34
  let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(windows_bt) } }
35
35
 
36
36
  let(:parsed_backtrace) do
37
- # rubocop:disable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
37
+ # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
38
38
  [{:file=>"C:/Program Files/Server/app/models/user.rb", :line=>13, :function=>"magic"},
39
39
  {:file=>"C:/Program Files/Server/app/controllers/users_controller.rb", :line=>8, :function=>"index"}]
40
- # rubocop:enable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
40
+ # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
41
41
  end
42
42
 
43
43
  it "returns a properly formatted array of hashes" do
@@ -47,7 +47,7 @@ RSpec.describe Airbrake::Backtrace do
47
47
 
48
48
  context "JRuby Java exceptions" do
49
49
  let(:backtrace_array) do
50
- # rubocop:disable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
50
+ # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
51
51
  [{:file=>"InstanceMethodInvoker.java", :line=>26, :function=>"org.jruby.java.invokers.InstanceMethodInvoker.call"},
52
52
  {:file=>"Interpreter.java", :line=>126, :function=>"org.jruby.ir.interpreter.Interpreter.INTERPRET_EVAL"},
53
53
  {:file=>"RubyKernel$INVOKER$s$0$3$eval19.gen", :line=>nil, :function=>"org.jruby.RubyKernel$INVOKER$s$0$3$eval19.call"},
@@ -59,7 +59,7 @@ RSpec.describe Airbrake::Backtrace do
59
59
  {:file=>"Compiler.java", :line=>111, :function=>"org.jruby.ir.Compiler$1.load"},
60
60
  {:file=>"Main.java", :line=>225, :function=>"org.jruby.Main.run"},
61
61
  {:file=>"Main.java", :line=>197, :function=>"org.jruby.Main.main"}]
62
- # rubocop:enable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
62
+ # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
63
63
  end
64
64
 
65
65
  it "returns a properly formatted array of hashes" do
@@ -72,21 +72,21 @@ RSpec.describe Airbrake::Backtrace do
72
72
 
73
73
  context "JRuby classloader exceptions" do
74
74
  let(:backtrace) do
75
- # rubocop:disable Metrics/LineLength
75
+ # rubocop:disable Layout/LineLength
76
76
  ['uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill(uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb:158)',
77
77
  'bin.processors.image_uploader.block in make_streams(bin/processors/image_uploader.rb:21)',
78
78
  'uri_3a_classloader_3a_.gems.faye_minus_websocket_minus_0_dot_10_dot_5.lib.faye.websocket.api.invokeOther13:dispatch_event(uri_3a_classloader_3a_/gems/faye_minus_websocket_minus_0_dot_10_dot_5/lib/faye/websocket/uri:classloader:/gems/faye-websocket-0.10.5/lib/faye/websocket/api.rb:109)',
79
79
  'tmp.jruby9022301782566983632extract.$dot.META_minus_INF.rails.file(/tmp/jruby9022301782566983632extract/./META-INF/rails.rb:13)']
80
- # rubocop:enable Metrics/LineLength
80
+ # rubocop:enable Layout/LineLength
81
81
  end
82
82
 
83
83
  let(:parsed_backtrace) do
84
- # rubocop:disable Metrics/LineLength
84
+ # rubocop:disable Layout/LineLength
85
85
  [{ file: 'uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb', line: 158, function: 'uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill' },
86
86
  { file: 'bin/processors/image_uploader.rb', line: 21, function: 'bin.processors.image_uploader.block in make_streams' },
87
87
  { file: 'uri_3a_classloader_3a_/gems/faye_minus_websocket_minus_0_dot_10_dot_5/lib/faye/websocket/uri:classloader:/gems/faye-websocket-0.10.5/lib/faye/websocket/api.rb', line: 109, function: 'uri_3a_classloader_3a_.gems.faye_minus_websocket_minus_0_dot_10_dot_5.lib.faye.websocket.api.invokeOther13:dispatch_event' },
88
88
  { file: '/tmp/jruby9022301782566983632extract/./META-INF/rails.rb', line: 13, function: 'tmp.jruby9022301782566983632extract.$dot.META_minus_INF.rails.file' }]
89
- # rubocop:enable Metrics/LineLength
89
+ # rubocop:enable Layout/LineLength
90
90
  end
91
91
 
92
92
  let(:ex) { JavaAirbrakeTestError.new.tap { |e| e.set_backtrace(backtrace) } }
@@ -99,19 +99,19 @@ RSpec.describe Airbrake::Backtrace do
99
99
 
100
100
  context "JRuby non-throwable exceptions" do
101
101
  let(:backtrace) do
102
- # rubocop:disable Metrics/LineLength
102
+ # rubocop:disable Layout/LineLength
103
103
  ['org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(org/postgresql/core/v3/ConnectionFactoryImpl.java:257)',
104
104
  'org.postgresql.core.ConnectionFactory.openConnection(org/postgresql/core/ConnectionFactory.java:65)',
105
105
  'org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(org/postgresql/jdbc2/AbstractJdbc2Connection.java:149)']
106
- # rubocop:enable Metrics/LineLength
106
+ # rubocop:enable Layout/LineLength
107
107
  end
108
108
 
109
109
  let(:parsed_backtrace) do
110
- # rubocop:disable Metrics/LineLength
110
+ # rubocop:disable Layout/LineLength
111
111
  [{ file: 'org/postgresql/core/v3/ConnectionFactoryImpl.java', line: 257, function: 'org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl' },
112
112
  { file: 'org/postgresql/core/ConnectionFactory.java', line: 65, function: 'org.postgresql.core.ConnectionFactory.openConnection' },
113
113
  { file: 'org/postgresql/jdbc2/AbstractJdbc2Connection.java', line: 149, function: 'org.postgresql.jdbc2.AbstractJdbc2Connection.<init>' }]
114
- # rubocop:enable Metrics/LineLength
114
+ # rubocop:enable Layout/LineLength
115
115
  end
116
116
 
117
117
  let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(backtrace) } }
@@ -123,22 +123,22 @@ RSpec.describe Airbrake::Backtrace do
123
123
 
124
124
  context "generic backtrace" do
125
125
  context "when function is absent" do
126
- # rubocop:disable Metrics/LineLength
126
+ # rubocop:disable Layout/LineLength
127
127
  let(:generic_bt) do
128
128
  ["/home/bingo/bango/assets/stylesheets/error_pages.scss:139:in `animation'",
129
129
  "/home/bingo/bango/assets/stylesheets/error_pages.scss:139",
130
130
  "/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb:349:in `block in visit_mixin'"]
131
131
  end
132
- # rubocop:enable Metrics/LineLength
132
+ # rubocop:enable Layout/LineLength
133
133
 
134
134
  let(:ex) { AirbrakeTestError.new.tap { |e| e.set_backtrace(generic_bt) } }
135
135
 
136
136
  let(:parsed_backtrace) do
137
- # rubocop:disable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
137
+ # rubocop:disable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
138
138
  [{:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>"animation"},
139
139
  {:file=>"/home/bingo/bango/assets/stylesheets/error_pages.scss", :line=>139, :function=>nil},
140
140
  {:file=>"/home/bingo/.gem/ruby/2.2.2/gems/sass-3.4.20/lib/sass/tree/visitors/perform.rb", :line=>349, :function=>"block in visit_mixin"}]
141
- # rubocop:enable Metrics/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
141
+ # rubocop:enable Layout/LineLength, Style/HashSyntax, Layout/SpaceInsideHashLiteralBraces, Layout/SpaceAroundOperators
142
142
  end
143
143
 
144
144
  it "returns a properly formatted array of hashes" do
@@ -277,9 +277,9 @@ RSpec.describe Airbrake::Backtrace do
277
277
  93 => ' begin',
278
278
  94 => ' json = @payload.to_json',
279
279
  95 => ' rescue *JSON_EXCEPTIONS => ex',
280
- # rubocop:disable Metrics/LineLength,Lint/InterpolationCheck
280
+ # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
281
281
  96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
282
- # rubocop:enable Metrics/LineLength,Lint/InterpolationCheck
282
+ # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
283
283
  },
284
284
  },
285
285
  {
@@ -325,9 +325,9 @@ RSpec.describe Airbrake::Backtrace do
325
325
  93 => ' begin',
326
326
  94 => ' json = @payload.to_json',
327
327
  95 => ' rescue *JSON_EXCEPTIONS => ex',
328
- # rubocop:disable Metrics/LineLength,Lint/InterpolationCheck
328
+ # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
329
329
  96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
330
- # rubocop:enable Metrics/LineLength,Lint/InterpolationCheck
330
+ # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
331
331
  },
332
332
  },
333
333
  ]
@@ -357,9 +357,9 @@ RSpec.describe Airbrake::Backtrace do
357
357
  93 => ' begin',
358
358
  94 => ' json = @payload.to_json',
359
359
  95 => ' rescue *JSON_EXCEPTIONS => ex',
360
- # rubocop:disable Metrics/LineLength,Lint/InterpolationCheck
360
+ # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
361
361
  96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
362
- # rubocop:enable Metrics/LineLength,Lint/InterpolationCheck
362
+ # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
363
363
  },
364
364
  },
365
365
  {
@@ -370,9 +370,9 @@ RSpec.describe Airbrake::Backtrace do
370
370
  93 => ' begin',
371
371
  94 => ' json = @payload.to_json',
372
372
  95 => ' rescue *JSON_EXCEPTIONS => ex',
373
- # rubocop:disable Metrics/LineLength,Lint/InterpolationCheck
373
+ # rubocop:disable Layout/LineLength,Lint/InterpolationCheck
374
374
  96 => ' @config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")',
375
- # rubocop:enable Metrics/LineLength,Lint/InterpolationCheck
375
+ # rubocop:enable Layout/LineLength,Lint/InterpolationCheck
376
376
  97 => ' else',
377
377
  },
378
378
  },
@@ -34,9 +34,9 @@ RSpec.describe Airbrake::CodeHunk do
34
34
  eq(
35
35
  1 => 'module Airbrake',
36
36
  2 => ' ##',
37
- # rubocop:disable Metrics/LineLength
37
+ # rubocop:disable Layout/LineLength
38
38
  3 => ' # Represents a chunk of information that is meant to be either sent to',
39
- # rubocop:enable Metrics/LineLength
39
+ # rubocop:enable Layout/LineLength
40
40
  ),
41
41
  )
42
42
  end
@@ -0,0 +1,209 @@
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
+ let(:config) do
58
+ Airbrake::Config.new(project_id: 123)
59
+ end
60
+
61
+ it "sets remote settings" do
62
+ expect(Airbrake::RemoteSettings).to receive(:poll)
63
+ described_class.new(config).process_remote_configuration
64
+ end
65
+ end
66
+ end
67
+
68
+ describe "#add_filters" do
69
+ context "when there's a root directory" do
70
+ let(:config) { Airbrake::Config.new(root_directory: '/abc') }
71
+
72
+ it "adds RootDirectoryFilter" do
73
+ described_class.new(config).add_filters(notifier)
74
+ expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
75
+ .to eq(true)
76
+ end
77
+
78
+ it "adds GitRevisionFilter" do
79
+ described_class.new(config).add_filters(notifier)
80
+ expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
81
+ .to eq(true)
82
+ end
83
+
84
+ it "adds GitRepositoryFilter" do
85
+ described_class.new(config).add_filters(notifier)
86
+ expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
87
+ .to eq(true)
88
+ end
89
+
90
+ it "adds GitLastCheckoutFilter" do
91
+ described_class.new(config).add_filters(notifier)
92
+ expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
93
+ .to eq(true)
94
+ end
95
+ end
96
+
97
+ context "when there's NO root directory" do
98
+ let(:config) { Airbrake::Config.new(root_directory: nil) }
99
+
100
+ it "doesn't add RootDirectoryFilter" do
101
+ described_class.new(config).add_filters(notifier)
102
+ expect(notifier.has_filter?(Airbrake::Filters::RootDirectoryFilter))
103
+ .to eq(false)
104
+ end
105
+
106
+ it "doesn't add GitRevisionFilter" do
107
+ described_class.new(config).add_filters(notifier)
108
+ expect(notifier.has_filter?(Airbrake::Filters::GitRevisionFilter))
109
+ .to eq(false)
110
+ end
111
+
112
+ it "doesn't add GitRepositoryFilter" do
113
+ described_class.new(config).add_filters(notifier)
114
+ expect(notifier.has_filter?(Airbrake::Filters::GitRepositoryFilter))
115
+ .to eq(false)
116
+ end
117
+
118
+ it "doesn't add GitLastCheckoutFilter" do
119
+ described_class.new(config).add_filters(notifier)
120
+ expect(notifier.has_filter?(Airbrake::Filters::GitLastCheckoutFilter))
121
+ .to eq(false)
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#poll_callback" do
127
+ let(:logger) { Logger.new(File::NULL) }
128
+
129
+ let(:config) do
130
+ Airbrake::Config.new(
131
+ project_id: 123,
132
+ logger: logger,
133
+ )
134
+ end
135
+
136
+ let(:data) do
137
+ instance_double(Airbrake::RemoteSettings::SettingsData)
138
+ end
139
+
140
+ before do
141
+ allow(data).to receive(:to_h)
142
+ allow(data).to receive(:error_host)
143
+ allow(data).to receive(:apm_host)
144
+ allow(data).to receive(:error_notifications?)
145
+ allow(data).to receive(:performance_stats?)
146
+ end
147
+
148
+ it "logs given data" do
149
+ expect(logger).to receive(:debug).with(/applying remote settings/)
150
+ described_class.new(config).poll_callback(data)
151
+ end
152
+
153
+ it "sets the error_notifications option" do
154
+ config.error_notifications = false
155
+ expect(data).to receive(:error_notifications?).and_return(true)
156
+
157
+ described_class.new(config).poll_callback(data)
158
+ expect(config.error_notifications).to eq(true)
159
+ end
160
+
161
+ it "sets the performance_stats option" do
162
+ config.performance_stats = false
163
+ expect(data).to receive(:performance_stats?).and_return(true)
164
+
165
+ described_class.new(config).poll_callback(data)
166
+ expect(config.performance_stats).to eq(true)
167
+ end
168
+
169
+ context "when error_host returns a value" do
170
+ it "sets the error_host option" do
171
+ config.error_host = 'http://api.airbrake.io'
172
+ allow(data).to receive(:error_host).and_return('https://api.example.com')
173
+
174
+ described_class.new(config).poll_callback(data)
175
+ expect(config.error_host).to eq('https://api.example.com')
176
+ end
177
+ end
178
+
179
+ context "when error_host returns nil" do
180
+ it "doesn't modify the error_host option" do
181
+ config.error_host = 'http://api.airbrake.io'
182
+ allow(data).to receive(:error_host).and_return(nil)
183
+
184
+ described_class.new(config).poll_callback(data)
185
+ expect(config.error_host).to eq('http://api.airbrake.io')
186
+ end
187
+ end
188
+
189
+ context "when apm_host returns a value" do
190
+ it "sets the apm_host option" do
191
+ config.apm_host = 'http://api.airbrake.io'
192
+ allow(data).to receive(:apm_host).and_return('https://api.example.com')
193
+
194
+ described_class.new(config).poll_callback(data)
195
+ expect(config.apm_host).to eq('https://api.example.com')
196
+ end
197
+ end
198
+
199
+ context "when apm_host returns nil" do
200
+ it "doesn't modify the apm_host option" do
201
+ config.apm_host = 'http://api.airbrake.io'
202
+ allow(data).to receive(:apm_host).and_return(nil)
203
+
204
+ described_class.new(config).poll_callback(data)
205
+ expect(config.apm_host).to eq('http://api.airbrake.io')
206
+ end
207
+ end
208
+ end
209
+ 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
@@ -10,19 +10,26 @@ RSpec.describe Airbrake::Config do
10
10
  its(:app_version) { is_expected.to be_nil }
11
11
  its(:versions) { is_expected.to be_empty }
12
12
  its(:host) { is_expected.to eq('https://api.airbrake.io') }
13
- its(:endpoint) { is_expected.not_to be_nil }
13
+ its(:error_host) { is_expected.to eq('https://api.airbrake.io') }
14
+ its(:apm_host) { is_expected.to eq('https://api.airbrake.io') }
15
+ its(:error_endpoint) { is_expected.not_to be_nil }
14
16
  its(:workers) { is_expected.to eq(1) }
15
17
  its(:queue_size) { is_expected.to eq(100) }
16
18
  its(:root_directory) { is_expected.to eq(Bundler.root.realpath.to_s) }
17
19
  its(:environment) { is_expected.to be_nil }
18
20
  its(:ignore_environments) { is_expected.to be_empty }
19
21
  its(:timeout) { is_expected.to be_nil }
20
- its(:blacklist_keys) { is_expected.to be_empty }
21
- its(:whitelist_keys) { is_expected.to be_empty }
22
+ its(:blocklist_keys) { is_expected.to be_empty }
23
+ its(:allowlist_keys) { is_expected.to be_empty }
22
24
  its(:performance_stats) { is_expected.to eq(true) }
23
25
  its(:performance_stats_flush_period) { is_expected.to eq(15) }
24
26
  its(:query_stats) { is_expected.to eq(true) }
25
27
  its(:job_stats) { is_expected.to eq(true) }
28
+ its(:error_notifications) { is_expected.to eq(true) }
29
+
30
+ its(:remote_config_host) do
31
+ is_expected.to eq('https://v1-production-notifier-configs.s3.amazonaws.com')
32
+ end
26
33
 
27
34
  describe "#new" do
28
35
  context "when user config is passed" do
@@ -63,13 +70,13 @@ RSpec.describe Airbrake::Config do
63
70
  end
64
71
  end
65
72
 
66
- describe "#endpoint" do
73
+ describe "#error_endpoint" do
67
74
  subject { described_class.new(valid_params.merge(user_config)) }
68
75
 
69
76
  context "when host ends with a URL with a slug with a trailing slash" do
70
77
  let(:user_config) { { host: 'https://localhost/bingo/' } }
71
78
 
72
- its(:endpoint) do
79
+ its(:error_endpoint) do
73
80
  is_expected.to eq(URI('https://localhost/bingo/api/v3/projects/1/notices'))
74
81
  end
75
82
  end
@@ -77,7 +84,7 @@ RSpec.describe Airbrake::Config do
77
84
  context "when host ends with a URL with a slug without a trailing slash" do
78
85
  let(:user_config) { { host: 'https://localhost/bingo' } }
79
86
 
80
- its(:endpoint) do
87
+ its(:error_endpoint) do
81
88
  is_expected.to eq(URI('https://localhost/api/v3/projects/1/notices'))
82
89
  end
83
90
  end