replace assignable column on role

pull/10244/head
ulferts 3 years ago
parent a775e9e5d8
commit d18f60aefe
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 1
      app/contracts/roles/base_contract.rb
  2. 10
      app/models/members/scopes/assignable.rb
  3. 2
      app/models/role.rb
  4. 3
      app/views/roles/_member_attributes.html.erb
  5. 5
      app/views/roles/_permissions.html.erb
  6. 3
      config/locales/en.yml
  7. 30
      db/migrate/20220302123642_assignable_to_permission.rb
  8. 3
      frontend/src/global_styles/content/_forms.sass
  9. 3
      modules/backlogs/spec/features/impediments_spec.rb
  10. 3
      modules/backlogs/spec/features/tasks_on_taskboard_spec.rb
  11. 2
      modules/backlogs/spec/services/impediments/create_services_spec.rb
  12. 4
      modules/bim/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb
  13. 2
      modules/bim/spec/requests/api/bcf/v2_1/topics_api_spec.rb
  14. 2
      modules/boards/spec/features/action_boards/assignee_board_spec.rb
  15. 2
      modules/budgets/spec/features/budgets/add_budget_spec.rb
  16. 8
      modules/budgets/spec/features/budgets/update_budget_spec.rb
  17. 14
      modules/costs/spec/features/cost_entries/add_cost_entry_spec.rb
  18. 8
      modules/costs/spec/features/cost_entries/add_entry_without_rate_permission_spec.rb
  19. 9
      modules/my_page/spec/features/my/assigned_to_me_spec.rb
  20. 2
      modules/reporting/spec/features/update_entries_spec.rb
  21. 1
      modules/team_planner/spec/features/shared_context.rb
  22. 2
      modules/team_planner/spec/features/team_planner_user_interaction_spec.rb
  23. 1
      spec/contracts/roles/create_contract_spec.rb
  24. 1
      spec/contracts/roles/shared_contract_examples.rb
  25. 4
      spec/contracts/roles/update_contract_spec.rb
  26. 3
      spec/controllers/work_packages/bulk_controller_spec.rb
  27. 3
      spec/controllers/work_packages/moves_controller_spec.rb
  28. 8
      spec/factories/role_factory.rb
  29. 2
      spec/features/global_roles/global_role_crud_spec.rb
  30. 7
      spec/features/projects/copy_spec.rb
  31. 10
      spec/features/users/invite_user_modal/invite_user_modal_spec.rb
  32. 2
      spec/features/users/invite_user_modal/subproject_invite_spec.rb
  33. 2
      spec/features/work_packages/copy_spec.rb
  34. 2
      spec/features/work_packages/custom_actions/custom_actions_spec.rb
  35. 3
      spec/features/work_packages/edit_work_package_spec.rb
  36. 2
      spec/features/work_packages/new/attributes_from_filter_spec.rb
  37. 2
      spec/features/work_packages/new/new_work_package_spec.rb
  38. 2
      spec/features/work_packages/table/queries/me_filter_spec.rb
  39. 4
      spec/models/mail_handler_spec.rb
  40. 2
      spec/models/principals/scopes/possible_assignee_spec.rb
  41. 8
      spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb
  42. 6
      spec/requests/api/v3/work_packages/update_resource_spec.rb
  43. 5
      spec/services/members/cleanup_service_integration_spec.rb
  44. 2
      spec/services/projects/copy_service_integration_spec.rb
  45. 27
      spec/support/api/v3/shared_available_principals_examples.rb
  46. 4
      spec_legacy/fixtures/role_permissions.yml
  47. 2
      spec_legacy/unit/mail_handler_spec.rb

@ -29,7 +29,6 @@
module Roles module Roles
class BaseContract < ::ModelContract class BaseContract < ::ModelContract
attribute :name attribute :name
attribute :assignable
validate :check_permission_prerequisites validate :check_permission_prerequisites

@ -39,7 +39,15 @@ module Members::Scopes
not_locked not_locked
.includes(:roles) .includes(:roles)
.references(:roles) .references(:roles)
.where(roles: { assignable: true }) .where(assignable_permission_exists)
end
def assignable_permission_exists
RolePermission
.where('role_permissions.role_id = roles.id')
.where(permission: 'work_package_assigned')
.arel
.exists
end end
end end
end end

