Merge pull request #5208 from opf/feature/split-types-form-into-tabs

Feature/split types form into tabs
pull/5217/head
Markus Kahl 8 years ago committed by GitHub
commit 8a07087be2
  1. 17
      app/controllers/types_controller.rb
  2. 146
      app/views/types/_form.html.erb
  3. 33
      app/views/types/edit.html.erb
  4. 95
      app/views/types/form/_form_configuration.html.erb
  5. 61
      app/views/types/form/_projects.html.erb
  6. 56
      app/views/types/form/_settings.html.erb
  7. 54
      app/views/types/index.html.erb
  8. 6
      app/views/types/new.html.erb
  9. 5
      config/locales/en.yml
  10. 6
      config/routes.rb
  11. 126
      spec/controllers/types_controller_spec.rb
  12. 2
      spec/features/types/form_configuration_spec.rb
  13. 31
      spec_legacy/functional/types_controller_spec.rb

@ -69,13 +69,19 @@ class TypesController < ApplicationController
end
def edit
@projects = Project.all
@type = ::Type.includes(:projects,
:custom_fields)
.find(params[:id])
if params[:tab].blank?
redirect_to tab: :settings
else
@tab = params[:tab]
@projects = Project.all
@type = ::Type.includes(:projects,
:custom_fields)
.find(params[:id])
end
end
def update
@tab = params["tab"] || "settings"
@type = ::Type.find(params[:id])
# forbid renaming if it is a standard type
@ -85,7 +91,8 @@ class TypesController < ApplicationController
result = service.call(attributes: permitted_params.type)
if result.success?
redirect_to edit_type_path(id: @type.id), notice: t(:notice_successful_update)
redirect_to(edit_type_tab_path(id: @type.id, tab: @tab),
notice: t(:notice_successful_update))
else
@projects = Project.all
render action: 'edit'

