require 'rails_helper'
RSpec.describe ActiveAdmin::Views::PaginatedCollection do
describe "creating with the dsl" do
before :all do
load_defaults!
reload_routes!
end
let(:view) do
view = mock_action_view
allow(view.request).to receive(:query_parameters).and_return page: '1'
allow(view.request).to receive(:path_parameters).and_return controller: 'admin/posts', action: 'index'
view
end
# Helper to render paginated collections within an arbre context
def paginated_collection(*args)
render_arbre_component({paginated_collection_args: args}, view) do
paginated_collection(*paginated_collection_args)
end
end
let(:collection) do
posts = [Post.new(title: "First Post"), Post.new(title: "Second Post"), Post.new(title: "Third Post")]
Kaminari.paginate_array(posts).page(1).per(5)
end
before do
allow(collection).to receive(:except) { collection } unless collection.respond_to? :except
allow(collection).to receive(:group_values) { [] } unless collection.respond_to? :group_values
end
let(:pagination){ paginated_collection collection }
it "should set :collection as the passed in collection" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 3 posts"
end
it "should raise error if collection has no pagination scope" do
expect {
paginated_collection([Post.new, Post.new])
}.to raise_error(StandardError, "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection.")
end
it 'should preserve custom query params' do
allow(view.request).to receive(:query_parameters).and_return page: '1', something: 'else'
pagination_content = pagination.content
expect(pagination_content).to include '/admin/posts.csv?page=1&something=else'
expect(pagination_content).to include '/admin/posts.xml?page=1&something=else'
expect(pagination_content).to include '/admin/posts.json?page=1&something=else'
end
context "when specifying :param_name option" do
let(:collection) do
posts = 10.times.map{ Post.new }
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, param_name: :post_page) }
it "should customize the page number parameter in pagination links" do
expect(pagination.children.last.content).to match(/\/admin\/posts\?post_page=2/)
end
end
context "when specifying :params option" do
let(:collection) do
posts = 10.times.map{ Post.new }
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, param_name: :post_page, params: { anchor: 'here' }) }
it "should pass it through to Kaminari" do
expect(pagination.children.last.content).to match(/\/admin\/posts\?post_page=2#here/)
end
end
context "when specifying download_links: false option" do
let(:collection) do
posts = 10.times.map{ Post.new }
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, download_links: false) }
it "should not render download links" do
expect(pagination.find_by_tag('div').last.content).to_not match(/Download:/)
end
end
context "when specifying :entry_name option with a single item" do
let(:collection) do
posts = [Post.new]
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, entry_name: "message") }
it "should use :entry_name as the collection name" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying 1 message"
end
end
context "when specifying :entry_name option with multiple items" do
let(:pagination) { paginated_collection(collection, entry_name: "message") }
it "should use :entry_name as the collection name" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 3 messages"
end
end
context "when specifying :entry_name and :entries_name option with a single item" do
let(:collection) do
posts = [Post.new]
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, entry_name: "singular", entries_name: "plural") }
it "should use :entry_name as the collection name" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying 1 singular"
end
end
context "when specifying :entry_name and :entries_name option with a multiple items" do
let(:pagination) { paginated_collection(collection, entry_name: "singular", entries_name: "plural") }
it "should use :entries_name as the collection name" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 3 plural"
end
end
context "when omitting :entry_name with a single item" do
let(:collection) do
posts = [Post.new]
Kaminari.paginate_array(posts).page(1).per(5)
end
it "should use 'post' as the collection name when there is no I18n translation" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying 1 post"
end
it "should use 'Singular' as the collection name when there is an I18n translation" do
allow(I18n).to receive(:translate) { "Singular" }
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying 1 Singular"
end
end
context "when omitting :entry_name with multiple items" do
it "should use 'posts' as the collection name when there is no I18n translation" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 3 posts"
end
it "should use 'Plural' as the collection name when there is an I18n translation" do
allow(I18n).to receive(:translate) { "Plural" }
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 3 Plural"
end
end
context "when specifying an empty collection" do
let(:collection) do
posts = []
Kaminari.paginate_array(posts).page(1).per(5)
end
it "should display 'No entries found'" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "No entries found"
end
end
context "when collection comes from find with GROUP BY" do
let(:collection) do
%w{Foo Foo Bar}.each {|title| Post.create(title: title) }
Post.select(:title).group(:title).page(1).per(5)
end
it "should display proper message (including number and not hash)" do
expect(pagination.find_by_class('pagination_information').first.content).to eq "Displaying all 2 posts"
end
end
context "when collection with many pages comes from find with GROUP BY" do
let(:collection) do
%w{Foo Foo Bar Baz}.each {|title| Post.create(title: title) }
Post.select(:title).group(:title).page(1).per(2)
end
it "should display proper message (including number and not hash)" do
expect(pagination.find_by_class('pagination_information').first.content.gsub(' ', ' ')).
to eq "Displaying posts 1 - 2 of 3 in total"
end
end
context "when viewing the last page of a collection that has multiple pages" do
let(:collection) do
Kaminari.paginate_array([Post.new] * 81).page(3).per(30)
end
it "should show the proper item counts" do
expect(pagination.find_by_class('pagination_information').first.content.gsub(' ', ' ')).
to eq "Displaying posts 61 - 81 of 81 in total"
end
end
context "with :pagination_total" do
let(:collection) do
Kaminari.paginate_array([Post.new] * 256).page(1).per(30)
end
describe "set to false" do
it "should not show the total item counts" do
expect(collection).not_to receive(:total_pages)
pagination = paginated_collection(collection, pagination_total: false)
info = pagination.find_by_class('pagination_information').first.content.gsub(' ', ' ')
expect(info).to eq "Displaying posts 1 - 30"
end
end
describe "set to true" do
let(:pagination) { paginated_collection(collection, pagination_total: true) }
it "should show the total item counts" do
info = pagination.find_by_class('pagination_information').first.content.gsub(' ', ' ')
expect(info).to eq "Displaying posts 1 - 30 of 256 in total"
end
end
end
context "when specifying per_page: array option" do
let(:collection) do
posts = 10.times.map { Post.new }
Kaminari.paginate_array(posts).page(1).per(5)
end
let(:pagination) { paginated_collection(collection, per_page: [1, 2, 3]) }
let(:pagination_html) { pagination.find_by_class("pagination_per_page").first }
let(:pagination_node) { Capybara.string(pagination_html.to_s) }
it "should render per_page select tag" do
expect(pagination_html.content).to match(/Per page:/)
expect(pagination_node).to have_css("select option", count: 3)
end
end
end
end