object_manager_attributes_spec.rb 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'ObjectManager Attributes', type: :request do
  4. let(:admin) do
  5. create(:admin)
  6. end
  7. describe 'request handling' do
  8. it 'does add new ticket text object' do
  9. authenticated_as(admin)
  10. post '/api/v1/object_manager_attributes', params: {}, as: :json
  11. # token based on headers
  12. params = {
  13. name: 'test1',
  14. object: 'Ticket',
  15. display: 'Test 1',
  16. active: true,
  17. data_type: 'input',
  18. data_option: {
  19. default: 'test',
  20. type: 'text',
  21. maxlength: 120
  22. },
  23. screens: {
  24. create_middle: {
  25. 'ticket.customer': {
  26. shown: true,
  27. item_class: 'column'
  28. },
  29. 'ticket.agent': {
  30. shown: true,
  31. item_class: 'column'
  32. }
  33. },
  34. edit: {
  35. 'ticket.customer': {
  36. shown: true
  37. },
  38. 'ticket.agent': {
  39. shown: true
  40. }
  41. }
  42. },
  43. id: 'c-196'
  44. }
  45. post '/api/v1/object_manager_attributes', params: params, as: :json
  46. expect(response).to have_http_status(:created)
  47. expect(json_response).to be_truthy
  48. expect(json_response['data_option']['null']).to be_truthy
  49. expect(json_response['data_option']['null']).to be(true)
  50. expect(json_response['name']).to eq('test1')
  51. end
  52. it 'does add new ticket text object - no default' do
  53. authenticated_as(admin)
  54. post '/api/v1/object_manager_attributes', params: {}, as: :json
  55. # token based on headers
  56. params = {
  57. name: 'test2',
  58. object: 'Ticket',
  59. display: 'Test 2',
  60. active: true,
  61. data_type: 'input',
  62. data_option: {
  63. type: 'text',
  64. maxlength: 120
  65. },
  66. screens: {
  67. create_middle: {
  68. 'ticket.customer': {
  69. shown: true,
  70. item_class: 'column'
  71. },
  72. 'ticket.agent': {
  73. shown: true,
  74. item_class: 'column'
  75. }
  76. },
  77. edit: {
  78. 'ticket.customer': {
  79. shown: true
  80. },
  81. 'ticket.agent': {
  82. shown: true
  83. }
  84. }
  85. },
  86. id: 'c-196'
  87. }
  88. post '/api/v1/object_manager_attributes', params: params, as: :json
  89. expect(response).to have_http_status(:created)
  90. expect(json_response).to be_truthy
  91. expect(json_response['data_option']['null']).to be_truthy
  92. expect(json_response['data_option']['null']).to be(true)
  93. expect(json_response['name']).to eq('test2')
  94. end
  95. it 'does update ticket text object', db_strategy: :reset do
  96. # add a new object
  97. object = create(:object_manager_attribute_text)
  98. migration = ObjectManager::Attribute.migration_execute
  99. expect(migration).to be(true)
  100. authenticated_as(admin)
  101. post "/api/v1/object_manager_attributes/#{object.id}", params: {}, as: :json
  102. # parameters for updating
  103. params = {
  104. name: object.name,
  105. object: 'Ticket',
  106. display: 'Test 4',
  107. active: true,
  108. data_type: 'input',
  109. data_option: {
  110. default: 'test',
  111. type: 'text',
  112. maxlength: 120
  113. },
  114. screens: {
  115. create_middle: {
  116. 'ticket.customer': {
  117. shown: true,
  118. item_class: 'column'
  119. },
  120. 'ticket.agent': {
  121. shown: true,
  122. item_class: 'column'
  123. }
  124. },
  125. edit: {
  126. 'ticket.customer': {
  127. shown: true
  128. },
  129. 'ticket.agent': {
  130. shown: true
  131. }
  132. }
  133. },
  134. id: 'c-196'
  135. }
  136. # update the object
  137. put "/api/v1/object_manager_attributes/#{object.id}", params: params, as: :json
  138. expect(response).to have_http_status(:ok)
  139. expect(json_response).to be_truthy
  140. expect(json_response['data_option']['null']).to be_truthy
  141. expect(json_response['name']).to eq(object.name)
  142. expect(json_response['display']).to eq('Test 4')
  143. end
  144. it 'does add new ticket boolean object' do
  145. authenticated_as(admin)
  146. post '/api/v1/object_manager_attributes', params: {}, as: :json
  147. # token based on headers
  148. params = {
  149. active: true,
  150. data_option: {
  151. options: {
  152. false: 'no',
  153. true: 'yes'
  154. }
  155. },
  156. data_type: 'boolean',
  157. display: 'Boolean 2',
  158. id: 'c-200',
  159. name: 'bool2',
  160. object: 'Ticket',
  161. screens: {
  162. create_middle: {
  163. 'ticket.agent' => {
  164. item_class: 'column',
  165. shown: true
  166. },
  167. 'ticket.customer' => {
  168. item_class: 'column',
  169. shown: true
  170. }
  171. },
  172. edit: {
  173. 'ticket.agent' => {
  174. shown: true
  175. },
  176. 'ticket.customer' => {
  177. shown: true
  178. }
  179. }
  180. }
  181. }
  182. post '/api/v1/object_manager_attributes', params: params, as: :json
  183. expect(response).to have_http_status(:created)
  184. expect(json_response).to be_truthy
  185. expect(json_response['data_option']['null']).to be_truthy
  186. expect(json_response['data_option']['null']).to be(true)
  187. expect(json_response['name']).to eq('bool2')
  188. end
  189. it 'does add new user select object' do
  190. authenticated_as(admin)
  191. post '/api/v1/object_manager_attributes', params: {}, as: :json
  192. # token based on headers
  193. params = {
  194. active: true,
  195. data_option: {
  196. options: {
  197. key1: 'foo'
  198. }
  199. },
  200. data_type: 'select',
  201. display: 'Test 5',
  202. id: 'c-204',
  203. name: 'test5',
  204. object: 'User',
  205. screens: {
  206. create: {
  207. 'admin.user' => {
  208. shown: true
  209. },
  210. 'ticket.agent' => {
  211. shown: true
  212. },
  213. 'ticket.customer' => {
  214. shown: true
  215. }
  216. },
  217. edit: {
  218. 'admin.user' => {
  219. shown: true
  220. },
  221. 'ticket.agent' => {
  222. shown: true
  223. }
  224. },
  225. view: {
  226. 'admin.user' => {
  227. shown: true
  228. },
  229. 'ticket.agent' => {
  230. shown: true
  231. },
  232. 'ticket.customer' => {
  233. shown: true
  234. }
  235. }
  236. }
  237. }
  238. post '/api/v1/object_manager_attributes', params: params, as: :json
  239. expect(response).to have_http_status(:created)
  240. expect(json_response).to be_truthy
  241. expect(json_response['data_option']['null']).to be_truthy
  242. expect(json_response['data_option']['null']).to be(true)
  243. expect(json_response['name']).to eq('test5')
  244. end
  245. it 'does update user select object', authenticated_as: -> { admin }, db_strategy: :reset do
  246. # add a new object
  247. object = create(:object_manager_attribute_text, object_name: 'User')
  248. migration = ObjectManager::Attribute.migration_execute
  249. expect(migration).to be(true)
  250. post "/api/v1/object_manager_attributes/#{object.id}", params: {}, as: :json
  251. # parameters for updating
  252. params = {
  253. active: true,
  254. data_option: {
  255. options: {
  256. key1: 'foo',
  257. key2: 'bar'
  258. }
  259. },
  260. data_type: 'select',
  261. display: 'Test 7',
  262. id: 'c-204',
  263. name: object.name,
  264. object: 'User',
  265. screens: {
  266. create: {
  267. 'admin.user' => {
  268. shown: true
  269. },
  270. 'ticket.agent' => {
  271. shown: true
  272. },
  273. 'ticket.customer' => {
  274. shown: true
  275. }
  276. },
  277. edit: {
  278. 'admin.user' => {
  279. shown: true
  280. },
  281. 'ticket.agent' => {
  282. shown: true
  283. }
  284. },
  285. view: {
  286. 'admin.user' => {
  287. shown: true
  288. },
  289. 'ticket.agent' => {
  290. shown: true
  291. },
  292. 'ticket.customer' => {
  293. shown: true
  294. }
  295. }
  296. }
  297. }
  298. # update the object
  299. put "/api/v1/object_manager_attributes/#{object.id}", params: params, as: :json
  300. expect(response).to have_http_status(:ok)
  301. expect(json_response).to be_truthy
  302. expect(json_response['data_option']['options']).to be_truthy
  303. expect(json_response['name']).to eq(object.name)
  304. expect(json_response['display']).to eq('Test 7')
  305. end
  306. it 'does converts string to boolean for default value for boolean data type with true (01)', db_strategy: :reset do
  307. params = {
  308. name: "customerdescription#{SecureRandom.uuid.tr('-', '_')}",
  309. object: 'Ticket',
  310. display: "custom description#{SecureRandom.uuid.tr('-', '_')}",
  311. active: true,
  312. data_type: 'boolean',
  313. data_option: {
  314. options: {
  315. true: '',
  316. false: '',
  317. },
  318. default: 'true',
  319. screens: {
  320. create_middle: {
  321. 'ticket.customer': {
  322. shown: true,
  323. item_class: 'column'
  324. },
  325. 'ticket.agent': {
  326. shown: true,
  327. item_class: 'column'
  328. }
  329. },
  330. edit: {
  331. 'ticket.customer': {
  332. shown: true
  333. },
  334. 'ticket.agent': {
  335. shown: true
  336. }
  337. }
  338. }
  339. },
  340. id: 'c-201'
  341. }
  342. authenticated_as(admin)
  343. post '/api/v1/object_manager_attributes', params: params, as: :json
  344. migration = ObjectManager::Attribute.migration_execute
  345. expect(migration).to be(true)
  346. expect(response).to have_http_status(:created) # created
  347. expect(json_response).to be_truthy
  348. expect(json_response['data_option']['default']).to be_truthy
  349. expect(json_response['data_option']['default']).to be(true)
  350. expect(json_response['data_type']).to eq('boolean')
  351. end
  352. it 'does converts string to boolean for default value for boolean data type with false (02)', db_strategy: :reset do
  353. params = {
  354. name: "customerdescription_#{SecureRandom.uuid.tr('-', '_')}",
  355. object: 'Ticket',
  356. display: "custom description #{SecureRandom.uuid.tr('-', '_')}",
  357. active: true,
  358. data_type: 'boolean',
  359. data_option: {
  360. options: {
  361. true: '',
  362. false: '',
  363. },
  364. default: 'false',
  365. screens: {
  366. create_middle: {
  367. 'ticket.customer': {
  368. shown: true,
  369. item_class: 'column'
  370. },
  371. 'ticket.agent': {
  372. shown: true,
  373. item_class: 'column'
  374. }
  375. },
  376. edit: {
  377. 'ticket.customer': {
  378. shown: true
  379. },
  380. 'ticket.agent': {
  381. shown: true
  382. }
  383. }
  384. }
  385. },
  386. }
  387. authenticated_as(admin)
  388. post '/api/v1/object_manager_attributes', params: params, as: :json
  389. migration = ObjectManager::Attribute.migration_execute
  390. expect(migration).to be(true)
  391. expect(response).to have_http_status(:created) # created
  392. expect(json_response).to be_truthy
  393. expect(json_response['data_option']['default']).to be_falsey
  394. expect(json_response['data_option']['default']).to be(false)
  395. expect(json_response['data_type']).to eq('boolean')
  396. end
  397. it 'does ticket attributes cannot be removed when it is referenced by an overview (03)', db_strategy: :reset do
  398. # 1. create a new ticket attribute and execute migration
  399. ObjectManager::Attribute.migration_execute
  400. params = {
  401. name: 'test_attribute_referenced_by_an_overview',
  402. object: 'Ticket',
  403. display: 'Test Attribute',
  404. active: true,
  405. data_type: 'input',
  406. data_option: {
  407. default: '',
  408. type: 'text',
  409. maxlength: 120,
  410. null: true,
  411. options: {},
  412. relation: ''
  413. },
  414. screens: {
  415. create_middle: {
  416. 'ticket.customer': {
  417. shown: true,
  418. item_class: 'column'
  419. },
  420. 'ticket.agent': {
  421. shown: true,
  422. item_class: 'column'
  423. }
  424. },
  425. edit: {
  426. 'ticket.customer': {
  427. shown: true
  428. },
  429. 'ticket.agent': {
  430. shown: true
  431. }
  432. }
  433. },
  434. }
  435. authenticated_as(admin)
  436. post '/api/v1/object_manager_attributes', params: params, as: :json
  437. migration = ObjectManager::Attribute.migration_execute
  438. expect(migration).to be(true)
  439. # 2. create an overview that uses the attribute
  440. params = {
  441. name: 'test_overview',
  442. roles: Role.where(name: 'Agent').pluck(:name),
  443. condition: {
  444. 'ticket.state_id': {
  445. operator: 'is',
  446. value: Ticket::State.all.pluck(:id),
  447. },
  448. 'ticket.test_attribute_referenced_by_an_overview': {
  449. operator: 'contains',
  450. value: 'DUMMY'
  451. },
  452. },
  453. order: {
  454. by: 'created_at',
  455. direction: 'DESC',
  456. },
  457. view: {
  458. d: %w[title customer state created_at],
  459. s: %w[number title customer state created_at],
  460. m: %w[number title customer state created_at],
  461. view_mode_default: 's',
  462. },
  463. user_ids: [ '1' ],
  464. }
  465. if Overview.where('name like ?', '%test%').empty?
  466. post '/api/v1/overviews', params: params, as: :json
  467. expect(response).to have_http_status(:created)
  468. expect(Hash).to eq(json_response.class)
  469. expect('test_overview').to eq(json_response['name'])
  470. end
  471. # 3. attempt to delete the ticket attribute
  472. get '/api/v1/object_manager_attributes', as: :json
  473. expect(response).to have_http_status(:ok)
  474. target_attribute = json_response.select { |x| x['name'] == 'test_attribute_referenced_by_an_overview' && x['object'] == 'Ticket' }
  475. expect(target_attribute.size).to eq(1)
  476. target_id = target_attribute[0]['id']
  477. delete "/api/v1/object_manager_attributes/#{target_id}", as: :json
  478. expect(response).to have_http_status(:unprocessable_entity)
  479. expect(response.body).to include('Overview')
  480. expect(response.body).to include('test_overview')
  481. expect(response.body).to include('cannot be deleted!')
  482. end
  483. it 'does ticket attributes cannot be removed when it is referenced by a trigger (04)', db_strategy: :reset do
  484. # 1. create a new ticket attribute and execute migration
  485. ObjectManager::Attribute.migration_execute
  486. params = {
  487. name: 'test_attribute_referenced_by_a_trigger',
  488. object: 'Ticket',
  489. display: 'Test Attribute',
  490. active: true,
  491. data_type: 'input',
  492. data_option: {
  493. default: '',
  494. type: 'text',
  495. maxlength: 120,
  496. null: true,
  497. options: {},
  498. relation: ''
  499. },
  500. screens: {
  501. create_middle: {
  502. 'ticket.customer': {
  503. shown: true,
  504. item_class: 'column'
  505. },
  506. 'ticket.agent': {
  507. shown: true,
  508. item_class: 'column'
  509. }
  510. },
  511. edit: {
  512. 'ticket.customer': {
  513. shown: true
  514. },
  515. 'ticket.agent': {
  516. shown: true
  517. }
  518. }
  519. },
  520. }
  521. authenticated_as(admin)
  522. post '/api/v1/object_manager_attributes', params: params, as: :json
  523. migration = ObjectManager::Attribute.migration_execute
  524. expect(migration).to be(true)
  525. # 2. create an trigger that uses the attribute
  526. params = {
  527. name: 'test_trigger',
  528. condition: {
  529. 'ticket.test_attribute_referenced_by_a_trigger': {
  530. operator: 'contains',
  531. value: 'DUMMY'
  532. }
  533. },
  534. perform: {
  535. 'ticket.state_id': {
  536. value: '2'
  537. }
  538. },
  539. active: true,
  540. id: 'c-3'
  541. }
  542. if Trigger.where('name like ?', '%test%').empty?
  543. post '/api/v1/triggers', params: params, as: :json
  544. expect(response).to have_http_status(:created)
  545. expect(Hash).to eq(json_response.class)
  546. expect('test_trigger').to eq(json_response['name'])
  547. end
  548. # 3. attempt to delete the ticket attribute
  549. get '/api/v1/object_manager_attributes', as: :json
  550. expect(response).to have_http_status(:ok)
  551. target_attribute = json_response.select { |x| x['name'] == 'test_attribute_referenced_by_a_trigger' && x['object'] == 'Ticket' }
  552. expect(target_attribute.size).to eq(1)
  553. target_id = target_attribute[0]['id']
  554. delete "/api/v1/object_manager_attributes/#{target_id}", as: :json
  555. expect(response).to have_http_status(:unprocessable_entity)
  556. expect(response.body).to include('Trigger')
  557. expect(response.body).to include('test_trigger')
  558. expect(response.body).to include('cannot be deleted!')
  559. end
  560. it 'does ticket attributes cannot be removed when it is referenced by a scheduler (05)', db_strategy: :reset do
  561. # 1. create a new ticket attribute and execute migration
  562. ObjectManager::Attribute.migration_execute
  563. params = {
  564. name: 'test_attribute_referenced_by_a_scheduler',
  565. object: 'Ticket',
  566. display: 'Test Attribute',
  567. active: true,
  568. data_type: 'input',
  569. data_option: {
  570. default: '',
  571. type: 'text',
  572. maxlength: 120,
  573. null: true,
  574. options: {},
  575. relation: ''
  576. },
  577. screens: {
  578. create_middle: {
  579. 'ticket.customer': {
  580. shown: true,
  581. item_class: 'column'
  582. },
  583. 'ticket.agent': {
  584. shown: true,
  585. item_class: 'column'
  586. }
  587. },
  588. edit: {
  589. 'ticket.customer': {
  590. shown: true
  591. },
  592. 'ticket.agent': {
  593. shown: true
  594. }
  595. }
  596. },
  597. }
  598. authenticated_as(admin)
  599. post '/api/v1/object_manager_attributes', params: params, as: :json
  600. migration = ObjectManager::Attribute.migration_execute
  601. expect(migration).to be(true)
  602. # 2. create a scheduler that uses the attribute
  603. params = {
  604. name: 'test_scheduler',
  605. timeplan: {
  606. days: {
  607. Mon: true,
  608. Tue: false,
  609. Wed: false,
  610. Thu: false,
  611. Fri: false,
  612. Sat: false,
  613. Sun: false
  614. },
  615. hours: {
  616. '0': true,
  617. '1': false,
  618. '2': false,
  619. '3': false,
  620. '4': false,
  621. '5': false,
  622. '6': false,
  623. '7': false,
  624. '8': false,
  625. '9': false,
  626. '10': false,
  627. '11': false,
  628. '12': false,
  629. '13': false,
  630. '14': false,
  631. '15': false,
  632. '16': false,
  633. '17': false,
  634. '18': false,
  635. '19': false,
  636. '20': false,
  637. '21': false,
  638. '22': false,
  639. '23': false
  640. },
  641. minutes: {
  642. '0': true,
  643. '10': false,
  644. '20': false,
  645. '30': false,
  646. '40': false,
  647. '50': false
  648. }
  649. },
  650. condition: {
  651. 'ticket.test_attribute_referenced_by_a_scheduler': {
  652. operator: 'contains',
  653. value: 'DUMMY'
  654. }
  655. },
  656. perform: {
  657. 'ticket.state_id': {
  658. value: '2'
  659. }
  660. },
  661. disable_notification: true,
  662. note: '',
  663. active: true,
  664. id: 'c-0'
  665. }
  666. if Job.where('name like ?', '%test%').empty?
  667. post '/api/v1/jobs', params: params, as: :json
  668. expect(response).to have_http_status(:created)
  669. expect(Hash).to eq(json_response.class)
  670. expect('test_scheduler').to eq(json_response['name'])
  671. end
  672. # 3. attempt to delete the ticket attribute
  673. get '/api/v1/object_manager_attributes', as: :json
  674. expect(response).to have_http_status(:ok)
  675. target_attribute = json_response.select { |x| x['name'] == 'test_attribute_referenced_by_a_scheduler' && x['object'] == 'Ticket' }
  676. expect(target_attribute.size).to eq(1)
  677. target_id = target_attribute[0]['id']
  678. delete "/api/v1/object_manager_attributes/#{target_id}", as: :json
  679. expect(response).to have_http_status(:unprocessable_entity)
  680. expect(response.body).to include('Job')
  681. expect(response.body).to include('test_scheduler')
  682. expect(response.body).to include('cannot be deleted!')
  683. end
  684. it 'does ticket attributes can be removed when it is referenced by an overview but by user object (06)', db_strategy: :reset do
  685. # 1. create a new ticket attribute and execute migration
  686. ObjectManager::Attribute.migration_execute
  687. params = {
  688. name: 'test_attribute_referenced_by_an_overview',
  689. object: 'Ticket',
  690. display: 'Test Attribute',
  691. active: true,
  692. data_type: 'input',
  693. data_option: {
  694. default: '',
  695. type: 'text',
  696. maxlength: 120,
  697. null: true,
  698. options: {},
  699. relation: ''
  700. },
  701. screens: {
  702. create_middle: {
  703. 'ticket.customer': {
  704. shown: true,
  705. item_class: 'column'
  706. },
  707. 'ticket.agent': {
  708. shown: true,
  709. item_class: 'column'
  710. }
  711. },
  712. edit: {
  713. 'ticket.customer': {
  714. shown: true
  715. },
  716. 'ticket.agent': {
  717. shown: true
  718. }
  719. }
  720. },
  721. }
  722. authenticated_as(admin)
  723. post '/api/v1/object_manager_attributes', params: params, as: :json
  724. params = {
  725. name: 'test_attribute_referenced_by_an_overview',
  726. object: 'User',
  727. display: 'Test Attribute',
  728. active: true,
  729. data_type: 'input',
  730. data_option: {
  731. default: '',
  732. type: 'text',
  733. maxlength: 120,
  734. null: true,
  735. options: {},
  736. relation: ''
  737. },
  738. screens: {
  739. create_middle: {
  740. 'ticket.customer': {
  741. shown: true,
  742. item_class: 'column'
  743. },
  744. 'ticket.agent': {
  745. shown: true,
  746. item_class: 'column'
  747. }
  748. },
  749. edit: {
  750. 'ticket.customer': {
  751. shown: true
  752. },
  753. 'ticket.agent': {
  754. shown: true
  755. }
  756. }
  757. },
  758. }
  759. post '/api/v1/object_manager_attributes', params: params, as: :json
  760. migration = ObjectManager::Attribute.migration_execute
  761. expect(migration).to be(true)
  762. # 2. create an overview that uses the attribute
  763. params = {
  764. name: 'test_overview',
  765. roles: Role.where(name: 'Agent').pluck(:name),
  766. condition: {
  767. 'ticket.state_id': {
  768. operator: 'is',
  769. value: Ticket::State.all.pluck(:id),
  770. },
  771. 'ticket.test_attribute_referenced_by_an_overview': {
  772. operator: 'contains',
  773. value: 'DUMMY'
  774. },
  775. },
  776. order: {
  777. by: 'created_at',
  778. direction: 'DESC',
  779. },
  780. view: {
  781. d: %w[title customer state created_at],
  782. s: %w[number title customer state created_at],
  783. m: %w[number title customer state created_at],
  784. view_mode_default: 's',
  785. },
  786. user_ids: [ '1' ],
  787. }
  788. if Overview.where('name like ?', '%test%').empty?
  789. post '/api/v1/overviews', params: params, as: :json
  790. expect(response).to have_http_status(:created)
  791. expect(Hash).to eq(json_response.class)
  792. expect('test_overview').to eq(json_response['name'])
  793. end
  794. # 3. attempt to delete the ticket attribute
  795. get '/api/v1/object_manager_attributes', as: :json
  796. expect(response).to have_http_status(:ok)
  797. all_json_response = json_response
  798. target_attribute = all_json_response.select { |x| x['name'] == 'test_attribute_referenced_by_an_overview' && x['object'] == 'User' }
  799. expect(target_attribute.size).to eq(1)
  800. target_id = target_attribute[0]['id']
  801. delete "/api/v1/object_manager_attributes/#{target_id}", as: :json
  802. expect(response).to have_http_status(:ok)
  803. target_attribute = all_json_response.select { |x| x['name'] == 'test_attribute_referenced_by_an_overview' && x['object'] == 'Ticket' }
  804. expect(target_attribute.size).to eq(1)
  805. target_id = target_attribute[0]['id']
  806. delete "/api/v1/object_manager_attributes/#{target_id}", as: :json
  807. expect(response).to have_http_status(:unprocessable_entity)
  808. expect(response.body).to include('Overview')
  809. expect(response.body).to include('test_overview')
  810. expect(response.body).to include('cannot be deleted!')
  811. migration = ObjectManager::Attribute.migration_execute
  812. expect(migration).to be(true)
  813. end
  814. it 'does verify if attribute type can not be changed (07)', db_strategy: :reset do
  815. params = {
  816. name: "customerdescription_#{SecureRandom.uuid.tr('-', '_')}",
  817. object: 'Ticket',
  818. display: "custom description #{SecureRandom.uuid.tr('-', '_')}",
  819. active: true,
  820. data_type: 'boolean',
  821. data_option: {
  822. options: {
  823. true: '',
  824. false: '',
  825. },
  826. default: 'false',
  827. screens: {
  828. create_middle: {
  829. 'ticket.customer': {
  830. shown: true,
  831. item_class: 'column'
  832. },
  833. 'ticket.agent': {
  834. shown: true,
  835. item_class: 'column'
  836. }
  837. },
  838. edit: {
  839. 'ticket.customer': {
  840. shown: true
  841. },
  842. 'ticket.agent': {
  843. shown: true
  844. }
  845. }
  846. }
  847. },
  848. }
  849. authenticated_as(admin)
  850. post '/api/v1/object_manager_attributes', params: params, as: :json
  851. expect(response).to have_http_status(:created) # created
  852. expect(json_response).to be_truthy
  853. expect(json_response['data_option']['default']).to be_falsey
  854. expect(json_response['data_option']['default']).to be(false)
  855. expect(json_response['data_type']).to eq('boolean')
  856. migration = ObjectManager::Attribute.migration_execute
  857. expect(migration).to be(true)
  858. params['data_type'] = 'input'
  859. params['data_option'] = {
  860. default: 'test',
  861. type: 'text',
  862. maxlength: 120
  863. }
  864. put "/api/v1/object_manager_attributes/#{json_response['id']}", params: params, as: :json
  865. expect(response).to have_http_status(:unprocessable_entity)
  866. expect(json_response).to be_truthy
  867. expect(json_response['error']).to be_truthy
  868. end
  869. it 'does verify if attribute type can be changed (08)', db_strategy: :reset do
  870. params = {
  871. name: "customerdescription_#{SecureRandom.uuid.tr('-', '_')}",
  872. object: 'Ticket',
  873. display: "custom description #{SecureRandom.uuid.tr('-', '_')}",
  874. active: true,
  875. data_type: 'input',
  876. data_option: {
  877. default: 'test',
  878. type: 'text',
  879. maxlength: 120,
  880. },
  881. screens: {
  882. create_middle: {
  883. 'ticket.customer': {
  884. shown: true,
  885. item_class: 'column'
  886. },
  887. 'ticket.agent': {
  888. shown: true,
  889. item_class: 'column'
  890. }
  891. },
  892. edit: {
  893. 'ticket.customer': {
  894. shown: true
  895. },
  896. 'ticket.agent': {
  897. shown: true
  898. }
  899. },
  900. },
  901. }
  902. authenticated_as(admin)
  903. post '/api/v1/object_manager_attributes', params: params, as: :json
  904. expect(response).to have_http_status(:created) # created
  905. expect(json_response).to be_truthy
  906. expect(json_response['data_option']['default']).to eq('test')
  907. expect(json_response['data_type']).to eq('input')
  908. migration = ObjectManager::Attribute.migration_execute
  909. expect(migration).to be(true)
  910. params['data_type'] = 'select'
  911. params['data_option'] = {
  912. default: 'fuu',
  913. options: {
  914. key1: 'foo',
  915. key2: 'fuu',
  916. }
  917. }
  918. put "/api/v1/object_manager_attributes/#{json_response['id']}", params: params, as: :json
  919. expect(response).to have_http_status(:ok)
  920. expect(json_response).to be_truthy
  921. expect(json_response['data_option']['default']).to eq('test')
  922. expect(json_response['data_option_new']['default']).to eq('fuu')
  923. expect(json_response['data_type']).to eq('select')
  924. end
  925. it "doesn't let to update item that doesn't exist", authenticated_as: -> { admin } do
  926. params = {
  927. active: true,
  928. data_option: {
  929. type: 'text',
  930. maxlength: 200
  931. },
  932. data_type: 'input',
  933. display: 'Test 7',
  934. name: 'attribute_that_doesnt_exist',
  935. object: 'User',
  936. }
  937. # update the object
  938. put '/api/v1/object_manager_attributes/abc', params: params, as: :json
  939. expect(response).to have_http_status(:unprocessable_entity)
  940. end
  941. context 'position handling', authenticated_as: -> { admin } do
  942. let(:base_params) do
  943. {
  944. name: "customerdescription_#{SecureRandom.uuid.tr('-', '_')}",
  945. object: 'Ticket',
  946. display: "custom description #{SecureRandom.uuid.tr('-', '_')}",
  947. active: true,
  948. data_type: 'input',
  949. data_option: {
  950. default: 'test',
  951. type: 'text',
  952. maxlength: 120,
  953. },
  954. }
  955. end
  956. let(:new_attribute_id) { json_response['id'] }
  957. let(:new_attribute_object) { ObjectManager::Attribute.find new_attribute_id }
  958. before { post '/api/v1/object_manager_attributes', params: params, as: :json }
  959. context 'when creating a new attribute' do
  960. let(:params) { base_params }
  961. context 'with no position attribute provided' do
  962. let(:maximum_position) do
  963. ObjectManager::Attribute
  964. .for_object(params[:object])
  965. .maximum(:position)
  966. end
  967. it 'defaults to the maximum available position' do
  968. expect(new_attribute_object.position).to eq maximum_position
  969. end
  970. end
  971. context 'with a position attribute given' do
  972. let(:position) { 50 }
  973. let(:params) { base_params.merge(position: position) }
  974. it 'defaults to given position' do
  975. expect(new_attribute_object.position).to eq position
  976. end
  977. end
  978. end
  979. context 'when updating an existing attribute' do
  980. let(:alternative_position) { 123 }
  981. let(:alternative_display) { 'another description' }
  982. let(:params) { base_params }
  983. let(:alternative_params) { base_params.merge(display: alternative_display) }
  984. before do
  985. new_attribute_object.update! position: alternative_position
  986. put "/api/v1/object_manager_attributes/#{new_attribute_id}", params: alternative_params, as: :json
  987. new_attribute_object.reload
  988. end
  989. # confirm that test build up was correct
  990. it 'request succeeds' do
  991. expect(new_attribute_object.display).to eq alternative_display
  992. end
  993. # https://github.com/zammad/zammad/issues/3044
  994. it 'position did not reset' do
  995. expect(new_attribute_object.position).to eq alternative_position
  996. end
  997. end
  998. end
  999. end
  1000. end