elasticsearch_test.rb 15 KB

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