user_csv_import_test.rb 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. require 'test_helper'
  2. class UserCsvImportTest < ActiveSupport::TestCase
  3. test 'import example verify' do
  4. csv_string = User.csv_example
  5. rows = CSV.parse(csv_string)
  6. header = rows.shift
  7. assert_equal('id', header[0])
  8. assert_equal('login', header[1])
  9. assert_equal('firstname', header[2])
  10. assert_equal('lastname', header[3])
  11. assert_equal('email', header[4])
  12. assert(header.include?('organization'))
  13. end
  14. test 'empty payload' do
  15. csv_string = ''
  16. result = User.csv_import(
  17. string: csv_string,
  18. parse_params: {
  19. col_sep: ';',
  20. },
  21. try: true,
  22. )
  23. assert_equal(true, result[:try])
  24. assert_nil(result[:records])
  25. assert_equal('failed', result[:result])
  26. assert_equal('Unable to parse empty file/string for User.', result[:errors][0])
  27. csv_string = "login;firstname;lastname;email;active;\n"
  28. result = User.csv_import(
  29. string: csv_string,
  30. parse_params: {
  31. col_sep: ';',
  32. },
  33. try: true,
  34. )
  35. assert_equal(true, result[:try])
  36. assert(result[:records].blank?)
  37. assert_equal('failed', result[:result])
  38. assert_equal('No records found in file/string for User.', result[:errors][0])
  39. end
  40. test 'verify required lookup headers' do
  41. csv_string = "firstname;lastname;active;\nfirstname-simple-import1;lastname-simple-import1;;true\nfirstname-simple-import2;lastname-simple-import2;false\n"
  42. result = User.csv_import(
  43. string: csv_string,
  44. parse_params: {
  45. col_sep: ';',
  46. },
  47. try: true,
  48. )
  49. assert_equal(true, result[:try])
  50. assert_equal('failed', result[:result])
  51. assert_equal('No lookup column like id,login,email for User found.', result[:errors][0])
  52. end
  53. test 'simple import' do
  54. count = User.count
  55. csv_string = "login;firstname;lastname;email;active;\nuser-simple-IMPORT1;firstname-simple-import1;lastname-simple-import1;user-simple-IMPORT1@example.com ;true\nuser-simple-import2;firstname-simple-import2;lastname-simple-import2;user-simple-import2@example.com;false\n"
  56. result = User.csv_import(
  57. string: csv_string,
  58. parse_params: {
  59. col_sep: ';',
  60. },
  61. try: true,
  62. )
  63. assert_equal(true, result[:try])
  64. assert_equal(2, result[:records].count)
  65. assert_equal('success', result[:result])
  66. assert_equal(2, result[:stats][:created])
  67. assert_equal(0, result[:stats][:updated])
  68. assert_equal(count, User.count)
  69. assert_nil(User.find_by(login: 'user-simple-import1'))
  70. assert_nil(User.find_by(login: 'user-simple-import2'))
  71. result = User.csv_import(
  72. string: csv_string,
  73. parse_params: {
  74. col_sep: ';',
  75. },
  76. try: false,
  77. )
  78. assert_equal(false, result[:try])
  79. assert_equal(2, result[:records].count)
  80. assert_equal('success', result[:result])
  81. assert_equal(2, result[:stats][:created])
  82. assert_equal(0, result[:stats][:updated])
  83. assert_equal(count + 2, User.count)
  84. user1 = User.find_by(login: 'user-simple-import1')
  85. assert(user1)
  86. assert_equal(user1.login, 'user-simple-import1')
  87. assert_equal(user1.firstname, 'firstname-simple-import1')
  88. assert_equal(user1.lastname, 'lastname-simple-import1')
  89. assert_equal(user1.email, 'user-simple-import1@example.com')
  90. assert_equal(user1.active, true)
  91. user2 = User.find_by(login: 'user-simple-import2')
  92. assert(user2)
  93. assert_equal(user2.login, 'user-simple-import2')
  94. assert_equal(user2.firstname, 'firstname-simple-import2')
  95. assert_equal(user2.lastname, 'lastname-simple-import2')
  96. assert_equal(user2.email, 'user-simple-import2@example.com')
  97. assert_equal(user2.active, false)
  98. result = User.csv_import(
  99. string: csv_string,
  100. parse_params: {
  101. col_sep: ';',
  102. },
  103. try: false,
  104. )
  105. assert_equal(false, result[:try])
  106. assert_equal(2, result[:records].count)
  107. assert_equal('success', result[:result])
  108. assert_equal(0, result[:stats][:created])
  109. assert_equal(2, result[:stats][:updated])
  110. assert_equal(count + 2, User.count)
  111. user1_1 = user1
  112. user1 = User.find_by(login: 'user-simple-import1')
  113. assert(user1)
  114. assert_equal(user1.login, 'user-simple-import1')
  115. assert_equal(user1.firstname, 'firstname-simple-import1')
  116. assert_equal(user1.lastname, 'lastname-simple-import1')
  117. assert_equal(user1.email, 'user-simple-import1@example.com')
  118. assert_equal(user1.active, true)
  119. assert_equal(user1.updated_at, user1_1.updated_at)
  120. user2_1 = user2
  121. user2 = User.find_by(login: 'user-simple-import2')
  122. assert(user2)
  123. assert_equal(user2.login, 'user-simple-import2')
  124. assert_equal(user2.firstname, 'firstname-simple-import2')
  125. assert_equal(user2.lastname, 'lastname-simple-import2')
  126. assert_equal(user2.email, 'user-simple-import2@example.com')
  127. assert_equal(user2.active, false)
  128. assert_equal(user2.updated_at, user2_1.updated_at)
  129. travel 2.seconds
  130. csv_string = "login;firstname;lastname;email;active;\n ;firstname-simple-import1;lastname-simple-import1;user-simple-IMPORT1@example.com ;true\n user-simple-import2\t;firstname-simple-import2;lastname-simple-import2;;false\n"
  131. result = User.csv_import(
  132. string: csv_string,
  133. parse_params: {
  134. col_sep: ';',
  135. },
  136. try: false,
  137. )
  138. assert_equal(false, result[:try])
  139. assert_equal(2, result[:records].count)
  140. assert_equal(0, result[:stats][:created])
  141. assert_equal(2, result[:stats][:updated])
  142. assert_equal('success', result[:result])
  143. assert_equal(count + 2, User.count)
  144. user1_1 = user1
  145. user1 = User.find_by(email: 'user-simple-import1@example.com')
  146. assert(user1)
  147. assert_equal(user1.login, 'user-simple-import1@example.com')
  148. assert_equal(user1.firstname, 'firstname-simple-import1')
  149. assert_equal(user1.lastname, 'lastname-simple-import1')
  150. assert_equal(user1.email, 'user-simple-import1@example.com')
  151. assert_equal(user1.active, true)
  152. assert_not_equal(user1.updated_at, user1_1.updated_at)
  153. user2_1 = user2
  154. user2 = User.find_by(login: 'user-simple-import2')
  155. assert(user2)
  156. assert_equal(user2.login, 'user-simple-import2')
  157. assert_equal(user2.firstname, 'firstname-simple-import2')
  158. assert_equal(user2.lastname, 'lastname-simple-import2')
  159. assert_equal(user2.email, 'user-simple-import2@example.com')
  160. assert_equal(user2.active, false)
  161. assert_equal(user2.updated_at, user2_1.updated_at)
  162. user1.destroy!
  163. user2.destroy!
  164. end
  165. test 'simple import with invalid id' do
  166. csv_string = "id;login;firstname;lastname;email;active;\n999999999;user-simple-invalid_id-import1;firstname-simple-import1;lastname-simple-import1;user-simple-invalid_id-import1@example.com;true\n;user-simple-invalid_id-import2;firstname-simple-import2;lastname-simple-import2;user-simple-invalid_id-import2@example.com;false\n"
  167. result = User.csv_import(
  168. string: csv_string,
  169. parse_params: {
  170. col_sep: ';',
  171. },
  172. try: true,
  173. )
  174. assert_equal(true, result[:try])
  175. assert_equal(1, result[:errors].count)
  176. assert_equal('failed', result[:result])
  177. assert_equal("Line 1: unknown User with id '999999999'.", result[:errors][0])
  178. assert_nil(User.find_by(login: 'user-simple-invalid_id-import1'))
  179. assert_nil(User.find_by(login: 'user-simple-invalid_id-import2'))
  180. result = User.csv_import(
  181. string: csv_string,
  182. parse_params: {
  183. col_sep: ';',
  184. },
  185. try: false,
  186. )
  187. assert_equal(false, result[:try])
  188. assert_equal(1, result[:records].count)
  189. assert_equal('failed', result[:result])
  190. assert_nil(User.find_by(login: 'user-simple-invalid_id-import1'))
  191. # any single failure will cause the entire import to be aborted
  192. assert_nil(User.find_by(login: 'user-simple-invalid_id-import2'))
  193. end
  194. test 'simple import with read only id' do
  195. csv_string = "id;login;firstname;lastname;email;active;\n1;user-simple-readonly_id-import1;firstname-simple-import1;lastname-simple-import1;user-simple-readonly_id-import1@example.com;true\n;user-simple-readonly_id-import2;firstname-simple-import2;lastname-simple-import2;user-simple-readonly_id-import2@example.com;false\n"
  196. result = User.csv_import(
  197. string: csv_string,
  198. parse_params: {
  199. col_sep: ';',
  200. },
  201. try: true,
  202. )
  203. assert_equal(true, result[:try])
  204. assert_equal(1, result[:errors].count)
  205. assert_equal('failed', result[:result])
  206. assert_equal("Line 1: unable to update User with id '1'.", result[:errors][0])
  207. assert_nil(User.find_by(login: 'user-simple-readonly_id-import1'))
  208. assert_nil(User.find_by(login: 'user-simple-readonly_id-import2'))
  209. result = User.csv_import(
  210. string: csv_string,
  211. parse_params: {
  212. col_sep: ';',
  213. },
  214. try: false,
  215. )
  216. assert_equal(false, result[:try])
  217. assert_equal(1, result[:records].count)
  218. assert_equal('failed', result[:result])
  219. assert_nil(User.find_by(login: 'user-simple-readonly_id-import1'))
  220. # any single failure will cause the entire import to be aborted
  221. assert_nil(User.find_by(login: 'user-simple-readonly_id-import2'))
  222. end
  223. test 'simple import with roles' do
  224. UserInfo.current_user_id = 1
  225. admin = User.create_or_update(
  226. login: 'admin1@example.com',
  227. firstname: 'Admin',
  228. lastname: '1',
  229. email: 'admin1@example.com',
  230. password: 'agentpw',
  231. active: true,
  232. roles: Role.where(name: 'Admin'),
  233. )
  234. csv_string = "login;firstname;lastname;email;roles;\nuser-role-import1;firstname-role-import1;lastname-role-import1;user-role-import1@example.com;Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;user-role-import2@example.com;Agent\n;;;;Admin"
  235. result = User.csv_import(
  236. string: csv_string,
  237. parse_params: {
  238. col_sep: ';',
  239. },
  240. try: true,
  241. )
  242. assert_equal(true, result[:try])
  243. assert_equal(2, result[:records].count)
  244. assert_equal('success', result[:result])
  245. assert_nil(User.find_by(login: 'user-role-import1'))
  246. assert_nil(User.find_by(login: 'user-role-import2'))
  247. result = User.csv_import(
  248. string: csv_string,
  249. parse_params: {
  250. col_sep: ';',
  251. },
  252. try: false,
  253. )
  254. assert_equal(false, result[:try])
  255. assert_equal(2, result[:records].count)
  256. assert_equal('success', result[:result])
  257. user1 = User.find_by(login: 'user-role-import1')
  258. assert(user1)
  259. assert_equal(user1.login, 'user-role-import1')
  260. assert_equal(user1.firstname, 'firstname-role-import1')
  261. assert_equal(user1.lastname, 'lastname-role-import1')
  262. assert_equal(user1.email, 'user-role-import1@example.com')
  263. assert_equal(user1.roles.count, 1)
  264. user2 = User.find_by(login: 'user-role-import2')
  265. assert(user2)
  266. assert_equal(user2.login, 'user-role-import2')
  267. assert_equal(user2.firstname, 'firstname-role-import2')
  268. assert_equal(user2.lastname, 'lastname-role-import2')
  269. assert_equal(user2.email, 'user-role-import2@example.com')
  270. assert_equal(user2.roles.count, 2)
  271. user1.destroy!
  272. user2.destroy!
  273. admin.destroy!
  274. end
  275. test 'simple import + fixed params' do
  276. csv_string = "login;firstname;lastname;email\nuser-simple-import-fixed1;firstname-simple-import-fixed1;lastname-simple-import-fixed1;user-simple-import-fixed1@example.com\nuser-simple-import-fixed2;firstname-simple-import-fixed2;lastname-simple-import-fixed2;user-simple-import-fixed2@example.com\n"
  277. result = User.csv_import(
  278. string: csv_string,
  279. parse_params: {
  280. col_sep: ';',
  281. },
  282. fixed_params: {
  283. note: 'some note',
  284. },
  285. try: true,
  286. )
  287. assert_equal(true, result[:try])
  288. assert_equal(2, result[:records].count)
  289. assert_equal('success', result[:result])
  290. assert_nil(User.find_by(login: 'user-simple-import-fixed1'))
  291. assert_nil(User.find_by(login: 'user-simple-import-fixed2'))
  292. result = User.csv_import(
  293. string: csv_string,
  294. parse_params: {
  295. col_sep: ';',
  296. },
  297. fixed_params: {
  298. note: 'some note',
  299. },
  300. try: false,
  301. )
  302. assert_equal(false, result[:try])
  303. assert_equal(2, result[:records].count)
  304. assert_equal('success', result[:result])
  305. user1 = User.find_by(login: 'user-simple-import-fixed1')
  306. user2 = User.find_by(login: 'user-simple-import-fixed2')
  307. assert(user1)
  308. assert_equal('some note', user1.note)
  309. assert_equal('user-simple-import-fixed1', user1.login)
  310. assert_equal('firstname-simple-import-fixed1', user1.firstname)
  311. assert_equal('lastname-simple-import-fixed1', user1.lastname)
  312. assert_equal('user-simple-import-fixed1@example.com', user1.email)
  313. assert(user2)
  314. assert_equal('some note', user2.note)
  315. assert_equal('user-simple-import-fixed2', user2.login)
  316. assert_equal('firstname-simple-import-fixed2', user2.firstname)
  317. assert_equal('lastname-simple-import-fixed2', user2.lastname)
  318. assert_equal('user-simple-import-fixed2@example.com', user2.email)
  319. user1.destroy!
  320. user2.destroy!
  321. end
  322. test 'duplicate import' do
  323. csv_string = "login;firstname;lastname;email\nuser-duplicate-import1;firstname-duplicate-import1;firstname-duplicate-import1;user-duplicate-import1@example.com\nuser-duplicate-import2;firstname-duplicate-import2;firstname-duplicate-import2;user-duplicate-import2@example.com\nuser-duplicate-import2;firstname-duplicate-import3;firstname-duplicate-import3;user-duplicate-import3@example.com"
  324. result = User.csv_import(
  325. string: csv_string,
  326. parse_params: {
  327. col_sep: ';',
  328. },
  329. try: true,
  330. )
  331. assert_equal(true, result[:try])
  332. assert_equal(2, result[:records].count)
  333. assert_equal('failed', result[:result])
  334. assert_nil(User.find_by(login: 'user-duplicate-import1'))
  335. assert_nil(User.find_by(login: 'user-duplicate-import2'))
  336. assert_nil(User.find_by(login: 'user-duplicate-import3'))
  337. result = User.csv_import(
  338. string: csv_string,
  339. parse_params: {
  340. col_sep: ';',
  341. },
  342. try: false,
  343. )
  344. assert_equal(false, result[:try])
  345. assert_equal(2, result[:records].count)
  346. assert_equal('failed', result[:result])
  347. assert_nil(User.find_by(login: 'user-duplicate-import1'))
  348. assert_nil(User.find_by(login: 'user-duplicate-import2'))
  349. assert_nil(User.find_by(login: 'user-duplicate-import3'))
  350. end
  351. test 'invalid attributes' do
  352. csv_string = "login;firstname2;lastname;email\nuser-invalid-import1;firstname-invalid-import1;firstname-invalid-import1;user-invalid-import1@example.com\nuser-invalid-import2;firstname-invalid-import2;firstname-invalid-import2;user-invalid-import2@example.com\n"
  353. result = User.csv_import(
  354. string: csv_string,
  355. parse_params: {
  356. col_sep: ';',
  357. },
  358. try: true,
  359. )
  360. assert_equal(true, result[:try])
  361. assert_equal(2, result[:errors].count)
  362. assert_equal('failed', result[:result])
  363. assert_equal("Line 1: Unable to create record - unknown attribute 'firstname2' for User.", result[:errors][0])
  364. assert_equal("Line 2: Unable to create record - unknown attribute 'firstname2' for User.", result[:errors][1])
  365. assert_nil(User.find_by(login: 'user-invalid-import1'))
  366. assert_nil(User.find_by(login: 'user-invalid-import2'))
  367. result = User.csv_import(
  368. string: csv_string,
  369. parse_params: {
  370. col_sep: ';',
  371. },
  372. try: false,
  373. )
  374. assert_equal(false, result[:try])
  375. assert_equal(2, result[:errors].count)
  376. assert_equal('failed', result[:result])
  377. assert_equal("Line 1: Unable to create record - unknown attribute 'firstname2' for User.", result[:errors][0])
  378. assert_equal("Line 2: Unable to create record - unknown attribute 'firstname2' for User.", result[:errors][1])
  379. assert_nil(User.find_by(login: 'user-invalid-import1'))
  380. assert_nil(User.find_by(login: 'user-invalid-import2'))
  381. end
  382. test 'reference import' do
  383. csv_string = "login;firstname;lastname;email;organization\nuser-reference-import1;firstname-reference-import1;firstname-reference-import1;user-reference-import1@example.com;organization-reference-import1\nuser-reference-import2;firstname-reference-import2;firstname-reference-import2;user-reference-import2@example.com;organization-reference-import2\nuser-reference-import3;firstname-reference-import3;firstname-reference-import3;user-reference-import3@example.com;Zammad Foundation\n"
  384. result = User.csv_import(
  385. string: csv_string,
  386. parse_params: {
  387. col_sep: ';',
  388. },
  389. try: true,
  390. )
  391. assert_equal(true, result[:try])
  392. assert_equal(2, result[:errors].count)
  393. assert_equal('failed', result[:result])
  394. assert_nil(User.find_by(login: 'user-reference-import1'))
  395. assert_nil(User.find_by(login: 'user-reference-import2'))
  396. assert_nil(User.find_by(login: 'user-reference-import3'))
  397. assert_equal("Line 1: No lookup value found for 'organization': \"organization-reference-import1\"", result[:errors][0])
  398. assert_equal("Line 2: No lookup value found for 'organization': \"organization-reference-import2\"", result[:errors][1])
  399. result = User.csv_import(
  400. string: csv_string,
  401. parse_params: {
  402. col_sep: ';',
  403. },
  404. try: false,
  405. )
  406. assert_equal(false, result[:try])
  407. assert_equal(2, result[:errors].count)
  408. assert_equal('failed', result[:result])
  409. assert_nil(User.find_by(login: 'user-reference-import1'))
  410. assert_nil(User.find_by(login: 'user-reference-import2'))
  411. assert_nil(User.find_by(login: 'user-reference-import3'))
  412. assert_equal("Line 1: No lookup value found for 'organization': \"organization-reference-import1\"", result[:errors][0])
  413. assert_equal("Line 2: No lookup value found for 'organization': \"organization-reference-import2\"", result[:errors][1])
  414. UserInfo.current_user_id = 1
  415. orgaization1 = Organization.create_if_not_exists(name: 'organization-reference-import1')
  416. orgaization2 = Organization.create_if_not_exists(name: 'organization-reference-import2')
  417. result = User.csv_import(
  418. string: csv_string,
  419. parse_params: {
  420. col_sep: ';',
  421. },
  422. try: true,
  423. )
  424. assert_equal(true, result[:try])
  425. assert_equal(0, result[:errors].count)
  426. assert_equal('success', result[:result])
  427. assert_nil(User.find_by(login: 'user-reference-import1'))
  428. assert_nil(User.find_by(login: 'user-reference-import2'))
  429. # any single failure will cause the entire import to be aborted
  430. assert_nil(User.find_by(login: 'user-reference-import3'))
  431. result = User.csv_import(
  432. string: csv_string,
  433. parse_params: {
  434. col_sep: ';',
  435. },
  436. try: false,
  437. )
  438. assert_equal(false, result[:try])
  439. assert_equal(0, result[:errors].count)
  440. assert_equal('success', result[:result])
  441. assert(User.find_by(login: 'user-reference-import1'))
  442. assert(User.find_by(login: 'user-reference-import2'))
  443. assert(User.find_by(login: 'user-reference-import3'))
  444. User.find_by(login: 'user-reference-import1').destroy!
  445. User.find_by(login: 'user-reference-import2').destroy!
  446. User.find_by(login: 'user-reference-import3').destroy!
  447. orgaization1.destroy!
  448. orgaization2.destroy!
  449. end
  450. test 'simple import with delete' do
  451. csv_string = "login;firstname;lastname;email\nuser-simple-import-fixed1;firstname-simple-import-fixed1;lastname-simple-import-fixed1;user-simple-import-fixed1@example.com\nuser-simple-import-fixed2;firstname-simple-import-fixed2;lastname-simple-import-fixed2;user-simple-import-fixed2@example.com\n"
  452. result = User.csv_import(
  453. string: csv_string,
  454. parse_params: {
  455. col_sep: ';',
  456. },
  457. try: true,
  458. delete: true,
  459. )
  460. assert_equal(true, result[:try])
  461. assert_equal('failed', result[:result])
  462. assert_equal('Delete is not possible for User.', result[:errors][0])
  463. end
  464. end