lib/ndd/url_checker/status.rb
module NDD
module UrlChecker
# The result of a URI test.
# @author David DIDIER
# @attr_reader code [String] the state
# @attr_reader error [String, StandardError] the last error if any
# @attr_reader uris [Array<String>] the list of requested URI
class Status
attr_reader :code
attr_reader :error
attr_reader :uris
# Creates a new instance in the :unknown state.
# @param uri [String, URI::HTTP] the requested URI.
def initialize(uri)
@uris = [uri.to_s]
@code = :unknown
end
# @return [String] the first requested URI.
def uri
uris.first
end
# Note that the :unknown code is neither valid nor invalid.
# @return [Boolean] true if valid, false otherwise.
def valid?
VALID_CODES.include? @code
end
# Note that the :unknown code is neither valid nor invalid.
# @return [Boolean] true if invalid, false otherwise.
def invalid?
INVALID_CODES.include? @code
end
# @return [Boolean] true if redirected, false otherwise.
def redirected?
@code == :redirected
end
# When the URI is valid without any redirect.
# @return [self]
def direct
update_code(:direct, %i(unknown))
end
# When a generic error is raised.
# @param error [StandardError] the generic error.
# @return [self]
def failed(error)
@error = error
update_code(:failed, %i(unknown redirected))
end
# Adds a new URI to the redirected URI list.
# @param uri [String|URI::HTTP] the redirection URI.
# @return [self]
def redirected(uri)
@uris << uri.to_s
update_code(:redirected, %i(unknown redirected))
end
# When there are too many redirects.
# @return [self]
def too_many_redirects
update_code(:too_many_redirects, %i(unknown redirected))
end
# When the host cannot be resolved.
# @return [self]
def unknown_host
update_code(:unknown_host, %i(unknown redirected))
end
# Returns the status representation
def to_s
self.inspect
end
# -------------------------------------------------------------------------------------------------- private -----
private
VALID_CODES = %i(direct redirected).freeze
INVALID_CODES = %i(failed too_many_redirects unknown_host).freeze
# Updates the code if the transition is valid.
# @param code [Symbol] the new code.
# @param valid_source_codes [Array<Symbol>] the codes from which the transition can happen.
# @return [NDD::UrlChecker::Status] self.
def update_code(code, valid_source_codes)
unless valid_source_codes.include?(@code)
raise "Changing the status code from :#{@code} to :#{code} is forbidden"
end
@code = code
self
end
end
end
end