search_spec.rb 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. # Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Search', authenticated_as: :authenticate, searchindex: true, type: :system do
  4. let(:group_1) { create(:group) }
  5. let(:group_2) { create(:group) }
  6. let(:macro_without_group) { create(:macro) }
  7. let(:macro_group1) { create(:macro, groups: [group_1]) }
  8. let(:macro_group2) { create(:macro, groups: [group_2]) }
  9. let!(:ticket_1) { create(:ticket, title: 'Testing Ticket 1', group: group_1) }
  10. let!(:ticket_2) { create(:ticket, title: 'Testing Ticket 2', group: group_2) }
  11. let(:note) { 'Test note' }
  12. let(:authenticate_user) { true }
  13. let(:before_authenticate) { nil }
  14. def authenticate
  15. ticket_1 && ticket_2
  16. macro_without_group && macro_group1 && macro_group2
  17. before_authenticate
  18. searchindex_model_reload([Ticket, Organization, User])
  19. authenticate_user
  20. end
  21. before do
  22. visit '/'
  23. end
  24. it 'shows default widgets' do
  25. fill_in id: 'global-search', with: '"Welcome"'
  26. click_on 'Show Search Details'
  27. within '#navigation .tasks a[data-key=Search]' do
  28. expect(page).to have_content '"Welcome"'
  29. end
  30. end
  31. context 'with ticket search result' do
  32. let(:agent) { create(:agent, groups: Group.all) }
  33. let(:authenticate_user) { agent }
  34. before do
  35. fill_in id: 'global-search', with: 'Testing'
  36. click_on 'Show Search Details'
  37. find('[data-tab-content=Ticket]').click
  38. end
  39. context 'checkbox' do
  40. it 'has checkbox for each ticket records' do
  41. within '.detail-search table.table' do
  42. expect(page).to have_xpath(".//td[contains(@class, 'js-checkbox-field')]//input[@type='checkbox']", visible: :all, minimum: 2)
  43. end
  44. end
  45. it 'has select all checkbox' do
  46. within '.detail-search table.table' do
  47. expect(page).to have_xpath(".//th//input[@type='checkbox' and @name='bulk_all']", visible: :all, count: 1)
  48. end
  49. end
  50. it 'shows bulkform when checkbox is checked' do
  51. within '.detail-search table.table' do
  52. find("tr[data-id='#{ticket_1.id}']").check('bulk', allow_label_click: true)
  53. end
  54. expect(page).to have_css('.bulkAction.no-sidebar')
  55. expect(page).to have_no_selector('.bulkAction.no-sidebar.hide', visible: :all)
  56. end
  57. it 'shows bulkform when all checkbox is checked' do
  58. within '.detail-search table.table' do
  59. find('th.table-checkbox').check('bulk_all', allow_label_click: true)
  60. end
  61. expect(page).to have_css('.bulkAction.no-sidebar')
  62. expect(page).to have_no_selector('.bulkAction.no-sidebar.hide', visible: :all)
  63. end
  64. it 'hides bulkform when checkbox is unchecked' do
  65. within '.detail-search table.table' do
  66. find('th.table-checkbox').check('bulk_all', allow_label_click: true)
  67. all('.js-tableBody tr.item').each { |row| row.uncheck('bulk', allow_label_click: true) }
  68. end
  69. expect(page).to have_css('.bulkAction.no-sidebar.hide', visible: :hide)
  70. end
  71. end
  72. context 'with bulkform activated' do
  73. before do
  74. find('th.table-checkbox').check('bulk_all', allow_label_click: true)
  75. end
  76. it 'has group label' do
  77. within '.bulkAction .bulkAction-form' do
  78. expect(page).to have_content 'GROUP'
  79. end
  80. end
  81. it 'has owner label' do
  82. within '.bulkAction .bulkAction-form' do
  83. expect(page).to have_content 'OWNER'
  84. end
  85. end
  86. it 'has state label' do
  87. within '.bulkAction .bulkAction-form' do
  88. expect(page).to have_content 'STATE'
  89. end
  90. end
  91. it 'has priority label' do
  92. within '.bulkAction .bulkAction-form' do
  93. expect(page).to have_content 'PRIORITY'
  94. end
  95. end
  96. end
  97. context 'bulk note' do
  98. it 'adds note to selected ticket' do
  99. within :active_content do
  100. find("tr[data-id='#{ticket_1.id}']").check('bulk', allow_label_click: true)
  101. click '.js-confirm'
  102. find('.js-confirm-step textarea').fill_in with: note
  103. click '.js-submit'
  104. end
  105. expect do
  106. wait.until { ticket_1.articles.last&.body == note }
  107. end.not_to raise_error
  108. end
  109. end
  110. context 'with drag and drop' do
  111. context 'when checked tickets are dragged' do
  112. it 'shows the batch actions' do
  113. within(:active_content, '.main .table') do
  114. # get element to move
  115. element = page.find(:table_row, ticket_1.id).native
  116. click_and_hold(element)
  117. # move element a bit to display batch actions
  118. move_mouse_by(0, 5)
  119. # move mouse again to trigger the event for chrome
  120. move_mouse_by(0, 7)
  121. end
  122. expect(page).to have_css('.batch-overlay-circle--top.js-batch-macro-circle')
  123. .and(have_css('.batch-overlay-circle--bottom.js-batch-assign-circle'))
  124. end
  125. end
  126. end
  127. end
  128. context 'with ticket search result for macros bulk action' do
  129. let(:group_3) { create(:group) }
  130. let(:search_query) { 'Testing' }
  131. let!(:ticket_3) { create(:ticket, title: 'Testing Ticket 3', group: group_3) }
  132. let(:agent) { create(:agent, groups: Group.all) }
  133. before do
  134. fill_in id: 'global-search', with: search_query
  135. click_on 'Show Search Details'
  136. find('[data-tab-content=Ticket]').click
  137. await_empty_ajax_queue
  138. end
  139. describe 'group-dependent macros' do
  140. let(:authenticate_user) { agent }
  141. let(:before_authenticate) { ticket_3 }
  142. it 'shows only non-group macro when ticket does not match any group macros' do
  143. within(:active_content) do
  144. display_macro_batches ticket_3
  145. expect(page).to have_selector(:macro_batch, macro_without_group.id)
  146. .and(have_no_selector(:macro_batch, macro_group1.id))
  147. .and(have_no_selector(:macro_batch, macro_group2.id))
  148. end
  149. end
  150. it 'shows non-group and matching group macros for matching ticket' do
  151. display_macro_batches ticket_1
  152. within(:active_content) do
  153. expect(page).to have_selector(:macro_batch, macro_without_group.id)
  154. .and(have_selector(:macro_batch, macro_group1.id))
  155. .and(have_no_selector(:macro_batch, macro_group2.id))
  156. end
  157. end
  158. end
  159. describe 'when agent cannot change some of the tickets' do
  160. let(:authenticate_user) { agent }
  161. let(:before_authenticate) { agent.user_groups.create! group: ticket_3.group, access: 'read' }
  162. it 'show macros if agent cannot change selected tickets' do
  163. display_macro_batches ticket_1
  164. within(:active_content) do
  165. expect(page).to have_no_text(%r{No macros available}i)
  166. .and(have_selector(:macro_batch, macro_without_group.id))
  167. end
  168. end
  169. it 'show no macros if agent cannot change selected tickets' do
  170. display_macro_batches ticket_3
  171. within(:active_content) do
  172. expect(page).to have_text(%r{No macros available}i)
  173. .and(have_text(%r{no change permission}i))
  174. .and(have_no_selector(:macro_batch, macro_without_group.id))
  175. end
  176. end
  177. end
  178. describe 'when user is agent-customer' do
  179. let(:agent_customer) { create(:agent_and_customer) }
  180. let(:authenticate_user) { agent_customer }
  181. let(:before_authenticate) do
  182. ticket_1.update!(customer: agent_customer)
  183. agent_customer
  184. .tap { |user| user.groups << group_2 }
  185. end
  186. it 'show no macros if the ticket is customer-like' do
  187. display_macro_batches ticket_1
  188. within :active_content do
  189. expect(page).to have_text(%r{No macros available}i)
  190. .and(have_text(%r{no change permission}i))
  191. .and(have_no_selector(:macro_batch, macro_without_group.id))
  192. .and(have_no_selector(:macro_batch, macro_group1.id))
  193. .and(have_no_selector(:macro_batch, macro_group2.id))
  194. end
  195. end
  196. it 'show macros if tickets are only agent-like' do
  197. display_macro_batches ticket_2
  198. within :active_content do
  199. expect(page).to have_no_text(%r{No macros available}i)
  200. .and(have_selector(:macro_batch, macro_without_group.id))
  201. .and(have_no_selector(:macro_batch, macro_group1.id))
  202. .and(have_selector(:macro_batch, macro_group2.id))
  203. end
  204. end
  205. end
  206. describe 'when user is customer' do
  207. let(:customer) { create(:customer) }
  208. let(:authenticate_user) { customer }
  209. let(:before_authenticate) { ticket_1.update!(customer: customer) }
  210. it 'shows no overlay' do
  211. display_macro_batches ticket_1
  212. within :active_content do
  213. expect(page).to have_no_selector('.batch-overlay-backdrop')
  214. end
  215. end
  216. end
  217. context 'with macro batch overlay' do
  218. shared_examples "adding 'small' class to macro element" do
  219. it 'adds a "small" class to the macro element' do
  220. display_macro_batches ticket_1
  221. within(:active_content) do
  222. expect(page).to have_css('.batch-overlay-macro-entry.small')
  223. end
  224. end
  225. end
  226. shared_examples "not adding 'small' class to macro element" do
  227. it 'does not add a "small" class to the macro element' do
  228. display_macro_batches ticket_1
  229. within(:active_content) do
  230. expect(page).to have_no_selector('.batch-overlay-macro-entry.small')
  231. end
  232. end
  233. end
  234. shared_examples 'showing all macros' do
  235. it 'shows all macros' do
  236. display_macro_batches ticket_1
  237. within(:active_content) do
  238. expect(page).to have_css('.batch-overlay-macro-entry', count: all)
  239. end
  240. end
  241. end
  242. shared_examples 'showing some macros' do |count|
  243. it 'shows all macros' do
  244. display_macro_batches ticket_1
  245. within(:active_content) do
  246. expect(page).to have_css('.batch-overlay-macro-entry', count: count)
  247. end
  248. end
  249. end
  250. let(:authenticate_user) { agent }
  251. let(:before_authenticate) { Macro.destroy_all && create_list(:macro, all) }
  252. context 'with few macros' do
  253. let(:all) { 15 }
  254. context 'when on large screen', screen_size: :desktop do
  255. it_behaves_like 'showing all macros'
  256. it_behaves_like "not adding 'small' class to macro element"
  257. end
  258. context 'when on small screen', screen_size: :tablet do
  259. it_behaves_like 'showing all macros'
  260. it_behaves_like "not adding 'small' class to macro element"
  261. end
  262. end
  263. context 'with many macros' do
  264. let(:all) { 50 }
  265. context 'when on large screen', screen_size: :desktop do
  266. it_behaves_like 'showing some macros', 32
  267. end
  268. context 'when on small screen', screen_size: :tablet do
  269. it_behaves_like 'showing some macros', 24
  270. it_behaves_like "adding 'small' class to macro element"
  271. end
  272. end
  273. end
  274. end
  275. # https://github.com/zammad/zammad/issues/5505
  276. context 'when tickets are ordered by grroups' do
  277. let(:agent) { create(:agent, groups: Group.all) }
  278. let(:authenticate_user) { agent }
  279. let(:ticket_3) { create(:ticket, title: 'Testing Ticket 3', group: group_1) }
  280. let(:ticket_4) { create(:ticket, title: 'Testing Ticket 4', group: group_2) }
  281. let(:ticket_5) { create(:ticket, title: 'Testing Ticket 5', group: group_1) }
  282. let(:ticket_6) { create(:ticket, title: 'Testing Ticket 6', group: group_2) }
  283. before do
  284. ticket_4 && ticket_5 && ticket_6 && ticket_3
  285. searchindex_model_reload([Ticket, Organization, User])
  286. fill_in id: 'global-search', with: 'Testing'
  287. click_on 'Show Search Details'
  288. find('[data-tab-content=Ticket]').click
  289. end
  290. it 'sorts correctly' do
  291. # bug is most visible in descending order
  292. find('.table-column-title', text: 'GROUP').click
  293. find('.table-column-title', text: 'GROUP').click
  294. actual_ids = all('.js-tableBody tr.item').map { |row| row['data-id'].to_i }
  295. expected_ids = [ticket_6, ticket_4, ticket_2, ticket_3, ticket_5, ticket_1].map(&:id)
  296. expect(actual_ids).to eq(expected_ids)
  297. end
  298. end
  299. context 'Organization members' do
  300. let(:organization) { create(:organization) }
  301. let(:members) { organization.members.reorder(id: :asc) }
  302. let(:before_authenticate) { create_list(:customer, 50, organization: organization) }
  303. before do
  304. fill_in id: 'global-search', with: organization.name.to_s
  305. end
  306. it 'shows only first 10 members' do
  307. expect(page).to have_text(organization.name)
  308. popover_on_hover(first('a.nav-tab.organization'))
  309. expect(page).to have_text(members[9].fullname, wait: 30)
  310. expect(page).to have_no_text(members[10].fullname)
  311. end
  312. end
  313. context 'inactive user and organizations' do
  314. before do
  315. create(:organization, name: 'Example Inc.', active: true)
  316. create(:organization, name: 'Example Inactive Inc.', active: false)
  317. create(:customer, firstname: 'Firstname', lastname: 'Active', active: true)
  318. create(:customer, firstname: 'Firstname', lastname: 'Inactive', active: false)
  319. searchindex_model_reload([User, Organization])
  320. end
  321. it 'check that inactive organizations are marked correctly' do
  322. fill_in id: 'global-search', with: '"Example"'
  323. expect(page).to have_css('.nav-tab--search.organization', minimum: 2)
  324. expect(page).to have_css('.nav-tab--search.organization.is-inactive', count: 1)
  325. end
  326. it 'check that inactive users are marked correctly' do
  327. fill_in id: 'global-search', with: '"Firstname"'
  328. expect(page).to have_css('.nav-tab--search.user', minimum: 2)
  329. expect(page).to have_css('.nav-tab--search.user.is-inactive', count: 1)
  330. end
  331. it 'check that inactive users are also marked in the popover for the quick search result' do
  332. fill_in id: 'global-search', with: '"Firstname"'
  333. popover_on_hover(find('.nav-tab--search.user.is-inactive'))
  334. expect(page).to have_css('.popover-title .is-inactive', count: 1)
  335. end
  336. end
  337. describe 'Search is not triggered/updated if url of search is updated new search item or new search is triggered via global search #3873' do
  338. let(:agent) { create(:agent, groups: Group.all) }
  339. let(:authenticate_user) { agent }
  340. context 'when search changed via input box' do
  341. before do
  342. visit '#search'
  343. end
  344. it 'does switch search results properly' do
  345. page.find('.js-search').fill_in(with: '"Testing Ticket 1"')
  346. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  347. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  348. expect(current_url).to include('Testing%20Ticket%201')
  349. # switch by global search
  350. page.find('.js-search').fill_in(with: '"Testing Ticket 2"', fill_options: { clear: :backspace })
  351. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  352. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  353. expect(current_url).to include('Testing%20Ticket%202')
  354. end
  355. end
  356. context 'when search changed via global search' do
  357. before do
  358. fill_in id: 'global-search', with: '"Testing Ticket 1"'
  359. click_on 'Show Search Details'
  360. end
  361. it 'does switch search results properly' do
  362. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  363. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  364. expect(current_url).to include('Testing%20Ticket%201')
  365. # switch by global search
  366. fill_in id: 'global-search', with: '"Testing Ticket 2"'
  367. click_on 'Show Search Details'
  368. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  369. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  370. expect(current_url).to include('Testing%20Ticket%202')
  371. end
  372. end
  373. context 'when search is changed via url' do
  374. before do
  375. visit '#search/"Testing Ticket 1"'
  376. end
  377. it 'does switch search results properly' do
  378. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  379. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  380. expect(current_url).to include('Testing%20Ticket%201')
  381. # switch by url
  382. visit '#search/"Testing Ticket 2"'
  383. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  384. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  385. expect(current_url).to include('Testing%20Ticket%202')
  386. end
  387. end
  388. end
  389. context 'Assign user to multiple organizations #1573' do
  390. let(:organizations) { create_list(:organization, 20) }
  391. let(:customer) { create(:customer, organization: organizations[0], organizations: organizations[1..]) }
  392. context 'when agent' do
  393. let(:authenticate_user) { true }
  394. let(:before_authenticate) { customer }
  395. before do
  396. fill_in id: 'global-search', with: customer.firstname.to_s
  397. end
  398. it 'shows only first 3 organizations' do
  399. expect(page).to have_text(customer.firstname)
  400. popover_on_hover(first('a.nav-tab.user'))
  401. within '.popover' do
  402. expect(page).to have_text(organizations[2].name, wait: 30)
  403. expect(page).to have_no_text(organizations[10].name)
  404. end
  405. end
  406. end
  407. context 'when customer' do
  408. let(:authenticate_user) { customer }
  409. before do
  410. fill_in id: 'global-search', with: organizations[0].name.to_s
  411. end
  412. it 'does not show any organizations in global search because only agents have access to it' do
  413. within '.global-search-result' do
  414. expect(page).to have_no_text(organizations[0].name)
  415. end
  416. end
  417. end
  418. end
  419. describe 'Searches display all groups and owners on bulk selections #4054' do
  420. let(:group_1) { create(:group) }
  421. let(:group_2) { create(:group) }
  422. let(:agent_1) { create(:agent, groups: [group_1]) }
  423. let(:agent_2) { create(:agent, groups: [group_2]) }
  424. let(:agent_all) { create(:agent, groups: [group_1, group_2]) }
  425. let!(:ticket_1) { create(:ticket, group: group_1, title: '4054 group 1') }
  426. let!(:ticket_2) { create(:ticket, group: group_2, title: '4054 group 2') }
  427. let(:before_authenticate) { agent_1 && agent_2 && agent_all }
  428. let(:authenticate_user) { agent_all }
  429. def click_ticket(ticket)
  430. page.find(".js-tableBody tr.item[data-id='#{ticket.id}'] td.js-checkbox-field").click
  431. end
  432. def check_owner_agent1_shown
  433. expect(page).to have_select('owner_id', text: agent_1.fullname)
  434. expect(page).to have_no_select('owner_id', text: agent_2.fullname)
  435. end
  436. def check_owner_agent2_shown
  437. expect(page).to have_no_select('owner_id', text: agent_1.fullname)
  438. expect(page).to have_select('owner_id', text: agent_2.fullname)
  439. end
  440. def check_owner_field
  441. click_ticket(ticket_1)
  442. check_owner_agent1_shown
  443. click_ticket(ticket_1)
  444. click_ticket(ticket_2)
  445. check_owner_agent2_shown
  446. end
  447. context 'when search is used' do
  448. before do
  449. visit '#search/4054'
  450. end
  451. it 'does not show the bulk action when opening view' do
  452. expect(page).to have_text(ticket_1.title)
  453. expect(page).to have_text(ticket_2.title)
  454. expect(page).to have_no_css('.bulkAction select[name=owner_id]')
  455. end
  456. it 'does show the correct owner selection for each bulk action' do
  457. check_owner_field
  458. end
  459. end
  460. context 'when ticket overview is used' do
  461. before do
  462. visit '#ticket/view/all_unassigned'
  463. end
  464. it 'does not show the bulk action when opening view' do
  465. expect(page).to have_text(ticket_1.title)
  466. expect(page).to have_text(ticket_2.title)
  467. expect(page).to have_no_css('.bulkAction select[name=owner_id]')
  468. end
  469. it 'does show the correct owner selection for each bulk action' do
  470. check_owner_field
  471. end
  472. end
  473. end
  474. # https://github.com/zammad/zammad/issues/4264
  475. describe 'Keeps selected sorting' do
  476. before do
  477. fill_in id: 'global-search', with: 'Nico'
  478. click_on 'Show Search Details'
  479. find('.table-column-title', text: 'TITLE').click
  480. end
  481. it 'when switching to other taskbar keep sorting' do
  482. visit "ticket/zoom/#{Ticket.first.id}"
  483. click_on 'Nico'
  484. within('.table-column-head', text: 'TITLE') do
  485. expect(page).to have_css('.table-sort-arrow')
  486. end
  487. end
  488. it 'when switching to other search tab keep sorting' do
  489. within :active_content do
  490. find('.js-tab', text: 'User').click
  491. find('.js-tab', text: 'Ticket').click
  492. end
  493. # no need to wait for rerender in this case
  494. within('.table-column-head', text: 'TITLE') do
  495. expect(page).to have_css('.table-sort-arrow')
  496. end
  497. end
  498. it 'when changing search query clear sorting' do
  499. within :active_content do
  500. find('.js-search').fill_in with: 'Nicole'
  501. end
  502. within('.table-column-head', text: 'TITLE') do
  503. expect(page).to have_no_css('.table-sort-arrow')
  504. end
  505. end
  506. it 'when changing search query after navigation away-and-back clear sorting' do
  507. visit "ticket/zoom/#{Ticket.first.id}"
  508. click_on 'Nico'
  509. within :active_content do
  510. find('.js-search').fill_in with: 'Nicole'
  511. end
  512. within('.table-column-head', text: 'TITLE') do
  513. expect(page).to have_no_css('.table-sort-arrow')
  514. end
  515. end
  516. end
  517. describe 'Admin user can not find user or organization in the search bar #4574' do
  518. let(:admin) { create(:admin_only) }
  519. let(:agent) { create(:agent, groups: [Group.first]) }
  520. let(:organization) { create(:organization, name: SecureRandom.uuid) }
  521. let(:customer) { create(:customer, organization: organization, firstname: SecureRandom.uuid) }
  522. let(:ticket) { create(:ticket, title: SecureRandom.uuid, customer: customer, group: Group.first) }
  523. before do
  524. visit '#dashboard'
  525. end
  526. context 'when customer' do
  527. let(:before_authenticate) { organization && customer && ticket }
  528. let(:authenticate_user) { customer }
  529. it 'does find the ticket' do
  530. fill_in id: 'global-search', with: ticket.title
  531. expect(page.find('.global-search-menu')).to have_content(ticket.title)
  532. end
  533. it 'does not find the customer' do
  534. fill_in id: 'global-search', with: customer.firstname
  535. expect(page.find('.global-search-menu')).to have_no_content(customer.firstname)
  536. end
  537. it 'does not find the organization' do
  538. fill_in id: 'global-search', with: organization.name
  539. expect(page.find('.global-search-menu')).to have_no_content(organization.name)
  540. end
  541. end
  542. context 'when agent' do
  543. let(:before_authenticate) { organization && customer && ticket }
  544. let(:authenticate_user) { agent }
  545. it 'does find the ticket' do
  546. fill_in id: 'global-search', with: ticket.title
  547. expect(page.find('.global-search-menu')).to have_content(ticket.title)
  548. end
  549. it 'does find the customer' do
  550. fill_in id: 'global-search', with: customer.firstname
  551. expect(page.find('.global-search-menu')).to have_content(customer.firstname)
  552. end
  553. it 'does find the organization' do
  554. fill_in id: 'global-search', with: organization.name
  555. expect(page.find('.global-search-menu')).to have_content(organization.name)
  556. end
  557. end
  558. context 'when admin only' do
  559. let(:authenticate_user) { admin }
  560. let(:before_authenticate) { organization && customer && ticket }
  561. it 'does not find the ticket' do
  562. fill_in id: 'global-search', with: ticket.title
  563. expect(page.find('.global-search-menu')).to have_no_content(ticket.title)
  564. end
  565. it 'does find the customer' do
  566. fill_in id: 'global-search', with: customer.firstname
  567. expect(page.find('.global-search-menu')).to have_content(customer.firstname)
  568. end
  569. it 'does find the organization' do
  570. fill_in id: 'global-search', with: organization.name
  571. expect(page.find('.global-search-menu')).to have_content(organization.name)
  572. end
  573. end
  574. end
  575. describe 'popover closes when item is opened' do
  576. let(:agent) { create(:agent, groups: Group.all) }
  577. let(:authenticate_user) { agent }
  578. before do
  579. fill_in id: 'global-search', with: 'Testing'
  580. end
  581. it 'closes popover when item is clicked' do
  582. elem = first('a.nav-tab.ticket-popover')
  583. popover_on_hover(elem)
  584. expect(page).to have_css('.popover')
  585. elem.click
  586. expect(page).to have_no_css('.popover')
  587. end
  588. it 'closes popover when item is opened via keyboard' do
  589. first('a.nav-tab.ticket-popover') # ensure search results are visible
  590. send_keys(:down) # go to detailed search
  591. send_keys(:down) # go to first ticket
  592. expect(page).to have_css('.popover')
  593. send_keys(:enter) # open
  594. expect(page).to have_no_css('.popover')
  595. end
  596. end
  597. describe 'search with many results', searchindex: false do
  598. let(:new_customers) { create_list(:customer, 55) }
  599. let(:all_zammad_customers) { User.where('email LIKE ?', '%zammad%') }
  600. let(:all_zammad_customers_sorted) { all_zammad_customers.reorder(:login) }
  601. before do
  602. new_customers
  603. visit '#search/zammad'
  604. end
  605. it 'shows 50 on first page and remaining on second page' do
  606. expect(page).to have_css('.tab[data-tab-content=User] .tab-badge', text: all_zammad_customers.count)
  607. click '.tab[data-tab-content=User]'
  608. expect(page).to have_css('.js-tableBody tr', count: 50)
  609. page.first('.js-page', text: '2').click
  610. expect(page).to have_css('.js-tableBody tr', count: all_zammad_customers.count % 50)
  611. end
  612. it 'sorts correctly across pages' do
  613. click '.tab[data-tab-content=User]'
  614. first('.js-sort').click
  615. expect(page).to have_css('.js-tableBody tr:first-child',
  616. text: all_zammad_customers_sorted.first.login)
  617. first('.js-sort').click
  618. expect(page).to have_css('.js-tableBody tr:first-child',
  619. text: all_zammad_customers_sorted.last.login)
  620. first('.js-page', text: '2').click
  621. expect(page).to have_css('.js-tableBody tr:last-child',
  622. text: all_zammad_customers_sorted.first.login)
  623. end
  624. end
  625. end