introduce role services and contracts and move parts of global_roles into core

pull/7338/head
ulferts 6 years ago
parent 06308e1293
commit a06120db10
No known key found for this signature in database
GPG Key ID: A205708DE1284017
  1. 4
      app/contracts/members/base_contract.rb
  2. 2
      app/contracts/model_contract.rb
  3. 64
      app/contracts/roles/base_contract.rb
  4. 47
      app/contracts/roles/create_contract.rb
  5. 32
      app/contracts/roles/update_contract.rb
  6. 89
      app/controllers/roles_controller.rb
  7. 23
      app/helpers/roles_helper.rb
  8. 12
      app/models/role.rb
  9. 6
      app/seeders/basic_data/role_seeder.rb
  10. 6
      app/services/base_services/create.rb
  11. 63
      app/services/roles/create_service.rb
  12. 37
      app/services/roles/notify_mixin.rb
  13. 37
      app/services/roles/set_attributes_service.rb
  14. 39
      app/services/roles/update_service.rb
  15. 101
      app/views/roles/_form.html.erb
  16. 0
      app/views/roles/_member_attributes.html.erb
  17. 0
      app/views/roles/_member_form.html.erb
  18. 0
      app/views/roles/_permissions.html.erb
  19. 27
      app/views/roles/edit.html.erb
  20. 46
      app/views/roles/index.html.erb
  21. 29
      app/views/roles/new.html.erb
  22. 2
      app/views/roles/report.html.erb
  23. 12
      modules/global_roles/app/models/global_role.rb
  24. 65
      modules/global_roles/app/views/roles/_form.html.erb
  25. 31
      modules/global_roles/app/views/roles/edit.html.erb
  26. 105
      modules/global_roles/app/views/roles/index.html.erb
  27. 31
      modules/global_roles/app/views/roles/new.html.erb
  28. 2
      modules/global_roles/lib/open_project/global_roles/engine.rb
  29. 46
      modules/global_roles/lib/open_project/global_roles/patches/role_patch.rb
  30. 60
      modules/global_roles/lib/open_project/global_roles/patches/roles_controller_patch.rb
  31. 336
      modules/global_roles/spec/controllers/roles_controller_spec.rb
  32. 2
      modules/global_roles/spec/plugin_spec_helper.rb
  33. 63
      spec/contracts/roles/create_contract_spec.rb
  34. 63
      spec/contracts/roles/shared_contract_examples.rb
  35. 57
      spec/contracts/roles/update_contract_spec.rb