@ -50,7 +50,7 @@ class Role < ApplicationRecord
has_many :member_roles, dependent: :destroy has_many :member_roles, dependent: :destroy
has_many :members, through: :member_roles has_many :members, through: :member_roles
has_many :role_permissions has_many :role_permissions, dependent: :destroy
default_scope -> { default_scope -> {
includes(:role_permissions) includes(:role_permissions)

@ -27,9 +27,6 @@ See COPYRIGHT and LICENSE files for more details.
++#%> ++#%>
<div class="form--field">
<%= f.check_box :assignable %>
</div>
<% if role.new_record? && roles.any? %> <% if role.new_record? && roles.any? %>
<div class="form--field"> <div class="form--field">
<%= styled_label_tag :copy_workflow_from, t(:label_copy_workflow_from) %> <%= styled_label_tag :copy_workflow_from, t(:label_copy_workflow_from) %>

@ -51,9 +51,12 @@ See COPYRIGHT and LICENSE files for more details.
<%= styled_check_box_tag 'role[permissions][]', <%= styled_check_box_tag 'role[permissions][]',
permission.name, permission.name,
(role.permissions && role.permissions.include?(permission.name)) %> (role.permissions && role.permissions.include?(permission.name)) %>
<%= l_or_humanize(permission.name, prefix: 'permission_') %> <%= t(:"permission_#{permission.name}") %>
</label> </label>
</div> </div>
<div class="form--field-instructions -labeled-checkbox">
<%= t(:"permission_#{permission.name}_explanation", default: nil) %>
</div>
</div> </div>
<% end %> <% end %>
</div> </div>

@ -529,7 +529,6 @@ en:
repository: repository:
url: "URL" url: "URL"
role: role:
assignable: "Work packages can be assigned to users and groups in possession of this role in the respective project"
permissions: "Permissions" permissions: "Permissions"
time_entry: time_entry:
activity: "Activity" activity: "Activity"
@ -2287,6 +2286,8 @@ en:
permission_view_timelines: "View timelines" permission_view_timelines: "View timelines"
permission_view_wiki_edits: "View wiki history" permission_view_wiki_edits: "View wiki history"
permission_view_wiki_pages: "View wiki" permission_view_wiki_pages: "View wiki"
permission_work_package_assigned: "Become assignee/responsible"
permission_work_package_assigned_explanation: "Work packages can be assigned to users and groups in possession of this role in the respective project"
placeholders: placeholders:
default: "-" default: "-"

@ -0,0 +1,30 @@
class AssignableToPermission < ActiveRecord::Migration[6.1]
def up
# Because of a missing dependent: :destroy, some role_permission
# for removed roles exist.
execute <<~SQL.squish
DELETE FROM role_permissions WHERE role_id IS NULL
SQL
execute <<~SQL.squish
INSERT INTO role_permissions (role_id, permission, created_at, updated_at)
SELECT id role_id, 'work_package_assigned' permission, NOW() created_at, NOW() updated_at FROM roles
WHERE assignable AND type = 'Role' AND builtin = 0
SQL
remove_column :roles, :assignable
end
def down
add_column :roles, :assignable, :boolean, default: true
execute <<~SQL.squish
UPDATE roles
SET assignable = EXISTS(SELECT 1 from role_permissions WHERE permission = 'work_package_assigned' and role_id = roles.id)
SQL
execute <<~SQL.squish
DELETE FROM role_permissions where permission = 'work_package_assigned'
SQL
end
end

@ -484,6 +484,9 @@ fieldset.form--fieldset
&.-no-italic &.-no-italic
font-style: normal font-style: normal
&.-labeled-checkbox
margin-left: 25px
.form--inline-instructions .form--inline-instructions
font-style: italic font-style: italic
display: inline display: inline

@ -60,7 +60,8 @@ describe 'Impediments on taskboard',
view_work_packages view_work_packages
edit_work_packages edit_work_packages
manage_subtasks manage_subtasks
assign_versions)) assign_versions
work_package_assigned))
end end
let!(:current_user) do let!(:current_user) do
create(:user, create(:user,

@ -57,7 +57,8 @@ describe 'Tasks on taskboard',
view_work_packages view_work_packages
edit_work_packages edit_work_packages
manage_subtasks manage_subtasks
assign_versions)) assign_versions
work_package_assigned))
end end
let!(:current_user) do let!(:current_user) do
create(:user, create(:user,

@ -32,7 +32,7 @@ describe Impediments::CreateService do
let(:instance) { described_class.new(user: user) } let(:instance) { described_class.new(user: user) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:role) { create(:role, permissions: %i(add_work_packages assign_versions)) } let(:role) { create(:role, permissions: %i(add_work_packages assign_versions work_package_assigned)) }
let(:type_feature) { create(:type_feature) } let(:type_feature) { create(:type_feature) }
let(:type_task) { create(:type_task) } let(:type_task) { create(:type_task) }
let(:priority) { create(:priority, is_default: true) } let(:priority) { create(:priority, is_default: true) }

@ -75,13 +75,13 @@ describe 'BCF 2.1 project extensions resource', type: :request, content_type: :j
let(:current_user) do let(:current_user) do
create(:user, create(:user,
member_in_project: project, member_in_project: project,
member_with_permissions: %i[view_project edit_project manage_bcf view_members]) member_with_permissions: %i[view_project edit_project manage_bcf view_members work_package_assigned])
end end
let(:other_user) do let(:other_user) do
create(:user, create(:user,
member_in_project: project, member_in_project: project,
member_with_permissions: [:view_project]) member_with_permissions: %i[view_project work_package_assigned])
end end
before do before do

@ -38,7 +38,7 @@ describe 'BCF 2.1 topics resource', type: :request, content_type: :json, with_ma
let(:view_only_user) do let(:view_only_user) do
create(:user, create(:user,
member_in_project: project, member_in_project: project,
member_with_permissions: %i[view_linked_issues view_work_packages]) member_with_permissions: %i[view_linked_issues view_work_packages work_package_assigned])
end end
let(:only_member_user) do let(:only_member_user) do
create(:user, create(:user,

@ -51,7 +51,7 @@ describe 'Assignee action board',
let(:permissions) do let(:permissions) do
%i[show_board_views manage_board_views add_work_packages %i[show_board_views manage_board_views add_work_packages
edit_work_packages view_work_packages manage_public_queries] edit_work_packages view_work_packages manage_public_queries work_package_assigned]
end end
let!(:priority) { create :default_priority } let!(:priority) { create :default_priority }

@ -97,7 +97,7 @@ describe 'adding a new budget', type: :feature, js: true do
let(:new_budget_page) { Pages::NewBudget.new project.identifier } let(:new_budget_page) { Pages::NewBudget.new project.identifier }
let(:budget_page) { Pages::EditBudget.new Budget.last } let(:budget_page) { Pages::EditBudget.new Budget.last }
let(:project_members) { { user => create(:role) } } let(:project_members) { { user => create(:role, permissions: %i[work_package_assigned]) } }
before do before do
create :cost_rate, cost_type: cost_type, rate: 50.0 create :cost_rate, cost_type: cost_type, rate: 50.0

@ -31,15 +31,13 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb')
describe 'updating a budget', type: :feature, js: true do describe 'updating a budget', type: :feature, js: true do
let(:project) do let(:project) do
create :project_with_types, create :project_with_types,
enabled_module_names: %i[budgets costs], enabled_module_names: %i[budgets costs work_package_tracking],
members: { user => create(:role) } members: { user => create(:role, permissions: %i[work_package_assigned]) }
end end
let(:user) { create :admin } let(:user) { create :admin }
let(:budget) { create :budget, author: user, project: project } let(:budget) { create :budget, author: user, project: project }
before do current_user { user }
login_as(user)
end
describe 'with new cost items' do describe 'with new cost items' do
let(:cost_type) do let(:cost_type) do

@ -36,12 +36,14 @@ describe 'Work Package cost fields', type: :feature, js: true do
create(:project, types: [type_task]) create(:project, types: [type_task])
end end
shared_let(:role) do shared_let(:role) do
create :role, permissions: %i[view_work_packages create :role,
delete_work_packages permissions: %i[view_work_packages
log_costs delete_work_packages
view_cost_rates log_costs
edit_cost_entries view_cost_rates
view_cost_entries] edit_cost_entries
view_cost_entries
work_package_assigned]
end end
shared_let(:user) do shared_let(:user) do
create :user, create :user,

@ -36,9 +36,11 @@ describe 'Create cost entry without rate permissions', type: :feature, js: true
create(:project, types: [type_task]) create(:project, types: [type_task])
end end
shared_let(:role) do shared_let(:role) do
create :role, permissions: %i[view_work_packages create :role,
log_costs permissions: %i[view_work_packages
view_cost_entries] log_costs
view_cost_entries
work_package_assigned]
end end
shared_let(:user) do shared_let(:user) do
create :user, create :user,

@ -63,7 +63,10 @@ describe 'Assigned to me embedded query on my page', type: :feature, js: true do
create(:user) create(:user)
end end
let(:role) { create(:role, permissions: %i[view_work_packages add_work_packages edit_work_packages save_queries]) } let(:role) do
create(:role,
permissions: %i[view_work_packages add_work_packages edit_work_packages save_queries work_package_assigned])
end
let(:user) do let(:user) do
create(:user, create(:user,
@ -78,9 +81,7 @@ describe 'Assigned to me embedded query on my page', type: :feature, js: true do
let(:embedded_table) { Pages::EmbeddedWorkPackagesTable.new(assigned_area.area) } let(:embedded_table) { Pages::EmbeddedWorkPackagesTable.new(assigned_area.area) }
let(:hierarchies) { ::Components::WorkPackages::Hierarchies.new } let(:hierarchies) { ::Components::WorkPackages::Hierarchies.new }
before do current_user { user }
login_as user
end
context 'with parent work package' do context 'with parent work package' do
let!(:assigned_work_package_child) do let!(:assigned_work_package_child) do

@ -32,7 +32,7 @@ require_relative 'support/components/cost_reports_base_table'
describe 'Updating entries within the cost report', type: :feature, js: true do describe 'Updating entries within the cost report', type: :feature, js: true do
let(:project) { create :project } let(:project) { create :project }
let(:user) { create :admin } let(:user) { create :admin, member_in_project: project, member_with_permissions: %i[work_package_assigned] }
let(:work_package) { create :work_package, project: project } let(:work_package) { create :work_package, project: project }
let!(:time_entry_user) do let!(:time_entry_user) do

@ -43,6 +43,7 @@ shared_context 'with team planner full access' do
view_work_packages edit_work_packages add_work_packages view_work_packages edit_work_packages add_work_packages
view_team_planner manage_team_planner view_team_planner manage_team_planner
save_queries manage_public_queries save_queries manage_public_queries
work_package_assigned
] ]
end end

@ -43,7 +43,7 @@ describe 'Team planner drag&dop and resizing', type: :feature, js: true do
firstname: 'Bernd', firstname: 'Bernd',
member_in_project: project, member_in_project: project,
member_with_permissions: %w[ member_with_permissions: %w[
view_work_packages view_team_planner view_work_packages view_team_planner work_package_assigned
] ]
end end

@ -34,7 +34,6 @@ describe Roles::CreateContract do
let(:role) do let(:role) do
Role.new.tap do |r| Role.new.tap do |r|
r.name = role_name r.name = role_name
r.assignable = role_assignable
r.permissions = role_permissions r.permissions = role_permissions
end end
end end

@ -34,7 +34,6 @@ shared_examples_for 'roles contract' do
end end
let(:role_instance) { Role.new } let(:role_instance) { Role.new }
let(:role_name) { 'A role name' } let(:role_name) { 'A role name' }
let(:role_assignable) { true }
let(:role_permissions) { [:view_work_packages] } let(:role_permissions) { [:view_work_packages] }
def expect_valid(valid, symbols = {}) def expect_valid(valid, symbols = {})

@ -33,10 +33,8 @@ describe Roles::UpdateContract do
it_behaves_like 'roles contract' do it_behaves_like 'roles contract' do
let(:role) do let(:role) do
build_stubbed(:role, build_stubbed(:role,
name: 'Some name', name: 'Some name').tap do |r|
assignable: !role_assignable).tap do |r|
r.name = role_name r.name = role_name
r.assignable = role_assignable
r.permissions = role_permissions r.permissions = role_permissions
end end
end end

@ -58,7 +58,8 @@ describe WorkPackages::BulkController, type: :controller, with_settings: { journ
permissions: %i[edit_work_packages permissions: %i[edit_work_packages
view_work_packages view_work_packages
manage_subtasks manage_subtasks
assign_versions]) assign_versions
work_package_assigned])
end end
let(:member1_p1) do let(:member1_p1) do
create(:member, create(:member,

@ -37,7 +37,8 @@ describe WorkPackages::MovesController, type: :controller, with_settings: { jour
add_work_packages add_work_packages
edit_work_packages edit_work_packages
assign_versions assign_versions
manage_subtasks) manage_subtasks
work_package_assigned)
end end
let(:type) { create :type } let(:type) { create :type }
let(:type_2) { create :type } let(:type_2) { create :type }

@ -32,25 +32,21 @@ FactoryBot.define do
factory :role do factory :role do
permissions { [] } permissions { [] }
sequence(:name) { |n| "role_#{n}" } sequence(:name) { |n| "role_#{n}" }
assignable { true }
factory :non_member do factory :non_member do
name { 'Non member' } name { 'Non member' }
builtin { Role::BUILTIN_NON_MEMBER } builtin { Role::BUILTIN_NON_MEMBER }
assignable { false }
initialize_with { Role.where(name: name).first_or_initialize } initialize_with { Role.where(name: name).first_or_initialize }
end end
factory :anonymous_role do factory :anonymous_role do
name { 'Anonymous' } name { 'Anonymous' }
builtin { Role::BUILTIN_ANONYMOUS } builtin { Role::BUILTIN_ANONYMOUS }
assignable { false }
initialize_with { Role.where(name: name).first_or_initialize } initialize_with { Role.where(name: name).first_or_initialize }
end end
factory :existing_role do factory :existing_role do
name { 'Role ' + Digest::MD5.hexdigest(permissions.map(&:to_s).join('/'))[0..4] } name { "Role #{Digest::MD5.hexdigest(permissions.map(&:to_s).join('/'))[0..4]}" }
assignable { true }
permissions { [] } permissions { [] }
initialize_with do initialize_with do
@ -58,7 +54,7 @@ FactoryBot.define do
if Role.where(name: name).exists? if Role.where(name: name).exists?
Role.find_by(name: name) Role.find_by(name: name)
else else
Role.create name: name, assignable: assignable Role.create name: name
end end
role.add_permission!(*permissions.reject { |p| role.permissions.include?(p) }) role.add_permission!(*permissions.reject { |p| role.permissions.include?(p) })

@ -52,7 +52,7 @@ describe 'Global role: Global role CRUD', type: :feature, js: true do
# And I should see "Global group" # And I should see "Global group"
expect(page).to have_text 'GLOBAL GROUP' expect(page).to have_text 'GLOBAL GROUP'
# And I should see "Glob test" # And I should see "Glob test"
expect(page).to have_text 'Glob test' expect(page).to have_text 'Permission Glob Test'
# And I should not see "Issues can be assigned to this role" # And I should not see "Issues can be assigned to this role"
expect(page).to have_no_text 'Issues can be assigned to this role' expect(page).to have_no_text 'Issues can be assigned to this role'
# When I fill in "Name" with "Manager" # When I fill in "Name" with "Manager"

@ -76,7 +76,9 @@ describe 'Projects copy',
create(:role, create(:role,
permissions: permissions) permissions: permissions)
end end
let(:permissions) { %i(copy_projects edit_project add_subprojects manage_types view_work_packages select_custom_fields) } let(:permissions) do
%i(copy_projects edit_project add_subprojects manage_types view_work_packages select_custom_fields work_package_assigned)
end
let(:wp_user) do let(:wp_user) do
user = create(:user) user = create(:user)
@ -151,7 +153,8 @@ describe 'Projects copy',
expect(page).to have_text 'The job has been queued and will be processed shortly.' expect(page).to have_text 'The job has been queued and will be processed shortly.'
# ensure all jobs are run especially emails which might be sent later on # ensure all jobs are run especially emails which might be sent later on
while perform_enqueued_jobs > 0 do end while perform_enqueued_jobs > 0
end
copied_project = Project.find_by(name: 'Copied project') copied_project = Project.find_by(name: 'Copied project')

@ -32,7 +32,7 @@ describe 'Invite user modal', type: :feature, js: true do
shared_let(:project) { create :project } shared_let(:project) { create :project }
shared_let(:work_package) { create :work_package, project: project } shared_let(:work_package) { create :work_package, project: project }
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] }
let(:global_permissions) { %i[] } let(:global_permissions) { %i[] }
let(:modal) do let(:modal) do
::Components::Users::InviteUserModal.new project: project, ::Components::Users::InviteUserModal.new project: project,
@ -127,7 +127,7 @@ describe 'Invite user modal', type: :feature, js: true do
let(:principal) { build :invited_user } let(:principal) { build :invited_user }
context 'when the current user has permissions to create a user' do context 'when the current user has permissions to create a user' do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] }
let(:global_permissions) { %i[manage_user] } let(:global_permissions) { %i[manage_user] }
it_behaves_like 'invites the principal to the project' do it_behaves_like 'invites the principal to the project' do
@ -139,6 +139,7 @@ describe 'Invite user modal', type: :feature, js: true do
context 'when the current user does not have permissions to invite a user to the instance by email' do context 'when the current user does not have permissions to invite a user to the instance by email' do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
it 'does not show the invite user option' do it 'does not show the invite user option' do
modal.project_step modal.project_step
ngselect = modal.open_select_in_step principal.mail ngselect = modal.open_select_in_step principal.mail
@ -186,9 +187,10 @@ describe 'Invite user modal', type: :feature, js: true do
let(:principal) { build :placeholder_user, name: 'MY NEW PLACEHOLDER' } let(:principal) { build :placeholder_user, name: 'MY NEW PLACEHOLDER' }
context 'an enterprise system', with_ee: %i[placeholder_users] do context 'an enterprise system', with_ee: %i[placeholder_users] do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] }
describe 'create a new placeholder' do describe 'create a new placeholder' do
context 'with permissions to manage placeholders' do context 'with permissions to manage placeholders' do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
let(:global_permissions) { %i[manage_placeholder_user] } let(:global_permissions) { %i[manage_placeholder_user] }
it_behaves_like 'invites the principal to the project' do it_behaves_like 'invites the principal to the project' do
@ -199,7 +201,6 @@ describe 'Invite user modal', type: :feature, js: true do
end end
context 'without permissions to manage placeholders' do context 'without permissions to manage placeholders' do
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
it 'does not allow to invite a new placeholder' do it 'does not allow to invite a new placeholder' do
modal.project_step modal.project_step
@ -213,7 +214,6 @@ describe 'Invite user modal', type: :feature, js: true do
context 'with an existing placeholder' do context 'with an existing placeholder' do
let(:principal) { create :placeholder_user, name: 'EXISTING PLACEHOLDER' } let(:principal) { create :placeholder_user, name: 'EXISTING PLACEHOLDER' }
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] }
let(:global_permissions) { %i[] } let(:global_permissions) { %i[] }
it_behaves_like 'invites the principal to the project' do it_behaves_like 'invites the principal to the project' do

