You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

issues_custom_fields_visibility_test.rb 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. # Redmine - project management software
  2. # Copyright (C) 2006-2015 Jean-Philippe Lang
  3. #
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU General Public License
  6. # as published by the Free Software Foundation; either version 2
  7. # of the License, or (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. require File.expand_path('../../test_helper', __FILE__)
  18. class IssuesCustomFieldsVisibilityTest < ActionController::TestCase
  19. tests IssuesController
  20. fixtures :projects,
  21. :users, :email_addresses,
  22. :roles,
  23. :members,
  24. :member_roles,
  25. :issue_statuses,
  26. :trackers,
  27. :projects_trackers,
  28. :enabled_modules,
  29. :enumerations,
  30. :workflows
  31. def setup
  32. CustomField.delete_all
  33. Issue.delete_all
  34. field_attributes = {:field_format => 'string', :is_for_all => true, :is_filter => true, :trackers => Tracker.all}
  35. @fields = []
  36. @fields << (@field1 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 1', :visible => true)))
  37. @fields << (@field2 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 2', :visible => false, :role_ids => [1, 2])))
  38. @fields << (@field3 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 3', :visible => false, :role_ids => [1, 3])))
  39. @issue = Issue.generate!(
  40. :author_id => 1,
  41. :project_id => 1,
  42. :tracker_id => 1,
  43. :custom_field_values => {@field1.id => 'Value0', @field2.id => 'Value1', @field3.id => 'Value2'}
  44. )
  45. @user_with_role_on_other_project = User.generate!
  46. User.add_to_project(@user_with_role_on_other_project, Project.find(2), Role.find(3))
  47. @users_to_test = {
  48. User.find(1) => [@field1, @field2, @field3],
  49. User.find(3) => [@field1, @field2],
  50. @user_with_role_on_other_project => [@field1], # should see field1 only on Project 1
  51. User.generate! => [@field1],
  52. User.anonymous => [@field1]
  53. }
  54. Member.where(:project_id => 1).each do |member|
  55. member.destroy unless @users_to_test.keys.include?(member.principal)
  56. end
  57. end
  58. def test_show_should_show_visible_custom_fields_only
  59. @users_to_test.each do |user, fields|
  60. @request.session[:user_id] = user.id
  61. get :show, :id => @issue.id
  62. @fields.each_with_index do |field, i|
  63. if fields.include?(field)
  64. assert_select '.value', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name}"
  65. else
  66. assert_select '.value', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name}"
  67. end
  68. end
  69. end
  70. end
  71. def test_show_should_show_visible_custom_fields_only_in_api
  72. @users_to_test.each do |user, fields|
  73. with_settings :rest_api_enabled => '1' do
  74. get :show, :id => @issue.id, :format => 'xml', :include => 'custom_fields', :key => user.api_key
  75. end
  76. @fields.each_with_index do |field, i|
  77. if fields.include?(field)
  78. assert_select "custom_field[id=?] value", field.id.to_s, {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name} in API"
  79. else
  80. assert_select "custom_field[id=?] value", field.id.to_s, {:text => "Value#{i}", :count => 0}, "User #{user.id} was not able to view #{field.name} in API"
  81. end
  82. end
  83. end
  84. end
  85. def test_show_should_show_visible_custom_fields_only_in_history
  86. @issue.init_journal(User.find(1))
  87. @issue.custom_field_values = {@field1.id => 'NewValue0', @field2.id => 'NewValue1', @field3.id => 'NewValue2'}
  88. @issue.save!
  89. @users_to_test.each do |user, fields|
  90. @request.session[:user_id] = user.id
  91. get :show, :id => @issue.id
  92. @fields.each_with_index do |field, i|
  93. if fields.include?(field)
  94. assert_select 'ul.details i', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name} change"
  95. else
  96. assert_select 'ul.details i', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name} change"
  97. end
  98. end
  99. end
  100. end
  101. def test_show_should_show_visible_custom_fields_only_in_history_api
  102. @issue.init_journal(User.find(1))
  103. @issue.custom_field_values = {@field1.id => 'NewValue0', @field2.id => 'NewValue1', @field3.id => 'NewValue2'}
  104. @issue.save!
  105. @users_to_test.each do |user, fields|
  106. with_settings :rest_api_enabled => '1' do
  107. get :show, :id => @issue.id, :format => 'xml', :include => 'journals', :key => user.api_key
  108. end
  109. @fields.each_with_index do |field, i|
  110. if fields.include?(field)
  111. assert_select 'details old_value', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name} change in API"
  112. else
  113. assert_select 'details old_value', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name} change in API"
  114. end
  115. end
  116. end
  117. end
  118. def test_edit_should_show_visible_custom_fields_only
  119. Role.anonymous.add_permission! :edit_issues
  120. @users_to_test.each do |user, fields|
  121. @request.session[:user_id] = user.id
  122. get :edit, :id => @issue.id
  123. @fields.each_with_index do |field, i|
  124. if fields.include?(field)
  125. assert_select 'input[value=?]', "Value#{i}", 1, "User #{user.id} was not able to edit #{field.name}"
  126. else
  127. assert_select 'input[value=?]', "Value#{i}", 0, "User #{user.id} was able to edit #{field.name}"
  128. end
  129. end
  130. end
  131. end
  132. def test_update_should_update_visible_custom_fields_only
  133. Role.anonymous.add_permission! :edit_issues
  134. @users_to_test.each do |user, fields|
  135. @request.session[:user_id] = user.id
  136. put :update, :id => @issue.id,
  137. :issue => {:custom_field_values => {
  138. @field1.id.to_s => "User#{user.id}Value0",
  139. @field2.id.to_s => "User#{user.id}Value1",
  140. @field3.id.to_s => "User#{user.id}Value2",
  141. }}
  142. @issue.reload
  143. @fields.each_with_index do |field, i|
  144. if fields.include?(field)
  145. assert_equal "User#{user.id}Value#{i}", @issue.custom_field_value(field), "User #{user.id} was not able to update #{field.name}"
  146. else
  147. assert_not_equal "User#{user.id}Value#{i}", @issue.custom_field_value(field), "User #{user.id} was able to update #{field.name}"
  148. end
  149. end
  150. end
  151. end
  152. def test_index_should_show_visible_custom_fields_only
  153. @users_to_test.each do |user, fields|
  154. @request.session[:user_id] = user.id
  155. get :index, :c => (["subject"] + @fields.map{|f| "cf_#{f.id}"})
  156. @fields.each_with_index do |field, i|
  157. if fields.include?(field)
  158. assert_select 'td', {:text => "Value#{i}", :count => 1}, "User #{user.id} was not able to view #{field.name}"
  159. else
  160. assert_select 'td', {:text => "Value#{i}", :count => 0}, "User #{user.id} was able to view #{field.name}"
  161. end
  162. end
  163. end
  164. end
  165. def test_index_as_csv_should_show_visible_custom_fields_only
  166. @users_to_test.each do |user, fields|
  167. @request.session[:user_id] = user.id
  168. get :index, :c => (["subject"] + @fields.map{|f| "cf_#{f.id}"}), :format => 'csv'
  169. @fields.each_with_index do |field, i|
  170. if fields.include?(field)
  171. assert_include "Value#{i}", response.body, "User #{user.id} was not able to view #{field.name} in CSV"
  172. else
  173. assert_not_include "Value#{i}", response.body, "User #{user.id} was able to view #{field.name} in CSV"
  174. end
  175. end
  176. end
  177. end
  178. def test_index_with_partial_custom_field_visibility
  179. Issue.delete_all
  180. p1 = Project.generate!
  181. p2 = Project.generate!
  182. user = User.generate!
  183. User.add_to_project(user, p1, Role.where(:id => [1, 3]).to_a)
  184. User.add_to_project(user, p2, Role.where(:id => 3).to_a)
  185. Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueA'})
  186. Issue.generate!(:project => p2, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueB'})
  187. Issue.generate!(:project => p1, :tracker_id => 1, :custom_field_values => {@field2.id => 'ValueC'})
  188. @request.session[:user_id] = user.id
  189. get :index, :c => ["subject", "cf_#{@field2.id}"]
  190. assert_select 'td', :text => 'ValueA'
  191. assert_select 'td', :text => 'ValueB', :count => 0
  192. assert_select 'td', :text => 'ValueC'
  193. get :index, :sort => "cf_#{@field2.id}"
  194. # ValueB is not visible to user and ignored while sorting
  195. assert_equal %w(ValueB ValueA ValueC), assigns(:issues).map{|i| i.custom_field_value(@field2)}
  196. get :index, :set_filter => '1', "cf_#{@field2.id}" => '*'
  197. assert_equal %w(ValueA ValueC), assigns(:issues).map{|i| i.custom_field_value(@field2)}
  198. CustomField.update_all(:field_format => 'list')
  199. get :index, :group => "cf_#{@field2.id}"
  200. assert_equal %w(ValueA ValueC), assigns(:issues).map{|i| i.custom_field_value(@field2)}
  201. end
  202. def test_create_should_send_notifications_according_custom_fields_visibility
  203. # anonymous user is never notified
  204. users_to_test = @users_to_test.reject {|k,v| k.anonymous?}
  205. ActionMailer::Base.deliveries.clear
  206. @request.session[:user_id] = 1
  207. with_settings :bcc_recipients => '1' do
  208. assert_difference 'Issue.count' do
  209. post :create,
  210. :project_id => 1,
  211. :issue => {
  212. :tracker_id => 1,
  213. :status_id => 1,
  214. :subject => 'New issue',
  215. :priority_id => 5,
  216. :custom_field_values => {@field1.id.to_s => 'Value0', @field2.id.to_s => 'Value1', @field3.id.to_s => 'Value2'},
  217. :watcher_user_ids => users_to_test.keys.map(&:id)
  218. }
  219. assert_response 302
  220. end
  221. end
  222. assert_equal users_to_test.values.uniq.size, ActionMailer::Base.deliveries.size
  223. # tests that each user receives 1 email with the custom fields he is allowed to see only
  224. users_to_test.each do |user, fields|
  225. mails = ActionMailer::Base.deliveries.select {|m| m.bcc.include? user.mail}
  226. assert_equal 1, mails.size
  227. mail = mails.first
  228. @fields.each_with_index do |field, i|
  229. if fields.include?(field)
  230. assert_mail_body_match "Value#{i}", mail, "User #{user.id} was not able to view #{field.name} in notification"
  231. else
  232. assert_mail_body_no_match "Value#{i}", mail, "User #{user.id} was able to view #{field.name} in notification"
  233. end
  234. end
  235. end
  236. end
  237. def test_update_should_send_notifications_according_custom_fields_visibility
  238. # anonymous user is never notified
  239. users_to_test = @users_to_test.reject {|k,v| k.anonymous?}
  240. users_to_test.keys.each do |user|
  241. Watcher.create!(:user => user, :watchable => @issue)
  242. end
  243. ActionMailer::Base.deliveries.clear
  244. @request.session[:user_id] = 1
  245. with_settings :bcc_recipients => '1' do
  246. put :update,
  247. :id => @issue.id,
  248. :issue => {
  249. :custom_field_values => {@field1.id.to_s => 'NewValue0', @field2.id.to_s => 'NewValue1', @field3.id.to_s => 'NewValue2'}
  250. }
  251. assert_response 302
  252. end
  253. assert_equal users_to_test.values.uniq.size, ActionMailer::Base.deliveries.size
  254. # tests that each user receives 1 email with the custom fields he is allowed to see only
  255. users_to_test.each do |user, fields|
  256. mails = ActionMailer::Base.deliveries.select {|m| m.bcc.include? user.mail}
  257. assert_equal 1, mails.size
  258. mail = mails.first
  259. @fields.each_with_index do |field, i|
  260. if fields.include?(field)
  261. assert_mail_body_match "Value#{i}", mail, "User #{user.id} was not able to view #{field.name} in notification"
  262. else
  263. assert_mail_body_no_match "Value#{i}", mail, "User #{user.id} was able to view #{field.name} in notification"
  264. end
  265. end
  266. end
  267. end
  268. def test_updating_hidden_custom_fields_only_should_not_notifiy_user
  269. # anonymous user is never notified
  270. users_to_test = @users_to_test.reject {|k,v| k.anonymous?}
  271. users_to_test.keys.each do |user|
  272. Watcher.create!(:user => user, :watchable => @issue)
  273. end
  274. ActionMailer::Base.deliveries.clear
  275. @request.session[:user_id] = 1
  276. with_settings :bcc_recipients => '1' do
  277. put :update,
  278. :id => @issue.id,
  279. :issue => {
  280. :custom_field_values => {@field2.id.to_s => 'NewValue1', @field3.id.to_s => 'NewValue2'}
  281. }
  282. assert_response 302
  283. end
  284. users_to_test.each do |user, fields|
  285. mails = ActionMailer::Base.deliveries.select {|m| m.bcc.include? user.mail}
  286. if (fields & [@field2, @field3]).any?
  287. assert_equal 1, mails.size, "User #{user.id} was not notified"
  288. else
  289. assert_equal 0, mails.size, "User #{user.id} was notified"
  290. end
  291. end
  292. end
  293. end