forked from Shopify/maintenance_tasks
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce RunsPage model to handle cursor-based pagination of runs
- Loading branch information
1 parent
6cde08a
commit e046c03
Showing
5 changed files
with
139 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# frozen_string_literal: true | ||
module MaintenanceTasks | ||
# This class is responsible for handling cursor-based pagination for Run | ||
# records. | ||
# | ||
# @api private | ||
class RunsPage | ||
# The number of Runs to show on a single Task page. | ||
RUNS_PER_PAGE = 20 | ||
|
||
# Initializes a Runs Page with a Runs relation and a cursor. This page is | ||
# used by the views to render a set of Runs. | ||
# @param runs [ActiveRecord::Relation<MaintenanceTasks::Run>] the relation | ||
# of Run records to be paginated. | ||
# @param cursor [String, nil] the id that serves as the cursor when | ||
# querying the Runs dataset to produce a page of Runs. If nil, the first | ||
# Runs in the relation are used. | ||
def initialize(runs, cursor) | ||
@runs = runs | ||
@cursor = cursor | ||
end | ||
|
||
# Returns the records for a Page, taking into account the cursor if one is | ||
# present. Limits the number of records to 20. | ||
# | ||
# @return [ActiveRecord::Relation<MaintenanceTasks::Run>] a limited amount | ||
# of Run records. | ||
def records | ||
runs_after_cursor = if @cursor.present? | ||
@runs.where('id < ?', @cursor) | ||
else | ||
@runs | ||
end | ||
runs_after_cursor.limit(RUNS_PER_PAGE) | ||
end | ||
|
||
# Returns the cursor to use for the next Page of Runs. It is the id of the | ||
# last record on the current Page. | ||
# | ||
# @return [Integer] the id of the last record for the Page. | ||
def next_cursor | ||
records.last.id | ||
end | ||
|
||
# Returns whether this Page is the last one. | ||
# | ||
# @return [Boolean] whether this Page contains the last Run record in the | ||
# Runs dataset that is being paginated. | ||
def last? | ||
@runs.last == records.last | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'test_helper' | ||
|
||
module MaintenanceTasks | ||
class RunsPageTest < ActiveSupport::TestCase | ||
setup do | ||
@task_name = 'Maintenance::TestTask' | ||
21.times do | ||
Run.create!( | ||
task_name: @task_name, | ||
started_at: Time.now, | ||
tick_count: 10, | ||
tick_total: 10, | ||
status: :succeeded, | ||
ended_at: Time.now | ||
) | ||
end | ||
@runs = Run.where(task_name: @task_name).order(created_at: :desc) | ||
end | ||
|
||
test '#records returns the most recent 20 runs when there is no cursor' do | ||
runs_page = RunsPage.new(@runs, nil) | ||
assert_equal @runs.first(20), runs_page.records | ||
end | ||
|
||
test '#records returns 20 runs after cursor if one is present' do | ||
runs_page = RunsPage.new(@runs, @runs.first.id) | ||
assert_equal @runs.last(20), runs_page.records | ||
end | ||
|
||
test '#next_cursor returns the id of the last run in the record set' do | ||
last_id = @runs.last.id | ||
runs_page = RunsPage.new(@runs, @runs.first.id) | ||
assert_equal last_id, runs_page.next_cursor | ||
end | ||
|
||
test '#last? returns true if the last run in the record set is the last run for the relation' do | ||
runs_page = RunsPage.new(@runs, @runs.first.id) | ||
assert_predicate runs_page, :last? | ||
end | ||
|
||
test '#last? returns false if the last run in the record set is not the last run for the relation' do | ||
runs_page = RunsPage.new(@runs, nil) | ||
refute_predicate runs_page, :last? | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters