Merge pull request #3445 from NobodysNightmare/feature/attachment_links

Improve Attachment links
pull/3446/head
Oliver Günther 9 years ago
commit 9d19f67672
  1. 6
      doc/apiv3-documentation.apib
  2. 8
      lib/api/v3/attachments/attachment_representer.rb
  3. 8
      lib/api/v3/work_packages/work_package_representer.rb
  4. 35
      spec/lib/api/v3/attachments/attachment_representer_spec.rb
  5. 159
      spec/lib/api/v3/work_packages/work_package_representer_spec.rb

@ -714,6 +714,12 @@ Updates an activity's comment and, on success, returns the updated activity.
Attachments are files that were uploaded to OpenProject. Each attachment belongs to a single
container (e.g. a work package or a board message).
## Actions
| Link | Description | Condition |
|:-------------------:|----------------------------------------------------------------------| -------------------------------------------- |
| delete | Deletes this attachment | **Permission**: edit on attachment container |
## Linked Properties
| Link | Description | Type | Constraints | Supported operations |
|:----------------:| --------------------------------------------------- | ------------- | ----------- | -------------------- |

@ -50,6 +50,14 @@ module API
}
end
# visibility of this link is also work_package specific!
link :delete do
{
href: api_v3_paths.attachment(represented.id),
method: :delete
} if current_user_allowed_to(:edit_work_packages, context: represented.container.project)
end
property :id
property :file_name,
getter: -> (*) { filename }

@ -51,8 +51,7 @@ module API
link :update do
{
href: api_v3_paths.work_package_form(represented.id),
method: :post,
title: "Update #{represented.subject}"
method: :post
} if current_user_allowed_to(:edit_work_packages, context: represented.project)
end
@ -65,8 +64,7 @@ module API
link :updateImmediately do
{
href: api_v3_paths.work_package(represented.id),
method: :patch,
title: "Update #{represented.subject}"
method: :patch
} if current_user_allowed_to(:edit_work_packages, context: represented.project)
end
@ -125,7 +123,7 @@ module API
{
href: api_v3_paths.attachments_by_work_package(represented.id),
method: :post
}
} if current_user_allowed_to(:edit_work_packages, context: represented.project)
end
link :availableWatchers do

@ -31,8 +31,20 @@ require 'spec_helper'
describe ::API::V3::Attachments::AttachmentRepresenter do
include API::V3::Utilities::PathHelper
let(:attachment) { FactoryGirl.create(:attachment) }
let(:representer) { ::API::V3::Attachments::AttachmentRepresenter.new(attachment) }
let(:current_user) {
FactoryGirl.create(:user, member_in_project: project, member_through_role: role)
}
let(:project) { FactoryGirl.create(:project) }
let(:role) { FactoryGirl.create(:role, permissions: permissions) }
let(:all_permissions) { [:view_work_packages, :edit_work_packages] }
let(:permissions) { all_permissions }
let(:container) { FactoryGirl.create(:work_package, project: project) }
let(:attachment) { FactoryGirl.create(:attachment, container: container) }
let(:representer) {
::API::V3::Attachments::AttachmentRepresenter.new(attachment, current_user: current_user)
}
subject { representer.to_json }
@ -76,5 +88,24 @@ describe ::API::V3::Attachments::AttachmentRepresenter do
let(:href) { api_v3_paths.user(attachment.author.id) }
let(:title) { attachment.author.name }
end
describe 'delete link' do
it_behaves_like 'has an untitled link' do
let(:link) { 'delete' }
let(:href) { api_v3_paths.attachment(attachment.id) }
end
it 'has the DELETE method' do
is_expected.to be_json_eql('delete'.to_json).at_path('_links/delete/method')
end
context 'user is not allowed to edit the container' do
let(:permissions) { all_permissions - [:edit_work_packages] }
it_behaves_like 'has no link' do
let(:link) { 'delete' }
end
end
end
end
end

