Skip to content

Commit

Permalink
Merge branch 'master' into disable-sort-when-limit-is-explicit
Browse files Browse the repository at this point in the history
  • Loading branch information
vjik authored Oct 19, 2024
2 parents f6439d4 + 8739893 commit beec83f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- Bug #195: Fix invalid count in `IterableDataReader` when limit or/and offset used (@vjik)
- Enh #201: Disable sorting when limit is set explicitly in a paginator, use `InvalidArgumentException` when sorting
is supplied in this case (@samdark)
- Enh #202: Check that correct sort is passed to `withSort()` of keyset paginator (@samdark)
- Enh #207: More secific Psalm type for OffsetPaginator::withCurrentPage() (@samdark)

## 1.0.1 January 25, 2023
Expand Down
23 changes: 14 additions & 9 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 @@ -123,14 +122,7 @@ public function __construct(ReadableDataInterface $dataReader)
}

$sort = $dataReader->getSort();

if ($sort === null) {
throw new RuntimeException('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.');
}
$this->assertSort($sort);

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

public function withSort(?Sort $sort): static
{
$this->assertSort($sort);

$new = clone $this;
$new->dataReader = $this->dataReader->withSort($sort);
return $new;
Expand Down Expand Up @@ -440,4 +434,15 @@ private function getFieldAndSortingFromSort(Sort $sort): array
reset($order) === 'asc' ? SORT_ASC : SORT_DESC,
];
}

private function assertSort(?Sort $sort): void
{
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.');
}
}
}
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

0 comments on commit beec83f

Please sign in to comment.