bundler-audit 0.8.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug-report.md +44 -0
  3. data/.github/ISSUE_TEMPLATE/feature-request.md +14 -0
  4. data/.github/workflows/ruby.yml +16 -2
  5. data/.rubocop.yml +86 -0
  6. data/COPYING.txt +4 -4
  7. data/ChangeLog.md +51 -0
  8. data/Gemfile +8 -3
  9. data/README.md +58 -26
  10. data/Rakefile +7 -3
  11. data/bundler-audit.gemspec +2 -3
  12. data/gemspec.yml +7 -0
  13. data/lib/bundler/audit/advisory.rb +25 -3
  14. data/lib/bundler/audit/cli/formats/json.rb +17 -3
  15. data/lib/bundler/audit/cli/formats/junit.rb +127 -0
  16. data/lib/bundler/audit/cli/formats/text.rb +13 -9
  17. data/lib/bundler/audit/cli/formats.rb +8 -4
  18. data/lib/bundler/audit/cli.rb +37 -18
  19. data/lib/bundler/audit/configuration.rb +8 -5
  20. data/lib/bundler/audit/database.rb +28 -10
  21. data/lib/bundler/audit/results/insecure_source.rb +5 -2
  22. data/lib/bundler/audit/results/unpatched_gem.rb +7 -3
  23. data/lib/bundler/audit/results.rb +2 -2
  24. data/lib/bundler/audit/scanner.rb +17 -8
  25. data/lib/bundler/audit/task.rb +50 -5
  26. data/lib/bundler/audit/version.rb +3 -3
  27. data/lib/bundler/audit.rb +2 -2
  28. data/spec/advisory_spec.rb +19 -2
  29. data/spec/bundle/insecure_sources/Gemfile.lock +71 -73
  30. data/spec/bundle/secure/Gemfile.lock +60 -62
  31. data/spec/cli/formats/json_spec.rb +1 -0
  32. data/spec/cli/formats/junit_spec.rb +284 -0
  33. data/spec/cli/formats/text_spec.rb +88 -18
  34. data/spec/cli_spec.rb +57 -17
  35. data/spec/database_spec.rb +26 -2
  36. data/spec/fixtures/advisory/CVE-2020-1234.yml +1 -0
  37. data/spec/fixtures/lib/bundler/audit/cli/formats/bad.rb +0 -2
  38. data/spec/fixtures/lib/bundler/audit/cli/formats/good.rb +0 -2
  39. data/spec/results/unpatched_gem_spec.rb +2 -2
  40. data/spec/scanner_spec.rb +25 -1
  41. data/spec/spec_helper.rb +5 -1
  42. metadata +29 -8
