elasticsearch_test.rb 15 KB

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