Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix #202: Check that correct sort is passed to withSort() of keyset paginator #209

Merged
merged 4 commits into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
- Chg #163: Rename `FilterableDataInterface::withFilterHandlers()` to `FilterableDataInterface::withAddedFilterHandlers()` (@samdark)
- Enh #190: Use `str_contains` for case-sensitive match in `LikeHandler` (@samdark)
- Enh #194: Improve psalm annotations in `LimitableDataInterface` (@vjik)
- Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik)
- Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik)
- Enh #202: Check that correct sort is passed to `withSort()` of keyset paginator (@samdark)

## 1.0.1 January 25, 2023

Expand Down
13 changes: 10 additions & 3 deletions src/Paginator/KeysetPaginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Closure;
use InvalidArgumentException;
use RuntimeException;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\GreaterThan;
use Yiisoft\Data\Reader\Filter\GreaterThanOrEqual;
Expand Down Expand Up @@ -125,11 +124,11 @@ public function __construct(ReadableDataInterface $dataReader)
$sort = $dataReader->getSort();

if ($sort === null) {
throw new RuntimeException('Data sorting should be configured to work with keyset pagination.');
throw new InvalidArgumentException('Data sorting should be configured to work with keyset pagination.');
}

if (empty($sort->getOrder())) {
throw new RuntimeException('Data should be always sorted to work with keyset pagination.');
throw new InvalidArgumentException('Data should be always sorted to work with keyset pagination.');
}

$this->dataReader = $dataReader;
Expand Down Expand Up @@ -262,6 +261,14 @@ public function isSortable(): bool

public function withSort(?Sort $sort): static
{
if ($sort === null) {
throw new InvalidArgumentException('Data sorting should be configured to work with keyset pagination.');
}

if (empty($sort->getOrder())) {
throw new InvalidArgumentException('Data should be always sorted to work with keyset pagination.');
}

$new = clone $this;
$new->dataReader = $this->dataReader->withSort($sort);
return $new;
Expand Down
26 changes: 24 additions & 2 deletions tests/Paginator/KeysetPaginatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,23 +149,45 @@ public function testThrowsExceptionWhenReaderHasNoSort(): void
{
$dataReader = new IterableDataReader(self::getDataSet());

$this->expectException(RuntimeException::class);
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Data sorting should be configured to work with keyset pagination.');

new KeysetPaginator($dataReader);
}

public function testThrowsExceptionForWithSortNull(): void
{
$sort = Sort::only(['id', 'name'])->withOrderString('id');
$dataReader = (new IterableDataReader(self::getDataSet()))->withSort($sort);

$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Data sorting should be configured to work with keyset pagination.');

(new KeysetPaginator($dataReader))->withSort(null);
}

public function testThrowsExceptionWhenNotSorted(): void
{
$sort = Sort::only(['id', 'name']);
$dataReader = (new IterableDataReader(self::getDataSet()))->withSort($sort);

$this->expectException(RuntimeException::class);
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Data should be always sorted to work with keyset pagination.');

new KeysetPaginator($dataReader);
}

public function testThrowsExceptionForWithSortNotSorted(): void
{
$sort = Sort::only(['id', 'name'])->withOrderString('id');
$dataReader = (new IterableDataReader(self::getDataSet()))->withSort($sort);

$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Data should be always sorted to work with keyset pagination.');

(new KeysetPaginator($dataReader))->withSort(Sort::only(['id', 'name']));
}

public function testPageSizeCannotBeLessThanOne(): void
{
$sort = Sort::only(['id', 'name'])->withOrderString('id');
Expand Down
Loading