@ -34,7 +34,7 @@ describe 'Invite user modal subprojects', type: :feature, js: true do
shared_let(:work_package) { create :work_package, project: subproject } shared_let(:work_package) { create :work_package, project: subproject }
shared_let(:invitable_user) { create :user, firstname: 'Invitable', lastname: 'User' } shared_let(:invitable_user) { create :user, firstname: 'Invitable', lastname: 'User' }
let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] }
let(:global_permissions) { %i[] } let(:global_permissions) { %i[] }
let(:modal) do let(:modal) do
::Components::Users::InviteUserModal.new project: subproject, ::Components::Users::InviteUserModal.new project: subproject,

@ -61,7 +61,7 @@ RSpec.feature 'Work package copy', js: true, selenium: true do
type: type, type: type,
author: author) author: author)
end end
let(:role) { build(:role, permissions: [:view_work_packages]) } let(:role) { build(:role, permissions: %i[view_work_packages work_package_assigned]) }
let(:assignee) do let(:assignee) do
create(:user, create(:user,
firstname: 'An', firstname: 'An',

@ -31,7 +31,7 @@ require 'spec_helper'
describe 'Custom actions', type: :feature, js: true do describe 'Custom actions', type: :feature, js: true do
shared_let(:admin) { create :admin } shared_let(:admin) { create :admin }
let(:permissions) { %i(view_work_packages edit_work_packages move_work_packages) } let(:permissions) { %i(view_work_packages edit_work_packages move_work_packages work_package_assigned) }
let(:role) { create(:role, permissions: permissions) } let(:role) { create(:role, permissions: permissions) }
let!(:other_role) { create(:role, permissions: permissions) } let!(:other_role) { create(:role, permissions: permissions) }
let(:user) do let(:user) do

@ -17,7 +17,8 @@ describe 'edit work package', js: true do
let(:manager_role) do let(:manager_role) do
create :role, create :role,
permissions: %i[view_work_packages permissions: %i[view_work_packages
edit_work_packages] edit_work_packages
work_package_assigned]
end end
let(:manager) do let(:manager) do
create :admin, create :admin,

@ -41,7 +41,7 @@ RSpec.feature 'Work package create uses attributes from filters', js: true, sele
let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } let(:wp_table) { ::Pages::WorkPackagesTable.new(project) }
let(:split_view_create) { ::Pages::SplitWorkPackageCreate.new(project: project) } let(:split_view_create) { ::Pages::SplitWorkPackageCreate.new(project: project) }
let(:role) { create :existing_role, permissions: [:view_work_packages] } let(:role) { create :existing_role, permissions: %i[view_work_packages work_package_assigned] }
let!(:query) do let!(:query) do
build(:query, project: project, user: user).tap do |query| build(:query, project: project, user: user).tap do |query|

@ -13,7 +13,7 @@ describe 'new work package', js: true do
create(:project, types: types) create(:project, types: types)
end end
let(:permissions) { %i[view_work_packages add_work_packages edit_work_packages] } let(:permissions) { %i[view_work_packages add_work_packages edit_work_packages work_package_assigned] }
let(:user) do let(:user) do
create(:user, create(:user,
member_in_project: project, member_in_project: project,

@ -36,7 +36,7 @@ describe 'filter me value', js: true do
public: true, public: true,
members: project_members members: project_members
end end
let(:role) { create :existing_role, permissions: [:view_work_packages] } let(:role) { create :existing_role, permissions: %i[view_work_packages work_package_assigned] }
let(:admin) { create :admin } let(:admin) { create :admin }
let(:user) { create :user } let(:user) { create :user }
let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } let(:wp_table) { ::Pages::WorkPackagesTable.new(project) }

@ -47,7 +47,7 @@ describe MailHandler, type: :model do
end end
shared_context 'wp_on_given_project' do shared_context 'wp_on_given_project' do
let(:permissions) { %i[add_work_packages assign_versions] } let(:permissions) { %i[add_work_packages assign_versions work_package_assigned] }
let!(:user) do let!(:user) do
create(:user, create(:user,
mail: 'JSmith@somenet.foo', mail: 'JSmith@somenet.foo',
@ -151,7 +151,7 @@ describe MailHandler, type: :model do
end end
shared_context 'with a reply to a wp mention with attributes' do shared_context 'with a reply to a wp mention with attributes' do
let(:permissions) { %i[add_work_package_notes view_work_packages edit_work_packages] } let(:permissions) { %i[add_work_package_notes view_work_packages edit_work_packages work_package_assigned] }
let(:role) do let(:role) do
create(:role, permissions: permissions) create(:role, permissions: permissions)
end end

@ -34,7 +34,7 @@ describe Principals::Scopes::PossibleAssignee, type: :model do
let(:project) { create(:project) } let(:project) { create(:project) }
let(:other_project) { create(:project) } let(:other_project) { create(:project) }
let(:role_assignable) { true } let(:role_assignable) { true }
let(:role) { create(:role, assignable: role_assignable) } let(:role) { create(:role, permissions: (role_assignable ? [:work_package_assigned] : [])) }
let(:user_status) { :active } let(:user_status) { :active }
let!(:member_user) do let!(:member_user) do
create(:user, create(:user,

@ -404,7 +404,8 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d
let(:path) { "_embedded/payload/_links/#{property}/href" } let(:path) { "_embedded/payload/_links/#{property}/href" }
let(:visible_user) do let(:visible_user) do
create(:user, create(:user,
member_in_project: project) member_in_project: project,
member_with_permissions: [:work_package_assigned])
end end
let(:user_parameter) { { _links: { property => { href: user_link } } } } let(:user_parameter) { { _links: { property => { href: user_link } } } }
let(:params) { valid_params.merge(user_parameter) } let(:params) { valid_params.merge(user_parameter) }
@ -441,7 +442,7 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d
context 'existing group' do context 'existing group' do
let(:user_link) { api_v3_paths.group group.id } let(:user_link) { api_v3_paths.group group.id }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:role) { create(:role) } let(:role) { create(:role, permissions: %i[work_package_assigned]) }
let(:group_member) do let(:group_member) do
create(:member, create(:member,
principal: group, principal: group,
@ -458,11 +459,10 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d
context 'existing placeholder_user' do context 'existing placeholder_user' do
let(:user_link) { api_v3_paths.placeholder_user placeholder_user.id } let(:user_link) { api_v3_paths.placeholder_user placeholder_user.id }
let(:role) { create(:role) }
let(:placeholder_user) do let(:placeholder_user) do
create(:placeholder_user, create(:placeholder_user,
member_in_project: project, member_in_project: project,
member_through_role: role) member_with_permissions: %i[work_package_assigned])
end end
it_behaves_like 'valid user assignment' it_behaves_like 'valid user assignment'

@ -45,7 +45,7 @@ describe 'API v3 Work package resource',
create(:project, identifier: 'test_project', public: false) create(:project, identifier: 'test_project', public: false)
end end
let(:role) { create(:role, permissions: permissions) } let(:role) { create(:role, permissions: permissions) }
let(:permissions) { %i[view_work_packages edit_work_packages assign_versions] } let(:permissions) { %i[view_work_packages edit_work_packages assign_versions work_package_assigned] }
let(:type) { create(:type) } let(:type) { create(:type) }
current_user do current_user do
@ -442,7 +442,7 @@ describe 'API v3 Work package resource',
end end
context 'assignee and responsible' do context 'assignee and responsible' do
let(:user) { create(:user, member_in_project: project) } let(:user) { create(:user, member_in_project: project, member_with_permissions: %i[work_package_assigned]) }
let(:params) { valid_params.merge(user_parameter) } let(:params) { valid_params.merge(user_parameter) }
let(:work_package) do let(:work_package) do
create(:work_package, create(:work_package,
@ -455,7 +455,7 @@ describe 'API v3 Work package resource',
shared_context 'setup group membership' do shared_context 'setup group membership' do
let(:group) { create(:group) } let(:group) { create(:group) }
let(:group_role) { create(:role) } let(:group_role) { create(:role, permissions: %i[work_package_assigned]) }
let!(:group_member) do let!(:group_member) do
create(:member, create(:member,
principal: group, principal: group,

@ -58,7 +58,7 @@ describe Members::CleanupService, 'integration', type: :model do
create(:member, create(:member,
principal: user, principal: user,
project: project, project: project,
roles: [create(:role, assignable: true)]) roles: [create(:role, permissions: %i[work_package_assigned])])
end end
it 'keeps assigned_to to the user' do it 'keeps assigned_to to the user' do
@ -74,7 +74,8 @@ describe Members::CleanupService, 'integration', type: :model do
create(:member, create(:member,
principal: user, principal: user,
project: project, project: project,
roles: [create(:role, assignable: false)]) # Lacking work_package_assigned
roles: [create(:role, permissions: [])])
end end
it 'sets assigned_to to nil' do it 'sets assigned_to to nil' do

@ -51,7 +51,7 @@ describe Projects::CopyService, 'integration', type: :model do
member_in_project: source, member_in_project: source,
member_through_role: role) member_through_role: role)
end end
let(:role) { create :role, permissions: %i[copy_projects view_work_packages] } let(:role) { create :role, permissions: %i[copy_projects view_work_packages work_package_assigned] }
shared_let(:new_project_role) { create :role, permissions: %i[] } shared_let(:new_project_role) { create :role, permissions: %i[] }
let(:instance) do let(:instance) do
described_class.new(source: source, user: current_user) described_class.new(source: source, user: current_user)

@ -39,21 +39,23 @@ shared_examples_for 'available principals' do |principals|
let(:other_user) do let(:other_user) do
create(:user, create(:user,
member_in_project: project, member_in_project: project,
member_through_role: role) member_through_role: assignable_role)
end end
let(:role) { create(:role, permissions: permissions) } let(:role) { create(:role, permissions: permissions) }
let(:assignable_role) { create(:role, permissions: assignable_permissions) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:group) do let(:group) do
create(:group, create(:group,
member_in_project: project, member_in_project: project,
member_through_role: role) member_through_role: assignable_role)
end end
let(:placeholder_user) do let(:placeholder_user) do
create(:placeholder_user, create(:placeholder_user,
member_in_project: project, member_in_project: project,
member_through_role: role) member_through_role: assignable_role)
end end
let(:permissions) { [:view_work_packages] } let(:permissions) { [:view_work_packages] }
let(:assignable_permissions) { [:work_package_assigned] }
shared_context "request available #{principals}" do shared_context "request available #{principals}" do
before { get href } before { get href }
@ -67,13 +69,15 @@ shared_examples_for 'available principals' do |principals|
end end
describe 'users' do describe 'users' do
context 'single user' do let(:permissions) { %i[view_work_packages work_package_assigned] }
context 'for a single user' do
# The current user # The current user
it_behaves_like "returns available #{principals}", 1, 1, 'User' it_behaves_like "returns available #{principals}", 1, 1, 'User'
end end
context 'multiple users' do context 'for multiple users' do
before do before do
other_user other_user
# and the current user # and the current user
@ -81,26 +85,31 @@ shared_examples_for 'available principals' do |principals|
it_behaves_like "returns available #{principals}", 2, 2, 'User' it_behaves_like "returns available #{principals}", 2, 2, 'User'
end end
context 'if the user lacks the assignable permission' do
let(:permissions) { %i[view_work_packages] }
it_behaves_like "returns available #{principals}", 0, 0, 'User'
end
end end
describe 'groups' do describe 'groups' do
let!(:users) { [group] } let!(:users) { [group] }
# current user and group it_behaves_like "returns available #{principals}", 1, 1, 'Group'
it_behaves_like "returns available #{principals}", 2, 2, 'Group'
end end
describe 'placeholder users' do describe 'placeholder users' do
let!(:users) { [placeholder_user] } let!(:users) { [placeholder_user] }
# current user and placeholder user it_behaves_like "returns available #{principals}", 1, 1, 'PlaceholderUser'
it_behaves_like "returns available #{principals}", 2, 2, 'PlaceholderUser'
end end
end end
describe 'if not allowed' do describe 'if not allowed' do
include Rack::Test::Methods include Rack::Test::Methods
let(:permissions) { [] } let(:permissions) { [] }
before { get href } before { get href }
it_behaves_like 'unauthorized access' it_behaves_like 'unauthorized access'

@ -340,6 +340,10 @@ role_permission132:
id: 132 id: 132
role_id: 2 role_id: 2
permission: 'assign_versions' permission: 'assign_versions'
role_permission133:
id: 133
role_id: 2
permission: 'work_package_assigned'
role_permission200: role_permission200:
id: 200 id: 200

@ -114,7 +114,7 @@ describe MailHandler, type: :model do
it 'should add work package should match assignee on display name' do # added from redmine - not sure if it is ok here it 'should add work package should match assignee on display name' do # added from redmine - not sure if it is ok here
user = create(:user, firstname: 'Foo', lastname: 'Bar') user = create(:user, firstname: 'Foo', lastname: 'Bar')
role = create(:role, name: 'Superhero') role = create(:role, name: 'Superhero', permissions: ['work_package_assigned'])
create(:member, user: user, project: Project.find(2), role_ids: [role.id]) create(:member, user: user, project: Project.find(2), role_ids: [role.id])
issue = submit_email('ticket_on_given_project.eml') do |email| issue = submit_email('ticket_on_given_project.eml') do |email|
email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar') email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar')

Loading…
Cancel
Save