From 886a0d70be5c346c51f01c451041f8c0c7909fb0 Mon Sep 17 00:00:00 2001 From: JonPurvis Date: Sun, 8 Mar 2026 00:22:08 +0000 Subject: [PATCH] reset body checksums on rewind to fix false infinite-loop on multiple collect() --- src/Paginator.php | 1 + tests/Feature/CollectTest.php | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Paginator.php b/src/Paginator.php index deb5e6a..22d3374 100644 --- a/src/Paginator.php +++ b/src/Paginator.php @@ -212,6 +212,7 @@ public function valid(): bool */ public function rewind(): void { + $this->lastFiveBodyChecksums = []; $this->currentPage = max(0, $this->startPage - 1); $this->page = $this->startPage; $this->currentResponse = null; diff --git a/tests/Feature/CollectTest.php b/tests/Feature/CollectTest.php index a6c3586..2f955a8 100644 --- a/tests/Feature/CollectTest.php +++ b/tests/Feature/CollectTest.php @@ -4,6 +4,8 @@ use Saloon\Http\Response; use Illuminate\Support\Collection; +use Saloon\Http\Faking\MockClient; +use Saloon\Http\Faking\MockResponse; use Saloon\PaginationPlugin\Tests\Fixtures\Connectors\PagedConnector; use Saloon\PaginationPlugin\Tests\Fixtures\Requests\SuperheroPagedRequest; @@ -29,3 +31,38 @@ function toIds(array $items): array expect($paginator->getTotalResults())->toEqual(20); }); + +/** + * @see https://github.com/saloonphp/saloon/issues/464 + */ +test('multiple collect calls on same LazyCollection do not trigger infinite loop detection', function () { + $singlePageResponse = [ + 'data' => [['id' => 1], ['id' => 2]], + 'next_page_url' => null, + ]; + + $connector = new PagedConnector; + $connector->withMockClient(new MockClient([ + MockResponse::make($singlePageResponse), + MockResponse::make($singlePageResponse), + MockResponse::make($singlePageResponse), + MockResponse::make($singlePageResponse), + MockResponse::make($singlePageResponse), + MockResponse::make($singlePageResponse), + ])); + + $request = new SuperheroPagedRequest; + $lazyCollection = $connector->paginate($request)->collect(); + + $first = $lazyCollection->collect(); + expect($first)->toBeInstanceOf(Collection::class); + expect($first->pluck('id')->all())->toBe([1, 2]); + + $lazyCollection->collect(); + $lazyCollection->collect(); + $lazyCollection->collect(); + $lazyCollection->collect(); + + $again = $lazyCollection->collect(); + expect($again->pluck('id')->all())->toBe([1, 2]); +});