Skip to content

Commit

Permalink
Merge pull request #16770 from yrudman/fixed-expression-evaluation-fo…
Browse files Browse the repository at this point in the history
…r-custom-button

Fixed expression evaluation for custom button in CustomActionMixin
(cherry picked from commit 091a546)

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1535153
  • Loading branch information
gtanzillo authored and simaishi committed Jan 16, 2018
1 parent af95c6d commit 039ca82
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 10 deletions.
29 changes: 20 additions & 9 deletions app/models/mixins/custom_actions_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ module CustomActionsMixin
virtual_has_one :custom_action_buttons, :class_name => "Array"
end

def custom_actions
def custom_actions(applies_to = self)
{
:buttons => filter_by_visibility(custom_buttons).collect(&method(:serialize_button)),
:buttons => serialize_buttons_if_visible(custom_buttons, applies_to),
:button_groups => custom_button_sets_with_generics.collect do |button_set|
button_set.serializable_hash.merge(
:buttons => filter_by_visibility(button_set.children).collect(&method(:serialize_button))
:buttons => serialize_buttons_if_visible(button_set.children, applies_to)
)
end
}
end

def custom_action_buttons
filter_by_visibility(custom_buttons + custom_button_sets_with_generics.collect(&:children).flatten)
def custom_action_buttons(applies_to = self)
filter_by_visibility(custom_buttons + custom_button_sets_with_generics.collect(&:children).flatten, applies_to)
end

def generic_button_group
Expand All @@ -39,15 +39,26 @@ def direct_custom_buttons
CustomButton.buttons_for(self).select { |b| b.parent.nil? }
end

def filter_by_visibility(buttons)
buttons.select { |b| b.evaluate_visibility_expression_for(self) }
def filter_by_visibility(buttons, applies_to = self)
buttons.select { |b| b.evaluate_visibility_expression_for(target_for_expression(b, applies_to)) }
end

def serialize_button(button)
button.expanded_serializable_hash.merge("enabled" => button.evaluate_enablement_expression_for(self))
def serialize_button(button, applies_to = self)
obj = target_for_expression(button, applies_to)
button.expanded_serializable_hash.merge("enabled" => button.evaluate_enablement_expression_for(obj))
end

def generic_custom_buttons
CustomButton.buttons_for(self.class.base_model.name)
end

private

def serialize_buttons_if_visible(buttons, applies_to)
filter_by_visibility(buttons, applies_to).collect { |button| serialize_button(button, applies_to) }
end

def target_for_expression(button, applies_to)
button.applies_to_class == applies_to.class.base_model.name ? applies_to : self
end
end
9 changes: 8 additions & 1 deletion app/models/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class Service < ApplicationRecord
before_validation :set_tenant_from_group
before_create :apply_dialog_settings

delegate :custom_actions, :custom_action_buttons, :to => :service_template, :allow_nil => true
delegate :provision_dialog, :to => :miq_request, :allow_nil => true
delegate :user, :to => :miq_request, :allow_nil => true

Expand Down Expand Up @@ -99,6 +98,14 @@ def power_states
vms.map(&:power_state)
end

def custom_actions
service_template&.custom_actions(self)
end

def custom_action_buttons
service_template&.custom_action_buttons(self)
end

def power_state
if options[:power_status] == "starting"
return 'on' if power_states_match?(:start)
Expand Down
19 changes: 19 additions & 0 deletions spec/models/service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,23 @@ def create_deep_tree
@service_c121 = FactoryGirl.create(:service, :service => @service_c12)
@service_c2 = FactoryGirl.create(:service, :service => @service)
end

context "custom actions" do
let(:service_template) { FactoryGirl.create(:service_template) }
let(:service) { FactoryGirl.create(:service, :service_template => service_template) }

describe "#custom_actions" do
it "get list of custom actions from linked service template" do
expect(service_template).to receive(:custom_actions)
service.custom_actions
end
end

describe "#custom_action_buttons" do
it "get list of custom action buttons from linked service template" do
expect(service_template).to receive(:custom_action_buttons)
service.custom_action_buttons
end
end
end
end
59 changes: 59 additions & 0 deletions spec/models/service_template_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,65 @@
expect(service_template.custom_actions).to match(expected)
end

context "expression evaluation" do
let(:service_template) { FactoryGirl.create(:service_template, :prov_type=> "vmware") }
let(:service) { FactoryGirl.create(:service, :name => "foo", :service_template => service_template) }
let(:true_expression_on_template) do
MiqExpression.new("=" => {"field" => "ServiceTemplate-prov_type", "value" => "vmware"})
end
let(:false_expression_on_template) do
MiqExpression.new("=" => {"field" => "ServiceTemplate-prov_type", "value" => "not_vmware"})
end
let(:true_expression_on_service) do
MiqExpression.new("=" => {"field" => "Service-name", "value" => "foo"})
end
let(:false_expression_on_service) do
MiqExpression.new("=" => {"field" => "Service-name", "value" => "not_foo"})
end

before do
FactoryGirl.create(:custom_button,
:name => "visible button on service",
:applies_to_class => "Service",
:visibility_expression => true_expression_on_service)
FactoryGirl.create(:custom_button,
:name => "hidden button on service",
:applies_to_class => "Service",
:visibility_expression => false_expression_on_service)
FactoryGirl.create(:custom_button,
:name => "visible button on template",
:applies_to_class => "ServiceTemplate",
:applies_to_id => service_template.id,
:visibility_expression => true_expression_on_template)
FactoryGirl.create(:custom_button,
:name => "hidden visible button on template",
:applies_to_class => "ServiceTemplate",
:applies_to_id => service_template.id,
:visibility_expression => false_expression_on_template)
end

it "uses ServiceTemplate object to evaluate expression defined on Service Template if no parameter passed" do
expected = {
:buttons => [
a_hash_including("name" => "visible button on template")
],
:button_groups => []
}
expect(service_template.custom_actions).to match(expected)
end

it "uses passed object for expression defined on that object and ServiceTemplate for expression on template" do
expected = {
:buttons => a_collection_containing_exactly(
a_hash_including("name" => "visible button on service"),
a_hash_including("name" => "visible button on template")
),
:button_groups => []
}
expect(service_template.custom_actions(service)).to match(expected)
end
end

it "serializes the enablement" do
service_template = FactoryGirl.create(:service_template, :name => "foo")
true_expression = MiqExpression.new("=" => {"field" => "ServiceTemplate-name", "value" => "foo"})
Expand Down

0 comments on commit 039ca82

Please sign in to comment.