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.

custom_fields_controller_test.rb 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006- Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require_relative '../test_helper'
  19. class CustomFieldsControllerTest < Redmine::ControllerTest
  20. fixtures :custom_fields, :custom_values,
  21. :custom_fields_projects, :custom_fields_trackers,
  22. :roles, :users,
  23. :members, :member_roles,
  24. :groups_users,
  25. :trackers, :projects_trackers,
  26. :enabled_modules,
  27. :projects, :issues,
  28. :issue_statuses,
  29. :issue_categories,
  30. :enumerations,
  31. :workflows
  32. def setup
  33. @request.session[:user_id] = 1
  34. end
  35. def test_index
  36. get :index
  37. assert_response :success
  38. assert_select 'table.custom_fields'
  39. end
  40. def test_new_without_type_should_render_select_type
  41. get :new
  42. assert_response :success
  43. assert_select 'input[name=type]', CustomFieldsHelper::CUSTOM_FIELDS_TABS.size
  44. assert_select 'input[name=type][checked=checked]', 1
  45. end
  46. def test_new_should_work_for_each_customized_class_and_format
  47. custom_field_classes.each do |klass|
  48. Redmine::FieldFormat.formats_for_custom_field_class(klass).each do |format|
  49. get(
  50. :new,
  51. :params => {
  52. :type => klass.name,
  53. :custom_field => {
  54. :field_format => format.name
  55. }
  56. }
  57. )
  58. assert_response :success
  59. assert_select 'form#custom_field_form' do
  60. assert_select 'select[name=?]', 'custom_field[field_format]' do
  61. assert_select 'option[value=?][selected=selected]', format.name
  62. end
  63. assert_select 'input[type=hidden][name=type][value=?]', klass.name
  64. end
  65. end
  66. end
  67. end
  68. def test_new_should_have_string_default_format
  69. get(
  70. :new,
  71. :params => {
  72. :type => 'IssueCustomField'
  73. }
  74. )
  75. assert_response :success
  76. assert_select 'select[name=?]', 'custom_field[field_format]' do
  77. assert_select 'option[value=?][selected=selected]', 'string'
  78. end
  79. end
  80. def test_new_issue_custom_field
  81. get(
  82. :new,
  83. :params => {
  84. :type => 'IssueCustomField'
  85. }
  86. )
  87. assert_response :success
  88. assert_select 'form#custom_field_form' do
  89. assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]' do
  90. assert_select 'option[value=user]', :text => 'User'
  91. assert_select 'option[value=version]', :text => 'Version'
  92. end
  93. # Visibility
  94. assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2
  95. assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3
  96. assert_select 'input[type=checkbox][name=?]', 'custom_field[project_ids][]', Project.count
  97. assert_select 'input[type=hidden][name=?]', 'custom_field[project_ids][]', 1
  98. assert_select 'input[type=hidden][name=type][value=IssueCustomField]'
  99. end
  100. end
  101. def test_new_time_entry_custom_field
  102. get(
  103. :new,
  104. :params => {
  105. :type => 'TimeEntryCustomField'
  106. }
  107. )
  108. assert_response :success
  109. assert_select 'form#custom_field_form' do
  110. assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]' do
  111. assert_select 'option[value=user]', :text => 'User'
  112. assert_select 'option[value=version]', :text => 'Version'
  113. end
  114. # Visibility
  115. assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2
  116. assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3
  117. assert_select 'input[type=hidden][name=type][value=TimeEntryCustomField]'
  118. end
  119. end
  120. def test_new_project_custom_field
  121. get(
  122. :new,
  123. :params => {
  124. :type => 'ProjectCustomField'
  125. }
  126. )
  127. assert_response :success
  128. assert_select 'form#custom_field_form' do
  129. assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]' do
  130. assert_select 'option[value=user]', :text => 'User'
  131. assert_select 'option[value=version]', :text => 'Version'
  132. end
  133. # Visibility
  134. assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2
  135. assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3
  136. assert_select 'input[type=hidden][name=type][value=ProjectCustomField]'
  137. end
  138. end
  139. def test_new_version_custom_field
  140. get(
  141. :new,
  142. :params => {
  143. :type => 'VersionCustomField'
  144. }
  145. )
  146. assert_response :success
  147. assert_select 'form#custom_field_form' do
  148. assert_select 'select#custom_field_field_format[name=?]', 'custom_field[field_format]' do
  149. assert_select 'option[value=user]', :text => 'User'
  150. assert_select 'option[value=version]', :text => 'Version'
  151. end
  152. # Visibility
  153. assert_select 'input[type=radio][name=?]', 'custom_field[visible]', 2
  154. assert_select 'input[type=checkbox][name=?]', 'custom_field[role_ids][]', 3
  155. assert_select 'input[type=hidden][name=type][value=VersionCustomField]'
  156. end
  157. end
  158. def test_new_time_entry_custom_field_should_not_show_trackers_and_projects
  159. get(
  160. :new,
  161. :params => {
  162. :type => 'TimeEntryCustomField'
  163. }
  164. )
  165. assert_response :success
  166. assert_select 'form#custom_field_form' do
  167. assert_select 'input[name=?]', 'custom_field[tracker_ids][]', 0
  168. assert_select 'input[name=?]', 'custom_field[project_ids][]', 0
  169. end
  170. end
  171. def test_default_value_should_be_an_input_for_string_custom_field
  172. get(
  173. :new,
  174. :params => {
  175. :type => 'IssueCustomField',
  176. :custom_field => {
  177. :field_format => 'string'
  178. }
  179. }
  180. )
  181. assert_response :success
  182. assert_select 'input[name=?]', 'custom_field[default_value]'
  183. end
  184. def test_default_value_should_be_a_textarea_for_text_custom_field
  185. get(
  186. :new,
  187. :params => {
  188. :type => 'IssueCustomField',
  189. :custom_field => {
  190. :field_format => 'text'
  191. }
  192. }
  193. )
  194. assert_response :success
  195. assert_select 'textarea[name=?]', 'custom_field[default_value]'
  196. end
  197. def test_default_value_should_be_a_checkbox_for_bool_custom_field
  198. get(
  199. :new,
  200. :params => {
  201. :type => 'IssueCustomField',
  202. :custom_field => {
  203. :field_format => 'bool'
  204. }
  205. }
  206. )
  207. assert_response :success
  208. assert_select 'select[name=?]', 'custom_field[default_value]' do
  209. assert_select 'option', 3
  210. end
  211. end
  212. def test_default_value_should_not_be_present_for_user_custom_field
  213. get(
  214. :new,
  215. :params => {
  216. :type => 'IssueCustomField',
  217. :custom_field => {
  218. :field_format => 'user'
  219. }
  220. }
  221. )
  222. assert_response :success
  223. assert_select '[name=?]', 'custom_field[default_value]', 0
  224. end
  225. def test_setting_full_width_layout_shoul_be_present_only_for_long_text_issue_custom_field
  226. get(
  227. :new,
  228. :params => {
  229. :type => 'IssueCustomField',
  230. :custom_field => {
  231. :field_format => 'text'
  232. }
  233. }
  234. )
  235. assert_response :success
  236. assert_select '[name=?]', 'custom_field[full_width_layout]'
  237. get(
  238. :new,
  239. :params => {
  240. :type => 'IssueCustomField',
  241. :custom_field => {
  242. :field_format => 'list'
  243. }
  244. }
  245. )
  246. assert_response :success
  247. assert_select '[name=?]', 'custom_field[full_width_layout]', 0
  248. get(
  249. :new,
  250. :params => {
  251. :type => 'TimeEntryCustomField',
  252. :custom_field => {
  253. :field_format => 'text'
  254. }
  255. }
  256. )
  257. assert_response :success
  258. assert_select '[name=?]', 'custom_field[full_width_layout]', 0
  259. end
  260. def test_new_js
  261. get(
  262. :new,
  263. :params => {
  264. :type => 'IssueCustomField',
  265. :custom_field => {
  266. :field_format => 'list'
  267. },
  268. :format => 'js'
  269. },
  270. :xhr => true
  271. )
  272. assert_response :success
  273. assert_equal 'text/javascript', response.media_type
  274. assert_include '<option selected=\"selected\" value=\"list\">List<\/option>', response.body
  275. end
  276. def test_new_with_invalid_custom_field_class_should_render_select_type
  277. get(
  278. :new,
  279. :params => {
  280. :type => 'UnknownCustomField'
  281. }
  282. )
  283. assert_response :success
  284. assert_select 'input[type=radio][name=type]'
  285. end
  286. def test_new_with_copy
  287. role_ids = [1, 2]
  288. tracker_ids = [1, 2]
  289. project_ids = [1, 2, 3]
  290. copy_from = CustomField.find(1)
  291. copy_from.role_ids = role_ids
  292. copy_from.tracker_ids = tracker_ids
  293. copy_from.project_ids = project_ids
  294. copy_from.save
  295. get :new, :params => {:copy => copy_from.id.to_s, :type => IssueCustomField}
  296. assert_response :success
  297. assert_select 'form' do
  298. # field_format selected
  299. assert_select 'select[name=?]', 'custom_field[field_format]' do
  300. assert_select "option[value=\"#{copy_from.field_format}\"][selected=selected]"
  301. end
  302. # blank name
  303. assert_select 'input[name=?][value=""]', 'custom_field[name]'
  304. # description copied
  305. assert_select 'textarea[name=?]', 'custom_field[description]', :text => copy_from.description
  306. # role checked
  307. role_ids.each do |role_id|
  308. assert_select "input[type=checkbox][name=?][value=#{role_id}][checked=checked]", 'custom_field[role_ids][]'
  309. end
  310. # role not checked
  311. (Role.givable.pluck(:id) - role_ids).each do |role_id|
  312. assert_select "input[type=checkbox][name=?][value=#{role_id}]", 'custom_field[role_ids][]'
  313. end
  314. # tracker checked
  315. tracker_ids.each do |tracker_id|
  316. assert_select "input[type=checkbox][name=?][value=#{tracker_id}][checked=checked]", 'custom_field[tracker_ids][]'
  317. end
  318. # tracker not checked
  319. (Tracker.pluck(:id) - tracker_ids).each do |tracker_id|
  320. assert_select "input[type=checkbox][name=?][value=#{tracker_id}]", 'custom_field[tracker_ids][]'
  321. end
  322. # project checked
  323. project_ids.each do |project_id|
  324. assert_select "input[type=checkbox][name=?][value=#{project_id}][checked=checked]", 'custom_field[project_ids][]'
  325. end
  326. # project not checked
  327. (Project.pluck(:id) - project_ids).each do |project_id|
  328. assert_select "input[type=checkbox][name=?][value=#{project_id}]", 'custom_field[project_ids][]'
  329. end
  330. end
  331. end
  332. def test_create_list_custom_field
  333. field = new_record(IssueCustomField) do
  334. post(
  335. :create,
  336. :params => {
  337. :type => "IssueCustomField",
  338. :custom_field => {
  339. :name => "test_post_new_list",
  340. :default_value => "",
  341. :min_length => "0",
  342. :searchable => "0",
  343. :regexp => "",
  344. :is_for_all => "1",
  345. :possible_values => "0.1\n0.2\n",
  346. :max_length => "0",
  347. :is_filter => "0",
  348. :is_required =>"0",
  349. :field_format => "list",
  350. :tracker_ids => ["1", ""]
  351. }
  352. }
  353. )
  354. end
  355. assert_redirected_to "/custom_fields?tab=IssueCustomField"
  356. assert_equal "test_post_new_list", field.name
  357. assert_equal ["0.1", "0.2"], field.possible_values
  358. assert_equal 1, field.trackers.size
  359. end
  360. def test_create_project_custom_field
  361. field = new_record(ProjectCustomField) do
  362. post(
  363. :create,
  364. :params => {
  365. :type => 'ProjectCustomField',
  366. :custom_field => {
  367. :field_format => 'string',
  368. :name => 'test_new_project_custom_field',
  369. :description => '',
  370. :min_length => '',
  371. :max_length => '',
  372. :regexp => '',
  373. :text_formatting => '',
  374. :default_value => '',
  375. :url_pattern => '',
  376. :is_filter => '0',
  377. :is_required => '0'
  378. }
  379. }
  380. )
  381. end
  382. assert_redirected_to '/custom_fields?tab=ProjectCustomField'
  383. assert_equal 'test_new_project_custom_field', field.name
  384. end
  385. def test_create_with_project_ids
  386. assert_difference 'CustomField.count' do
  387. post(
  388. :create,
  389. :params => {
  390. :type => "IssueCustomField",
  391. :custom_field => {
  392. :name => "foo",
  393. :field_format => "string",
  394. :is_for_all => "0",
  395. :project_ids => ["1", "3", ""]
  396. }
  397. }
  398. )
  399. assert_response 302
  400. end
  401. field = IssueCustomField.order("id desc").first
  402. assert_equal [1, 3], field.projects.map(&:id).sort
  403. end
  404. def test_create_with_continue_params
  405. assert_difference 'CustomField.count' do
  406. post(
  407. :create,
  408. :params => {
  409. :type => 'IssueCustomField',
  410. :continue => 'Create and Continue',
  411. :custom_field => {
  412. :name => 'foo',
  413. :field_format => 'string'
  414. }
  415. }
  416. )
  417. end
  418. assert_redirected_to '/custom_fields/new?type=IssueCustomField'
  419. end
  420. def test_create_with_failure
  421. assert_no_difference 'CustomField.count' do
  422. post(
  423. :create,
  424. :params => {
  425. :type => "IssueCustomField",
  426. :custom_field => {
  427. :name => ''
  428. }
  429. }
  430. )
  431. end
  432. assert_response :success
  433. assert_select_error /name cannot be blank/i
  434. end
  435. def test_create_without_type_should_render_select_type
  436. assert_no_difference 'CustomField.count' do
  437. post(
  438. :create,
  439. :params => {
  440. :custom_field => {
  441. :name => ''
  442. }
  443. }
  444. )
  445. end
  446. assert_response :success
  447. assert_select 'input[type=radio][name=type]'
  448. end
  449. def test_create_with_enumerations
  450. custom_field = IssueCustomField.create(:field_format => 'enumeration', :name => 'IssueCustomField')
  451. custom_field.enumerations.build(:name => 'enumeration1', :position => 1)
  452. custom_field.enumerations.build(:name => 'enumeration2', :position => 2)
  453. assert custom_field.save
  454. assert_difference 'CustomField.count' do
  455. post(
  456. :create,
  457. :params => {
  458. :type => 'IssueCustomField',
  459. :copy => custom_field.id,
  460. :custom_field => {:name => 'Copy'}
  461. }
  462. )
  463. assert_response 302
  464. end
  465. field = IssueCustomField.order('id desc').first
  466. assert_equal 'Copy', field.name
  467. assert_equal ['enumeration1', 'enumeration2'], field.enumerations.pluck(:name).sort
  468. assert_equal [1, 2], field.enumerations.pluck(:position).sort
  469. end
  470. def test_edit
  471. get(
  472. :edit,
  473. :params => {
  474. :id => 1
  475. }
  476. )
  477. assert_response :success
  478. assert_select 'input[name=?][value=?]', 'custom_field[name]', 'Database'
  479. end
  480. def test_edit_invalid_custom_field_should_render_404
  481. get(
  482. :edit,
  483. :params => {
  484. :id => 99
  485. }
  486. )
  487. assert_response 404
  488. end
  489. def test_update
  490. put(
  491. :update,
  492. :params => {
  493. :id => 1,
  494. :custom_field => {
  495. :name => 'New name'
  496. }
  497. }
  498. )
  499. assert_redirected_to '/custom_fields/1/edit'
  500. field = CustomField.find(1)
  501. assert_equal 'New name', field.name
  502. end
  503. def test_update_with_failure
  504. put(
  505. :update,
  506. :params => {
  507. :id => 1,
  508. :custom_field => {
  509. :name => ''
  510. }
  511. }
  512. )
  513. assert_response :success
  514. assert_select_error /name cannot be blank/i
  515. end
  516. def test_destroy
  517. custom_values_count = CustomValue.where(:custom_field_id => 1).count
  518. assert custom_values_count > 0
  519. assert_difference 'CustomField.count', -1 do
  520. assert_difference 'CustomValue.count', - custom_values_count do
  521. delete(
  522. :destroy,
  523. :params => {
  524. :id => 1
  525. }
  526. )
  527. end
  528. end
  529. assert_redirected_to '/custom_fields?tab=IssueCustomField'
  530. assert_nil CustomField.find_by_id(1)
  531. assert_nil CustomValue.find_by_custom_field_id(1)
  532. end
  533. def custom_field_classes
  534. classes =
  535. Dir.glob(Rails.root.join('app/models/*_custom_field.rb')).map do |f|
  536. File.basename(f, '.rb').classify.constantize
  537. end
  538. assert classes.size > 0
  539. classes
  540. end
  541. end