From ec3a5b9da7cbc81b844ea1c73e8cf541f904b408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 28 Jul 2015 18:32:06 +0200 Subject: [PATCH] Browse revisions by work package with linked collection --- .../revisions_by_work_package_api.rb | 54 ++++++++++++++ .../revisions_collection_representer.rb | 38 ++++++++++ .../work_packages/work_package_representer.rb | 14 ---- lib/api/v3/work_packages/work_packages_api.rb | 1 + .../repositories/revision_representer_spec.rb | 3 +- .../work_package_representer_spec.rb | 22 ------ ...revisions_by_work_package_resource_spec.rb | 72 +++++++++++++++++++ .../revisions_resource_spec.rb | 13 ++-- 8 files changed, 173 insertions(+), 44 deletions(-) create mode 100644 lib/api/v3/repositories/revisions_by_work_package_api.rb create mode 100644 lib/api/v3/repositories/revisions_collection_representer.rb create mode 100644 spec/requests/api/v3/repositories/revisions_by_work_package_resource_spec.rb rename spec/requests/api/v3/{ => repositories}/revisions_resource_spec.rb (98%) diff --git a/lib/api/v3/repositories/revisions_by_work_package_api.rb b/lib/api/v3/repositories/revisions_by_work_package_api.rb new file mode 100644 index 0000000000..4a236634c0 --- /dev/null +++ b/lib/api/v3/repositories/revisions_by_work_package_api.rb @@ -0,0 +1,54 @@ +#-- 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 'api/v3/repositories/revisions_collection_representer' + +module API + module V3 + module Repositories + class RevisionsByWorkPackageAPI < ::API::OpenProjectAPI + resources :revisions do + before do + authorize(:view_changesets, context: work_package.project) do + raise API::Errors::NotFound.new + end + end + + get do + self_path = api_v3_paths.attachments_by_work_package(work_package.id) + + revisions = work_package.changesets + RevisionsCollectionRepresenter.new(revisions, + revisions.count, + self_path) + end + end + end + end + end +end diff --git a/lib/api/v3/repositories/revisions_collection_representer.rb b/lib/api/v3/repositories/revisions_collection_representer.rb new file mode 100644 index 0000000000..104d0bc8c4 --- /dev/null +++ b/lib/api/v3/repositories/revisions_collection_representer.rb @@ -0,0 +1,38 @@ +#-- encoding: UTF-8 +#-- 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. +#++ + +module API + module V3 + module Repositories + class RevisionsCollectionRepresenter < ::API::Decorators::Collection + element_decorator ::API::V3::Repositories::RevisionRepresenter + end + end + end +end diff --git a/lib/api/v3/work_packages/work_package_representer.rb b/lib/api/v3/work_packages/work_package_representer.rb index 92c3511bb2..1dfe3282ea 100644 --- a/lib/api/v3/work_packages/work_package_representer.rb +++ b/lib/api/v3/work_packages/work_package_representer.rb @@ -290,14 +290,6 @@ module API property :activities, embedded: true, exec_context: :decorator - property :revisions, - embedded: true, - exec_context: :decorator, - if: -> (*) { - current_user_allowed_to(:view_changesets, - context: represented.project) - } - property :version, embedded: true, exec_context: :decorator, @@ -326,12 +318,6 @@ module API end end - def revisions - represented.changesets.map do |revision| - ::API::V3::Repositories::RevisionRepresenter.new(revision, current_user: current_user) - end - end - def watchers # TODO/LEGACY: why do we need to ensure a specific order here? watchers = represented.watcher_users.order(User::USER_FORMATS_STRUCTURE[Setting.user_format]) diff --git a/lib/api/v3/work_packages/work_packages_api.rb b/lib/api/v3/work_packages/work_packages_api.rb index 1c3a13a2f1..d7aba29af4 100644 --- a/lib/api/v3/work_packages/work_packages_api.rb +++ b/lib/api/v3/work_packages/work_packages_api.rb @@ -109,6 +109,7 @@ module API mount ::API::V3::WorkPackages::WatchersAPI mount ::API::V3::Relations::RelationsAPI mount ::API::V3::Attachments::AttachmentsByWorkPackageAPI + mount ::API::V3::Repositories::RevisionsByWorkPackageAPI mount ::API::V3::WorkPackages::UpdateFormAPI end diff --git a/spec/lib/api/v3/repositories/revision_representer_spec.rb b/spec/lib/api/v3/repositories/revision_representer_spec.rb index f5ee2fb001..6f5780cd9b 100644 --- a/spec/lib/api/v3/repositories/revision_representer_spec.rb +++ b/spec/lib/api/v3/repositories/revision_representer_spec.rb @@ -34,7 +34,7 @@ describe ::API::V3::Repositories::RevisionRepresenter do let(:representer) { described_class.new(revision) } let(:project) { FactoryGirl.build :project } - let(:repository) { FactoryGirl.build :repository_subversion, project: project} + let(:repository) { FactoryGirl.build :repository_subversion, project: project } let(:revision) { FactoryGirl.build(:changeset, id: 42, @@ -80,7 +80,6 @@ describe ::API::V3::Repositories::RevisionRepresenter do end end - context 'with referencing commit message' do let(:work_package) { FactoryGirl.build_stubbed(:work_package, project: project) } let(:commit_message) { "Totally references ##{work_package.id}" } diff --git a/spec/lib/api/v3/work_packages/work_package_representer_spec.rb b/spec/lib/api/v3/work_packages/work_package_representer_spec.rb index 26f9b05e2a..c1a6924f54 100644 --- a/spec/lib/api/v3/work_packages/work_package_representer_spec.rb +++ b/spec/lib/api/v3/work_packages/work_package_representer_spec.rb @@ -738,28 +738,6 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do it { is_expected.to have_json_type(Array).at_path('_embedded/activities') } it { is_expected.to have_json_size(0).at_path('_embedded/activities') } end - - describe 'linked revisions' do - context 'when no revisions available' do - it 'contains an empty linked property revisions' do - expect(subject).to have_json_size(0).at_path('_embedded/revisions') - end - end - - context 'when revisions available' do - let(:repository) { FactoryGirl.build(:repository_subversion) } - let(:rev1) { FactoryGirl.build(:changeset, repository: repository) } - let(:rev2) { FactoryGirl.build(:changeset, repository: repository) } - - before do - allow(work_package).to receive(:changesets).and_return([rev1, rev2]) - end - - it 'contains the linked revision' do - expect(subject).to have_json_size(2).at_path('_embedded/revisions') - end - end - end end end end diff --git a/spec/requests/api/v3/repositories/revisions_by_work_package_resource_spec.rb b/spec/requests/api/v3/repositories/revisions_by_work_package_resource_spec.rb new file mode 100644 index 0000000000..31b6e3b78c --- /dev/null +++ b/spec/requests/api/v3/repositories/revisions_by_work_package_resource_spec.rb @@ -0,0 +1,72 @@ +#-- 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' +require 'rack/test' + +describe 'API v3 Revisions by work package resource', type: :request do + include Rack::Test::Methods + include API::V3::Utilities::PathHelper + include FileHelpers + + let(:current_user) { + FactoryGirl.create(:user, + member_in_project: project, + member_through_role: role) + } + let(:project) { FactoryGirl.create(:project, is_public: false) } + let(:role) { FactoryGirl.create(:role, permissions: permissions) } + let(:permissions) { [:view_work_packages, :view_changesets] } + let(:repository) { FactoryGirl.create(:repository_subversion, project: project) } + let(:work_package) { FactoryGirl.create(:work_package, author: current_user, project: project) } + + subject(:response) { last_response } + + before do + allow(User).to receive(:current).and_return current_user + FactoryGirl.create_list(:changeset, + 5, + comments: "This commit references ##{work_package.id}", + repository: repository + ) + end + + describe '#get' do + let(:get_path) { api_v3_paths.work_package_revisions work_package.id } + + before do + get get_path + end + + it 'should respond with 200' do + expect(subject.status).to eq(200) + end + + it_behaves_like 'API V3 collection response', 5, 5, 'Revision' + end +end diff --git a/spec/requests/api/v3/revisions_resource_spec.rb b/spec/requests/api/v3/repositories/revisions_resource_spec.rb similarity index 98% rename from spec/requests/api/v3/revisions_resource_spec.rb rename to spec/requests/api/v3/repositories/revisions_resource_spec.rb index 986ed12c3b..3692ccafa0 100644 --- a/spec/requests/api/v3/revisions_resource_spec.rb +++ b/spec/requests/api/v3/repositories/revisions_resource_spec.rb @@ -44,16 +44,17 @@ describe 'API v3 Revisions resource', type: :request do let(:repository) { FactoryGirl.create(:repository_subversion, project: project) } - let(:project) do + let(:project) { FactoryGirl.create(:project, identifier: 'test_project', is_public: false) - end - let(:role) do + } + let(:role) { FactoryGirl.create(:role, permissions: [:view_changesets]) - end - let(:current_user) do + } + let(:current_user) { FactoryGirl.create(:user, member_in_project: project, member_through_role: role) - end + } + let(:unauthorized_user) { FactoryGirl.create(:user) } describe '#get' do