elasticsearch_test.rb 15 KB

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