@ -1,146 +0,0 @@
<%#-- 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.
++#%>
<%= javascript_include_tag "type_form.js" %>
<%= error_messages_for 'type' %>
<div class="grid-block">
<div class="grid-content">
<section class="form--section">
<!--[form:type]-->
<div class="form--field -wide-label"><%= f.text_field :name, required: true, disabled: @type.is_standard? %></div>
<div class="form--field -wide-label"><%= f.check_box :is_in_roadmap %></div>
<div class="form--field -wide-label"><%= f.select :color_id, options_for_colors(@type) %></div>
<div class="form--field -wide-label"><%= f.check_box :in_aggregation %></div>
<div class="form--field -wide-label"><%= f.check_box :is_default, label: t(:label_type_default_new_projects) %></div>
<div class="form--field -wide-label"><%= f.check_box :is_milestone %></div>
<% if @type.new_record? && @types.any? %>
<div class="form--field -wide-label">
<%= styled_label_tag 'copy_workflow_from', t(:label_copy_workflow_from) %>
<%= styled_select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@types, :id, :name)) %>
</div>
<% end %>
<!--[eoform:type]-->
</section>
</div>
</div>
<section class="form--section">
<div class="grid-block wrap">
<div class="grid-content small-12 large-6">
<fieldset class="form--fieldset -collapsible" id="type_attribute_visibility">
<legend class="form--fieldset-legend" onclick="toggleFieldset(this);">
<%= I18n.t('label_form_configuration')%>
</legend>
<div>
<p><%= I18n.t('text_form_configuration') %></p>
<table class="attributes-table -two-options">
<thead>
<tr>
<th><%= I18n.t('label_attribute') %></th>
<th class="attributes-table--option"><%= I18n.t('label_active') %></th>
<th class="attributes-table--option"><%= I18n.t('label_always_visible') %></th>
</tr>
</thead>
<tbody>
<%
attributes = ::TypesHelper
.work_package_form_attributes(merge_date: true)
.reject { |name, attr|
# display all custom fields don't display required fields without a default
not name =~ /custom_field_/ and (attr[:required] and not attr[:has_default])
}
keys = attributes.keys.sort_by do |name|
translated_attribute_name(name, attributes[name])
end
%>
<% keys.each do |name| %>
<% attr = attributes[name] %>
<tr>
<td>
<%= label_tag "type_attribute_visibility_#{name}",
translated_attribute_name(name, attr),
value: "type_attribute_visibility[#{name}]",
class: 'ellipsis' %>
</td>
<td>
<input name="<%= "type[attribute_visibility][#{name}]" %>" type="hidden" value="hidden" />
<% active_checked = [nil, 'default', 'visible'].include?(attr_visibility(name, @type)) %>
<%= check_box_tag "type[attribute_visibility][#{name}]",
'default',
active_checked,
id: "type_attribute_visibility_default_#{name}",
title: I18n.t('tooltip.attribute_visibility.default') %>
</td>
<td>
<%= check_box_tag "type[attribute_visibility][#{name}]",
'visible',
attr_visibility(name, @type) == 'visible',
id: "type_attribute_visibility_visible_#{name}",
title: I18n.t('tooltip.attribute_visibility.visible'),
disabled: !active_checked %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</fieldset>
</div>
<div class="grid-content small-12 large-6">
<% if @projects.any? %>
<fieldset class="form--fieldset -collapsible" id="type_project_ids">
<legend class="form--fieldset-legend" onclick="toggleFieldset(this);">
<%= t(:label_project_plural) %>
</legend>
<div>
<div class="form--fieldset-control">
<span class="form--fieldset-control-container">
(<%= check_all_links 'type_project_ids' %>)
</span>
</div>
<%= project_nested_ul(@projects) do |p|
content_tag('label',
check_box_tag('type[project_ids][]', p.id, @type.projects.include?(p), id: nil) +
' ' + h(p), class: 'form--label-with-check-box')
end %>
<%= hidden_field_tag('type[project_ids][]', '', id: nil) %>
</div>
</fieldset>
<% end %>
</div>
</div>
</section>
<div class="grid-block">
<div class="generic-table--action-buttons">
<%= styled_button_tag t(@type.new_record? ? :button_create : :button_save),
class: '-highlight -with-icon icon-checkmark' %>
</div>
</div>

@ -27,7 +27,7 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<% html_title l(:label_administration), "#{l(:label_edit)} #{Type.model_name.human} #{h @type.name}" %>
<% html_title t(:label_administration), "#{t(:label_edit)} #{t(:label_work_package_types)} #{h @type.name}" %>
<% local_assigns[:additional_breadcrumb] = @type.name %>
@ -36,6 +36,33 @@ See doc/COPYRIGHT.rdoc for more details.
<%= breadcrumb_toolbar @type.name %>
</div>
<%= form_for @type, builder: TabularFormBuilder, lang: current_language do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<div class="tabs">
<ul>
<li>
<%= link_to t("types.edit.settings"),
edit_type_tab_path(id: @type.id, tab: :settings),
class: "#{'selected' if @tab == "settings" }" %>
</li>
<li>
<%= link_to t("types.edit.form_configuration"),
edit_type_tab_path(id: @type.id, tab: :form_configuration),
class: "#{'selected' if @tab == 'form_configuration' }" %>
</li>
<li>
<%= link_to t("types.edit.projects"),
edit_type_tab_path(id: @type.id, tab: :projects),
class: "#{'selected' if @tab == 'projects' }" %>
</li>
</ul>
</div>
<%= javascript_include_tag "type_form.js" %>
<%= error_messages_for 'type' %>
<%= form_for @type,
url: update_type_tab_path(id: @type.id, tab: @tab),
builder: TabularFormBuilder,
lang: current_language do |f| %>
<%= render partial: "types/form/#{@tab}", locals: { f: f } %>
<% end %>

@ -0,0 +1,95 @@
<%#-- 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.
++#%>
<section class="form--section">
<div class="grid-block wrap">
<div class="grid-content small-12 large-6">
<div>
<p><%= I18n.t('text_form_configuration') %></p>
<table class="attributes-table -two-options">
<thead>
<tr>
<th><%= I18n.t('label_attribute') %></th>
<th class="attributes-table--option"><%= I18n.t('label_active') %></th>
<th class="attributes-table--option"><%= I18n.t('label_always_visible') %></th>
</tr>
</thead>
<tbody>
<%
attributes = ::TypesHelper
.work_package_form_attributes(merge_date: true)
.reject { |name, attr|
# display all custom fields don't display required fields without a default
not name =~ /custom_field_/ and (attr[:required] and not attr[:has_default])
}
keys = attributes.keys.sort_by do |name|
translated_attribute_name(name, attributes[name])
end
%>
<% keys.each do |name| %>
<% attr = attributes[name] %>
<tr>
<td>
<%= label_tag "type_attribute_visibility_#{name}",
translated_attribute_name(name, attr),
value: "type_attribute_visibility[#{name}]",
class: 'ellipsis' %>
</td>
<td>
<input name="<%= "type[attribute_visibility][#{name}]" %>" type="hidden" value="hidden" />
<% active_checked = [nil, 'default', 'visible'].include?(attr_visibility(name, @type)) %>
<%= check_box_tag "type[attribute_visibility][#{name}]",
'default',
active_checked,
id: "type_attribute_visibility_default_#{name}",
title: I18n.t('tooltip.attribute_visibility.default') %>
</td>
<td>
<%= check_box_tag "type[attribute_visibility][#{name}]",
'visible',
attr_visibility(name, @type) == 'visible',
id: "type_attribute_visibility_visible_#{name}",
title: I18n.t('tooltip.attribute_visibility.visible'),
disabled: !active_checked %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</section>
<div class="grid-block">
<div class="generic-table--action-buttons">
<%= styled_button_tag t(@type.new_record? ? :button_create : :button_save),
class: '-highlight -with-icon icon-checkmark' %>
</div>
</div>

@ -0,0 +1,61 @@
<%#-- 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.
++#%>
<section class="form--section">
<div class="grid-block wrap">
<div class="grid-content small-12 large-6">
<% if @projects.any? %>
<fieldset class="form--fieldset" id="type_project_ids">
<legend class="form--fieldset-legend" onclick="toggleFieldset(this);">
<%= t('types.edit.enabled_projects') %>
</legend>
<div>
<div class="form--fieldset-control">
<span class="form--fieldset-control-container">
(<%= check_all_links 'type_project_ids' %>)
</span>
</div>
<%= project_nested_ul(@projects) do |p|
content_tag('label',
check_box_tag('type[project_ids][]', p.id, @type.projects.include?(p), id: nil) +
' ' + h(p), class: 'form--label-with-check-box')
end %>
<%= hidden_field_tag('type[project_ids][]', '', id: nil) %>
</div>
<% end %>
</div>
</div>
</section>
<div class="grid-block">
<div class="generic-table--action-buttons">
<%= styled_button_tag t(@type.new_record? ? :button_create : :button_save),
class: '-highlight -with-icon icon-checkmark' %>
</div>
</div>

@ -0,0 +1,56 @@
<%#-- 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.
++#%>
<div class="grid-block">
<div class="grid-content">
<!--[form:type]-->
<div class="form--field -wide-label"><%= f.text_field :name, required: true, disabled: @type.is_standard? %></div>
<div class="form--field -wide-label"><%= f.check_box :is_in_roadmap %></div>
<div class="form--field -wide-label"><%= f.select :color_id, options_for_colors(@type) %></div>
<div class="form--field -wide-label"><%= f.check_box :in_aggregation %></div>
<div class="form--field -wide-label"><%= f.check_box :is_default, label: t(:label_type_default_new_projects) %></div>
<div class="form--field -wide-label"><%= f.check_box :is_milestone %></div>
<% if @type.new_record? && @types.any? %>
<div class="form--field -wide-label">
<%= styled_label_tag 'copy_workflow_from', t(:label_copy_workflow_from) %>
<%= styled_select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@types, :id, :name)) %>
</div>
<% end %>
<!--[eoform:type]-->
</div>
</div>
<div class="grid-block">
<div class="generic-table--action-buttons">
<%= styled_button_tag t(@type.new_record? ? :button_create : :button_save),
class: '-highlight -with-icon icon-checkmark' %>
</div>
</div>

