Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit Generic Object associations to the same list of objects available to reporting. #15735

Merged
merged 1 commit into from
Aug 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions app/models/generic_object_definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class GenericObjectDefinition < ApplicationRecord
FEATURES = %w(attribute association method).freeze
REG_ATTRIBUTE_NAME = /\A[a-z][a-zA-Z_0-9]*\z/
REG_METHOD_NAME = /\A[a-z][a-zA-Z_0-9]*[!?]?\z/
ALLOWED_ASSOCIATION_TYPES = (MiqReport.reportable_models + %w(GenericObject)).freeze

serialize :properties, Hash

Expand Down Expand Up @@ -102,7 +103,10 @@ def delete_property_attribute(name)
end

def add_property_association(name, type)
properties[:associations][name.to_s] = type.to_s.classify
type = type.to_s.classify
raise "invalid model for association: [#{type}]" unless type.in?(ALLOWED_ASSOCIATION_TYPES)

properties[:associations][name.to_s] = type
save
end

Expand Down Expand Up @@ -160,12 +164,10 @@ def validate_property_attributes
end

def validate_property_associations
properties[:associations].each do |name, klass|
begin
klass.constantize
rescue NameError
errors[:properties] << "association [#{name}] is not of a valid model: [#{klass}]"
end
invalid_models = properties[:associations].values - ALLOWED_ASSOCIATION_TYPES
errors[:properties] << "invalid models for association: [#{invalid_models.join(",")}]" unless invalid_models.empty?

properties[:associations].each do |name, _klass|
errors[:properties] << "invalid association name: [#{name}]" unless REG_ATTRIBUTE_NAME =~ name
end
end
Expand Down
28 changes: 23 additions & 5 deletions spec/models/generic_object_definition_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,17 @@
expect { testdef.save! }.to raise_error(ActiveRecord::RecordInvalid)
end

it 'raises an error if any property association is not a reportable model' do
testdef = described_class.new(:name => 'test', :properties => {:associations => {'folders' => :ems_folder}})
expect { testdef.save! }.to raise_error(ActiveRecord::RecordInvalid)
end

it 'property name is unique among attributes, associations and methods' do
testdef = described_class.new(
:name => 'test',
:properties => {
:attributes => {:vms => "float", 'server' => 'localhost'},
:associations => {'vms' => :strang_model, 'hosts' => :host},
:associations => {'vms' => :vm, 'hosts' => :host},
:methods => [:hosts, :some_method]
}
)
Expand Down Expand Up @@ -69,6 +74,11 @@
expect { testdef.save! }.to raise_error(ActiveRecord::RecordInvalid)
end

it 'accepts GenericObject as an association' do
testdef = described_class.create(:name => 'test', :properties => {:associations => {'balancers' => :generic_object}})
expect(testdef.properties[:associations]).to include('balancers' => 'GenericObject')
end

describe '#destroy' do
let(:generic_object) do
FactoryGirl.build(:generic_object, :generic_object_definition => definition, :name => 'test')
Expand Down Expand Up @@ -194,8 +204,17 @@
end

it 'updates the association with different class' do
definition.add_property_association(:vms, 'vm_or_template')
expect(definition.properties[:associations]).to include('vms' => 'VmOrTemplate')
definition.add_property_association(:vms, 'vm_cloud')
expect(definition.properties[:associations]).to include('vms' => 'VmCloud')
end

it 'accepts GenericObject as the association' do
definition.add_property_association(:balancers, 'generic_object')
expect(definition.properties[:associations]).to include('balancers' => 'GenericObject')
end

it 'raises an error if the association is not a reportable model' do
expect { definition.add_property_association(:folders, 'ems_folder') }.to raise_error(RuntimeError, "invalid model for association: [EmsFolder]")
end
end

Expand Down Expand Up @@ -257,8 +276,7 @@

it 'raises an error with undefined attributes' do
@options = {:max_number => 10, :attr1 => true, :attr2 => 1}
expect { subject }.to raise_error(RuntimeError,
"[attr1, attr2]: not searchable for Generic Object of #{definition.name}")
expect { subject }.to raise_error(RuntimeError, "[attr1, attr2]: not searchable for Generic Object of #{definition.name}")
end

it 'finds by associations' do
Expand Down