@@ -0,0 +1,284 @@
1
+ require 'spec_helper'
2
+ require 'bundler/audit/cli/formats'
3
+ require 'bundler/audit/cli/formats/junit'
4
+ require 'bundler/audit/report'
5
+
6
+ describe Bundler::Audit::CLI::Formats::Junit do
7
+ it "must register the 'junit' format" do
8
+ expect(Bundler::Audit::CLI::Formats[:junit]).to be described_class
9
+ end
10
+
11
+ let(:options) { {} }
12
+
13
+ subject do
14
+ Bundler::Audit::CLI.new([],options).tap do |obj|
15
+ obj.extend described_class
16
+ end
17
+ end
18
+
19
+ describe "#print_report" do
20
+ let(:report) { Bundler::Audit::Report.new }
21
+ let(:stdout) { StringIO.new }
22
+
23
+ before { subject.print_report(report,stdout) }
24
+
25
+ let(:output) { stdout.string }
26
+
27
+ context "when vulnerabilities were found" do
28
+ context "when the report contains InsecureSources" do
29
+ let(:uri) { URI('git://github.com/foo/bar.git') }
30
+ let(:insecure_source) do
31
+ Bundler::Audit::Results::InsecureSource.new(uri)
32
+ end
33
+
34
+ let(:report) do
35
+ super().tap do |report|
36
+ report << insecure_source
37
+ end
38
+ end
39
+
40
+ it 'must print "Insecure Source URI found: ..."' do
41
+ expect(output).to include("Insecure Source URI found: #{uri}")
42
+ end
43
+
44
+ it 'must print have a positive number of failures' do
45
+ expect(output).to match(/failures="[1-9][0-9]*"/)
46
+ end
47
+ end
48
+
49
+ context "when the report contains UnpatchedGems" do
50
+ let(:gem) do
51
+ Gem::Specification.new do |spec|
52
+ spec.name = 'test'
53
+ spec.version = '0.1.0'
54
+ end
55
+ end
56
+
57
+ let(:advisory) do
58
+ Bundler::Audit::Advisory.load(Fixtures.join('advisory','CVE-2020-1234.yml'))
59
+ end
60
+ let(:unpatched_gem) do
61
+ Bundler::Audit::Results::UnpatchedGem.new(gem,advisory)
62
+ end
63
+
64
+ let(:report) do
65
+ super().tap do |report|
66
+ report << unpatched_gem
67
+ end
68
+ end
69
+
70
+ it "must print 'Name: ...'" do
71
+ expect(output).to include("Name: #{gem.name}")
72
+ end
73
+
74
+ it "must print 'Version: ...'" do
75
+ expect(output).to include("Version: #{gem.version}")
76
+ end
77
+
78
+ context "when the advisory has a CVE ID" do
79
+ it "must print 'CVE: CVE-YYYY-NNNN'" do
80
+ expect(output).to include("Advisory: CVE-#{advisory.cve} GHSA-aaaa-bbbb-cccc")
81
+ end
82
+ end
83
+
84
+ context "when the advisory does not have a CVE ID" do
85
+ let(:advisory) do
86
+ super().tap do |advisory|
87
+ advisory.cve = nil
88
+ end
89
+ end
90
+
91
+ it "must not print 'CVE: CVE-YYYY-NNNN'" do
92
+ expect(output).to_not include("CVE-")
93
+ end
94
+ end
95
+
96
+ context "when the advisory has a GHSA ID" do
97
+ it "must print 'GHSA-xxxx-xxxx-xxxx'" do
98
+ expect(output).to include("GHSA-#{advisory.ghsa}")
99
+ end
100
+ end
101
+
102
+ context "when the advisory does not have a GHSA ID" do
103
+ let(:advisory) do
104
+ super().tap do |advisory|
105
+ advisory.ghsa = nil
106
+ end
107
+ end
108
+
109
+ it "must not print 'GHSA-xxxx-xxxx-xxxx'" do
110
+ expect(output).to_not include("GHSA-#{advisory.ghsa}")
111
+ end
112
+ end
113
+
114
+ context "when CVSS v3 is present" do
115
+ context "when Advisory#criticality is :none (cvss_v3 only)" do
116
+ let(:advisory) do
117
+ super().tap do |advisory|
118
+ advisory.cvss_v3 = 0.0
119
+ end
120
+ end
121
+
122
+ it "must print 'Criticality: None'" do
123
+ expect(output).to include("Criticality: None")
124
+ end
125
+ end
126
+
127
+ context "when Advisory#criticality is :low" do
128
+ let(:advisory) do
129
+ super().tap do |advisory|
130
+ advisory.cvss_v3 = 0.1
131
+ end
132
+ end
133
+
134
+ it "must print 'Criticality: Low'" do
135
+ expect(output).to include("Criticality: Low")
136
+ end
137
+ end
138
+
139
+ context "when Advisory#criticality is :medium" do
140
+ let(:advisory) do
141
+ super().tap do |advisory|
142
+ advisory.cvss_v3 = 4.0
143
+ end
144
+ end
145
+
146
+ it "must print 'Criticality: Medium'" do
147
+ expect(output).to include("Criticality: Medium")
148
+ end
149
+ end
150
+
151
+ context "when Advisory#criticality is :high" do
152
+ let(:advisory) do
153
+ super().tap do |advisory|
154
+ advisory.cvss_v3 = 7.0
155
+ end
156
+ end
157
+
158
+ it "must print 'Criticality: High'" do
159
+ expect(output).to include("Criticality: High")
160
+ end
161
+ end
162
+
163
+ context "when Advisory#criticality is :critical (cvss_v3 only)" do
164
+ let(:advisory) do
165
+ super().tap do |advisory|
166
+ advisory.cvss_v3 = 9.0
167
+ end
168
+ end
169
+
170
+ it "must print 'Criticality: High'" do
171
+ expect(output).to include("Criticality: Critical")
172
+ end
173
+ end
174
+ end
175
+
176
+ context "when CVSS v2 is present" do
177
+ let(:advisory) do
178
+ super().tap do |advisory|
179
+ advisory.cvss_v3 = nil
180
+ end
181
+ end
182
+
183
+ context "when Advisory#criticality is :low" do
184
+ let(:advisory) do
185
+ super().tap do |advisory|
186
+ advisory.cvss_v2 = 0.0
187
+ end
188
+ end
189
+
190
+ it "must print 'Criticality: Low'" do
191
+ expect(output).to include("Criticality: Low")
192
+ end
193
+ end
194
+
195
+ context "when Advisory#criticality is :medium" do
196
+ let(:advisory) do
197
+ super().tap do |advisory|
198
+ advisory.cvss_v2 = 4.0
199
+ end
200
+ end
201
+
202
+ it "must print 'Criticality: Medium'" do
203
+ expect(output).to include("Criticality: Medium")
204
+ end
205
+ end
206
+
207
+ context "when Advisory#criticality is :high" do
208
+ let(:advisory) do
209
+ super().tap do |advisory|
210
+ advisory.cvss_v2 = 7.0
211
+ end
212
+ end
213
+
214
+ it "must print 'Criticality: High'" do
215
+ expect(output).to include("Criticality: High")
216
+ end
217
+ end
218
+ end
219
+
220
+ it "must print 'URL: ...'" do
221
+ expect(output).to include("URL: #{advisory.url}")
222
+ end
223
+
224
+ context "when :verbose is not enabled" do
225
+ it 'must print "Title:" and the advisory description' do
226
+ expect(output).to include("Title: #{advisory.title}")
227
+ end
228
+ end
229
+
230
+ context "when Advisory#title contains XML special chars" do
231
+ let(:advisory) do
232
+ super().tap do |advisory|
233
+ advisory.title = '<entity id="one">One</entity>'
234
+ end
235
+ end
236
+
237
+ it 'must print "Title:" with escaped characters' do
238
+ expect(output).to include("Title: #{CGI.escapeHTML(advisory.title)}")
239
+ end
240
+ end
241
+
242
+ context "when Advisory#patched_versions is not empty" do
243
+ it 'must print "Solution: upgrade to ..."' do
244
+ expect(output).to include("Solution: upgrade to #{CGI.escapeHTML(advisory.patched_versions.map { |v| "'#{v}'" }.join(', '))}")
245
+ end
246
+ end
247
+
248
+ context "when Advisory#patched_versions is empty" do
249
+ let(:advisory) do
250
+ super().tap do |advisory|
251
+ advisory.patched_versions = []
252
+ end
253
+ end
254
+
255
+ it 'must print "Solution: remove or disable this gem until a patch is available!"' do
256
+ expect(output).to include("Solution: remove or disable this gem until a patch is available!")
257
+ end
258
+ end
259
+
260
+ it 'must print have a positive number of failures' do
261
+ expect(output).to match(/failures="[1-9][0-9]*"/)
262
+ end
263
+ end
264
+ end
265
+
266
+ context "when no vulnerabilities were found" do
267
+ it 'must print an empty testsuite' do
268
+ expect(output).to include('failures="0"')
269
+ end
270
+
271
+ context "when :quiet is enabled" do
272
+ let(:options) { {quiet: true} }
273
+
274
+ it "should print nothing" do
275
+ expect(output).to be_empty
276
+ end
277
+ end
278
+ end
279
+
280
+ it "must restore $stdout" do
281
+ expect($stdout).to_not be(stdout)
282
+ end
283
+ end
284
+ end
@@ -104,39 +104,109 @@ describe Bundler::Audit::CLI::Formats::Text do
104
104
  end
