remove stand alone definition object

pull/7896/head
ulferts 5 years ago
parent e594f76cc6
commit 683273cef2
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 5
      modules/bcf/app/controllers/bcf/api/v2_1/project_extensions/api.rb
  2. 44
      modules/bcf/app/representers/bcf/api/v2_1/project_extensions/definitions.rb
  3. 81
      modules/bcf/app/representers/bcf/api/v2_1/project_extensions/representer.rb
  4. 4
      modules/bcf/app/representers/bcf/api/v2_1/topics/authorization_representer.rb
  5. 135
      modules/bcf/spec/representers/bcf/api/v2_1/project_extensions/definitions_spec.rb
  6. 190
      modules/bcf/spec/representers/bcf/api/v2_1/project_extensions/representer_spec.rb
  7. 1
      modules/bcf/spec/representers/bcf/api/v2_1/topics/single_representer_rendering_spec.rb
  8. 6
      modules/bcf/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb

@ -32,8 +32,9 @@ module Bcf::API::V2_1
module ProjectExtensions module ProjectExtensions
class API < ::API::OpenProjectAPI class API < ::API::OpenProjectAPI
get :extensions do get :extensions do
mapper = Definitions.new(project: @project, user: current_user) work_package = WorkPackage.new project: @project
Representer.new(mapper) contract = WorkPackages::CreateContract.new(work_package, current_user)
Representer.new(contract)
end end
end end
end end

@ -37,26 +37,34 @@ module Bcf::API::V2_1
end end
def topic_type def topic_type
contract.assignable_types.pluck(:name) with_manage_bcf do
contract.assignable_types.pluck(:name)
end
end end
## ##
# We only return the default status for now # We only return the default status for now
# since that can always be set to a new issue # since that can always be set to a new issue
def topic_status def topic_status
contract.assignable_statuses(true).pluck(:name) with_manage_bcf do
contract.assignable_statuses(true).pluck(:name)
end
end end
def priority def priority
contract.assignable_priorities.pluck(:name) with_manage_bcf do
contract.assignable_priorities.pluck(:name)
end
end end
def user_id_type def user_id_type
if allowed?(:view_members) with_manage_bcf do
# TODO: Move possible_assignees handling into wp base contract if allowed?(:view_members)
project.possible_assignees.pluck(:mail) # TODO: Move possible_assignees handling into wp base contract
else project.possible_assignees.pluck(:mail)
[] else
[]
end
end end
end end
@ -83,10 +91,8 @@ module Bcf::API::V2_1
end end
def topic_actions def topic_actions
if allowed?(:manage_bcf) with_manage_bcf do
%w[update updateRelatedTopics updateFiles createViewpoint] %w[update updateRelatedTopics updateFiles createViewpoint]
else
[]
end end
end end
@ -94,10 +100,6 @@ module Bcf::API::V2_1
[] []
end end
private
attr_reader :project, :user
def contract def contract
@contract ||= begin @contract ||= begin
work_package = WorkPackage.new project: project work_package = WorkPackage.new project: project
@ -105,6 +107,18 @@ module Bcf::API::V2_1
end end
end end
private
attr_reader :user, :project
def with_manage_bcf
if allowed?(:manage_bcf)
yield
else
[]
end
end
def allowed?(permission) def allowed?(permission)
user.allowed_to?(permission, project) user.allowed_to?(permission, project)
end end

@ -30,15 +30,76 @@
module Bcf::API::V2_1 module Bcf::API::V2_1
class ProjectExtensions::Representer < BaseRepresenter class ProjectExtensions::Representer < BaseRepresenter
property :topic_type property :topic_type,
property :topic_status getter: ->(decorator:, **) {
property :topic_label decorator.with_check do
property :snippet_type assignable_types.pluck(:name)
property :priority end
property :user_id_type }
property :stage
property :project_actions # TODO: Labels do not yet exist
property :topic_actions property :topic_label,
property :comment_actions getter: ->(*) {
[]
}
# TODO: Snippet types do not exist
property :snippet_type,
getter: ->(*) {
[]
}
property :priority,
getter: ->(decorator:, **) {
decorator.with_check do
assignable_priorities.pluck(:name)
end
}
property :user_id_type,
getter: ->(decorator:, **) {
decorator.with_check(%i[manage_bcf view_members]) do
# TODO: Move possible_assignees handling into wp base contract
model.project.possible_assignees.pluck(:mail)
end
}
# TODO: Stage do not yet exist
property :stage,
getter: ->(*) {
[]
}
property :project_actions,
getter: ->(decorator:, **) {
[].tap do |actions|
actions << 'update' if decorator.allowed?(:edit_project)
actions << 'createTopic' if decorator.allowed?(:manage_bcf)
end
}
property :comment_actions,
getter: ->(*) {
[]
}
def to_hash(*)
topic_authorization = Bcf::API::V2_1::Topics::AuthorizationRepresenter
.new(represented)
super.merge(topic_authorization.to_hash)
end
def with_check(permissions = :manage_bcf)
if Array(permissions).all? { |permission| allowed?(permission) }
yield
else
[]
end
end
def allowed?(permission)
represented.user.allowed_to?(permission, represented.model.project)
end
end end
end end

