nvd-json_feeds 0.1.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/.document +3 -0
- data/.github/workflows/ruby.yml +29 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +25 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.md +136 -0
- data/Rakefile +31 -0
- data/gemspec.yml +22 -0
- data/lib/nvd/json_feeds.rb +25 -0
- data/lib/nvd/json_feeds/exceptions.rb +15 -0
- data/lib/nvd/json_feeds/feed.rb +50 -0
- data/lib/nvd/json_feeds/feed_file.rb +95 -0
- data/lib/nvd/json_feeds/feed_uri.rb +131 -0
- data/lib/nvd/json_feeds/gz_feed_file.rb +60 -0
- data/lib/nvd/json_feeds/gz_feed_uri.rb +25 -0
- data/lib/nvd/json_feeds/json_feed_file.rb +21 -0
- data/lib/nvd/json_feeds/meta.rb +122 -0
- data/lib/nvd/json_feeds/meta_feed_uri.rb +22 -0
- data/lib/nvd/json_feeds/schema/configurations.rb +61 -0
- data/lib/nvd/json_feeds/schema/configurations/node.rb +98 -0
- data/lib/nvd/json_feeds/schema/cpe/has_uri.rb +66 -0
- data/lib/nvd/json_feeds/schema/cpe/match.rb +117 -0
- data/lib/nvd/json_feeds/schema/cpe/name.rb +67 -0
- data/lib/nvd/json_feeds/schema/cve_feed.rb +142 -0
- data/lib/nvd/json_feeds/schema/cve_item.rb +94 -0
- data/lib/nvd/json_feeds/schema/cvss_v2.rb +298 -0
- data/lib/nvd/json_feeds/schema/cvss_v3.rb +332 -0
- data/lib/nvd/json_feeds/schema/has_data_version.rb +54 -0
- data/lib/nvd/json_feeds/schema/impact.rb +73 -0
- data/lib/nvd/json_feeds/schema/impact/base_metric_v2.rb +132 -0
- data/lib/nvd/json_feeds/schema/impact/base_metric_v3.rb +79 -0
- data/lib/nvd/json_feeds/schema/timestamp.rb +9 -0
- data/lib/nvd/json_feeds/version.rb +6 -0
- data/lib/nvd/json_feeds/zip_feed_file.rb +64 -0
- data/lib/nvd/json_feeds/zip_feed_uri.rb +25 -0
- data/nvd-json_feeds.gemspec +61 -0
- data/spec/feed_file_examples.rb +27 -0
- data/spec/feed_file_spec.rb +42 -0
- data/spec/feed_spec.rb +56 -0
- data/spec/feed_uri_spec.rb +81 -0
- data/spec/fixtures/gz_feed_file/nvdcve-1.1-recent.json.gz +0 -0
- data/spec/fixtures/nvdcve-1.1-recent.json +180 -0
- data/spec/fixtures/zip_feed_file/nvdcve-1.1-recent.json.zip +0 -0
- data/spec/gz_feed_file_spec.rb +66 -0
- data/spec/gz_feed_uri_spec.rb +35 -0
- data/spec/json_feed_file_spec.rb +18 -0
- data/spec/json_feeds_spec.rb +8 -0
- data/spec/meta_spec.rb +141 -0
- data/spec/schema/configurations/node_spec.rb +87 -0
- data/spec/schema/configurations_spec.rb +57 -0
- data/spec/schema/cpe/match_spec.rb +188 -0
- data/spec/schema/cpe/name_spec.rb +54 -0
- data/spec/schema/cve_feed_spec.rb +162 -0
- data/spec/schema/cve_item_spec.rb +116 -0
- data/spec/schema/impact/base_metric_v2_spec.rb +183 -0
- data/spec/schema/impact/base_metric_v3_spec.rb +80 -0
- data/spec/schema/impact_spec.rb +53 -0
- data/spec/schema/shared_examples.rb +136 -0
- data/spec/schema/timestamp_spec.rb +8 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/zip_feed_file_spec.rb +66 -0
- data/spec/zip_feed_uri_spec.rb +35 -0
- metadata +156 -0
Binary file
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'feed_file_examples'
|
3
|
+
require 'nvd/json_feeds/gz_feed_file'
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'shellwords'
|
7
|
+
|
8
|
+
describe NVD::JSONFeeds::GzFeedFile do
|
9
|
+
let(:fixtures_dir) { File.expand_path('../fixtures',__FILE__) }
|
10
|
+
let(:json_filename) { 'nvdcve-1.1-recent.json' }
|
11
|
+
let(:json_file) { File.join(fixtures_dir,json_filename) }
|
12
|
+
|
13
|
+
let(:gz_filename) { "#{json_filename}.gz" }
|
14
|
+
let(:dir) { File.join(fixtures_dir,'gz_feed_file') }
|
15
|
+
let(:path) { File.join(dir,gz_filename) }
|
16
|
+
|
17
|
+
subject { described_class.new(path) }
|
18
|
+
|
19
|
+
include_examples "FeedFile"
|
20
|
+
|
21
|
+
describe "#json_filename" do
|
22
|
+
it "must return the '.json' filename without the '.gz' extension" do
|
23
|
+
expect(subject.json_filename).to eq(json_filename)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#read" do
|
28
|
+
it "must read the ungziped contents" do
|
29
|
+
expect(subject.read).to be == File.read(json_file)
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when gunzip is not installed" do
|
33
|
+
before do
|
34
|
+
expect(subject).to receive(:`).and_raise(Errno::ENOENT)
|
35
|
+
end
|
36
|
+
|
37
|
+
it do
|
38
|
+
expect { subject.read }.to raise_error(ReadFailed)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#extract" do
|
44
|
+
let(:extracted_json_file) { File.join(dir,json_filename) }
|
45
|
+
|
46
|
+
it "must gunzip the '.gz' file and return a JSONFeedfile" do
|
47
|
+
feed_file = subject.extract
|
48
|
+
|
49
|
+
expect(feed_file).to be_kind_of(JSONFeedFile)
|
50
|
+
expect(feed_file.path).to eq(extracted_json_file)
|
51
|
+
expect(File.file?(extracted_json_file)).to be(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when gunzip fails" do
|
55
|
+
before do
|
56
|
+
allow(subject).to receive(:system).and_return(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it do
|
60
|
+
expect { subject.extract }.to raise_error(ExtractFailed)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
after { FileUtils.rm_f(extracted_json_file) }
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nvd/json_feeds/gz_feed_uri'
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
describe NVD::JSONFeeds::GzFeedURI do
|
7
|
+
let(:fixtures_dir) { File.expand_path('../fixtures',__FILE__) }
|
8
|
+
|
9
|
+
let(:name) { :recent }
|
10
|
+
let(:ext) { '.json.gz' }
|
11
|
+
|
12
|
+
subject { described_class.new(name,ext) }
|
13
|
+
|
14
|
+
describe "#download", :integration do
|
15
|
+
let(:download_dir) { File.join(fixtures_dir,'download') }
|
16
|
+
let(:dest) { File.join(download_dir,subject.filename) }
|
17
|
+
|
18
|
+
before do
|
19
|
+
FileUtils.mkdir_p(download_dir)
|
20
|
+
FileUtils.rm_f(dest)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must return a GzFeedFile object for the newly downloaded file" do
|
24
|
+
feed_file = subject.download(dest)
|
25
|
+
|
26
|
+
expect(feed_file).to be_kind_of(GzFeedFile)
|
27
|
+
expect(feed_file.path).to eq(dest)
|
28
|
+
expect(File.file?(dest)).to be(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
FileUtils.rm_f(dest)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'feed_file_examples'
|
3
|
+
require 'nvd/json_feeds/json_feed_file'
|
4
|
+
|
5
|
+
describe JSONFeedFile do
|
6
|
+
let(:fixtures_dir) { File.expand_path('../fixtures',__FILE__) }
|
7
|
+
let(:path) { File.join(fixtures_dir,'nvdcve-1.1-recent.json') }
|
8
|
+
|
9
|
+
subject { described_class.new(path) }
|
10
|
+
|
11
|
+
include_examples "FeedFile"
|
12
|
+
|
13
|
+
describe "#read" do
|
14
|
+
it "must read the contents of the json file" do
|
15
|
+
expect(subject.read).to eq(File.read(path))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/meta_spec.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nvd/json_feeds/meta'
|
3
|
+
|
4
|
+
describe Meta do
|
5
|
+
let(:last_modified_date_string) { '2021-01-18T08:01:40-05:00' }
|
6
|
+
let(:last_modified_date) { DateTime.parse(last_modified_date_string) }
|
7
|
+
let(:size) { 3499526 }
|
8
|
+
let(:zip_size) {212317 }
|
9
|
+
let(:gz_size) { 212173 }
|
10
|
+
let(:sha256) { '9013088A0E882B4FBB590A25D8CC00431AE4CA465CB66EF9E2F7F231EE54BE6F' }
|
11
|
+
|
12
|
+
describe "#initialize" do
|
13
|
+
subject do
|
14
|
+
described_class.new(last_modified_date,size,zip_size,gz_size,sha256)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "must set #last_modified_date" do
|
18
|
+
expect(subject.last_modified_date).to eq(last_modified_date)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "must set #size" do
|
22
|
+
expect(subject.size).to eq(size)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "must set #zip_size" do
|
26
|
+
expect(subject.zip_size).to eq(zip_size)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "must set #gz_size" do
|
30
|
+
expect(subject.gz_size).to eq(gz_size)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "must set #sha256" do
|
34
|
+
expect(subject.sha256).to eq(sha256)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".parse" do
|
39
|
+
let(:string) do
|
40
|
+
[
|
41
|
+
"lastModifiedDate:#{last_modified_date_string}",
|
42
|
+
"size:#{size}",
|
43
|
+
"zipSize:#{zip_size}",
|
44
|
+
"gzSize:#{gz_size}",
|
45
|
+
"sha256:#{sha256}"
|
46
|
+
].join("\r\n")
|
47
|
+
end
|
48
|
+
|
49
|
+
subject { described_class }
|
50
|
+
|
51
|
+
it "must return a #{described_class} object" do
|
52
|
+
expect(subject.parse(string)).to be_kind_of(described_class)
|
53
|
+
end
|
54
|
+
|
55
|
+
context "lastModifiedDate" do
|
56
|
+
subject { described_class.parse(string) }
|
57
|
+
|
58
|
+
it "must parse into a DatEtime" do
|
59
|
+
expect(subject.last_modified_date).to be_kind_of(DateTime)
|
60
|
+
end
|
61
|
+
|
62
|
+
it { expect(subject.last_modified_date).to eq(last_modified_date) }
|
63
|
+
end
|
64
|
+
|
65
|
+
context "size" do
|
66
|
+
subject { described_class.parse(string) }
|
67
|
+
|
68
|
+
it "must convert into an Integer" do
|
69
|
+
expect(subject.size).to be_kind_of(Integer)
|
70
|
+
end
|
71
|
+
|
72
|
+
it { expect(subject.size).to eq(size) }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "zipSize" do
|
76
|
+
subject { described_class.parse(string) }
|
77
|
+
|
78
|
+
it "must convert into an Integer" do
|
79
|
+
expect(subject.zip_size).to be_kind_of(Integer)
|
80
|
+
end
|
81
|
+
|
82
|
+
it { expect(subject.zip_size).to eq(zip_size) }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "gzSize" do
|
86
|
+
subject { described_class.parse(string) }
|
87
|
+
|
88
|
+
it "must convert into an Integer" do
|
89
|
+
expect(subject.gz_size).to be_kind_of(Integer)
|
90
|
+
end
|
91
|
+
|
92
|
+
it { expect(subject.gz_size).to eq(gz_size) }
|
93
|
+
end
|
94
|
+
|
95
|
+
context "sha256" do
|
96
|
+
subject { described_class.parse(string) }
|
97
|
+
|
98
|
+
it { expect(subject.sha256).to eq(sha256) }
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when lastModifiedDate is missing" do
|
102
|
+
let(:string) { super().sub(/^lastModifiedDate:.*$/,'') }
|
103
|
+
|
104
|
+
it do
|
105
|
+
expect { subject.parse(string) }.to raise_error(MetaParseError)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "when size is missing" do
|
110
|
+
let(:string) { super().sub(/^size:.*$/,'') }
|
111
|
+
|
112
|
+
it do
|
113
|
+
expect { subject.parse(string) }.to raise_error(MetaParseError)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when zipSize is missing" do
|
118
|
+
let(:string) { super().sub(/^zipSize:.*$/,'') }
|
119
|
+
|
120
|
+
it do
|
121
|
+
expect { subject.parse(string) }.to raise_error(MetaParseError)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "when gzSize is missing" do
|
126
|
+
let(:string) { super().sub(/^gzSize:.*$/,'') }
|
127
|
+
|
128
|
+
it do
|
129
|
+
expect { subject.parse(string) }.to raise_error(MetaParseError)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when sha256 is missing" do
|
134
|
+
let(:string) { super().sub(/^sha256:.*$/,'') }
|
135
|
+
|
136
|
+
it do
|
137
|
+
expect { subject.parse(string) }.to raise_error(MetaParseError)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'schema/shared_examples'
|
3
|
+
require 'nvd/json_feeds/schema/configurations/node'
|
4
|
+
|
5
|
+
describe Schema::Configurations::Node do
|
6
|
+
describe "#initialize" do
|
7
|
+
context "when operator: is given" do
|
8
|
+
let(:operator) { :AND }
|
9
|
+
|
10
|
+
subject { described_class.new(operator: operator) }
|
11
|
+
|
12
|
+
it "must set #operator" do
|
13
|
+
expect(subject.operator).to eq(operator)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when operator: is not given" do
|
18
|
+
it { expect(subject.operator).to be(nil) }
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when negate: is given" do
|
22
|
+
let(:negate) { true }
|
23
|
+
|
24
|
+
subject { described_class.new(negate: negate) }
|
25
|
+
|
26
|
+
it "must set #negate" do
|
27
|
+
expect(subject.negate).to eq(negate)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when negate: is not given" do
|
32
|
+
it { expect(subject.negate).to be(nil) }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when children: is given" do
|
36
|
+
let(:children) { [double(:Node1), double(:Node2)] }
|
37
|
+
|
38
|
+
subject { described_class.new(children: children) }
|
39
|
+
|
40
|
+
it "must set #children" do
|
41
|
+
expect(subject.children).to eq(children)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when children: is not given" do
|
46
|
+
it { expect(subject.children).to eq([]) }
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when cpe_match: is given" do
|
50
|
+
let(:cpe_match) { [double("CPE::Match1"), double("CPE::Match2")] }
|
51
|
+
|
52
|
+
subject { described_class.new(cpe_match: cpe_match) }
|
53
|
+
|
54
|
+
it "must set #cpe_match" do
|
55
|
+
expect(subject.cpe_match).to eq(cpe_match)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when cpe_match: is not given" do
|
60
|
+
it { expect(subject.cpe_match).to eq([]) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".load" do
|
65
|
+
include_examples ".load"
|
66
|
+
|
67
|
+
let(:json_node) { json_tree['CVE_Items'][0]['configurations']['nodes'][0] }
|
68
|
+
|
69
|
+
include_examples "JSON field", json_key: 'operator',
|
70
|
+
method: :operator,
|
71
|
+
map: described_class::OPERATORS
|
72
|
+
|
73
|
+
include_examples "JSON field", json_key: 'negate',
|
74
|
+
method: :negate
|
75
|
+
|
76
|
+
pending 'need an example containing \"children\"'do
|
77
|
+
include_examples "JSON Array field", json_key: 'children',
|
78
|
+
method: :children,
|
79
|
+
element_class: described_class
|
80
|
+
end
|
81
|
+
|
82
|
+
include_examples "JSON Array field", json_key: 'cpe_match',
|
83
|
+
method: :cpe_match,
|
84
|
+
element_class: Schema::CPE::Match
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'schema/shared_examples'
|
3
|
+
require 'nvd/json_feeds/schema/configurations'
|
4
|
+
|
5
|
+
describe Schema::Configurations do
|
6
|
+
describe "#initialize" do
|
7
|
+
let(:data_version) { :"4.0" }
|
8
|
+
|
9
|
+
context "when data_version: is given" do
|
10
|
+
subject { described_class.new(data_version: data_version) }
|
11
|
+
|
12
|
+
it "must set #data_version" do
|
13
|
+
expect(subject.data_version).to eq(data_version)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "and when nodes: is given" do
|
17
|
+
let(:nodes) { [double(:Node1), double(:Node2)] }
|
18
|
+
|
19
|
+
subject do
|
20
|
+
described_class.new(data_version: data_version, nodes: nodes)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must set #nodes" do
|
24
|
+
expect(subject.nodes).to eq(nodes)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "but when nodes: is not given" do
|
29
|
+
it { expect(subject.nodes).to eq([]) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when data_version: is not given" do
|
34
|
+
it do
|
35
|
+
expect {
|
36
|
+
described_class.new
|
37
|
+
}.to raise_error(ArgumentError)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe ".load" do
|
43
|
+
include_examples ".load"
|
44
|
+
|
45
|
+
let(:json_node) { json_tree['CVE_Items'][0]['configurations'] }
|
46
|
+
|
47
|
+
include_examples "JSON field", json_key: 'CVE_data_version',
|
48
|
+
required: true,
|
49
|
+
method: :data_version,
|
50
|
+
map: described_class::DATA_VERSIONS
|
51
|
+
|
52
|
+
include_examples "JSON Array field", json_key: 'nodes',
|
53
|
+
method: :nodes,
|
54
|
+
element_class: described_class::Node
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'schema/shared_examples'
|
3
|
+
require 'nvd/json_feeds/schema/cpe/match'
|
4
|
+
|
5
|
+
describe Schema::CPE::Match do
|
6
|
+
describe "#initialize" do
|
7
|
+
context "when cpe23uri: is given" do
|
8
|
+
let(:cpe23uri) { 'cpe:2.3:a:bitcoinsv:bitcoin_sv:*:*:*:*:*:*:*:*' }
|
9
|
+
|
10
|
+
context "and when vulnerable: is given" do
|
11
|
+
let(:vulnerable) { true }
|
12
|
+
|
13
|
+
subject do
|
14
|
+
described_class.new(
|
15
|
+
cpe23uri: cpe23uri,
|
16
|
+
vulnerable: vulnerable
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must set #vulnerable" do
|
21
|
+
expect(subject.vulnerable).to eq(vulnerable)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "and when version_start_excluding: is given" do
|
25
|
+
let(:version) { '1.2.3' }
|
26
|
+
|
27
|
+
subject do
|
28
|
+
described_class.new(
|
29
|
+
cpe23uri: cpe23uri,
|
30
|
+
vulnerable: vulnerable,
|
31
|
+
version_start_excluding: version
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "must set #version_start_excluding" do
|
36
|
+
expect(subject.version_start_excluding).to eq(version)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "but when version_start_excluding: is not given" do
|
41
|
+
it { expect(subject.version_start_excluding).to be(nil) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "and when version_start_including: is given" do
|
45
|
+
let(:version) { '1.2.3' }
|
46
|
+
|
47
|
+
subject do
|
48
|
+
described_class.new(
|
49
|
+
cpe23uri: cpe23uri,
|
50
|
+
vulnerable: vulnerable,
|
51
|
+
version_start_including: version
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "must set #version_start_including" do
|
56
|
+
expect(subject.version_start_including).to eq(version)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "but when version_start_including: is not given" do
|
61
|
+
it { expect(subject.version_start_including).to be(nil) }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "and when version_end_excluding: is given" do
|
65
|
+
let(:version) { '1.2.3' }
|
66
|
+
|
67
|
+
subject do
|
68
|
+
described_class.new(
|
69
|
+
cpe23uri: cpe23uri,
|
70
|
+
vulnerable: vulnerable,
|
71
|
+
version_end_excluding: version
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "must set #version_end_excluding" do
|
76
|
+
expect(subject.version_end_excluding).to eq(version)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "but when version_end_excluding: is not given" do
|
81
|
+
it { expect(subject.version_end_excluding).to be(nil) }
|
82
|
+
end
|
83
|
+
|
84
|
+
context "and when version_end_including: is given" do
|
85
|
+
let(:version) { '1.2.3' }
|
86
|
+
|
87
|
+
subject do
|
88
|
+
described_class.new(
|
89
|
+
cpe23uri: cpe23uri,
|
90
|
+
vulnerable: vulnerable,
|
91
|
+
version_end_including: version
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "must set #version_end_including" do
|
96
|
+
expect(subject.version_end_including).to eq(version)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "but when version_end_including: is not given" do
|
101
|
+
it { expect(subject.version_end_including).to be(nil) }
|
102
|
+
end
|
103
|
+
|
104
|
+
context "and when cpe_name: is given" do
|
105
|
+
let(:cpe_name) { [double("CPE::Name1"), double("CPE::Name2")] }
|
106
|
+
|
107
|
+
subject do
|
108
|
+
described_class.new(
|
109
|
+
cpe23uri: cpe23uri,
|
110
|
+
vulnerable: vulnerable,
|
111
|
+
cpe_name: cpe_name
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "must set #cpe_name" do
|
116
|
+
expect(subject.cpe_name).to eq(cpe_name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "but when cpe_name: is not given" do
|
121
|
+
it { expect(subject.cpe_name).to eq([]) }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "but when vulnerable: is not given" do
|
126
|
+
it do
|
127
|
+
expect {
|
128
|
+
described_class.new
|
129
|
+
}.to raise_error(ArgumentError)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "but when cpe23uri: is not given" do
|
135
|
+
it do
|
136
|
+
expect {
|
137
|
+
described_class.new
|
138
|
+
}.to raise_error(ArgumentError)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe ".load" do
|
144
|
+
include_examples ".load"
|
145
|
+
|
146
|
+
let(:json_node) do
|
147
|
+
json_tree['CVE_Items'][0]['configurations']['nodes'][0]['cpe_match'][0]
|
148
|
+
end
|
149
|
+
|
150
|
+
include_examples "JSON field", json_key: 'vulnerable',
|
151
|
+
required: true,
|
152
|
+
method: :vulnerable
|
153
|
+
|
154
|
+
include_examples "JSON field", json_key: 'cpe23Uri',
|
155
|
+
required: true,
|
156
|
+
method: :cpe23uri
|
157
|
+
|
158
|
+
pending 'need to find an example containing the "cpe22Uri" key' do
|
159
|
+
include_examples "JSON field", json_key: 'cpe22Uri',
|
160
|
+
required: true,
|
161
|
+
method: :cpe22uri
|
162
|
+
end
|
163
|
+
|
164
|
+
pending 'need to find an example containing the "versionStartExcluding" key' do
|
165
|
+
include_examples "JSON field", json_key: 'versionStartExcluding',
|
166
|
+
method: :version_start_excluding
|
167
|
+
end
|
168
|
+
|
169
|
+
pending 'need to find an example containing the "versionStartIncluding" key' do
|
170
|
+
include_examples "JSON field", json_key: 'versionStartIncluding',
|
171
|
+
method: :version_start_including
|
172
|
+
end
|
173
|
+
|
174
|
+
include_examples "JSON field", json_key: 'versionEndExcluding',
|
175
|
+
method: :version_end_excluding
|
176
|
+
|
177
|
+
pending 'need to find an example containing the "versionEndIncluding" key' do
|
178
|
+
include_examples "JSON field", json_key: 'versionEndIncluding',
|
179
|
+
method: :version_end_including
|
180
|
+
end
|
181
|
+
|
182
|
+
pending 'need to find an example containing the "cpe_name" key' do
|
183
|
+
include_examples "JSON Array field", json_key: 'cpe_name',
|
184
|
+
method: :cpe_name,
|
185
|
+
element_class: Schema::CPE::Name
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|