105
105
  end
106
106
 
107
- context "when Advisory#criticality is :low" do
108
- let(:advisory) do
109
- super().tap do |advisory|
110
- advisory.cvss_v2 = 0.0
107
+ context "when CVSS v3 is present" do
108
+ context "when Advisory#criticality is :none (cvss_v3 only)" do
109
+ let(:advisory) do
110
+ super().tap do |advisory|
111
+ advisory.cvss_v3 = 0.0
112
+ end
113
+ end
114
+
115
+ it "must print 'Criticality: None'" do
116
+ expect(output_lines).to include("Criticality: None")
111
117
  end
112
118
  end
113
119
 
114
- it "must print 'Criticality: Low'" do
115
- expect(output_lines).to include("Criticality: Low")
120
+ context "when Advisory#criticality is :low" do
121
+ let(:advisory) do
122
+ super().tap do |advisory|
123
+ advisory.cvss_v3 = 0.1
124
+ end
125
+ end
126
+
127
+ it "must print 'Criticality: Low'" do
128
+ expect(output_lines).to include("Criticality: Low")
129
+ end
116
130
  end
117
- end
118
131
 
119
- context "when Advisory#criticality is :medium" do
120
- let(:advisory) do
121
- super().tap do |advisory|
122
- advisory.cvss_v2 = 6.9
132
+ context "when Advisory#criticality is :medium" do
133
+ let(:advisory) do
134
+ super().tap do |advisory|
135
+ advisory.cvss_v3 = 4.0
136
+ end
137
+ end
138
+
139
+ it "must print 'Criticality: Medium'" do
140
+ expect(output_lines).to include("Criticality: Medium")
123
141
  end
