From 6d7ee9dcb3ab073ec7ca0fb6ec9be5c27cc1812f Mon Sep 17 00:00:00 2001 From: Yuichi HARADA Date: Thu, 12 Aug 2021 17:30:47 +0900 Subject: [PATCH 3/5] Modify tests for custom fields configurable/switchable per project --- .../context_menus_controller_test.rb | 2 +- .../custom_fields_controller_test.rb | 98 ++++++------ test/functional/issues_controller_test.rb | 2 +- .../project_enumerations_controller_test.rb | 25 +++ test/functional/projects_controller_test.rb | 4 +- .../projects_custom_fields_visibility_test.rb | 145 ++++++++++++++++++ test/functional/timelog_controller_test.rb | 6 +- .../timelog_custom_fields_visibility_test.rb | 57 ++++++- test/helpers/application_helper_test.rb | 2 +- .../integration/api_test/time_entries_test.rb | 2 +- test/unit/custom_field_test.rb | 50 +++--- test/unit/project_test.rb | 12 +- test/unit/query_test.rb | 2 +- test/unit/time_entry_custom_field_test.rb | 10 +- 14 files changed, 324 insertions(+), 93 deletions(-) create mode 100644 test/functional/projects_custom_fields_visibility_test.rb diff --git a/test/functional/context_menus_controller_test.rb b/test/functional/context_menus_controller_test.rb index ccbc4dfba3..b0ce363e2c 100644 --- a/test/functional/context_menus_controller_test.rb +++ b/test/functional/context_menus_controller_test.rb @@ -419,7 +419,7 @@ class ContextMenusControllerTest < Redmine::ControllerTest end def test_time_entries_context_menu_should_include_custom_fields - field = TimeEntryCustomField.generate!(:name => "Field", :field_format => "list", :possible_values => ["foo", "bar"]) + field = TimeEntryCustomField.generate!(:name => "Field", :field_format => "list", :possible_values => ["foo", "bar"], :is_for_all => true) @request.session[:user_id] = 2 get( diff --git a/test/functional/custom_fields_controller_test.rb b/test/functional/custom_fields_controller_test.rb index 8f3d410d8c..7536333611 100644 --- a/test/functional/custom_fields_controller_test.rb +++ b/test/functional/custom_fields_controller_test.rb @@ -134,6 +134,8 @@ class CustomFieldsControllerTest < Redmine::ControllerTest assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2 assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3 + assert_select 'input[type=checkbox][name=?]', 'custom_field[project_ids][]', Project.count + assert_select 'input[type=hidden][name=?]', 'custom_field[project_ids][]', 1 assert_select 'input[type=hidden][name=type][value=TimeEntryCustomField]' end end @@ -157,6 +159,8 @@ class CustomFieldsControllerTest < Redmine::ControllerTest assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2 assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3 + assert_select 'input[type=checkbox][name=?]', 'custom_field[project_ids][]', Project.count + assert_select 'input[type=hidden][name=?]', 'custom_field[project_ids][]', 1 assert_select 'input[type=hidden][name=type][value=ProjectCustomField]' end end @@ -184,7 +188,7 @@ class CustomFieldsControllerTest < Redmine::ControllerTest end end - def test_new_time_entry_custom_field_should_not_show_trackers_and_projects + def test_new_time_entry_custom_field_should_not_show_trackers get( :new, :params => { @@ -195,7 +199,6 @@ class CustomFieldsControllerTest < Redmine::ControllerTest assert_select 'form#custom_field_form' do assert_select 'input[name=?]', 'custom_field[tracker_ids][]', 0 - assert_select 'input[name=?]', 'custom_field[project_ids][]', 0 end end @@ -257,7 +260,7 @@ class CustomFieldsControllerTest < Redmine::ControllerTest assert_select '[name=?]', 'custom_field[default_value]', 0 end - def test_setting_full_width_layout_shoul_be_present_only_for_long_text_issue_custom_field + def test_setting_full_width_layout_should_be_present_only_for_long_text_issue_custom_field get( :new, :params => { @@ -330,47 +333,54 @@ class CustomFieldsControllerTest < Redmine::ControllerTest tracker_ids = [1, 2] project_ids = [1, 2, 3] - copy_from = CustomField.find(1) - copy_from.role_ids = role_ids - copy_from.tracker_ids = tracker_ids - copy_from.project_ids = project_ids - copy_from.save - - get :new, :params => {:copy => copy_from.id.to_s, :type => IssueCustomField} - assert_response :success - - assert_select 'form' do - # field_format selected - assert_select 'select[name=?]', 'custom_field[field_format]' do - assert_select "option[value=\"#{copy_from.field_format}\"][selected=selected]" - end - # blank name - assert_select 'input[name=?][value=""]', 'custom_field[name]' - # description copied - assert_select 'textarea[name=?]', 'custom_field[description]', :text => copy_from.description - # role checked - role_ids.each do |role_id| - assert_select "input[type=checkbox][name=?][value=#{role_id}][checked=checked]", 'custom_field[role_ids][]' - end - # role not checked - (Role.givable.pluck(:id) - role_ids).each do |role_id| - assert_select "input[type=checkbox][name=?][value=#{role_id}]", 'custom_field[role_ids][]' - end - # tracker checked - tracker_ids.each do |tracker_id| - assert_select "input[type=checkbox][name=?][value=#{tracker_id}][checked=checked]", 'custom_field[tracker_ids][]' - end - # tracker not checked - (Tracker.all.pluck(:id) - tracker_ids).each do |tracker_id| - assert_select "input[type=checkbox][name=?][value=#{tracker_id}]", 'custom_field[tracker_ids][]' - end - # project checked - project_ids.each do |project_id| - assert_select "input[type=checkbox][name=?][value=#{project_id}][checked=checked]", 'custom_field[project_ids][]' - end - # project not checked - (Project.all.pluck(:id) - project_ids).each do |project_id| - assert_select "input[type=checkbox][name=?][value=#{project_id}]", 'custom_field[project_ids][]' + [ + CustomField.find(1), # IssueCustomField + CustomField.find(3), # ProjectCustomField + CustomField.find(10), # TimeEntryCustomField + ].each do |copy_from| + copy_from.role_ids = role_ids + copy_from.tracker_ids = tracker_ids if copy_from.is_a?(IssueCustomField) + copy_from.project_ids = project_ids + copy_from.save + + get :new, :params => {:copy => copy_from.id.to_s, :type => copy_from.class} + assert_response :success + + assert_select 'form' do + # field_format selected + assert_select 'select[name=?]', 'custom_field[field_format]' do + assert_select "option[value=\"#{copy_from.field_format}\"][selected=selected]" + end + # blank name + assert_select 'input[name=?][value=""]', 'custom_field[name]' + # description copied + assert_select 'textarea[name=?]', 'custom_field[description]', :text => copy_from.description + # role checked + role_ids.each do |role_id| + assert_select "input[type=checkbox][name=?][value=#{role_id}][checked=checked]", 'custom_field[role_ids][]' + end + # role not checked + (Role.givable.pluck(:id) - role_ids).each do |role_id| + assert_select "input[type=checkbox][name=?][value=#{role_id}]", 'custom_field[role_ids][]' + end + if copy_from.is_a?(IssueCustomField) + # tracker checked + tracker_ids.each do |tracker_id| + assert_select "input[type=checkbox][name=?][value=#{tracker_id}][checked=checked]", 'custom_field[tracker_ids][]' + end + # tracker not checked + (Tracker.all.pluck(:id) - tracker_ids).each do |tracker_id| + assert_select "input[type=checkbox][name=?][value=#{tracker_id}]", 'custom_field[tracker_ids][]' + end + end + # project checked + project_ids.each do |project_id| + assert_select "input[type=checkbox][name=?][value=#{project_id}][checked=checked]", 'custom_field[project_ids][]' + end + # project not checked + (Project.all.pluck(:id) - project_ids).each do |project_id| + assert_select "input[type=checkbox][name=?][value=#{project_id}]", 'custom_field[project_ids][]' + end end end end diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index d90dcfaccb..3cc8bb92b2 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -298,7 +298,7 @@ class IssuesControllerTest < Redmine::ControllerTest def test_index_with_project_custom_field_filter field = ProjectCustomField. - create!(:name => 'Client', :is_filter => true, :field_format => 'string') + create!(:name => 'Client', :is_filter => true, :field_format => 'string', :is_for_all => true) CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo') CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo') filter_name = "project.cf_#{field.id}" diff --git a/test/functional/project_enumerations_controller_test.rb b/test/functional/project_enumerations_controller_test.rb index 3c4f44f32e..7f7d089ccc 100644 --- a/test/functional/project_enumerations_controller_test.rb +++ b/test/functional/project_enumerations_controller_test.rb @@ -213,6 +213,31 @@ class ProjectEnumerationsControllerTest < Redmine::ControllerTest "Time Entries are not assigned to system activities" end + def test_update_could_be_switch_availability_of_time_entry_custom_field + custom_field = TimeEntryCustomField.generate!(:is_for_all => false) + project = Project.find(1) + refute_includes project.time_entry_custom_fields, custom_field + + @request.session[:user_id] = 2 # manager + put( + :update, + :params => { + :project_id => 1, + :enumerations => { + "11"=>{"parent_id"=>"11", "custom_field_values"=>{"7"=>"1"}, "active"=>"1"} # QA, no changes + }, + :project => { + 'time_entry_custom_field_ids' => [custom_field.id.to_s] + } + } + ) + assert_response :redirect + assert_redirected_to '/projects/ecookbook/settings/activities' + + project.reload + assert_includes project.time_entry_custom_fields, custom_field + end + def test_destroy @request.session[:user_id] = 2 # manager project_activity = TimeEntryActivity.new({ diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb index 2c3cb2968e..1e31c39204 100644 --- a/test/functional/projects_controller_test.rb +++ b/test/functional/projects_controller_test.rb @@ -688,8 +688,8 @@ class ProjectsControllerTest < Redmine::ControllerTest end def test_show_should_not_display_blank_custom_fields_with_multiple_values - f1 = ProjectCustomField.generate! :field_format => 'list', :possible_values => %w(Foo Bar), :multiple => true - f2 = ProjectCustomField.generate! :field_format => 'list', :possible_values => %w(Baz Qux), :multiple => true + f1 = ProjectCustomField.generate! :field_format => 'list', :possible_values => %w(Foo Bar), :multiple => true, :is_for_all => true + f2 = ProjectCustomField.generate! :field_format => 'list', :possible_values => %w(Baz Qux), :multiple => true, :is_for_all => true project = Project.generate!(:custom_field_values => {f2.id.to_s => %w(Qux)}) get(:show, :params => {:id => project.id}) assert_response :success diff --git a/test/functional/projects_custom_fields_visibility_test.rb b/test/functional/projects_custom_fields_visibility_test.rb new file mode 100644 index 0000000000..4a878c95b4 --- /dev/null +++ b/test/functional/projects_custom_fields_visibility_test.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006-2021 Jean-Philippe Lang +# +# 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. + +require File.expand_path('../../test_helper', __FILE__) + +class ProjectsCustomFieldsVisibilityTest < Redmine::ControllerTest + tests ProjectsController + fixtures :projects, :members, :roles, :member_roles, + :users, + :custom_fields, :custom_values, :custom_fields_projects + + def test_index_should_show_visible_custom_fields_only + prepare_test_data + + with_settings project_list_display_type: 'list' do + @users_to_test.each do |user, fields| + @request.session[:user_id] = user.id + get :index, params: { + c: (['identifier'] + @fields.map{|f| "cf_#{f.id}"}) + } + @fields.each_with_index do |field, i| + if fields.include?(field) + assert_select 'td', {text: "Value#{i}", count: 1}, "User #{user.id} was not able to view #{field.name}" + else + assert_select 'td', {text: "Value#{i}", count: 0}, "User #{user.id} was able to view #{field.name}" + end + end + end + end + end + + def test_index_as_csv_should_show_visible_custom_fields_only + prepare_test_data + + with_settings project_list_display_type: 'list' do + @users_to_test.each do |user, fields| + @request.session[:user_id] = user.id + get :index, params: { + c: (['identifier'] + @fields.map{|f| "cf_#{f.id}"}), + format: 'csv' + } + @fields.each_with_index do |field, i| + if fields.include?(field) + assert_include "Value#{i}", response.body, "User #{user.id} was not able to view #{field.name} in CSV" + else + assert_not_include "Value#{i}", response.body, "User #{user.id} was able to view #{field.name} in CSV" + end + end + end + end + end + + def test_settings_should_not_show_custom_fields_not_visible_for_user + project_cf = ProjectCustomField.find(3) + project_cf.visible = false + project_cf.role_ids = [2] # Developer + project_cf.save! + + @request.session[:user_id] = 2 # Manager + get :settings, params: { + id: 1 + } + + assert_response :success + assert_select 'select#project_custom_field_values_3', 0 + assert_select 'input[type=checkbox][name="project[project_custom_field_ids][]"][value="3"]' + end + + def test_show_should_not_show_custom_fields_not_visible_for_user + project_cf = ProjectCustomField.find(3) + project_cf.visible = false + project_cf.role_ids = [2] # Developer + project_cf.save! + + @request.session[:user_id] = 2 # Manager + get :show, params: { + id: 1 + } + + assert_response :success + assert_select 'li.list_cf.cf_3', 0 + end + + def test_show_should_not_show_custom_fields_not_available_for_project + project_cf = ProjectCustomField.find(3) + project_cf.visible = true + project_cf.is_for_all = false + project_cf.project_ids = [2] + project_cf.save! + + @request.session[:user_id] = 2 + get :show, params: { + id: 1 + } + + assert_response :success + assert_select 'li.list_cf.cf_3', 0 + end + + private + + def prepare_test_data + field_attributes = {field_format: 'string', is_for_all: true, is_filter: true} + @fields = [] + @fields << (field1 = ProjectCustomField.create!(field_attributes.merge(name: 'Field 1', visible: true))) + @fields << (field2 = ProjectCustomField.create!(field_attributes.merge(name: 'Field 2', visible: false, role_ids: [1, 2]))) + @fields << (field3 = ProjectCustomField.create!(field_attributes.merge(name: 'Field 3', visible: false, role_ids: [1, 3]))) + project = Project.find(1) + project.safe_attributes = { + custom_field_values: {field1.id => 'Value0', field2.id => 'Value1', field3.id => 'Value2'} + }; + project.save! + + user_with_role_on_other_project = User.generate! + User.add_to_project(user_with_role_on_other_project, Project.find(2), Role.find(3)) + + @users_to_test = { + User.find(1) => [field1, field2, field3], + User.find(3) => [field1, field2], + user_with_role_on_other_project => [field1], # should see field1 only on Project 1 + User.generate! => [field1], + User.anonymous => [field1], + } + + Member.where(project_id: 1).each do |member| + member.destroy unless @users_to_test.key?(member.principal) + end + end +end diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb index b1a4899cc4..3103f9ca6d 100644 --- a/test/functional/timelog_controller_test.rb +++ b/test/functional/timelog_controller_test.rb @@ -859,7 +859,7 @@ class TimelogControllerTest < Redmine::ControllerTest end def test_bulk_update_clear_custom_field - field = TimeEntryCustomField.generate!(:field_format => 'string') + field = TimeEntryCustomField.generate!(:field_format => 'string', :is_for_all => true) @request.session[:user_id] = 2 post( :bulk_update, @@ -1467,7 +1467,7 @@ class TimelogControllerTest < Redmine::ControllerTest end def test_index_with_time_entry_custom_field_column - field = TimeEntryCustomField.generate!(:field_format => 'string') + field = TimeEntryCustomField.generate!(:field_format => 'string', :is_for_all => true) entry = TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value'}) field_name = "cf_#{field.id}" @@ -1479,7 +1479,7 @@ class TimelogControllerTest < Redmine::ControllerTest end def test_index_with_time_entry_custom_field_sorting - field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field') + field = TimeEntryCustomField.generate!(:field_format => 'string', :name => 'String Field', :is_for_all => true) TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 1'}) TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 3'}) TimeEntry.generate!(:hours => 2.5, :custom_field_values => {field.id => 'CF Value 2'}) diff --git a/test/functional/timelog_custom_fields_visibility_test.rb b/test/functional/timelog_custom_fields_visibility_test.rb index 68f5f88895..df5a46f2d2 100644 --- a/test/functional/timelog_custom_fields_visibility_test.rb +++ b/test/functional/timelog_custom_fields_visibility_test.rb @@ -42,7 +42,12 @@ class TimelogCustomFieldsVisibilityTest < Redmine::ControllerTest get :index, :params => { :project_id => 1, :issue_id => @issue.id, - :c => (['hours'] + @fields.map{|f| "issue.cf_#{f.id}"}) + :c => (['hours'] + + @fields.map{|f| + f.is_a?(TimeEntryCustomField) ? + "cf_#{f.id}" : "#{(/(.+)CustomField/ =~ f.class.name;$1).underscore}.cf_#{f.id}" + } + ) } @fields.each_with_index do |field, i| if fields.include?(field) @@ -62,7 +67,12 @@ class TimelogCustomFieldsVisibilityTest < Redmine::ControllerTest get :index, :params => { :project_id => 1, :issue_id => @issue.id, - :c => (['hours'] + @fields.map{|f| "issue.cf_#{f.id}"}), + :c => (['hours'] + + @fields.map{|f| + f.is_a?(TimeEntryCustomField) ? + "cf_#{f.id}" : "#{(/(.+)CustomField/ =~ f.class.name;$1).underscore}.cf_#{f.id}" + } + ), :format => 'csv' } @fields.each_with_index do |field, i| @@ -125,31 +135,62 @@ class TimelogCustomFieldsVisibilityTest < Redmine::ControllerTest assert_select 'select#time_entry_custom_field_values_10', 0 end + def test_edit_should_not_show_custom_fields_not_available_for_project + time_entry_cf = TimeEntryCustomField.find(10) + time_entry_cf.visible = true + time_entry_cf.is_for_all = false + time_entry_cf.project_ids = [2] + time_entry_cf.save! + + @request.session[:user_id] = 2 + get :edit, :params => { + :id => 3, + :project_id => 1 + } + assert_response :success + assert_select 'select#time_entry_custom_field_values_10', 0 + end + private def prepare_test_data field_attributes = {:field_format => 'string', :is_for_all => true, :is_filter => true, :trackers => Tracker.all} + field_attributes_exclude_trackers = field_attributes.reject{|k,v|k == :trackers} @fields = [] @fields << (@field1 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 1', :visible => true))) @fields << (@field2 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 2', :visible => false, :role_ids => [1, 2]))) @fields << (@field3 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 3', :visible => false, :role_ids => [1, 3]))) + @fields << (@field4 = TimeEntryCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 4', :visible => true))) + @fields << (@field5 = TimeEntryCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 5', :visible => false, :role_ids => [1, 2]))) + @fields << (@field6 = TimeEntryCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 6', :visible => false, :role_ids => [1, 3]))) + @fields << (@field7 = ProjectCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 7', :visible => true))) + @fields << (@field8 = ProjectCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 8', :visible => false, :role_ids => [1, 2]))) + @fields << (@field9 = ProjectCustomField.create!(field_attributes_exclude_trackers.merge(:name => 'Field 9', :visible => false, :role_ids => [1, 3]))) @issue = Issue.generate!( :author_id => 1, :project_id => 1, :tracker_id => 1, :custom_field_values => {@field1.id => 'Value0', @field2.id => 'Value1', @field3.id => 'Value2'} ) - TimeEntry.generate!(:issue => @issue) + TimeEntry.generate!( + :issue => @issue, + :custom_field_values => {@field4.id => 'Value3', @field5.id => 'Value4', @field6.id => 'Value5'} + ) + project = Project.find(1) + project.safe_attributes = { + :custom_field_values => {@field7.id => 'Value6', @field8.id => 'Value7', @field9.id => 'Value8'} + }; + project.save! @user_with_role_on_other_project = User.generate! User.add_to_project(@user_with_role_on_other_project, Project.find(2), Role.find(3)) @users_to_test = { - User.find(1) => [@field1, @field2, @field3], - User.find(3) => [@field1, @field2], - @user_with_role_on_other_project => [@field1], # should see field1 only on Project 1 - User.generate! => [@field1], - User.anonymous => [@field1] + User.find(1) => [@field1, @field2, @field3, @field4, @field5, @field6, @field7, @field8, @field9], + User.find(3) => [@field1, @field2, @field4, @field5, @field7, @field8], + @user_with_role_on_other_project => [@field1, @field4, @field7], # should see field1,field4,field7 only on Project 1 + User.generate! => [@field1, @field4, @field7], + User.anonymous => [@field1, @field4, @field7], } Member.where(:project_id => 1).each do |member| diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index 6caafcb89c..9afa437012 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -1815,7 +1815,7 @@ class ApplicationHelperTest < Redmine::HelperTest end def test_link_to_attachment_container - field = ProjectCustomField.generate!(:name => "File", :field_format => 'attachment') + field = ProjectCustomField.generate!(:name => "File", :field_format => 'attachment', :is_for_all => true) project = projects(:projects_001) project_custom_value_attachment = new_record(Attachment) do project.custom_field_values = {field.id => {:file => mock_file}} diff --git a/test/integration/api_test/time_entries_test.rb b/test/integration/api_test/time_entries_test.rb index a8f54d9200..128db310da 100644 --- a/test/integration/api_test/time_entries_test.rb +++ b/test/integration/api_test/time_entries_test.rb @@ -89,7 +89,7 @@ class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base end test "POST /time_entries.xml with issue_id should accept custom fields" do - field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string') + field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string', :is_for_all => true) assert_difference 'TimeEntry.count' do post( diff --git a/test/unit/custom_field_test.rb b/test/unit/custom_field_test.rb index 1c058ec072..5eb3944b2c 100644 --- a/test/unit/custom_field_test.rb +++ b/test/unit/custom_field_test.rb @@ -22,7 +22,8 @@ require File.expand_path('../../test_helper', __FILE__) class CustomFieldTest < ActiveSupport::TestCase fixtures :custom_fields, :roles, :projects, :trackers, :issue_statuses, - :issues, :users + :issues, :users, + :time_entries, :members, :member_roles, :custom_fields_projects def setup User.current = nil @@ -260,10 +261,10 @@ class CustomFieldTest < ActiveSupport::TestCase def test_changing_multiple_to_false_should_delete_multiple_values field = ProjectCustomField.create!(:name => 'field', :field_format => 'list', :multiple => 'true', - :possible_values => ['field1', 'field2']) + :possible_values => ['field1', 'field2'], :is_for_all => true) other = ProjectCustomField.create!(:name => 'other', :field_format => 'list', :multiple => 'true', - :possible_values => ['other1', 'other2']) + :possible_values => ['other1', 'other2'], :is_for_all => true) item_with_multiple_values = Project.generate!(:custom_field_values => {field.id => ['field1', 'field2'], other.id => ['other1', 'other2']}) @@ -349,19 +350,27 @@ class CustomFieldTest < ActiveSupport::TestCase assert_equal -12.5, field.cast_value('-12.5') end - def test_project_custom_field_visibility - project_field = ProjectCustomField.generate!(:visible => false, :field_format => 'list', :possible_values => %w[a b c]) - project = Project.find(3) - project.custom_field_values = {project_field.id => 'a'} - - # Admins can find projects with the field - with_current_user(User.find(1)) do - assert_includes Project.where(project_field.visibility_by_project_condition), project - end - - # The field is not visible to normal users - with_current_user(User.find(2)) do - refute_includes Project.where(project_field.visibility_by_project_condition), project + def test_custom_field_visibility_by_project_condition + Member.create!(:principal => User.find(2), :project_id => 3, :role_ids => [1]) + [Issue.find(5), TimeEntry.find(4), Project.find(3)].each do |customized_obj| + customized_klass = customized_obj.class + custom_field_klass = "#{customized_klass.name}CustomField".constantize + custom_field = custom_field_klass.generate!( + :field_format => 'list', :possible_values => %w[a b c], + :visible => false, :role_ids => [2], + :is_for_all => false, :project_ids => [3] + ) + customized_obj.custom_field_values = {custom_field.id => 'a'} + + # Admins can find customized objects with the field + with_current_user(User.find(1)) do + assert_includes customized_klass.where(custom_field.visibility_by_project_condition), customized_obj + end + + # The field is not visible to normal users + with_current_user(User.find(2)) do + refute_includes customized_klass.where(custom_field.visibility_by_project_condition), customized_obj + end end end @@ -417,8 +426,11 @@ class CustomFieldTest < ActiveSupport::TestCase end def test_copy_from_should_copy_projects - issue_custom_field = IssueCustomField.new(:name => 'IssueCustomField', :project_ids => [1, 2, 3, 4, 5, 6]) - copy = IssueCustomField.new.copy_from(issue_custom_field) - assert_equal [1, 2, 3, 4, 5, 6], copy.project_ids + %w(IssueCustomField TimeEntryCustomField ProjectCustomField).each do |klass_name| + klass = klass_name.constantize + custom_field = klass.new(:name => klass_name, :project_ids => [1, 2, 3, 4, 5, 6]) + copy = klass.new.copy_from(custom_field) + assert_equal [1, 2, 3, 4, 5, 6], copy.project_ids + end end end diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index 7a0e9934fa..d23989b56d 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -1094,11 +1094,11 @@ class ProjectTest < ActiveSupport::TestCase def test_safe_attributes_should_include_only_custom_fields_visible_to_user cf1 = ProjectCustomField.create!(:name => 'Visible field', :field_format => 'string', - :visible => false, :role_ids => [1]) + :visible => false, :role_ids => [1], :is_for_all => true) cf2 = ProjectCustomField.create!(:name => 'Non visible field', :field_format => 'string', - :visible => false, :role_ids => [3]) - user = User.find(2) + :visible => false, :role_ids => [3], :is_for_all => true) + User.current = User.find(2) project = Project.find(1) project.send( @@ -1107,8 +1107,7 @@ class ProjectTest < ActiveSupport::TestCase 'custom_field_values' => { cf1.id.to_s => 'value1', cf2.id.to_s => 'value2' } - }, - user + } ) assert_equal 'value1', project.custom_field_value(cf1) assert_nil project.custom_field_value(cf2) @@ -1121,8 +1120,7 @@ class ProjectTest < ActiveSupport::TestCase {'id' => cf1.id.to_s, 'value' => 'valuea'}, {'id' => cf2.id.to_s, 'value' => 'valueb'} ] - }, - user + } ) assert_equal 'valuea', project.custom_field_value(cf1) assert_nil project.custom_field_value(cf2) diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index ccf30f4773..e7e172ea72 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -1161,7 +1161,7 @@ class QueryTest < ActiveSupport::TestCase end def test_filter_on_project_custom_field - field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string') + field = ProjectCustomField.create!(:name => 'Client', :is_filter => true, :field_format => 'string', :is_for_all => true) CustomValue.create!(:custom_field => field, :customized => Project.find(3), :value => 'Foo') CustomValue.create!(:custom_field => field, :customized => Project.find(5), :value => 'Foo') diff --git a/test/unit/time_entry_custom_field_test.rb b/test/unit/time_entry_custom_field_test.rb index 4d52667b62..55b45d5eff 100644 --- a/test/unit/time_entry_custom_field_test.rb +++ b/test/unit/time_entry_custom_field_test.rb @@ -49,17 +49,17 @@ class TimeEntryCustomFieldTest < ActiveSupport::TestCase def test_safe_attributes_should_include_only_custom_fields_visible_to_user cf1 = TimeEntryCustomField.create!(:name => 'Visible field', :field_format => 'string', - :visible => false, :role_ids => [1]) + :visible => false, :role_ids => [1], :is_for_all => true) cf2 = TimeEntryCustomField.create!(:name => 'Non visible field', :field_format => 'string', - :visible => false, :role_ids => [3]) - user = User.find(2) + :visible => false, :role_ids => [3], :is_for_all => true) + User.current = User.find(2) time_entry = TimeEntry.new(:issue_id => 1) time_entry.send :safe_attributes=, {'custom_field_values' => { cf1.id.to_s => 'value1', cf2.id.to_s => 'value2' - }}, user + }} assert_equal 'value1', time_entry.custom_field_value(cf1) assert_nil time_entry.custom_field_value(cf2) @@ -67,7 +67,7 @@ class TimeEntryCustomFieldTest < ActiveSupport::TestCase time_entry.send :safe_attributes=, {'custom_fields' => [ {'id' => cf1.id.to_s, 'value' => 'valuea'}, {'id' => cf2.id.to_s, 'value' => 'valueb'} - ]}, user + ]} assert_equal 'valuea', time_entry.custom_field_value(cf1) assert_nil time_entry.custom_field_value(cf2) -- 2.33.0