@ -28,10 +28,6 @@
module Members
class BaseContract < ::ModelContract
def self.model
Member
end
delegate :principal,
:project,
:new_record?,

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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' %>
<% roles ||= nil %>
<% unless @role.builtin? %>
<div class="form--field -required"><%= f.text_field :name, required: true, container_class: '-middle' %></div>
<div class="form--field"><%= f.check_box :assignable %></div>
<% if @role.new_record? && @roles.any? %>
<div id="member_attributes">
<div class="form--field">
<%= styled_label_tag 'copy_workflow_from', t(:label_copy_workflow_from) %>
<div class="form--field-container">
<%= styled_select_tag(:copy_workflow_from,
options_from_collection_for_select(@roles, :id, :name, params[:copy_workflow_from]),
include_blank: true,
container_class: '-middle') %>
</div>
</div>
<%= error_messages_for_contract(role, @call.errors) if @call %>
<div class="form--field -required">
<%= f.text_field :name, required: true, container_class: '-slim' %>
</div>
<div class="form--field">
<% if role.new_record? %>
<%= styled_label_tag :global_role, t(:label_global_role) %>
<div class="form--field-container">
<%= styled_check_box_tag("global_role", "1", role.is_a?(GlobalRole))%>
</div>
<% else %>
<%= styled_label_tag :unchangeable, "#{t(:label_role_type)} #{t(:label_not_changeable)}" %>
<div class="form--field-container">
<%= (role.is_a?(GlobalRole) ? t(:label_global_role) : t(:label_member_role))%>
</div>
<% end %>
</div>
<% if role.new_record? || role.is_a?(GlobalRole) %>
<div id="global_attributes" style="display:none">
<%= render partial: "global_attributes", locals: { f: f, role: role, roles: roles&.select {|r| r.is_a?(GlobalRole)} }%>
</div>
<% end %>
<% if role.new_record? || !role.is_a?(GlobalRole) %>
<div id="member_attributes">
<%= render partial: "member_attributes", locals: { f: f, role: role, roles: roles&.select {|r| !r.is_a?(GlobalRole)} }%>
</div>
<% end %>
<% if role.new_record? || role.is_a?(GlobalRole) %>
<div id="global_permissions" style=<%= role.new_record? && !role.is_a?(GlobalRole) ? "display:none" : ""%> >
<%= render partial: "permissions", locals: {permissions: grouped_setable_permissions(GlobalRole.new), role: role, showGlobalRole: true }%>
</div>
<% end %>
<% if role.new_record? || !role.is_a?(GlobalRole) %>
<div id="member_permissions" style=<%= role.new_record? && role.is_a?(GlobalRole) ? "display:none" : ""%>>
<%= render partial: "permissions", locals: {permissions: grouped_setable_permissions(Role.new), role: role, showGlobalRole: false }%>
</div>
<% end %>
<div id="member_permissions">
<% @permissions.each do |mod, mod_permissions| %>
<% module_name = mod.blank? ? 'fieldset--' + Project.model_name.human.downcase.gsub(' ', '_') : 'fieldset--' + l_or_humanize(mod, prefix: 'project_module_').downcase.gsub(' ', '_') %>
<fieldset class="form--fieldset -collapsible" id="<%= module_name %>">
<% module_name = mod.blank? ? "form--" + I18n.t('attributes.project') : "form--" + l_or_humanize(mod, prefix: 'project_module_').gsub(' ','_') %>
<div class="grid-section">
<fieldset class="form--fieldset -collapsible" id= "<%= module_name %>">
<legend class="form--fieldset-legend" ><%= mod.blank? ? Project.model_name.human : l_or_humanize(mod, prefix: 'project_module_') %></legend>
<div class="form--fieldset-control">
<span class="form--fieldset-control-container">
(<%= check_all_links module_name %>)
</span>
</div>
<div class="-columns-2">
<% mod_permissions.each do |permission| %>
<div class="form--field">
<div class="form--field-container">
<label class="form--label-with-check-box">
<%= styled_check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name) %>
<%= l_or_humanize(permission.name, prefix: 'permission_') %>
</label>
</div>
</div>
<% end %>
</div>
</fieldset>
</div>
</fieldset>
<% end %>
</div>

@ -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,18 +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_edit)} #{Role.model_name.human} #{h @role.name}" %>
<% html_title t(:label_administration), "#{t(:label_edit)} #{Role.model_name.human} #{@role.name}" %>
<% local_assigns[:additional_breadcrumb] = @role.name %>
<%= breadcrumb_toolbar @role.name %>
<%= labelled_tabular_form_for @role, html: { id: 'role_form' }, as: :role do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<%= styled_button_tag l(:button_save), class: '-highlight -with-icon icon-checkmark' %>
<%= 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 } %>
<br/>
<%= styled_button_tag l(:button_save), class: '-with-icon icon-checkmark' %>
<% end %>

@ -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,26 +16,25 @@ 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_plural") %>
<%= toolbar title: l(:label_role_plural) do %>
<%= toolbar title: Role.model_name.human(count: 2) do %>
<li class="toolbar-item">
<%= link_to new_role_path,
<%= link_to({ action: 'new'},
{ class: 'button -alt-highlight',
aria: {label: t(:label_role_new)},
title: t(:label_role_new)} do %>
title: t(:label_role_new)}) do %>
<%= op_icon('button--icon icon-add') %>
<span class="button--text"><%= Role.model_name.human %></span>
<% end %>
</li>
<% end %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>
<col highlight-col>
<col>
@ -58,6 +50,15 @@ See docs/COPYRIGHT.rdoc for more details.
</div>
</div>
</th>
<th>
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
<%=l(:label_global)%>
</span>
</div>
</div>
</th>
<th>
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
@ -73,10 +74,15 @@ See docs/COPYRIGHT.rdoc for more details.
<tbody>
<% for role in @roles %>
<tr>
<td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), action: 'edit', id: role)) %></td>
<td>
<%= content_tag(role.builtin? ? 'em' : 'span', link_to(role.name, :action => 'edit', :id => role)) %>
</td>
<td>
<%= icon_wrapper('icon-context icon-checkmark', I18n.t(:general_text_Yes)) if role.is_a?(GlobalRole) %>
</td>
<td>
<% unless role.builtin? %>
<%= reorder_links('role', {action: 'update', id: role}, method: :put) %>
<%= reorder_links('role', {:action => 'update', :id => role}, :method => :put) %>
<% end %>
</td>
<td class="buttons">
@ -93,5 +99,7 @@ See docs/COPYRIGHT.rdoc for more details.
</div>
</div>
<%= pagination_links_full @roles %>
<p><%= link_to l(:label_permissions_report), action: 'report' %></p>
<p><%= link_to l(:label_permissions_report), :action => 'report' %></p>