124
142
  end
125
143
 
126
- it "must print 'Criticality: Medium'" do
127
- expect(output_lines).to include("Criticality: Medium")
144
+ context "when Advisory#criticality is :high" do
145
+ let(:advisory) do
146
+ super().tap do |advisory|
147
+ advisory.cvss_v3 = 7.0
148
+ end
149
+ end
150
+
151
+ it "must print 'Criticality: High'" do
152
+ expect(output_lines).to include("Criticality: High")
153
+ end
154
+ end
155
+
156
+ context "when Advisory#criticality is :critical (cvss_v3 only)" do
157
+ let(:advisory) do
158
+ super().tap do |advisory|
159
+ advisory.cvss_v3 = 9.0
160
+ end
161
+ end
162
+
163
+ it "must print 'Criticality: High'" do
164
+ expect(output_lines).to include("Criticality: Critical")
165
+ end
128
166
  end
129
167
  end
130
168
 
131
- context "when Advisory#criticality is :high" do
169
+ context "when CVSS v2 is present" do
132
170
  let(:advisory) do
133
171
  super().tap do |advisory|
134
- advisory.cvss_v2 = 10.0
172
+ advisory.cvss_v3 = nil
173
+ end
174
+ end
175
+
176
+ context "when Advisory#criticality is :low" do
177
+ let(:advisory) do
178
+ super().tap do |advisory|
179
+ advisory.cvss_v2 = 0.0
180
+ end
181
+ end
182
+
183
+ it "must print 'Criticality: Low'" do
184
+ expect(output_lines).to include("Criticality: Low")
135
185
  end
136
186
  end
137
187
 
