@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | |||
Gem::Specification.new do |spec| | |||
spec.name = 'cryptcheck' | |||
spec.version = '1.0.0' | |||
spec.version = '2.0.0' | |||
spec.authors = ['Aeris'] | |||
spec.email = ['aeris+tls@imirhil.fr'] | |||
@@ -6,7 +6,7 @@ class String | |||
error: :red, | |||
warning: :light_red, | |||
good: :green, | |||
perfect: :blue, | |||
great: :blue, | |||
best: :magenta, | |||
unknown: { background: :black } | |||
} | |||
@@ -1,11 +1,11 @@ | |||
module CryptCheck | |||
class Logger | |||
LEVELS = %i(trace debug info warning error fatal none) | |||
@@level = :info | |||
def self.level=(level) | |||
@@level = level.to_sym | |||
end | |||
self.level = ENV.fetch 'LOG', :info | |||
def self.log(level, string=nil, output: $stdout, &block) | |||
return unless enabled? level | |||
@@ -1,15 +1,31 @@ | |||
module CryptCheck | |||
module State | |||
def states | |||
@status ||= calculate_states | |||
# Remove duplicated test for each level | |||
@states ||= self.checks.group_by { |c| c[1] }.collect do |level, checks| | |||
states = checks.group_by(&:first).collect do |name, checks| | |||
states = checks.collect &:last | |||
# true > false > nil | |||
state = if states.include? true | |||
true | |||
elsif states.include? false | |||
false | |||
else | |||
nil | |||
end | |||
[name, state] | |||
end.to_h | |||
[level, states] | |||
end.to_h | |||
end | |||
def status | |||
State.status self.states.reject { |_, v| v.empty? }.keys | |||
@status ||= State.status self.checks.select { |c| c.last == true }.collect { |c| c[1] } | |||
end | |||
LEVELS = %i(best perfect good warning error critical).freeze | |||
PROBLEMS = %i(warning error critical).freeze | |||
BADS = %i(critical error warning).freeze | |||
GOODS = %i(good great best).freeze | |||
LEVELS = (BADS + GOODS).freeze | |||
extend Enumerable | |||
@@ -32,7 +48,7 @@ module CryptCheck | |||
def self.problem(states) | |||
states = self.convert states | |||
self.min PROBLEMS, states | |||
self.min BADS, states | |||
end | |||
def self.sort(states) | |||
@@ -40,7 +56,9 @@ module CryptCheck | |||
end | |||
def self.compare(a, b) | |||
LEVELS.find_index(a.status) <=> LEVELS.find_index(b.status) | |||
a = LEVELS.find_index(a.status) || (LEVELS.size - 1) / 2.0 | |||
b = LEVELS.find_index(b.status) || (LEVELS.size - 1) / 2.0 | |||
a <=> b | |||
end | |||
def performed_checks | |||
@@ -48,6 +66,11 @@ module CryptCheck | |||
@performed_checks | |||
end | |||
protected | |||
def checks | |||
@checks ||= self.available_checks.collect { |c| perform_check c }.flatten(1) + children.collect(&:checks).flatten(1) | |||
end | |||
private | |||
def self.convert(status) | |||
status = [status] unless status.respond_to? :first | |||
@@ -57,6 +80,11 @@ module CryptCheck | |||
end | |||
def self.min(levels, states) | |||
return nil if states.empty? | |||
(levels & states).first | |||
end | |||
def self.max(levels, states) | |||
return nil if states.empty? | |||
(levels & states).last | |||
end | |||
@@ -74,37 +102,27 @@ module CryptCheck | |||
end | |||
def perform_check(check) | |||
name, check, level = check | |||
result = check.call self | |||
return nil unless result | |||
level ||= result | |||
[level, name] | |||
end | |||
def personal_states | |||
states = State.empty | |||
performed_checks = checks | |||
performed_checks.each do |check| | |||
level, name = perform_check check | |||
next unless level | |||
states[level] << name | |||
name, levels, check = check | |||
result = check.call self | |||
case levels | |||
when Symbol # Expected result is true/false/nil | |||
return [[name, levels, result]] | |||
else # Expected result is the best/worst case | |||
# N/A, so return all levels as N/A | |||
return levels.collect { |l| [name, l, nil] } if result.nil? | |||
checks = [] | |||
if BADS.include? result | |||
checks += (GOODS & levels).collect { |l| [name, l, false] } | |||
index = BADS.index result | |||
checks += (BADS & levels).collect { |l| [name, l, BADS.index(l) >= index] } | |||
else | |||
checks += (BADS & levels).collect { |l| [name, l, false] } | |||
index = GOODS.index result | |||
checks += (GOODS & levels).collect { |l| [name, l, GOODS.index(l) <= index] } | |||
end | |||
return checks | |||
end | |||
performed_checks = [ | |||
performed_checks | |||
.collect { |n, _, l| [l, n] } | |||
.group_by(&:first) | |||
.map { |k, v| [k, v.collect(&:last)] }.to_h | |||
] + children.collect(&:performed_checks) | |||
@performed_checks = State.merge *performed_checks | |||
states | |||
end | |||
def calculate_states | |||
children_states = children.collect(&:states) | |||
states = [personal_states] + children_states | |||
State.merge *states | |||
end | |||
end | |||
end |
@@ -107,15 +107,16 @@ module CryptCheck | |||
@cert.issuer | |||
end | |||
protected | |||
include State | |||
CHECKS = WEAK_SIGN.collect do |level, hashes| | |||
hashes.collect do |hash| | |||
["#{hash}_sign".to_sym, -> (s) { s.send "#{hash}?" }, level] | |||
["#{hash}_sign".to_sym, level, -> (s) { s.send "#{hash}?" }] | |||
end | |||
end.flatten(1).freeze | |||
def checks | |||
def available_checks | |||
CHECKS | |||
end | |||
@@ -104,7 +104,7 @@ module CryptCheck | |||
def to_s(type = :long) | |||
case type | |||
when :long | |||
states = self.states.collect { |k, vs| vs.collect { |v| v.to_s.colorize k } }.flatten.join ' ' | |||
states = self.states.collect { |k, vs| vs.select { |_, c| c == true }.collect { |v| v.first.to_s.colorize k } }.flatten.join ' ' | |||
"#{@method} #{@name.colorize self.status} [#{states}]" | |||
when :short | |||
@name.colorize self.status | |||
@@ -227,28 +227,26 @@ module CryptCheck | |||
end | |||
end | |||
protected | |||
include State | |||
CHECKS = [ | |||
[:dss, -> (c) { c.dss? }, :critical], | |||
[:anonymous, -> (c) { c.anonymous? }, :critical], | |||
[:null, -> (c) { c.null? }, :critical], | |||
[:export, -> (c) { c.export? }, :critical], | |||
[:des, -> (c) { c.des? }, :critical], | |||
[:md5, -> (c) { c.md5? }, :critical], | |||
[:rc4, -> (c) { c.rc4? }, :error], | |||
[:sweet32, -> (c) { c.sweet32? }, :error], | |||
[:no_pfs, -> (c) { not c.pfs? }, :warning], | |||
[:pfs, -> (c) { c.pfs? }, :good], | |||
[:dhe, -> (c) { c.dhe? }, :warning], | |||
[:ecdhe, -> (c) { c.ecdhe? }, :good], | |||
[:aead, -> (c) { c.aead? }, :good] | |||
[:dss, :critical, -> (c) { c.dss? }], | |||
[:anonymous, :critical, -> (c) { c.anonymous? }], | |||
[:null, :critical, -> (c) { c.null? }], | |||
[:export, :critical, -> (c) { c.export? }], | |||
[:des, :critical, -> (c) { c.des? }], | |||
[:md5, :critical, -> (c) { c.md5? }], | |||
[:rc4, :critical, -> (c) { c.rc4? }], | |||
[:sweet32, :critical, -> (c) { c.sweet32? }], | |||
[:pfs, :error, -> (c) { not c.pfs? }], | |||
[:dhe, :warning, -> (c) { c.dhe? }], | |||
[:aead, :good, -> (c) { c.aead? }] | |||
].freeze | |||
def checks | |||
def available_checks | |||
CHECKS | |||
end | |||
@@ -40,11 +40,13 @@ module CryptCheck | |||
end | |||
end | |||
protected | |||
include State | |||
CHECKS = [].freeze | |||
def checks | |||
protected | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -17,10 +17,11 @@ class ::OpenSSL::PKey::EC | |||
"ECC #{self.size} bits" | |||
end | |||
protected | |||
include ::CryptCheck::State | |||
CHECKS = [ | |||
[:weak_key, -> (s) do | |||
[:ecc, %i(critical error warning), -> (s) do | |||
case s.size | |||
when 0...160 | |||
:critical | |||
@@ -32,7 +33,7 @@ class ::OpenSSL::PKey::EC | |||
end] | |||
].freeze | |||
def checks | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -50,10 +51,11 @@ class ::OpenSSL::PKey::RSA | |||
"RSA #{self.size} bits" | |||
end | |||
protected | |||
include ::CryptCheck::State | |||
CHECKS = [ | |||
[:weak_key, -> (s) do | |||
[:rsa, %i(critical error), -> (s) do | |||
case s.size | |||
when 0...1024 | |||
:critical | |||
@@ -63,7 +65,7 @@ class ::OpenSSL::PKey::RSA | |||
end] | |||
].freeze | |||
def checks | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -84,10 +86,11 @@ class ::OpenSSL::PKey::DSA | |||
include ::CryptCheck::State | |||
CHECKS = [ | |||
[:weak_key, -> (_) { :critical }] | |||
[:dsa, :critical, -> (_) { true }] | |||
].freeze | |||
def checks | |||
protected | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -105,10 +108,11 @@ class ::OpenSSL::PKey::DH | |||
"DH #{self.size} bits" | |||
end | |||
protected | |||
include ::CryptCheck::State | |||
CHECKS = [ | |||
[:weak_dh, -> (s) do | |||
[:dh, %i(critical error), -> (s) do | |||
case s.size | |||
when 0...1024 | |||
:critical | |||
@@ -118,7 +122,8 @@ class ::OpenSSL::PKey::DH | |||
end] | |||
].freeze | |||
def checks | |||
protected | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -16,7 +16,7 @@ module CryptCheck | |||
when 'A', 'A+' | |||
:best | |||
when 'B', 'B+' | |||
:perfect | |||
:great | |||
when 'C', 'C+' | |||
:good | |||
when 'E' | |||
@@ -32,6 +32,10 @@ module CryptCheck | |||
Logger.info { "Grade : #{self.grade.colorize color }" } | |||
end | |||
def to_h | |||
{ checks: @checks, states: @states } | |||
end | |||
private | |||
def calculate_grade | |||
return 'V' unless @server.valid? | |||
@@ -47,7 +51,7 @@ module CryptCheck | |||
end | |||
[[:good, 'D', 'C'], | |||
[:perfect, 'C', 'B'], | |||
[:great, 'C', 'B'], | |||
[:best, 'B', 'A']].each do |type, score1, score2| | |||
expected = @checks[type] | |||
unless expected.empty? | |||
@@ -44,25 +44,37 @@ module CryptCheck | |||
end | |||
[[@hostname, ip, @port], result] | |||
end.to_h | |||
# rescue StandardError | |||
# raise | |||
rescue => e | |||
@error = e | |||
end | |||
def to_json | |||
JSON.generate(@servers.collect do |host, result| | |||
hostname, ip, _ = host | |||
json = { | |||
hostname: hostname, | |||
ip: ip, | |||
} | |||
case result | |||
when Grade | |||
json[:result] = result.to_json | |||
else | |||
json[:error] = result.message | |||
def to_h | |||
target = { | |||
target: { hostname: @hostname, port: @port }, | |||
} | |||
if @error | |||
target[:error] = @error | |||
else | |||
target[:hosts] = @servers.collect do |host, grade| | |||
hostname, ip, port = host | |||
host = { | |||
hostname: hostname, | |||
ip: ip, | |||
port: port | |||
} | |||
case grade | |||
when Grade | |||
host[:analysis] = grade.server.to_h | |||
host[:status] = grade.to_h | |||
else | |||
host[:error] = grade.message | |||
end | |||
host | |||
end | |||
json | |||
end) | |||
end | |||
target | |||
end | |||
private | |||
@@ -48,11 +48,11 @@ module CryptCheck | |||
hsts? and @hsts >= LONG_HSTS | |||
end | |||
def checks | |||
protected | |||
def available_checks | |||
super + [ | |||
[:hsts, -> (s) { s.hsts? }, :good], | |||
[:hsts_long, -> (s) { s.hsts_long? }, :perfect], | |||
#[:must_staple, -> (s) { s.must_staple? }, :best], | |||
[:hsts, %i(warning good great), -> (s) { s.hsts_long? ? :great : s.hsts? ? :good : :warning }], | |||
#[:must_staple, :best, -> (s) { s.must_staple? }], | |||
] | |||
end | |||
end | |||
@@ -36,12 +36,14 @@ module CryptCheck | |||
include State | |||
CHECKS = [ | |||
[:sslv2, -> (s) { s == :SSLv2 }, :critical], | |||
[:sslv3, -> (s) { s == :SSLv3 }, :critical], | |||
[:tlsv1_2, -> (s) { s == :TLSv1_2 }, :good] | |||
[:sslv2, :critical, -> (s) { s == :SSLv2 }], | |||
[:sslv3, :critical, -> (s) { s == :SSLv3 }], | |||
[:tlsv1_0, :error, -> (s) { s == :TLSv1 }], | |||
[:tlsv1_1, :warning, -> (s) { s == :TLSv1_1 }] | |||
] | |||
def checks | |||
protected | |||
def available_checks | |||
CHECKS | |||
end | |||
end | |||
@@ -61,24 +61,23 @@ module CryptCheck | |||
@trusted | |||
end | |||
def to_h | |||
end | |||
protected | |||
include State | |||
CHECKS = [ | |||
[:tlsv1_2_only, -> (s) { s.tlsv1_2_only? }, :perfect], | |||
[:pfs_only, -> (s) { s.pfs_only? }, :perfect], | |||
[:ecdhe_only, -> (s) { s.ecdhe_only? }, :perfect], | |||
#[:aead_only, -> (s) { s.aead_only? }, :best], | |||
[:fallback_scsv, :good, -> (s) { s.fallback_scsv? }] | |||
# [:tlsv1_2_only, -> (s) { s.tlsv1_2_only? }, :great], | |||
# [:pfs_only, -> (s) { s.pfs_only? }, :great], | |||
# [:ecdhe_only, -> (s) { s.ecdhe_only? }, :great], | |||
#[:aead_only, -> (s) { s.aead_only? }, :best], | |||
].freeze | |||
def checks | |||
checks = CHECKS | |||
unless self.fallback_scsv? == nil | |||
checks += [ | |||
[:no_fallback_scsv, -> (s) { not s.fallback_scsv? }, :error], | |||
[:fallback_scsv, -> (s) { s.fallback_scsv? }, :good] | |||
] | |||
end | |||
checks | |||
def available_checks | |||
CHECKS | |||
end | |||
def children | |||
@@ -13,7 +13,7 @@ describe CryptCheck::State do | |||
[:critical, :warning] => :critical, | |||
[:critical, nil] => :critical, | |||
[:critical, :good] => :critical, | |||
[:critical, :perfect] => :critical, | |||
[:critical, :great] => :critical, | |||
[:critical, :best] => :critical, | |||
[:error, :critical] => :critical, | |||
@@ -21,7 +21,7 @@ describe CryptCheck::State do | |||
[:error, :warning] => :error, | |||
[:error, nil] => :error, | |||
[:error, :good] => :error, | |||
[:error, :perfect] => :error, | |||
[:error, :great] => :error, | |||
[:error, :best] => :error, | |||
[:warning, :critical] => :critical, | |||
@@ -29,7 +29,7 @@ describe CryptCheck::State do | |||
[:warning, :warning] => :warning, | |||
[:warning, nil] => :warning, | |||
[:warning, :good] => :warning, | |||
[:warning, :perfect] => :warning, | |||
[:warning, :great] => :warning, | |||
[:warning, :best] => :warning, | |||
[:good, :critical] => :critical, | |||
@@ -37,23 +37,23 @@ describe CryptCheck::State do | |||
[:good, :warning] => :warning, | |||
[:good, nil] => :good, | |||
[:good, :good] => :good, | |||
[:good, :perfect] => :good, | |||
[:good, :great] => :good, | |||
[:good, :best] => :good, | |||
[:perfect, :critical] => :critical, | |||
[:perfect, :error] => :error, | |||
[:perfect, :warning] => :warning, | |||
[:perfect, nil] => :perfect, | |||
[:perfect, :good] => :good, | |||
[:perfect, :perfect] => :perfect, | |||
[:perfect, :best] => :perfect, | |||
[:great, :critical] => :critical, | |||
[:great, :error] => :error, | |||
[:great, :warning] => :warning, | |||
[:great, nil] => :great, | |||
[:great, :good] => :good, | |||
[:great, :great] => :great, | |||
[:great, :best] => :great, | |||
[:best, :critical] => :critical, | |||
[:best, :error] => :error, | |||
[:best, :warning] => :warning, | |||
[:best, nil] => :best, | |||
[:best, :good] => :good, | |||
[:best, :perfect] => :perfect, | |||
[:best, :great] => :great, | |||
[:best, :best] => :best | |||
}.each do |levels, result| | |||
got = CryptCheck::State.status levels | |||
@@ -76,7 +76,7 @@ describe CryptCheck::State do | |||
[:critical, :warning] => :critical, | |||
[:critical, nil] => :critical, | |||
[:critical, :good] => :critical, | |||
[:critical, :perfect] => :critical, | |||
[:critical, :great] => :critical, | |||
[:critical, :best] => :critical, | |||
[:error, :critical] => :critical, | |||
@@ -84,7 +84,7 @@ describe CryptCheck::State do | |||
[:error, :warning] => :error, | |||
[:error, nil] => :error, | |||
[:error, :good] => :error, | |||
[:error, :perfect] => :error, | |||
[:error, :great] => :error, | |||
[:error, :best] => :error, | |||
[:warning, :critical] => :critical, | |||
@@ -92,7 +92,7 @@ describe CryptCheck::State do | |||
[:warning, :warning] => :warning, | |||
[:warning, nil] => :warning, | |||
[:warning, :good] => :warning, | |||
[:warning, :perfect] => :warning, | |||
[:warning, :great] => :warning, | |||
[:warning, :best] => :warning, | |||
[:good, :critical] => :critical, | |||
@@ -100,23 +100,23 @@ describe CryptCheck::State do | |||
[:good, :warning] => :warning, | |||
[:good, nil] => nil, | |||
[:good, :good] => nil, | |||
[:good, :perfect] => nil, | |||
[:good, :great] => nil, | |||
[:good, :best] => nil, | |||
[:perfect, :critical] => :critical, | |||
[:perfect, :error] => :error, | |||
[:perfect, :warning] => :warning, | |||
[:perfect, nil] => nil, | |||
[:perfect, :good] => nil, | |||
[:perfect, :perfect] => nil, | |||
[:perfect, :best] => nil, | |||
[:great, :critical] => :critical, | |||
[:great, :error] => :error, | |||
[:great, :warning] => :warning, | |||
[:great, nil] => nil, | |||
[:great, :good] => nil, | |||
[:great, :great] => nil, | |||
[:great, :best] => nil, | |||
[:best, :critical] => :critical, | |||
[:best, :error] => :error, | |||
[:best, :warning] => :warning, | |||
[:best, nil] => nil, | |||
[:best, :good] => nil, | |||
[:best, :perfect] => nil, | |||
[:best, :great] => nil, | |||
[:best, :best] => nil | |||
}.each do |levels, result| | |||
got = CryptCheck::State.problem levels | |||
@@ -133,7 +133,6 @@ describe CryptCheck::State do | |||
describe '#states' do | |||
def match_states(actual, **expected) | |||
expected = ::CryptCheck::State.empty.merge expected | |||
expect(actual.states).to eq expected | |||
end | |||
@@ -141,7 +140,7 @@ describe CryptCheck::State do | |||
Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
def available_checks | |||
[] | |||
end | |||
end.new | |||
@@ -150,11 +149,11 @@ describe CryptCheck::State do | |||
Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
def available_checks | |||
[ | |||
[:foo, -> (_) { true }, :critical], | |||
[:bar, -> (_) { :error }], | |||
[:baz, -> (_) { false }] | |||
[:foo, :critical, -> (_) { true }], | |||
[:bar, :error, -> (_) { true }], | |||
[:baz, :warning, -> (_) { false }] | |||
] | |||
end | |||
end.new | |||
@@ -163,8 +162,8 @@ describe CryptCheck::State do | |||
child = Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
[[:bar, -> (_) { :error }]] | |||
def available_checks | |||
[[:bar, :error, -> (_) { true }]] | |||
end | |||
end.new | |||
Class.new do | |||
@@ -174,21 +173,21 @@ describe CryptCheck::State do | |||
@child = child | |||
end | |||
def checks | |||
[[:foo, -> (_) { :critical }]] | |||
def available_checks | |||
[[:foo, :critical, -> (_) { true }]] | |||
end | |||
def children | |||
[@child] | |||
end | |||
end.new(child) | |||
end.new child | |||
end | |||
let(:duplicated) do | |||
child = Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
[[:foo, -> (_) { :critical }]] | |||
def available_checks | |||
[[:foo, :error, -> (_) { true }]] | |||
end | |||
end.new | |||
Class.new do | |||
@@ -198,8 +197,8 @@ describe CryptCheck::State do | |||
@child = child | |||
end | |||
def checks | |||
[[:foo, -> (_) { :critical }]] | |||
def available_checks | |||
[[:foo, :critical, -> (_) { true }]] | |||
end | |||
def children | |||
@@ -208,20 +207,118 @@ describe CryptCheck::State do | |||
end.new(child) | |||
end | |||
it 'must return the level if single level specified' do | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, :critical, -> (_) { true }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ critical: { foo: true } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, :critical, -> (_) { false }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ critical: { foo: false } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, :critical, -> (_) { nil }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ critical: { foo: nil } }) | |||
end | |||
it 'must return all levels if multiple levels specified' do | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, %i(critical error good great), -> (_) { :critical }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ | |||
critical: { foo: true }, | |||
error: { foo: true }, | |||
good: { foo: false }, | |||
great: { foo: false } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, %i(critical error good great), -> (_) { :error }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ | |||
critical: { foo: false }, | |||
error: { foo: true }, | |||
good: { foo: false }, | |||
great: { foo: false } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, %i(critical error good great), -> (_) { :great }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ | |||
critical: { foo: false }, | |||
error: { foo: false }, | |||
good: { foo: true }, | |||
great: { foo: true } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, %i(critical error good great), -> (_) { :good }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ | |||
critical: { foo: false }, | |||
error: { foo: false }, | |||
good: { foo: true }, | |||
great: { foo: false } }) | |||
obj = Class.new do | |||
include ::CryptCheck::State | |||
def available_checks | |||
[[:foo, %i(critical error good great), -> (_) { nil }]] | |||
end | |||
end.new | |||
expect(obj.states).to eq({ | |||
critical: { foo: nil }, | |||
error: { foo: nil }, | |||
good: { foo: nil }, | |||
great: { foo: nil } }) | |||
end | |||
it 'must return empty if no check nor child' do | |||
match_states empty | |||
end | |||
it 'must return personal status if no child' do | |||
match_states childless, critical: %i(foo), error: %i(bar) | |||
match_states childless, critical: { foo: true }, error: { bar: true }, warning: { baz: false } | |||
end | |||
it 'must return personal and children statuses' do | |||
match_states parent, critical: %i(foo), error: %i(bar) | |||
match_states parent, critical: { foo: true }, error: { bar: true} | |||
end | |||
it 'must return remove duplicated status' do | |||
match_states duplicated, critical: %i(foo) | |||
match_states duplicated, critical: { foo: true }, error: { foo: true } | |||
end | |||
end | |||
@@ -230,7 +327,7 @@ describe CryptCheck::State do | |||
empty = Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
def available_checks | |||
[] | |||
end | |||
end.new | |||
@@ -241,8 +338,8 @@ describe CryptCheck::State do | |||
empty = Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
[[:foo, -> (_) { :critical }]] | |||
def available_checks | |||
[[:foo, :critical, -> (_) { true }]] | |||
end | |||
end.new | |||
expect(empty.status).to be :critical | |||
@@ -252,9 +349,9 @@ describe CryptCheck::State do | |||
empty = Class.new do | |||
include ::CryptCheck::State | |||
def checks | |||
[[:foo, -> (_) { :critical }], | |||
[:bar, -> (_) { :error }]] | |||
def available_checks | |||
[[:foo, :critical, -> (_) { true }], | |||
[:bar, :error, -> (_) { true }]] | |||
end | |||
end.new | |||
expect(empty.status).to be :critical | |||