ManageIQ/manageiq-api

View on GitHub
app/controllers/api/base_controller/normalizer.rb

Summary

Maintainability
A
1 hr
Test Coverage
A
98%
module Api
class BaseController
module Normalizer
#
# Object or Hash Normalizer
#
 
Method `normalize_hash` has a Cognitive Complexity of 21 (exceeds 11 allowed). Consider refactoring.
def normalize_hash(type, obj, opts = {})
Environment.fetch_encrypted_attribute_names(obj.class)
attrs = normalize_select_attributes(obj, opts)
result = {}
 
if type
key_id = collection_config.resource_identifier(type)
if obj[key_id].present? && obj['href'].blank?
href = normalize_href(type, obj[key_id])
if href.present?
result["href"] = href
attrs -= ["href"]
end
end
end
 
is_ar = obj.kind_of?(ActiveRecord::Base)
attrs.each do |k|
next if Api.encrypted_attribute?(k) && api_resource_action_options.exclude?("include_encrypted_attributes")
next if is_ar ? !obj.respond_to?(k) : !obj.try(:key?, k)
result[k] = normalize_attr(k, is_ar ? obj.try(k) : obj[k])
end
result
end
 
private
 
def normalize_input_value(value)
value = Float::INFINITY if value.try(:downcase).presence == "infinity"
 
value
end
 
Cyclomatic complexity for normalize_attr is too high. [13/11]
def normalize_attr(attr, value)
return if value.nil?
if value.kind_of?(Array) || value.kind_of?(ActiveRecord::Relation)
normalize_array(value)
elsif value.respond_to?(:attributes) || value.respond_to?(:keys)
normalize_hash(attr, value)
elsif attr.to_s == "id" || attr.to_s.ends_with?("_id")
value.to_s
elsif Api.time_attribute?(attr)
normalize_time(value)
elsif Api.url_attribute?(attr)
normalize_url(value)
elsif Api.encrypted_attribute?(attr)
normalize_encrypted(value)
elsif value == Float::INFINITY
Float::INFINITY.to_s
elsif Api.resource_attribute?(attr)
normalize_resource(value)
else
value
end
end
 
#
# Timestamps should all be in the XmlSchema form, an ISO 8601
# UTC time representation as follows: 2014-01-30T18:57:55Z
#
# Function takes either a Time string or Seconds since Epoch
#
def normalize_time(value)
return Time.at(value).utc.iso8601 if value.kind_of?(Integer)
 
value.respond_to?(:utc) ? value.utc.iso8601 : value
end
 
#
# Let's normalize a URL
#
# Note, all URLs are baselined as per the request specifying versioning and such.
#
def normalize_url(value)
svalue = value.to_s
pref = @req.api_prefix
suffix = @req.api_suffix
svalue.match(pref) ? svalue : "#{pref}/#{svalue}#{suffix}"
end
 
#
# Let's normalize an href based on type and id value
#
def normalize_href(type, value)
href = Api::Href.new(type.to_s)
 
if href.collection? && href.subcollection?
# type is a 'reftype' (/:collection/:id/:subcollection)
normalize_url("#{href.collection}/#{href.collection_id}/#{href.subcollection}/#{value}")
elsif href.collection == @req.subcollection
# type is a subcollection name
# Use the request to assume the proper collection to nest this under
if collection_config.subcollection?(@req.collection, href.collection.to_sym)
normalize_url("#{@req.collection}/#{@req.collection_id}/#{href.collection}/#{value}")
end
else
# type is a collection name
if collection_config.collection?(href.collection)
normalize_url("#{href.collection}/#{value}")
end
end
end
 
#
# Let's normalize href accessible resources
#
def normalize_resource(value)
value.to_s.starts_with?("/") ? "#{@req.base}#{value}" : value
end
 
#
# Let's filter out encrypted attributes, i.e. passwords
#
def normalize_encrypted(_value)
nil
end
 
def normalize_select_attributes(obj, opts)
if opts[:render_attributes].present?
opts[:render_attributes]
elsif obj.respond_to?(:attributes) && obj.class.respond_to?(:virtual_attribute_names)
obj.class.all_attribute_names - obj.class.virtual_attribute_names
elsif obj.respond_to?(:attributes)
obj.class.all_attribute_names
else
obj.keys
end
end
 
def normalize_array(obj, type = nil)
type ||= @req.subject
obj.collect { |item| normalize_attr(get_reftype(type, type, item), item) }
end
 
def create_resource_attributes_hash(attributes, resource)
attributes.each_with_object({}) do |attr, hash|
hash[attr] = resource.public_send(attr.to_sym) if resource.respond_to?(attr.to_sym)
end
end
end
end
end