138
- it "must print 'Criticality: High'" do
139
- expect(output_lines).to include("Criticality: High")
188
+ context "when Advisory#criticality is :medium" do
189
+ let(:advisory) do
190
+ super().tap do |advisory|
191
+ advisory.cvss_v2 = 4.0
192
+ end
193
+ end
194
+
195
+ it "must print 'Criticality: Medium'" do
196
+ expect(output_lines).to include("Criticality: Medium")
197
+ end
198
+ end
199
+
200
+ context "when Advisory#criticality is :high" do
201
+ let(:advisory) do
202
+ super().tap do |advisory|
203
+ advisory.cvss_v2 = 7.0
204
+ end
205
+ end
206
+
207
+ it "must print 'Criticality: High'" do
208
+ expect(output_lines).to include("Criticality: High")
209
+ end
140
210
  end
141
211
  end
142
212
 
@@ -160,7 +230,7 @@ describe Bundler::Audit::CLI::Formats::Text do
160
230
 
161
231
  context "when Advisory#patched_versions is not empty" do
162
232
  it 'must print "Solution: upgrade to ..."' do
163
- expect(output_lines).to include("Solution: upgrade to #{advisory.patched_versions.join(', ')}")
233
+ expect(output_lines).to include("Solution: upgrade to #{advisory.patched_versions.map { |v| "'#{v}'" }.join(', ')}")
164
234
  end
165
235
  end
166
236
 
data/spec/cli_spec.rb CHANGED
@@ -15,28 +15,68 @@ describe Bundler::Audit::CLI do
15
15
  end
16
16
  end
17
17
 
18
+ describe "#stats" do
19
+ let(:size) { 1234 }
20
+ let(:last_updated_at) { Time.now }
21
+ let(:commit_id) { 'f0f97c4c493b853319e029d226e96f2c2f0dc539' }
22
+
23
+ let(:database) { double(Bundler::Audit::Database) }
24
+
25
+ before do
26
+ expect(Bundler::Audit::Database).to receive(:new).and_return(database)
27
+
28
+ expect(database).to receive(:size).and_return(size)
29
+ expect(database).to receive(:last_updated_at).and_return(last_updated_at)
30
+ expect(database).to receive(:commit_id).and_return(commit_id)
31
+ end
32
+
33
+ it "prints total advisory count" do
34
+ expect { subject.stats }.to output(
35
+ include(
36
+ "advisories:\t#{size} advisories",
37
+ "last updated:\t#{last_updated_at}",
38
+ "commit:\t#{commit_id}"
39
+ )
40
+ ).to_stdout
41
+ end
42
+ end
43
+
18
44
  describe "#update" do
45
+ let(:database) { double(Bundler::Audit::Database) }
46
+
47
+ before do
48
+ allow(Bundler::Audit::Database).to receive(:new).and_return(database)
49
+ end
50
+
19
51
  context "not --quiet (the default)" do
20
52
  context "when update succeeds" do
53
+ let(:size) { 1234 }
54
+ let(:last_updated_at) { Time.now }
55
+ let(:commit_id) { 'f0f97c4c493b853319e029d226e96f2c2f0dc539' }
56
+
21
57
  before do
22
- expect_any_instance_of(Bundler::Audit::Database).to receive(:update!).and_return(true)
58
+ expect(database).to receive(:update!).and_return(true)
59
+ expect(database).to receive(:size).and_return(size)
60
+ expect(database).to receive(:last_updated_at).and_return(last_updated_at)
61
+ expect(database).to receive(:commit_id).and_return(commit_id)
23
62
  end
24
63
 
