From f943e0639c52b1b6967a95865b1370439dce8c63 Mon Sep 17 00:00:00 2001 From: ulferts Date: Wed, 20 Jul 2016 16:16:02 +0200 Subject: [PATCH] add remainingTime and storyPoints to wp sums (#226) * add remainingTime and storyPoints to wp sums * specify the format to be used for sums rendering --- lib/open_project/backlogs/engine.rb | 37 ++++++++ ...rk_package_sums_schema_representer_spec.rb | 88 +++++++++++++++++++ .../work_package_sums_representer_spec.rb | 79 +++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 spec/api/work_packages/schema/work_package_sums_schema_representer_spec.rb create mode 100644 spec/api/work_packages/work_package_sums_representer_spec.rb diff --git a/lib/open_project/backlogs/engine.rb b/lib/open_project/backlogs/engine.rb index 479c8354b3..0ea21d2d2f 100644 --- a/lib/open_project/backlogs/engine.rb +++ b/lib/open_project/backlogs/engine.rb @@ -189,6 +189,43 @@ module OpenProject::Backlogs show_if: -> (*) { represented.project && represented.project.backlogs_enabled? } end + extend_api_response(:v3, :work_packages, :schema, :work_package_sums_schema) do + schema :story_points, + type: 'Integer', + required: false, + show_if: -> (*) { + ::Setting.work_package_list_summable_columns.include?('story_points') + } + + schema :remaining_time, + type: 'Duration', + name_source: :remaining_hours, + required: false, + writable: false, + show_if: -> (*) { + ::Setting.work_package_list_summable_columns.include?('remaining_hours') + } + end + + extend_api_response(:v3, :work_packages, :work_package_sums) do + property :story_points, + render_nil: true, + if: -> (*) { + ::Setting.work_package_list_summable_columns.include?('story_points') + } + + property :remaining_time, + render_nil: true, + exec_context: :decorator, + getter: -> (*) { + datetime_formatter.format_duration_from_hours(represented.remaining_hours, + allow_nil: true) + }, + if: -> (*) { + ::Setting.work_package_list_summable_columns.include?('remaining_hours') + } + end + add_api_attribute on: :work_package, ar_name: :story_points add_api_attribute on: :work_package, ar_name: :remaining_hours, api_name: :remaining_time do if !model.new_record? && diff --git a/spec/api/work_packages/schema/work_package_sums_schema_representer_spec.rb b/spec/api/work_packages/schema/work_package_sums_schema_representer_spec.rb new file mode 100644 index 0000000000..27539c1eac --- /dev/null +++ b/spec/api/work_packages/schema/work_package_sums_schema_representer_spec.rb @@ -0,0 +1,88 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +# +# 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-2013 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 doc/COPYRIGHT.rdoc for more details. +#++ + +require 'spec_helper' + +describe ::API::V3::WorkPackages::Schema::WorkPackageSumsSchemaRepresenter do + let(:current_user) { + FactoryGirl.build_stubbed(:user) + } + + let(:schema) { ::API::V3::WorkPackages::Schema::WorkPackageSumsSchema.new } + + let(:representer) { described_class.create(schema, current_user: current_user) } + subject { representer.to_json } + + describe 'storyPoints' do + let(:setting) { ['story_points'] } + + before do + allow(Setting) + .to receive(:work_package_list_summable_columns) + .and_return(setting) + end + + it_behaves_like 'has basic schema properties' do + let(:path) { 'storyPoints' } + let(:type) { 'Integer' } + let(:name) { I18n.t('activerecord.attributes.work_package.story_points') } + let(:required) { false } + let(:writable) { true } + end + + context 'not marked as summable' do + let(:setting) { [] } + + it 'does not show story points' do + is_expected.to_not have_json_path('storyPoints') + end + end + end + + describe 'remainingTime' do + let(:setting) { ['remaining_time'] } + + shared_examples_for 'has schema for remainingTime' do + it_behaves_like 'has basic schema properties' do + let(:path) { 'remainingTime' } + let(:type) { 'Duration' } + let(:name) { I18n.t('activerecord.attributes.work_package.remaining_hours') } + let(:required) { false } + let(:writable) { true } + end + end + + context 'not marked as summable' do + let(:setting) { [] } + + it 'does not show remaining time' do + is_expected.to_not have_json_path('remaining time') + end + end + end +end diff --git a/spec/api/work_packages/work_package_sums_representer_spec.rb b/spec/api/work_packages/work_package_sums_representer_spec.rb new file mode 100644 index 0000000000..edcc878909 --- /dev/null +++ b/spec/api/work_packages/work_package_sums_representer_spec.rb @@ -0,0 +1,79 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +# +# 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-2013 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 doc/COPYRIGHT.rdoc for more details. +#++ + +require 'spec_helper' + +describe ::API::V3::WorkPackages::WorkPackageSumsRepresenter do + let(:sums) { double 'sums', story_points: 5, remaining_hours: 10 } + let(:schema) { double 'schema', available_custom_fields: [] } + let(:representer) { + described_class.create_class(schema).new(sums) + } + let(:summable_columns) { [] } + + before do + allow(Setting) + .to receive(:work_package_list_summable_columns) + .and_return(summable_columns) + end + + subject { representer.to_json } + + context 'remainingTime' do + context 'with it being configured to be summable' do + let(:summable_columns) { ['remaining_hours'] } + + it 'is represented' do + expected = 'PT10H' + expect(subject).to be_json_eql(expected.to_json).at_path('remainingTime') + end + end + + context 'without it being configured to be summable' do + it 'is not represented when the summable setting does not list it' do + expect(subject).to_not have_json_path('remainingTime') + end + end + end + + context 'storyPoints' do + context 'with it being configured to be summable' do + let(:summable_columns) { ['story_points'] } + + it 'is represented' do + expect(subject).to be_json_eql(sums.story_points.to_json).at_path('storyPoints') + end + end + + context 'without it being configured to be summable' do + it 'is not represented when the summable setting does not list it' do + expect(subject).to_not have_json_path('storyPoints') + end + end + end +end