search_spec.rb 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. require 'rails_helper'
  2. RSpec.describe 'Search', type: :request, searchindex: true do
  3. let(:group) { create(:group) }
  4. let!(:admin) do
  5. create(:admin, groups: [Group.lookup(name: 'Users'), group])
  6. end
  7. let!(:agent) do
  8. create(:agent, firstname: 'Search 1234', groups: [Group.lookup(name: 'Users'), group])
  9. end
  10. let!(:customer) do
  11. create(:customer)
  12. end
  13. let!(:organization1) do
  14. create(:organization, name: 'Rest Org')
  15. end
  16. let!(:organization2) do
  17. create(:organization, name: 'Rest Org #2')
  18. end
  19. let!(:organization3) do
  20. create(:organization, name: 'Rest Org #3')
  21. end
  22. let!(:organization4) do
  23. create(:organization, name: 'Tes.t. Org')
  24. end
  25. let!(:organization5) do
  26. create(:organization, name: 'ABC_D Org')
  27. end
  28. let!(:organization_nested) do
  29. create(:organization, name: 'Tomato42 Ltd.', note: 'Tomato42 Ltd.')
  30. end
  31. let!(:customer_nested) do
  32. create(:customer, organization: organization_nested)
  33. end
  34. let!(:customer2) do
  35. create(:customer, organization: organization1)
  36. end
  37. let!(:customer3) do
  38. create(:customer, organization: organization1)
  39. end
  40. let!(:ticket1) do
  41. create(:ticket, title: 'test 1234-1', customer: customer, group: group)
  42. end
  43. let!(:ticket2) do
  44. create(:ticket, title: 'test 1234-2', customer: customer2, group: group)
  45. end
  46. let!(:ticket3) do
  47. create(:ticket, title: 'test 1234-2', customer: customer3, group: group)
  48. end
  49. let!(:ticket_nested) do
  50. create(:ticket, title: 'vegetable request', customer: customer_nested, group: group)
  51. end
  52. let!(:article1) do
  53. create(:ticket_article, ticket_id: ticket1.id)
  54. end
  55. let!(:article2) do
  56. create(:ticket_article, ticket_id: ticket2.id)
  57. end
  58. let!(:article3) do
  59. create(:ticket_article, ticket_id: ticket3.id)
  60. end
  61. let!(:article_nested) do
  62. article = create(:ticket_article, ticket_id: ticket_nested.id)
  63. Store.add(
  64. object: 'Ticket::Article',
  65. o_id: article.id,
  66. data: File.binread(Rails.root.join('test/data/elasticsearch/es-normal.txt')),
  67. filename: 'es-normal.txt',
  68. preferences: {},
  69. created_by_id: 1,
  70. )
  71. article
  72. end
  73. before do
  74. configure_elasticsearch do
  75. travel 1.minute
  76. rebuild_searchindex
  77. # execute background jobs
  78. Scheduler.worker(true)
  79. sleep 6
  80. end
  81. end
  82. describe 'request handling' do
  83. it 'does settings index with nobody' do
  84. params = {
  85. query: 'test 1234',
  86. limit: 2,
  87. }
  88. post '/api/v1/search/ticket', params: params, as: :json
  89. expect(response).to have_http_status(:forbidden)
  90. expect(json_response).to be_a_kind_of(Hash)
  91. expect(json_response).not_to be_blank
  92. expect(json_response['error']).to eq('Authentication required')
  93. post '/api/v1/search/user', params: params, as: :json
  94. expect(response).to have_http_status(:forbidden)
  95. expect(json_response).to be_a_kind_of(Hash)
  96. expect(json_response).not_to be_blank
  97. expect(json_response['error']).to eq('Authentication required')
  98. post '/api/v1/search', params: params, as: :json
  99. expect(response).to have_http_status(:forbidden)
  100. expect(json_response).to be_a_kind_of(Hash)
  101. expect(json_response).not_to be_blank
  102. expect(json_response['error']).to eq('Authentication required')
  103. end
  104. it 'does settings index with admin' do
  105. params = {
  106. query: '1234*',
  107. limit: 1,
  108. }
  109. authenticated_as(admin)
  110. post '/api/v1/search', params: params, as: :json
  111. expect(response).to have_http_status(:ok)
  112. expect(json_response).to be_a_kind_of(Hash)
  113. expect(json_response).to be_truthy
  114. expect(json_response['result'][0]['type']).to eq('Ticket')
  115. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  116. expect(json_response['result'][1]['type']).to eq('User')
  117. expect(json_response['result'][1]['id']).to eq(agent.id)
  118. expect(json_response['result'][2]).to be_falsey
  119. params = {
  120. query: '1234*',
  121. limit: 10,
  122. }
  123. post '/api/v1/search', params: params, as: :json
  124. expect(response).to have_http_status(:ok)
  125. expect(json_response).to be_a_kind_of(Hash)
  126. expect(json_response).to be_truthy
  127. expect(json_response['result'][0]['type']).to eq('Ticket')
  128. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  129. expect(json_response['result'][1]['type']).to eq('Ticket')
  130. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  131. expect(json_response['result'][2]['type']).to eq('Ticket')
  132. expect(json_response['result'][2]['id']).to eq(ticket1.id)
  133. expect(json_response['result'][3]['type']).to eq('User')
  134. expect(json_response['result'][3]['id']).to eq(agent.id)
  135. expect(json_response['result'][4]).to be_falsey
  136. params = {
  137. query: '1234*',
  138. limit: 10,
  139. }
  140. post '/api/v1/search/ticket', params: params, as: :json
  141. expect(response).to have_http_status(:ok)
  142. expect(json_response).to be_a_kind_of(Hash)
  143. expect(json_response).to be_truthy
  144. expect(json_response['result'][0]['type']).to eq('Ticket')
  145. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  146. expect(json_response['result'][1]['type']).to eq('Ticket')
  147. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  148. expect(json_response['result'][2]['type']).to eq('Ticket')
  149. expect(json_response['result'][2]['id']).to eq(ticket1.id)
  150. expect(json_response['result'][3]).to be_falsey
  151. params = {
  152. query: '1234*',
  153. limit: 10,
  154. }
  155. post '/api/v1/search/user', params: params, as: :json
  156. expect(response).to have_http_status(:ok)
  157. expect(json_response).to be_a_kind_of(Hash)
  158. expect(json_response['result'][0]['type']).to eq('User')
  159. expect(json_response['result'][0]['id']).to eq(agent.id)
  160. expect(json_response['result'][1]).to be_falsey
  161. end
  162. it 'does settings index with agent' do
  163. params = {
  164. query: '1234*',
  165. limit: 1,
  166. }
  167. authenticated_as(agent)
  168. post '/api/v1/search', params: params, as: :json
  169. expect(response).to have_http_status(:ok)
  170. expect(json_response).to be_a_kind_of(Hash)
  171. expect(json_response).to be_truthy
  172. expect(json_response['result'][0]['type']).to eq('Ticket')
  173. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  174. expect(json_response['result'][1]['type']).to eq('User')
  175. expect(json_response['result'][1]['id']).to eq(agent.id)
  176. expect(json_response['result'][2]).to be_falsey
  177. params = {
  178. query: '1234*',
  179. limit: 10,
  180. }
  181. post '/api/v1/search', params: params, as: :json
  182. expect(response).to have_http_status(:ok)
  183. expect(json_response).to be_a_kind_of(Hash)
  184. expect(json_response).to be_truthy
  185. expect(json_response['result'][0]['type']).to eq('Ticket')
  186. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  187. expect(json_response['result'][1]['type']).to eq('Ticket')
  188. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  189. expect(json_response['result'][2]['type']).to eq('Ticket')
  190. expect(json_response['result'][2]['id']).to eq(ticket1.id)
  191. expect(json_response['result'][3]['type']).to eq('User')
  192. expect(json_response['result'][3]['id']).to eq(agent.id)
  193. expect(json_response['result'][4]).to be_falsey
  194. params = {
  195. query: '1234*',
  196. limit: 10,
  197. }
  198. post '/api/v1/search/ticket', params: params, as: :json
  199. expect(response).to have_http_status(:ok)
  200. expect(json_response).to be_a_kind_of(Hash)
  201. expect(json_response).to be_truthy
  202. expect(json_response['result'][0]['type']).to eq('Ticket')
  203. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  204. expect(json_response['result'][1]['type']).to eq('Ticket')
  205. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  206. expect(json_response['result'][2]['type']).to eq('Ticket')
  207. expect(json_response['result'][2]['id']).to eq(ticket1.id)
  208. expect(json_response['result'][3]).to be_falsey
  209. params = {
  210. query: '1234*',
  211. limit: 10,
  212. }
  213. post '/api/v1/search/user', params: params, as: :json
  214. expect(response).to have_http_status(:ok)
  215. expect(json_response).to be_a_kind_of(Hash)
  216. expect(json_response['result'][0]['type']).to eq('User')
  217. expect(json_response['result'][0]['id']).to eq(agent.id)
  218. expect(json_response['result'][1]).to be_falsey
  219. end
  220. it 'does settings index with customer 1' do
  221. params = {
  222. query: '1234*',
  223. limit: 10,
  224. }
  225. authenticated_as(customer)
  226. post '/api/v1/search', params: params, as: :json
  227. expect(response).to have_http_status(:ok)
  228. expect(json_response).to be_a_kind_of(Hash)
  229. expect(json_response).to be_truthy
  230. expect(json_response['result'][0]['type']).to eq('Ticket')
  231. expect(json_response['result'][0]['id']).to eq(ticket1.id)
  232. expect(json_response['result'][1]).to be_falsey
  233. params = {
  234. query: '1234*',
  235. limit: 10,
  236. }
  237. post '/api/v1/search/ticket', params: params, as: :json
  238. expect(response).to have_http_status(:ok)
  239. expect(json_response).to be_a_kind_of(Hash)
  240. expect(json_response).to be_truthy
  241. expect(json_response['result'][0]['type']).to eq('Ticket')
  242. expect(json_response['result'][0]['id']).to eq(ticket1.id)
  243. expect(json_response['result'][1]).to be_falsey
  244. params = {
  245. query: '1234*',
  246. limit: 10,
  247. }
  248. post '/api/v1/search/user', params: params, as: :json
  249. expect(response).to have_http_status(:ok)
  250. expect(json_response).to be_a_kind_of(Hash)
  251. expect(json_response['result'][0]).to be_falsey
  252. end
  253. it 'does settings index with customer 2' do
  254. params = {
  255. query: '1234*',
  256. limit: 10,
  257. }
  258. authenticated_as(customer2)
  259. post '/api/v1/search', params: params, as: :json
  260. expect(response).to have_http_status(:ok)
  261. expect(json_response).to be_a_kind_of(Hash)
  262. expect(json_response).to be_truthy
  263. expect(json_response['result'][0]['type']).to eq('Ticket')
  264. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  265. expect(json_response['result'][1]['type']).to eq('Ticket')
  266. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  267. expect(json_response['result'][2]).to be_falsey
  268. params = {
  269. query: '1234*',
  270. limit: 10,
  271. }
  272. post '/api/v1/search/ticket', params: params, as: :json
  273. expect(response).to have_http_status(:ok)
  274. expect(json_response).to be_a_kind_of(Hash)
  275. expect(json_response).to be_truthy
  276. expect(json_response['result'][0]['type']).to eq('Ticket')
  277. expect(json_response['result'][0]['id']).to eq(ticket3.id)
  278. expect(json_response['result'][1]['type']).to eq('Ticket')
  279. expect(json_response['result'][1]['id']).to eq(ticket2.id)
  280. expect(json_response['result'][2]).to be_falsey
  281. params = {
  282. query: '1234*',
  283. limit: 10,
  284. }
  285. post '/api/v1/search/user', params: params, as: :json
  286. expect(response).to have_http_status(:ok)
  287. expect(json_response).to be_a_kind_of(Hash)
  288. expect(json_response['result'][0]).to be_falsey
  289. end
  290. # Verify fix for Github issue #2058 - Autocomplete hangs on dot in the new user form
  291. it 'does searching for organization with a dot in its name' do
  292. authenticated_as(agent)
  293. get '/api/v1/search/organization?query=tes.', as: :json
  294. expect(response).to have_http_status(:ok)
  295. expect(json_response['result'].size).to eq(1)
  296. expect(json_response['result'][0]['type']).to eq('Organization')
  297. target_id = json_response['result'][0]['id']
  298. expect(json_response['assets']['Organization'][target_id.to_s]['name']).to eq('Tes.t. Org')
  299. end
  300. # Search query H& should correctly match H&M
  301. it 'does searching for organization with _ in its name' do
  302. authenticated_as(agent)
  303. get '/api/v1/search/organization?query=abc_', as: :json
  304. expect(response).to have_http_status(:ok)
  305. expect(json_response['result'].size).to eq(1)
  306. expect(json_response['result'][0]['type']).to eq('Organization')
  307. target_id = json_response['result'][0]['id']
  308. expect(json_response['assets']['Organization'][target_id.to_s]['name']).to eq('ABC_D Org')
  309. end
  310. it 'does find the user of the nested organization and also even if the organization name changes' do
  311. # because of the initial relation between user and organization
  312. # both user and organization will be found as result
  313. authenticated_as(agent)
  314. post '/api/v1/search/User', params: { query: 'Tomato42' }, as: :json
  315. expect(response).to have_http_status(:ok)
  316. expect(json_response).to be_a_kind_of(Hash)
  317. expect(json_response).to be_truthy
  318. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  319. expect(json_response['assets']['User'][customer_nested.id.to_s]).to be_truthy
  320. post '/api/v1/search/User', params: { query: 'organization.name:Tomato42' }, as: :json
  321. expect(response).to have_http_status(:ok)
  322. expect(json_response).to be_a_kind_of(Hash)
  323. expect(json_response).to be_truthy
  324. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  325. expect(json_response['assets']['User'][customer_nested.id.to_s]).to be_truthy
  326. organization_nested.update(name: 'Cucumber43 Ltd.')
  327. Scheduler.worker(true)
  328. SearchIndexBackend.refresh
  329. # even after a change of the organization name we should find
  330. # the customer user because of the nested organization data
  331. post '/api/v1/search/User', params: { query: 'Cucumber43' }, as: :json
  332. expect(response).to have_http_status(:ok)
  333. expect(json_response).to be_a_kind_of(Hash)
  334. expect(json_response).to be_truthy
  335. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  336. expect(json_response['assets']['User'][customer_nested.id.to_s]).to be_truthy
  337. post '/api/v1/search/User', params: { query: 'organization.name:Cucumber43' }, as: :json
  338. expect(response).to have_http_status(:ok)
  339. expect(json_response).to be_a_kind_of(Hash)
  340. expect(json_response).to be_truthy
  341. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  342. expect(json_response['assets']['User'][customer_nested.id.to_s]).to be_truthy
  343. end
  344. it 'does find the ticket by organization name even if the organization name changes' do
  345. authenticated_as(agent)
  346. post '/api/v1/search/Ticket', params: { query: 'Tomato42' }, as: :json
  347. expect(response).to have_http_status(:ok)
  348. expect(json_response).to be_a_kind_of(Hash)
  349. expect(json_response).to be_truthy
  350. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  351. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  352. post '/api/v1/search/Ticket', params: { query: 'organization.name:Tomato42' }, as: :json
  353. expect(response).to have_http_status(:ok)
  354. expect(json_response).to be_a_kind_of(Hash)
  355. expect(json_response).to be_truthy
  356. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  357. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  358. organization_nested.update(name: 'Cucumber43 Ltd.')
  359. Scheduler.worker(true)
  360. SearchIndexBackend.refresh
  361. post '/api/v1/search/Ticket', params: { query: 'Cucumber43' }, as: :json
  362. expect(response).to have_http_status(:ok)
  363. expect(json_response).to be_a_kind_of(Hash)
  364. expect(json_response).to be_truthy
  365. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  366. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  367. post '/api/v1/search/Ticket', params: { query: 'organization.name:Cucumber43' }, as: :json
  368. expect(response).to have_http_status(:ok)
  369. expect(json_response).to be_a_kind_of(Hash)
  370. expect(json_response).to be_truthy
  371. expect(json_response['assets']['Organization'][organization_nested.id.to_s]).to be_truthy
  372. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  373. end
  374. it 'does find the ticket by group name even if the group name changes' do
  375. authenticated_as(agent)
  376. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && group.name:ultrasupport" }, as: :json
  377. expect(response).to have_http_status(:ok)
  378. expect(json_response).to be_a_kind_of(Hash)
  379. expect(json_response).to be_truthy
  380. expect(json_response['assets']['Ticket']).to be_falsey
  381. expect(group).not_to eq('ultrasupport')
  382. group.update(name: 'ultrasupport')
  383. Scheduler.worker(true)
  384. SearchIndexBackend.refresh
  385. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && group.name:ultrasupport" }, as: :json
  386. expect(response).to have_http_status(:ok)
  387. expect(json_response).to be_a_kind_of(Hash)
  388. expect(json_response).to be_truthy
  389. expect(json_response['assets']['Ticket'][ticket1.id.to_s]).to be_truthy
  390. end
  391. it 'does find the ticket by state name even if the state name changes' do
  392. authenticated_as(agent)
  393. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && state.name:ultrastate" }, as: :json
  394. expect(response).to have_http_status(:ok)
  395. expect(json_response).to be_a_kind_of(Hash)
  396. expect(json_response).to be_truthy
  397. expect(json_response['assets']['Ticket']).to be_falsey
  398. expect(ticket1.state.name).not_to eq('ultrastate')
  399. ticket1.state.update(name: 'ultrastate')
  400. Scheduler.worker(true)
  401. SearchIndexBackend.refresh
  402. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && state.name:ultrastate" }, as: :json
  403. expect(response).to have_http_status(:ok)
  404. expect(json_response).to be_a_kind_of(Hash)
  405. expect(json_response).to be_truthy
  406. expect(json_response['assets']['Ticket'][ticket1.id.to_s]).to be_truthy
  407. end
  408. it 'does find the ticket by priority name even if the priority name changes' do
  409. authenticated_as(agent)
  410. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && priority.name:ultrapriority" }, as: :json
  411. expect(response).to have_http_status(:ok)
  412. expect(json_response).to be_a_kind_of(Hash)
  413. expect(json_response).to be_truthy
  414. expect(json_response['assets']['Ticket']).to be_falsey
  415. expect(ticket1.priority.name).not_to eq('ultrapriority')
  416. ticket1.priority.update(name: 'ultrapriority')
  417. Scheduler.worker(true)
  418. SearchIndexBackend.refresh
  419. post '/api/v1/search/Ticket', params: { query: "number:#{ticket1.number} && priority.name:ultrapriority" }, as: :json
  420. expect(response).to have_http_status(:ok)
  421. expect(json_response).to be_a_kind_of(Hash)
  422. expect(json_response).to be_truthy
  423. expect(json_response['assets']['Ticket'][ticket1.id.to_s]).to be_truthy
  424. end
  425. it 'does find the ticket by attachment even after ticket reindex' do
  426. params = {
  427. query: 'text66',
  428. limit: 10,
  429. }
  430. authenticated_as(agent)
  431. post '/api/v1/search/Ticket', params: params, as: :json
  432. expect(response).to have_http_status(:ok)
  433. expect(json_response).to be_a_kind_of(Hash)
  434. expect(json_response).to be_truthy
  435. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  436. organization_nested.update(name: 'Cucumber43 Ltd.')
  437. Scheduler.worker(true)
  438. SearchIndexBackend.refresh
  439. params = {
  440. query: 'text66',
  441. limit: 10,
  442. }
  443. post '/api/v1/search/Ticket', params: params, as: :json
  444. expect(response).to have_http_status(:ok)
  445. expect(json_response).to be_a_kind_of(Hash)
  446. expect(json_response).to be_truthy
  447. expect(json_response['assets']['Ticket'][ticket_nested.id.to_s]).to be_truthy
  448. end
  449. end
  450. end