agent_ticket_overview_level0_test.rb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'browser_test_helper'
  3. class AgentTicketOverviewLevel0Test < TestCase
  4. def test_bulk_close
  5. @browser = browser_instance
  6. login(
  7. username: 'admin@example.com',
  8. password: 'test',
  9. url: browser_url,
  10. )
  11. tasks_close_all
  12. # test bulk action
  13. # create new ticket
  14. ticket1 = ticket_create(
  15. data: {
  16. customer: 'nico',
  17. group: 'Users',
  18. title: 'overview count test #1',
  19. body: 'overview count test #1',
  20. }
  21. )
  22. ticket2 = ticket_create(
  23. data: {
  24. customer: 'nico',
  25. group: 'Users',
  26. title: 'overview count test #2',
  27. body: 'overview count test #2',
  28. }
  29. )
  30. click(text: 'Overviews')
  31. # enable full overviews
  32. execute(
  33. js: '$(".content.active .sidebar").css("display", "block")',
  34. )
  35. click(text: 'Unassigned & Open')
  36. watch_for(
  37. css: '.content.active',
  38. value: 'overview count test #2',
  39. )
  40. # select both via bulk action
  41. click(
  42. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  43. fast: true,
  44. )
  45. # scroll to reply - needed for chrome
  46. scroll_to(
  47. position: 'top',
  48. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  49. )
  50. click(
  51. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  52. fast: true,
  53. )
  54. exists(
  55. css: %(.content.active table tr td input[value="#{ticket1[:id]}"][type="checkbox"]:checked),
  56. )
  57. exists(
  58. css: %(.content.active table tr td input[value="#{ticket2[:id]}"][type="checkbox"]:checked),
  59. )
  60. # remember current overview count
  61. overview_counter_before = overview_counter
  62. # select close state & submit
  63. select(
  64. css: '.content.active .bulkAction [name="state_id"]',
  65. value: 'closed',
  66. )
  67. click(
  68. css: '.content.active .bulkAction .js-confirm',
  69. )
  70. click(
  71. css: '.content.active .bulkAction .js-submit',
  72. )
  73. watch_for_disappear(
  74. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  75. timeout: 12,
  76. )
  77. exists_not(
  78. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  79. )
  80. exists_not(
  81. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  82. )
  83. # remember current overview count
  84. await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
  85. overview_counter_before = overview_counter
  86. # click options and enable number and article count
  87. click(css: '.content.active [data-type="settings"]')
  88. modal_ready
  89. check(
  90. css: '.modal input[value="number"]',
  91. )
  92. check(
  93. css: '.modal input[value="title"]',
  94. )
  95. check(
  96. css: '.modal input[value="customer"]',
  97. )
  98. check(
  99. css: '.modal input[value="group"]',
  100. )
  101. check(
  102. css: '.modal input[value="created_at"]',
  103. )
  104. check(
  105. css: '.modal input[value="article_count"]',
  106. )
  107. click(css: '.modal .js-submit')
  108. modal_disappear
  109. # check if number and article count is shown
  110. match(
  111. css: '.content.active table th:nth-child(3)',
  112. value: '#',
  113. )
  114. match(
  115. css: '.content.active table th:nth-child(4)',
  116. value: 'Title',
  117. )
  118. match(
  119. css: '.content.active table th:nth-child(7)',
  120. value: 'Article#',
  121. )
  122. # reload browser
  123. reload
  124. sleep 4
  125. # check if number and article count is shown
  126. match(
  127. css: '.content.active table th:nth-child(3)',
  128. value: '#',
  129. )
  130. match(
  131. css: '.content.active table th:nth-child(4)',
  132. value: 'Title',
  133. )
  134. match(
  135. css: '.content.active table th:nth-child(7)',
  136. value: 'Article#',
  137. )
  138. # disable number and article count
  139. click(css: '.content.active [data-type="settings"]')
  140. modal_ready
  141. uncheck(
  142. css: '.modal input[value="number"]',
  143. )
  144. uncheck(
  145. css: '.modal input[value="article_count"]',
  146. )
  147. click(css: '.modal .js-submit')
  148. modal_disappear
  149. # check if number and article count is gone
  150. match_not(
  151. css: '.content.active table th:nth-child(3)',
  152. value: '#',
  153. )
  154. match(
  155. css: '.content.active table th:nth-child(3)',
  156. value: 'Title',
  157. )
  158. exists_not(
  159. css: '.content.active table th:nth-child(8)',
  160. )
  161. # create new ticket
  162. ticket3 = ticket_create(
  163. data: {
  164. customer: 'nico',
  165. group: 'Users',
  166. title: 'overview count test #3',
  167. body: 'overview count test #3',
  168. }
  169. )
  170. # get new overview count
  171. await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] + 1)
  172. # open ticket by search
  173. ticket_open_by_search(
  174. number: ticket3[:number],
  175. )
  176. sleep 1
  177. # close ticket
  178. ticket_update(
  179. data: {
  180. state: 'closed',
  181. }
  182. )
  183. # get current overview count
  184. await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'])
  185. # cleanup
  186. tasks_close_all
  187. end
  188. def test_bulk_pending
  189. @browser = browser_instance
  190. login(
  191. username: 'admin@example.com',
  192. password: 'test',
  193. url: browser_url,
  194. )
  195. tasks_close_all
  196. # test bulk action
  197. # create new ticket
  198. ticket1 = ticket_create(
  199. data: {
  200. customer: 'nico',
  201. group: 'Users',
  202. title: 'overview count test #3',
  203. body: 'overview count test #3',
  204. }
  205. )
  206. ticket2 = ticket_create(
  207. data: {
  208. customer: 'nico',
  209. group: 'Users',
  210. title: 'overview count test #4',
  211. body: 'overview count test #4',
  212. }
  213. )
  214. click(text: 'Overviews')
  215. # enable full overviews
  216. execute(
  217. js: '$(".content.active .sidebar").css("display", "block")',
  218. )
  219. click(text: 'Unassigned & Open')
  220. watch_for(
  221. css: '.content.active',
  222. value: 'overview count test #4',
  223. timeout: 8,
  224. )
  225. # remember current overview count
  226. overview_counter_before = overview_counter
  227. # select both via bulk action
  228. click(
  229. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  230. fast: true,
  231. )
  232. # scroll to reply - needed for chrome
  233. scroll_to(
  234. position: 'top',
  235. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  236. )
  237. click(
  238. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  239. fast: true,
  240. )
  241. exists(
  242. css: %(.content.active table tr td input[value="#{ticket1[:id]}"][type="checkbox"]:checked),
  243. )
  244. exists(
  245. css: %(.content.active table tr td input[value="#{ticket2[:id]}"][type="checkbox"]:checked),
  246. )
  247. exists(
  248. displayed: false,
  249. css: '.content.active .bulkAction [data-name="pending_time"]',
  250. )
  251. select(
  252. css: '.content.active .bulkAction [name="state_id"]',
  253. value: 'pending close',
  254. )
  255. exists(
  256. displayed: true,
  257. css: '.content.active .bulkAction [data-name="pending_time"]',
  258. )
  259. set(
  260. css: '.content.active .bulkAction [data-item="date"]',
  261. value: '05/23/2037',
  262. )
  263. select(
  264. css: '.content.active .bulkAction [name="group_id"]',
  265. value: 'Users',
  266. )
  267. select(
  268. css: '.content.active .bulkAction [name="owner_id"]',
  269. value: 'Test Admin Agent',
  270. )
  271. click(
  272. css: '.content.active .bulkAction .js-confirm',
  273. )
  274. click(
  275. css: '.content.active .bulkAction .js-submit',
  276. )
  277. watch_for_disappear(
  278. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  279. timeout: 12,
  280. )
  281. exists_not(
  282. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  283. )
  284. exists_not(
  285. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  286. )
  287. # get new overview count
  288. await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
  289. # open ticket by search
  290. ticket_open_by_search(
  291. number: ticket1[:number],
  292. )
  293. sleep 1
  294. # close ticket
  295. ticket_update(
  296. data: {
  297. state: 'closed',
  298. }
  299. )
  300. # open ticket by search
  301. ticket_open_by_search(
  302. number: ticket2[:number],
  303. )
  304. sleep 1
  305. # close ticket
  306. ticket_update(
  307. data: {
  308. state: 'closed',
  309. }
  310. )
  311. # cleanup
  312. tasks_close_all
  313. end
  314. # verify correct behaviour for issue #1864 - Bulk-Action: Not possible to change owner
  315. def test_bulk_owner_change
  316. @browser = browser_instance
  317. login(
  318. username: 'admin@example.com',
  319. password: 'test',
  320. url: browser_url,
  321. )
  322. tasks_close_all
  323. # test bulk action
  324. # create new ticket
  325. ticket1 = ticket_create(
  326. data: {
  327. customer: 'nico',
  328. group: 'Users',
  329. title: 'overview owner change test #1',
  330. body: 'overview owner change #1',
  331. }
  332. )
  333. ticket2 = ticket_create(
  334. data: {
  335. customer: 'nico',
  336. group: 'Users',
  337. title: 'overview owner change #2',
  338. body: 'overview owner change #2',
  339. }
  340. )
  341. overview_open(
  342. link: '#ticket/view/all_unassigned',
  343. )
  344. watch_for(
  345. css: '.content.active',
  346. value: 'overview owner change #2',
  347. timeout: 8,
  348. )
  349. # remember current overview count
  350. overview_counter_before = overview_counter
  351. # select both via bulk action
  352. click(
  353. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  354. fast: true,
  355. )
  356. # scroll to reply - needed for chrome
  357. scroll_to(
  358. position: 'top',
  359. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  360. )
  361. click(
  362. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  363. fast: true,
  364. )
  365. exists(
  366. css: %(.content.active table tr td input[value="#{ticket1[:id]}"][type="checkbox"]:checked),
  367. )
  368. exists(
  369. css: %(.content.active table tr td input[value="#{ticket2[:id]}"][type="checkbox"]:checked),
  370. )
  371. select(
  372. css: '.content.active .bulkAction [name="owner_id"]',
  373. value: 'Test Admin Agent',
  374. )
  375. select(
  376. css: '.content.active .bulkAction [name="state_id"]',
  377. value: 'closed',
  378. )
  379. click(
  380. css: '.content.active .bulkAction .js-confirm',
  381. )
  382. click(
  383. css: '.content.active .bulkAction .js-submit',
  384. )
  385. watch_for_disappear(
  386. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  387. timeout: 12,
  388. )
  389. exists_not(
  390. css: %(.content.active table tr td input[value="#{ticket1[:id]}"]),
  391. )
  392. exists_not(
  393. css: %(.content.active table tr td input[value="#{ticket2[:id]}"]),
  394. )
  395. # get new overview count
  396. await_overview_counter(view: '#ticket/view/all_unassigned', count: overview_counter_before['#ticket/view/all_unassigned'] - 2)
  397. # cleanup
  398. tasks_close_all
  399. end
  400. # verify fix for issue #2026 - Bulk action should not be shown if user has no change permissions
  401. def test_no_bulk_action_when_missing_change_permission
  402. @browser = browser_instance
  403. login(
  404. username: 'admin@example.com',
  405. password: 'test',
  406. url: browser_url,
  407. )
  408. tasks_close_all
  409. # create new group
  410. group_create(
  411. data: {
  412. name: 'some group2',
  413. },
  414. )
  415. role_edit(
  416. data: {
  417. name: 'Agent',
  418. group_permissions: { 2 => ['full'],
  419. 3 => ['full'], }
  420. },
  421. )
  422. user_edit(
  423. data: {
  424. login: 'admin@example.com',
  425. permissions: { 1 => ['full'],
  426. 2 => ['full'],
  427. 3 => ['full'], }
  428. },
  429. )
  430. user_create(
  431. data: {
  432. firstname: 'Tester',
  433. lastname: 'Agent 2',
  434. email: 'agent2@example.com',
  435. password: 'test',
  436. role: 'Agent',
  437. permissions: { 1 => %w[read create overview] }
  438. },
  439. )
  440. # create new tickets
  441. can_change_ticket = ticket_create(
  442. data: {
  443. customer: 'nico',
  444. group: 'some group2',
  445. title: 'overview test #5',
  446. body: 'overview test #5',
  447. }
  448. )
  449. cannot_change_ticket = ticket_create(
  450. data: {
  451. customer: 'nico',
  452. group: 'Users',
  453. title: 'overview test #6',
  454. body: 'overview test #6',
  455. }
  456. )
  457. logout # logout as admin@example.com then login as agent2@example.com
  458. login(
  459. username: 'agent2@example.com',
  460. password: 'test',
  461. url: browser_url,
  462. )
  463. tasks_close_all
  464. # open Overview menu tab
  465. click(
  466. css: '.js-menu .js-overviewsMenuItem',
  467. )
  468. # enable full overviews
  469. execute(
  470. js: '$(".content.active .sidebar").css("display", "block")',
  471. )
  472. # click Unassigned & Open tab
  473. click(
  474. css: '.content.active [href="#ticket/view/all_unassigned"]',
  475. )
  476. watch_for(
  477. css: '.content.active',
  478. value: 'overview test #6',
  479. timeout: 8,
  480. )
  481. # first select the ticket that we have change rights to
  482. check(
  483. css: %(.content.active table tr td input[value="#{can_change_ticket[:id]}"]),
  484. )
  485. # check that the bulk action form appears
  486. exists(
  487. displayed: true,
  488. css: '.content.active .bulkAction',
  489. )
  490. # then select the ticket that we do not have change rights to
  491. scroll_to(
  492. position: 'top',
  493. css: %(.content.active table tr td input[value="#{cannot_change_ticket[:id]}"]),
  494. )
  495. check(
  496. css: %(.content.active table tr td input[value="#{cannot_change_ticket[:id]}"]),
  497. )
  498. # check that the bulk action form disappears
  499. exists(
  500. displayed: false,
  501. css: '.content.active .bulkAction',
  502. )
  503. # de-select the ticket that we do not have change rights to
  504. uncheck(
  505. css: %(.content.active table tr td input[value="#{cannot_change_ticket[:id]}"]),
  506. fast: true,
  507. )
  508. # check that the bulk action form appears again
  509. exists(
  510. displayed: true,
  511. css: '.content.active .bulkAction',
  512. )
  513. # de-select the ticket that we have change rights to
  514. uncheck(
  515. css: %(.content.active table tr td input[value="#{can_change_ticket[:id]}"]),
  516. fast: true,
  517. )
  518. # check that the bulk action form disappears again
  519. exists(
  520. displayed: false,
  521. css: '.content.active .bulkAction',
  522. )
  523. # cleanup
  524. tasks_close_all
  525. logout # logout as agent2@example.com and then login as admin@example.com to clean up tickets
  526. login(
  527. username: 'admin@example.com',
  528. password: 'test',
  529. url: browser_url,
  530. )
  531. tasks_close_all
  532. # open ticket by search
  533. ticket_open_by_search(
  534. number: cannot_change_ticket[:number],
  535. )
  536. sleep 1
  537. # close ticket
  538. ticket_update(
  539. data: {
  540. state: 'closed',
  541. }
  542. )
  543. # open ticket by search
  544. ticket_open_by_search(
  545. number: can_change_ticket[:number],
  546. )
  547. sleep 1
  548. # close ticket
  549. ticket_update(
  550. data: {
  551. state: 'closed',
  552. }
  553. )
  554. end
  555. end