From 13fa9541d69b2b0cab4306af72dbb15a1a00c3b1 Mon Sep 17 00:00:00 2001 From: aeris Date: Sun, 5 Feb 2017 18:10:45 +0100 Subject: [PATCH] Better way to manage status --- lib/cryptcheck.rb | 1 + lib/cryptcheck/status.rb | 4 ++ lib/cryptcheck/statused.rb | 48 +++++++++++++++++++ lib/cryptcheck/tls/grade.rb | 2 +- spec/cryptcheck/statused_spec.rb | 82 ++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 lib/cryptcheck/statused.rb create mode 100644 spec/cryptcheck/statused_spec.rb diff --git a/lib/cryptcheck.rb b/lib/cryptcheck.rb index e032386..a09d0db 100644 --- a/lib/cryptcheck.rb +++ b/lib/cryptcheck.rb @@ -32,6 +32,7 @@ module CryptCheck end autoload :Status, 'cryptcheck/status' + autoload :Statused, 'cryptcheck/statused' autoload :Logger, 'cryptcheck/logger' autoload :Tls, 'cryptcheck/tls' module Tls diff --git a/lib/cryptcheck/status.rb b/lib/cryptcheck/status.rb index b5f89eb..464ee55 100644 --- a/lib/cryptcheck/status.rb +++ b/lib/cryptcheck/status.rb @@ -9,6 +9,10 @@ module CryptCheck LEVELS.each &block end + def self.empty + self.collect { |s| [s, []] }.to_h + end + def self.status(statuses) statuses = self.convert statuses self.min LEVELS, statuses diff --git a/lib/cryptcheck/statused.rb b/lib/cryptcheck/statused.rb new file mode 100644 index 0000000..2411105 --- /dev/null +++ b/lib/cryptcheck/statused.rb @@ -0,0 +1,48 @@ +module CryptCheck + module Statused + def status + @status ||= calculate_status + end + + private + def merge(statuses) + Status.collect do |s| + status = statuses.collect { |ss| ss[s] } + status = status.inject &:+ + [s, status.uniq] + end.to_h + end + + def checks + [] + end + + def children + [] + end + + def perform_check(check) + name, check, level = check + result = check.call self + return nil unless result + level ||= result + [level, name] + end + + def personal_status + states = Status.empty + checks.each do |check| + level, name = perform_check check + next unless level + states[level] << name + end + states + end + + def calculate_status + children_statuses = children.collect(&:status) + statuses = [personal_status] + children_statuses + merge statuses + end + end +end diff --git a/lib/cryptcheck/tls/grade.rb b/lib/cryptcheck/tls/grade.rb index 18b3582..a953d43 100644 --- a/lib/cryptcheck/tls/grade.rb +++ b/lib/cryptcheck/tls/grade.rb @@ -124,7 +124,7 @@ module CryptCheck end def calculate_states - states = Status.collect { |s| [s, []] }.to_h + states = Status.empty @checks.each do |name, check, status| result = check.call @server if result diff --git a/spec/cryptcheck/statused_spec.rb b/spec/cryptcheck/statused_spec.rb new file mode 100644 index 0000000..a53dabb --- /dev/null +++ b/spec/cryptcheck/statused_spec.rb @@ -0,0 +1,82 @@ +describe CryptCheck::Statused do + def match_status(actual, **expected) + expected = ::CryptCheck::Status.empty.merge expected + expect(actual.status).to eq expected + end + + describe '::status' do + it 'must return empty if no check nor child' do + statused = Class.new do + include ::CryptCheck::Statused + end.new + match_status statused + end + + it 'must return personal status if no child' do + statused = Class.new do + include ::CryptCheck::Statused + + def checks + [ + [:foo, -> (_) { true }, :critical], + [:bar, -> (_) { :error }], + [:baz, -> (_) { false }] + ] + end + end.new + match_status statused, critical: %i(foo), error: %i(bar) + end + + it 'must return personal and children statuses' do + child = Class.new do + include ::CryptCheck::Statused + + def checks + [[:bar, -> (_) { :error }]] + end + end.new + parent = Class.new do + include ::CryptCheck::Statused + + def initialize(child) + @child = child + end + + def checks + [[:foo, -> (_) { :critical }]] + end + + def children + [@child] + end + end.new(child) + match_status parent, critical: %i(foo), error: %i(bar) + end + + it 'must return remove duplicated status' do + child = Class.new do + include ::CryptCheck::Statused + + def checks + [[:foo, -> (_) { :critical }]] + end + end.new + parent = Class.new do + include ::CryptCheck::Statused + + def initialize(child) + @child = child + end + + def checks + [[:foo, -> (_) { :critical }]] + end + + def children + [@child] + end + end.new(child) + match_status parent, critical: %i(foo) + end + end +end