zendesk_import_test.rb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. # Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
  2. require 'integration_test_helper'
  3. class ZendeskImportTest < ActiveSupport::TestCase
  4. self.test_order = :sorted
  5. if !ENV['IMPORT_ZENDESK_ENDPOINT']
  6. raise "ERROR: Need IMPORT_ZENDESK_ENDPOINT - hint IMPORT_ZENDESK_ENDPOINT='https://example.zendesk.com/api/v2'"
  7. end
  8. if !ENV['IMPORT_ZENDESK_ENDPOINT_KEY']
  9. raise "ERROR: Need IMPORT_ZENDESK_ENDPOINT_KEY - hint IMPORT_ZENDESK_ENDPOINT_KEY='01234567899876543210'"
  10. end
  11. if !ENV['IMPORT_ZENDESK_ENDPOINT_USERNAME']
  12. raise "ERROR: Need IMPORT_ZENDESK_ENDPOINT_USERNAME - hint IMPORT_ZENDESK_ENDPOINT_USERNAME='bob.ross@happylittletrees.com'"
  13. end
  14. Setting.set('import_zendesk_endpoint', ENV['IMPORT_ZENDESK_ENDPOINT'])
  15. Setting.set('import_zendesk_endpoint_key', ENV['IMPORT_ZENDESK_ENDPOINT_KEY'])
  16. Setting.set('import_zendesk_endpoint_username', ENV['IMPORT_ZENDESK_ENDPOINT_USERNAME'])
  17. Setting.set('import_mode', true)
  18. Setting.set('system_init_done', false)
  19. job = ImportJob.create(name: 'Import::Zendesk')
  20. job.start
  21. # check statistic count
  22. test 'check statistic' do
  23. # retrive statistic
  24. compare_statistic = {
  25. Groups: {
  26. skipped: 0,
  27. created: 2,
  28. updated: 0,
  29. unchanged: 0,
  30. failed: 0,
  31. deactivated: 0,
  32. sum: 2,
  33. total: 2
  34. },
  35. Users: {
  36. skipped: 0,
  37. created: 141,
  38. updated: 1,
  39. unchanged: 0,
  40. failed: 0,
  41. deactivated: 0,
  42. sum: 142,
  43. total: 142
  44. },
  45. Organizations: {
  46. skipped: 0,
  47. created: 1,
  48. updated: 0,
  49. unchanged: 1,
  50. failed: 0,
  51. deactivated: 0,
  52. sum: 2,
  53. total: 2
  54. },
  55. Tickets: {
  56. skipped: 1,
  57. created: 142,
  58. updated: 2,
  59. unchanged: 0,
  60. failed: 0,
  61. deactivated: 0,
  62. sum: 145,
  63. total: 145
  64. }
  65. }
  66. assert_equal(compare_statistic.with_indifferent_access, job.result, 'statistic')
  67. end
  68. # check count of imported items
  69. test 'check counts' do
  70. assert_equal(144, User.count, 'users')
  71. assert_equal(3, Group.count, 'groups')
  72. assert_equal(3, Role.count, 'roles')
  73. assert_equal(2, Organization.count, 'organizations')
  74. assert_equal(143, Ticket.count, 'tickets')
  75. assert_equal(153, Ticket::Article.count, 'ticket articles')
  76. assert_equal(3, Store.count, 'ticket article attachments')
  77. # TODO: Macros, Views, Automations...
  78. end
  79. # check imported users and permission
  80. test 'check users' do
  81. role_admin = Role.find_by(name: 'Admin')
  82. role_agent = Role.find_by(name: 'Agent')
  83. role_customer = Role.find_by(name: 'Customer')
  84. group_support = Group.find_by(name: 'Support')
  85. group_additional_group = Group.find_by(name: 'Additional Group')
  86. checks = [
  87. {
  88. id: 144,
  89. data: {
  90. firstname: 'Bob Smith',
  91. lastname: 'Smith',
  92. login: 'bob.smith@znuny.com',
  93. email: 'bob.smith@znuny.com',
  94. active: true,
  95. phone: '00114124',
  96. lieblingstier: 'Hundä',
  97. },
  98. roles: [role_admin, role_agent],
  99. groups: [group_support],
  100. },
  101. {
  102. id: 142,
  103. data: {
  104. firstname: 'Hansimerkur',
  105. lastname: '',
  106. login: 'hansimerkur@znuny.com',
  107. email: 'hansimerkur@znuny.com',
  108. active: true,
  109. lieblingstier: nil,
  110. },
  111. roles: [role_admin, role_agent],
  112. groups: [group_additional_group, group_support],
  113. },
  114. {
  115. id: 6,
  116. data: {
  117. firstname: 'Bernd',
  118. lastname: 'Hofbecker',
  119. login: 'bernd.hofbecker@znuny.com',
  120. email: 'bernd.hofbecker@znuny.com',
  121. active: true,
  122. },
  123. roles: [role_customer],
  124. groups: [],
  125. },
  126. {
  127. id: 143,
  128. data: {
  129. firstname: 'Zendesk',
  130. lastname: '',
  131. login: 'noreply@zendesk.com',
  132. email: 'noreply@zendesk.com',
  133. active: true,
  134. },
  135. roles: [role_customer],
  136. groups: [],
  137. },
  138. {
  139. id: 5,
  140. data: {
  141. firstname: 'Hans',
  142. lastname: 'Peter Wurst',
  143. login: 'hansimerkur+zd-c1@znuny.com',
  144. email: 'hansimerkur+zd-c1@znuny.com',
  145. active: true,
  146. },
  147. roles: [role_customer],
  148. groups: [],
  149. },
  150. ]
  151. checks.each do |check|
  152. user = User.find(check[:id])
  153. check[:data].each do |key, value|
  154. user_value = user[key]
  155. text = "user.#{key} for user_id #{check[:id]}"
  156. if value.nil?
  157. assert_nil(user_value, text)
  158. else
  159. assert_equal(value, user_value, text)
  160. end
  161. end
  162. assert_equal(check[:roles], user.roles.sort.to_a, "#{user.login} roles")
  163. assert_equal(check[:groups], user.groups_access('full').sort.to_a, "#{user.login} groups")
  164. end
  165. end
  166. # check user fields
  167. test 'check user fields' do
  168. local_fields = User.column_names
  169. copmare_fields = %w[
  170. id
  171. organization_id
  172. login
  173. firstname
  174. lastname
  175. email
  176. image
  177. image_source
  178. web
  179. password
  180. phone
  181. fax
  182. mobile
  183. department
  184. street
  185. zip
  186. city
  187. country
  188. address
  189. vip
  190. verified
  191. active
  192. note
  193. last_login
  194. source
  195. login_failed
  196. out_of_office
  197. out_of_office_start_at
  198. out_of_office_end_at
  199. out_of_office_replacement_id
  200. preferences
  201. updated_by_id
  202. created_by_id
  203. created_at
  204. updated_at
  205. lieblingstier
  206. custom_dropdown
  207. ]
  208. assert_equal(copmare_fields, local_fields, 'user fields')
  209. end
  210. # check groups/queues
  211. test 'check groups' do
  212. checks = [
  213. {
  214. id: 1,
  215. data: {
  216. name: 'Users',
  217. active: true,
  218. },
  219. },
  220. {
  221. id: 2,
  222. data: {
  223. name: 'Additional Group',
  224. active: true,
  225. },
  226. },
  227. {
  228. id: 3,
  229. data: {
  230. name: 'Support',
  231. active: true,
  232. },
  233. },
  234. ]
  235. checks.each do |check|
  236. group = Group.find(check[:id])
  237. check[:data].each do |key, value|
  238. assert_equal(value, group[key], "group.#{key} for group_id #{check[:id]}")
  239. end
  240. end
  241. end
  242. # check imported organizations
  243. test 'check organizations' do
  244. checks = [
  245. {
  246. id: 1,
  247. data: {
  248. name: 'Zammad Foundation',
  249. note: '',
  250. api_key: nil,
  251. custom_dropdown: nil,
  252. },
  253. },
  254. {
  255. id: 2,
  256. data: {
  257. name: 'Znuny',
  258. note: nil,
  259. api_key: 'my api öäüß',
  260. custom_dropdown: 'b',
  261. },
  262. },
  263. ]
  264. checks.each do |check|
  265. organization = Organization.find(check[:id])
  266. check[:data].each do |key, value|
  267. organization_value = organization[key]
  268. text = "organization.#{key} for organization_id #{check[:id]}"
  269. if value.nil?
  270. assert_nil(organization_value, text)
  271. else
  272. assert_equal(value, organization_value, text)
  273. end
  274. end
  275. end
  276. end
  277. # check organization fields
  278. test 'check organization fields' do
  279. local_fields = Organization.column_names
  280. copmare_fields = %w[
  281. id
  282. name
  283. shared
  284. domain
  285. domain_assignment
  286. active
  287. note
  288. updated_by_id
  289. created_by_id
  290. created_at
  291. updated_at
  292. api_key
  293. custom_dropdown
  294. ]
  295. assert_equal(copmare_fields, local_fields, 'organization fields')
  296. end
  297. # check imported tickets
  298. test 'check tickets' do
  299. checks = [
  300. {
  301. id: 2,
  302. data: {
  303. number: '2',
  304. title: 'test',
  305. note: nil,
  306. create_article_type_id: 1,
  307. create_article_sender_id: 2,
  308. article_count: 2,
  309. state_id: 3,
  310. group_id: 3,
  311. priority_id: 3,
  312. owner_id: User.find_by(login: 'bob.smith@znuny.com').id,
  313. customer_id: User.find_by(login: 'bernd.hofbecker@znuny.com').id,
  314. organization_id: 2,
  315. test_checkbox: true,
  316. custom_integer: 999,
  317. custom_dropdown: 'key2',
  318. custom_decimal: '1.6',
  319. not_existing: nil,
  320. },
  321. },
  322. {
  323. id: 3,
  324. data: {
  325. number: '3',
  326. title: 'Bob Smith, here is the test ticket you requested',
  327. note: nil,
  328. create_article_type_id: 10,
  329. create_article_sender_id: 2,
  330. article_count: 5,
  331. state_id: 3,
  332. group_id: 3,
  333. priority_id: 1,
  334. owner_id: User.find_by(login: 'bob.smith@znuny.com').id,
  335. customer_id: User.find_by(login: 'noreply@zendesk.com').id,
  336. organization_id: nil,
  337. test_checkbox: false,
  338. custom_integer: nil,
  339. custom_dropdown: '',
  340. custom_decimal: nil,
  341. not_existing: nil,
  342. },
  343. },
  344. {
  345. id: 5,
  346. data: {
  347. number: '5',
  348. title: 'Twitter',
  349. note: nil,
  350. create_article_type_id: 6,
  351. create_article_sender_id: 2,
  352. article_count: 1,
  353. state_id: 1,
  354. group_id: 3,
  355. priority_id: 2,
  356. owner_id: User.find_by(login: '-').id,
  357. customer_id: 69,
  358. organization_id: nil,
  359. },
  360. },
  361. {
  362. id: 143,
  363. data: {
  364. number: '143',
  365. title: 'Basti ist cool',
  366. note: nil,
  367. create_article_type_id: 8,
  368. create_article_sender_id: 2,
  369. article_count: 1,
  370. state_id: 1,
  371. group_id: 1,
  372. priority_id: 2,
  373. owner_id: User.find_by(login: '-').id,
  374. customer_id: 7,
  375. organization_id: nil,
  376. },
  377. },
  378. {
  379. id: 145,
  380. data: {
  381. number: '145',
  382. title: 'closed ticket - should be archived and imported',
  383. note: nil,
  384. create_article_type_id: 11,
  385. create_article_sender_id: 1,
  386. article_count: 2,
  387. state_id: Ticket::State.find_by(name: 'closed').id,
  388. group_id: Group.find_by(name: 'Additional Group').id,
  389. priority_id: Ticket::Priority.find_by(name: '2 normal').id,
  390. owner_id: User.find_by(login: 'hansimerkur@znuny.com').id,
  391. customer_id: User.find_by(login: 'bob.smith@znuny.com').id,
  392. organization_id: Organization.find_by(name: 'Znuny').id,
  393. },
  394. },
  395. # {
  396. # id: ,
  397. # data: {
  398. # title: ,
  399. # note: ,
  400. # create_article_type_id: ,
  401. # create_article_sender_id: ,
  402. # article_count: ,
  403. # state_id: ,
  404. # group_id: ,
  405. # priority_id: ,
  406. # owner_id: ,
  407. # customer_id: ,
  408. # organization_id: ,
  409. # },
  410. # },
  411. ]
  412. checks.each do |check|
  413. ticket = Ticket.find(check[:id])
  414. check[:data].each do |key, value|
  415. ticket_value = ticket[key]
  416. text = "ticket.#{key} for ticket_id #{check[:id]}"
  417. if value.nil?
  418. assert_nil(ticket_value, text)
  419. else
  420. assert_equal(value, ticket_value, text)
  421. end
  422. end
  423. end
  424. end
  425. test 'check article attachments' do
  426. checks = [
  427. {
  428. message_id: 39_984_258_725,
  429. data: {
  430. count: 1,
  431. 1 => {
  432. preferences: {
  433. 'Content-Type' => 'image/jpeg',
  434. 'resizable' => true,
  435. 'content_preview' => true
  436. },
  437. filename: '1a3496b9-53d9-494d-bbb0-e1d2e22074f8.jpeg',
  438. },
  439. },
  440. },
  441. {
  442. message_id: 32_817_827_921,
  443. data: {
  444. count: 1,
  445. 1 => {
  446. preferences: {
  447. 'Content-Type' => 'image/jpeg',
  448. 'resizable' => true,
  449. 'content_preview' => true
  450. },
  451. filename: 'paris.jpg',
  452. },
  453. },
  454. },
  455. {
  456. message_id: 538_901_840_720,
  457. data: {
  458. count: 1,
  459. 1 => {
  460. preferences: {
  461. 'Content-Type' => 'text/rtf'
  462. },
  463. filename: 'test.rtf',
  464. },
  465. },
  466. },
  467. ]
  468. checks.each do |check|
  469. article = Ticket::Article.find_by(message_id: check[:message_id])
  470. assert_equal(check[:data][:count], article.attachments.count, 'attachemnt count')
  471. (1..check[:data][:count]).each do |attachment_counter|
  472. attachment = article.attachments[ attachment_counter - 1 ]
  473. compare_attachment = check[:data][ attachment_counter ]
  474. assert_equal(compare_attachment[:filename], attachment.filename, 'attachment file name')
  475. assert_equal(compare_attachment[:preferences], attachment[:preferences], 'attachment preferences')
  476. end
  477. end
  478. end
  479. # check ticket fields
  480. test 'check ticket fields' do
  481. local_fields = Ticket.column_names
  482. copmare_fields = %w[
  483. id
  484. group_id
  485. priority_id
  486. state_id
  487. organization_id
  488. number
  489. title
  490. owner_id
  491. customer_id
  492. note
  493. first_response_at
  494. first_response_escalation_at
  495. first_response_in_min
  496. first_response_diff_in_min
  497. close_at
  498. close_escalation_at
  499. close_in_min
  500. close_diff_in_min
  501. update_escalation_at
  502. update_in_min
  503. update_diff_in_min
  504. last_contact_at
  505. last_contact_agent_at
  506. last_contact_customer_at
  507. last_owner_update_at
  508. create_article_type_id
  509. create_article_sender_id
  510. article_count
  511. escalation_at
  512. pending_time
  513. type
  514. time_unit
  515. preferences
  516. updated_by_id
  517. created_by_id
  518. created_at
  519. updated_at
  520. custom_decimal
  521. test_checkbox
  522. custom_date
  523. custom_integer
  524. custom_regex
  525. custom_dropdown
  526. ]
  527. assert_equal(copmare_fields, local_fields, 'ticket fields')
  528. end
  529. end