pagination: refactor to avoid counting pages in API.

Previously the page-based (numbered) paginator would always count the
total_pages, even in API calls when it wasn't needed. This could be very
slow in some cases. Refactor so that total_pages isn't calculated unless
it's called.

While we're at it, refactor to condense all the sequential vs. numbered
pagination logic into one module. This incidentally fixes a couple more
bugs:

* "page=b0" returned all pages rather than nothing.
* Bad parameters like "page=blaha123" and "page=a123blah" were accepted.
This commit is contained in:
evazion
2019-10-07 20:41:41 -05:00
parent e1f37113b3
commit 93dd952949
12 changed files with 131 additions and 182 deletions

View File

@@ -12,6 +12,11 @@ class PaginatorTest < ActiveSupport::TestCase
assert_equal(expected_posts.map(&:id), posts.map(&:id))
end
should "return nothing for b0" do
posts = Post.paginate("b0")
assert_empty(posts.map(&:id))
end
end
context "sequential pagination (after)" do
@@ -30,5 +35,30 @@ class PaginatorTest < ActiveSupport::TestCase
assert_equal(expected_posts.map(&:id), posts.map(&:id))
end
should "raise an error when exceeding the page limit" do
Danbooru.config.stubs(:max_numbered_pages).returns(5)
assert_raises(PaginationExtension::PaginationError) do
Post.paginate(10)
end
end
should "count pages correctly" do
assert_equal(5, Post.paginate(1, limit: 1).total_pages)
assert_equal(3, Post.paginate(1, limit: 2).total_pages)
assert_equal(2, Post.paginate(1, limit: 3).total_pages)
assert_equal(2, Post.paginate(1, limit: 4).total_pages)
assert_equal(1, Post.paginate(1, limit: 5).total_pages)
end
should "detect the first and last page correctly" do
assert(Post.paginate(0, limit: 1).is_first_page?)
assert(Post.paginate(1, limit: 1).is_first_page?)
refute(Post.paginate(1, limit: 1).is_last_page?)
refute(Post.paginate(5, limit: 1).is_first_page?)
assert(Post.paginate(5, limit: 1).is_last_page?)
assert(Post.paginate(6, limit: 1).is_last_page?)
end
end
end

View File

@@ -1,5 +1,4 @@
require 'test_helper'
require "danbooru/paginator/pagination_error"
module PostSets
class IntroTest < ActiveSupport::TestCase

View File

@@ -1,5 +1,4 @@
require 'test_helper'
require "danbooru/paginator/pagination_error"
module PostSets
class PostTest < ActiveSupport::TestCase
@@ -86,7 +85,7 @@ module PostSets
end
should "fail" do
assert_raises(Danbooru::Paginator::PaginationError) do
assert_raises(PaginationExtension::PaginationError) do
@set.posts
end
end