elasticsearch_test.rb 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. require 'test_helper'
  2. class ElasticsearchTest < ActiveSupport::TestCase
  3. include SearchindexHelper
  4. setup do
  5. configure_elasticsearch(required: true)
  6. rebuild_searchindex
  7. groups = Group.where(name: 'Users')
  8. roles = Role.where(name: 'Agent')
  9. @agent = User.create!(
  10. login: 'es-agent@example.com',
  11. firstname: 'E',
  12. lastname: 'S',
  13. email: 'es-agent@example.com',
  14. password: 'agentpw',
  15. active: true,
  16. roles: roles,
  17. groups: groups,
  18. updated_by_id: 1,
  19. created_by_id: 1,
  20. )
  21. group_without_access = Group.create_if_not_exists(
  22. name: 'WithoutAccess',
  23. note: 'Test for not access check.',
  24. updated_by_id: 1,
  25. created_by_id: 1
  26. )
  27. roles = Role.where(name: 'Customer')
  28. @organization1 = Organization.create_if_not_exists(
  29. name: 'Customer Organization Update',
  30. note: 'some note',
  31. updated_by_id: 1,
  32. created_by_id: 1,
  33. )
  34. @customer1 = User.create!(
  35. login: 'es-customer1@example.com',
  36. firstname: 'ES',
  37. lastname: 'Customer1',
  38. email: 'es-customer1@example.com',
  39. password: 'customerpw',
  40. active: true,
  41. organization_id: @organization1.id,
  42. roles: roles,
  43. updated_by_id: 1,
  44. created_by_id: 1,
  45. )
  46. @customer2 = User.create!(
  47. login: 'es-customer2@example.com',
  48. firstname: 'ES',
  49. lastname: 'Customer2',
  50. email: 'es-customer2@example.com',
  51. password: 'customerpw',
  52. active: true,
  53. organization_id: @organization1.id,
  54. roles: roles,
  55. updated_by_id: 1,
  56. created_by_id: 1,
  57. )
  58. @customer3 = User.create!(
  59. login: 'es-customer3@example.com',
  60. firstname: 'ES',
  61. lastname: 'Customer3',
  62. email: 'es-customer3@example.com',
  63. password: 'customerpw',
  64. active: true,
  65. roles: roles,
  66. updated_by_id: 1,
  67. created_by_id: 1,
  68. )
  69. # execute background jobs to index created/changed objects
  70. Scheduler.worker(true)
  71. end
  72. # check search attributes
  73. test 'a - objects' do
  74. # user
  75. attributes = @agent.search_index_data
  76. assert_equal('E', attributes['firstname'])
  77. assert_equal('S', attributes['lastname'])
  78. assert_equal('es-agent@example.com', attributes['email'])
  79. assert(attributes['preferences'])
  80. assert_not(attributes['password'])
  81. assert_not(attributes['organization'])
  82. attributes = @agent.search_index_attribute_lookup
  83. assert_equal('E', attributes['firstname'])
  84. assert_equal('S', attributes['lastname'])
  85. assert_equal('es-agent@example.com', attributes['email'])
  86. assert(attributes['preferences'])
  87. assert_not(attributes['password'])
  88. assert_not(attributes['organization'])
  89. attributes = @customer1.search_index_attribute_lookup
  90. assert_equal('ES', attributes['firstname'])
  91. assert_equal('Customer1', attributes['lastname'])
  92. assert_equal('es-customer1@example.com', attributes['email'])
  93. assert(attributes['preferences'])
  94. assert_not(attributes['password'])
  95. assert_equal('Customer Organization Update', attributes['organization'])
  96. # organization
  97. attributes = @organization1.search_index_data
  98. assert_equal('Customer Organization Update', attributes['name'])
  99. assert_equal('some note', attributes['note'])
  100. assert_not(attributes['members'])
  101. attributes = @organization1.search_index_attribute_lookup
  102. assert_equal('Customer Organization Update', attributes['name'])
  103. assert_equal('some note', attributes['note'])
  104. assert(attributes['members'])
  105. # ticket/article
  106. ticket1 = Ticket.create!(
  107. title: 'some title äöüß',
  108. group: Group.lookup(name: 'Users'),
  109. customer_id: @customer1.id,
  110. state: Ticket::State.lookup(name: 'new'),
  111. priority: Ticket::Priority.lookup(name: '2 normal'),
  112. updated_by_id: 1,
  113. created_by_id: 1,
  114. )
  115. article1 = Ticket::Article.create!(
  116. ticket_id: ticket1.id,
  117. from: 'some_sender@example.com',
  118. to: 'some_recipient@example.com',
  119. subject: 'some subject',
  120. message_id: 'some@id',
  121. body: 'some message',
  122. internal: false,
  123. sender: Ticket::Article::Sender.where(name: 'Customer').first,
  124. type: Ticket::Article::Type.where(name: 'email').first,
  125. updated_by_id: 1,
  126. created_by_id: 1,
  127. )
  128. Store.add(
  129. object: 'Ticket::Article',
  130. o_id: article1.id,
  131. data: File.binread(Rails.root.join('test', 'data', 'elasticsearch', 'es-normal.txt')),
  132. filename: 'es-normal.txt',
  133. preferences: {},
  134. created_by_id: 1,
  135. )
  136. attributes = ticket1.search_index_attribute_lookup
  137. assert_equal('Users', attributes['group'])
  138. assert_equal('new', attributes['state'])
  139. assert_equal('2 normal', attributes['priority'])
  140. assert_equal('ES', attributes['customer']['firstname'])
  141. assert_equal('Customer1', attributes['customer']['lastname'])
  142. assert_equal('es-customer1@example.com', attributes['customer']['email'])
  143. assert_not(attributes['customer']['password'])
  144. assert_equal('Customer Organization Update', attributes['customer']['organization'])
  145. assert_equal('-', attributes['owner']['login'])
  146. assert_equal('-', attributes['owner']['firstname'])
  147. assert_not(attributes['owner']['password'])
  148. assert_not(attributes['owner']['organization'])
  149. assert(attributes['article'][0]['attachment'])
  150. assert(attributes['article'][0]['attachment'][0])
  151. assert_not(attributes['article'][0]['attachment'][1])
  152. assert_equal('es-normal.txt', attributes['article'][0]['attachment'][0]['_name'])
  153. assert_equal('c29tZSBub3JtYWwgdGV4dDY2Cg==', attributes['article'][0]['attachment'][0]['_content'])
  154. ticket1.destroy!
  155. # execute background jobs
  156. Scheduler.worker(true)
  157. ticket1 = Ticket.create!(
  158. title: "some title\n äöüß",
  159. group: Group.lookup(name: 'Users'),
  160. customer_id: @customer1.id,
  161. state: Ticket::State.lookup(name: 'new'),
  162. priority: Ticket::Priority.lookup(name: '2 normal'),
  163. updated_by_id: 1,
  164. created_by_id: 1,
  165. )
  166. article1 = Ticket::Article.create!(
  167. ticket_id: ticket1.id,
  168. from: 'some_sender@example.com',
  169. to: 'some_recipient@example.com',
  170. subject: 'some subject',
  171. message_id: 'some@id',
  172. body: 'some message',
  173. internal: false,
  174. sender: Ticket::Article::Sender.where(name: 'Customer').first,
  175. type: Ticket::Article::Type.where(name: 'email').first,
  176. updated_by_id: 1,
  177. created_by_id: 1,
  178. )
  179. # add attachments which should get index / .txt
  180. # "some normal text66"
  181. Store.add(
  182. object: 'Ticket::Article',
  183. o_id: article1.id,
  184. data: File.binread(Rails.root.join('test', 'data', 'elasticsearch', 'es-normal.txt')),
  185. filename: 'es-normal.txt',
  186. preferences: {},
  187. created_by_id: 1,
  188. )
  189. # add attachments which should get index / .pdf
  190. # "Zammad Test77"
  191. Store.add(
  192. object: 'Ticket::Article',
  193. o_id: article1.id,
  194. data: File.binread(Rails.root.join('test', 'data', 'elasticsearch', 'es-pdf1.pdf')),
  195. filename: 'es-pdf1.pdf',
  196. preferences: {},
  197. created_by_id: 1,
  198. )
  199. # add attachments which should get index / .box
  200. # "Old programmers never die test99"
  201. Store.add(
  202. object: 'Ticket::Article',
  203. o_id: article1.id,
  204. data: File.binread(Rails.root.join('test', 'data', 'elasticsearch', 'es-box1.box')),
  205. filename: 'mail1.box',
  206. preferences: {},
  207. created_by_id: 1,
  208. )
  209. # add to big attachment which should not get index
  210. # "some too big text88"
  211. Store.add(
  212. object: 'Ticket::Article',
  213. o_id: article1.id,
  214. data: File.binread(Rails.root.join('test', 'data', 'elasticsearch', 'es-too-big.txt')),
  215. filename: 'es-too-big.txt',
  216. preferences: {},
  217. created_by_id: 1,
  218. )
  219. ticket1.tag_add('someTagA', 1)
  220. travel 1.minute
  221. ticket2 = Ticket.create!(
  222. title: 'something else',
  223. group: Group.lookup(name: 'Users'),
  224. customer_id: @customer2.id,
  225. state: Ticket::State.lookup(name: 'open'),
  226. priority: Ticket::Priority.lookup(name: '2 normal'),
  227. updated_by_id: 1,
  228. created_by_id: 1,
  229. )
  230. article2 = Ticket::Article.create!(
  231. ticket_id: ticket2.id,
  232. from: 'some_sender@example.org',
  233. to: 'some_recipient@example.org',
  234. subject: 'some subject2 / autobahn what else?',
  235. message_id: 'some@id',
  236. body: 'some other message <b>with s<u>t</u>rong text<b>',
  237. content_type: 'text/html',
  238. internal: false,
  239. sender: Ticket::Article::Sender.where(name: 'Customer').first,
  240. type: Ticket::Article::Type.where(name: 'email').first,
  241. updated_by_id: 1,
  242. created_by_id: 1,
  243. )
  244. ticket2.tag_add('someTagB', 1)
  245. travel 1.minute
  246. ticket3 = Ticket.create!(
  247. title: 'something else',
  248. group: Group.lookup(name: 'WithoutAccess'),
  249. customer_id: @customer3.id,
  250. state: Ticket::State.lookup(name: 'open'),
  251. priority: Ticket::Priority.lookup(name: '2 normal'),
  252. updated_by_id: 1,
  253. created_by_id: 1,
  254. )
  255. article3 = Ticket::Article.create!(
  256. ticket_id: ticket3.id,
  257. from: 'some_sender@example.org',
  258. to: 'some_recipient@example.org',
  259. subject: 'some subject3',
  260. message_id: 'some@id',
  261. body: 'some other message 3 / kindergarden what else?',
  262. internal: false,
  263. sender: Ticket::Article::Sender.where(name: 'Customer').first,
  264. type: Ticket::Article::Type.where(name: 'email').first,
  265. updated_by_id: 1,
  266. created_by_id: 1,
  267. )
  268. # execute background jobs
  269. Scheduler.worker(true)
  270. sleep 2 # for ES to come ready/indexed
  271. # search as @agent
  272. # search for article data
  273. result = Ticket.search(
  274. current_user: @agent,
  275. query: 'autobahn',
  276. limit: 15,
  277. )
  278. assert(result.present?, 'result exists not')
  279. assert(result[0], 'record 1')
  280. assert_not(result[1], 'record 2')
  281. assert_equal(result[0].id, ticket2.id)
  282. # search for html content
  283. result = Ticket.search(
  284. current_user: @agent,
  285. query: 'strong',
  286. limit: 15,
  287. )
  288. assert(result.present?, 'result exists not')
  289. assert(result[0], 'record 1')
  290. assert_not(result[1], 'record 2')
  291. assert_equal(result[0].id, ticket2.id)
  292. # search for indexed attachment
  293. result = Ticket.search(
  294. current_user: @agent,
  295. query: '"some normal text66"',
  296. limit: 15,
  297. )
  298. assert(result[0], 'record 1')
  299. assert_equal(result[0].id, ticket1.id)
  300. result = Ticket.search(
  301. current_user: @agent,
  302. query: 'test77',
  303. limit: 15,
  304. )
  305. assert(result[0], 'record 1')
  306. assert_equal(result[0].id, ticket1.id)
  307. # search for not indexed attachment
  308. result = Ticket.search(
  309. current_user: @agent,
  310. query: 'test88',
  311. limit: 15,
  312. )
  313. assert_not(result[0], 'record 1')
  314. result = Ticket.search(
  315. current_user: @agent,
  316. query: 'test99',
  317. limit: 15,
  318. )
  319. assert_not(result[0], 'record 1')
  320. # search for ticket with no permissions
  321. result = Ticket.search(
  322. current_user: @agent,
  323. query: 'kindergarden',
  324. limit: 15,
  325. )
  326. assert(result.blank?, 'result should be empty')
  327. assert_not(result[0], 'record 1')
  328. # search as @customer1
  329. result = Ticket.search(
  330. current_user: @customer1,
  331. query: 'title OR else',
  332. limit: 15,
  333. )
  334. assert(result.present?, 'result exists not')
  335. assert(result[0], 'record 1')
  336. assert(result[1], 'record 2')
  337. assert_not(result[2], 'record 3')
  338. assert_equal(result[0].id, ticket2.id)
  339. assert_equal(result[1].id, ticket1.id)
  340. # search as @customer2
  341. result = Ticket.search(
  342. current_user: @customer2,
  343. query: 'title OR else',
  344. limit: 15,
  345. )
  346. assert(result.present?, 'result exists not')
  347. assert(result[0], 'record 1')
  348. assert(result[1], 'record 2')
  349. assert_not(result[2], 'record 3')
  350. assert_equal(result[0].id, ticket2.id)
  351. assert_equal(result[1].id, ticket1.id)
  352. # search as @customer3
  353. result = Ticket.search(
  354. current_user: @customer3,
  355. query: 'title OR else',
  356. limit: 15,
  357. )
  358. assert(result.present?, 'result exists not')
  359. assert(result[0], 'record 1')
  360. assert_not(result[1], 'record 2')
  361. assert_equal(result[0].id, ticket3.id)
  362. # search for tags
  363. result = Ticket.search(
  364. current_user: @agent,
  365. query: 'tags:someTagA',
  366. limit: 15,
  367. )
  368. assert(result[0], 'record 1')
  369. assert_not(result[1], 'record 1')
  370. assert_equal(result[0].id, ticket1.id)
  371. result = Ticket.search(
  372. current_user: @agent,
  373. query: 'tags:someTagB',
  374. limit: 15,
  375. )
  376. assert(result[0], 'record 2')
  377. assert_not(result[1], 'record 2')
  378. assert_equal(result[0].id, ticket2.id)
  379. # rename tag (e. g. via admin interface)
  380. tag_item = Tag::Item.lookup(name: 'someTagA')
  381. Tag::Item.rename(
  382. id: tag_item.id,
  383. name: 'someTagC',
  384. updated_by_id: 1,
  385. )
  386. # execute background jobs
  387. Scheduler.worker(true)
  388. sleep 2 # for ES to come ready/indexed
  389. # search for tags
  390. result = Ticket.search(
  391. current_user: @agent,
  392. query: 'tags:someTagA',
  393. limit: 15,
  394. )
  395. assert_not(result[0], 'record 1')
  396. assert_not(result[1], 'record 1')
  397. result = Ticket.search(
  398. current_user: @agent,
  399. query: 'tags:someTagB',
  400. limit: 15,
  401. )
  402. assert(result[0], 'record 2')
  403. assert_not(result[1], 'record 2')
  404. assert_equal(result[0].id, ticket2.id)
  405. result = Ticket.search(
  406. current_user: @agent,
  407. query: 'tags:someTagC',
  408. limit: 15,
  409. )
  410. assert(result[0], 'record 1')
  411. assert_not(result[1], 'record 2')
  412. assert_equal(result[0].id, ticket1.id)
  413. result = Ticket.search(
  414. current_user: @agent,
  415. query: 'state:open',
  416. limit: 15,
  417. )
  418. assert(result[0], 'record 1')
  419. assert_not(result[1], 'record 2')
  420. assert_equal(result[0].id, ticket2.id)
  421. result = Ticket.search(
  422. current_user: @agent,
  423. query: '"some_sender@example.com"',
  424. limit: 15,
  425. )
  426. assert(result[0], 'record 1')
  427. assert_not(result[1], 'record 2')
  428. assert_equal(result[0].id, ticket1.id)
  429. result = Ticket.search(
  430. current_user: @agent,
  431. query: 'article.from:"some_sender@example.com"',
  432. limit: 15,
  433. )
  434. assert(result[0], 'record 1')
  435. assert_not(result[1], 'record 2')
  436. assert_equal(result[0].id, ticket1.id)
  437. # check users and search it
  438. # search as @agent
  439. result = User.search(
  440. current_user: @agent,
  441. query: 'customer1',
  442. limit: 15,
  443. )
  444. assert(result.present?, 'result should not be empty')
  445. assert(result[0], 'record 1')
  446. assert_not(result[1], 'record 2')
  447. assert_equal(result[0].id, @customer1.id)
  448. # search as @customer1
  449. result = User.search(
  450. current_user: @customer1,
  451. query: 'customer1',
  452. limit: 15,
  453. )
  454. assert(result.blank?, 'result should be empty')
  455. assert_not(result[0], 'record 1')
  456. # cleanup
  457. Rake::Task['searchindex:drop'].execute
  458. end
  459. end