diff --git a/app/models/custom_button.rb b/app/models/custom_button.rb index b6cb3862dcc..9c3f9f057a0 100644 --- a/app/models/custom_button.rb +++ b/app/models/custom_button.rb @@ -1,6 +1,11 @@ class CustomButton < ApplicationRecord has_one :resource_action, :as => :resource, :dependent => :destroy, :autosave => true + scope :with_array_order, lambda { |ids, column = :id, column_type = :bigint| + order = sanitize_sql_array(["array_position(ARRAY[?]::#{column_type}[], #{table_name}.#{column}::#{column_type})", ids]) + order(order) + } + serialize :options, Hash serialize :visibility_expression serialize :enablement_expression diff --git a/app/models/custom_button_set.rb b/app/models/custom_button_set.rb index eb04f5914f1..8c533c07fc0 100644 --- a/app/models/custom_button_set.rb +++ b/app/models/custom_button_set.rb @@ -56,7 +56,7 @@ def self.applies_to_all_instances(class_name) # - filtered custom_button_sets array when all visibilty expression custom buttons have been evaluated to false def self.filter_with_visibility_expression(custom_button_sets, object) custom_button_sets.each_with_object([]) do |custom_button_set, ret| - custom_button_from_set = CustomButton.where(:id => custom_button_set.custom_buttons.pluck(:id)).select(:id, :visibility_expression).order(:name) + custom_button_from_set = CustomButton.where(:id => custom_button_set.custom_buttons.pluck(:id)).select(:id, :visibility_expression).with_array_order(custom_button_set.set_data[:button_order]) filtered_ids = custom_button_from_set.select { |x| x.evaluate_visibility_expression_for(object) }.pluck(:id) if filtered_ids.present? custom_button_set.set_data[:button_order] = filtered_ids diff --git a/spec/models/custom_button_set_spec.rb b/spec/models/custom_button_set_spec.rb index 8f50af8a96b..678e0f36771 100644 --- a/spec/models/custom_button_set_spec.rb +++ b/spec/models/custom_button_set_spec.rb @@ -25,7 +25,7 @@ let(:vm_1) { FactoryGirl.create(:vm_vmware, :name => 'vm_1') } let(:custom_button_1) { FactoryGirl.create(:custom_button, :applies_to => vm_1) } let(:miq_expression) { MiqExpression.new('EQUAL' => {'field' => 'Vm-name', 'value' => "vm_1"}) } - let(:custom_button_2) { FactoryGirl.create(:custom_button, :name => "DDD", :applies_to => vm_1, :visibility_expression => miq_expression) } + let(:custom_button_2) { FactoryGirl.create(:custom_button, :applies_to => vm_1, :visibility_expression => miq_expression) } let(:set_data) { {:applies_to_class => "Vm", :button_order => [custom_button_1.id, custom_button_2.id]} } let(:custom_button_set) { FactoryGirl.create(:custom_button_set, :name => "set_1", :set_data => set_data) } @@ -44,16 +44,16 @@ context 'when any visibility_expression is evaluated to false and any to true' do let(:miq_expression_false) { MiqExpression.new('EQUAL' => {'field' => 'Vm-name', 'value' => "vm_2"}) } let(:custom_button_1) { FactoryGirl.create(:custom_button, :applies_to => vm_1, :visibility_expression => miq_expression_false) } - let(:custom_button_3) { FactoryGirl.create(:custom_button, :name => "ZZZ", :applies_to => vm_1, :visibility_expression => miq_expression) } - let(:custom_button_4) { FactoryGirl.create(:custom_button, :name => "BBBB", :applies_to => vm_1, :visibility_expression => miq_expression) } - let(:set_data) { {:applies_to_class => "Vm", :button_order => [custom_button_1.id, custom_button_2.id, custom_button_3.id]} } + let(:custom_button_3) { FactoryGirl.create(:custom_button, :applies_to => vm_1, :visibility_expression => miq_expression) } + let(:custom_button_4) { FactoryGirl.create(:custom_button, :applies_to => vm_1, :visibility_expression => miq_expression) } + let(:set_data) { {:applies_to_class => "Vm", :button_order => [custom_button_4.id, custom_button_2.id, custom_button_1.id, custom_button_3.id]} } let(:custom_button_set) { FactoryGirl.create(:custom_button_set, :name => "set_1", :set_data => set_data) } before do [custom_button_3, custom_button_4].each { |x| custom_button_set.add_member(x) } end - it 'returns filtered array of CustomButtonSet and CustomButtons ordered by name' do + it 'returns filtered array of CustomButtonSet and CustomButtons ordered by custom_button_set.set_data[:button_order]' do set = described_class.filter_with_visibility_expression([custom_button_set], vm_1).first expect(set.set_data[:button_order]).to eq([custom_button_4.id, custom_button_2.id, custom_button_3.id]) end diff --git a/spec/models/custom_button_spec.rb b/spec/models/custom_button_spec.rb index c2cedf67814..306380702af 100644 --- a/spec/models/custom_button_spec.rb +++ b/spec/models/custom_button_spec.rb @@ -1,6 +1,25 @@ describe CustomButton do - context "with no buttons" do + describe '.with_array_order' do + context 'order by array' do + let!(:custom_button_1) { FactoryGirl.create(:custom_button, :name => 'AAA', :applies_to_id => 100, :applies_to_class => Vm) } + let!(:custom_button_2) { FactoryGirl.create(:custom_button, :name => 'BBB', :applies_to_id => 200, :applies_to_class => Vm) } + let!(:custom_button_3) { FactoryGirl.create(:custom_button, :name => 'CCC', :applies_to_id => 300, :applies_to_class => Vm) } + + context 'by bigint column' do + it 'orders by memory_shares column' do + expect(CustomButton.with_array_order(%w(300 100 200), :applies_to_id).ids).to eq([custom_button_3.id, custom_button_1.id, custom_button_2.id]) + end + end + context 'by string column' do + it 'orders by name column' do + expect(CustomButton.with_array_order(%w(BBB AAA CCC), :name, :text).ids).to eq([custom_button_2.id, custom_button_1.id, custom_button_3.id]) + end + end + end + end + + context "with no buttons" do describe '#evaluate_enablement_expression_for' do let(:miq_expression) { MiqExpression.new('EQUAL' => {'field' => 'Vm-name', 'value' => 'vm_1'}) } let(:vm) { FactoryGirl.create(:vm_vmware, :name => 'vm_1') }