@ -27,15 +27,17 @@ See doc/COPYRIGHT.rdoc for more details.
++#%>
<% html_title l(:label_administration), l("label_type_plural") %>
<%= toolbar title: l(:label_type_plural) do %>
<% html_title t(:label_administration), t("label_type_plural") %>
<%= toolbar title: t(:label_work_package_types) do %>
<li class="toolbar-item">
<%= link_to new_type_path,
{ class: 'button -alt-highlight',
aria: {label: t(:label_type_new)},
aria: { label: t(:label_type_new) },
title: t(:label_type_new)} do %>
<i class="button--icon icon-add"></i>
<span class="button--text"><%= t('activerecord.attributes.workpackage.type') %></button>
<span class="button--text">
<%= t('activerecord.attributes.workpackage.type') %>
</button>
<% end %>
</li>
<% end %>
@ -85,7 +87,8 @@ See doc/COPYRIGHT.rdoc for more details.
</div>
</div>
</th>
<th title="<%= l('timelines.work_packages_are_displayed_in_aggregations') %>">
<th title="<%=
t('timelines.work_packages_are_displayed_in_aggregations') %>">
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
@ -107,7 +110,7 @@ See doc/COPYRIGHT.rdoc for more details.
<div class="generic-table--sort-header-outer">
<div class="generic-table--sort-header">
<span>
<%=l(:button_sort)%>
<%=t(:button_sort)%>
</span>
</div>
</div>
@ -118,16 +121,39 @@ See doc/COPYRIGHT.rdoc for more details.
<tbody>
<% for type in @types %>
<tr>
<td class="timelines-pet-name"><%= link_to type.name, edit_type_path(type) %></td>
<td><% if type.workflows.empty? %><span class="icon-context icon-warning"><%= l(:text_type_no_workflow) %> (<%= link_to l(:button_edit), {controller: '/workflows', action: 'edit', type_id: type} %>)</span><% end %></td>
<td class="timelines-pet-color"><%= icon_for_type type %></td>
<td class="timelines-pet-is_default"><%= checked_image(type.is_default) %></td>
<td class="timelines-pet-in_aggregation"><%= checked_image(type.in_aggregation) %></td>
<td class="timelines-pet-is_milestone"><%= checked_image(type.is_milestone) %></td>
<td class="timelines-pet-reorder"><%= reorder_links('type', {action: 'move', id: type}) %></td>
<td class="timelines-pet-name">
<%= link_to type.name, edit_type_tab_path(type, tab: "settings") %>
</td>
<td>
<% if type.workflows.empty? %>
<span class="icon-context icon-warning">
<%= t(:text_type_no_workflow) %>
(<%= link_to t(:button_edit), { controller: '/workflows',
action: 'edit',
type_id: type} %>)
</span>
<% end %>
</td>
<td class="timelines-pet-color">
<%= icon_for_type type %>
</td>
<td class="timelines-pet-is_default">
<%= checked_image(type.is_default) %>
</td>
<td class="timelines-pet-in_aggregation">
<%= checked_image(type.in_aggregation) %>
</td>
<td class="timelines-pet-is_milestone">
<%= checked_image(type.is_milestone) %>
</td>
<td class="timelines-pet-reorder">
<%= reorder_links('type', {action: 'move', id: type}) %>
</td>
<td class="buttons">
<% if !type.is_standard? %>
<%= link_to type, method: :delete, data: { confirm: t(:text_are_you_sure) }, class: 'icon icon-delete' do %>
<%= link_to type, method: :delete,
data: { confirm: t(:text_are_you_sure) },
class: 'icon icon-delete' do %>
<%= t(:button_delete) %>
<span class="hidden-for-sighted"><%=h type.name %></span>
<% end %>

