admin_object_manager_test.rb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. require 'browser_test_helper'
  2. class AdminObjectManagerTest < TestCase
  3. def test_basic_a
  4. @browser = browser_instance
  5. login(
  6. username: 'master@example.com',
  7. password: 'test',
  8. url: browser_url,
  9. )
  10. tasks_close_all()
  11. # already existing
  12. object_manager_attribute_create(
  13. data: {
  14. name: 'customer_id',
  15. display: 'Customer Should Not Creatable',
  16. data_type: 'Text',
  17. },
  18. error: 'already exists'
  19. )
  20. # invalid name
  21. object_manager_attribute_create(
  22. data: {
  23. name: 'some_other_id',
  24. display: 'Should Not Creatable',
  25. data_type: 'Text',
  26. },
  27. error: 'are not allowed'
  28. )
  29. # invalid name
  30. object_manager_attribute_create(
  31. data: {
  32. name: 'some_other_ids',
  33. display: 'Should Not Creatable',
  34. data_type: 'Text',
  35. },
  36. error: 'are not allowed'
  37. )
  38. # invalid name
  39. object_manager_attribute_create(
  40. data: {
  41. name: 'some spaces',
  42. display: 'Should Not Creatable',
  43. data_type: 'Text',
  44. },
  45. error: 'are not allowed'
  46. )
  47. # valid name
  48. object_manager_attribute_create(
  49. data: {
  50. name: 'browser_test1',
  51. display: 'Browser Test 1',
  52. data_type: 'Text',
  53. },
  54. )
  55. watch_for(
  56. css: '.content.active',
  57. value: 'Database Update required',
  58. )
  59. click(css: '.content.active .tab-pane.active div.js-execute')
  60. watch_for(
  61. css: '.modal',
  62. value: 'restart',
  63. )
  64. watch_for_disappear(
  65. css: '.modal',
  66. timeout: 7.minutes,
  67. )
  68. sleep 5
  69. watch_for(
  70. css: '.content.active',
  71. )
  72. # create new ticket
  73. ticket = ticket_create(
  74. data: {
  75. customer: 'nico',
  76. group: 'Users',
  77. priority: '2 normal',
  78. state: 'open',
  79. title: 'ticket attribute test #1',
  80. body: 'ticket attribute test #1',
  81. },
  82. #custom_data_select: {
  83. # key1: 'some value',
  84. #},
  85. custom_data_input: {
  86. browser_test1: 'some value öäüß',
  87. },
  88. disable_group_check: true,
  89. )
  90. # update ticket
  91. ticket_update(
  92. data: {},
  93. #custom_data_select: {
  94. # key1: 'some value',
  95. #},
  96. custom_data_input: {
  97. browser_test1: 'some value ABC',
  98. },
  99. )
  100. # discard new attribute
  101. click(css: 'a[href="#manage"]')
  102. click(css: 'a[href="#system/object_manager"]')
  103. watch_for(
  104. css: '.content.active table',
  105. value: 'browser_test1',
  106. )
  107. match_not(
  108. css: '.content.active',
  109. value: 'Database Update required',
  110. )
  111. object_manager_attribute_delete(
  112. data: {
  113. name: 'browser_test1',
  114. },
  115. )
  116. watch_for(
  117. css: '.content.active',
  118. value: 'Database Update required',
  119. )
  120. watch_for(
  121. css: '.content.active table',
  122. value: 'browser_test1',
  123. )
  124. click(css: '.content.active .tab-pane.active div.js-execute')
  125. watch_for(
  126. css: '.modal',
  127. value: 'restart',
  128. )
  129. watch_for_disappear(
  130. css: '.modal',
  131. timeout: 7.minutes,
  132. )
  133. sleep 5
  134. watch_for(
  135. css: '.content.active',
  136. )
  137. match_not(
  138. css: '.content.active',
  139. value: 'Database Update required',
  140. )
  141. match_not(
  142. css: '.content.active table',
  143. value: 'browser_test1',
  144. )
  145. end
  146. def test_basic_b
  147. @browser = browser_instance
  148. login(
  149. username: 'master@example.com',
  150. password: 'test',
  151. url: browser_url,
  152. )
  153. tasks_close_all()
  154. object_manager_attribute_create(
  155. data: {
  156. name: 'browser_test2',
  157. display: 'Browser Test 2',
  158. data_type: 'Select',
  159. data_option: {
  160. options: {
  161. 'aa' => 'AA',
  162. 'bb' => 'BB',
  163. },
  164. },
  165. },
  166. )
  167. object_manager_attribute_discard_changes
  168. sleep 4
  169. object_manager_attribute_create(
  170. data: {
  171. name: 'browser_test2',
  172. display: 'Browser Test 2',
  173. data_type: 'Text',
  174. #data_option: {
  175. # default: 'xxx',
  176. #},
  177. },
  178. )
  179. object_manager_attribute_create(
  180. data: {
  181. name: 'browser_test3',
  182. display: 'Browser Test 3',
  183. data_type: 'Select',
  184. data_option: {
  185. options: {
  186. 'aa' => 'AA',
  187. 'bb' => 'BB',
  188. 'cc' => 'CC',
  189. },
  190. },
  191. },
  192. )
  193. object_manager_attribute_create(
  194. data: {
  195. name: 'browser_test4',
  196. display: 'Browser Test 4',
  197. data_type: 'Integer',
  198. #data_option: {
  199. # default: 'xxx',
  200. # min: 15,
  201. # max: 99,
  202. #},
  203. },
  204. )
  205. object_manager_attribute_create(
  206. data: {
  207. name: 'browser_test5',
  208. display: 'Browser Test 5',
  209. data_type: 'Datetime',
  210. #data_option: {
  211. # future: true,
  212. # past: true,
  213. # diff: 24
  214. #},
  215. },
  216. )
  217. object_manager_attribute_create(
  218. data: {
  219. name: 'browser_test6',
  220. display: 'Browser Test 6',
  221. data_type: 'Date',
  222. #data_option: {
  223. # future: true,
  224. # past: true,
  225. # diff: 24
  226. #},
  227. },
  228. )
  229. # rubocop:disable Lint/BooleanSymbol
  230. object_manager_attribute_create(
  231. data: {
  232. name: 'browser_test7',
  233. display: 'Browser Test 7',
  234. data_type: 'Boolean',
  235. data_option: {
  236. options: {
  237. true: 'YES',
  238. false: 'NO',
  239. },
  240. # default: true,
  241. },
  242. },
  243. )
  244. # rubocop:enable Lint/BooleanSymbol
  245. watch_for(
  246. css: '.content.active',
  247. value: 'Database Update required',
  248. )
  249. click(css: '.content.active .tab-pane.active div.js-execute')
  250. watch_for(
  251. css: '.modal',
  252. value: 'restart',
  253. )
  254. watch_for_disappear(
  255. css: '.modal',
  256. timeout: 7.minutes,
  257. )
  258. sleep 5
  259. watch_for(
  260. css: '.content.active',
  261. )
  262. # create new ticket
  263. ticket = ticket_create(
  264. data: {
  265. customer: 'nico',
  266. group: 'Users',
  267. priority: '2 normal',
  268. state: 'open',
  269. title: 'ticket attribute test all #1',
  270. body: 'ticket attribute test all #1',
  271. },
  272. custom_data_select: {
  273. browser_test3: 'CC',
  274. browser_test7: 'NO',
  275. },
  276. custom_data_input: {
  277. browser_test2: 'some value öäüß',
  278. browser_test4: '25',
  279. },
  280. disable_group_check: true,
  281. )
  282. ticket_verify(
  283. data: {
  284. title: 'ticket attribute test all #1',
  285. custom_data_select: {
  286. browser_test3: 'CC',
  287. browser_test7: 'NO',
  288. },
  289. custom_data_input: {
  290. browser_test2: 'some value öäüß',
  291. browser_test4: '25',
  292. },
  293. },
  294. )
  295. object_manager_attribute_delete(
  296. data: {
  297. name: 'browser_test2',
  298. },
  299. )
  300. object_manager_attribute_delete(
  301. data: {
  302. name: 'browser_test3',
  303. },
  304. )
  305. object_manager_attribute_delete(
  306. data: {
  307. name: 'browser_test4',
  308. },
  309. )
  310. object_manager_attribute_delete(
  311. data: {
  312. name: 'browser_test5',
  313. },
  314. )
  315. object_manager_attribute_delete(
  316. data: {
  317. name: 'browser_test6',
  318. },
  319. )
  320. object_manager_attribute_delete(
  321. data: {
  322. name: 'browser_test7',
  323. },
  324. )
  325. click(css: '.content.active .tab-pane.active div.js-execute')
  326. watch_for(
  327. css: '.modal',
  328. value: 'restart',
  329. )
  330. watch_for_disappear(
  331. css: '.modal',
  332. timeout: 7.minutes,
  333. )
  334. sleep 5
  335. watch_for(
  336. css: '.content.active',
  337. )
  338. match_not(
  339. css: '.content.active',
  340. value: 'Database Update required',
  341. )
  342. match_not(
  343. css: '.content.active table',
  344. value: 'browser_test2',
  345. )
  346. match_not(
  347. css: '.content.active table',
  348. value: 'browser_test3',
  349. )
  350. match_not(
  351. css: '.content.active table',
  352. value: 'browser_test4',
  353. )
  354. match_not(
  355. css: '.content.active table',
  356. value: 'browser_test5',
  357. )
  358. match_not(
  359. css: '.content.active table',
  360. value: 'browser_test6',
  361. )
  362. match_not(
  363. css: '.content.active table',
  364. value: 'browser_test7',
  365. )
  366. end
  367. def test_basic_c
  368. @browser = browser_instance
  369. login(
  370. username: 'master@example.com',
  371. password: 'test',
  372. url: browser_url,
  373. )
  374. tasks_close_all()
  375. # valid name
  376. object_manager_attribute_create(
  377. data: {
  378. name: 'browser_update_test1',
  379. display: 'Browser Update Test 1',
  380. data_type: 'Text',
  381. },
  382. )
  383. watch_for(
  384. css: '.content.active',
  385. value: 'Database Update required',
  386. )
  387. click(css: '.content.active .tab-pane.active div.js-execute')
  388. watch_for(
  389. css: '.modal',
  390. value: 'restart',
  391. )
  392. watch_for_disappear(
  393. css: '.modal',
  394. timeout: 7.minutes,
  395. )
  396. sleep 5
  397. watch_for(
  398. css: '.content.active',
  399. )
  400. match_not(
  401. css: '.content.active',
  402. value: 'Database Update required',
  403. )
  404. # valid name
  405. object_manager_attribute_update(
  406. data: {
  407. name: 'browser_update_test1',
  408. display: 'Browser Update Test 2',
  409. data_type: 'Text',
  410. },
  411. )
  412. watch_for(
  413. css: '.content.active',
  414. value: 'Database Update required',
  415. )
  416. click(css: '.content.active .tab-pane.active div.js-execute')
  417. watch_for(
  418. css: '.modal',
  419. value: 'configuration of Zammad has changed',
  420. )
  421. click(css: '.modal .js-submit')
  422. watch_for_disappear(
  423. css: '.modal',
  424. timeout: 7.minutes,
  425. )
  426. sleep 5
  427. watch_for(
  428. css: '.content.active',
  429. )
  430. match_not(
  431. css: '.content.active',
  432. value: 'Database Update required',
  433. )
  434. object_manager_attribute_delete(
  435. data: {
  436. name: 'browser_update_test1',
  437. },
  438. )
  439. watch_for(
  440. css: '.content.active',
  441. value: 'Database Update required',
  442. )
  443. watch_for(
  444. css: '.content.active table',
  445. value: 'browser_update_test1',
  446. )
  447. click(css: '.content.active .tab-pane.active div.js-execute')
  448. watch_for(
  449. css: '.modal',
  450. value: 'restart',
  451. )
  452. watch_for_disappear(
  453. css: '.modal',
  454. timeout: 7.minutes,
  455. )
  456. sleep 5
  457. watch_for(
  458. css: '.content.active',
  459. )
  460. match_not(
  461. css: '.content.active',
  462. value: 'Database Update required',
  463. )
  464. match_not(
  465. css: '.content.active table',
  466. value: 'browser_update_test1',
  467. )
  468. end
  469. def test_that_attributes_with_references_should_have_a_disabled_delete_button
  470. @browser = instance = browser_instance
  471. login(
  472. username: 'master@example.com',
  473. password: 'test',
  474. url: browser_url,
  475. )
  476. tasks_close_all()
  477. # create two new attributes
  478. object_manager_attribute_create(
  479. data: {
  480. name: 'deletable_attribute',
  481. display: 'Deletable Attribute',
  482. data_type: 'Text',
  483. },
  484. )
  485. object_manager_attribute_create(
  486. data: {
  487. name: 'undeletable_attribute',
  488. display: 'Undeletable Attribute',
  489. data_type: 'Text',
  490. },
  491. )
  492. watch_for(
  493. css: '.content.active',
  494. value: 'Database Update required',
  495. )
  496. click(css: '.content.active .tab-pane.active div.js-execute')
  497. watch_for(
  498. css: '.modal',
  499. value: 'restart',
  500. )
  501. watch_for_disappear(
  502. css: '.modal',
  503. timeout: 7.minutes,
  504. )
  505. sleep 5
  506. watch_for(
  507. css: '.content.active',
  508. )
  509. match_not(
  510. css: '.content.active',
  511. value: 'Database Update required',
  512. )
  513. # create a new overview that references the undeletable_attribute
  514. overview_create(
  515. browser: instance,
  516. data: {
  517. name: 'test_overview',
  518. roles: ['Agent'],
  519. selector: {
  520. 'Undeletable Attribute' => 'DUMMY',
  521. },
  522. 'order::direction' => 'down',
  523. 'text_input' => true,
  524. }
  525. )
  526. click(
  527. browser: instance,
  528. css: 'a[href="#manage"]',
  529. mute_log: true,
  530. )
  531. click(
  532. browser: instance,
  533. css: '.content.active a[href="#system/object_manager"]',
  534. mute_log: true,
  535. )
  536. 30.times do
  537. deletable_attribute = instance.find_elements(xpath: '//td[text()="deletable_attribute"]/following-sibling::*[2]')[0]
  538. break if deletable_attribute
  539. sleep 1
  540. end
  541. sleep 1
  542. deletable_attribute = instance.find_elements(xpath: '//td[text()="deletable_attribute"]/following-sibling::*[2]')[0]
  543. assert_not_nil(deletable_attribute)
  544. deletable_attribute_html = deletable_attribute.attribute('innerHTML')
  545. assert(deletable_attribute_html.include?('title="Delete"'))
  546. assert(deletable_attribute_html.include?('href="#"'))
  547. assert(deletable_attribute_html.exclude?('cannot be deleted'))
  548. undeletable_attribute = instance.find_elements(xpath: '//td[text()="undeletable_attribute"]/following-sibling::*[2]')[0]
  549. assert_not_nil(undeletable_attribute)
  550. undeletable_attribute_html = undeletable_attribute.attribute('innerHTML')
  551. assert(undeletable_attribute_html.include?('Overview'))
  552. assert(undeletable_attribute_html.include?('test_overview'))
  553. assert(undeletable_attribute_html.include?('cannot be deleted'))
  554. assert(undeletable_attribute_html.exclude?('href="#"'))
  555. end
  556. def test_proper_sorting_of_select_attributes
  557. @browser = browser_instance
  558. login(
  559. username: 'master@example.com',
  560. password: 'test',
  561. url: browser_url,
  562. )
  563. tasks_close_all()
  564. # lexicographically ordered list of option strings
  565. options = %w[0 000.000 1 100.100 100.200 2 200.100 200.200 3 ä b n ö p sr ß st t ü v]
  566. options_hash = Hash[options.reverse.collect { |o| [o, o] }]
  567. object_manager_attribute_create(
  568. data: {
  569. name: 'select_attributes_sorting_test',
  570. display: 'Select Attributes Sorting Test',
  571. data_type: 'Select',
  572. data_option: { options: options_hash },
  573. },
  574. )
  575. sleep 2
  576. # open the select attribute that we just created
  577. execute(js: "$(\".content.active td:contains('select_attributes_sorting_test')\").first().click()")
  578. sleep 3
  579. unsorted_locations = options.map do |key|
  580. [get_location(xpath: "//input[@value='#{key}']").y, key]
  581. end
  582. log("unsorted_locations = #{unsorted_locations.inspect}")
  583. sorted_locations = unsorted_locations.sort_by(&:first).map(&:second)
  584. log("sorted_locations = #{sorted_locations.inspect}")
  585. assert_equal options, sorted_locations
  586. # close the attribute modal
  587. click(css: '.modal button.js-submit')
  588. watch_for(
  589. css: '.content.active',
  590. value: 'Database Update required',
  591. )
  592. watch_for(
  593. css: '.content.active table',
  594. value: 'select_attributes_sorting_test',
  595. )
  596. click(css: '.content.active .tab-pane.active div.js-execute')
  597. watch_for(
  598. css: '.modal',
  599. value: 'restart',
  600. )
  601. watch_for_disappear(
  602. css: '.modal',
  603. timeout: 7.minutes,
  604. )
  605. sleep 5
  606. watch_for(
  607. css: '.content.active',
  608. )
  609. # create a new ticket and check whether the select attributes are correctly sorted or not
  610. click(
  611. css: 'a[href="#ticket/create"]',
  612. mute_log: true,
  613. )
  614. watch_for(
  615. css: 'select[name="select_attributes_sorting_test"]',
  616. )
  617. select_element = @browser.find_elements(css: 'select[name="select_attributes_sorting_test"]')[0]
  618. unsorted_options = select_element.find_elements(xpath: './*').map(&:text).reject { |x| x == '-' }
  619. log unsorted_options.inspect
  620. assert_equal options, unsorted_options
  621. end
  622. end