Allow to delete work packages via APIv3

pull/3446/head
Jan Sandbrink 9 years ago
parent 9d19f67672
commit ab9d502009
  1. 42
      doc/apiv3-documentation.apib
  2. 5
      lib/api/v3/work_packages/work_package_representer.rb
  3. 7
      lib/api/v3/work_packages/work_packages_api.rb
  4. 17
      spec/lib/api/v3/support/link_examples.rb
  5. 13
      spec/lib/api/v3/work_packages/work_package_representer_spec.rb
  6. 58
      spec/requests/api/v3/work_package_resource_spec.rb

@ -3686,6 +3686,48 @@ The value of `lockVersion` is used to implement [optimistic locking](http://en.w
}
}
## Delete Work Package [DELETE]
+ Parameters
+ id (required, integer, `1`) ... Work package id
+ Response 204 (application/hal+json)
Returned if the work package was deleted successfully.
Note that the response body is empty as of now. In future versions of the API a body
*might* be returned along with an appropriate HTTP status.
+ Body
+ Response 403 (application/hal+json)
Returned if the client does not have sufficient permissions.
**Required permission:** delete work package
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission",
"message": "You are not allowed to delete this work package."
}
+ Response 404 (application/hal+json)
Returned if the work package does not exist or the client does not have sufficient permissions to see it.
**Required permission:** view work package
+ Body
{
"_type": "Error",
"errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound",
"message": "The specified work package does not exist."
}
## Work Package Schema [/api/v3/work_packages/schemas/{identifier}]
## View Work Package Schema [GET]

@ -70,9 +70,8 @@ module API
link :delete do
{
href: work_packages_bulk_path(ids: represented),
method: :delete,
title: "Delete #{represented.subject}"
href: api_v3_paths.work_package(represented.id),
method: :delete
} if current_user_allowed_to(:delete_work_packages, context: represented.project)
end

@ -86,6 +86,13 @@ module API
end
end
delete do
authorize(:delete_work_packages, context: @work_package.project)
@work_package.destroy
status 204
end
mount ::API::V3::WorkPackages::WatchersAPI
mount ::API::V3::Relations::RelationsAPI
mount ::API::V3::Activities::ActivitiesByWorkPackageAPI

@ -28,6 +28,9 @@
require 'spec_helper'
# FIXME: deprecate this example and replace by 'has an untitled action link'
# it does not work as intended (setting user has no effect, but by chance :role overrides base spec)
# it does not check the actual href/method
shared_examples_for 'action link' do
let(:role) { FactoryGirl.create(:role, permissions: [:view_work_packages, :edit_work_packages]) }
let(:user) {
@ -49,6 +52,20 @@ shared_examples_for 'action link' do
end
end
shared_examples_for 'has an untitled action link' do
it_behaves_like 'has an untitled link'
it 'indicates the desired method' do
is_expected.to be_json_eql(method.to_json).at_path("_links/#{link}/method")
end
describe 'without permission' do
let(:permissions) { all_permissions - [permission] }
it_behaves_like 'has no link'
end
end
shared_examples_for 'has a titled link' do
it { is_expected.to be_json_eql(href.to_json).at_path("_links/#{link}/href") }
it { is_expected.to be_json_eql(title.to_json).at_path("_links/#{link}/title") }

@ -60,7 +60,8 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
:add_work_package_notes,
:add_work_packages,
:view_time_entries,
:view_changesets
:view_changesets,
:delete_work_packages
]
}
let(:permissions) { all_permissions }
@ -672,11 +673,11 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
end
describe 'delete' do
it_behaves_like 'action link' do
let(:action) { 'delete' }
let(:permission) { :delete_work_packages }
end
it_behaves_like 'has an untitled action link' do
let(:link) { 'delete' }
let(:href) { api_v3_paths.work_package(work_package.id) }
let(:method) { :delete }
let(:permission) { :delete_work_packages }
end
describe 'log_time' do

@ -72,10 +72,8 @@ h4. things we like
let(:project) do
FactoryGirl.create(:project, identifier: 'test_project', is_public: false)
end
let(:role) do
FactoryGirl.create(:role,
permissions: [:view_work_packages, :view_timelines, :edit_work_packages])
end
let(:role) { FactoryGirl.create(:role, permissions: permissions) }
let(:permissions) { [:view_work_packages, :view_timelines, :edit_work_packages] }
let(:current_user) do
FactoryGirl.create(:user, member_in_project: project, member_through_role: role)
end
@ -89,11 +87,14 @@ h4. things we like
let(:unauthorize_user) { FactoryGirl.create(:user) }
let(:type) { FactoryGirl.create(:type) }
before do
allow(User).to receive(:current).and_return current_user
end
describe '#get list' do
subject { last_response }
before(:each) do
allow(User).to receive(:current).and_return current_user
get api_v3_paths.work_packages
end
@ -914,4 +915,51 @@ h4. things we like
end
end
end
describe '#delete' do
let(:path) { api_v3_paths.work_package work_package.id }
before do
delete path
end
subject { last_response }
context 'with required permissions' do
let(:permissions) { [:view_work_packages, :delete_work_packages] }
it 'responds with HTTP No Content' do
expect(subject.status).to eq 204
end
it 'deletes the work package' do
expect(WorkPackage.exists?(work_package.id)).to be_falsey
end
context 'for a non-existent work package' do
let(:path) { api_v3_paths.work_package 1337 }
it_behaves_like 'not found' do
let(:id) { 1337 }
let(:type) { 'WorkPackage' }
end
end
end
context 'without permission to see work packages' do
let(:permissions) { [] }
it_behaves_like 'not found'
end
context 'without permission to delete work packages' do
let(:permissions) { [:view_work_packages] }
it_behaves_like 'unauthorized access'
it 'does not delete the work package' do
expect(WorkPackage.exists?(work_package.id)).to be_truthy
end
end
end
end

Loading…
Cancel
Save