Fix only work package custom_options being avaialable in API

https://community.openproject.org/wp/44281
pull/11379/head
Oliver Günther 2 years ago
parent ef34660a07
commit 0f933b8f08
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 26
      lib/api/v3/custom_options/custom_options_api.rb
  2. 2
      modules/costs/spec/lib/api/v3/time_entries/schemas/time_entry_schema_representer_spec.rb
  3. 2
      modules/costs/spec/lib/api/v3/time_entries/time_entry_representer_rendering_spec.rb
  4. 2
      modules/costs/spec/requests/api/time_entries/create_form_resource_spec.rb
  5. 2
      modules/costs/spec/requests/api/time_entries/update_form_resource_spec.rb
  6. 2
      modules/costs/spec/requests/api/time_entry_resource_spec.rb
  7. 81
      spec/factories/custom_field_factory.rb
  8. 188
      spec/requests/api/v3/custom_options/custom_options_resource_spec.rb

@ -37,12 +37,26 @@ module API
end
helpers do
def authorize_view_in_activated_project(custom_option)
def authorize_custom_option_visibility(custom_option)
case custom_option.custom_field
when WorkPackageCustomField
authorized_work_package_option(custom_option)
when ProjectCustomField
authorize_any(%i[view_project], global: true) { raise API::Errors::NotFound }
when TimeEntryCustomField
authorize_any(%i[log_time log_own_time], global: true) { raise API::Errors::NotFound }
when UserCustomField, GroupCustomField
true
else
raise API::Errors::NotFound
end
end
def authorized_work_package_option(custom_option)
allowed = Project
.allowed_to(current_user, :view_work_packages)
.joins(:work_package_custom_fields)
.where(custom_fields: { id: custom_option.custom_field_id })
.exists?
.allowed_to(current_user, :view_work_packages)
.joins(:work_package_custom_fields)
.exists?(custom_fields: { id: custom_option.custom_field_id })
unless allowed
raise API::Errors::NotFound
@ -53,7 +67,7 @@ module API
get do
co = CustomOption.find(params[:id])
authorize_view_in_activated_project(co)
authorize_custom_option_visibility(co)
CustomOptionRepresenter.new(co, current_user:)
end

@ -268,7 +268,7 @@ describe ::API::V3::TimeEntries::Schemas::TimeEntrySchemaRepresenter do
end
context 'custom value' do
let(:custom_field) { build_stubbed(:time_entry_custom_field) }
let(:custom_field) { build_stubbed(:text_time_entry_custom_field) }
let(:path) { "customField#{custom_field.id}" }
before do

