metasploit_data_models 4.0.2 → 4.1.4
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -1
- data/.github/workflows/verify.yml +68 -0
- data/app/models/mdm/nexpose_console.rb +7 -4
- data/app/models/mdm/workspace.rb +6 -5
- data/app/models/metasploit_data_models/search/visitor/where.rb +1 -1
- data/db/migrate/20190308134512_create_async_callbacks.rb +0 -1
- data/lib/metasploit_data_models/version.rb +1 -1
- data/metasploit_data_models.gemspec +9 -18
- data/spec/app/models/mdm/nexpose_console_spec.rb +15 -1
- data/spec/app/models/metasploit_data_models/ip_address/v4/segment/single_spec.rb +3 -3
- data/spec/app/models/metasploit_data_models/search/visitor/where_spec.rb +1 -1
- data/spec/dummy/config/{database.yml.travis → database.yml.github_actions} +4 -5
- metadata +43 -42
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -22
- data/app/validators/ip_format_validator.rb +0 -22
- data/app/validators/parameters_validator.rb +0 -129
- data/app/validators/password_is_strong_validator.rb +0 -117
- data/bin/mdm_console +0 -68
- data/bin/rails +0 -14
- data/spec/app/validators/parameters_validator_spec.rb +0 -342
- data/spec/app/validators/password_is_strong_validator_spec.rb +0 -332
metadata.gz.sig
CHANGED
Binary file
|
data/.travis.yml
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
dist: trusty
|
2
|
-
sudo: false
|
3
|
-
group: stable
|
4
|
-
cache: bundler
|
5
|
-
language: ruby
|
6
|
-
addons:
|
7
|
-
postgresql: '9.6'
|
8
|
-
apt:
|
9
|
-
packages:
|
10
|
-
- libpcap-dev
|
11
|
-
- graphviz
|
12
|
-
rvm:
|
13
|
-
- 2.6.5
|
14
|
-
before_script:
|
15
|
-
- cp spec/dummy/config/database.yml.travis spec/dummy/config/database.yml
|
16
|
-
- bundle exec rake --version
|
17
|
-
- bundle exec rake db:create db:migrate
|
18
|
-
script:
|
19
|
-
# Disabling this check because it is proving unreliable
|
20
|
-
#- git diff --exit-code spec/dummy/db/structure.sql
|
21
|
-
- bundle exec rake spec
|
22
|
-
- bundle exec rake yard
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require "ipaddr"
|
2
|
-
|
3
|
-
# Validates that attribute is a valid IPv4 or IPv6 address.
|
4
|
-
class IpFormatValidator < ActiveModel::EachValidator
|
5
|
-
# Validates that `attribute`'s `value` on `object` is a valid IPv4 or IPv6 address.
|
6
|
-
#
|
7
|
-
# @return [void]
|
8
|
-
def validate_each(object, attribute, value)
|
9
|
-
error_message_block = lambda{ object.errors.add attribute, " must be a valid IPv4 or IPv6 address" }
|
10
|
-
begin
|
11
|
-
if value.is_a? IPAddr
|
12
|
-
potential_ip = value.dup
|
13
|
-
else
|
14
|
-
potential_ip = IPAddr.new(value)
|
15
|
-
end
|
16
|
-
|
17
|
-
error_message_block.call unless potential_ip.ipv4? || potential_ip.ipv6?
|
18
|
-
rescue ArgumentError
|
19
|
-
error_message_block.call
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,129 +0,0 @@
|
|
1
|
-
# Validates that attribute's value is Array<Array(String, String)> which is the only valid type signature for serialized
|
2
|
-
# parameters.
|
3
|
-
class ParametersValidator < ActiveModel::EachValidator
|
4
|
-
#
|
5
|
-
# CONSTANTS
|
6
|
-
#
|
7
|
-
|
8
|
-
# Sentence explaining the valid type signature for parameters.
|
9
|
-
TYPE_SIGNATURE_SENTENCE = 'Valid parameters are an Array<Array(String, String)>.'
|
10
|
-
|
11
|
-
#
|
12
|
-
# Instance Methods
|
13
|
-
#
|
14
|
-
|
15
|
-
# Validates that `attribute`'s `value` on `record` is `Array<Array(String, String)>` which is the only valid type
|
16
|
-
# signature for serialized parameters.
|
17
|
-
#
|
18
|
-
# @return [void]
|
19
|
-
def validate_each(record, attribute, value)
|
20
|
-
if value.is_a? Array
|
21
|
-
value.each_with_index do |element, index|
|
22
|
-
if element.is_a? Array
|
23
|
-
if element.length != 2
|
24
|
-
extreme = :few
|
25
|
-
|
26
|
-
if element.length > 2
|
27
|
-
extreme = :many
|
28
|
-
end
|
29
|
-
|
30
|
-
length_error = length_error_at(
|
31
|
-
:extreme => extreme,
|
32
|
-
:element => element,
|
33
|
-
:index => index
|
34
|
-
)
|
35
|
-
|
36
|
-
record.errors.add attribute, length_error
|
37
|
-
else
|
38
|
-
parameter_name = element.first
|
39
|
-
|
40
|
-
if parameter_name.is_a? String
|
41
|
-
unless parameter_name.present?
|
42
|
-
error = error_at(
|
43
|
-
:element => element,
|
44
|
-
:index => index,
|
45
|
-
:prefix => "has blank parameter name"
|
46
|
-
)
|
47
|
-
record.errors.add attribute, error
|
48
|
-
end
|
49
|
-
else
|
50
|
-
error = error_at(
|
51
|
-
:element => element,
|
52
|
-
:index => index,
|
53
|
-
:prefix => "has non-String parameter name (#{parameter_name.inspect})"
|
54
|
-
)
|
55
|
-
record.errors.add attribute, error
|
56
|
-
end
|
57
|
-
|
58
|
-
parameter_value = element.second
|
59
|
-
|
60
|
-
unless parameter_value.is_a? String
|
61
|
-
error = error_at(
|
62
|
-
:element => element,
|
63
|
-
:index => index,
|
64
|
-
:prefix => "has non-String parameter value (#{parameter_value.inspect})"
|
65
|
-
)
|
66
|
-
record.errors.add attribute, error
|
67
|
-
end
|
68
|
-
end
|
69
|
-
else
|
70
|
-
error = error_at(
|
71
|
-
:element => element,
|
72
|
-
:index => index,
|
73
|
-
:prefix => 'has non-Array'
|
74
|
-
)
|
75
|
-
record.errors.add attribute, error
|
76
|
-
end
|
77
|
-
end
|
78
|
-
else
|
79
|
-
record.errors.add attribute, "is not an Array. #{TYPE_SIGNATURE_SENTENCE}"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def error_at(options={})
|
86
|
-
options.assert_valid_keys(:element, :index, :prefix)
|
87
|
-
prefix = options.fetch(:prefix)
|
88
|
-
|
89
|
-
clause = location_clause(
|
90
|
-
:element => options[:element],
|
91
|
-
:index => options[:index]
|
92
|
-
)
|
93
|
-
sentence = "#{prefix} #{clause}."
|
94
|
-
|
95
|
-
sentences = [
|
96
|
-
sentence,
|
97
|
-
TYPE_SIGNATURE_SENTENCE
|
98
|
-
]
|
99
|
-
|
100
|
-
error = sentences.join(" ")
|
101
|
-
|
102
|
-
error
|
103
|
-
end
|
104
|
-
|
105
|
-
def length_error_at(options={})
|
106
|
-
options.assert_valid_keys(:element, :extreme, :index)
|
107
|
-
extreme = options.fetch(:extreme)
|
108
|
-
|
109
|
-
prefix = "has too #{extreme} elements"
|
110
|
-
error = error_at(
|
111
|
-
:element => options[:element],
|
112
|
-
:index => options[:index],
|
113
|
-
:prefix => prefix
|
114
|
-
)
|
115
|
-
|
116
|
-
error
|
117
|
-
end
|
118
|
-
|
119
|
-
def location_clause(options={})
|
120
|
-
options.assert_valid_keys(:element, :index)
|
121
|
-
|
122
|
-
element = options.fetch(:element)
|
123
|
-
index = options.fetch(:index)
|
124
|
-
|
125
|
-
clause = "at index #{index} (#{element.inspect})"
|
126
|
-
|
127
|
-
clause
|
128
|
-
end
|
129
|
-
end
|
@@ -1,117 +0,0 @@
|
|
1
|
-
# Validates that
|
2
|
-
class PasswordIsStrongValidator < ActiveModel::EachValidator
|
3
|
-
#
|
4
|
-
# CONSTANTS
|
5
|
-
#
|
6
|
-
|
7
|
-
# Known passwords that should NOT be allowed and should be considered weak.
|
8
|
-
COMMON_PASSWORDS = %w{
|
9
|
-
password pass root admin metasploit
|
10
|
-
msf 123456 qwerty abc123 letmein monkey link182 demo
|
11
|
-
changeme test1234 rapid7
|
12
|
-
}
|
13
|
-
|
14
|
-
# Special characters that are considered to strength passwords and are required once in a strong password.
|
15
|
-
SPECIAL_CHARS = %q{!@"#$%&'()*+,-./:;<=>?[\\]^_`{|}~ }
|
16
|
-
|
17
|
-
# Validates that the `attribute`'s `value` on `record` contains letters, numbers, and at least one special character
|
18
|
-
# without containing the `record.username`, any {COMMON_PASSWORDS} or repetition.
|
19
|
-
def validate_each(record, attribute, value)
|
20
|
-
return if value.blank?
|
21
|
-
|
22
|
-
if is_simple?(value)
|
23
|
-
record.errors[attribute] << "must contain letters, numbers, and at least one special character"
|
24
|
-
end
|
25
|
-
|
26
|
-
if contains_username?(record.username, value)
|
27
|
-
record.errors[attribute] << "must not contain the username"
|
28
|
-
end
|
29
|
-
|
30
|
-
if is_common_password?(value)
|
31
|
-
record.errors[attribute] << "must not be a common password"
|
32
|
-
end
|
33
|
-
|
34
|
-
if contains_repetition?(value)
|
35
|
-
record.errors[attribute] << "must not be a predictable sequence of characters"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def is_simple?(password)
|
42
|
-
not (password =~ /[A-Za-z]/ and password =~ /[0-9]/ and password =~ /[#{Regexp.escape(SPECIAL_CHARS)}]/)
|
43
|
-
end
|
44
|
-
|
45
|
-
def contains_username?(username, password)
|
46
|
-
!!(password =~ /#{username}/i)
|
47
|
-
end
|
48
|
-
|
49
|
-
def is_common_password?(password)
|
50
|
-
COMMON_PASSWORDS.each do |pw|
|
51
|
-
common_pw = [pw] # pw + "!", pw + "1", pw + "12", pw + "123", pw + "1234"]
|
52
|
-
common_pw += mutate_pass(pw)
|
53
|
-
common_pw.each do |common_pass|
|
54
|
-
if password.downcase =~ /#{common_pass}[\d!]*/
|
55
|
-
return true
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
false
|
60
|
-
end
|
61
|
-
|
62
|
-
def mutate_pass(password)
|
63
|
-
mutations = {
|
64
|
-
'a' => '@',
|
65
|
-
'o' => '0',
|
66
|
-
'e' => '3',
|
67
|
-
's' => '$',
|
68
|
-
't' => '7',
|
69
|
-
'l' => '1'
|
70
|
-
}
|
71
|
-
|
72
|
-
iterations = mutations.keys.dup
|
73
|
-
results = []
|
74
|
-
|
75
|
-
# Find PowerSet of all possible mutation combinations
|
76
|
-
iterations = iterations.inject([[]]){|c,y|r=[];c.each{|i|r<<i;r<<i+[y]};r}
|
77
|
-
|
78
|
-
# Iterate through combinations to create each possible mutation
|
79
|
-
iterations.each do |iteration|
|
80
|
-
next if iteration.flatten.empty?
|
81
|
-
first = iteration.shift
|
82
|
-
intermediate = password.gsub(/#{first}/i, mutations[first])
|
83
|
-
iteration.each do |mutator|
|
84
|
-
next unless mutator.kind_of? String
|
85
|
-
intermediate.gsub!(/#{mutator}/i, mutations[mutator])
|
86
|
-
end
|
87
|
-
results << intermediate
|
88
|
-
end
|
89
|
-
|
90
|
-
return results
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
def contains_repetition?(password)
|
96
|
-
# Password repetition (quite basic) -- no "aaaaaa" or "ababab" or "abcabc" or
|
97
|
-
# "abcdabcd" (but note that the user can use "aaaaaab" or something).
|
98
|
-
|
99
|
-
if password.scan(/./).uniq.size < 2
|
100
|
-
return true
|
101
|
-
end
|
102
|
-
|
103
|
-
if (password.size % 2 == 0) and (password.scan(/../).uniq.size < 2)
|
104
|
-
return true
|
105
|
-
end
|
106
|
-
|
107
|
-
if (password.size % 3 == 0) and (password.scan(/.../).uniq.size < 2)
|
108
|
-
return true
|
109
|
-
end
|
110
|
-
|
111
|
-
if (password.size % 4 == 0) and (password.scan(/..../).uniq.size < 2)
|
112
|
-
return true
|
113
|
-
end
|
114
|
-
|
115
|
-
false
|
116
|
-
end
|
117
|
-
end
|
data/bin/mdm_console
DELETED
@@ -1,68 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
def mdm_banner
|
4
|
-
banner = {}
|
5
|
-
banner[:color] = "\e[34m"
|
6
|
-
banner[:text] = <<-BANNER
|
7
|
-
_______ _______________________ _______ _______ _ _______ __________________
|
8
|
-
( ) ____ \\__ __/ ___ ) ____ \\ ____ ) \\ ( ___ )\\__ __/\\__ __/
|
9
|
-
| () () | ( \\/ ) ( | ( ) | ( \\/ ( )| ( | ( ) | ) ( ) (
|
10
|
-
| || || | (__ | | | (___) | (_____| (____)| | | | | | | | | |
|
11
|
-
| |(_)| | __) | | | ___ |_____ ) _____) | | | | | | | | |
|
12
|
-
| | | | ( | | | ( ) | ) | ( | | | | | | | | | |
|
13
|
-
| ) ( | (____/\\ | | | ) ( |\\____) | ) | (____/\\ (___) |___) (___ | |
|
14
|
-
|/ \\|_______/ )_( |/ \\|_______)/ (_______/_______)\\_______/ )_(
|
15
|
-
|
16
|
-
|
17
|
-
______ _______________________ _______ _______ ______ _______ _ _______
|
18
|
-
( __ \\( ___ )__ __/ ___ ) ) ___ ) __ \\( ____ \\ \\ ( ____ \\
|
19
|
-
| ( \\ ) ( ) | ) ( | ( ) | () () | ( ) | ( \\ ) ( \\/ ( | ( \\/
|
20
|
-
| | ) | (___) | | | | (___) | || || | | | | | ) | (__ | | | (_____
|
21
|
-
| | | | ___ | | | | ___ | |(_)| | | | | | | | __) | | (_____ )
|
22
|
-
| | ) | ( ) | | | | ( ) | | | | | | | | ) | ( | | ) |
|
23
|
-
| (__/ ) ) ( | | | | ) ( | ) ( | (___) | (__/ ) (____/\\ (____/Y\\____) |
|
24
|
-
(______/|/ \\| )_( |/ \\|/ \\|_______)______/(_______/_______|_______)
|
25
|
-
BANNER
|
26
|
-
banner
|
27
|
-
end
|
28
|
-
|
29
|
-
def db_info_file
|
30
|
-
hidden_file = "#{Dir.home}/.mdm.yml"
|
31
|
-
if File.readable?(hidden_file)
|
32
|
-
pro_path = YAML.load_file(hidden_file)['pro_path']
|
33
|
-
return "#{pro_path}/ui/config/database.yml"
|
34
|
-
elsif !ARGV[0].blank?
|
35
|
-
return ARGV[0]
|
36
|
-
else
|
37
|
-
warn "No YAML file of DB info available"
|
38
|
-
exit
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
begin
|
43
|
-
require 'pry'
|
44
|
-
require "metasploit_data_models"
|
45
|
-
|
46
|
-
# Set up a DB connection, preferring one from Pro if it's in the normal place
|
47
|
-
# Otherwise get from ARGV[0]
|
48
|
-
|
49
|
-
if File.readable?(db_info_file)
|
50
|
-
connection_info = YAML.load_file(db_info_file)
|
51
|
-
ActiveRecord::Base.establish_connection(connection_info['development'])
|
52
|
-
else
|
53
|
-
warn "Can't access DB -- check file path."
|
54
|
-
exit
|
55
|
-
end
|
56
|
-
|
57
|
-
MetasploitDataModels.require_models
|
58
|
-
|
59
|
-
puts "\n\n\n#{mdm_banner[:color]}#{mdm_banner[:text]}\e[0m\n\n\n"
|
60
|
-
|
61
|
-
Pry.config.prompt = proc { |obj, nest_level, _| "mdm:#{nest_level}> " }
|
62
|
-
|
63
|
-
Pry.start
|
64
|
-
exit
|
65
|
-
rescue LoadError
|
66
|
-
warn "Unable to load Pry"
|
67
|
-
end
|
68
|
-
|
data/bin/rails
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
-
# installed from the root of your application.
|
4
|
-
|
5
|
-
ENGINE_ROOT = File.expand_path('..', __dir__)
|
6
|
-
ENGINE_PATH = File.expand_path('../lib/metasploit_data_models/engine', __dir__)
|
7
|
-
APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
|
8
|
-
|
9
|
-
# Set up gems listed in the Gemfile.
|
10
|
-
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
11
|
-
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
-
|
13
|
-
require 'rails/all'
|
14
|
-
require 'rails/engine/commands'
|
@@ -1,342 +0,0 @@
|
|
1
|
-
RSpec.describe ParametersValidator do
|
2
|
-
subject(:parameters_validator) do
|
3
|
-
described_class.new(
|
4
|
-
:attributes => attributes
|
5
|
-
)
|
6
|
-
end
|
7
|
-
|
8
|
-
let(:attribute) do
|
9
|
-
:params
|
10
|
-
end
|
11
|
-
|
12
|
-
let(:attributes) do
|
13
|
-
attribute
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:element) do
|
17
|
-
[]
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:index) do
|
21
|
-
rand(100)
|
22
|
-
end
|
23
|
-
|
24
|
-
let(:type_signature_sentence) do
|
25
|
-
'Valid parameters are an Array<Array(String, String)>.'
|
26
|
-
end
|
27
|
-
|
28
|
-
context 'CONSTANTS' do
|
29
|
-
it 'should define TYPE_SIGNATURE_SENTENCE' do
|
30
|
-
expect(described_class::TYPE_SIGNATURE_SENTENCE).to eq(type_signature_sentence)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context '#error_at' do
|
35
|
-
subject(:error_at) do
|
36
|
-
parameters_validator.send(
|
37
|
-
:error_at,
|
38
|
-
:element => element,
|
39
|
-
:index => index,
|
40
|
-
:prefix => prefix
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
let(:prefix) do
|
45
|
-
'has a prefix'
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'should include prefix' do
|
49
|
-
expect(error_at).to include(prefix)
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'should include location_clause in same sentence as prefix' do
|
53
|
-
location_clause = parameters_validator.send(
|
54
|
-
:location_clause,
|
55
|
-
:element => element,
|
56
|
-
:index => index
|
57
|
-
)
|
58
|
-
|
59
|
-
expect(error_at).to include("#{prefix} #{location_clause}.")
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'should include TYPE_SIGNATURE_SENTENCE' do
|
63
|
-
expect(error_at).to include(type_signature_sentence)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context '#length_error_at' do
|
68
|
-
subject(:length_error_at) do
|
69
|
-
parameters_validator.send(
|
70
|
-
:length_error_at,
|
71
|
-
:element => element,
|
72
|
-
:extreme => extreme,
|
73
|
-
:index => index
|
74
|
-
)
|
75
|
-
end
|
76
|
-
|
77
|
-
let(:extreme) do
|
78
|
-
[:few, :many].sample
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should include extreme in prefix' do
|
82
|
-
expect(parameters_validator).to receive(:error_at) do |*args|
|
83
|
-
options = args.first
|
84
|
-
expect(options[:prefix]).to include(extreme.to_s)
|
85
|
-
end
|
86
|
-
|
87
|
-
length_error_at
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context '#location_clause' do
|
92
|
-
subject(:location_clause) do
|
93
|
-
parameters_validator.send(
|
94
|
-
:location_clause,
|
95
|
-
:element => element,
|
96
|
-
:index => index
|
97
|
-
)
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'should include numerical index' do
|
101
|
-
expect(location_clause).to include("at index #{index}")
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'should include inspect of element' do
|
105
|
-
expect(location_clause).to include(element.inspect)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
context '#validate_each' do
|
110
|
-
subject(:errors) do
|
111
|
-
record.errors[attribute]
|
112
|
-
end
|
113
|
-
|
114
|
-
def validate_each
|
115
|
-
parameters_validator.validate_each(record, attribute, value)
|
116
|
-
end
|
117
|
-
|
118
|
-
let(:record) do
|
119
|
-
Object.new.tap { |object|
|
120
|
-
object.extend ActiveModel::Validations
|
121
|
-
}
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'with Array' do
|
125
|
-
let(:value) do
|
126
|
-
[]
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'element' do
|
130
|
-
let(:value) do
|
131
|
-
[element]
|
132
|
-
end
|
133
|
-
|
134
|
-
context 'with Array' do
|
135
|
-
let(:element) do
|
136
|
-
[]
|
137
|
-
end
|
138
|
-
|
139
|
-
context 'with length < 2' do
|
140
|
-
let(:element) do
|
141
|
-
[]
|
142
|
-
end
|
143
|
-
|
144
|
-
it 'should call #length_error_at with :extreme => :few' do
|
145
|
-
expect(parameters_validator).to receive(:length_error_at).with(
|
146
|
-
hash_including(
|
147
|
-
:extreme => :few
|
148
|
-
)
|
149
|
-
)
|
150
|
-
|
151
|
-
validate_each
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'should record error' do
|
155
|
-
validate_each
|
156
|
-
|
157
|
-
expect(errors).not_to be_empty
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
context 'with length > 2' do
|
162
|
-
let(:element) do
|
163
|
-
['', '', '']
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'should call #length_error_at with :extreme => :many' do
|
167
|
-
expect(parameters_validator).to receive(:length_error_at).with(
|
168
|
-
hash_including(
|
169
|
-
:extreme => :many
|
170
|
-
)
|
171
|
-
)
|
172
|
-
|
173
|
-
validate_each
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'should record error' do
|
177
|
-
validate_each
|
178
|
-
|
179
|
-
expect(errors).not_to be_empty
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'with length == 2' do
|
184
|
-
let(:element) do
|
185
|
-
[parameter_name, parameter_value]
|
186
|
-
end
|
187
|
-
|
188
|
-
let(:parameter_name) do
|
189
|
-
'parameter_name'
|
190
|
-
end
|
191
|
-
|
192
|
-
let(:parameter_value) do
|
193
|
-
'parameter_value'
|
194
|
-
end
|
195
|
-
|
196
|
-
context 'parameter name' do
|
197
|
-
context 'with String' do
|
198
|
-
context 'with blank' do
|
199
|
-
let(:parameter_name) do
|
200
|
-
''
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'should call error_at with blank parameter name prefix' do
|
204
|
-
expect(parameters_validator).to receive(:error_at).with(
|
205
|
-
hash_including(
|
206
|
-
:prefix => 'has blank parameter name'
|
207
|
-
)
|
208
|
-
)
|
209
|
-
|
210
|
-
validate_each
|
211
|
-
end
|
212
|
-
|
213
|
-
it 'should record error' do
|
214
|
-
validate_each
|
215
|
-
|
216
|
-
expect(errors).not_to be_empty
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context 'without blank' do
|
221
|
-
let(:parameter_name) do
|
222
|
-
'parameter_name'
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'should not record error' do
|
226
|
-
validate_each
|
227
|
-
|
228
|
-
expect(errors).to be_blank
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
context 'without String' do
|
234
|
-
let(:parameter_name) do
|
235
|
-
:parameter_name
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'should call error_at with non-String prefix' do
|
239
|
-
expect(parameters_validator).to receive(:error_at).with(
|
240
|
-
hash_including(
|
241
|
-
:prefix => "has non-String parameter name (#{parameter_name.inspect})"
|
242
|
-
)
|
243
|
-
)
|
244
|
-
|
245
|
-
validate_each
|
246
|
-
end
|
247
|
-
|
248
|
-
it 'should record error' do
|
249
|
-
validate_each
|
250
|
-
|
251
|
-
expect(errors).not_to be_empty
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
context 'parameter value' do
|
257
|
-
context 'with String' do
|
258
|
-
let(:parameter_value) do
|
259
|
-
'parameter_value'
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'should not record error' do
|
263
|
-
validate_each
|
264
|
-
|
265
|
-
expect(errors).to be_blank
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
context 'without String' do
|
270
|
-
let(:parameter_value) do
|
271
|
-
0
|
272
|
-
end
|
273
|
-
|
274
|
-
it 'should call error_at with non-String prefix' do
|
275
|
-
expect(parameters_validator).to receive(:error_at).with(
|
276
|
-
hash_including(
|
277
|
-
:prefix => "has non-String parameter value (#{parameter_value.inspect})"
|
278
|
-
)
|
279
|
-
)
|
280
|
-
|
281
|
-
validate_each
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'should record error' do
|
285
|
-
validate_each
|
286
|
-
|
287
|
-
expect(errors).not_to be_empty
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
context 'without Array' do
|
295
|
-
let(:element) do
|
296
|
-
{}
|
297
|
-
end
|
298
|
-
|
299
|
-
it 'should use #error_at with has non-Array for prefix' do
|
300
|
-
expect(parameters_validator).to receive(:error_at).with(
|
301
|
-
hash_including(
|
302
|
-
:prefix => 'has non-Array'
|
303
|
-
)
|
304
|
-
)
|
305
|
-
|
306
|
-
validate_each
|
307
|
-
end
|
308
|
-
|
309
|
-
it 'should record error' do
|
310
|
-
validate_each
|
311
|
-
|
312
|
-
expect(errors).not_to be_empty
|
313
|
-
end
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
context 'without Array' do
|
319
|
-
let(:value) do
|
320
|
-
''
|
321
|
-
end
|
322
|
-
|
323
|
-
before(:example) do
|
324
|
-
validate_each
|
325
|
-
end
|
326
|
-
|
327
|
-
it 'should error that attribute is not an array' do
|
328
|
-
expect(
|
329
|
-
errors.any? { |error|
|
330
|
-
error.include? 'is not an Array.'
|
331
|
-
}
|
332
|
-
).to eq(true)
|
333
|
-
end
|
334
|
-
|
335
|
-
it 'should include TYPE_SIGNATURE_SENTENCE' do
|
336
|
-
errors.each do |error|
|
337
|
-
expect(error).to include(type_signature_sentence)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|