@ -42,14 +42,14 @@ module Bcf::API::V2_1
property :topic_status, property :topic_status,
getter: ->(decorator:, **) { getter: ->(decorator:, **) {
if decorator.manage_bcf_allowed? if decorator.manage_bcf_allowed?
assignable_statuses.pluck(:name) assignable_statuses(model.new_record?).pluck(:name)
else else
[] []
end end
} }
def manage_bcf_allowed? def manage_bcf_allowed?
User.current.allowed_to?(:manage_bcf, represented.model.project) represented.user.allowed_to?(:manage_bcf, represented.model.project)
end end
end end
end end

@ -1,135 +0,0 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2019 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-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'
require_relative '../shared_examples'
describe Bcf::API::V2_1::ProjectExtensions::Definitions, 'rendering' do
shared_let(:type_task) { FactoryBot.create :type_task, name: 'My BCF type' }
shared_let(:project) { FactoryBot.create(:project, types: [type_task]) }
let(:user) { FactoryBot.build_stubbed(:user) }
let(:instance) { described_class.new(project: project, user: user) }
describe '#topic_type' do
subject { instance.topic_type }
it 'returns the project type names' do
expect(subject).to eq ['My BCF type']
end
end
describe '#topic_status' do
let!(:default_status) { FactoryBot.create :default_status }
let!(:status) { FactoryBot.create :status }
subject { instance.topic_status }
it 'returns default status only' do
expect(subject).to eq [default_status.name]
end
end
describe '#priority' do
let!(:priority) { FactoryBot.create :default_priority }
subject { instance.priority }
it 'returns statuses for the available types' do
expect(subject).to eq [priority.name]
end
end
describe '#user_id_type' do
let!(:other_user) do
FactoryBot.create(:user,
member_in_project: project,
member_with_permissions: [:view_work_packages])
end
subject { instance.user_id_type }
before do
allow(user)
.to receive(:allowed_to?).with(:view_members, project)
.and_return is_permitted
end
context 'with permissions' do
let(:is_permitted) { true }
it 'returns the user as assignee' do
expect(subject).to eq [other_user.mail]
end
end
context 'with no permissions' do
let(:is_permitted) { false }
it 'returns nothing' do
expect(subject).to eq []
end
end
end
describe '#project_actions' do
subject { instance.project_actions }
it 'includes nothing if not permitted' do
allow(user).to receive(:allowed_to?).and_return false
expect(subject).to be_empty
end
it 'includes `update` if edit_project permission' do
allow(user).to receive(:allowed_to?).and_return false
allow(user).to receive(:allowed_to?).with(:edit_project, project).and_return true
expect(subject).to include 'update'
end
it 'includes `createTopic` if edit_project permission' do
allow(user).to receive(:allowed_to?).and_return false
allow(user).to receive(:allowed_to?).with(:manage_bcf, project).and_return true
expect(subject).to include 'createTopic'
end
end
describe '#topic_actions' do
subject { instance.topic_actions }
it 'includes nothing if not permitted' do
allow(user).to receive(:allowed_to?).and_return false
expect(subject).to be_empty
end
it 'includes `update` if manage_bcf permission' do
allow(user).to receive(:allowed_to?).and_return false
allow(user).to receive(:allowed_to?).with(:manage_bcf, project).and_return true
expect(subject).to match_array %w[update updateRelatedTopics updateFiles createViewpoint]
end
end
end

