airbrake-ruby 4.6.0
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.
- checksums.yaml +7 -0
- data/lib/airbrake-ruby.rb +513 -0
- data/lib/airbrake-ruby/async_sender.rb +142 -0
- data/lib/airbrake-ruby/backtrace.rb +196 -0
- data/lib/airbrake-ruby/benchmark.rb +39 -0
- data/lib/airbrake-ruby/code_hunk.rb +51 -0
- data/lib/airbrake-ruby/config.rb +229 -0
- data/lib/airbrake-ruby/config/validator.rb +91 -0
- data/lib/airbrake-ruby/deploy_notifier.rb +36 -0
- data/lib/airbrake-ruby/file_cache.rb +48 -0
- data/lib/airbrake-ruby/filter_chain.rb +95 -0
- data/lib/airbrake-ruby/filters/context_filter.rb +29 -0
- data/lib/airbrake-ruby/filters/dependency_filter.rb +31 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +46 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +33 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +92 -0
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +64 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +66 -0
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +49 -0
- data/lib/airbrake-ruby/filters/keys_filter.rb +140 -0
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +48 -0
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +28 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +104 -0
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +23 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +92 -0
- data/lib/airbrake-ruby/hash_keyable.rb +37 -0
- data/lib/airbrake-ruby/ignorable.rb +44 -0
- data/lib/airbrake-ruby/inspectable.rb +39 -0
- data/lib/airbrake-ruby/loggable.rb +34 -0
- data/lib/airbrake-ruby/monotonic_time.rb +43 -0
- data/lib/airbrake-ruby/nested_exception.rb +38 -0
- data/lib/airbrake-ruby/notice.rb +162 -0
- data/lib/airbrake-ruby/notice_notifier.rb +134 -0
- data/lib/airbrake-ruby/performance_breakdown.rb +45 -0
- data/lib/airbrake-ruby/performance_notifier.rb +125 -0
- data/lib/airbrake-ruby/promise.rb +109 -0
- data/lib/airbrake-ruby/query.rb +53 -0
- data/lib/airbrake-ruby/request.rb +45 -0
- data/lib/airbrake-ruby/response.rb +74 -0
- data/lib/airbrake-ruby/stashable.rb +15 -0
- data/lib/airbrake-ruby/stat.rb +73 -0
- data/lib/airbrake-ruby/sync_sender.rb +113 -0
- data/lib/airbrake-ruby/tdigest.rb +393 -0
- data/lib/airbrake-ruby/time_truncate.rb +17 -0
- data/lib/airbrake-ruby/timed_trace.rb +58 -0
- data/lib/airbrake-ruby/truncator.rb +115 -0
- data/lib/airbrake-ruby/version.rb +6 -0
- data/spec/airbrake_spec.rb +324 -0
- data/spec/async_sender_spec.rb +155 -0
- data/spec/backtrace_spec.rb +427 -0
- data/spec/benchmark_spec.rb +33 -0
- data/spec/code_hunk_spec.rb +115 -0
- data/spec/config/validator_spec.rb +184 -0
- data/spec/config_spec.rb +154 -0
- data/spec/deploy_notifier_spec.rb +48 -0
- data/spec/file_cache.rb +36 -0
- data/spec/filter_chain_spec.rb +92 -0
- data/spec/filters/context_filter_spec.rb +23 -0
- data/spec/filters/dependency_filter_spec.rb +12 -0
- data/spec/filters/exception_attributes_filter_spec.rb +50 -0
- data/spec/filters/gem_root_filter_spec.rb +41 -0
- data/spec/filters/git_last_checkout_filter_spec.rb +46 -0
- data/spec/filters/git_repository_filter.rb +61 -0
- data/spec/filters/git_revision_filter_spec.rb +126 -0
- data/spec/filters/keys_blacklist_spec.rb +225 -0
- data/spec/filters/keys_whitelist_spec.rb +194 -0
- data/spec/filters/root_directory_filter_spec.rb +39 -0
- data/spec/filters/sql_filter_spec.rb +219 -0
- data/spec/filters/system_exit_filter_spec.rb +14 -0
- data/spec/filters/thread_filter_spec.rb +277 -0
- data/spec/fixtures/notroot.txt +7 -0
- data/spec/fixtures/project_root/code.rb +221 -0
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +1 -0
- data/spec/fixtures/project_root/short_file.rb +3 -0
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +5 -0
- data/spec/helpers.rb +9 -0
- data/spec/ignorable_spec.rb +14 -0
- data/spec/inspectable_spec.rb +45 -0
- data/spec/monotonic_time_spec.rb +12 -0
- data/spec/nested_exception_spec.rb +73 -0
- data/spec/notice_notifier_spec.rb +356 -0
- data/spec/notice_notifier_spec/options_spec.rb +259 -0
- data/spec/notice_spec.rb +296 -0
- data/spec/performance_breakdown_spec.rb +12 -0
- data/spec/performance_notifier_spec.rb +435 -0
- data/spec/promise_spec.rb +197 -0
- data/spec/query_spec.rb +11 -0
- data/spec/request_spec.rb +11 -0
- data/spec/response_spec.rb +88 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/stashable_spec.rb +23 -0
- data/spec/stat_spec.rb +47 -0
- data/spec/sync_sender_spec.rb +133 -0
- data/spec/tdigest_spec.rb +230 -0
- data/spec/time_truncate_spec.rb +13 -0
- data/spec/timed_trace_spec.rb +125 -0
- data/spec/truncator_spec.rb +238 -0
- metadata +213 -0
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec.describe Airbrake::Benchmark do
|
2
|
+
describe ".measure" do
|
3
|
+
it "returns measured performance time" do
|
4
|
+
expect(described_class.measure { '10' * 10 }).to be_kind_of(Numeric)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#stop" do
|
9
|
+
before { subject }
|
10
|
+
|
11
|
+
context "when called one time" do
|
12
|
+
its(:stop) { is_expected.to eq(true) }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when called twice or more" do
|
16
|
+
before { subject.stop }
|
17
|
+
|
18
|
+
its(:stop) { is_expected.to eq(false) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#duration" do
|
23
|
+
context "when #stop wasn't called yet" do
|
24
|
+
its(:duration) { is_expected.to be_zero }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when #stop was called" do
|
28
|
+
before { subject.stop }
|
29
|
+
|
30
|
+
its(:duration) { is_expected.to be > 0 }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
RSpec.describe Airbrake::CodeHunk do
|
2
|
+
after do
|
3
|
+
%w[empty_file.rb code.rb banana.rb short_file.rb long_line.txt].each do |f|
|
4
|
+
Airbrake::FileCache[project_root_path(f)] = nil
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#to_h" do
|
9
|
+
context "when file is empty" do
|
10
|
+
subject do
|
11
|
+
described_class.new.get(project_root_path('empty_file.rb'), 1)
|
12
|
+
end
|
13
|
+
|
14
|
+
it { is_expected.to eq(1 => '') }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when line is nil" do
|
18
|
+
subject { described_class.new.get(project_root_path('code.rb'), nil) }
|
19
|
+
|
20
|
+
it { is_expected.to be_nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when a file doesn't exist" do
|
24
|
+
subject { described_class.new.get(project_root_path('banana.rb'), 1) }
|
25
|
+
|
26
|
+
it { is_expected.to be_nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when a file has less than NLINES lines before start line" do
|
30
|
+
subject { described_class.new.get(project_root_path('code.rb'), 1) }
|
31
|
+
|
32
|
+
it do
|
33
|
+
is_expected.to(
|
34
|
+
eq(
|
35
|
+
1 => 'module Airbrake',
|
36
|
+
2 => ' ##',
|
37
|
+
# rubocop:disable Metrics/LineLength
|
38
|
+
3 => ' # Represents a chunk of information that is meant to be either sent to',
|
39
|
+
# rubocop:enable Metrics/LineLength
|
40
|
+
)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when a file has less than NLINES lines after end line" do
|
46
|
+
subject { described_class.new.get(project_root_path('code.rb'), 222) }
|
47
|
+
|
48
|
+
it do
|
49
|
+
is_expected.to(
|
50
|
+
eq(
|
51
|
+
220 => ' end',
|
52
|
+
221 => 'end'
|
53
|
+
)
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when a file has less than NLINES lines before and after" do
|
59
|
+
subject do
|
60
|
+
described_class.new.get(project_root_path('short_file.rb'), 2)
|
61
|
+
end
|
62
|
+
|
63
|
+
it do
|
64
|
+
is_expected.to(
|
65
|
+
eq(
|
66
|
+
1 => 'module Banana',
|
67
|
+
2 => ' attr_reader :bingo',
|
68
|
+
3 => 'end'
|
69
|
+
)
|
70
|
+
)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when a file has enough lines before and after" do
|
75
|
+
subject { described_class.new.get(project_root_path('code.rb'), 100) }
|
76
|
+
|
77
|
+
it do
|
78
|
+
is_expected.to(
|
79
|
+
eq(
|
80
|
+
98 => ' return json if json && json.bytesize <= MAX_NOTICE_SIZE',
|
81
|
+
99 => ' end',
|
82
|
+
100 => '',
|
83
|
+
101 => ' break if truncate == 0',
|
84
|
+
102 => ' end'
|
85
|
+
)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when a line exceeds the length limit" do
|
91
|
+
subject do
|
92
|
+
described_class.new.get(project_root_path('long_line.txt'), 1)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "strips the line" do
|
96
|
+
expect(subject[1]).to eq('l' + 'o' * 196 + 'ng')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when an error occurrs while fetching code" do
|
101
|
+
before do
|
102
|
+
expect(Airbrake::FileCache).to receive(:[]).and_raise(Errno::EACCES)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "logs error and returns nil" do
|
106
|
+
expect(Airbrake::Loggable.instance).to receive(:error).with(
|
107
|
+
/can't read code hunk.+Permission denied/
|
108
|
+
)
|
109
|
+
expect(subject.get(project_root_path('code.rb'), 1)).to(
|
110
|
+
eq(1 => '')
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
RSpec.describe Airbrake::Config::Validator do
|
2
|
+
let(:valid_id) { 123 }
|
3
|
+
let(:valid_key) { '123' }
|
4
|
+
let(:config) { Airbrake::Config.new(config_params) }
|
5
|
+
|
6
|
+
describe ".validate" do
|
7
|
+
context "when project_id is numerical" do
|
8
|
+
let(:config_params) { { project_id: valid_id, project_key: valid_key } }
|
9
|
+
|
10
|
+
it "returns a resolved promise" do
|
11
|
+
promise = described_class.validate(config)
|
12
|
+
expect(promise).to be_resolved
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when project_id is a numerical String" do
|
17
|
+
let(:config_params) { { project_id: '123', project_key: valid_key } }
|
18
|
+
|
19
|
+
it "returns a resolved promise" do
|
20
|
+
promise = described_class.validate(config)
|
21
|
+
expect(promise).to be_resolved
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when project_id is zero" do
|
26
|
+
let(:config_params) { { project_id: 0, project_key: valid_key } }
|
27
|
+
|
28
|
+
it "returns a rejected promise" do
|
29
|
+
promise = described_class.validate(config)
|
30
|
+
expect(promise.value).to eq('error' => ':project_id is required')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when project_id consists of letters" do
|
35
|
+
let(:config_params) { { project_id: 'foo', project_key: valid_key } }
|
36
|
+
|
37
|
+
it "returns a rejected promise" do
|
38
|
+
promise = described_class.validate(config)
|
39
|
+
expect(promise.value).to eq('error' => ':project_id is required')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when project_id is less than zero" do
|
44
|
+
let(:config_params) { { project_id: -123, project_key: valid_key } }
|
45
|
+
|
46
|
+
it "returns a rejected promise" do
|
47
|
+
promise = described_class.validate(config)
|
48
|
+
expect(promise.value).to eq('error' => ':project_id is required')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when project_key is a non-empty String" do
|
53
|
+
let(:config_params) { { project_id: valid_id, project_key: '123' } }
|
54
|
+
|
55
|
+
it "returns a resolved promise" do
|
56
|
+
promise = described_class.validate(config)
|
57
|
+
expect(promise).to be_resolved
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when project_key is an empty String" do
|
62
|
+
let(:config_params) { { project_id: valid_id, project_key: '' } }
|
63
|
+
|
64
|
+
it "returns a rejected promise" do
|
65
|
+
promise = described_class.validate(config)
|
66
|
+
expect(promise.value).to eq('error' => ':project_key is required')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when project_key is a non-String" do
|
71
|
+
let(:config_params) { { project_id: valid_id, project_key: 123 } }
|
72
|
+
|
73
|
+
it "returns a rejected promise" do
|
74
|
+
promise = described_class.validate(config)
|
75
|
+
expect(promise.value).to eq('error' => ':project_key is required')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when environment is nil" do
|
80
|
+
let(:config_params) do
|
81
|
+
{ project_id: valid_id, project_key: valid_key, environment: nil }
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns a resolved promise" do
|
85
|
+
promise = described_class.validate(config)
|
86
|
+
expect(promise).to be_resolved
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when environment is a String" do
|
91
|
+
let(:config_params) do
|
92
|
+
{ project_id: valid_id, project_key: valid_key, environment: 'test' }
|
93
|
+
end
|
94
|
+
|
95
|
+
it "returns a resolved promise" do
|
96
|
+
promise = described_class.validate(config)
|
97
|
+
expect(promise).to be_resolved
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when environment is a Symbol" do
|
102
|
+
let(:config_params) do
|
103
|
+
{ project_id: valid_id, project_key: valid_key, environment: :test }
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns a resolved promise" do
|
107
|
+
promise = described_class.validate(config)
|
108
|
+
expect(promise).to be_resolved
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when environment is non-String and non-Symbol" do
|
113
|
+
let(:config_params) do
|
114
|
+
{ project_id: valid_id, project_key: valid_key, environment: 1.0 }
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns a rejected promise" do
|
118
|
+
promise = described_class.validate(config)
|
119
|
+
expect(promise.value).to eq(
|
120
|
+
'error' => "the 'environment' option must be configured with a " \
|
121
|
+
"Symbol (or String), but 'Float' was provided: 1.0"
|
122
|
+
)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when environment is String-like" do
|
127
|
+
let(:string_inquirer) { Class.new(String) }
|
128
|
+
|
129
|
+
let(:config_params) do
|
130
|
+
{
|
131
|
+
project_id: valid_id,
|
132
|
+
project_key: valid_key,
|
133
|
+
environment: string_inquirer.new('test')
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
it "returns a resolved promise" do
|
138
|
+
promise = described_class.validate(config)
|
139
|
+
expect(promise).to be_resolved
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "#check_notify_ability" do
|
145
|
+
context "when current environment is ignored" do
|
146
|
+
let(:config_params) do
|
147
|
+
{
|
148
|
+
project_id: valid_id,
|
149
|
+
project_key: valid_key,
|
150
|
+
environment: 'test',
|
151
|
+
ignore_environments: ['test']
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
it "returns a rejected promise" do
|
156
|
+
promise = described_class.check_notify_ability(config)
|
157
|
+
expect(promise.value).to eq(
|
158
|
+
'error' => "current environment 'test' is ignored"
|
159
|
+
)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context "when no environment is specified but ignore_environments is" do
|
164
|
+
let(:config_params) do
|
165
|
+
{
|
166
|
+
project_id: valid_id,
|
167
|
+
project_key: valid_key,
|
168
|
+
ignore_environments: ['test']
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
it "returns a rejected promise" do
|
173
|
+
promise = described_class.check_notify_ability(config)
|
174
|
+
expect(promise).to be_resolved
|
175
|
+
end
|
176
|
+
|
177
|
+
it "warns about 'no effect'" do
|
178
|
+
expect(config.logger).to receive(:warn)
|
179
|
+
.with(/'ignore_environments' has no effect/)
|
180
|
+
described_class.check_notify_ability(config)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
RSpec.describe Airbrake::Config do
|
2
|
+
let(:resolved_promise) { Airbrake::Promise.new.resolve }
|
3
|
+
let(:rejected_promise) { Airbrake::Promise.new.reject }
|
4
|
+
|
5
|
+
let(:valid_params) { { project_id: 1, project_key: '2' } }
|
6
|
+
|
7
|
+
its(:project_id) { is_expected.to be_nil }
|
8
|
+
its(:project_key) { is_expected.to be_nil }
|
9
|
+
its(:logger) { is_expected.to be_a(Logger) }
|
10
|
+
its(:app_version) { is_expected.to be_nil }
|
11
|
+
its(:versions) { is_expected.to be_empty }
|
12
|
+
its(:host) { is_expected.to eq('https://api.airbrake.io') }
|
13
|
+
its(:endpoint) { is_expected.not_to be_nil }
|
14
|
+
its(:workers) { is_expected.to eq(1) }
|
15
|
+
its(:queue_size) { is_expected.to eq(100) }
|
16
|
+
its(:root_directory) { is_expected.to eq(Bundler.root.realpath.to_s) }
|
17
|
+
its(:environment) { is_expected.to be_nil }
|
18
|
+
its(:ignore_environments) { is_expected.to be_empty }
|
19
|
+
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(:performance_stats) { is_expected.to eq(true) }
|
23
|
+
its(:performance_stats_flush_period) { is_expected.to eq(15) }
|
24
|
+
its(:query_stats) { is_expected.to eq(false) }
|
25
|
+
|
26
|
+
describe "#new" do
|
27
|
+
context "when user config is passed" do
|
28
|
+
subject { described_class.new(logger: StringIO.new) }
|
29
|
+
its(:logger) { is_expected.to be_a(StringIO) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#valid?" do
|
34
|
+
context "when #validate returns a resolved promise" do
|
35
|
+
before { expect(subject).to receive(:validate).and_return(resolved_promise) }
|
36
|
+
it { is_expected.to be_valid }
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when #validate returns a rejected promise" do
|
40
|
+
before { expect(subject).to receive(:validate).and_return(rejected_promise) }
|
41
|
+
it { is_expected.not_to be_valid }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#ignored_environment?" do
|
46
|
+
context "when Validator returns a resolved promise" do
|
47
|
+
before do
|
48
|
+
expect(Airbrake::Config::Validator).to receive(:check_notify_ability)
|
49
|
+
.and_return(resolved_promise)
|
50
|
+
end
|
51
|
+
|
52
|
+
its(:ignored_environment?) { is_expected.to be_falsey }
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when Validator returns a rejected promise" do
|
56
|
+
before do
|
57
|
+
expect(Airbrake::Config::Validator).to receive(:check_notify_ability)
|
58
|
+
.and_return(rejected_promise)
|
59
|
+
end
|
60
|
+
|
61
|
+
its(:ignored_environment?) { is_expected.to be_truthy }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#endpoint" do
|
66
|
+
subject { described_class.new(valid_params.merge(user_config)) }
|
67
|
+
|
68
|
+
context "when host ends with a URL with a slug with a trailing slash" do
|
69
|
+
let(:user_config) { { host: 'https://localhost/bingo/' } }
|
70
|
+
|
71
|
+
its(:endpoint) do
|
72
|
+
is_expected.to eq(URI('https://localhost/bingo/api/v3/projects/1/notices'))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when host ends with a URL with a slug without a trailing slash" do
|
77
|
+
let(:user_config) { { host: 'https://localhost/bingo' } }
|
78
|
+
|
79
|
+
its(:endpoint) do
|
80
|
+
is_expected.to eq(URI('https://localhost/api/v3/projects/1/notices'))
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "#validate" do
|
86
|
+
its(:validate) { is_expected.to be_an(Airbrake::Promise) }
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "#check_configuration" do
|
90
|
+
let(:user_config) { {} }
|
91
|
+
|
92
|
+
subject { described_class.new(valid_params.merge(user_config)) }
|
93
|
+
|
94
|
+
its(:check_configuration) { is_expected.to be_an(Airbrake::Promise) }
|
95
|
+
|
96
|
+
context "when config is invalid" do
|
97
|
+
let(:user_config) { { project_id: nil } }
|
98
|
+
its(:check_configuration) { is_expected.to be_rejected }
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when current environment is ignored" do
|
102
|
+
let(:user_config) { { environment: 'test', ignore_environments: ['test'] } }
|
103
|
+
its(:check_configuration) { is_expected.to be_rejected }
|
104
|
+
end
|
105
|
+
|
106
|
+
context "when config is valid and allows notifying" do
|
107
|
+
its(:check_configuration) { is_expected.not_to be_rejected }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#check_performance_options" do
|
112
|
+
it "returns a promise" do
|
113
|
+
resource = Airbrake::Query.new(
|
114
|
+
method: '', route: '', query: '', start_time: Time.now
|
115
|
+
)
|
116
|
+
expect(subject.check_performance_options(resource))
|
117
|
+
.to be_an(Airbrake::Promise)
|
118
|
+
end
|
119
|
+
|
120
|
+
context "when performance stats are disabled" do
|
121
|
+
before { subject.performance_stats = false }
|
122
|
+
|
123
|
+
let(:resource) do
|
124
|
+
Airbrake::Request.new(
|
125
|
+
method: 'GET', route: '/foo', status_code: 200, start_time: Time.new
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "returns a rejected promise" do
|
130
|
+
promise = subject.check_performance_options(resource)
|
131
|
+
expect(promise.value).to eq(
|
132
|
+
'error' => "The Performance Stats feature is disabled"
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when query stats are disabled" do
|
138
|
+
before { subject.query_stats = false }
|
139
|
+
|
140
|
+
let(:resource) do
|
141
|
+
Airbrake::Query.new(
|
142
|
+
method: 'GET', route: '/foo', query: '', start_time: Time.new
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "returns a rejected promise" do
|
147
|
+
promise = subject.check_performance_options(resource)
|
148
|
+
expect(promise.value).to eq(
|
149
|
+
'error' => "The Query Stats feature is disabled"
|
150
|
+
)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|