diff --git a/app/controllers/attribute_help_texts_controller.rb b/app/controllers/attribute_help_texts_controller.rb new file mode 100644 index 00000000000..7bd3c6636cf --- /dev/null +++ b/app/controllers/attribute_help_texts_controller.rb @@ -0,0 +1,112 @@ +#-- encoding: UTF-8 +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 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-2013 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 AttributeHelpTextsController < ApplicationController + layout 'admin' + menu_item :attribute_help_texts + + before_action :require_admin + before_action :find_entry, only: %i(edit update destroy) + before_action :find_type_scope + + def new + @attribute_help_text = AttributeHelpText.new type: @attribute_scope + end + + def edit; end + + def update + @attribute_help_text.attributes = permitted_params.attribute_help_text + + if @attribute_help_text.save + flash[:notice] = t(:notice_successful_update) + redirect_to attribute_help_texts_path(tab: @attribute_help_text.attribute_scope) + else + render action: 'edit' + end + end + + def create + @attribute_help_text = AttributeHelpText.new permitted_params.attribute_help_text + + if @attribute_help_text.save + flash[:notice] = t(:notice_successful_create) + redirect_to attribute_help_texts_path(tab: @attribute_help_text.attribute_scope) + else + render action: 'new' + end + end + + def destroy + if @attribute_help_text.destroy + flash[:notice] = t(:notice_successful_delete) + else + flash[:error] = t(:error_can_not_delete_entry) + end + + redirect_to attribute_help_texts_path(tab: @attribute_help_text.attribute_scope) + end + + def index + @texts_by_type = AttributeHelpText.all.group_by(&:attribute_scope) + end + + protected + + def default_breadcrumb + if action_name == 'index' + t('attribute_help_texts.label_plural') + else + ActionController::Base.helpers.link_to(t('attribute_help_texts.label_plural'), attribute_help_texts_path) + end + end + + def show_local_breadcrumb + true + end + + private + + def find_entry + @attribute_help_text = AttributeHelpText.find(params[:id]) + rescue ActiveRecord::RecordNotFound + render_404 + end + + def find_type_scope + name = params.fetch(:name, 'WorkPackage') + submodule = AttributeHelpText.available_types.find { |mod| mod == name } + + if submodule.nil? + render_404 + end + + @attribute_scope = AttributeHelpText.const_get(submodule) + end +end diff --git a/app/helpers/attribute_help_texts_helper.rb b/app/helpers/attribute_help_texts_helper.rb new file mode 100644 index 00000000000..7290a3db9ec --- /dev/null +++ b/app/helpers/attribute_help_texts_helper.rb @@ -0,0 +1,40 @@ +#-- encoding: UTF-8 + +#-- 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 AttributeHelpTextsHelper + def selectable_attributes(instance) + available = instance.class.available_attributes + used = AttributeHelpText.used_attributes(instance.type) + + available.reject! { |k, | used.include? k } + + available.map { |k, v| [v, k] } + end +end diff --git a/app/models/attribute_help_text.rb b/app/models/attribute_help_text.rb new file mode 100644 index 00000000000..ba463928b5b --- /dev/null +++ b/app/models/attribute_help_text.rb @@ -0,0 +1,30 @@ + +class AttributeHelpText < ActiveRecord::Base + def self.available_types + subclasses.map { |child| child.name.demodulize } + end + + def self.used_attributes(scope) + where(type: scope) + .select(:attribute_name) + .distinct + .pluck(:attribute_name) + end + + validates_presence_of :help_text + validates_uniqueness_of :attribute_name, scope: :type + + def attribute_caption + self.class.available_attributes[attribute_name] + end + + def attribute_scope + raise 'not implemented' + end + + def type_caption + raise 'not implemented' + end +end + +require_dependency 'attribute_help_text/work_package' diff --git a/app/models/attribute_help_text/work_package.rb b/app/models/attribute_help_text/work_package.rb new file mode 100644 index 00000000000..d72ae133ad4 --- /dev/null +++ b/app/models/attribute_help_text/work_package.rb @@ -0,0 +1,15 @@ +class AttributeHelpText::WorkPackage < AttributeHelpText + def self.available_attributes + Hash[::Query.new.available_columns.map { |c| [c.name.to_s, c.caption] }] + end + + validates_inclusion_of :attribute_name, in: available_attributes.keys + + def attribute_scope + 'WorkPackage' + end + + def type_caption + I18n.t(:label_work_package) + end +end diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index 3b95c131672..b475c9922ba 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -57,6 +57,10 @@ class PermittedParams permitted_attributes[key].concat(params) end + def attribute_help_text + params.require(:attribute_help_text).permit(*self.class.permitted_attributes[:attribute_help_text]) + end + def auth_source params.require(:auth_source).permit(*self.class.permitted_attributes[:auth_source]) end @@ -446,6 +450,11 @@ class PermittedParams def self.permitted_attributes @whitelisted_params ||= begin params = { + attribute_help_text: [ + :type, + :attribute_name, + :help_text + ], auth_source: [ :name, :host, diff --git a/app/views/attribute_help_texts/_form.html.erb b/app/views/attribute_help_texts/_form.html.erb new file mode 100644 index 00000000000..d755a1030f2 --- /dev/null +++ b/app/views/attribute_help_texts/_form.html.erb @@ -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. + +++#%> +<%= error_messages_for 'attribute_help_text' %> + +
+
+ <% if local_assigns[:editing] %> + <%= f.select :attribute_name, + [[@attribute_help_text.attribute_caption, @attribute_help_text.attribute_name]], + {}, + disabled: true + %> + <% else %> + <%= f.select :attribute_name, selectable_attributes(@attribute_help_text) %> + <% end %> +
+
+ <%= f.text_area :help_text, :cols => 100, :rows => 25, :class => 'wiki-edit' %> + <%= wikitoolbar_for("#{f.object_name}_help_text") %> +
+
diff --git a/app/views/attribute_help_texts/_tab.html.erb b/app/views/attribute_help_texts/_tab.html.erb new file mode 100644 index 00000000000..18d1fe457e8 --- /dev/null +++ b/app/views/attribute_help_texts/_tab.html.erb @@ -0,0 +1,100 @@ +<%#-- 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. + +++#%> + +<% entries = @texts_by_type[tab[:name]] || [] %> +<% if entries.any? %> +
+
+ + + + + + + + + + + + + + + + <% entries.each do |attribute_help_text| -%> + + + + + + <% end %> + +
+
+
+ + <%= AttributeHelpText.human_attribute_name(:attribute_name) %> + +
+
+
+
+
+ + <%= AttributeHelpText.human_attribute_name(:help_text) %> + +
+
+
+
+
+ <%= link_to h(attribute_help_text.attribute_caption), + edit_attribute_help_text_path(attribute_help_text) %> + + + <%= op_icon('icon icon-help2') %> + <%= t(:'attribute_help_texts.show_preview') %> + + + <%= delete_link attribute_help_text_path(attribute_help_text) %> +
+
+
+<% else %> + <%= no_results_box %> +<% end %> + +
+ <%= link_to new_attribute_help_text_path(name: tab[:name]), + { class: 'attribute-help-texts--create-button button -alt-highlight', + aria: {label: t(:'attribute_help_texts.add_new')}, + title: t(:'attribute_help_texts.add_new')} do %> + <%= op_icon('button--icon icon-add') %> + <%= t('activerecord.models.attribute_help_text') %> + <% end %> +
diff --git a/app/views/attribute_help_texts/edit.html.erb b/app/views/attribute_help_texts/edit.html.erb new file mode 100644 index 00000000000..0a6224ed276 --- /dev/null +++ b/app/views/attribute_help_texts/edit.html.erb @@ -0,0 +1,44 @@ +<%#-- 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. + +++#%> + +<% html_title t(:label_administration), l(:'attribute_help_texts.edit', attribute_caption: @attribute_help_text.attribute_caption) %> +<% local_assigns[:additional_breadcrumb] = link_to(@attribute_help_text.type_caption, + attribute_help_texts_path(tab: @attribute_help_text.attribute_scope)), + t(:'attribute_help_texts.edit', attribute_caption: @attribute_help_text.attribute_caption) %> +<%= breadcrumb_toolbar t(:'attribute_help_texts.edit', attribute_caption: @attribute_help_text.attribute_caption) +%> + +<%= labelled_tabular_form_for @attribute_help_text, + as: 'attribute_help_text', + url: { action: :update }, + html: {id: 'attribute_help_text_form'} do |f| %> + <%= render partial: 'form', locals: { f: f, editing: true } %> + <%= hidden_field_tag 'attribute_scope', @attribute_help_text.attribute_scope %> + <%= styled_button_tag l(:button_save), class: '-highlight -with-icon icon-checkmark' %> +<% end %> diff --git a/app/views/attribute_help_texts/index.html.erb b/app/views/attribute_help_texts/index.html.erb new file mode 100644 index 00000000000..ab659bab8be --- /dev/null +++ b/app/views/attribute_help_texts/index.html.erb @@ -0,0 +1,42 @@ +<%#-- 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. + +++#%> +<%= toolbar title: t(:'attribute_help_texts.label_plural') %> + +
+
+

