diff --git a/app/controllers/application_controller/buttons.rb b/app/controllers/application_controller/buttons.rb index 732e64ce1f8..5c52d427473 100644 --- a/app/controllers/application_controller/buttons.rb +++ b/app/controllers/application_controller/buttons.rb @@ -100,6 +100,38 @@ def group_update # we need a "Provider" so adding an "ExtManagementSystem" to the list. MODEL_WITH_OPEN_URL = %w[ExtManagementSystem Service User MiqGroup Tenant CloudTenant GenericObject Vm].freeze + # Types of visibility for the custom buttons + VISIBILITY_TYPES = {'role' => 'role', 'all' => 'all'}.freeze + ALL_ROLES = ["_ALL_", "all"].freeze + FIELDS_EMPTY = [[""], ["", ""]].freeze + + def button_visibility_box_edit + typ_changed = params[:visibility_typ].present? + @edit[:new][:visibility_typ] = VISIBILITY_TYPES[params[:visibility_typ]] if typ_changed + visibility_typ = @edit[:new][:visibility_typ] + + if visibility_typ.to_s == "role" + plural = visibility_typ.pluralize + key = plural.to_sym + prefix = "#{plural}_" + + @edit[:new][key] = [] if typ_changed + params.each do |var, value| + next unless var.starts_with?(prefix) + + name = var.split(prefix).last.to_i + if value == "1" + @edit[:new][key] |= [name] # union + elsif value.downcase == "null" + @edit[:new][key].delete(name) + end + end + else + @edit[:new][:roles] ||= [] + @edit[:new][:roles] |= ["_ALL_"] + end + end + def automate_button_field_changed assert_privileges(feature_by_action) @@ -125,7 +157,7 @@ def automate_button_field_changed @edit[:new][:dialog_id] = nil if params[:display_for].present? && params[:display_for] != 'single' @edit[:new][:dialog_id] = params[:dialog_id] == "" ? nil : params[:dialog_id] if params.key?("dialog_id") - visibility_box_edit + button_visibility_box_edit if params[:button_type] == 'default' clear_playbook_variables @@ -147,7 +179,55 @@ def automate_button_field_changed page.replace("form_role_visibility", :partial => "layouts/role_visibility", :locals => {:rec_id => (@custom_button.id || "new").to_s, :action => "automate_button_field_changed"}) end unless params[:target_class] - @changed = session[:changed] = (@edit[:new] != @edit[:current]) + @changed = session[:changed] = false + # This block checks if any of the fields have changed + # Broken into different branches for specific fields + # If no fields are changed it will not set @changed or session[:changed] to true + @edit[:new].each_key do |key| + if @edit[:new][key] != @edit[:current][key] + if @edit[:new][key].blank? && @edit[:current][key].blank? # check empty string / nil case + next + elsif @edit[:new][key] == @edit[:current][key].to_s # check string / integer case + next + elsif key == :roles # check role values + if (ALL_ROLES.include?(@edit[:new][key]) || @edit[:new][key].empty?) && (ALL_ROLES.include?(@edit[:current][key]) || @edit[:current][key].nil?) # if visibility is set to "To All" + next + elsif @edit[:new][key].collect(&:to_i).sort == @edit[:current][key].collect(&:to_i).sort # check if new roles array and current roles array are equal after sorting the ids + next + else # if new roles array and current roles array are not equal + @changed = session[:changed] = true + break + + end + elsif key == :attrs # check attribute values + @edit[:new][key].each_with_index do |_item, index| + if FIELDS_EMPTY.include?(@edit[:new][:attrs][index]) && @edit[:current][:attrs][index].empty? # check if attribute and value field is empty + next + elsif @edit[:new][:attrs][index].empty? && @edit[:current][:attrs][index].empty? # check if attribute or value field is empty + next + else # if new attribute array and current attribute array are not equal + @changed = session[:changed] = true + break + + end + end + + elsif key == :visibility_typ # check visibility type + if @edit[:new][key] == "all" && @edit[:current][key].nil? # if visibility is set to "To All" + next + else # if new visibility type value and current visibility type value are not equal + @changed = session[:changed] = true + break + + end + else # if new value and current value are not equal + @changed = session[:changed] = true + break + + end + end + end + page << javascript_for_miq_button_visibility(@changed) end page << "miqSparkle(false);" diff --git a/cypress.config.js b/cypress.config.js index e07067ffb9f..9d9bcd36896 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -7,7 +7,7 @@ module.exports = defineConfig({ baseUrl: 'http://localhost:3000', viewportHeight: 800, viewportWidth: 1800, - numTestsKeptInMemory: 0, + numTestsKeptInMemory: 5, videoCompression: false, // See: https://docs.cypress.io/app/references/experiments#Experimental-Flake-Detection-Features diff --git a/cypress/e2e/ui/Automation/Embedded-Automate/customization.cy.js b/cypress/e2e/ui/Automation/Embedded-Automate/customization.cy.js index a7f44467d95..1d692e19d9c 100644 --- a/cypress/e2e/ui/Automation/Embedded-Automate/customization.cy.js +++ b/cypress/e2e/ui/Automation/Embedded-Automate/customization.cy.js @@ -3,7 +3,6 @@ describe('Automation > Embedded Automate > Customization', () => { beforeEach(() => { cy.login(); - cy.intercept('POST', '/ops/accordion_select?id=rbac_accord').as('accordion'); cy.menu('Automation', 'Embedded Automate', 'Customization'); cy.get('#explorer_title_text'); }); @@ -162,4 +161,82 @@ describe('Automation > Embedded Automate > Customization', () => { cy.get('[class="list-group"]').should('not.contain', 'Test Description'); }); }); + + describe('Button Form', () => { + beforeEach(() => { + cy.intercept('POST', '/miq_ae_customization/accordion_select?id=ab_accord').as('accordion'); + cy.get('#control_ab_accord > .panel-title > .collapsed').click(); + cy.wait('@accordion'); + cy.wait(5000); + }); + + it('Validates the save button correctly', () => { + cy.get('.clickable-row').contains('Availability Zone').click({force: true}); + cy.get('.clickable-row').contains('Unassigned Buttons').click({force: true}); + cy.get('[title="Configuration"]').click({force: true}); + cy.get('[title="Add a new Button"]').click({force: true}); + cy.get('#explorer_title_text').contains('Adding a new Button'); + + cy.get('#name').type('Test Button'); + cy.get('#description').type('Test Description'); + cy.get('.icon-button').click(); + cy.get(':nth-child(1) > span > .ff').click(); + cy.get('.bx--modal-footer > .bx--btn--primary').click(); + + cy.get('#ab_advanced_tab_tab > a').click(); + cy.get('#object_request').type('Test Request'); + cy.get('#attribute_1').type('1-attribute'); + cy.get('#value_1').type('1-value'); + cy.get('#attribute_2').type('2-attribute'); + cy.get('#value_2').type('2-value'); + cy.get('.col-md-10 > .btn-group > .btn').click(); + cy.get('.col-md-10 > .btn-group > .open > .dropdown-menu > [data-original-index="1"] > a').click(); + + cy.get('#roles_1').click(); + cy.get('#roles_2').click(); + cy.get('#roles_3').click(); + cy.get('#roles_4').click(); + + cy.get('#buttons_on > .btn-primary').click(); + cy.get('.clickable-row').contains('Test Button').click(); + + cy.get('.attribute_value_pair').contains('1-attribute, 1-value'); + cy.get('.attribute_value_pair').contains('2-attribute, 2-value'); + cy.get('.visibility').contains('EvmRole-administrator, EvmRole-approver, EvmRole-auditor, EvmRole-super_administrator'); + + cy.get('[title="Configuration"]').click(); + cy.get('[title="Edit this Button"]').click(); + + cy.get('#buttons_off > .btn-primary'); + cy.get('#ab_advanced_tab_tab > a').click(); + cy.get('#attribute_2').clear(); + cy.get('#value_2').clear(); + + cy.get('#buttons_on > .btn-primary').click(); + + cy.get('.attribute_value_pair').contains('1-attribute, 1-value'); + cy.get('.attribute_value_pair').should('not.contain', '2-attribute, 2-value'); + + cy.get('[title="Configuration"]').click(); + cy.get('[title="Edit this Button"]').click(); + + cy.get('#buttons_off > .btn-primary'); + cy.get('#ab_advanced_tab_tab > a').click(); + + cy.get('#roles_2').click(); + cy.get('#roles_3').click(); + + cy.get('#buttons_on > .btn-primary').click(); + + cy.get('.visibility').contains('EvmRole-auditor, EvmRole-super_administrator'); + cy.get('.visibility').should('not.contain', 'EvmRole-administrator, EvmRole-approver'); + + cy.get('[title="Configuration"]').click(); + cy.get('[title="Remove this Button"]').click(); + cy.get('h4 > strong').contains('Test Button'); + cy.get('.Delete').click({ force: true }); + + cy.get('.alert').contains('The item "Test Button" has been successfully deleted'); + }); + }); });