@ -33,6 +33,10 @@ See doc/COPYRIGHT.rdoc for more details.
<% local_assigns[:additional_breadcrumb] = t(:label_type_new) %>
<%= breadcrumb_toolbar t(:label_type_new) %>
<%= javascript_include_tag "type_form.js" %>
<%= error_messages_for 'type' %>
<%= form_for controller.type, builder: TabularFormBuilder, lang: current_language do |f| %>
<%= render partial: 'form', locals: { f: f } %>
<%= render partial: 'types/form/settings', locals: { f: f } %>
<% end %>

@ -156,6 +156,11 @@ en:
index:
no_results_title_text: There are currently no types.
no_results_content_text: Create a new type
edit:
settings: "Settings"
form_configuration: "Form configuration"
projects: "Projects"
enabled_projects: "Enabled projects"
versions:
overview:

@ -149,6 +149,11 @@ OpenProject::Application.routes.draw do
get '/roles/workflow/:id/:role_id/:type_id' => 'roles#workflow'
get '/help/:ctrl/:page' => 'help#index'
get '/types/:id/edit/:tab' => "types#edit",
as: "edit_type_tab"
match '/types/:id/update/:tab' => "types#update",
as: "update_type_tab",
via: [:post, :patch]
resources :types do
post 'move/:id', action: 'move', on: :collection
end
@ -171,6 +176,7 @@ OpenProject::Application.routes.draw do
as: :delete_option_of
end
end
get '(projects/:project_id)/search' => 'search#index', as: 'search'
# only providing routes for journals when there are multiple subclasses of journals

