search_spec.rb 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. # Copyright (C) 2012-2024 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. context 'Organization members' do
  276. let(:organization) { create(:organization) }
  277. let(:members) { organization.members.reorder(id: :asc) }
  278. let(:before_authenticate) { create_list(:customer, 50, organization: organization) }
  279. before do
  280. fill_in id: 'global-search', with: organization.name.to_s
  281. end
  282. it 'shows only first 10 members' do
  283. expect(page).to have_text(organization.name)
  284. popover_on_hover(first('a.nav-tab.organization'))
  285. expect(page).to have_text(members[9].fullname, wait: 30)
  286. expect(page).to have_no_text(members[10].fullname)
  287. end
  288. end
  289. context 'inactive user and organizations' do
  290. before do
  291. create(:organization, name: 'Example Inc.', active: true)
  292. create(:organization, name: 'Example Inactive Inc.', active: false)
  293. create(:customer, firstname: 'Firstname', lastname: 'Active', active: true)
  294. create(:customer, firstname: 'Firstname', lastname: 'Inactive', active: false)
  295. searchindex_model_reload([User, Organization])
  296. end
  297. it 'check that inactive organizations are marked correctly' do
  298. fill_in id: 'global-search', with: '"Example"'
  299. expect(page).to have_css('.nav-tab--search.organization', minimum: 2)
  300. expect(page).to have_css('.nav-tab--search.organization.is-inactive', count: 1)
  301. end
  302. it 'check that inactive users are marked correctly' do
  303. fill_in id: 'global-search', with: '"Firstname"'
  304. expect(page).to have_css('.nav-tab--search.user', minimum: 2)
  305. expect(page).to have_css('.nav-tab--search.user.is-inactive', count: 1)
  306. end
  307. it 'check that inactive users are also marked in the popover for the quick search result' do
  308. fill_in id: 'global-search', with: '"Firstname"'
  309. popover_on_hover(find('.nav-tab--search.user.is-inactive'))
  310. expect(page).to have_css('.popover-title .is-inactive', count: 1)
  311. end
  312. end
  313. 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
  314. let(:agent) { create(:agent, groups: Group.all) }
  315. let(:authenticate_user) { agent }
  316. context 'when search changed via input box' do
  317. before do
  318. visit '#search'
  319. end
  320. it 'does switch search results properly' do
  321. page.find('.js-search').fill_in(with: '"Testing Ticket 1"')
  322. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  323. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  324. expect(current_url).to include('Testing%20Ticket%201')
  325. # switch by global search
  326. page.find('.js-search').fill_in(with: '"Testing Ticket 2"', fill_options: { clear: :backspace })
  327. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  328. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  329. expect(current_url).to include('Testing%20Ticket%202')
  330. end
  331. end
  332. context 'when search changed via global search' do
  333. before do
  334. fill_in id: 'global-search', with: '"Testing Ticket 1"'
  335. click_on 'Show Search Details'
  336. end
  337. it 'does switch search results properly' do
  338. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  339. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  340. expect(current_url).to include('Testing%20Ticket%201')
  341. # switch by global search
  342. fill_in id: 'global-search', with: '"Testing Ticket 2"'
  343. click_on 'Show Search Details'
  344. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  345. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  346. expect(current_url).to include('Testing%20Ticket%202')
  347. end
  348. end
  349. context 'when search is changed via url' do
  350. before do
  351. visit '#search/"Testing Ticket 1"'
  352. end
  353. it 'does switch search results properly' do
  354. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 1')
  355. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 2')
  356. expect(current_url).to include('Testing%20Ticket%201')
  357. # switch by url
  358. visit '#search/"Testing Ticket 2"'
  359. expect(page.find('.js-tableBody')).to have_text('Testing Ticket 2')
  360. expect(page.find('.js-tableBody')).to have_no_text('Testing Ticket 1')
  361. expect(current_url).to include('Testing%20Ticket%202')
  362. end
  363. end
  364. end
  365. context 'Assign user to multiple organizations #1573' do
  366. let(:organizations) { create_list(:organization, 20) }
  367. let(:customer) { create(:customer, organization: organizations[0], organizations: organizations[1..]) }
  368. context 'when agent' do
  369. let(:authenticate_user) { true }
  370. let(:before_authenticate) { customer }
  371. before do
  372. fill_in id: 'global-search', with: customer.firstname.to_s
  373. end
  374. it 'shows only first 3 organizations' do
  375. expect(page).to have_text(customer.firstname)
  376. popover_on_hover(first('a.nav-tab.user'))
  377. within '.popover' do
  378. expect(page).to have_text(organizations[2].name, wait: 30)
  379. expect(page).to have_no_text(organizations[10].name)
  380. end
  381. end
  382. end
  383. context 'when customer' do
  384. let(:authenticate_user) { customer }
  385. before do
  386. fill_in id: 'global-search', with: organizations[0].name.to_s
  387. end
  388. it 'does not show any organizations in global search because only agents have access to it' do
  389. within '.global-search-result' do
  390. expect(page).to have_no_text(organizations[0].name)
  391. end
  392. end
  393. end
  394. end
  395. describe 'Searches display all groups and owners on bulk selections #4054' do
  396. let(:group_1) { create(:group) }
  397. let(:group_2) { create(:group) }
  398. let(:agent_1) { create(:agent, groups: [group_1]) }
  399. let(:agent_2) { create(:agent, groups: [group_2]) }
  400. let(:agent_all) { create(:agent, groups: [group_1, group_2]) }
  401. let!(:ticket_1) { create(:ticket, group: group_1, title: '4054 group 1') }
  402. let!(:ticket_2) { create(:ticket, group: group_2, title: '4054 group 2') }
  403. let(:before_authenticate) { agent_1 && agent_2 && agent_all }
  404. let(:authenticate_user) { agent_all }
  405. def click_ticket(ticket)
  406. page.find(".js-tableBody tr.item[data-id='#{ticket.id}'] td.js-checkbox-field").click
  407. end
  408. def check_owner_agent1_shown
  409. expect(page).to have_select('owner_id', text: agent_1.fullname)
  410. expect(page).to have_no_select('owner_id', text: agent_2.fullname)
  411. end
  412. def check_owner_agent2_shown
  413. expect(page).to have_no_select('owner_id', text: agent_1.fullname)
  414. expect(page).to have_select('owner_id', text: agent_2.fullname)
  415. end
  416. def check_owner_field
  417. click_ticket(ticket_1)
  418. check_owner_agent1_shown
  419. click_ticket(ticket_1)
  420. click_ticket(ticket_2)
  421. check_owner_agent2_shown
  422. end
  423. context 'when search is used' do
  424. before do
  425. visit '#search/4054'
  426. end
  427. it 'does not show the bulk action when opening view' do
  428. expect(page).to have_text(ticket_1.title)
  429. expect(page).to have_text(ticket_2.title)
  430. expect(page).to have_no_css('.bulkAction select[name=owner_id]')
  431. end
  432. it 'does show the correct owner selection for each bulk action' do
  433. check_owner_field
  434. end
  435. end
  436. context 'when ticket overview is used' do
  437. before do
  438. visit '#ticket/view/all_unassigned'
  439. end
  440. it 'does not show the bulk action when opening view' do
  441. expect(page).to have_text(ticket_1.title)
  442. expect(page).to have_text(ticket_2.title)
  443. expect(page).to have_no_css('.bulkAction select[name=owner_id]')
  444. end
  445. it 'does show the correct owner selection for each bulk action' do
  446. check_owner_field
  447. end
  448. end
  449. end
  450. # https://github.com/zammad/zammad/issues/4264
  451. describe 'Keeps selected sorting' do
  452. before do
  453. fill_in id: 'global-search', with: 'Nico'
  454. click_on 'Show Search Details'
  455. find('.table-column-title', text: 'TITLE').click
  456. end
  457. it 'when switching to other taskbar keep sorting' do
  458. visit "ticket/zoom/#{Ticket.first.id}"
  459. click_on 'Nico'
  460. within('.table-column-head', text: 'TITLE') do
  461. expect(page).to have_css('.table-sort-arrow')
  462. end
  463. end
  464. it 'when switching to other search tab keep sorting' do
  465. within :active_content do
  466. find('.js-tab', text: 'User').click
  467. find('.js-tab', text: 'Ticket').click
  468. end
  469. # no need to wait for rerender in this case
  470. within('.table-column-head', text: 'TITLE') do
  471. expect(page).to have_css('.table-sort-arrow')
  472. end
  473. end
  474. it 'when changing search query clear sorting' do
  475. within :active_content do
  476. find('.js-search').fill_in with: 'Nicole'
  477. end
  478. within('.table-column-head', text: 'TITLE') do
  479. expect(page).to have_no_css('.table-sort-arrow')
  480. end
  481. end
  482. it 'when changing search query after navigation away-and-back clear sorting' do
  483. visit "ticket/zoom/#{Ticket.first.id}"
  484. click_on 'Nico'
  485. within :active_content do
  486. find('.js-search').fill_in with: 'Nicole'
  487. end
  488. within('.table-column-head', text: 'TITLE') do
  489. expect(page).to have_no_css('.table-sort-arrow')
  490. end
  491. end
  492. end
  493. describe 'Admin user can not find user or organization in the search bar #4574' do
  494. let(:admin) { create(:admin_only) }
  495. let(:agent) { create(:agent, groups: [Group.first]) }
  496. let(:organization) { create(:organization, name: SecureRandom.uuid) }
  497. let(:customer) { create(:customer, organization: organization, firstname: SecureRandom.uuid) }
  498. let(:ticket) { create(:ticket, title: SecureRandom.uuid, customer: customer, group: Group.first) }
  499. before do
  500. visit '#dashboard'
  501. end
  502. context 'when customer' do
  503. let(:before_authenticate) { organization && customer && ticket }
  504. let(:authenticate_user) { customer }
  505. it 'does find the ticket' do
  506. fill_in id: 'global-search', with: ticket.title
  507. expect(page.find('.global-search-menu')).to have_content(ticket.title)
  508. end
  509. it 'does not find the customer' do
  510. fill_in id: 'global-search', with: customer.firstname
  511. expect(page.find('.global-search-menu')).to have_no_content(customer.firstname)
  512. end
  513. it 'does not find the organization' do
  514. fill_in id: 'global-search', with: organization.name
  515. expect(page.find('.global-search-menu')).to have_no_content(organization.name)
  516. end
  517. end
  518. context 'when agent' do
  519. let(:before_authenticate) { organization && customer && ticket }
  520. let(:authenticate_user) { agent }
  521. it 'does find the ticket' do
  522. fill_in id: 'global-search', with: ticket.title
  523. expect(page.find('.global-search-menu')).to have_content(ticket.title)
  524. end
  525. it 'does find the customer' do
  526. fill_in id: 'global-search', with: customer.firstname
  527. expect(page.find('.global-search-menu')).to have_content(customer.firstname)
  528. end
  529. it 'does find the organization' do
  530. fill_in id: 'global-search', with: organization.name
  531. expect(page.find('.global-search-menu')).to have_content(organization.name)
  532. end
  533. end
  534. context 'when admin only' do
  535. let(:authenticate_user) { admin }
  536. let(:before_authenticate) { organization && customer && ticket }
  537. it 'does not find the ticket' do
  538. fill_in id: 'global-search', with: ticket.title
  539. expect(page.find('.global-search-menu')).to have_no_content(ticket.title)
  540. end
  541. it 'does find the customer' do
  542. fill_in id: 'global-search', with: customer.firstname
  543. expect(page.find('.global-search-menu')).to have_content(customer.firstname)
  544. end
  545. it 'does find the organization' do
  546. fill_in id: 'global-search', with: organization.name
  547. expect(page.find('.global-search-menu')).to have_content(organization.name)
  548. end
  549. end
  550. end
  551. describe 'popover closes when item is opened' do
  552. let(:agent) { create(:agent, groups: Group.all) }
  553. let(:authenticate_user) { agent }
  554. before do
  555. fill_in id: 'global-search', with: 'Testing'
  556. end
  557. it 'closes popover when item is clicked' do
  558. elem = first('a.nav-tab.ticket-popover')
  559. popover_on_hover(elem)
  560. expect(page).to have_css('.popover')
  561. elem.click
  562. expect(page).to have_no_css('.popover')
  563. end
  564. it 'closes popover when item is opened via keyboard' do
  565. first('a.nav-tab.ticket-popover') # ensure search results are visible
  566. send_keys(:down) # go to detailed search
  567. send_keys(:down) # go to first ticket
  568. expect(page).to have_css('.popover')
  569. send_keys(:enter) # open
  570. expect(page).to have_no_css('.popover')
  571. end
  572. end
  573. describe 'search with many results', searchindex: false do
  574. let(:new_customers) { create_list(:customer, 55) }
  575. let(:all_zammad_customers) { User.where('email LIKE ?', '%zammad%') }
  576. let(:all_zammad_customers_sorted) { all_zammad_customers.reorder(:login) }
  577. before do
  578. new_customers
  579. visit '#search/zammad'
  580. end
  581. it 'shows 50 on first page and remaining on second page' do
  582. expect(page).to have_css('.tab[data-tab-content=User] .tab-badge', text: all_zammad_customers.count)
  583. click '.tab[data-tab-content=User]'
  584. expect(page).to have_css('.js-tableBody tr', count: 50)
  585. page.first('.js-page', text: '2').click
  586. expect(page).to have_css('.js-tableBody tr', count: all_zammad_customers.count % 50)
  587. end
  588. it 'sorts correctly across pages' do
  589. click '.tab[data-tab-content=User]'
  590. first('.js-sort').click
  591. expect(page).to have_css('.js-tableBody tr:first-child',
  592. text: all_zammad_customers_sorted.first.login)
  593. first('.js-sort').click
  594. expect(page).to have_css('.js-tableBody tr:first-child',
  595. text: all_zammad_customers_sorted.last.login)
  596. first('.js-page', text: '2').click
  597. expect(page).to have_css('.js-tableBody tr:last-child',
  598. text: all_zammad_customers_sorted.first.login)
  599. end
  600. end
  601. end