@ -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 } %>
<br/>
<%= styled_button_tag t(:button_create), class: '-with-icon icon-checkmark' %>
<% end %>

@ -94,7 +94,7 @@ See docs/COPYRIGHT.rdoc for more details.
</td>
<% @roles.each do |role| %>
<td>
<% 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 %>
</td>

@ -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

@ -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 %>
<div class="form--field -required">
<%= f.text_field :name, required: true, container_class: '-slim' %>
</div>
<div class="form--field">
<% if role.new_record? %>
<%= styled_label_tag :global_role, l(:label_global_role) %>
<div class="form--field-container">
<%= styled_check_box_tag("global_role", "1", role.is_a?(GlobalRole))%>
</div>
<% else %>
<%= styled_label_tag :unchangeable, "#{l(:label_role_type)} #{l(:label_not_changeable)}" %>
<div class="form--field-container">
<%= (role.is_a?(GlobalRole) ? l(:label_global_role) : l(:label_member_role))%>
</div>
<% end %>
</div>
<% if role.new_record? || role.is_a?(GlobalRole) %>
<div id="global_attributes" style="display:none">
<%= render partial: "global_attributes", locals: { f: f, role: role, roles: roles&.select {|r| r.is_a?(GlobalRole)} }%>
</div>
<% end %>
<% if role.new_record? || !role.is_a?(GlobalRole) %>
<div id="member_attributes">
<%= render partial: "member_attributes", locals: { f: f, role: role, roles: roles&.select {|r| !r.is_a?(GlobalRole)} }%>
</div>
<% end %>
<% if role.new_record? || role.is_a?(GlobalRole) %>
<div id="global_permissions" style=<%= role.new_record? && !role.is_a?(GlobalRole) ? "display:none" : ""%> >
<%= render partial: "permissions", locals: {permissions: @global_permissions, role: role, showGlobalRole: true }%>
</div>
<% end %>
<% if role.new_record? || !role.is_a?(GlobalRole) %>
<div id="member_permissions" style=<%= role.new_record? && role.is_a?(GlobalRole) ? "display:none" : ""%>>
<%= render partial: "permissions", locals: {permissions: @permissions, role: role, showGlobalRole: false }%>
</div>
<% end %>

@ -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 } %>
<br/>
<%= styled_button_tag l(:button_save), class: '-with-icon icon-checkmark' %>
<% end %>

@ -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 %>
<li class="toolbar-item">
<%= link_to({ action: 'new'},
{ class: 'button -alt-highlight',
aria: {label: t(:label_role_new)},
title: t(:label_role_new)}) do %>
<%= op_icon('button--icon icon-add') %>
<span class="button--text"><%= Role.model_name.human %></span>
<% end %>
</li>
<% end %>
<div class="generic-table--container">
<div class="generic-table--results-container">
<table class="generic-table">
<colgroup>
<col highlight-col>
<col highlight-col>
<col highlight-col>
<col>
</colgroup>
<thead>
<tr>
<th>
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
<%= Role.model_name.human %>
</span>
</div>
</div>
</th>
<th>
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
<%=l(:label_global)%>
</span>
</div>
</div>
</th>
<th>
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
<%=l(:button_sort)%>
</span>
</div>
</div>
</th>
<th><div class="generic-table--empty-header"></div></th>
</tr>
</thead>
<tbody>
<% for role in @roles %>
<tr>
<td>
<%= content_tag(role.builtin? ? 'em' : 'span', link_to(role.name, :action => 'edit', :id => role)) %>
</td>
<td>
<%= icon_wrapper('icon-context icon-checkmark', I18n.t(:general_text_Yes)) if role.is_a?(GlobalRole) %>
</td>
<td>
<% unless role.builtin? %>
<%= reorder_links('role', {:action => 'update', :id => role}, :method => :put) %>
<% end %>
</td>
<td class="buttons">
<%= link_to('', role_path(role),
method: :delete,
data: { confirm: l(:text_are_you_sure) },
class: 'icon icon-delete',
title: t(:button_delete)) unless role.builtin? %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<%= pagination_links_full @roles %>
<p><%= link_to l(:label_permissions_report), :action => 'report' %></p>

@ -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 } %>
<br/>
<%= styled_button_tag t(:button_create), class: '-with-icon icon-checkmark' %>
<% end %>

@ -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,

@ -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

@ -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)

@ -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

@ -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

@ -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

@ -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

@ -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
Loading…
Cancel
Save