Merge pull request #10662 from opf/fix/37149/sorting-wps-by-project

Case insensitive sorting for work packages
pull/10709/head
ulferts 3 years ago committed by GitHub
commit f0c9c60669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .rubocop.yml
  2. 71
      app/models/query/results.rb
  3. 36
      app/models/query/results/group_by.rb
  4. 491
      spec/models/query/results_spec.rb

@ -172,8 +172,7 @@ RSpec/MultipleExpectations:
- 'modules/*/spec/features/**/*.rb'
RSpec/MultipleMemoizedHelpers:
Max: 20
AllowSubject: true
Enabled: false
RSpec/NestedGroups:
Max: 4

@ -123,25 +123,74 @@ class ::Query::Results
criteria = ::Query::SortCriteria.new query.sortable_columns
criteria.available_criteria = aliased_sorting_by_column_name
criteria.criteria = query.sort_criteria
criteria.map_each { |criteria| criteria.map { |raw| Arel.sql raw } }
criteria.map_each { |c| c.map { |raw| Arel.sql raw } }
end
def aliased_sorting_by_column_name
sorting_by_column_name = query.sortable_key_by_column_name
aliases = include_aliases
reflections = reflection_includes
sorting_by_column_name.each_with_object({}) do |(column_key, sortable), hash|
column_is_association = reflections.include?(column_key.to_sym)
columns_hash = columns_hash_for(column_is_association ? column_key : nil)
hash[column_key] = if column_is_association
alias_name = aliases[column_key.to_sym]
expand_association_columns(alias_name, sortable, columns_hash)
else
case_insensitive_condition(column_key, sortable, columns_hash)
end
end
end
reflection_includes.each do |inc|
sorting_by_column_name[inc.to_s] = Array(sorting_by_column_name[inc.to_s]).map do |column|
if column.respond_to?(:call)
column.call(aliases[inc])
else
"#{aliases[inc]}.#{column}"
end
end
##
# Returns the expanded association columns name
def expand_association_columns(alias_name, sortable, columns_hash)
Array(sortable).map do |column|
sort_condition = expand_association_column(column, alias_name)
case_insensitive_condition(column, sort_condition, columns_hash)
end
end
sorting_by_column_name
##
# Returns a single expanded association column name
def expand_association_column(column, alias_name)
if column.respond_to?(:call)
column.call(alias_name)
else
"#{alias_name}.#{column}"
end
end
##
# Return the columns hash for a given association
# If the association is nil, then return the WorkPackage.columns_hash
def columns_hash_for(association = nil)
if association
WorkPackage.reflections[association].klass.columns_hash
else
WorkPackage.columns_hash
end
end
##
# Return the case insensitive version for columns with a string type
def case_insensitive_condition(column_key, condition, columns_hash)
if columns_hash[column_key]&.type == :string
"LOWER(#{condition})"
elsif custom_field_type(column_key) == "string"
condition.map { |c| "LOWER(#{c})" }
else
condition
end
end
##
# Find the custom field type based on the column key
def custom_field_type(column_key)
(column = query.sortable_columns.detect { |c| c.name.to_s == column_key }) &&
column.respond_to?(:custom_field) &&
column.custom_field.field_format
end
# To avoid naming conflicts, joined tables are aliased if they are joined

@ -29,13 +29,11 @@
module ::Query::Results::GroupBy
# Returns the work package count by group or nil if query is not grouped
def work_package_count_by_group
@work_package_count_by_group ||= begin
if query.grouped?
r = group_counts_by_group
@work_package_count_by_group ||= if query.grouped?
r = group_counts_by_group
transform_group_keys(r)
end
end
transform_group_keys(r)
end
rescue ::ActiveRecord::StatementInvalid => e
raise ::Query::StatementInvalid.new(e.message)
end
@ -65,7 +63,7 @@ module ::Query::Results::GroupBy
def group_by_for_count
Array(query.group_by_statement).map { |statement| Arel.sql(statement) } +
[Arel.sql(group_by_sort(false))]
[Arel.sql(group_by_sort(order: false))]
end
def pluck_for_count
@ -137,33 +135,33 @@ module ::Query::Results::GroupBy
def transform_association_property_keys(association, groups)
ar_keys = association.class_name.constantize.find(groups.keys.compact)
groups.map do |key, value|
[ar_keys.detect { |ar_key| ar_key.id == key }, value]
end.to_h
groups.transform_keys do |key|
ar_keys.detect { |ar_key| ar_key.id == key }
end
end
# Returns the SQL sort order that should be prepended for grouping
def group_by_sort(order = true)
def group_by_sort(order: true)
if query.grouped? && (column = query.group_by_column)
aliases = include_aliases
alias_name = include_aliases[column.name]
columns_hash = columns_hash_for(alias_name ? column.association : nil)
Array(column.sortable).map do |s|
direction = order ? order_for_group_by(column) : nil
aliased_group_by_sort_order(aliases[column.name], s, direction)
aliased_group_by_sort_order(alias_name, s, columns_hash, direction)
end.join(', ')
end
end
def aliased_group_by_sort_order(alias_name, sortable, order = nil)
column = if alias_name && sortable.respond_to?(:call)
sortable.call(alias_name)
elsif alias_name
"#{alias_name}.#{sortable}"
def aliased_group_by_sort_order(alias_name, sortable, columns_hash, order = nil)
column = if alias_name
expand_association_column(sortable, alias_name)
else
sortable
end
column = case_insensitive_condition(sortable, column, columns_hash)
if order
column + " #{order} "
else