@ -29,15 +29,15 @@
require 'spec_helper'
describe TypesController, type: :controller do
let(:project) {
let(:project) do
FactoryGirl.create(:project,
work_package_custom_fields: [custom_field_2])
}
let(:custom_field_1) {
end
let(:custom_field_1) do
FactoryGirl.create(:work_package_custom_field,
field_format: 'string',
is_for_all: true)
}
end
let(:custom_field_2) { FactoryGirl.create(:work_package_custom_field) }
let(:status_0) { FactoryGirl.create(:status) }
let(:status_1) { FactoryGirl.create(:status) }
@ -51,7 +51,7 @@ describe TypesController, type: :controller do
describe 'GET index' do
describe 'the access should be restricted' do
before do get 'index' end
before { get 'index' }
it { expect(response.status).to eq(403) }
end
@ -59,7 +59,7 @@ describe TypesController, type: :controller do
describe 'GET new' do
describe 'the access should be restricted' do
before do get 'new' end
before { get 'new' }
it { expect(response.status).to eq(403) }
end
@ -67,7 +67,7 @@ describe TypesController, type: :controller do
describe 'GET edit' do
describe 'the access should be restricted' do
before do get 'edit' end
before { get 'edit' }
it { expect(response.status).to eq(403) }
end
@ -75,7 +75,7 @@ describe TypesController, type: :controller do
describe 'POST create' do
describe 'the access should be restricted' do
before do post 'create' end
before { post 'create' }
it { expect(response.status).to eq(403) }
end
@ -83,7 +83,7 @@ describe TypesController, type: :controller do
describe 'DELETE destroy' do
describe 'the access should be restricted' do
before do delete 'destroy' end
before { delete 'destroy' }
it { expect(response.status).to eq(403) }
end
@ -91,7 +91,7 @@ describe TypesController, type: :controller do
describe 'POST update' do
describe 'the access should be restricted' do
before do post 'update' end
before { post 'update' }
it { expect(response.status).to eq(403) }
end
@ -99,7 +99,7 @@ describe TypesController, type: :controller do
describe 'POST move' do
describe 'the access should be restricted' do
before do post 'move' end
before { post 'move' }
it { expect(response.status).to eq(403) }
end
@ -114,24 +114,25 @@ describe TypesController, type: :controller do
end
describe 'GET index' do
before do get 'index' end
before { get 'index' }
it { expect(response).to be_success }
it { expect(response).to render_template 'index' }
end
describe 'GET new' do
before do get 'new' end
before { get 'new' }
it { expect(response).to be_success }
it { expect(response).to render_template 'new' }
end
describe 'POST create' do
describe 'WITH valid params' do
let(:params) {
let(:params) do
{ 'type' => { name: 'New type',
project_ids: { '1' => project.id },
custom_field_ids: { '1' => custom_field_1.id, '2' => custom_field_2.id }
} } }
custom_field_ids: { '1' => custom_field_1.id,
'2' => custom_field_2.id } } }
end
before do
post :create, params: params
@ -143,11 +144,12 @@ describe TypesController, type: :controller do
describe 'WITH an empty name' do
render_views
let(:params) {
let(:params) do
{ 'type' => { name: '',
project_ids: { '1' => project.id },
custom_field_ids: { '1' => custom_field_1.id, '2' => custom_field_2.id }
} } }
custom_field_ids: { '1' => custom_field_1.id,
'2' => custom_field_2.id } } }
end
before do
post :create, params: params
@ -161,18 +163,19 @@ describe TypesController, type: :controller do
describe 'WITH workflow copy' do
let!(:existing_type) { FactoryGirl.create(:type, name: 'Existing type') }
let!(:workflow) {
let!(:workflow) do
FactoryGirl.create(:workflow,
old_status: status_0,
new_status: status_1,
type_id: existing_type.id)
}
let(:params) {
end
let(:params) do
{ 'type' => { name: 'New type',
project_ids: { '1' => project.id },
custom_field_ids: { '1' => custom_field_1.id, '2' => custom_field_2.id } },
'copy_workflow_from' => existing_type.id
} }
'copy_workflow_from' => existing_type.id }
end
before do
post :create, params: params
@ -181,53 +184,96 @@ describe TypesController, type: :controller do
it { expect(response).to be_redirect }
it { expect(response).to redirect_to(types_path) }
it 'should have the copied workflows' do
expect(::Type.find_by(name: 'New type').workflows.count).to eq(existing_type.workflows.count)
expect(::Type.find_by(name: 'New type')
.workflows.count).to eq(existing_type.workflows.count)
end
end
end
describe 'GET edit' do
describe 'GET edit settings' do
render_views
let(:type) { FactoryGirl.create(:type, name: 'My type', is_milestone: true, projects: [project]) }
let(:type) do
FactoryGirl.create(:type, name: 'My type',
is_milestone: true,
projects: [project])
end
before do
get 'edit', params: { id: type.id }
get 'edit', params: { id: type.id, tab: :settings }
end
it { expect(response).to be_success }
it { expect(response).to render_template 'edit' }
it { expect(response).to render_template 'types/form/_settings' }
it { expect(response.body).to have_selector "input[@name='type[name]'][@value='My type']" }
it { expect(response.body).to have_selector "input[@name='type[project_ids][]'][@value='#{project.id}'][@checked='checked']" }
it { expect(response.body).to have_selector "input[@name='type[is_milestone]'][@value='1'][@checked='checked']" }
end
describe 'GET edit projects' do
render_views
let(:type) do
FactoryGirl.create(:type, name: 'My type',
is_milestone: true,
projects: [project])
end
before do
get 'edit', params: { id: type.id, tab: :projects }
end
it { expect(response).to be_success }
it { expect(response).to render_template 'edit' }
it { expect(response).to render_template 'types/form/_projects' }
it { expect(response.body).to have_selector "input[@name='type[project_ids][]'][@value='#{project.id}'][@checked='checked']" }
end
describe 'POST update' do
let(:project2) { FactoryGirl.create(:project) }
let(:type) { FactoryGirl.create(:type, name: 'My type', is_milestone: true, projects: [project, project2]) }
let(:type) do
FactoryGirl.create(:type, name: 'My type',
is_milestone: true,
projects: [project, project2])
end
describe 'WITH type rename' do
let(:params) { { 'id' => type.id, 'type' => { name: 'My type renamed' } } }
let(:params) do
{ 'id' => type.id,
'type' => { name: 'My type renamed' },
'tab' => "settings" }
end
before do
put :update, params: params
end
it { expect(response).to be_redirect }
it { expect(response).to redirect_to(edit_type_path(id: type.id)) }
it do
expect(response).to(
redirect_to(edit_type_tab_path(id: type.id, tab: "settings"))
)
end
it 'should be renamed' do
expect(::Type.find_by(name: 'My type renamed').id).to eq(type.id)
end
end
describe 'WITH projects removed' do
let(:params) { { 'id' => type.id, 'type' => { project_ids: [''] } } }
let(:params) do
{ 'id' => type.id,
'type' => { project_ids: [''] },
'tab' => "projects" }
end
before do
put :update, params: params
end
it { expect(response).to be_redirect }
it { expect(response).to redirect_to(edit_type_path(id: type.id)) }
it do
expect(response).to(
redirect_to(edit_type_tab_path(id: type.id, tab: :projects))
)
end
it 'should have no projects assigned' do
expect(::Type.find_by(name: 'My type').projects.count).to eq(0)
end
@ -273,17 +319,17 @@ describe TypesController, type: :controller do
end
describe 'detroy type in use should fail' do
let(:project2) {
let(:project2) do
FactoryGirl.create(:project,
work_package_custom_fields: [custom_field_2],
types: [type2])
}
let!(:work_package) {
end
let!(:work_package) do
FactoryGirl.create(:work_package,
author: current_user,
type: type2,
project: project2)
}
end
let(:params) { { 'id' => type2.id } }
before do
@ -303,9 +349,7 @@ describe TypesController, type: :controller do
describe 'destroy standard type should fail' do
let(:params) { { 'id' => type3.id } }
before do
delete :destroy, params: params
end
before { delete :destroy, params: params }
it { expect(response).to be_redirect }
it { expect(response).to redirect_to(types_path) }

