metasploit_data_models 0.18.1 → 0.19.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 +8 -8
- data/app/models/mdm/host.rb +7 -0
- data/app/models/mdm/service.rb +30 -1
- data/app/models/mdm/tag.rb +10 -0
- data/app/models/metasploit_data_models/ip_address/v4/cidr.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/nmap.rb +14 -0
- data/app/models/metasploit_data_models/ip_address/v4/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list.rb +126 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range.rb +12 -0
- data/app/models/metasploit_data_models/ip_address/v4/segment/single.rb +123 -0
- data/app/models/metasploit_data_models/ip_address/v4/segmented.rb +200 -0
- data/app/models/metasploit_data_models/ip_address/v4/single.rb +53 -0
- data/app/models/metasploit_data_models/search/operation/ip_address.rb +60 -0
- data/app/models/metasploit_data_models/search/operator/ip_address.rb +33 -0
- data/app/models/metasploit_data_models/search/visitor/attribute.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/includes.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/joins.rb +1 -0
- data/app/models/metasploit_data_models/search/visitor/where.rb +51 -0
- data/config/locales/en.yml +35 -4
- data/lib/metasploit_data_models/ip_address.rb +5 -0
- data/lib/metasploit_data_models/ip_address/cidr.rb +174 -0
- data/lib/metasploit_data_models/ip_address/range.rb +181 -0
- data/lib/metasploit_data_models/match/child.rb +48 -0
- data/lib/metasploit_data_models/match/parent.rb +103 -0
- data/lib/metasploit_data_models/version.rb +4 -4
- data/metasploit_data_models.gemspec +2 -1
- data/spec/app/models/mdm/cred_spec.rb +164 -31
- data/spec/app/models/mdm/service_spec.rb +33 -44
- data/spec/app/models/metasploit_data_models/ip_address/v4/cidr_spec.rb +121 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/nmap_spec.rb +151 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/range_spec.rb +300 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/list_spec.rb +278 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/nmap/range_spec.rb +304 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/segmented_spec.rb +29 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +315 -0
- data/spec/app/models/metasploit_data_models/ip_address/v4/single_spec.rb +183 -0
- data/spec/app/models/metasploit_data_models/search/operation/ip_address_spec.rb +182 -0
- data/spec/app/models/metasploit_data_models/search/operator/ip_address_spec.rb +19 -0
- data/spec/app/models/metasploit_data_models/search/visitor/relation_spec.rb +229 -36
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/db/structure.sql +3011 -0
- data/spec/factories/mdm/services.rb +3 -1
- data/spec/lib/metasploit_data_models/ip_address/cidr_spec.rb +350 -0
- data/spec/lib/metasploit_data_models/ip_address/range_spec.rb +77 -0
- data/spec/lib/metasploit_data_models/match/child_spec.rb +61 -0
- data/spec/lib/metasploit_data_models/match/parent_spec.rb +155 -0
- data/spec/support/matchers/match_regex_exactly.rb +28 -0
- data/spec/support/shared/contexts/rex/text.rb +15 -0
- data/spec/support/shared/examples/metasploit_data_models/search/operation/ipaddress/match.rb +109 -0
- metadata +58 -9
- data/spec/dummy/db/schema.rb +0 -609
@@ -3,6 +3,28 @@ require 'spec_helper'
|
|
3
3
|
describe Mdm::Service do
|
4
4
|
it_should_behave_like 'Metasploit::Concern.run'
|
5
5
|
|
6
|
+
context 'CONSTANTS' do
|
7
|
+
context 'PROTOS' do
|
8
|
+
subject(:protos) {
|
9
|
+
described_class::PROTOS
|
10
|
+
}
|
11
|
+
|
12
|
+
it { should include 'tcp' }
|
13
|
+
it { should include 'udp' }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'STATES' do
|
17
|
+
subject(:states) {
|
18
|
+
described_class::STATES
|
19
|
+
}
|
20
|
+
|
21
|
+
it { should include 'closed' }
|
22
|
+
it { should include 'filtered' }
|
23
|
+
it { should include 'open' }
|
24
|
+
it { should include 'unknown' }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
6
28
|
context "Associations" do
|
7
29
|
|
8
30
|
it { should have_many(:task_services).class_name('Mdm::TaskService').dependent(:destroy) }
|
@@ -33,13 +55,13 @@ describe Mdm::Service do
|
|
33
55
|
end
|
34
56
|
end
|
35
57
|
|
36
|
-
context "search for '
|
58
|
+
context "search for 'tcp'" do
|
37
59
|
it "should find only services that match" do
|
38
|
-
|
39
|
-
|
40
|
-
search_results = Mdm::Service.search('
|
41
|
-
search_results.should include(
|
42
|
-
search_results.should_not include(
|
60
|
+
tcp_service = FactoryGirl.create(:mdm_service, proto: 'tcp')
|
61
|
+
udp_service = FactoryGirl.create(:mdm_service, proto: 'udp')
|
62
|
+
search_results = Mdm::Service.search('tcp')
|
63
|
+
search_results.should include(tcp_service)
|
64
|
+
search_results.should_not include(udp_service)
|
43
65
|
end
|
44
66
|
end
|
45
67
|
end
|
@@ -98,44 +120,11 @@ describe Mdm::Service do
|
|
98
120
|
end
|
99
121
|
|
100
122
|
context "validations" do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
mdm_service
|
105
|
-
end
|
106
|
-
|
107
|
-
context "invalid" do
|
108
|
-
it "should validate presence of :port" do
|
109
|
-
mdm_service.port = nil
|
110
|
-
mdm_service.valid?
|
111
|
-
mdm_service.errors[:port][0].should include "is not a number"
|
112
|
-
end
|
123
|
+
subject(:mdm_service) {
|
124
|
+
FactoryGirl.build(:mdm_service)
|
125
|
+
}
|
113
126
|
|
114
|
-
|
115
|
-
|
116
|
-
mdm_service.valid?
|
117
|
-
mdm_service.errors[:proto][0].should include "can't be blank"
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should not allow non-numeric value for port" do
|
121
|
-
mdm_service.port = Faker::Lorem.characters(4)
|
122
|
-
mdm_service.valid?
|
123
|
-
mdm_service.errors[:port][0].should include "is not a number"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
context "valid" do
|
128
|
-
it "should allow numeric value for port" do
|
129
|
-
mdm_service.port = Faker::Number.number(4)
|
130
|
-
mdm_service.valid?
|
131
|
-
mdm_service.should have(0).errors_on(:port)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "should allow proto" do
|
135
|
-
mdm_service.proto = "tcp"
|
136
|
-
mdm_service.valid?
|
137
|
-
mdm_service.should have(0).errors_on(:proto)
|
138
|
-
end
|
139
|
-
end
|
127
|
+
it { should validate_numericality_of(:port).only_integer }
|
128
|
+
it { should ensure_inclusion_of(:proto).in_array(described_class::PROTOS) }
|
140
129
|
end
|
141
130
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::CIDR do
|
4
|
+
subject(:cidr) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
let(:formatted_value) {
|
11
|
+
nil
|
12
|
+
}
|
13
|
+
|
14
|
+
it { should be_a MetasploitDataModels::IPAddress::CIDR }
|
15
|
+
|
16
|
+
context 'address_class' do
|
17
|
+
subject(:address_class) {
|
18
|
+
described_class.address_class
|
19
|
+
}
|
20
|
+
|
21
|
+
it { should == MetasploitDataModels::IPAddress::V4::Single }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'validations' do
|
25
|
+
let(:formatted_address) {
|
26
|
+
'1.2.3.4'
|
27
|
+
}
|
28
|
+
|
29
|
+
context 'with IPv4 CIDR notation' do
|
30
|
+
let(:formatted_prefix_length) {
|
31
|
+
'8'
|
32
|
+
}
|
33
|
+
|
34
|
+
let(:formatted_value) {
|
35
|
+
"#{formatted_address}/#{formatted_prefix_length}"
|
36
|
+
}
|
37
|
+
|
38
|
+
it { should be_valid }
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with IPv4 address' do
|
42
|
+
let(:formatted_value) {
|
43
|
+
formatted_address
|
44
|
+
}
|
45
|
+
|
46
|
+
it { should_not be_valid }
|
47
|
+
|
48
|
+
context 'errors' do
|
49
|
+
before(:each) do
|
50
|
+
cidr.valid?
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'on #address' do
|
54
|
+
subject(:address_errors) {
|
55
|
+
cidr.errors[:address]
|
56
|
+
}
|
57
|
+
|
58
|
+
it { should be_empty }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'on #prefix_length' do
|
62
|
+
subject(:prefix_length_errors) {
|
63
|
+
cidr.errors[:prefix_length]
|
64
|
+
}
|
65
|
+
|
66
|
+
let(:blank_error) {
|
67
|
+
I18n.translate!('errors.messages.not_a_number')
|
68
|
+
}
|
69
|
+
|
70
|
+
it { should include(blank_error) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with IPv6 CIDR notation' do
|
76
|
+
let(:formatted_value) {
|
77
|
+
"#{formatted_address}/#{formatted_prefix_length}"
|
78
|
+
}
|
79
|
+
|
80
|
+
let(:formatted_address) {
|
81
|
+
'::1'
|
82
|
+
}
|
83
|
+
|
84
|
+
let(:formatted_prefix_length) {
|
85
|
+
'48'
|
86
|
+
}
|
87
|
+
|
88
|
+
it { should_not be_valid }
|
89
|
+
|
90
|
+
context 'errors' do
|
91
|
+
before(:each) do
|
92
|
+
cidr.valid?
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'on #address' do
|
96
|
+
subject(:address_errors) {
|
97
|
+
cidr.errors[:address]
|
98
|
+
}
|
99
|
+
|
100
|
+
let(:invalid_error) {
|
101
|
+
I18n.translate!('errors.messages.invalid')
|
102
|
+
}
|
103
|
+
|
104
|
+
it { should include(invalid_error) }
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'on #prefix_length' do
|
108
|
+
subject(:prefix_length_errors) {
|
109
|
+
cidr.errors[:prefix_length]
|
110
|
+
}
|
111
|
+
|
112
|
+
let(:too_big_error) {
|
113
|
+
I18n.translate!('errors.messages.less_than_or_equal_to', count: 32)
|
114
|
+
}
|
115
|
+
|
116
|
+
it { should include(too_big_error) }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Nmap do
|
4
|
+
subject(:nmap) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
context 'validation' do
|
11
|
+
before(:each) do
|
12
|
+
nmap.valid?
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'errors on #segments' do
|
16
|
+
subject(:segments_errors) {
|
17
|
+
nmap.errors[:segments]
|
18
|
+
}
|
19
|
+
|
20
|
+
context 'with segments' do
|
21
|
+
context 'with invalid segment' do
|
22
|
+
let(:error) {
|
23
|
+
I18n.translate!(
|
24
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segmented.attributes.segments.segment_invalid',
|
25
|
+
index: 0,
|
26
|
+
segment: '5-4'
|
27
|
+
)
|
28
|
+
}
|
29
|
+
|
30
|
+
let(:formatted_value) {
|
31
|
+
'5-4.3.2.1'
|
32
|
+
}
|
33
|
+
|
34
|
+
it 'should include index of segment and segment value in the error' do
|
35
|
+
expect(segments_errors).to include(error)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with valid segments' do
|
40
|
+
let(:formatted_value) {
|
41
|
+
'1.2.3.4'
|
42
|
+
}
|
43
|
+
|
44
|
+
it { should be_empty }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'without segments' do
|
49
|
+
let(:formatted_value) {
|
50
|
+
'::1'
|
51
|
+
}
|
52
|
+
|
53
|
+
let(:length_error) {
|
54
|
+
I18n.translate!(
|
55
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/v4/segmented.attributes.segments.wrong_length',
|
56
|
+
count: 4
|
57
|
+
)
|
58
|
+
}
|
59
|
+
|
60
|
+
it { should include length_error }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'regexp' do
|
66
|
+
subject(:regexp) {
|
67
|
+
described_class.regexp
|
68
|
+
}
|
69
|
+
|
70
|
+
it 'matches a normal IPv4 address because they are a generate form of Nmap format' do
|
71
|
+
expect(regexp).to match_string_exactly('1.2.3.4')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'matches an IPv4 Nmap address with comma separated list of numbers and ranges for each segment' do
|
75
|
+
expect(regexp).to match_string_exactly('1,2-3.4-5,6.7,8.9-10,11-12')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context '#value' do
|
80
|
+
subject(:value) {
|
81
|
+
nmap.value
|
82
|
+
}
|
83
|
+
|
84
|
+
context 'with nil' do
|
85
|
+
let(:formatted_value) {
|
86
|
+
nil
|
87
|
+
}
|
88
|
+
|
89
|
+
it { should be_nil }
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with matching formatted value' do
|
93
|
+
let(:formatted_value) {
|
94
|
+
'1.2-3.4,5-6.7-8,9'
|
95
|
+
}
|
96
|
+
|
97
|
+
it 'has 4 segments' do
|
98
|
+
expect(value.length).to eq(4)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'has MetasploitDataModels::IPAddress::V4::Segment::Nmap::List for segments' do
|
102
|
+
expect(
|
103
|
+
value.all? { |segment|
|
104
|
+
segment.is_a? MetasploitDataModels::IPAddress::V4::Segment::Nmap::List
|
105
|
+
}
|
106
|
+
).to eq(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'has segments ordered from high to low' do
|
110
|
+
highest_segment = value[0]
|
111
|
+
|
112
|
+
expect(highest_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
113
|
+
expect(highest_segment.value[0].value).to eq(1)
|
114
|
+
|
115
|
+
high_middle_segment = value[1]
|
116
|
+
|
117
|
+
expect(high_middle_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
118
|
+
expect(high_middle_segment.value[0].begin.value).to eq(2)
|
119
|
+
expect(high_middle_segment.value[0].end.value).to eq(3)
|
120
|
+
|
121
|
+
low_middle_segment = value[2]
|
122
|
+
|
123
|
+
expect(low_middle_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
124
|
+
expect(low_middle_segment.value[0].value).to eq(4)
|
125
|
+
|
126
|
+
expect(low_middle_segment.value[1]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
127
|
+
expect(low_middle_segment.value[1].begin.value).to eq(5)
|
128
|
+
expect(low_middle_segment.value[1].end.value).to eq(6)
|
129
|
+
|
130
|
+
low_segment = value[3]
|
131
|
+
|
132
|
+
expect(low_segment.value[0]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Nmap::Range
|
133
|
+
expect(low_segment.value[0].begin.value).to eq(7)
|
134
|
+
expect(low_segment.value[0].end.value).to eq(8)
|
135
|
+
|
136
|
+
expect(low_segment.value[1]).to be_a MetasploitDataModels::IPAddress::V4::Segment::Single
|
137
|
+
expect(low_segment.value[1].value).to eq(9)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'without matching formatted value' do
|
142
|
+
let(:formatted_value) {
|
143
|
+
'::1'
|
144
|
+
}
|
145
|
+
|
146
|
+
it 'is the formated value' do
|
147
|
+
expect(value).to eq(formatted_value)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,300 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetasploitDataModels::IPAddress::V4::Range do
|
4
|
+
subject(:range) {
|
5
|
+
described_class.new(
|
6
|
+
value: formatted_value
|
7
|
+
)
|
8
|
+
}
|
9
|
+
|
10
|
+
#
|
11
|
+
# lets
|
12
|
+
#
|
13
|
+
|
14
|
+
let(:formatted_value) {
|
15
|
+
nil
|
16
|
+
}
|
17
|
+
|
18
|
+
context 'validations' do
|
19
|
+
#
|
20
|
+
# lets
|
21
|
+
#
|
22
|
+
|
23
|
+
let(:presence_error) {
|
24
|
+
I18n.translate!('errors.messages.blank')
|
25
|
+
}
|
26
|
+
|
27
|
+
let(:invalid_error) {
|
28
|
+
I18n.translate!('errors.messages.invalid')
|
29
|
+
}
|
30
|
+
|
31
|
+
#
|
32
|
+
# Callbacks
|
33
|
+
#
|
34
|
+
|
35
|
+
before(:each) do
|
36
|
+
range.valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'errors on #begin' do
|
40
|
+
subject(:begin_errors) {
|
41
|
+
range.errors[:begin]
|
42
|
+
}
|
43
|
+
|
44
|
+
context '#begin' do
|
45
|
+
context 'with nil' do
|
46
|
+
let(:formatted_value) {
|
47
|
+
nil
|
48
|
+
}
|
49
|
+
|
50
|
+
it { should include presence_error }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with MetasploitDataModels::IPAddress::V4::Single' do
|
54
|
+
context 'with valid' do
|
55
|
+
let(:formatted_value) {
|
56
|
+
'1.1.1.1-256.256.256.256'
|
57
|
+
}
|
58
|
+
|
59
|
+
it { should_not include invalid_error }
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'without valid' do
|
63
|
+
let(:formatted_value) {
|
64
|
+
'256.256.256.256-257.257.257.257'
|
65
|
+
}
|
66
|
+
|
67
|
+
it { should include invalid_error }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'errors on #end' do
|
74
|
+
subject(:end_errors) {
|
75
|
+
range.errors[:end]
|
76
|
+
}
|
77
|
+
|
78
|
+
context '#end' do
|
79
|
+
context 'with nil' do
|
80
|
+
let(:formatted_value) {
|
81
|
+
nil
|
82
|
+
}
|
83
|
+
|
84
|
+
it { should include presence_error }
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'with MetasploitDataModels::IPAddress::V4::Single' do
|
88
|
+
context 'with valid' do
|
89
|
+
let(:formatted_value) {
|
90
|
+
'256.256.256.256-1.1.1.1'
|
91
|
+
}
|
92
|
+
|
93
|
+
it { should_not include invalid_error }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'without valid' do
|
97
|
+
let(:formatted_value) {
|
98
|
+
'257.257.257.257-256.256.256.256'
|
99
|
+
}
|
100
|
+
|
101
|
+
it { should include invalid_error }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'errors on #value' do
|
108
|
+
subject(:value_errors) {
|
109
|
+
range.errors[:value]
|
110
|
+
}
|
111
|
+
|
112
|
+
let(:error) {
|
113
|
+
I18n.translate!(
|
114
|
+
'metasploit.model.errors.models.metasploit_data_models/ip_address/range.attributes.value.order',
|
115
|
+
begin: range.begin,
|
116
|
+
end: range.end
|
117
|
+
)
|
118
|
+
}
|
119
|
+
|
120
|
+
context 'with nil' do
|
121
|
+
let(:formatted_value) {
|
122
|
+
nil
|
123
|
+
}
|
124
|
+
|
125
|
+
it { should_not include error }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'with incomparables' do
|
129
|
+
let(:formatted_value) {
|
130
|
+
'a-1'
|
131
|
+
}
|
132
|
+
|
133
|
+
it { should_not include error }
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with numbers' do
|
137
|
+
context 'in order' do
|
138
|
+
let(:formatted_value) {
|
139
|
+
'1.1.1.1-2.2.2.2'
|
140
|
+
}
|
141
|
+
|
142
|
+
it { should_not include error }
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'out of order' do
|
146
|
+
let(:formatted_value) {
|
147
|
+
'2.2.2.2-1.1.1.1'
|
148
|
+
}
|
149
|
+
|
150
|
+
it { should include error }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'match_regexp' do
|
157
|
+
subject(:match_regexp) do
|
158
|
+
described_class::match_regexp
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'matches range exactly' do
|
162
|
+
expect(match_regexp).to match_string_exactly('1.1.1.1-255.255.255.255')
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'regexp' do
|
167
|
+
subject(:regexp) {
|
168
|
+
described_class::regexp
|
169
|
+
}
|
170
|
+
|
171
|
+
it 'does not match a single IPv4 address' do
|
172
|
+
expect(regexp).not_to match('255.255.255.255')
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'does not match separator by itself' do
|
176
|
+
expect(regexp).not_to match('-')
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'does not match range with only one extreme' do
|
180
|
+
expect(regexp).not_to match('1.1.1.1-')
|
181
|
+
expect(regexp).not_to match('-255.255.255.255')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'matches range' do
|
185
|
+
expect(regexp).to match_string_exactly('1.1.1.1-255.255.255.255')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context '#to_s' do
|
190
|
+
subject(:to_s) {
|
191
|
+
range.to_s
|
192
|
+
}
|
193
|
+
|
194
|
+
context 'with Range' do
|
195
|
+
let(:formatted_value) {
|
196
|
+
'1.1.1.1-2.2.2.2'
|
197
|
+
}
|
198
|
+
|
199
|
+
it 'equals the original formatted value' do
|
200
|
+
expect(to_s).to eq(formatted_value)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'without Range' do
|
205
|
+
let(:formatted_value) {
|
206
|
+
'1..2'
|
207
|
+
}
|
208
|
+
|
209
|
+
it { should == '-' }
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context '#value' do
|
214
|
+
subject(:value) {
|
215
|
+
range.value
|
216
|
+
}
|
217
|
+
|
218
|
+
context 'with -' do
|
219
|
+
context 'with extremes' do
|
220
|
+
let(:formatted_value) {
|
221
|
+
'1.1.1.1-2.2.2.2'
|
222
|
+
}
|
223
|
+
|
224
|
+
it { should be_a Range }
|
225
|
+
|
226
|
+
context 'Range#begin' do
|
227
|
+
subject(:range_begin) {
|
228
|
+
value.begin
|
229
|
+
}
|
230
|
+
|
231
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
232
|
+
|
233
|
+
it "is value before '-'" do
|
234
|
+
expect(range_begin).to eq(MetasploitDataModels::IPAddress::V4::Single.new(value: '1.1.1.1'))
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'Range#end' do
|
239
|
+
subject(:range_end) {
|
240
|
+
value.end
|
241
|
+
}
|
242
|
+
|
243
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
244
|
+
|
245
|
+
it "is value after '-'" do
|
246
|
+
expect(range_end).to eq(MetasploitDataModels::IPAddress::V4::Single.new(value: '2.2.2.2'))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'without extremes' do
|
252
|
+
let(:formatted_value) {
|
253
|
+
'-'
|
254
|
+
}
|
255
|
+
|
256
|
+
it { should be_a Range }
|
257
|
+
|
258
|
+
context 'Range#begin' do
|
259
|
+
subject(:range_begin) {
|
260
|
+
value.begin
|
261
|
+
}
|
262
|
+
|
263
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
264
|
+
|
265
|
+
context 'MetasploitDataModels::IPAddress::V4::Single#value' do
|
266
|
+
subject(:begin_value) {
|
267
|
+
range_begin.value
|
268
|
+
}
|
269
|
+
|
270
|
+
it { should == '' }
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'Range#end' do
|
275
|
+
subject(:range_end) {
|
276
|
+
value.end
|
277
|
+
}
|
278
|
+
|
279
|
+
it { should be_a MetasploitDataModels::IPAddress::V4::Single }
|
280
|
+
|
281
|
+
context 'MetasploitDataModels::IPAddress::V4::Single#value' do
|
282
|
+
subject(:end_value) {
|
283
|
+
range_end.value
|
284
|
+
}
|
285
|
+
|
286
|
+
it { should == '' }
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
context 'without -' do
|
293
|
+
let(:formatted_value) do
|
294
|
+
'1'
|
295
|
+
end
|
296
|
+
|
297
|
+
it { should_not be_a Range }
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|