@ -49,7 +49,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
estimated_hours: 6.0)
}
let(:project) { work_package.project }
let(:permissions) {
let(:all_permissions) {
[
:view_work_packages,
:view_work_package_watchers,
@ -57,9 +57,13 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
:add_work_package_watchers,
:delete_work_package_watchers,
:manage_work_package_relations,
:add_work_package_notes
:add_work_package_notes,
:add_work_packages,
:view_time_entries,
:view_changesets
]
}
let(:permissions) { all_permissions }
let(:role) { FactoryGirl.create :role, permissions: permissions }
before(:each) do
@ -150,31 +154,9 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
describe 'spentTime' do
before do permissions << :view_time_entries end
describe '#content' do
let(:wp) { FactoryGirl.create(:work_package) }
let(:permissions) { [:view_work_packages, :view_time_entries] }
let(:role) { FactoryGirl.create(:role, permissions: permissions) }
let(:user) {
FactoryGirl.create(:user,
member_in_project: wp.project,
member_through_role: role)
}
let(:representer) { described_class.new(wp, current_user: user) }
before do
allow(User).to receive(:current).and_return(user)
allow(user).to receive(:allowed_to?).and_return(false)
allow(user).to receive(:allowed_to?).with(:view_time_entries, anything).and_return(true)
end
context 'no view_time_entries permission' do
before do
allow(user).to receive(:allowed_to?).with(:view_time_entries, anything)
.and_return(false)
end
let(:permissions) { all_permissions - [:view_time_entries] }
it { is_expected.not_to have_json_path('spentTime') }
end
@ -184,27 +166,23 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'time entry with single hour' do
let(:time_entry) {
before do
FactoryGirl.create(:time_entry,
project: wp.project,
work_package: wp,
project: work_package.project,
work_package: work_package,
hours: 1.0)
}
before do time_entry end
end
it { is_expected.to be_json_eql('PT1H'.to_json).at_path('spentTime') }
end
context 'time entry with multiple hours' do
let(:time_entry) {
before do
FactoryGirl.create(:time_entry,
project: wp.project,
work_package: wp,
project: work_package.project,
work_package: work_package,
hours: 42.5)
}
before do time_entry end
end
it { is_expected.to be_json_eql('P1DT18H30M'.to_json).at_path('spentTime') }
end
@ -242,24 +220,37 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
describe 'update links' do
describe 'update by form' do
it { expect(subject).to have_json_path('_links/update/href') }
it {
expect(subject).to be_json_eql("/api/v3/work_packages/#{work_package.id}/form".to_json)
.at_path('_links/update/href')
}
it { expect(subject).to be_json_eql('post'.to_json).at_path('_links/update/method') }
it_behaves_like 'has an untitled link' do
let(:link) { 'update' }
let(:href) { api_v3_paths.work_package_form(work_package.id) }
end
it 'is a post link' do
is_expected.to be_json_eql('post'.to_json).at_path('_links/update/method')
end
end
describe 'immediate update' do
it { expect(subject).to have_json_path('_links/updateImmediately/href') }
it {
expect(subject).to be_json_eql("/api/v3/work_packages/#{work_package.id}".to_json)
.at_path('_links/updateImmediately/href')
}
it {
expect(subject).to be_json_eql('patch'.to_json)
.at_path('_links/updateImmediately/method')
}
it_behaves_like 'has an untitled link' do
let(:link) { 'updateImmediately' }
let(:href) { api_v3_paths.work_package(work_package.id) }
end
it 'is a patch link' do
is_expected.to be_json_eql('patch'.to_json).at_path('_links/updateImmediately/method')
end
end
context 'user is not allowed to edit work packages' do
let(:permissions) { all_permissions - [:edit_work_packages] }
it_behaves_like 'has no link' do
let(:link) { 'update' }
end
it_behaves_like 'has no link' do
let(:link) { 'updateImmediately' }
end
end
end
@ -328,21 +319,17 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
describe 'revisions' do
context 'when the user lacks the view_changesets permission' do
it_behaves_like 'has no link' do
let(:link) { 'revisions' }
end
it_behaves_like 'has an untitled link' do
let(:link) { 'revisions' }
let(:href) {
api_v3_paths.work_package_revisions(work_package.id)
}
end
context 'when the user has the required permission' do
let(:revision_permissions) { [:view_changesets] }
let(:role) { FactoryGirl.create :role, permissions: permissions + revision_permissions }
it_behaves_like 'has an untitled link' do
context 'when the user lacks the view_changesets permission' do
let(:permissions) { all_permissions - [:view_changesets] }
it_behaves_like 'has no link' do
let(:link) { 'revisions' }
let(:href) {
api_v3_paths.work_package_revisions(work_package.id)
}
end
end
end
@ -466,6 +453,14 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
it 'addAttachments is a post link' do
is_expected.to be_json_eql('post'.to_json).at_path('_links/addAttachment/method')
end
context 'user is not allowed to edit work packages' do
let(:permissions) { all_permissions - [:edit_work_packages] }
it_behaves_like 'has no link' do
let(:link) { 'addAttachment' }
end
end
end
context 'when the user is not watching the work package' do
@ -503,9 +498,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user does not have the permission to add comments' do
before do
role.permissions.delete(:add_work_package_notes) and role.save
end
let(:permissions) { all_permissions - [:add_work_package_notes] }
it 'should not have a link to add comment' do
expect(subject).not_to have_json_path('_links/addComment/href')
@ -527,9 +520,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user does not have the permission to add watchers' do
before do
role.permissions.delete(:add_work_package_watchers) and role.save
end
let(:permissions) { all_permissions - [:add_work_package_watchers] }
it 'should not have a link to add watcher' do
expect(subject).not_to have_json_path('_links/addWatcher/href')
@ -537,9 +528,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user does not have the permission to remove watchers' do
before do
role.permissions.delete(:delete_work_package_watchers) and role.save
end
let(:permissions) { all_permissions - [:delete_work_package_watchers] }
it 'should not have a link to remove watcher' do
expect(subject).not_to have_json_path('_links/removeWatcher/href')
@ -559,9 +548,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user is not allowed to see watchers' do
before do
role.permissions.delete(:view_work_package_watchers) and role.save
end
let(:permissions) { all_permissions - [:view_work_package_watchers] }
it_behaves_like 'has no link' do
let(:link) { 'watchers' }
@ -576,9 +563,7 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user does not have the permission to manage relations' do
before do
role.permissions.delete(:manage_work_package_relations) and role.save
end
let(:permissions) { all_permissions - [:manage_work_package_relations] }
it 'should not have a link to add relation' do
expect(subject).not_to have_json_path('_links/addRelation/href')
@ -586,36 +571,28 @@ describe ::API::V3::WorkPackages::WorkPackageRepresenter do
end
context 'when the user has the permission to add work packages' do
before do
role.permissions.push(:add_work_packages) and role.save
end
it 'should have a link to add child' do
expect(subject).to have_json_path('_links/addChild/href')
end
end
context 'when the user does not have the permission to add work packages' do
before do
role.permissions.delete(:add_work_packages) and role.save
end
let(:permissions) { all_permissions - [:add_work_packages] }
it 'should not have a link to add child' do
expect(subject).not_to have_json_path('_links/addChild/href')
end
end
context 'when the user has the permission to view time entries' do
before do
role.permissions.push(:view_time_entries) and role.save
end
it 'should have a link to add child' do
expect(subject).to have_json_path('_links/timeEntries/href')
end
end
context 'when the user does not have the permission to view time entries' do
before do
role.permissions.delete(:view_time_entries) and role.save
end
let(:permissions) { all_permissions - [:view_time_entries] }
it 'should not have a link to timeEntries' do
expect(subject).not_to have_json_path('_links/timeEntries/href')
end

Loading…
Cancel
Save