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.

queries_controller_test.rb 30KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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 QueriesControllerTest < Redmine::ControllerTest
  20. fixtures :projects, :enabled_modules,
  21. :users, :email_addresses,
  22. :members, :member_roles, :roles,
  23. :trackers, :issue_statuses, :issue_categories, :enumerations, :versions,
  24. :issues, :custom_fields, :custom_values,
  25. :queries
  26. def setup
  27. User.current = nil
  28. end
  29. def test_index
  30. get :index
  31. # HTML response not implemented
  32. assert_response :not_acceptable
  33. end
  34. def test_new_project_query
  35. @request.session[:user_id] = 2
  36. get(:new, :params => {:project_id => 1})
  37. assert_response :success
  38. assert_select 'input[name=?][value="0"][checked=checked]', 'query[visibility]'
  39. assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked]):not([disabled])'
  40. assert_select 'select[name=?]', 'c[]' do
  41. assert_select 'option[value=tracker]'
  42. assert_select 'option[value=subject]'
  43. end
  44. end
  45. def test_new_global_query
  46. @request.session[:user_id] = 2
  47. get :new
  48. assert_response :success
  49. assert_select 'input[name=?]', 'query[visibility]', 0
  50. assert_select 'input[name=query_is_for_all][type=checkbox][checked]:not([disabled])'
  51. end
  52. def test_new_on_invalid_project
  53. @request.session[:user_id] = 2
  54. get(:new, :params => {:project_id => 'invalid'})
  55. assert_response :not_found
  56. end
  57. def test_new_should_not_render_show_inline_columns_option_for_query_without_available_inline_columns
  58. @request.session[:user_id] = 1
  59. get(:new, :params => {:type => 'ProjectQuery'})
  60. assert_response :success
  61. assert_select 'p[class=?]', 'block_columns', 0
  62. end
  63. def test_new_should_not_render_show_totals_option_for_query_without_totable_columns
  64. @request.session[:user_id] = 1
  65. get(:new, :params => {:type => 'ProjectQuery'})
  66. assert_response :success
  67. assert_select 'p[class=?]', 'totables_columns', 0
  68. end
  69. def test_new_time_entry_query
  70. @request.session[:user_id] = 2
  71. get(:new, :params => {:project_id => 1, :type => 'TimeEntryQuery'})
  72. assert_response :success
  73. assert_select 'input[name=type][value=?]', 'TimeEntryQuery'
  74. assert_select 'p[class=?]', 'totable_columns', 1
  75. assert_select 'p[class=?]', 'block_columns', 0
  76. end
  77. def test_new_project_query_for_projects
  78. @request.session[:user_id] = 1
  79. get(:new, :params => {:type => 'ProjectQuery'})
  80. assert_response :success
  81. assert_select 'input[name=type][value=?]', 'ProjectQuery'
  82. end
  83. def test_new_project_query_should_not_render_roles_visibility_options
  84. @request.session[:user_id] = 1
  85. get(:new, :params => {:type => 'ProjectQuery'})
  86. assert_response :success
  87. assert_select 'input[id=?]', 'query_visibility_0', 1
  88. assert_select 'input[id=?]', 'query_visibility_2', 1
  89. assert_select 'input[id=?]', 'query_visibility_1', 0
  90. end
  91. def test_new_project_query_should_not_render_for_all_projects_option
  92. @request.session[:user_id] = 1
  93. get(:new, :params => {:type => 'ProjectQuery'})
  94. assert_response :success
  95. assert_select 'input[name=?]', 'for_all_projects', 0
  96. end
  97. def test_new_time_entry_query_should_select_spent_time_from_main_menu
  98. @request.session[:user_id] = 2
  99. get(
  100. :new,
  101. :params => {
  102. :project_id => 1,
  103. :type => 'TimeEntryQuery'
  104. }
  105. )
  106. assert_response :success
  107. assert_select '#main-menu a.time-entries.selected'
  108. end
  109. def test_new_time_entry_query_with_issue_tracking_module_disabled_should_be_allowed
  110. Project.find(1).disable_module! :issue_tracking
  111. @request.session[:user_id] = 2
  112. get(
  113. :new,
  114. :params => {
  115. :project_id => 1,
  116. :type => 'TimeEntryQuery'
  117. }
  118. )
  119. assert_response :success
  120. end
  121. def test_new_with_gantt_params
  122. @request.session[:user_id] = 2
  123. get :new, :params => {:gantt => 1}
  124. assert_response :success
  125. assert_select 'input[type="hidden"]#gantt', 1
  126. assert_select 'fieldset#options'
  127. assert_select 'fieldset#filters'
  128. assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
  129. assert_select 'fieldset#columns'
  130. end
  131. def test_new_with_calendar_params
  132. @request.session[:user_id] = 2
  133. get :new, :params => {:calendar => 1}
  134. assert_response :success
  135. assert_select 'input[type="hidden"]#calendar', 1
  136. assert_select 'fieldset#options', :count => 0
  137. assert_select 'fieldset#filters'
  138. assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
  139. assert_select 'fieldset#columns', :count => 0
  140. end
  141. def test_new_without_gantt_and_calendar_params
  142. @request.session[:user_id] = 2
  143. get :new
  144. assert_response :success
  145. assert_select 'fieldset#options'
  146. assert_select 'fieldset#filters'
  147. assert_select 'fieldset legend', {:text => 'Sort'}
  148. assert_select 'fieldset#columns'
  149. end
  150. def test_create_project_public_query
  151. @request.session[:user_id] = 2
  152. post(
  153. :create,
  154. :params => {
  155. :project_id => 'ecookbook',
  156. :default_columns => '1',
  157. :f => ["status_id", "assigned_to_id"],
  158. :op => {
  159. "assigned_to_id" => "=", "status_id" => "o"
  160. },
  161. :v => {
  162. "assigned_to_id" => ["1"], "status_id" => ["1"]
  163. },
  164. :query => {
  165. "name" => "test_new_project_public_query", "visibility" => "2"
  166. }
  167. }
  168. )
  169. q = Query.find_by_name('test_new_project_public_query')
  170. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
  171. assert q.is_public?
  172. assert q.has_default_columns?
  173. assert q.valid?
  174. end
  175. def test_create_project_private_query
  176. @request.session[:user_id] = 3
  177. post(
  178. :create,
  179. :params => {
  180. :project_id => 'ecookbook',
  181. :default_columns => '1',
  182. :fields => ["status_id", "assigned_to_id"],
  183. :operators => {
  184. "assigned_to_id" => "=", "status_id" => "o"
  185. },
  186. :values => {
  187. "assigned_to_id" => ["1"], "status_id" => ["1"]
  188. },
  189. :query => {
  190. "name" => "test_new_project_private_query", "visibility" => "0"
  191. }
  192. }
  193. )
  194. q = Query.find_by_name('test_new_project_private_query')
  195. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
  196. assert !q.is_public?
  197. assert q.has_default_columns?
  198. assert q.valid?
  199. end
  200. def test_create_project_roles_query
  201. @request.session[:user_id] = 2
  202. post(
  203. :create,
  204. :params => {
  205. :project_id => 'ecookbook',
  206. :default_columns => '1',
  207. :fields => ["status_id", "assigned_to_id"],
  208. :operators => {
  209. "assigned_to_id" => "=", "status_id" => "o"
  210. },
  211. :values => {
  212. "assigned_to_id" => ["1"], "status_id" => ["1"]
  213. },
  214. :query => {
  215. "name" => "test_create_project_roles_query",
  216. "visibility" => "1",
  217. "role_ids" => ["1", "2", ""]
  218. }
  219. }
  220. )
  221. q = Query.find_by_name('test_create_project_roles_query')
  222. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
  223. assert_equal Query::VISIBILITY_ROLES, q.visibility
  224. assert_equal [1, 2], q.roles.ids.sort
  225. end
  226. def test_create_global_private_query_with_custom_columns
  227. @request.session[:user_id] = 3
  228. post(
  229. :create,
  230. :params => {
  231. :fields => ["status_id", "assigned_to_id"],
  232. :operators => {
  233. "assigned_to_id" => "=", "status_id" => "o"
  234. },
  235. :values => {
  236. "assigned_to_id" => ["me"], "status_id" => ["1"]
  237. },
  238. :query => {
  239. "name" => "test_new_global_private_query", "visibility" => "0"
  240. },
  241. :c => ["", "tracker", "subject", "priority", "category"]
  242. }
  243. )
  244. q = Query.find_by_name('test_new_global_private_query')
  245. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
  246. assert !q.is_public?
  247. assert !q.has_default_columns?
  248. assert_equal [:id, :tracker, :subject, :priority, :category], q.columns.collect {|c| c.name}
  249. assert q.valid?
  250. end
  251. def test_create_global_query_with_custom_filters
  252. @request.session[:user_id] = 3
  253. post(
  254. :create,
  255. :params => {
  256. :fields => ["assigned_to_id"],
  257. :operators => {
  258. "assigned_to_id" => "="
  259. },
  260. :values => {
  261. "assigned_to_id" => ["me"]
  262. },
  263. :query => {
  264. "name" => "test_new_global_query"
  265. }
  266. }
  267. )
  268. q = Query.find_by_name('test_new_global_query')
  269. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => nil, :query_id => q
  270. assert !q.is_public?
  271. assert !q.has_filter?(:status_id)
  272. assert_equal ['assigned_to_id'], q.filters.keys
  273. assert q.valid?
  274. end
  275. def test_create_with_sort
  276. @request.session[:user_id] = 1
  277. post(
  278. :create,
  279. :params => {
  280. :default_columns => '1',
  281. :operators => {
  282. "status_id" => "o"
  283. },
  284. :values => {
  285. "status_id" => ["1"]
  286. },
  287. :query => {
  288. :name => "test_new_with_sort",
  289. :visibility => "2",
  290. :sort_criteria => {
  291. "0" => ["due_date", "desc"], "1" => ["tracker", ""]
  292. }
  293. }
  294. }
  295. )
  296. query = Query.find_by_name("test_new_with_sort")
  297. assert_not_nil query
  298. assert_equal [['due_date', 'desc'], ['tracker', 'asc']], query.sort_criteria
  299. end
  300. def test_create_with_description
  301. @request.session[:user_id] = 2
  302. assert_difference '::Query.count', 1 do
  303. post(
  304. :create,
  305. :params => {
  306. :project_id => 'ecookbook',
  307. :query => {
  308. :name => 'test_new_with_description', :description => 'Description for test_new_with_description'
  309. }
  310. }
  311. )
  312. end
  313. q = Query.find_by_name("test_new_with_description")
  314. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => q
  315. assert_equal 'Description for test_new_with_description', q.description
  316. end
  317. def test_create_with_failure
  318. @request.session[:user_id] = 2
  319. assert_no_difference '::Query.count' do
  320. post(
  321. :create,
  322. :params => {
  323. :project_id => 'ecookbook',
  324. :query => {
  325. :name => ''
  326. }
  327. }
  328. )
  329. end
  330. assert_response :success
  331. assert_select 'input[name=?]', 'query[name]'
  332. end
  333. def test_create_query_without_permission_should_fail
  334. Role.all.each {|r| r.remove_permission! :save_queries, :manage_public_queries}
  335. @request.session[:user_id] = 2
  336. assert_no_difference '::Query.count' do
  337. post(
  338. :create,
  339. :params => {
  340. :project_id => 'ecookbook',
  341. :query => {:name => 'Foo'}
  342. }
  343. )
  344. end
  345. assert_response :forbidden
  346. end
  347. def test_create_global_query_without_permission_should_fail
  348. Role.all.each {|r| r.remove_permission! :save_queries, :manage_public_queries}
  349. @request.session[:user_id] = 2
  350. assert_no_difference '::Query.count' do
  351. post(:create, :params => {:query => {:name => 'Foo'}})
  352. end
  353. assert_response :forbidden
  354. end
  355. def test_create_global_query_from_gantt
  356. @request.session[:user_id] = 1
  357. assert_difference 'IssueQuery.count' do
  358. post(
  359. :create,
  360. :params => {
  361. :gantt => 1,
  362. :operators => {
  363. "status_id" => "o"
  364. },
  365. :values => {
  366. "status_id" => ["1"]
  367. },
  368. :query => {
  369. :name => "test_create_from_gantt",
  370. :draw_relations => '1',
  371. :draw_progress_line => '1',
  372. :draw_selected_columns => '1'
  373. }
  374. }
  375. )
  376. assert_response :found
  377. end
  378. query = IssueQuery.order('id DESC').first
  379. assert_redirected_to "/issues/gantt?query_id=#{query.id}"
  380. assert_equal true, query.draw_relations
  381. assert_equal true, query.draw_progress_line
  382. assert_equal true, query.draw_selected_columns
  383. end
  384. def test_create_project_query_from_gantt
  385. @request.session[:user_id] = 1
  386. assert_difference 'IssueQuery.count' do
  387. post(
  388. :create,
  389. :params => {
  390. :project_id => 'ecookbook',
  391. :gantt => 1,
  392. :operators => {
  393. "status_id" => "o"
  394. },
  395. :values => {
  396. "status_id" => ["1"]
  397. },
  398. :query => {
  399. :name => "test_create_from_gantt",
  400. :draw_relations => '0',
  401. :draw_progress_line => '0',
  402. :draw_selected_columns => '0'
  403. }
  404. }
  405. )
  406. assert_response :found
  407. end
  408. query = IssueQuery.order('id DESC').first
  409. assert_redirected_to "/projects/ecookbook/issues/gantt?query_id=#{query.id}"
  410. assert_equal false, query.draw_relations
  411. assert_equal false, query.draw_progress_line
  412. assert_equal false, query.draw_selected_columns
  413. end
  414. def test_create_project_public_query_should_force_private_without_manage_public_queries_permission
  415. @request.session[:user_id] = 3
  416. query = new_record(Query) do
  417. post(
  418. :create,
  419. :params => {
  420. :project_id => 'ecookbook',
  421. :query => {
  422. "name" => "name", "visibility" => "2"
  423. }
  424. }
  425. )
  426. assert_response :found
  427. end
  428. assert_not_nil query.project
  429. assert_equal Query::VISIBILITY_PRIVATE, query.visibility
  430. end
  431. def test_create_global_public_query_should_force_private_without_manage_public_queries_permission
  432. @request.session[:user_id] = 3
  433. query = new_record(Query) do
  434. post(
  435. :create,
  436. :params => {
  437. :project_id => 'ecookbook',
  438. :query_is_for_all => '1',
  439. :query => {
  440. "name" => "name", "visibility" => "2"
  441. }
  442. }
  443. )
  444. assert_response :found
  445. end
  446. assert_nil query.project
  447. assert_equal Query::VISIBILITY_PRIVATE, query.visibility
  448. end
  449. def test_create_project_public_query_with_manage_public_queries_permission
  450. @request.session[:user_id] = 2
  451. query = new_record(Query) do
  452. post(
  453. :create,
  454. :params => {
  455. :project_id => 'ecookbook',
  456. :query => {
  457. "name" => "name", "visibility" => "2"
  458. }
  459. }
  460. )
  461. assert_response :found
  462. end
  463. assert_not_nil query.project
  464. assert_equal Query::VISIBILITY_PUBLIC, query.visibility
  465. end
  466. def test_create_global_public_query_should_force_private_with_manage_public_queries_permission
  467. @request.session[:user_id] = 2
  468. query = new_record(Query) do
  469. post(
  470. :create,
  471. :params => {
  472. :project_id => 'ecookbook',
  473. :query_is_for_all => '1',
  474. :query => {
  475. "name" => "name", "visibility" => "2"
  476. }
  477. }
  478. )
  479. assert_response :found
  480. end
  481. assert_nil query.project
  482. assert_equal Query::VISIBILITY_PRIVATE, query.visibility
  483. end
  484. def test_create_global_public_query_by_admin
  485. @request.session[:user_id] = 1
  486. query = new_record(Query) do
  487. post(
  488. :create,
  489. :params => {
  490. :project_id => 'ecookbook',
  491. :query_is_for_all => '1',
  492. :query => {
  493. "name" => "name", "visibility" => "2"
  494. }
  495. }
  496. )
  497. assert_response :found
  498. end
  499. assert_nil query.project
  500. assert_equal Query::VISIBILITY_PUBLIC, query.visibility
  501. end
  502. def test_create_project_public_time_entry_query
  503. @request.session[:user_id] = 2
  504. q = new_record(TimeEntryQuery) do
  505. post(
  506. :create,
  507. :params => {
  508. :project_id => 'ecookbook',
  509. :type => 'TimeEntryQuery',
  510. :default_columns => '1',
  511. :f => ["spent_on"],
  512. :op => {
  513. "spent_on" => "="
  514. },
  515. :v => {
  516. "spent_on" => ["2016-07-14"]
  517. },
  518. :query => {
  519. "name" => "test_new_project_public_query", "visibility" => "2"
  520. }
  521. }
  522. )
  523. end
  524. assert_redirected_to :controller => 'timelog', :action => 'index', :project_id => 'ecookbook', :query_id => q.id
  525. assert q.is_public?
  526. assert q.has_default_columns?
  527. assert q.valid?
  528. end
  529. def test_create_public_project_query
  530. @request.session[:user_id] = 1
  531. q = new_record(ProjectQuery) do
  532. post(
  533. :create,
  534. :params => {
  535. :type => 'ProjectQuery',
  536. :default_columns => '1',
  537. :f => ["status"],
  538. :op => {
  539. "status" => "="
  540. },
  541. :v => {
  542. "status" => ['1']
  543. },
  544. :query => {
  545. "name" => "test_new_project_public_query", "visibility" => "2"
  546. }
  547. }
  548. )
  549. end
  550. assert_redirected_to :controller => 'projects', :action => 'index', :query_id => q.id
  551. assert q.is_public?
  552. assert q.valid?
  553. end
  554. def test_create_admin_projects_query_should_redirect_to_admin_projects
  555. @request.session[:user_id] = 1
  556. q = new_record(ProjectQuery) do
  557. post(
  558. :create,
  559. :params => {
  560. :type => 'ProjectQuery',
  561. :default_columns => '1',
  562. :f => ["status"],
  563. :op => {
  564. "status" => "="
  565. },
  566. :v => {
  567. "status" => ['1']
  568. },
  569. :query => {
  570. "name" => "test_new_project_public_query", "visibility" => "2"
  571. },
  572. :admin_projects => 1
  573. }
  574. )
  575. end
  576. assert_redirected_to :controller => 'admin', :action => 'projects', :query_id => q.id, :admin_projects => 1
  577. end
  578. def test_edit_global_public_query
  579. @request.session[:user_id] = 1
  580. get(:edit, :params => {:id => 4})
  581. assert_response :success
  582. assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
  583. assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
  584. end
  585. def test_edit_global_private_query
  586. @request.session[:user_id] = 3
  587. get(:edit, :params => {:id => 3})
  588. assert_response :success
  589. assert_select 'input[name=?]', 'query[visibility]', 0
  590. assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
  591. end
  592. def test_edit_project_private_query
  593. @request.session[:user_id] = 3
  594. get(:edit, :params => {:id => 2})
  595. assert_response :success
  596. assert_select 'input[name=?]', 'query[visibility]', 0
  597. assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
  598. end
  599. def test_edit_project_public_query
  600. @request.session[:user_id] = 2
  601. get(:edit, :params => {:id => 1})
  602. assert_response :success
  603. assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
  604. assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
  605. end
  606. def test_edit_sort_criteria
  607. @request.session[:user_id] = 1
  608. get(:edit, :params => {:id => 5})
  609. assert_response :success
  610. assert_select 'select[name=?]', 'query[sort_criteria][0][]' do
  611. assert_select 'option[value=priority][selected=selected]'
  612. assert_select 'option[value=desc][selected=selected]'
  613. end
  614. end
  615. def test_edit_description
  616. @request.session[:user_id] = 1
  617. get(:edit, :params => {:id => 5})
  618. assert_response :success
  619. assert_select 'input[name="query[description]"][value=?]', 'Description for Oepn issues by priority and tracker'
  620. end
  621. def test_edit_invalid_query
  622. @request.session[:user_id] = 2
  623. get(:edit, :params => {:id => 99})
  624. assert_response :not_found
  625. end
  626. def test_update_global_private_query
  627. @request.session[:user_id] = 3
  628. put(
  629. :update,
  630. :params => {
  631. :id => 3,
  632. :default_columns => '1',
  633. :fields => ["status_id", "assigned_to_id"],
  634. :operators => {
  635. "assigned_to_id" => "=", "status_id" => "o"
  636. },
  637. :values => {
  638. "assigned_to_id" => ["me"], "status_id" => ["1"]
  639. },
  640. :query => {
  641. "name" => "test_edit_global_private_query", "visibility" => "2"
  642. }
  643. }
  644. )
  645. assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 3
  646. q = Query.find_by_name('test_edit_global_private_query')
  647. assert !q.is_public?
  648. assert q.has_default_columns?
  649. assert q.valid?
  650. end
  651. def test_update_global_public_query
  652. @request.session[:user_id] = 1
  653. put(
  654. :update,
  655. :params => {
  656. :id => 4,
  657. :default_columns => '1',
  658. :fields => ["status_id", "assigned_to_id"],
  659. :operators => {
  660. "assigned_to_id" => "=", "status_id" => "o"
  661. },
  662. :values => {
  663. "assigned_to_id" => ["1"], "status_id" => ["1"]
  664. },
  665. :query => {
  666. "name" => "test_edit_global_public_query", "visibility" => "2"
  667. }
  668. }
  669. )
  670. assert_redirected_to :controller => 'issues', :action => 'index', :query_id => 4
  671. q = Query.find_by_name('test_edit_global_public_query')
  672. assert q.is_public?
  673. assert q.has_default_columns?
  674. assert q.valid?
  675. end
  676. def test_update_admin_projects_query
  677. q = ProjectQuery.create(:name => 'project_query')
  678. @request.session[:user_id] = 1
  679. put(
  680. :update,
  681. :params => {
  682. :id => q.id,
  683. :default_columns => '1',
  684. :fields => ["status"],
  685. :operators => {
  686. "status" => "="
  687. },
  688. :values => {
  689. "status" => ['1']
  690. },
  691. :query => {
  692. "name" => "test_project_query_updated", "visibility" => "2"
  693. },
  694. :admin_projects => 1
  695. }
  696. )
  697. assert_redirected_to :controller => 'admin', :action => 'projects', :query_id => q.id, :admin_projects => 1
  698. assert Query.find_by_name('test_project_query_updated')
  699. end
  700. def test_update_description
  701. @request.session[:user_id] = 1
  702. q = Query.find(5)
  703. put(
  704. :update,
  705. :params => {
  706. :id => q.id,
  707. :query => {
  708. :name => q.name,
  709. :description => 'query description updated'
  710. }
  711. }
  712. )
  713. assert_redirected_to :controller => 'issues', :action => 'index', :query_id => q.id
  714. assert_equal 'query description updated', Query.find(5).description
  715. end
  716. def test_update_with_failure
  717. @request.session[:user_id] = 1
  718. put(
  719. :update,
  720. :params => {
  721. :id => 4,
  722. :query => {
  723. :name => ''
  724. }
  725. }
  726. )
  727. assert_response :success
  728. assert_select_error /Name cannot be blank/
  729. end
  730. def test_destroy
  731. @request.session[:user_id] = 2
  732. delete(:destroy, :params => {:id => 1})
  733. assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :set_filter => 1, :query_id => nil
  734. assert_nil Query.find_by_id(1)
  735. end
  736. def test_backslash_should_be_escaped_in_filters
  737. @request.session[:user_id] = 2
  738. get(:new, :params => {:subject => 'foo/bar'})
  739. assert_response :success
  740. assert_include 'addFilter("subject", "=", ["foo\/bar"]);', response.body
  741. end
  742. def test_filter_with_project_id_should_return_filter_values
  743. @request.session[:user_id] = 2
  744. get(
  745. :filter,
  746. :params => {
  747. :project_id => 1,
  748. :name => 'fixed_version_id'
  749. }
  750. )
  751. assert_response :success
  752. assert_equal 'application/json', response.media_type
  753. json = ActiveSupport::JSON.decode(response.body)
  754. assert_include ["eCookbook - 2.0", "3", "open"], json
  755. end
  756. def test_version_filter_time_entries_with_project_id_should_return_filter_values
  757. @request.session[:user_id] = 2
  758. get(
  759. :filter,
  760. :params => {
  761. :project_id => 1,
  762. :type => 'TimeEntryQuery',
  763. :name => 'issue.fixed_version_id'
  764. }
  765. )
  766. assert_response :success
  767. assert_equal 'application/json', response.media_type
  768. json = ActiveSupport::JSON.decode(response.body)
  769. assert_include ["eCookbook - 2.0", "3", "open"], json
  770. end
  771. def test_version_filter_without_project_id_should_return_all_visible_fixed_versions
  772. # Remove "jsmith" user from "Private child of eCookbook" project
  773. Project.find(5).memberships.find_by(:user_id => 2).destroy
  774. @request.session[:user_id] = 2
  775. get(
  776. :filter,
  777. :params => {
  778. :name => 'fixed_version_id'
  779. }
  780. )
  781. assert_response :success
  782. assert_equal 'application/json', response.media_type
  783. json = ActiveSupport::JSON.decode(response.body)
  784. # response includes visible version
  785. assert_include ["eCookbook Subproject 1 - 2.0", "4", "open"], json
  786. assert_include ["eCookbook - 0.1", "1", "closed"], json
  787. # response includes systemwide visible version
  788. assert_include ["OnlineStore - Systemwide visible version", "7", "open"], json
  789. # response doesn't include non visible version
  790. assert_not_include ["Private child of eCookbook - Private Version of public subproject", "6", "open"], json
  791. end
  792. def test_subproject_filter_time_entries_with_project_id_should_return_filter_values
  793. @request.session[:user_id] = 2
  794. get(
  795. :filter,
  796. :params => {
  797. :project_id => 1,
  798. :type => 'TimeEntryQuery',
  799. :name => 'subproject_id'
  800. }
  801. )
  802. assert_response :success
  803. assert_equal 'application/json', response.media_type
  804. json = ActiveSupport::JSON.decode(response.body)
  805. assert_equal 4, json.count
  806. assert_include ["Private child of eCookbook", "5"], json
  807. end
  808. def test_assignee_filter_should_return_active_and_locked_users_grouped_by_status
  809. @request.session[:user_id] = 1
  810. get(
  811. :filter,
  812. :params => {
  813. :project_id => 1,
  814. :type => 'IssueQuery',
  815. :name => 'assigned_to_id'
  816. }
  817. )
  818. assert_response :success
  819. assert_equal 'application/json', response.media_type
  820. json = ActiveSupport::JSON.decode(response.body)
  821. assert_equal 6, json.count
  822. # "me" value should not be grouped
  823. assert_include ["<< me >>", "me"], json
  824. assert_include ["Dave Lopper", "3", "active"], json
  825. assert_include ["Dave2 Lopper2", "5", "locked"], json
  826. end
  827. def test_author_filter_should_return_active_and_locked_users_grouped_by_status
  828. @request.session[:user_id] = 1
  829. get(
  830. :filter,
  831. :params => {
  832. :project_id => 1,
  833. :type => 'IssueQuery',
  834. :name => 'author_id'
  835. }
  836. )
  837. assert_response :success
  838. assert_equal 'application/json', response.media_type
  839. json = ActiveSupport::JSON.decode(response.body)
  840. assert_equal 7, json.count
  841. # "me" value should not be grouped
  842. assert_include ["<< me >>", "me"], json
  843. assert_include ["Dave Lopper", "3", "active"], json
  844. assert_include ["Dave2 Lopper2", "5", "locked"], json
  845. assert_include ["Anonymous", User.anonymous.id.to_s], json
  846. end
  847. def test_user_filter_should_return_active_and_locked_users_grouped_by_status
  848. @request.session[:user_id] = 1
  849. get(
  850. :filter,
  851. :params => {
  852. :project_id => 1,
  853. :type => 'TimeEntryQuery',
  854. :name => 'user_id'
  855. }
  856. )
  857. assert_response :success
  858. assert_equal 'application/json', response.media_type
  859. json = ActiveSupport::JSON.decode(response.body)
  860. assert_equal 7, json.count
  861. # "me" value should not be grouped
  862. assert_include ["<< me >>", "me"], json
  863. assert_include ["Dave Lopper", "3", "active"], json
  864. assert_include ["Dave2 Lopper2", "5", "locked"], json
  865. end
  866. def test_watcher_filter_without_permission_should_show_only_me
  867. # This user does not have view_issue_watchers permission
  868. @request.session[:user_id] = 7
  869. get(
  870. :filter,
  871. :params => {
  872. :project_id => 1,
  873. :type => 'IssueQuery',
  874. :name => 'watcher_id'
  875. }
  876. )
  877. assert_response :success
  878. assert_equal 'application/json', response.media_type
  879. json = ActiveSupport::JSON.decode(response.body)
  880. assert_equal 1, json.count
  881. assert_equal [["<< me >>", "me"]], json
  882. end
  883. def test_watcher_filter_with_permission_should_show_members_and_groups
  884. # This user has view_issue_watchers permission
  885. @request.session[:user_id] = 1
  886. get(
  887. :filter,
  888. :params => {
  889. :project_id => 1,
  890. :type => 'IssueQuery',
  891. :name => 'watcher_id'
  892. }
  893. )
  894. assert_response :success
  895. assert_equal 'application/json', response.media_type
  896. json = ActiveSupport::JSON.decode(response.body)
  897. assert_equal 7, json.count
  898. # "me" value should not be grouped
  899. assert_include ["<< me >>", "me"], json
  900. assert_include ["Dave Lopper", "3", "active"], json
  901. assert_include ["Dave2 Lopper2", "5", "locked"], json
  902. assert_include ["A Team", "10", "active"], json
  903. end
  904. def test_watcher_filter_with_permission_should_show_members_and_groups_globally
  905. # This user has view_issue_watchers permission
  906. @request.session[:user_id] = 1
  907. get(
  908. :filter,
  909. :params => {
  910. :type => 'IssueQuery',
  911. :name => 'watcher_id'
  912. }
  913. )
  914. assert_response :success
  915. assert_equal 'application/json', response.media_type
  916. json = ActiveSupport::JSON.decode(response.body)
  917. assert_equal 8, json.count
  918. # "me" value should not be grouped
  919. assert_include ['<< me >>', 'me'], json
  920. assert_include ['Dave Lopper', '3', 'active'], json
  921. assert_include ['Dave2 Lopper2', '5', 'locked'], json
  922. assert_include ['A Team', '10', 'active'], json
  923. end
  924. def test_activity_filter_should_return_active_and_system_activity_ids
  925. TimeEntryActivity.create!(:name => 'Design', :parent_id => 9, :project_id => 1)
  926. TimeEntryActivity.create!(:name => 'QA', :active => false, :parent_id => 11, :project_id => 1)
  927. TimeEntryActivity.create!(:name => 'Inactive Activity', :active => true, :parent_id => 14, :project_id => 1)
  928. @request.session[:user_id] = 2
  929. get(
  930. :filter,
  931. :params => {
  932. :project_id => 1,
  933. :type => 'TimeEntryQuery',
  934. :name => 'activity_id'
  935. }
  936. )
  937. assert_response :success
  938. assert_equal 'application/json', response.media_type
  939. json = ActiveSupport::JSON.decode(response.body)
  940. assert_equal 3, json.count
  941. assert_include ["Design", "9"], json
  942. assert_include ["Development", "10"], json
  943. assert_include ["Inactive Activity", "14"], json
  944. end
  945. end