diff --git a/app/components/queries/sort_by_field_component.html.erb b/app/components/queries/sort_by_field_component.html.erb index 302d95bdeadc..87ab4b986300 100644 --- a/app/components/queries/sort_by_field_component.html.erb +++ b/app/components/queries/sort_by_field_component.html.erb @@ -1,4 +1,4 @@ -<%= render(Primer::OpenProject::FlexLayout.new) do |flex| %> +<%= render(Primer::OpenProject::FlexLayout.new(data: { 'test-selector': 'sort-by-field' })) do |flex| %> <% flex.with_column(flex: 1) do %> <%#- We are just using the classes of the primer component here, because when using the primer component, we cannot detach the input element from the form %> <%#- The form="none" adds the input to a nonexistant form (as we do not have one with the ID="none" and thus the fields to not get appended to the query string %> diff --git a/spec/features/projects/projects_index_spec.rb b/spec/features/projects/projects_index_spec.rb index eea29eff69cb..54b13a72b9be 100644 --- a/spec/features/projects/projects_index_spec.rb +++ b/spec/features/projects/projects_index_spec.rb @@ -1007,13 +1007,85 @@ def expect_projects_in_order(*projects) end it "allows to sort via multiple columns" do - binding.pry + projects_page.open_configure_view + projects_page.switch_configure_view_tab(I18n.t("label_sort")) + + # Initially we have the projects ordered by hierarchy + # When we sort by hierarchy, there is a special behavior that no other sorting is possible + # and the sort order is always ascending + projects_page.within_sort_row(0) do + projects_page.expect_sort_order(column_identifier: "lft", direction: "asc", direction_enabled: false) + end + projects_page.expect_number_of_sort_fields(1) + + # Switch sorting order to Name descending + # We now get a second sort field to add another sort order, but it has nothing selected + # in the second field, name is not available as an option + projects_page.within_sort_row(0) do + projects_page.change_sort_order(column_identifier: :name, direction: :desc) + end + projects_page.expect_number_of_sort_fields(2) + + projects_page.within_sort_row(1) do + projects_page.expect_sort_order(column_identifier: "", direction: "") + projects_page.expect_sort_option_is_disabled(column_identifier: :name) + end + + # Let's add another sorting, this time by a custom field + # This will add a third sorting field + projects_page.within_sort_row(1) do + projects_page.change_sort_order(column_identifier: integer_custom_field.column_name, direction: :asc) + end + + projects_page.expect_number_of_sort_fields(3) + projects_page.within_sort_row(2) do + projects_page.expect_sort_order(column_identifier: "", direction: "") + projects_page.expect_sort_option_is_disabled(column_identifier: :name) + projects_page.expect_sort_option_is_disabled(column_identifier: integer_custom_field.column_name) + end + + # And now let's select a third option + # it will not add a 4th sorting field + projects_page.within_sort_row(2) do + projects_page.change_sort_order(column_identifier: :public, direction: :asc) + end + projects_page.expect_number_of_sort_fields(3) + + # We unset the first sorting, this will move the 2nd sorting (custom field) to the first position and + # the 3rd sorting (public) to the second position and will add an empty option to the third position + projects_page.within_sort_row(0) do + projects_page.remove_sort_order + end + + projects_page.expect_number_of_sort_fields(3) + + projects_page.within_sort_row(0) do + projects_page.expect_sort_order(column_identifier: integer_custom_field.column_name, direction: :asc) + end + projects_page.within_sort_row(1) { projects_page.expect_sort_order(column_identifier: :public, direction: :asc) } + projects_page.within_sort_row(2) { projects_page.expect_sort_order(column_identifier: "", direction: "") } + + # To roll back, we now select hierarchy as the third option, this will remove all other options + projects_page.within_sort_row(2) do + projects_page.change_sort_order(column_identifier: :lft, direction: :asc) + end + + projects_page.within_sort_row(0) do + projects_page.expect_sort_order(column_identifier: "lft", direction: "asc", direction_enabled: false) + end + projects_page.expect_number_of_sort_fields(1) end it "does not allow to sort via long text custom fields" do - end + long_text_custom_field = create(:text_project_custom_field) + Setting.enabled_projects_columns += [long_text_custom_field.column_name] - it "only allows exclusive sorting via the hierarchy and does not offer other columns" do + projects_page.open_configure_view + projects_page.switch_configure_view_tab(I18n.t("label_sort")) + + projects_page.within_sort_row(0) do + projects_page.expect_sort_option_not_available(column_identifier: long_text_custom_field.column_name) + end end end diff --git a/spec/support/pages/projects/index.rb b/spec/support/pages/projects/index.rb index c4687d61a16b..298029ae77fc 100644 --- a/spec/support/pages/projects/index.rb +++ b/spec/support/pages/projects/index.rb @@ -265,7 +265,7 @@ def toggle_filters_section end def set_columns(*columns) - click_more_menu_item(I18n.t(:"queries.configure_view.heading")) + open_configure_view # Assumption: there is always one item selected, the 'Name' column # That column can currently not be removed. @@ -356,6 +356,62 @@ def go_to_page(page_number) end end + def open_configure_view + click_more_menu_item(I18n.t(:"queries.configure_view.heading")) + end + + def switch_configure_view_tab(tab_name) + within "tab-container" do + find('button[role="tab"]', text: tab_name).click + end + end + + def expect_sort_order(column_identifier:, direction:, direction_enabled: true) + select = find("select") + segmented_control = find("segmented-control") + + expect(select.value).to eq(column_identifier.to_s) + + if direction.present? + active_direction = segmented_control.find("button[aria-current='true']")["data-direction"] + expect(active_direction).to eq(direction.to_s) + else + expect(segmented_control).to have_no_button("[aria-current='true']") + end + + expect(segmented_control).to have_button(disabled: !direction_enabled, count: 2) + end + + def expect_number_of_sort_fields(number, visible: true) + expect(page).to have_css("[data-test-selector='sort-by-field']", count: number, visible:) + end + + def change_sort_order(column_identifier:, direction:) + find("select option[value='#{column_identifier}']").select_option + find("segmented-control button[data-direction='#{direction}']").click + end + + def remove_sort_order + find("select option[value='']").select_option + end + + def expect_sort_option_is_disabled(column_identifier:) + select = find("select") + + expect(select).to have_css("option[value='#{column_identifier}']:disabled") + end + + def expect_sort_option_not_available(column_identifier:) + select = find("select") + + expect(select).to have_no_css("option[value='#{column_identifier}']") + end + + def within_sort_row(index, &) + field_component = page.all("[data-test-selector='sort-by-field']")[index] + within(field_component, &) + end + def within_table(&) within "#project-table", & end