@ -255,7 +255,7 @@ describe ::API::V3::TimeEntries::TimeEntryRepresenter, 'rendering' do
end
context 'custom value' do
let(:custom_field) { build_stubbed(:time_entry_custom_field) }
let(:custom_field) { build_stubbed(:text_time_entry_custom_field) }
let(:custom_value) do
CustomValue.new(custom_field:,
value: '1234',

@ -39,7 +39,7 @@ describe ::API::V3::TimeEntries::CreateFormAPI, content_type: :json do
TimeEntryActivitiesProject.insert(project_id: project.id, activity_id: tea.id, active: false)
end
end
let(:custom_field) { create(:time_entry_custom_field) }
let(:custom_field) { create(:text_time_entry_custom_field) }
let(:user) do
create(:user,
member_in_project: project,

@ -40,7 +40,7 @@ describe ::API::V3::TimeEntries::UpdateFormAPI, content_type: :json do
TimeEntryActivitiesProject.insert(project_id: project.id, activity_id: tea.id, active: false)
end
end
let(:custom_field) { create(:time_entry_custom_field) }
let(:custom_field) { create(:text_time_entry_custom_field) }
let(:user) do
create(:user,
member_in_project: project,

@ -54,7 +54,7 @@ describe 'API v3 time_entry resource', type: :request do
let(:other_project) { other_work_package.project }
let(:role) { create(:role, permissions:) }
let(:permissions) { %i(view_time_entries view_work_packages) }
let(:custom_field) { create(:time_entry_custom_field) }
let(:custom_field) { create(:text_time_entry_custom_field) }
let(:custom_value) do
CustomValue.create(custom_field:,
value: '1234',

@ -136,6 +136,47 @@ FactoryBot.define do
end
end
factory :group_custom_field, class: 'GroupCustomField' do
sequence(:name) { |n| "User Custom Field #{n}" }
type { 'GroupCustomField' }
factory :boolean_group_custom_field do
name { 'BooleanGroupCustomField' }
field_format { 'bool' }
end
factory :integer_group_custom_field do
name { 'IntegerGroupCustomField' }
field_format { 'int' }
end
factory :text_group_custom_field do
name { 'TextGroupCustomField' }
field_format { 'text' }
end
factory :string_group_custom_field do
name { 'StringGroupCustomField' }
field_format { 'string' }
end
factory :float_group_custom_field do
name { 'FloatGroupCustomField' }
field_format { 'float' }
end
factory :list_group_custom_field do
name { 'ListGroupCustomField' }
field_format { 'list' }
possible_values { ['1', '2', '3', '4', '5', '6', '7'] }
end
factory :date_group_custom_field do
name { 'DateGroupCustomField' }
field_format { 'date' }
end
end
factory :wp_custom_field, class: 'WorkPackageCustomField' do
sequence(:name) { |n| "Work package custom field #{n}" }
type { 'WorkPackageCustomField' }
@ -208,8 +249,44 @@ FactoryBot.define do
end
factory :time_entry_custom_field, class: 'TimeEntryCustomField' do
field_format { 'text' }
sequence(:name) { |n| "TimeEntryCustomField #{n}" }
sequence(:name) { |n| "User Custom Field #{n}" }
type { 'TimeEntryCustomField' }
factory :boolean_time_entry_custom_field do
name { 'BooleanTimeEntryCustomField' }
field_format { 'bool' }
end
factory :integer_time_entry_custom_field do
name { 'IntegerTimeEntryCustomField' }
field_format { 'int' }
end
factory :text_time_entry_custom_field do
name { 'TextTimeEntryCustomField' }
field_format { 'text' }
end
factory :string_time_entry_custom_field do
name { 'StringTimeEntryCustomField' }
field_format { 'string' }
end
factory :float_time_entry_custom_field do
name { 'FloatTimeEntryCustomField' }
field_format { 'float' }
end
factory :list_time_entry_custom_field do
name { 'ListTimeEntryCustomField' }
field_format { 'list' }
possible_values { ['A', 'B'] }
end
factory :date_time_entry_custom_field do
name { 'DateTimeEntryCustomField' }
field_format { 'date' }
end
end
factory :version_custom_field, class: 'VersionCustomField' do

@ -29,29 +29,19 @@
require 'spec_helper'
require 'rack/test'
describe 'API v3 Custom Options resource' do
describe 'API v3 Custom Options resource', :aggregate_failures do
include Rack::Test::Methods
include API::V3::Utilities::PathHelper
shared_let(:project) { create(:project) }
let(:user) do
create(:user,
member_in_project: project,
member_through_role: role)
end
let(:project) { create(:project) }
let(:role) { create(:role, permissions:) }
let(:permissions) { [:view_work_packages] }
let(:custom_field) do
cf = create(:list_wp_custom_field)
project.work_package_custom_fields << cf
cf
end
let(:custom_option) do
create(:custom_option,
custom_field:)
end
let(:modification) { nil }
subject(:response) { last_response }
@ -59,56 +49,178 @@ describe 'API v3 Custom Options resource' do
let(:path) { api_v3_paths.custom_option custom_option.id }
before do
modification&.call
allow(User)
.to receive(:current)
.and_return(user)
.and_return(user)
get path
end
context 'when being allowed' do
it 'is successful' do
expect(subject.status)
.to be(200)
describe 'WorkPackageCustomField' do
shared_let(:custom_field) do
cf = create(:list_wp_custom_field)
project.work_package_custom_fields << cf
cf
end
shared_let(:custom_option) do
create(:custom_option,
custom_field:)
end
context 'when being allowed' do
let(:permissions) { [:view_work_packages] }
it 'is successful' do
expect(subject.status)
.to be(200)
expect(response.body)
.to be_json_eql('CustomOption'.to_json)
.at_path('_type')
expect(response.body)
.to be_json_eql(custom_option.id.to_json)
.at_path('id')
expect(response.body)
.to be_json_eql(custom_option.value.to_json)
.at_path('value')
end
end
it 'returns the custom option' do
expect(response.body)
.to be_json_eql('CustomOption'.to_json)
.at_path('_type')
context 'when lacking permission' do
let(:permissions) { [] }
expect(response.body)
.to be_json_eql(custom_option.id.to_json)
.at_path('id')
it 'is 404' do
expect(subject.status)
.to be(404)
end
end
expect(response.body)
.to be_json_eql(custom_option.value.to_json)
.at_path('value')
context 'when custom option not in project' do
let(:permissions) { [:view_work_packages] }
let(:modification) do
-> do
project.work_package_custom_fields = []
project.save!
end
end
it 'is 404' do
expect(subject.status)
.to be(404)
end
end
end
context 'when lacking permission' do
describe 'ProjectCustomField' do
shared_let(:custom_field) { create(:list_project_custom_field) }
shared_let(:custom_option) { create(:custom_option, custom_field:) }
context 'when being allowed' do
let(:permissions) { [:view_project] }
it 'is successful' do
expect(subject.status)
.to be(200)
expect(response.body)
.to be_json_eql('CustomOption'.to_json)
.at_path('_type')
expect(response.body)
.to be_json_eql(custom_option.id.to_json)
.at_path('id')
expect(response.body)
.to be_json_eql(custom_option.value.to_json)
.at_path('value')
end
end
context 'when lacking permission' do
let(:user) { User.anonymous }
let(:permissions) { [] }
it 'is 404' do
expect(subject.status)
.to be(404)
end
end
end
describe 'TimeEntryCustomField' do
shared_let(:custom_field) { create(:list_time_entry_custom_field) }
shared_let(:custom_option) { create(:custom_option, custom_field:) }
context 'when being allowed with log_time' do
let(:permissions) { [:log_time] }
it 'is successful' do
expect(subject.status)
.to be(200)
expect(response.body)
.to be_json_eql('CustomOption'.to_json)
.at_path('_type')
expect(response.body)
.to be_json_eql(custom_option.id.to_json)
.at_path('id')
expect(response.body)
.to be_json_eql(custom_option.value.to_json)
.at_path('value')
end
end
context 'when being allowed with log_own_time' do
let(:permissions) { [:log_own_time] }
it 'is successful' do
expect(subject.status)
.to be(200)
end
end
context 'when lacking permission' do
let(:user) { User.anonymous }
let(:permissions) { [] }
it 'is 404' do
expect(subject.status)
.to be(404)
end
end
end
describe 'UserCustomField' do
shared_let(:custom_field) { create(:list_user_custom_field) }
shared_let(:custom_option) { create(:custom_option, custom_field:) }
let(:permissions) { [] }
it 'is 404' do
it 'is successful' do
expect(subject.status)
.to be(404)
.to be(200)
end
end
context 'when custom option not in project' do
let(:custom_field) do
# not added to project
create(:list_wp_custom_field)
end
describe 'GroupCustomField' do
shared_let(:custom_field) { create(:list_group_custom_field) }
shared_let(:custom_option) { create(:custom_option, custom_field:) }
let(:permissions) { [] }
it 'is 404' do
it 'is successful' do
expect(subject.status)
.to be(404)
.to be(200)
end
end
context 'when not existing' do
let(:path) { api_v3_paths.custom_option 0 }
let(:permissions) { [:view_work_packages] }
it 'is 404' do
expect(subject.status)

Loading…
Cancel
Save