pagination_examples.rb 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. RSpec.shared_examples 'pagination', authenticated_as: :authenticate do |model:, klass:, path:, sort_by: :name, create_params: {}, main_column: :name|
  3. let(:create_params) { create_params }
  4. let(:model) { model }
  5. let(:klass) { klass }
  6. let(:base_scope) { klass.try(:changeable) || klass }
  7. let(:indexable) { Models.indexable.include?(klass) }
  8. def authenticate
  9. create_list(model, 500, **create_params)
  10. true
  11. end
  12. def offset_first_of_page(page, entries_per_page)
  13. (entries_per_page * (page - 1)) + 1
  14. end
  15. before do
  16. visit path
  17. end
  18. it 'does paginate' do
  19. entries_per_page = page.all('.js-tableBody tr').count
  20. expect(page).to have_css('.js-pager')
  21. class_page1 = base_scope.reorder(sort_by => :asc, id: :asc).offset(offset_first_of_page(1, entries_per_page)).first
  22. expect(page).to have_text(class_page1.send(main_column))
  23. expect(page).to have_css('.js-page.btn--active', text: '1')
  24. expect(page).to have_no_css('.js-tableBody table-draggable')
  25. page.first('.js-page', text: '2').click
  26. class_page2 = base_scope.reorder(sort_by => :asc, id: :asc).offset(offset_first_of_page(2, entries_per_page)).first
  27. expect(page).to have_text(class_page2.send(main_column))
  28. expect(page).to have_css('.js-page.btn--active', text: '2')
  29. expect(page).to have_no_css('.js-tableBody table-draggable')
  30. page.first('.js-page', text: '3').click
  31. class_page3 = base_scope.reorder(sort_by => :asc, id: :asc).offset(offset_first_of_page(3, entries_per_page)).first
  32. expect(page).to have_text(class_page3.send(main_column))
  33. expect(page).to have_css('.js-page.btn--active', text: '3')
  34. expect(page).to have_no_css('.js-tableBody table-draggable')
  35. page.first('.js-page', text: '4').click
  36. class_page4 = base_scope.reorder(sort_by => :asc, id: :asc).offset(offset_first_of_page(4, entries_per_page)).first
  37. expect(page).to have_text(class_page4.send(main_column))
  38. expect(page).to have_css('.js-page.btn--active', text: '4')
  39. expect(page).to have_no_css('.js-tableBody table-draggable')
  40. page.first('.js-page', text: '1').click
  41. page.first(".js-tableHead[data-column-key=#{main_column}]").click
  42. class_page1 = base_scope.reorder(main_column => :asc, id: :asc).offset(offset_first_of_page(1, entries_per_page)).first
  43. expect(page).to have_text(class_page1.send(main_column))
  44. expect(page).to have_css('.js-page.btn--active', text: '1')
  45. expect(page).to have_no_css('.js-tableBody table-draggable')
  46. page.first(".js-tableHead[data-column-key=#{main_column}]").click
  47. class_last = base_scope.reorder(main_column => :desc, id: :asc).offset(offset_first_of_page(1, entries_per_page)).first
  48. expect(page).to have_text(class_last.send(main_column))
  49. end
  50. context 'when search is enabled' do
  51. before do
  52. skip 'No search field enabled' if !indexable || !page.has_css?('.page-content .searchfield .js-search', wait: 5)
  53. end
  54. it 'does filter results with the search bar' do
  55. page.find('.js-search').fill_in with: base_scope.last.try(main_column)
  56. wait.until { page.all('.js-tableBody tr').count == 1 }
  57. # does stay after reload
  58. refresh
  59. wait.until { page.find('.js-search').present? && page.all('.js-tableBody tr').count == 1 }
  60. # remove filter
  61. page.find('.js-search').fill_in with: '', fill_options: { clear: :backspace }
  62. wait.until { page.all('.js-tableBody tr').count != 1 }
  63. end
  64. context 'when ES is enabled', authenticated_as: :authenticate, searchindex: true do
  65. def authenticate
  66. create_list(model, 500, **create_params)
  67. searchindex_model_reload([klass]) if indexable
  68. create(:admin)
  69. end
  70. it 'does only show 2 pages because of a search filter and paginate through it' do
  71. entries_per_page = page.all('.js-tableBody tr').count
  72. search_query = base_scope.limit(entries_per_page * 2).pluck(:id).map { |i| "id: #{i}" }.join(' OR ')
  73. page.find('.js-search').fill_in with: search_query, fill_options: { clear: :backspace }
  74. wait.until { page.first('.js-pager').all('.js-page').count == 4 }
  75. page.first('.js-page', text: '2').click
  76. expect(page).to have_css('.js-page.btn--active', text: '2')
  77. expect(page).to have_no_css('.js-tableBody table-draggable')
  78. wait.until { page.find('.js-search').present? && page.find('.js-search').value == search_query && page.first('.js-pager').all('.js-page').count == 4 }
  79. end
  80. end
  81. end
  82. end