@ -0,0 +1,190 @@
#-- copyright
# OpenProject is a project management system.
# Copyright (C) 2012-2019 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-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'
require_relative '../shared_examples'
describe Bcf::API::V2_1::ProjectExtensions::Representer, 'rendering' do
let(:type_task) { FactoryBot.build_stubbed :type_task, name: 'My BCF type' }
let(:status) { FactoryBot.build_stubbed(:status) }
let(:user) { FactoryBot.build_stubbed(:user) }
let(:project) do
FactoryBot.build_stubbed(:project).tap do |p|
allow(p)
.to receive(:possible_assignees)
.and_return([user])
end
end
let(:work_package) { FactoryBot.build_stubbed(:stubbed_work_package, project: project) }
let(:priority) { FactoryBot.build_stubbed(:priority) }
let(:user) { FactoryBot.build_stubbed(:user) }
let(:contract) do
double('contract',
user: user,
model: work_package,
assignable_types: [type_task],
assignable_priorities: [priority],
assignable_statuses: [status])
end
let(:instance) { described_class.new(contract) }
let(:subject) { instance.to_json }
let(:permissions) { %i[manage_bcf edit_project] }
before do
allow(user)
.to receive(:allowed_to?) do |permission, context|
context == project && permissions.include?(permission)
end
end
shared_examples_for 'empty when lacking manage bcf' do
let(:permissions) { %i[edit_project] }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
describe 'attributes' do
describe 'topic_type' do
let(:path) { 'topic_type' }
it_behaves_like 'attribute' do
let(:value) { [type_task.name] }
end
it_behaves_like 'empty when lacking manage bcf'
end
describe 'topic_status' do
let(:path) { 'topic_status' }
it_behaves_like 'attribute' do
let(:value) { [status.name] }
end
it_behaves_like 'empty when lacking manage bcf'
end
describe 'topic_actions' do
let(:path) { 'topic_actions' }
it_behaves_like 'attribute' do
let(:value) { %w[update updateRelatedTopics updateFiles createViewpoint] }
end
it_behaves_like 'empty when lacking manage bcf'
end
describe 'priority' do
let(:path) { 'priority' }
it_behaves_like 'attribute' do
let(:value) { [priority.name] }
end
it_behaves_like 'empty when lacking manage bcf'
end
describe 'user_id_type' do
let(:path) { 'user_id_type' }
let(:permissions) { %i[manage_bcf view_members edit_project] }
it_behaves_like 'attribute' do
let(:value) { [user.mail] }
end
it_behaves_like 'empty when lacking manage bcf'
context 'when lacking view_members' do
let(:permissions) { %i[manage_bcf edit_project] }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
end
describe 'project_actions' do
let(:path) { 'project_actions' }
it_behaves_like 'attribute' do
let(:value) { %w(update createTopic) }
end
context 'when lacking manage_bcf' do
let(:permissions) { %i[edit_project] }
it_behaves_like 'attribute' do
let(:value) { ['update'] }
end
end
context 'when lacking edit_project' do
let(:permissions) { %i[manage_bcf] }
it_behaves_like 'attribute' do
let(:value) { ['createTopic'] }
end
end
end
describe 'topic_label' do
let(:path) { 'topic_label' }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
describe 'snippet_type' do
let(:path) { 'snippet_type' }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
describe 'stage' do
let(:path) { 'stage' }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
describe 'comment_actions' do
let(:path) { 'comment_actions' }
it_behaves_like 'attribute' do
let(:value) { [] }
end
end
end
end

@ -76,6 +76,7 @@ describe Bcf::API::V2_1::Topics::SingleRepresenter, 'rendering' do
contract = double('contract', contract = double('contract',
model: issue, model: issue,
user: current_user,
assignable_statuses: statuses) assignable_statuses: statuses)
allow(WorkPackages::UpdateContract) allow(WorkPackages::UpdateContract)

@ -56,9 +56,9 @@ describe 'BCF 2.1 project extensions resource', type: :request, content_type: :j
it_behaves_like 'bcf api successful response' do it_behaves_like 'bcf api successful response' do
let(:expected_body) do let(:expected_body) do
{ {
topic_type: [type_task.name], topic_type: [],
topic_status: [status.name], topic_status: [],
priority: [priority.name], priority: [],
snippet_type: [], snippet_type: [],
stage: [], stage: [],
topic_label: [], topic_label: [],

Loading…
Cancel
Save