@ -34,9 +34,9 @@ describe ::Query::Results, type: :model, with_mail: false do
show_hierarchies: false
end
let(:query_results) do
::Query::Results.new query
described_class.new query
end
let(:project_1) { create :project }
let(:project1) { create :project }
let(:role_pm) do
create(:role,
permissions: %i(
@ -50,18 +50,18 @@ describe ::Query::Results, type: :model, with_mail: false do
create(:role,
permissions: [:view_work_packages])
end
let(:user_1) do
let(:user1) do
create(:user,
firstname: 'user',
lastname: '1',
member_in_project: project_1,
member_in_project: project1,
member_through_role: [role_dev, role_pm])
end
let(:wp_p1) do
(1..3).map do
create(:work_package,
project: project_1,
assigned_to_id: user_1.id)
project: project1,
assigned_to_id: user1.id)
end
end
@ -70,67 +70,67 @@ describe ::Query::Results, type: :model, with_mail: false do
build :query,
show_hierarchies: false,
group_by: group_by,
project: project_1
project: project1
end
let(:type_1) do
let(:type1) do
create(:type)
end
let(:type_2) do
let(:type2) do
create(:type)
end
let(:work_package1) do
create(:work_package,
type: type_1,
project: project_1)
type: type1,
project: project1)
end
let(:work_package2) do
create(:work_package,
type: type_2,
project: project_1)
type: type2,
project: project1)
end
context 'grouping by responsible' do
context 'when grouping by responsible' do
let(:group_by) { 'responsible' }
it 'should produce a valid SQL statement' do
it 'produces a valid SQL statement' do
expect { query_results.work_package_count_by_group }.not_to raise_error
end
end
context 'grouping and filtering by text' do
context 'when grouping and filtering by text' do
let(:group_by) { 'responsible' }
before do
query.add_filter('search', '**', ['asdf'])
end
it 'should produce a valid SQL statement (Regression #29598)' do
it 'produces a valid SQL statement (Regression #29598)' do
expect { query_results.work_package_count_by_group }.not_to raise_error
end
end
context 'grouping by assigned_to' do
context 'when grouping by assigned_to' do
let(:group_by) { 'assigned_to' }
before do
work_package1
work_package2.update_column(:assigned_to_id, user_1.id)
work_package2.update_column(:assigned_to_id, user1.id)
login_as(user_1)
login_as(user1)
end
it 'returns a hash of counts by value' do
expect(query_results.work_package_count_by_group).to eql(nil => 1, user_1 => 1)
expect(query_results.work_package_count_by_group).to eql(nil => 1, user1 => 1)
end
end
context 'grouping by assigned_to with only a nil group' do
context 'when grouping by assigned_to with only a nil group' do
let(:group_by) { 'assigned_to' }
before do
work_package1
login_as(user_1)
login_as(user1)
end
it 'returns a hash of counts by value' do
@ -138,44 +138,44 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'grouping by type' do
context 'when grouping by type' do
let(:group_by) { 'type' }
before do
work_package1
work_package2
login_as(user_1)
login_as(user1)
end
it 'returns the groups sorted by type`s position' do
type_1.update_column(:position, 1)
type_2.update_column(:position, 2)
type1.update_column(:position, 1)
type2.update_column(:position, 2)
result = query_results.work_package_count_by_group
expect(result.length)
.to eql 2
.to be 2
expect(result.keys.map(&:id))
.to eql [type_1.id, type_2.id]
.to eql [type1.id, type2.id]
type_1.update_column(:position, 2)
type_2.update_column(:position, 1)
type1.update_column(:position, 2)
type2.update_column(:position, 1)
new_results = ::Query::Results.new(query)
new_results = described_class.new(query)
result = new_results.work_package_count_by_group
expect(result.length)
.to eql 2
.to be 2
expect(result.keys.map(&:id))
.to eql [type_2.id, type_1.id]
.to eql [type2.id, type1.id]
end
end
context 'grouping by list custom field and filtering for it at the same time' do
context 'when grouping by list custom field and filtering for it at the same time' do
let!(:custom_field) do
create(:list_wp_custom_field,
is_for_all: true,
@ -194,7 +194,7 @@ describe ::Query::Results, type: :model, with_mail: false do
let(:group_by) { "cf_#{custom_field.id}" }
before do
login_as(user_1)
login_as(user1)
work_package1.send(:"custom_field_#{custom_field.id}=", first_value)
work_package1.save!
@ -210,13 +210,13 @@ describe ::Query::Results, type: :model, with_mail: false do
expected_groups = [[first_value], [first_value, last_value]]
group_count.each do |key, count|
expect(count).to eql 1
expect(expected_groups.any? { |group| group & key == key & group }).to be_truthy
expect(count).to be 1
expect(expected_groups).to(be_any { |group| group & key == key & group })
end
end
end
context 'grouping by int custom field' do
context 'when grouping by int custom field' do
let!(:custom_field) do
create(:int_wp_custom_field, is_for_all: true, is_filter: true)
end
@ -224,10 +224,10 @@ describe ::Query::Results, type: :model, with_mail: false do
let(:group_by) { "cf_#{custom_field.id}" }
before do
login_as(user_1)
login_as(user1)
wp_p1[0].type.custom_fields << custom_field
project_1.work_package_custom_fields << custom_field
project1.work_package_custom_fields << custom_field
wp_p1[0].update_attribute(:"custom_field_#{custom_field.id}", 42)
wp_p1[0].save
@ -240,7 +240,7 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'grouping by user custom field' do
context 'when grouping by user custom field' do
let!(:custom_field) do
create(:user_wp_custom_field, is_for_all: true, is_filter: true)
end
@ -248,10 +248,10 @@ describe ::Query::Results, type: :model, with_mail: false do
let(:group_by) { "cf_#{custom_field.id}" }
before do
login_as(user_1)
login_as(user1)
wp_p1[0].type.custom_fields << custom_field
project_1.work_package_custom_fields << custom_field
project1.work_package_custom_fields << custom_field
end
it 'returns nil as user custom fields are not groupable' do
@ -259,7 +259,7 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'grouping by bool custom field' do
context 'when grouping by bool custom field' do
let!(:custom_field) do
create(:bool_wp_custom_field, is_for_all: true, is_filter: true)
end
@ -267,10 +267,10 @@ describe ::Query::Results, type: :model, with_mail: false do
let(:group_by) { "cf_#{custom_field.id}" }
before do
login_as(user_1)
login_as(user1)
wp_p1[0].type.custom_fields << custom_field
project_1.work_package_custom_fields << custom_field
project1.work_package_custom_fields << custom_field
wp_p1[0].update_attribute(:"custom_field_#{custom_field.id}", true)
wp_p1[0].save
@ -283,7 +283,7 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'grouping by date custom field' do
context 'when grouping by date custom field' do
let!(:custom_field) do
create(:date_wp_custom_field, is_for_all: true, is_filter: true)
end
@ -291,49 +291,49 @@ describe ::Query::Results, type: :model, with_mail: false do
let(:group_by) { "cf_#{custom_field.id}" }
before do
login_as(user_1)
login_as(user1)
wp_p1[0].type.custom_fields << custom_field
project_1.work_package_custom_fields << custom_field
project1.work_package_custom_fields << custom_field
wp_p1[0].update_attribute(:"custom_field_#{custom_field.id}", Date.today)
wp_p1[0].update_attribute(:"custom_field_#{custom_field.id}", Time.zone.today)
wp_p1[0].save
wp_p1[1].update_attribute(:"custom_field_#{custom_field.id}", Date.today)
wp_p1[1].update_attribute(:"custom_field_#{custom_field.id}", Time.zone.today)
wp_p1[1].save
end
it 'returns a hash of counts by value' do
expect(query_results.work_package_count_by_group).to eql(Date.today => 2, nil => 1)
expect(query_results.work_package_count_by_group).to eql(Time.zone.today => 2, nil => 1)
end
end
end
describe '#work_packages' do
let!(:project_1) { create :project }
let!(:project_2) { create :project }
describe 'filtering' do
let!(:project1) { create :project }
let!(:project2) { create :project }
let!(:member) do
create(:member,
project: project_2,
principal: user_1,
project: project2,
principal: user1,
roles: [role_pm])
end
let!(:user_2) do
let!(:user2) do
create(:user,
firstname: 'user',
lastname: '2',
member_in_project: project_2,
member_in_project: project2,
member_through_role: role_dev)
end
let!(:wp_p2) do
create(:work_package,
project: project_2,
assigned_to_id: user_2.id)
project: project2,
assigned_to_id: user2.id)
end
let!(:wp2_p2) do
create(:work_package,
project: project_2,
assigned_to_id: user_1.id)
project: project2,
assigned_to_id: user1.id)
end
before do
@ -342,16 +342,16 @@ describe ::Query::Results, type: :model, with_mail: false do
context 'when filtering for assigned_to_role' do
before do
allow(User).to receive(:current).and_return(user_2)
allow(project_2.descendants).to receive(:active).and_return([])
allow(User).to receive(:current).and_return(user2)
allow(project2.descendants).to receive(:active).and_return([])
query.add_filter('assigned_to_role', '=', [role_dev.id.to_s])
end
context 'when a project is set' do
let(:query) { build :query, project: project_2 }
let(:query) { build :query, project: project2 }
it 'should display only wp for selected project and selected role' do
it 'displays only wp for selected project and selected role' do
expect(query_results.work_packages).to match_array([wp_p2])
end
end
@ -359,7 +359,7 @@ describe ::Query::Results, type: :model, with_mail: false do
context 'when no project is set' do
let(:query) { build :query, project: nil }
it 'should display all wp from projects where User.current has access' do
it 'displays all wp from projects where User.current has access' do
expect(query_results.work_packages).to match_array([wp_p2, wp2_p2])
end
end
@ -373,13 +373,13 @@ describe ::Query::Results, type: :model, with_mail: false do
build_stubbed :query,
show_hierarchies: false,
group_by: group_by,
project: project_2
project: project2
end
let!(:custom_field) { create(:work_package_custom_field, is_for_all: true) }
before do
allow(User).to receive(:current).and_return(user_2)
allow(User).to receive(:current).and_return(user2)
# reload in order to have the custom field as an available
# custom field
@ -427,31 +427,31 @@ describe ::Query::Results, type: :model, with_mail: false do
build :query,
show_hierarchies: false,
group_by: group_by,
project: project_1
project: project1
end
let(:group_by) { 'responsible' }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
wp_p1[0].update_attribute(:responsible, user_1)
wp_p1[1].update_attribute(:responsible, user_2)
wp_p1[0].update_attribute(:responsible, user1)
wp_p1[1].update_attribute(:responsible, user2)
end
it 'outputs the work package count in the schema { <User> => count }' do
expect(query_results.work_package_count_by_group)
.to eql(user_1 => 1, user_2 => 1, nil => 1)
.to eql(user1 => 1, user2 => 1, nil => 1)
end
end
context 'when filtering by precedes and ordering by id' do
let(:query) do
build :query,
project: project_1
project: project1
end
before do
login_as(user_1)
login_as(user1)
create(:follows_relation, to: wp_p1[1], from: wp_p1[0])
@ -467,10 +467,10 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
describe '#work_packages' do
let(:work_package1) { create(:work_package, project: project_1, id: 1) }
let(:work_package2) { create(:work_package, project: project_1, id: 2) }
let(:work_package3) { create(:work_package, project: project_1, id: 3) }
describe 'sorting' do
let(:work_package1) { create(:work_package, project: project1, id: 1) }
let(:work_package2) { create(:work_package, project: project1, id: 2) }
let(:work_package3) { create(:work_package, project: project1, id: 3) }
let(:sort_by) { [['id', 'asc']] }
let(:columns) { %i(id subject) }
let(:group_by) { '' }
@ -480,24 +480,24 @@ describe ::Query::Results, type: :model, with_mail: false do
show_hierarchies: false,
group_by: group_by,
sort_criteria: sort_by,
project: project_1,
project: project1,
column_names: columns
end
let(:query_results) do
::Query::Results.new query
described_class.new query
end
let(:user_a) { create(:user, firstname: 'AAA', lastname: 'AAA') }
let(:user_m) { create(:user, firstname: 'MMM', lastname: 'MMM') }
let(:user_m) { create(:user, firstname: 'mmm', lastname: 'mmm') }
let(:user_z) { create(:user, firstname: 'ZZZ', lastname: 'ZZZ') }
context 'grouping by assigned_to, having the author column selected' do
context 'when grouping by assigned_to, having the author column selected' do
let(:group_by) { 'assigned_to' }
let(:columns) { %i(id subject author) }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
work_package1.assigned_to = user_m
work_package1.author = user_m
@ -515,7 +515,7 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package3.save(validate: false)
end
it 'sorts first by assigned_to (group by), then by sort criteria' do
it 'sorts case insensitive first by assigned_to (group by), then by sort criteria' do
# Would look like this in the table
#
# user_m
@ -528,12 +528,12 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'sorting by author, grouping by assigned_to' do
context 'when sorting by author, grouping by assigned_to' do
let(:group_by) { 'assigned_to' }
let(:sort_by) { [['author', 'asc']] }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
work_package1.assigned_to = user_m
work_package1.author = user_m
@ -551,7 +551,7 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package3.save(validate: false)
end
it 'sorts first by group by, then by assigned_to' do
it 'sorts case insensitive first by group by, then by assigned_to' do
# Would look like this in the table
#
# user_m
@ -576,13 +576,13 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'sorting and grouping by priority' do
context 'when sorting and grouping by priority' do
let(:prio_low) { create :issue_priority, position: 1 }
let(:prio_high) { create :issue_priority, position: 0 }
let(:group_by) { 'priority' }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
work_package1.priority = prio_low
work_package2.priority = prio_high
@ -604,13 +604,13 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'sorting by priority, grouping by project' do
context 'when sorting by priority, grouping by project' do
let(:prio_low) { create :issue_priority, position: 1 }
let(:prio_high) { create :issue_priority, position: 0 }
let(:group_by) { 'project' }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
work_package1.priority = prio_low
work_package2.priority = prio_high
@ -632,16 +632,16 @@ describe ::Query::Results, type: :model, with_mail: false do
group_count = query_results.work_package_count_by_group
expect(group_count).to eq({ project_1 => 2 })
expect(group_count).to eq({ project1 => 2 })
end
end
context 'sorting by author and responsible, grouping by assigned_to' do
context 'when sorting by author and responsible, grouping by assigned_to' do
let(:group_by) { 'assigned_to' }
let(:sort_by) { [['author', 'asc'], ['responsible', 'desc']] }
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
work_package1.assigned_to = user_m
work_package1.author = user_m
@ -662,7 +662,7 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package3.save(validate: false)
end
it 'sorts first by group by, then by assigned_to (neutral as equal), then by responsible' do
it 'sorts case insensitive first by group by, then by assigned_to (neutral as equal), then by responsible' do
# Would look like this in the table
#
# user_m
@ -687,7 +687,274 @@ describe ::Query::Results, type: :model, with_mail: false do
end
end
context 'filtering by bool cf' do
context 'when sorting by project' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:project1) { create :project, name: 'Project A' }
let(:project2) { create :project, name: 'Project b' }
let(:project3) { create :project, name: 'Project C' }
let(:work_package1) { create(:work_package, project: project1) }
let(:work_package2) { create(:work_package, project: project2) }
let(:work_package3) { create(:work_package, project: project3) }
before { login_as(user1) }
context 'when ascending' do
let(:sort_by) { [['project', 'asc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [['project', 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when sorting by category' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:category1) { create(:category, project: project1, name: 'Category A') }
let(:category2) { create(:category, project: project1, name: 'Category b') }
let(:category3) { create(:category, project: project1, name: 'Category C') }
let(:work_package1) { create(:work_package, project: project1, category: category1) }
let(:work_package2) { create(:work_package, project: project1, category: category2) }
let(:work_package3) { create(:work_package, project: project1, category: category3) }
before { login_as(user1) }
context 'when ascending' do
let(:sort_by) { [['category', 'asc']] }
it 'sorts case insensitive' do
query_results.work_packages
[work_package1, work_package2, work_package3]
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [['category', 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when sorting by subject' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:work_package1) { create(:work_package, project: project1, subject: 'WorkPackage A') }
let(:work_package2) { create(:work_package, project: project1, subject: 'WorkPackage b') }
let(:work_package3) { create(:work_package, project: project1, subject: 'WorkPackage C') }
before { login_as(user1) }
context 'when ascending' do
let(:sort_by) { [['subject', 'asc']] }
it 'sorts case insensitive' do
query_results.work_packages
[work_package1, work_package2, work_package3]
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [['subject', 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when sorting by finish date' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:work_package1) { create(:work_package, project: project1, due_date: 3.days.ago) }
let(:work_package2) { create(:work_package, project: project1, due_date: 2.days.ago) }
let(:work_package3) { create(:work_package, project: project1, due_date: 1.day.ago) }
before { login_as(user1) }
context 'when ascending' do
let(:sort_by) { [['due_date', 'asc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [['due_date', 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when sorting by string custom field' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:work_package1) { create(:work_package, project: project1) }
let(:work_package2) { create(:work_package, project: project1) }
let(:work_package3) { create(:work_package, project: project1) }
let(:string_cf) { create(:string_wp_custom_field, is_filter: true) }
let!(:custom_value) do
create(:custom_value,
custom_field: string_cf,
customized: work_package1,
value: 'String A')
end
let!(:custom_value2) do
create(:custom_value,
custom_field: string_cf,
customized: work_package2,
value: 'String b')
end
let!(:custom_value3) do
create(:custom_value,
custom_field: string_cf,
customized: work_package3,
value: 'String C')
end
before do
work_package1.project.work_package_custom_fields << string_cf
work_package1.type.custom_fields << string_cf
work_package1.reload
project1.reload
login_as(user1)
end
context 'when ascending' do
let(:sort_by) { [["cf_#{string_cf.id}", 'asc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [["assigned_to", 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when sorting by integer custom field' do
let(:user1) { create(:admin) }
let(:query) do
build_stubbed :query,
show_hierarchies: false,
project: nil,
sort_criteria: sort_by
end
let(:work_package1) { create(:work_package, project: project1) }
let(:work_package2) { create(:work_package, project: project1) }
let(:work_package3) { create(:work_package, project: project1) }
let(:int_cf) { create(:int_wp_custom_field, is_filter: true) }
let!(:custom_value) do
create(:custom_value,
custom_field: int_cf,
customized: work_package1,
value: 1)
end
let!(:custom_value2) do
create(:custom_value,
custom_field: int_cf,
customized: work_package2,
value: 2)
end
let!(:custom_value3) do
create(:custom_value,
custom_field: int_cf,
customized: work_package3,
value: 3)
end
before do
work_package1.project.work_package_custom_fields << int_cf
work_package1.type.custom_fields << int_cf
work_package1.reload
project1.reload
login_as(user1)
end
context 'when ascending' do
let(:sort_by) { [["cf_#{int_cf.id}", 'asc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package1, work_package2, work_package3]
end
end
context 'when descending' do
let(:sort_by) { [["cf_#{int_cf.id}", 'desc']] }
it 'sorts case insensitive' do
expect(query_results.work_packages)
.to match [work_package3, work_package2, work_package1]
end
end
end
context 'when filtering by bool cf' do
let(:bool_cf) { create(:bool_wp_custom_field, is_filter: true) }
let(:custom_value) do
create(:custom_value,
@ -702,11 +969,11 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package1.type.custom_fields << bool_cf
work_package1.reload
project_1.reload
project1.reload
end
before do
allow(User).to receive(:current).and_return(user_1)
allow(User).to receive(:current).and_return(user1)
custom_value
@ -771,22 +1038,6 @@ describe ::Query::Results, type: :model, with_mail: false do
it_behaves_like 'returns the wp'
end
context 'with the wp having no value for the cf
and filtering for false
and the cf not being active in the project' do
let(:custom_value) { nil }
let(:filter_value) { 'f' }
let(:activate_cf) do
work_package1.type.custom_fields << bool_cf
work_package1.reload
project_1.reload
end
it_behaves_like 'is empty'
end
context 'with the wp having no value for the cf
and filtering for false
and the cf not being active for the type' do
@ -797,7 +1048,7 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package1.type.custom_fields << bool_cf
work_package1.reload
project_1.reload
project1.reload
end
it_behaves_like 'is empty'
@ -819,7 +1070,7 @@ describe ::Query::Results, type: :model, with_mail: false do
work_package1.project.work_package_custom_fields << bool_cf
work_package1.reload
project_1.reload
project1.reload
end
it_behaves_like 'is empty'

Loading…
Cancel
Save