diff --git a/app/contracts/members/base_contract.rb b/app/contracts/members/base_contract.rb index 107a7090895..b316d291842 100644 --- a/app/contracts/members/base_contract.rb +++ b/app/contracts/members/base_contract.rb @@ -28,10 +28,6 @@ module Members class BaseContract < ::ModelContract - def self.model - Member - end - delegate :principal, :project, :new_record?, diff --git a/app/contracts/model_contract.rb b/app/contracts/model_contract.rb index 3b5202a37fe..60b099666ec 100644 --- a/app/contracts/model_contract.rb +++ b/app/contracts/model_contract.rb @@ -141,7 +141,7 @@ class ModelContract < Reform::Contract end def self.model - raise NotImplementedError + @model ||= name.deconstantize.singularize.constantize end # use activerecord as the base scope instead of 'activemodel' to be compatible diff --git a/app/contracts/roles/base_contract.rb b/app/contracts/roles/base_contract.rb new file mode 100644 index 00000000000..e654cc8b8fe --- /dev/null +++ b/app/contracts/roles/base_contract.rb @@ -0,0 +1,64 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2017 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 doc/COPYRIGHT.rdoc for more details. +#++ + +module Roles + class BaseContract < ::ModelContract + attribute :name + attribute :assignable + + def assignable_permissions + if model.is_a?(GlobalRole) + assignable_global_permissions + else + assignable_member_permissions + end + end + + private + + def assignable_member_permissions + permissions_to_remove = case model.builtin + when Role::BUILTIN_NON_MEMBER + [Redmine::AccessControl.members_only_permissions] + when Role::BUILTIN_ANONYMOUS + [Redmine::AccessControl.loggedin_only_permissions] + else + [] + end + + Redmine::AccessControl.permissions - + Redmine::AccessControl.public_permissions - + Redmine::AccessControl.global_permissions - + permissions_to_remove + end + + def assignable_global_permissions + Redmine::AccessControl.global_permissions + end + end +end diff --git a/app/contracts/roles/create_contract.rb b/app/contracts/roles/create_contract.rb new file mode 100644 index 00000000000..ed237c8dee8 --- /dev/null +++ b/app/contracts/roles/create_contract.rb @@ -0,0 +1,47 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2017 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 doc/COPYRIGHT.rdoc for more details. +#++ + +module Roles + class CreateContract < BaseContract + attribute :type + + def validate + type_in_allowed + + super + end + + private + + def type_in_allowed + unless [Role.name, GlobalRole.name].include?(model.type) + errors.add(:type, :inclusion) + end + end + end +end diff --git a/app/contracts/roles/update_contract.rb b/app/contracts/roles/update_contract.rb new file mode 100644 index 00000000000..3c39f8ef368 --- /dev/null +++ b/app/contracts/roles/update_contract.rb @@ -0,0 +1,32 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2017 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 doc/COPYRIGHT.rdoc for more details. +#++ + +module Roles + class UpdateContract < BaseContract + end +end diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 6a9dc8b9a2b..82a933f3137 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -29,42 +29,35 @@ class RolesController < ApplicationController include PaginationHelper + include Roles::NotifyMixin layout 'admin' before_action :require_admin, except: [:autocomplete_for_role] def index - @roles = Role - .order(Arel.sql('builtin, position')) - .page(page_param) - .per_page(per_page_param) + @roles = roles_scope + .page(page_param) + .per_page(per_page_param) render action: 'index', layout: false if request.xhr? end def new - # Prefills the form with 'Non member' role permissions - @role = Role.new(permitted_params.role? || {permissions: Role.non_member.permissions}) + @role = Role.new(permitted_params.role? || { permissions: Role.non_member.permissions }) - define_setable_permissions - - @roles = Role.order(Arel.sql('builtin, position')) + @roles = roles_scope end def create - @role = Role.new(permitted_params.role? || {permissions: Role.non_member.permissions}) - if @role.save - # workflow copy - if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by(id: params[:copy_workflow_from])) - @role.workflows.copy_from_role(copy_from) - end - flash[:notice] = l(:notice_successful_create) + @call = create_role + @role = @call.result + + if @call.success? + flash[:notice] = t(:notice_successful_create) redirect_to action: 'index' - notify_changed_roles(:added, @role) else - define_setable_permissions - @roles = Role.order(Arel.sql('builtin, position')) + @roles = roles_scope render action: 'new' end @@ -72,18 +65,17 @@ class RolesController < ApplicationController def edit @role = Role.find(params[:id]) - define_setable_permissions + @call = set_role_attributes(@role, 'update') end def update @role = Role.find(params[:id]) + @call = update_role(@role, permitted_params.role) - if @role.update_attributes(permitted_params.role) + if @call.success? flash[:notice] = l(:notice_successful_update) redirect_to action: 'index' - notify_changed_roles(:updated, @role) else - @permissions = @role.setable_permissions render action: 'edit' end end @@ -101,21 +93,20 @@ class RolesController < ApplicationController def report @roles = Role.order(Arel.sql('builtin, position')) - @permissions = Redmine::AccessControl.permissions.select {|p| !p.public?} + @permissions = Redmine::AccessControl.permissions.reject(&:public?) end def bulk_update - @roles = Role.order(Arel.sql('builtin, position')) + @roles = roles_scope @roles.each do |role| - new_permissions = params[:permissions][role.id.to_s].presence || [] - role.permissions = new_permissions - role.save + new_permissions = { permissions: params[:permissions][role.id.to_s].presence || [] } + + update_role(role, new_permissions) end flash[:notice] = l(:notice_successful_update) redirect_to action: 'index' - notify_changed_roles(:bulk_update, @roles) end def autocomplete_for_role @@ -134,11 +125,29 @@ class RolesController < ApplicationController private - def notify_changed_roles(action, changed_role) - OpenProject::Notifications.send(:roles_changed, action: action, role: changed_role) + def set_role_attributes(role, create_or_update) + contract = "Roles::#{create_or_update.camelize}Contract".constantize + + Roles::SetAttributesService + .new(user: current_user, model: role, contract_class: contract) + .call(new_params) end - protected + def update_role(role, params) + Roles::UpdateService + .new(user: current_user, model: role) + .call(params) + end + + def create_role + Roles::CreateService + .new(user: current_user) + .call(create_params) + end + + def roles_scope + Role.order(Arel.sql('builtin, position')) + end def default_breadcrumb if action_name == 'index' @@ -152,17 +161,13 @@ class RolesController < ApplicationController true end - def define_setable_permissions - @permissions = group_permissions_by_module(@role.setable_permissions) + def new_params + permitted_params.role? || {} end - def group_permissions_by_module(perms) - perms_by_module = perms.group_by {|p| p.project_module.to_s} - ::Redmine::AccessControl - .sorted_modules - .select {|module_name| perms_by_module[module_name].present?} - .map do |module_name| - [module_name, perms_by_module[module_name]] - end + def create_params + new_params + .merge(copy_workflow_from: params[:copy_workflow_from], + global_role: params[:global_role]) end end diff --git a/app/helpers/roles_helper.rb b/app/helpers/roles_helper.rb index f89612d1aee..da4278a4681 100644 --- a/app/helpers/roles_helper.rb +++ b/app/helpers/roles_helper.rb @@ -28,4 +28,27 @@ #++ module RolesHelper + def setable_permissions(role) + # Use the base contract for now as we are only interested in the setable permissions + # which do not differentiate. + contract = Roles::BaseContract.new(role, current_user) + + contract.assignable_permissions + end + + def grouped_setable_permissions(role) + group_permissions_by_module(setable_permissions(role)) + end + + private + + def group_permissions_by_module(perms) + perms_by_module = perms.group_by { |p| p.project_module.to_s } + ::Redmine::AccessControl + .sorted_modules + .select { |module_name| perms_by_module[module_name].present? } + .map do |module_name| + [module_name, perms_by_module[module_name]] + end + end end diff --git a/app/models/role.rb b/app/models/role.rb index 46716423656..f8548c17995 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -63,7 +63,9 @@ class Role < ActiveRecord::Base validates_length_of :name, maximum: 30 def self.givable - where(builtin: NON_BUILTIN).order(Arel.sql('position')) + where(builtin: NON_BUILTIN) + .where(type: 'Role') + .order(Arel.sql('position')) end def permissions @@ -132,14 +134,6 @@ class Role < ActiveRecord::Base end end - # Return all the permissions that can be given to the role - def setable_permissions - setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions - setable_permissions -= Redmine::AccessControl.members_only_permissions if builtin == BUILTIN_NON_MEMBER - setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if builtin == BUILTIN_ANONYMOUS - setable_permissions - end - # Return the builtin 'non member' role. If the role doesn't exist, # it will be created on the fly. def self.non_member diff --git a/app/seeders/basic_data/role_seeder.rb b/app/seeders/basic_data/role_seeder.rb index 74327693e8b..1015e05a8e6 100644 --- a/app/seeders/basic_data/role_seeder.rb +++ b/app/seeders/basic_data/role_seeder.rb @@ -141,7 +141,11 @@ module BasicData end def project_admin - { name: I18n.t(:default_role_project_admin), position: 5, permissions: Role.new.setable_permissions.map(&:name) } + { + name: I18n.t(:default_role_project_admin), + position: 5, + permissions: Roles::CreateContract.new(Role.new, nil).assignable_permissions.map(&:name) + } end def non_member diff --git a/app/services/base_services/create.rb b/app/services/base_services/create.rb index 02f40ca9906..01d19485203 100644 --- a/app/services/base_services/create.rb +++ b/app/services/base_services/create.rb @@ -65,16 +65,16 @@ module BaseServices def set_attributes(params) attributes_service_class .new(user: user, - model: new_instance, + model: new_instance(params), contract_class: contract_class) .call(params) end - def after_save(attributes_call) + def after_save(_attributes_call) # nothing for now but subclasses can override end - def new_instance + def new_instance(_params) instance_class.new end diff --git a/app/services/roles/create_service.rb b/app/services/roles/create_service.rb new file mode 100644 index 00000000000..b54f2fcba67 --- /dev/null +++ b/app/services/roles/create_service.rb @@ -0,0 +1,63 @@ +#-- encoding: UTF-8 + +#-- 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 doc/COPYRIGHT.rdoc for more details. +#++ + +class Roles::CreateService < ::BaseServices::Create + include Roles::NotifyMixin + + private + + def create(params) + copy_workflow_id = params.delete(:copy_workflow_from) + + super_call = super + + if super_call.success? + copy_workflows(copy_workflow_id, super_call.result) + + notify_changed_roles(:added, super_call.result) + end + + super_call + end + + def new_instance(params) + if params.delete(:global_role) + GlobalRole.new + else + super + end + end + + def copy_workflows(copy_workflow_id, role) + if copy_workflow_id.present? && (copy_from = Role.find_by(id: copy_workflow_id)) + role.workflows.copy_from_role(copy_from) + end + end +end diff --git a/app/services/roles/notify_mixin.rb b/app/services/roles/notify_mixin.rb new file mode 100644 index 00000000000..3fd72952cce --- /dev/null +++ b/app/services/roles/notify_mixin.rb @@ -0,0 +1,37 @@ +#-- encoding: UTF-8 + +#-- 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 doc/COPYRIGHT.rdoc for more details. +#++ + +module Roles::NotifyMixin + private + + def notify_changed_roles(action, changed_role) + OpenProject::Notifications.send(:roles_changed, action: action, role: changed_role) + end +end diff --git a/app/services/roles/set_attributes_service.rb b/app/services/roles/set_attributes_service.rb new file mode 100644 index 00000000000..3d7f9973207 --- /dev/null +++ b/app/services/roles/set_attributes_service.rb @@ -0,0 +1,37 @@ +#-- encoding: UTF-8 + +#-- 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 doc/COPYRIGHT.rdoc for more details. +#++ + +module Roles + class SetAttributesService < ::BaseServices::SetAttributes + def set_default_attributes + model.permissions = Role.non_member.permissions if model.permissions.nil? || model.permissions.empty? + end + end +end diff --git a/app/services/roles/update_service.rb b/app/services/roles/update_service.rb new file mode 100644 index 00000000000..7d10571ce02 --- /dev/null +++ b/app/services/roles/update_service.rb @@ -0,0 +1,39 @@ +#-- encoding: UTF-8 + +#-- 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 doc/COPYRIGHT.rdoc for more details. +#++ + +class Roles::UpdateService < ::BaseServices::Update + include Roles::NotifyMixin + + private + + def after_safe + notify_changed_roles(:updated, model) + end +end diff --git a/app/views/roles/_form.html.erb b/app/views/roles/_form.html.erb index 832d7cc34c9..d8ac66d4f9b 100644 --- a/app/views/roles/_form.html.erb +++ b/app/views/roles/_form.html.erb @@ -1,18 +1,11 @@ <%#-- copyright -OpenProject is a project management system. -Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +OpenProject Global Roles Plugin -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 +Copyright (C) 2010 - 2014 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 -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. +version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,57 +16,51 @@ 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. - ++#%> -<%= error_messages_for 'role' %> +<%= render :partial => 'shared/global_roles_header' %> -<% unless @role.builtin? %> -
|
+
+
+
+
+ <%=l(:label_global)%>
+
+
+ |
@@ -73,10 +74,15 @@ See docs/COPYRIGHT.rdoc for more details.
<% for role in @roles %>
<%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), action: 'edit', id: role)) %> |
+
+ <%= content_tag(role.builtin? ? 'em' : 'span', link_to(role.name, :action => 'edit', :id => role)) %>
+ |
+
+ <%= icon_wrapper('icon-context icon-checkmark', I18n.t(:general_text_Yes)) if role.is_a?(GlobalRole) %>
+ |
<% unless role.builtin? %>
- <%= reorder_links('role', {action: 'update', id: role}, method: :put) %>
+ <%= reorder_links('role', {:action => 'update', :id => role}, :method => :put) %>
<% end %>
|
@@ -93,5 +99,7 @@ See docs/COPYRIGHT.rdoc for more details.
+
<%= pagination_links_full @roles %>
- |
<% @roles.each do |role| %>
<%= link_to l(:label_permissions_report), action: 'report' %> + +<%= link_to l(:label_permissions_report), :action => 'report' %> diff --git a/app/views/roles/new.html.erb b/app/views/roles/new.html.erb index b206e20072f..1c210f16272 100644 --- a/app/views/roles/new.html.erb +++ b/app/views/roles/new.html.erb @@ -1,18 +1,11 @@ <%#-- copyright -OpenProject is a project management system. -Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +OpenProject Global Roles Plugin -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 +Copyright (C) 2010 - 2014 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 -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. +version 3. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,16 +16,16 @@ 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. - ++#%> -<% html_title l(:label_administration), l("label_role_new") %> +<% html_title t(:label_administration), t(:label_role_new) %> -<% local_assigns[:additional_breadcrumb] = l(:label_role_new) %> -<%= breadcrumb_toolbar l(:label_role_new) %> +<% local_assigns[:additional_breadcrumb] = t(:label_role_new) %> +<%= breadcrumb_toolbar t(:label_role_new) %> -<%= labelled_tabular_form_for @role, html: {id: 'role_form'}, as: :role do |f| %> - <%= render partial: 'form', locals: { f: f } %> - <%= styled_button_tag l(:button_create), class: '-highlight -with-icon icon-checkmark' %> +<%= labelled_tabular_form_for @role, :url => { :action => 'create' }, :html => {:id => 'role_form'}, :as => :role do |f| %> +<%= render partial: 'form', + locals: { f: f, role: @role, roles: @roles, permissions: @permissions, global_permissions: @global_permissions } %> ++<%= styled_button_tag t(:button_create), class: '-with-icon icon-checkmark' %> <% end %> diff --git a/app/views/roles/report.html.erb b/app/views/roles/report.html.erb index 806d3fc7d9c..2a65b2578ac 100644 --- a/app/views/roles/report.html.erb +++ b/app/views/roles/report.html.erb @@ -94,7 +94,7 @@ See docs/COPYRIGHT.rdoc for more details.
- <% if role.setable_permissions.include? permission %>
+ <% if setable_permissions(role).include? permission %>
<%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name), id: nil, class: "role-#{role.id}" %>
<% end %>
|
diff --git a/modules/global_roles/app/models/global_role.rb b/modules/global_roles/app/models/global_role.rb
index 2a4f16ca413..140bb8b0ee8 100644
--- a/modules/global_roles/app/models/global_role.rb
+++ b/modules/global_roles/app/models/global_role.rb
@@ -26,13 +26,13 @@ class GlobalRole < Role
self.assignable = false
end
- def setable_permissions
- Redmine::AccessControl.global_permissions
- end
+ #def setable_permissions
+ # Redmine::AccessControl.global_permissions
+ #end
- def self.setable_permissions
- Redmine::AccessControl.global_permissions
- end
+ #def self.setable_permissions
+ # Redmine::AccessControl.global_permissions
+ #end
def to_s
name
diff --git a/modules/global_roles/app/views/roles/_form.html.erb b/modules/global_roles/app/views/roles/_form.html.erb
deleted file mode 100644
index e308cb797ec..00000000000
--- a/modules/global_roles/app/views/roles/_form.html.erb
+++ /dev/null
@@ -1,65 +0,0 @@
-<%#-- copyright
-OpenProject Global Roles Plugin
-
-Copyright (C) 2010 - 2014 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.
-
-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.
-
-++#%>
-
-<%= render :partial => 'shared/global_roles_header' %>
-
-<% roles ||= nil %>
-
-<%= error_messages_for :role %>
-
- <%= f.text_field :name, required: true, container_class: '-slim' %>
-
-
- <% if role.new_record? %>
- <%= styled_label_tag :global_role, l(:label_global_role) %>
-
-
-<% if role.new_record? || role.is_a?(GlobalRole) %>
-
-<% end %>
-
-<% if role.new_record? || !role.is_a?(GlobalRole) %>
-
- <%= styled_check_box_tag("global_role", "1", role.is_a?(GlobalRole))%>
-
- <% else %>
- <%= styled_label_tag :unchangeable, "#{l(:label_role_type)} #{l(:label_not_changeable)}" %>
-
- <%= (role.is_a?(GlobalRole) ? l(:label_global_role) : l(:label_member_role))%>
-
- <% end %>
-
- <%= render partial: "member_attributes", locals: { f: f, role: role, roles: roles&.select {|r| !r.is_a?(GlobalRole)} }%>
-
-<% end %>
-
-<% if role.new_record? || role.is_a?(GlobalRole) %>
- >
- <%= render partial: "permissions", locals: {permissions: @global_permissions, role: role, showGlobalRole: true }%>
-
-<% end %>
-<% if role.new_record? || !role.is_a?(GlobalRole) %>
- >
- <%= render partial: "permissions", locals: {permissions: @permissions, role: role, showGlobalRole: false }%>
-
-<% end %>
-
diff --git a/modules/global_roles/app/views/roles/edit.html.erb b/modules/global_roles/app/views/roles/edit.html.erb
deleted file mode 100644
index 4fa81c9894d..00000000000
--- a/modules/global_roles/app/views/roles/edit.html.erb
+++ /dev/null
@@ -1,31 +0,0 @@
-<%#-- copyright
-OpenProject Global Roles Plugin
-
-Copyright (C) 2010 - 2014 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.
-
-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.
-
-++#%>
-
-<% html_title l(:label_administration), "#{l(:label_edit)} #{Role.model_name.human} #{@role.name}" %>
-
-<% local_assigns[:additional_breadcrumb] = @role.name %>
-<%= breadcrumb_toolbar @role.name %>
-
-<%= labelled_tabular_form_for @role, :url => { :action => 'update' }, :html => {:id => 'role_form'}, :as => :role do |f| %>
-<%= hidden_field_tag :id, @role.id %>
-<%= render partial: 'form', locals: { f: f , role: @role } %>
--<%= styled_button_tag l(:button_save), class: '-with-icon icon-checkmark' %> -<% end %> diff --git a/modules/global_roles/app/views/roles/index.html.erb b/modules/global_roles/app/views/roles/index.html.erb deleted file mode 100644 index adba5bfa9dd..00000000000 --- a/modules/global_roles/app/views/roles/index.html.erb +++ /dev/null @@ -1,105 +0,0 @@ -<%#-- copyright -OpenProject Global Roles Plugin - -Copyright (C) 2010 - 2014 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. - -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. - -++#%> -<% html_title l(:label_administration), l("label_role_plural") %> -<%= toolbar title: Role.model_name.human(count: 2) do %> -
-
-
-<%= pagination_links_full @roles %>
-
-
-
-
<%= link_to l(:label_permissions_report), :action => 'report' %> diff --git a/modules/global_roles/app/views/roles/new.html.erb b/modules/global_roles/app/views/roles/new.html.erb deleted file mode 100644 index 1c210f16272..00000000000 --- a/modules/global_roles/app/views/roles/new.html.erb +++ /dev/null @@ -1,31 +0,0 @@ -<%#-- copyright -OpenProject Global Roles Plugin - -Copyright (C) 2010 - 2014 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. - -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. - -++#%> - -<% html_title t(:label_administration), t(:label_role_new) %> - -<% local_assigns[:additional_breadcrumb] = t(:label_role_new) %> -<%= breadcrumb_toolbar t(:label_role_new) %> - -<%= labelled_tabular_form_for @role, :url => { :action => 'create' }, :html => {:id => 'role_form'}, :as => :role do |f| %> -<%= render partial: 'form', - locals: { f: f, role: @role, roles: @roles, permissions: @permissions, global_permissions: @global_permissions } %> --<%= styled_button_tag t(:button_create), class: '-with-icon icon-checkmark' %> -<% end %> diff --git a/modules/global_roles/lib/open_project/global_roles/engine.rb b/modules/global_roles/lib/open_project/global_roles/engine.rb index 87f0734b6ca..5a578b2ef55 100644 --- a/modules/global_roles/lib/open_project/global_roles/engine.rb +++ b/modules/global_roles/lib/open_project/global_roles/engine.rb @@ -34,7 +34,7 @@ module OpenProject::GlobalRoles # We still override version and project settings views from the core! URH override_core_views! - patches [:Principal, :Role, :User, :RolesController, :UsersController] + patches %i[Principal User UsersController] patch_with_namespace :BasicData, :RoleSeeder add_tab_entry :user, diff --git a/modules/global_roles/lib/open_project/global_roles/patches/role_patch.rb b/modules/global_roles/lib/open_project/global_roles/patches/role_patch.rb deleted file mode 100644 index 408f8e180d5..00000000000 --- a/modules/global_roles/lib/open_project/global_roles/patches/role_patch.rb +++ /dev/null @@ -1,46 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 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. -# -# 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. -#++ - -module OpenProject::GlobalRoles::Patches - module RolePatch - def self.included(base) - base.prepend InstanceMethods - - base.class_eval do - class << self - prepend ClassMethods - end - end - end - - module ClassMethods - def givable - super.where(type: 'Role') - end - end - - module InstanceMethods - def setable_permissions - setable_permissions = super - setable_permissions -= Redmine::AccessControl.global_permissions - setable_permissions - end - end - end -end diff --git a/modules/global_roles/lib/open_project/global_roles/patches/roles_controller_patch.rb b/modules/global_roles/lib/open_project/global_roles/patches/roles_controller_patch.rb deleted file mode 100644 index f73d165c8ec..00000000000 --- a/modules/global_roles/lib/open_project/global_roles/patches/roles_controller_patch.rb +++ /dev/null @@ -1,60 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 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. -# -# 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. -#++ - -module OpenProject::GlobalRoles::Patches - module RolesControllerPatch - def self.included(base) - base.prepend InstanceMethods - - base.class_eval do - before_action :define_global_permissions - end - end - - module InstanceMethods - def create - if params['global_role'] - create_global_role - else - super - end - end - - private - - def define_global_permissions - @global_permissions = group_permissions_by_module(GlobalRole.setable_permissions) - end - - def create_global_role - @role = GlobalRole.new permitted_params.role - if @role.save - flash[:notice] = l(:notice_successful_create) - redirect_to action: 'index' - else - define_setable_permissions - @roles = Role.order(Arel.sql('builtin, position')) - render template: 'roles/new' - end - end - end - end -end - -RolesController.send(:include, OpenProject::GlobalRoles::Patches::RolesControllerPatch) diff --git a/modules/global_roles/spec/controllers/roles_controller_spec.rb b/modules/global_roles/spec/controllers/roles_controller_spec.rb deleted file mode 100644 index b8af073db77..00000000000 --- a/modules/global_roles/spec/controllers/roles_controller_spec.rb +++ /dev/null @@ -1,336 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 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. -# -# 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. -#++ - -require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') - -describe RolesController, type: :controller do - before do - allow(@controller).to receive(:check_if_login_required) - expect(@controller).to receive(:require_admin) - disable_flash_sweep - end - - after do - User.current = nil - end - - shared_examples_for 'index' do - it {expect(response).to be_successful} - it {expect(assigns(:roles)).to eql(@roles)} - it {expect(response).to render_template 'roles/index'} - end - - shared_examples_for 'global assigns' do - it {expect(assigns(:global_roles)).to eql @global_roles} - it {expect(assigns(:global_role)).to eql @global_role} - end - - shared_examples_for 'successful create' do - it {expect(response).to be_redirect} - it {expect(response).to redirect_to '/admin/roles'} - it {expect(flash[:notice]).to eql I18n.t(:notice_successful_create)} - end - - shared_examples_for 'failed create' do - it {expect(response).to be_successful} - it {expect(response).to render_template 'new'} - end - - describe 'WITH get' do - describe 'VERB', :index do - before do - mock_role_find - end - - describe 'html' do - before {get 'index'} - - it_should_behave_like 'index' - end - - describe 'xhr' do - before {get :index, xhr: true} - - it_should_behave_like 'index' - end - end - - describe 'VERB', :new do - before do - @member_role = mocks_for_creating Role - allow(::Redmine::AccessControl).to receive(:sorted_modules).and_return(%w(Foo)) - allow(GlobalRole).to receive(:setable_permissions).and_return(doubled_permissions) - @non_member_role = mock_model Role - mock_permissions_on @non_member_role - allow(Role).to receive(:non_member).and_return(@non_member_role) - - mock_role_find - get 'new' - end - - it 'renders new' do - expect(response).to be_successful - expect(response).to render_template 'roles/new' - expect(assigns(:permissions)) - .to eql([['Foo', @member_role.setable_permissions]]) - expect(assigns(:roles)).to eql @roles - expect(assigns(:role)).to eql @member_role - end - end - - describe 'VERB', :edit do - before(:each) do - @member_role = mocks_for_creating Role - @global_role = mocks_for_creating GlobalRole - mock_role_find - end - - describe 'WITH member_role id' do - before do - @params = {'id' => '1'} - allow(Role).to receive(:find).and_return(@member_role) - end - - describe 'RESULT' do - describe 'success' do - describe 'html' do - before do - allow(::Redmine::AccessControl).to receive(:sorted_modules).and_return(%w(Foo)) - get :edit, params: @params - end - - - it do - expect(response).to be_successful - expect(response).to render_template 'roles/edit' - expect(assigns(:role)).to eql @member_role - expect(assigns(:permissions)) - .to eql([['Foo', @member_role.setable_permissions]]) - end - end - end - end - end - end - end - - describe 'WITH post' do - before(:each) do - @member_role = mocks_for_creating Role - @global_role = mocks_for_creating GlobalRole - mock_role_find - allow(Role).to receive(:find).with('1').and_return(@member_role) - allow(Role).to receive(:find).with('2').and_return(@global_role) - end - - describe 'VERB', :create do - describe 'WITH member_role params' do - before do - @params = {'role' => {'name' => 'role', - 'permissions' => %w(perm1 perm2 perm3), - 'assignable' => '1'}} - end - - describe 'RESULT' do - describe 'success' do - before(:each) do - expect(Role) - .to receive(:new) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(@member_role) - allow(@member_role).to receive(:save).and_return(true) - allow(@member_role).to receive(:errors).and_return([]) - end - - describe 'html' do - before do - post 'create', params: @params - end - - it_should_behave_like 'successful create' - it {expect(assigns(:role)).to eql @member_role} - end - end - - describe 'failure' do - before(:each) do - expect(Role) - .to receive(:new) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(@member_role) - allow(@member_role).to receive(:save).and_return(false) - allow(@member_role).to receive(:errors).and_return(['something is wrong']) - end - - describe 'html' do - before {post 'create', params: @params} - - it_should_behave_like 'failed create' - it {expect(assigns(:role)).to eql @member_role} - it {expect(assigns(:roles)).to eql Role.all} - end - end - end - end - - describe 'WITH global_role params' do - before do - @params = {'role' => {'name' => 'role', - 'permissions' => %w(perm1 perm2 perm3) - }, - 'global_role' => '1'} - end - - describe 'RESULTS' do - describe 'success' do - before(:each) do - expect(GlobalRole) - .to receive(:new) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(@global_role) - allow(@global_role).to receive(:save).and_return(true) - end - - describe 'html' do - before {post 'create', params: @params} - - it_should_behave_like 'successful create' - end - end - - describe 'failure' do - before(:each) do - expect(GlobalRole) - .to receive(:new) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(@global_role) - allow(@global_role).to receive(:save).and_return(false) - end - - describe 'html' do - before {post 'create', params: @params} - - it_should_behave_like 'failed create' - it {expect(assigns(:role)).to eql @global_role} - it {expect(assigns(:roles)).to eql Role.all} - end - end - end - end - end - - describe 'VERB', :destroy do - shared_examples_for 'destroy results' do - describe 'success' do - before do - expect(@role).to receive(:destroy) - post 'destroy', params: @params - end - - it {expect(response).to be_redirect} - it {expect(response).to redirect_to '/admin/roles'} - end - end - - describe 'WITH member_role params' do - before do - @params = {'class' => 'Role', 'id' => '1'} - @role = @member_role - end - - describe 'RESULTS' do - it_should_behave_like 'destroy results' - end - end - - describe 'WITH global_role params' do - before do - @params = {'class' => 'Role', 'id' => '2'} - @role = @global_role - end - - describe 'RESULTS' do - it_should_behave_like 'destroy results' - end - end - end - - describe 'VERB', :update do - shared_examples_for 'update results' do - describe 'success' do - describe 'html' do - before do - expect(@role) - .to receive(:update_attributes) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(true) - allow(@role).to receive(:errors).and_return([]) - post :update, params: @params - end - - it {expect(response).to be_redirect} - it {expect(response).to redirect_to '/admin/roles'} - it {expect(flash[:notice]).to eql I18n.t(:notice_successful_update)} - end - end - - describe 'failure' do - describe 'html' do - before(:each) do - expect(@role) - .to receive(:update_attributes) - .with(ActionController::Parameters.new(@params['role']).permit!) - .and_return(false) - allow(@role).to receive(:errors).and_return(['something is wrong']) - post :update, params: @params - end - - it {expect(response).to render_template 'roles/edit'} - end - end - end - - describe 'WITH member_role params' do - before do - @params = {'role' => {'permissions' => %w(permA permB), - 'name' => 'schmu'}, - 'id' => '1'} - @role = @member_role - end - - describe 'RESULT' do - it_should_behave_like 'update results' - end - end - - describe 'WITH global_role params' do - before do - @params = {'role' => {'permissions' => %w(permA permB), - 'name' => 'schmu'}, - 'id' => '2'} - @role = @global_role - end - - describe 'RESULT' do - it_should_behave_like 'update results' - end - end - end - end -end diff --git a/modules/global_roles/spec/plugin_spec_helper.rb b/modules/global_roles/spec/plugin_spec_helper.rb index 89d02bb7720..bccb7e7088d 100644 --- a/modules/global_roles/spec/plugin_spec_helper.rb +++ b/modules/global_roles/spec/plugin_spec_helper.rb @@ -92,6 +92,8 @@ module OpenProject def mocks_for_creating(role_class) role = mock_model role_class allow(role_class).to receive(:new).and_return role + allow(role).to receive(:attributes=) + allow(role).to receive(:changed).and_return([]) mock_permissions_on role role end diff --git a/spec/contracts/roles/create_contract_spec.rb b/spec/contracts/roles/create_contract_spec.rb new file mode 100644 index 00000000000..6b31721d092 --- /dev/null +++ b/spec/contracts/roles/create_contract_spec.rb @@ -0,0 +1,63 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 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_contract_examples' + +describe Roles::CreateContract do + it_behaves_like 'roles contract' do + let(:role) do + Role.new.tap do |r| + r.name = role_name + r.assignable = role_assignable + end + end + + subject(:contract) { described_class.new(role, current_user) } + + describe 'validation' do + context 'with the type set manually' do + before do + role.type = 'GlobalRole' + end + + it_behaves_like 'is valid' + end + + context 'with the type set manually to something other than Role or GlobalRole' do + before do + role.type = 'MyRole' + end + + it 'is invalid' do + expect_valid(false, type: %i(inclusion)) + end + end + end + end +end diff --git a/spec/contracts/roles/shared_contract_examples.rb b/spec/contracts/roles/shared_contract_examples.rb new file mode 100644 index 00000000000..c6c5446a930 --- /dev/null +++ b/spec/contracts/roles/shared_contract_examples.rb @@ -0,0 +1,63 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 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' + +shared_examples_for 'roles contract' do + let(:current_user) do + FactoryBot.build_stubbed(:admin) + end + let(:role_name) { 'A role name' } + let(:role_assignable) { true } + + def expect_valid(valid, symbols = {}) + expect(contract.validate).to eq(valid) + + symbols.each do |key, arr| + expect(contract.errors.symbols_for(key)).to match_array arr + end + end + + shared_examples 'is valid' do + it 'is valid' do + expect_valid(true) + end + end + + describe 'validation' do + it_behaves_like 'is valid' + + context 'if the name is nil' do + let(:role_name) { nil } + + it 'is invalid' do + expect_valid(false, name: %i(blank)) + end + end + end +end diff --git a/spec/contracts/roles/update_contract_spec.rb b/spec/contracts/roles/update_contract_spec.rb new file mode 100644 index 00000000000..dbb4f176956 --- /dev/null +++ b/spec/contracts/roles/update_contract_spec.rb @@ -0,0 +1,57 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 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_contract_examples' + +describe Roles::UpdateContract do + it_behaves_like 'roles contract' do + let(:role) do + FactoryBot.build_stubbed(:role, + name: 'Some name', + assignable: !role_assignable).tap do |r| + r.name = role_name + r.assignable = role_assignable + end + end + + subject(:contract) { described_class.new(role, current_user) } + + describe 'validation' do + context 'with the type set manually' do + before do + role.type = 'GlobalRole' + end + + it 'is invalid' do + expect_valid(false, type: %i(error_readonly)) + end + end + end + end +end |
|---|