OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/spec/models/query/results_sums_integration_sp...

278 lines
11 KiB

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2020 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2017 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
describe ::Query::Results, 'sums', type: :model do
let(:project) do
FactoryBot.create(:project).tap do |p|
p.work_package_custom_fields << int_cf
p.work_package_custom_fields << float_cf
end
end
let(:other_project) do
FactoryBot.create(:project).tap do |p|
p.work_package_custom_fields << int_cf
p.work_package_custom_fields << float_cf
end
end
let!(:work_package1) do
FactoryBot.create(:work_package,
type: type,
project: project,
estimated_hours: 5,
done_ratio: 10,
"custom_field_#{int_cf.id}" => 10,
"custom_field_#{float_cf.id}" => 3.414,
remaining_hours: 3,
story_points: 7)
end
let!(:work_package2) do
FactoryBot.create(:work_package,
type: type,
project: project,
assigned_to: current_user,
done_ratio: 50,
estimated_hours: 5,
"custom_field_#{int_cf.id}" => 10,
"custom_field_#{float_cf.id}" => 3.414,
remaining_hours: 3,
story_points: 7)
end
let!(:work_package3) do
FactoryBot.create(:work_package,
type: type,
project: project,
assigned_to: current_user,
responsible: current_user,
done_ratio: 50,
estimated_hours: 5,
"custom_field_#{int_cf.id}" => 10,
"custom_field_#{float_cf.id}" => 3.414,
remaining_hours: 3,
story_points: 7)
end
let!(:invisible_work_package1) do
FactoryBot.create(:work_package,
type: type,
project: other_project,
estimated_hours: 5,
"custom_field_#{int_cf.id}" => 10,
"custom_field_#{float_cf.id}" => 3.414,
remaining_hours: 3,
story_points: 7)
end
let!(:cost_entry1) do
FactoryBot.create(:cost_entry,
project: project,
work_package: work_package1,
user: current_user,
overridden_costs: 200)
end
let!(:cost_entry2) do
FactoryBot.create(:cost_entry,
project: project,
work_package: work_package2,
user: current_user,
overridden_costs: 200)
end
let!(:time_entry1) do
FactoryBot.create(:time_entry,
project: project,
work_package: work_package1,
user: current_user,
overridden_costs: 300)
end
let!(:time_entry2) do
FactoryBot.create(:time_entry,
project: project,
work_package: work_package2,
user: current_user,
overridden_costs: 300)
end
let(:int_cf) do
FactoryBot.create(:int_wp_custom_field)
end
let(:float_cf) do
FactoryBot.create(:float_wp_custom_field)
end
let(:type) do
FactoryBot.create(:type).tap do |t|
t.custom_fields << int_cf
t.custom_fields << float_cf
end
end
let(:current_user) do
FactoryBot.create(:user,
member_in_project: project,
member_with_permissions: permissions)
end
let(:permissions) do
%i[view_work_packages view_cost_entries view_time_entries view_cost_rates view_hourly_rates]
end
let(:group_by) { nil }
let(:query) do
FactoryBot.build :query,
project: project,
group_by: group_by
end
let(:query_results) do
::Query::Results.new query
end
before do
login_as(current_user)
end
let(:estimated_hours_column) { query.available_columns.detect { |c| c.name.to_s == 'estimated_hours' } }
let(:int_cf_column) { query.available_columns.detect { |c| c.name.to_s == "cf_#{int_cf.id}" } }
let(:float_cf_column) { query.available_columns.detect { |c| c.name.to_s == "cf_#{float_cf.id}" } }
let(:material_costs_column) { query.available_columns.detect { |c| c.name.to_s == "material_costs" } }
let(:labor_costs_column) { query.available_columns.detect { |c| c.name.to_s == "labor_costs" } }
let(:overall_costs_column) { query.available_columns.detect { |c| c.name.to_s == "overall_costs" } }
let(:remaining_hours_column) { query.available_columns.detect { |c| c.name.to_s == "remaining_hours" } }
let(:story_points_column) { query.available_columns.detect { |c| c.name.to_s == "story_points" } }
describe '#all_total_sums' do
it 'is a hash of all summable columns' do
expect(query_results.all_total_sums)
.to eql(estimated_hours_column => 15.0,
int_cf_column => 30,
float_cf_column => 10.24,
material_costs_column => 400.0,
labor_costs_column => 600.0,
overall_costs_column => 1000.0,
remaining_hours_column => 9.0,
story_points_column => 21)
end
context 'when filtering' do
before do
query.add_filter('assigned_to_id', '=', [current_user.id.to_s])
end
it 'is a hash of all summable columns and includes only the work packages matching the filter' do
expect(query_results.all_total_sums)
.to eql(estimated_hours_column => 10.0,
int_cf_column => 20,
float_cf_column => 6.83,
material_costs_column => 200.0,
labor_costs_column => 300.0,
overall_costs_column => 500.0,
remaining_hours_column => 6.0,
story_points_column => 14)
end
end
end
describe '#all_sums_for_group' do
context 'grouped by assigned_to' do
let(:group_by) { :assigned_to }
it 'is a hash of sums grouped by user values (and nil) and grouped columns' do
expect(query_results.all_group_sums)
.to eql(current_user => { estimated_hours_column => 10.0,
int_cf_column => 20,
float_cf_column => 6.83,
material_costs_column => 200.0,
labor_costs_column => 300.0,
overall_costs_column => 500.0,
remaining_hours_column => 6.0,
story_points_column => 14 },
nil => { estimated_hours_column => 5.0,
int_cf_column => 10,
float_cf_column => 3.41,
material_costs_column => 200.0,
labor_costs_column => 300.0,
overall_costs_column => 500.0,
remaining_hours_column => 3.0,
story_points_column => 7 })
end
context 'when filtering' do
before do
query.add_filter('responsible_id', '=', [current_user.id.to_s])
end
it 'is a hash of sums grouped by user values and grouped columns' do
expect(query_results.all_group_sums)
.to eql(current_user => { estimated_hours_column => 5.0,
int_cf_column => 10,
float_cf_column => 3.41,
material_costs_column => 0.0,
labor_costs_column => 0.0,
overall_costs_column => 0.0,
story_points_column => 7,
remaining_hours_column => 3.0 })
end
end
end
context 'grouped by done_ratio' do
let(:group_by) { :done_ratio }
it 'is a hash of sums grouped by done_ratio values and grouped columns' do
expect(query_results.all_group_sums)
.to eql(50 => { estimated_hours_column => 10.0,
int_cf_column => 20,
float_cf_column => 6.83,
material_costs_column => 200.0,
labor_costs_column => 300.0,
overall_costs_column => 500.0,
remaining_hours_column => 6.0,
story_points_column => 14 },
10 => { estimated_hours_column => 5.0,
int_cf_column => 10,
float_cf_column => 3.41,
material_costs_column => 200.0,
labor_costs_column => 300.0,
overall_costs_column => 500.0,
remaining_hours_column => 3.0,
story_points_column => 7 })
end
context 'when filtering' do
before do
query.add_filter('responsible_id', '=', [current_user.id.to_s])
end
it 'is a hash of sums grouped by done_ratio values and grouped columns' do
expect(query_results.all_group_sums)
.to eql(50 => { estimated_hours_column => 5.0,
int_cf_column => 10,
float_cf_column => 3.41,
material_costs_column => 0.0,
labor_costs_column => 0.0,
overall_costs_column => 0.0,
story_points_column => 7,
remaining_hours_column => 3.0 })
end
end
end
end
end