@ -49,7 +49,7 @@ describe 'form configuration', type: :feature, js: true do
before do
allow(User).to receive(:current).and_return current_user
visit edit_type_path(id: type.id)
visit edit_type_tab_path(id: type.id, tab: "form_configuration")
end
shared_examples 'attribute visibility' do

@ -26,7 +26,7 @@
#
# See doc/COPYRIGHT.rdoc for more details.
#++
require 'legacy_spec_helper'
require_relative '../legacy_spec_helper'
require 'types_controller'
describe TypesController, type: :controller do
@ -78,33 +78,38 @@ describe TypesController, type: :controller do
it 'should get edit' do
::Type.find(1).project_ids = [1, 3]
get :edit, id: 1
get :edit, id: 1, tab: 'settings'
assert_response :success
assert_template 'edit'
assert_template 'types/form/_settings'
assert_select 'input', attributes: { name: 'type[project_ids][]',
value: '1',
checked: 'checked' }
value: '1',
checked: 'checked' }
assert_select 'input', attributes: { name: 'type[project_ids][]',
value: '2',
checked: nil }
value: '2',
checked: nil }
assert_select 'input', attributes: { name: 'type[project_ids][]',
value: '',
type: 'hidden' }
value: '',
type: 'hidden' }
end
it 'should post update' do
post :update, id: 1, type: { name: 'Renamed',
project_ids: ['1', '2', ''] }
it 'should post update name' do
post :update, id: 1, tab: "settings", type: { name: 'Renamed' }
assert_equal "Renamed", ::Type.find(1).name
assert_redirected_to action: 'edit'
end
it 'should post update projects' do
post :update, id: 1, tab: "projects", type: { project_ids: ['1', '2', ''] }
assert_redirected_to action: 'edit'
assert_equal [1, 2], ::Type.find(1).project_ids.sort
end
it 'should post update without projects' do
post :update, id: 1, type: { name: 'Renamed',
project_ids: [''] }
post :update, id: 1, tab: "projects", type: { project_ids: [''] }
assert_redirected_to action: 'edit'
assert ::Type.find(1).project_ids.empty?
end

Loading…
Cancel
Save