Skip to content

Commit

Permalink
fix: handle key column not present in pagination cursor (#41)
Browse files Browse the repository at this point in the history
* fix: keyName column may not be present in pagination cursor
* test: add test to cover with Id Encoding combined with withoutKeySort behaviour

---------

Co-authored-by: Gregory Haddow <[email protected]>
  • Loading branch information
haddowg and Gregory Haddow authored Oct 31, 2024
1 parent 6e79095 commit 30f153f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/Pagination/Cursor/CursorParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ public function __construct(private IdParser $idParser, private string $keyName)
*/
public function encode(LaravelCursor $cursor): string
{
$key = $cursor->parameter($this->keyName);

if ($key) {
try {
$key = $cursor->parameter($this->keyName);
$parameters = $this->withoutPrivate($cursor->toArray());
$parameters[$this->keyName] = $this->idParser->encode($key);
$cursor = new LaravelCursor($parameters, $cursor->pointsToNextItems());
} catch (\UnexpectedValueException $ex) {
// Do nothing as the cursor does not contain the key.
}

return $cursor->encode();
Expand Down
51 changes: 51 additions & 0 deletions tests/lib/Acceptance/Pagination/CursorPaginationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,57 @@ public function testWithoutCursor(): void
$this->assertPage($posts->reverse()->take(3), $page);
}

/**
* @return void
*/
public function testWithIdEncodingWithoutKeySort(): void
{
$this->withIdEncoding();
$this->paginator->withoutKeySort();

$posts = Post::factory()->count(4)->sequence(['title' => 'd'], ['title' => 'c'], ['title' => 'b'], ['title' => 'a'])->create();

$meta = [
'from' => $this->encodeCursor(
["posts.title"=> "a"],
pointsToNextItems: false,
),
'hasMore' => true,
'perPage' => 3,
'to' => $this->encodeCursor(
["posts.title"=> "c"],
pointsToNextItems: true,
),
];

$links = [
'first' => [
'href' => 'http://localhost/api/v1/posts?' . Arr::query([
'page' => ['limit' => '3'],
'sort' => 'title',
]),
],
'next' => [
'href' => 'http://localhost/api/v1/posts?' . Arr::query([
'page' => [
'after' => $this->encodeCursor(
["posts.title"=> "c"],
pointsToNextItems: true,
),
'limit' => '3',
],
'sort' => 'title',
]),
],
];

$page = $this->posts->repository()->queryAll()->sort('title')->paginate(['limit' => '3']);

$this->assertSame(['page' => $meta], $page->meta());
$this->assertSame($links, $page->links()->toArray());
$this->assertPage($posts->reverse()->take(3), $page);
}

/**
* @return void
*/
Expand Down

0 comments on commit 30f153f

Please sign in to comment.