<%= t('attribute_help_texts.text_overview') %>

+
+
+ +<%= render_tabs [ + { name: 'WorkPackage', partial: 'attribute_help_texts/tab', label: :label_work_package }, + ] +%> + +<% html_title(t(:label_administration), t(:'attribute_help_texts.label_plural')) -%> diff --git a/app/views/attribute_help_texts/new.html.erb b/app/views/attribute_help_texts/new.html.erb new file mode 100644 index 00000000000..47fd4c5fb00 --- /dev/null +++ b/app/views/attribute_help_texts/new.html.erb @@ -0,0 +1,44 @@ +<%#-- 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. + +++#%> + +<% html_title t(:label_administration), t(:'attribute_help_texts.add_new') %> +<% local_assigns[:additional_breadcrumb] = link_to(@attribute_help_text.type_caption, + attribute_help_texts_path(tab: @attribute_help_text.attribute_scope)), + t(:'attribute_help_texts.add_new') %> +<%= breadcrumb_toolbar t(:'attribute_help_texts.add_new') +%> + +<%= labelled_tabular_form_for @attribute_help_text, + as: 'attribute_help_text', + url: { action: :create }, + html: {id: 'attribute_help_text_form'} do |f| %> + <%= render partial: 'form', locals: { f: f } %> + <%= f.hidden_field :type, value: @attribute_help_text.type %> + <%= styled_button_tag l(:button_save), class: '-highlight -with-icon icon-checkmark' %> +<% end %> diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index c418e021c6d..b16a2e05582 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -162,6 +162,11 @@ Redmine::MenuManager.map :admin_menu do |menu| icon: 'icon2 icon-custom-fields', html: { class: 'custom_fields' } + menu.push :attribute_help_texts, + { controller: '/attribute_help_texts' }, + caption: :'attribute_help_texts.label_plural', + icon: 'icon2 icon-help2' + menu.push :enumerations, { controller: '/enumerations' }, icon: 'icon2 icon-enumerations' diff --git a/config/locales/en.yml b/config/locales/en.yml index 0fd1fa183ce..a00d426bb8a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -69,6 +69,13 @@ en: is_active: currently displayed is_inactive: currently not displayed + attribute_help_texts: + text_overview: 'In this view, you can create custom help texts for attributes view. When defined, these texts can be shown by clicking the help icon next to its belonging attribute.' + label_plural: 'Attribute help texts' + show_preview: 'Preview text' + add_new: 'Add help text' + edit: "Edit help text for %{attribute_caption}" + auth_sources: index: no_results_content_title: There are currently no authentication modes. @@ -297,6 +304,9 @@ en: file: "File" filename: "File" filesize: "Size" + attribute_help_text: + attribute_name: 'Attribute' + help_text: 'Help text' auth_source: account: "Account" attr_firstname: "Firstname attribute" @@ -543,6 +553,7 @@ en: models: attachment: "File" + attribute_help_text: "Attribute help text" board: "Forum" comment: "Comment" custom_field: "Custom field" @@ -868,6 +879,7 @@ en: enumeration_reported_project_statuses: "Reported project status" error_can_not_archive_project: "This project cannot be archived" + error_can_not_delete_entry: "Unable to delete entry" error_can_not_delete_custom_field: "Unable to delete custom field" error_can_not_delete_type: "This type contains work packages and cannot be deleted." error_can_not_delete_standard_type: "Standard types cannot be deleted." diff --git a/config/routes.rb b/config/routes.rb index 055cac04a2e..0e2456febf5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -381,6 +381,8 @@ OpenProject::Application.routes.draw do post 'design/colors' => 'custom_styles#update_colors', as: 'update_design_colors' resource :custom_style, only: [:update, :show, :create], path: 'design' + resources :attribute_help_texts, only: %i(index new create edit update destroy) + resources :groups do member do get :autocomplete_for_user diff --git a/db/migrate/20170703075208_add_attribute_help_texts.rb b/db/migrate/20170703075208_add_attribute_help_texts.rb new file mode 100644 index 00000000000..1f2b575e8b0 --- /dev/null +++ b/db/migrate/20170703075208_add_attribute_help_texts.rb @@ -0,0 +1,11 @@ +class AddAttributeHelpTexts < ActiveRecord::Migration[5.0] + def change + create_table :attribute_help_texts do |t| + t.text :help_text, null: false + t.string :type, null: false + t.string :attribute_name, null: false + + t.timestamps + end + end +end diff --git a/spec/controllers/attribute_help_texts_controller_spec.rb b/spec/controllers/attribute_help_texts_controller_spec.rb new file mode 100644 index 00000000000..26a8413aba0 --- /dev/null +++ b/spec/controllers/attribute_help_texts_controller_spec.rb @@ -0,0 +1,76 @@ +require 'spec_helper' + +describe AttributeHelpTextsController, type: :controller do + let(:model) { FactoryGirl.build :work_package_help_text } + before do + expect(controller).to receive(:require_admin) + end + + describe '#index' do + before do + allow(AttributeHelpText).to receive(:all).and_return [model] + + get :index + end + + it do + expect(response).to be_success + expect(assigns(:texts_by_type)).to eql('WorkPackage' => [model]) + end + end + + describe '#edit' do + context 'when not found' + before do + get :edit, params: { id: 1234 } + end + + it do + expect(response.status).to eq 404 + end + end + + context 'when found' do + before do + allow(AttributeHelpText).to receive(:find).and_return(model) + + get :edit + end + + it do + expect(response).to be_success + expect(assigns(:attribute_help_text)).to eql model + end + end + + describe '#update' do + before do + allow(AttributeHelpText).to receive(:find).and_return(model) + expect(model).to receive(:save).and_return(success) + put :update, + params: { + attribute_help_text: { + help_text: 'my new help text' + } + } + end + + context 'when save is failure' do + let(:success) { false } + it 'fails to update the announcement' do + expect(response).to be_success + expect(response).to render_template 'edit' + end + end + + context 'when save is success' do + let(:success) { true } + it 'edits the announcement' do + expect(response).to redirect_to action: :index, tab: 'WorkPackage' + expect(controller).to set_flash[:notice].to I18n.t(:notice_successful_update) + + expect(model.help_text).to eq('my new help text') + end + end + end +end diff --git a/spec/factories/attribute_help_text_factory.rb b/spec/factories/attribute_help_text_factory.rb new file mode 100644 index 00000000000..821a7ff4d7d --- /dev/null +++ b/spec/factories/attribute_help_text_factory.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :work_package_help_text, class: AttributeHelpText::WorkPackage do + type 'AttributeHelpText::WorkPackage' + help_text 'Attribute help text' + attribute_name 'id' + end +end diff --git a/spec/features/admin/attribute_help_texts_spec.rb b/spec/features/admin/attribute_help_texts_spec.rb new file mode 100644 index 00000000000..8b3de6256a1 --- /dev/null +++ b/spec/features/admin/attribute_help_texts_spec.rb @@ -0,0 +1,90 @@ +#-- 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. +#++ + +require 'spec_helper' + +describe 'Attribute help texts', type: :feature, js: true do + let(:admin) { FactoryGirl.create(:admin) } + + describe 'Work package help texts' do + before do + login_as(admin) + visit attribute_help_texts_path + end + + it 'allows CRUD to attribute help texts' do + expect(page).to have_selector('.generic-table--no-results-container') + + # Create help text + # -> new + page.find('.attribute-help-texts--create-button').click + + # Set attributes + # -> create + select 'Status', from: 'attribute_help_text_attribute_name' + fill_in 'Help text', with: 'My attribute help text' + click_button 'Save' + + # Should now show on index for editing + expect(page).to have_selector('.attribute-help-text--entry td', text: 'Status') + instance = AttributeHelpText.last + expect(instance.attribute_scope).to eq 'WorkPackage' + expect(instance.attribute_name).to eq 'status' + expect(instance.help_text).to eq 'My attribute help text' + + # -> edit + page.find('.attribute-help-text--entry td a', text: 'Status').click + expect(page).to have_selector('#attribute_help_text_attribute_name[disabled]') + fill_in 'Help text', with: '' + click_button 'Save' + + # Handle errors + expect(page).to have_selector('#errorExplanation', text: "Help text can't be blank.") + fill_in 'Help text', with: 'New help text' + click_button 'Save' + + # On index again + expect(page).to have_selector('.attribute-help-text--entry td', text: 'Status') + instance.reload + expect(instance.help_text).to eq 'New help text' + + # Create new, status is now blocked + page.find('.attribute-help-texts--create-button').click + expect(page).to have_selector('#attribute_help_text_attribute_name option', text: 'ID') + expect(page).to have_no_selector('#attribute_help_text_attribute_name option', text: 'Status') + visit attribute_help_texts_path + + # Destroy + page.find('.attribute-help-text--entry a.icon-delete').click + page.driver.browser.switch_to.alert.accept + + expect(page).to have_selector('.generic-table--no-results-container') + expect(AttributeHelpText.count).to be_zero + end + end +end diff --git a/spec/models/attribute_help_text/work_package_spec.rb b/spec/models/attribute_help_text/work_package_spec.rb new file mode 100644 index 00000000000..0a88a6cc0cb --- /dev/null +++ b/spec/models/attribute_help_text/work_package_spec.rb @@ -0,0 +1,72 @@ +require 'spec_helper' + +describe AttributeHelpText::WorkPackage, type: :model do + describe '.available_attributes' do + subject { described_class.available_attributes } + it 'returns an array of potential attributes' do + expect(subject).to be_a Hash + end + end + + describe '.used_attributes' do + let!(:instance) { FactoryGirl.create :work_package_help_text } + subject { described_class.used_attributes instance.type } + + it 'returns used attributes' do + expect(subject).to eq([instance.attribute_name]) + end + end + + describe 'validations' do + before do + allow(described_class).to receive(:available_attributes).and_return(id: 'ID') + end + + let(:attribute_name) { 'id' } + let(:help_text) { 'foobar' } + + subject { described_class.new attribute_name: attribute_name, help_text: help_text } + + context 'help_text is nil' do + let(:help_text) { nil } + + it 'validates presence of help text' do + expect(subject.valid?).to be_falsey + expect(subject.errors[:help_text].count).to eql(1) + expect(subject.errors[:help_text].first) + .to eql(I18n.t('activerecord.errors.messages.blank')) + end + end + + context 'attribute_name is nil' do + let(:attribute_name) { nil } + + it 'validates presence of attribute name' do + expect(subject.valid?).to be_falsey + expect(subject.errors[:attribute_name].count).to eql(1) + expect(subject.errors[:attribute_name].first) + .to eql(I18n.t('activerecord.errors.messages.inclusion')) + end + end + + context 'attribute_name is invalid' do + let(:attribute_name) { 'foobar' } + + it 'validates inclusion of attribute name' do + expect(subject.valid?).to be_falsey + expect(subject.errors[:attribute_name].count).to eql(1) + expect(subject.errors[:attribute_name].first) + .to eql(I18n.t('activerecord.errors.messages.inclusion')) + end + end + end + + describe 'instance' do + subject { FactoryGirl.build :work_package_help_text } + + it 'provides a caption of its type' do + expect(subject.attribute_scope).to eq 'WorkPackage' + expect(subject.type_caption).to eq I18n.t(:label_work_package) + end + end +end diff --git a/spec/routing/attribute_help_text_spec.rb b/spec/routing/attribute_help_text_spec.rb new file mode 100644 index 00000000000..c01bb9e1746 --- /dev/null +++ b/spec/routing/attribute_help_text_spec.rb @@ -0,0 +1,48 @@ +#-- 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. +#++ + +require 'spec_helper' + +describe AttributeHelpTextsController, type: :routing do + it 'should route CRUD to the controller' do + expect(get('/admin/attribute_help_texts')) + .to route_to(controller: 'attribute_help_texts', action: 'index') + + expect(get('/admin/attribute_help_texts/1/edit')) + .to route_to(controller: 'attribute_help_texts', action: 'edit', id: '1') + + expect(post('/admin/attribute_help_texts')) + .to route_to(controller: 'attribute_help_texts', action: 'create') + + expect(put('/admin/attribute_help_texts/1')) + .to route_to(controller: 'attribute_help_texts', action: 'update', id: '1') + + expect(delete('/admin/attribute_help_texts/1')) + .to route_to(controller: 'attribute_help_texts', action: 'destroy', id: '1') + end +end