25
- it "prints updated message" do
26
- expect { subject.update }.to output(/Updated ruby-advisory-db/).to_stdout
27
- end
28
-
29
- it "prints total advisory count" do
30
- size = 1234
31
- expect_any_instance_of(Bundler::Audit::Database).to receive(:size).and_return(size)
32
-
33
- expect { subject.update }.to output(/advisories:\t#{size} advisories/).to_stdout
64
+ it "prints updated message and then the stats" do
65
+ expect { subject.update }.to output(
66
+ include(
67
+ "Updated ruby-advisory-db",
68
+ "ruby-advisory-db:",
69
+ " advisories:\t#{size} advisories",
70
+ " last updated:\t#{last_updated_at}",
71
+ " commit:\t#{commit_id}"
72
+ )
73
+ ).to_stdout
34
74
  end
35
75
  end
36
76
 
37
77
  context "when update fails" do
38
78
  before do
39
- expect_any_instance_of(Bundler::Audit::Database).to receive(:update!).and_return(false)
79
+ expect(database).to receive(:update!).and_return(false)
40
80
  end
41
81
 
42
82
  it "prints failure message" do
@@ -58,22 +98,22 @@ describe Bundler::Audit::CLI do
58
98
  expect(error.status).to eq(1)
59
99
  end
60
100
  end
61
-
62
101
  end
63
102
 
64
103
  context "when git is not installed" do
65
104
  before do
66
- expect_any_instance_of(Bundler::Audit::Database).to receive(:update!).and_return(nil)
105
+ expect(database).to receive(:update!).and_return(nil)
106
+
67
107
  expect(Bundler).to receive(:git_present?).and_return(false)
68
108
  end
69
109
 
70
110
  it "prints failure message" do
71
- expect do
111
+ expect {
72
112
  begin
73
113
  subject.update
74
114
  rescue SystemExit
75
115
  end
76
- end.to output(/Git is not installed!/).to_stderr
116
+ }.to output(/Git is not installed!/).to_stderr
77
117
  end
78
118
 
79
119
  it "exits with error status code" do
@@ -96,7 +136,7 @@ describe Bundler::Audit::CLI do
96
136
 
97
137
  context "when update succeeds" do
98
138
  before do
99
- expect_any_instance_of(Bundler::Audit::Database).to(
139
+ expect(database).to(
100
140
  receive(:update!).with(quiet: true).and_return(true)
101
141
  )
102
142
  end
@@ -108,7 +148,7 @@ describe Bundler::Audit::CLI do
108
148
 
109
149
  context "when update fails" do
110
150
  before do
111
- expect_any_instance_of(Bundler::Audit::Database).to(
151
+ expect(database).to(
112
152
  receive(:update!).with(quiet: true).and_return(false)
113
153
  )
114
154
  end
@@ -174,7 +174,7 @@ describe Bundler::Audit::Database do
174
174
  end
175
175
 
176
176
  context "when given a directory" do
177
- let(:path ) { Dir.tmpdir }
177
+ let(:path) { Dir.tmpdir }
178
178
 
179
179
  subject { described_class.new(path) }
180
180
 
@@ -263,12 +263,36 @@ describe Bundler::Audit::Database do
263
263
  end
264
264
  end
265
265
 
266
+ describe "#commit_id" do
267
+ context "when the database is a git repository" do
268
+ let(:last_commit) { Fixtures::Database::COMMIT }
269
+
270
+ it "should return the last commit ID" do
271
+ expect(subject.commit_id).to be == last_commit
272
+ end
273
+ end
274
+
275
+ context "when the database is a bare directory" do
276
+ let(:path) { Fixtures.join('mock-database-dir') }
277
+
278
+ before { FileUtils.mkdir(path) }
279
+
280
+ subject { described_class.new(path) }
281
+
282
+ it "should return the mtime of the directory" do
283
+ expect(subject.commit_id).to be(nil)
284
+ end
285
+
286
+ after { FileUtils.rmdir(path) }
287
+ end
288
+ end
289
+
266
290
  describe "#last_updated_at" do
267
291
  context "when the database is a git repository" do
268
292
  let(:last_commit) { Fixtures::Database::COMMIT }
269
293
  let(:last_commit_timestamp) do
270
294
  Dir.chdir(Fixtures::Database::PATH) do
271
- Time.parse(`git log --date=iso8601 --pretty="%cd" #{last_commit}`)
295
+ Time.parse(`git log -n 2 --date=iso8601 --pretty="%cd" #{last_commit}`)
272
296
  end
273
297
  end
274
298
 
@@ -10,6 +10,7 @@ description: |
10
10
  This is a test advisory.
11
11
 
12
12
  cvss_v2: 10.0
13
+ cvss_v3: 9.8
13
14
 
14
15
  unaffected_versions:
15
16
  - "< 0.1.0"
@@ -5,11 +5,9 @@ module Bundler
5
5
  class CLI < ::Thor
6
6
  module Formats
7
7
  module Bad
8
-
9
8
  def print_report(report,output=$stdout)
10
9
  say "I am a bad format!", :red
11
10
  end
12
-
13
11
  end
14
12
 
15
13
  Formats.register :incorrect, Bad
@@ -5,11 +5,9 @@ module Bundler
5
5
  class CLI < ::Thor
6
6
  module Formats
7
7
  module Good
8
-
9
8
  def print_report(report,output=$stdout)
10
9
  say "I am a good format.", :green
11
10
  end
12
-
13
11
  end
14
12
 
15
13
  Formats.register :good, Good
@@ -89,9 +89,10 @@ describe Bundler::Audit::Results::UnpatchedGem do
89
89
  subject { super().to_h }
90
90
 
91
91
  let(:advisory_hash) { {id: advisory.id} }
92
+
92
93
  before { expect(advisory).to receive(:to_h).and_return(advisory_hash) }
93
94
 
94
- it "must inclide type: :unpatched_gem" do
95
+ it "must include type: :unpatched_gem" do
95
96
  expect(subject[:type]).to be :unpatched_gem
96
97
  end
97
98
 
@@ -110,7 +111,6 @@ describe Bundler::Audit::Results::UnpatchedGem do
110
111
  end
111
112
 
112
113
  it "must include a :advisory key containing a Hash of the advisory" do
113
-
114
114
  expect(subject[:advisory]).to be == advisory_hash
115
115
  end
116
116
  end
data/spec/scanner_spec.rb CHANGED
@@ -36,7 +36,7 @@ describe Scanner do
36
36
  end
37
37
 
38
38
  context "when the :ignore option is given" do
39
- subject { super().scan(:ignore => ['OSVDB-89026']) }
39
+ subject { super().scan(ignore: ['OSVDB-89026']) }
40
40
 
41
41
  it "should ignore the specified advisories" do
42
42
  ids = subject.map { |result| result.advisory.id }
@@ -79,6 +79,30 @@ describe Scanner do
79
79
 
80
80
  expect(ids).not_to include('OSVDB-89025')
81
81
  end
82
+
83
+ context "when config path is absolute" do
84
+ let(:bundle) { 'unpatched_gems' }
85
+ let(:absolute_config_path) { File.absolute_path(File.join('spec','bundle','unpatched_gems_with_dot_configuration', '.bundler-audit.yml')) }
86
+ let(:scanner) { described_class.new(directory,'Gemfile.lock',Database.new,absolute_config_path) }
87
+
88
+ it "should read the config just fine" do
89
+ ids = subject.map { |result| result.advisory.id }
90
+
91
+ expect(ids).not_to include('OSVDB-89025')
92
+ end
93
+ end
94
+
95
+ context "when config path is relative" do
96
+ let(:bundle) { 'unpatched_gems' }
97
+ let(:relative_config_path) { File.join('..', 'unpatched_gems_with_dot_configuration', '.bundler-audit.yml') }
98
+ let(:scanner) { described_class.new(directory,'Gemfile.lock',Database.new,relative_config_path) }
99
+
100
+ it "should read the config just fine" do
101
+ ids = subject.map { |result| result.advisory.id }
102
+
103
+ expect(ids).not_to include('OSVDB-89025')
104
+ end
105
+ end
82
106
  end
83
107
  end
84
108