From 7a953cf60af7a1ad593d1030b806e197babb21c5 Mon Sep 17 00:00:00 2001 From: Tom H Anderson Date: Fri, 10 Jan 2025 15:27:57 -0700 Subject: [PATCH] fixed hasPreviousPage --- src/Resolve/ResolveCollectionFactory.php | 13 ++++-- src/Resolve/ResolveEntityFactory.php | 13 ++++-- test/Feature/Type/PaginationTest.php | 59 +++++++++++++++++++++--- 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/Resolve/ResolveCollectionFactory.php b/src/Resolve/ResolveCollectionFactory.php index e208f44..6c4f4ab 100644 --- a/src/Resolve/ResolveCollectionFactory.php +++ b/src/Resolve/ResolveCollectionFactory.php @@ -193,8 +193,7 @@ protected function buildPagination( 'endCursor' => $edgesAndCursors['cursors']['last'], 'startCursor' => $edgesAndCursors['cursors']['start'], 'hasNextPage' => $edgesAndCursors['cursors']['end'] !== $edgesAndCursors['cursors']['last'], - 'hasPreviousPage' => $edgesAndCursors['cursors']['first'] !== null - && $edgesAndCursors['cursors']['start'] !== $edgesAndCursors['cursors']['first'], + 'hasPreviousPage' => $edgesAndCursors['cursors']['start'] !== base64_encode((string) 0), ], ]; } @@ -215,6 +214,7 @@ protected function buildEdgesAndCursors(Collection $items, array $offsetAndLimit 'start' => base64_encode((string) 0), ]; + $startCursor = null; foreach ($items as $item) { $cursors['last'] = base64_encode((string) ($index + $offsetAndLimit['offset'])); @@ -223,6 +223,10 @@ protected function buildEdgesAndCursors(Collection $items, array $offsetAndLimit 'cursor' => $cursors['last'], ]; + if (! $startCursor) { + $startCursor = $cursors['last']; + } + if (! $cursors['first']) { $cursors['first'] = $cursors['last']; } @@ -230,8 +234,9 @@ protected function buildEdgesAndCursors(Collection $items, array $offsetAndLimit $index++; } - $endIndex = $itemCount ? $itemCount - 1 : 0; - $cursors['end'] = base64_encode((string) $endIndex); + $endIndex = $itemCount ? $itemCount - 1 : 0; + $cursors['end'] = base64_encode((string) $endIndex); + $cursors['start'] = $startCursor ?? $cursors['start']; return [ 'cursors' => $cursors, diff --git a/src/Resolve/ResolveEntityFactory.php b/src/Resolve/ResolveEntityFactory.php index 95ee87f..94e01a7 100644 --- a/src/Resolve/ResolveEntityFactory.php +++ b/src/Resolve/ResolveEntityFactory.php @@ -123,8 +123,7 @@ public function buildPagination( 'endCursor' => $edgesAndCursors['cursors']['last'], 'startCursor' => $edgesAndCursors['cursors']['start'], 'hasNextPage' => $edgesAndCursors['cursors']['end'] !== $edgesAndCursors['cursors']['last'], - 'hasPreviousPage' => $edgesAndCursors['cursors']['first'] !== null - && $edgesAndCursors['cursors']['start'] !== $edgesAndCursors['cursors']['first'], + 'hasPreviousPage' => $edgesAndCursors['cursors']['start'] !== base64_encode((string) 0), ], ]; } @@ -155,6 +154,7 @@ protected function buildEdgesAndCursors(QueryBuilder $queryBuilder, array $offse $paginator = new Paginator($queryBuilder->getQuery()); } + $startCursor = null; foreach ($paginator->getQuery()->getResult() as $result) { $cursors['last'] = base64_encode((string) ($index + $offsetAndLimit['offset'])); @@ -163,6 +163,10 @@ protected function buildEdgesAndCursors(QueryBuilder $queryBuilder, array $offse 'cursor' => $cursors['last'], ]; + if (! $startCursor) { + $startCursor = $cursors['last']; + } + if (! $cursors['first']) { $cursors['first'] = $cursors['last']; } @@ -170,8 +174,9 @@ protected function buildEdgesAndCursors(QueryBuilder $queryBuilder, array $offse $index++; } - $endIndex = $paginator->count() ? $paginator->count() - 1 : 0; - $cursors['end'] = base64_encode((string) $endIndex); + $endIndex = $paginator->count() ? $paginator->count() - 1 : 0; + $cursors['end'] = base64_encode((string) $endIndex); + $cursors['start'] = $startCursor ?? $cursors['start']; return [ 'cursors' => $cursors, diff --git a/test/Feature/Type/PaginationTest.php b/test/Feature/Type/PaginationTest.php index 57f8cad..50b46d4 100644 --- a/test/Feature/Type/PaginationTest.php +++ b/test/Feature/Type/PaginationTest.php @@ -23,13 +23,13 @@ public function testFirst(): void 'query' => new ObjectType([ 'name' => 'query', 'fields' => [ - 'performance' => $driver->completeConnection(Performance::class), + 'performances' => $driver->completeConnection(Performance::class), ], ]), ]); $query = '{ - performance (pagination: { first: 2 }) { + performances (pagination: { first: 2 }) { pageInfo { hasNextPage hasPreviousPage @@ -48,10 +48,54 @@ public function testFirst(): void $data = $result->toArray()['data']; - $this->assertEquals($data['performance']['pageInfo']['startCursor'], $data['performance']['edges'][0]['cursor']); - $this->assertEquals($data['performance']['pageInfo']['endCursor'], $data['performance']['edges'][1]['cursor']); + $this->assertEquals($data['performances']['pageInfo']['startCursor'], $data['performances']['edges'][0]['cursor']); + $this->assertEquals($data['performances']['pageInfo']['endCursor'], $data['performances']['edges'][1]['cursor']); - $this->assertEquals(2, count($data['performance']['edges'])); + $this->assertTrue($data['performances']['pageInfo']['hasNextPage']); + $this->assertFalse($data['performances']['pageInfo']['hasPreviousPage']); + + $this->assertEquals(2, count($data['performances']['edges'])); + } + + public function testFirstWithOffset(): void + { + $driver = new Driver($this->getEntityManager()); + $schema = new Schema([ + 'query' => new ObjectType([ + 'name' => 'query', + 'fields' => [ + 'performances' => $driver->completeConnection(Performance::class), + ], + ]), + ]); + + $query = '{ + performances (pagination: { first: 2 after: "MQ==" }) { + pageInfo { + hasNextPage + hasPreviousPage + startCursor + endCursor + } + edges { + cursor + node { + id + } + } + } + }'; + $result = GraphQL::executeQuery($schema, $query); + + $data = $result->toArray()['data']; + + $this->assertEquals($data['performances']['pageInfo']['startCursor'], $data['performances']['edges'][0]['cursor']); + $this->assertEquals($data['performances']['pageInfo']['endCursor'], $data['performances']['edges'][1]['cursor']); + + $this->assertTrue($data['performances']['pageInfo']['hasNextPage']); + $this->assertTrue($data['performances']['pageInfo']['hasPreviousPage']); + + $this->assertEquals(2, count($data['performances']['edges'])); } public function testCollectionFirst(): void @@ -72,7 +116,7 @@ public function testCollectionFirst(): void cursor node { id - performances (pagination: { first: 2 }) { + performances (pagination: { first: 2 after: "MQ==" }) { pageInfo { hasNextPage hasPreviousPage @@ -103,6 +147,9 @@ public function testCollectionFirst(): void $data['artists']['edges'][0]['node']['performances']['edges'][1]['cursor'], ); + $this->assertTrue($data['artists']['edges'][0]['node']['performances']['pageInfo']['hasNextPage']); + $this->assertTrue($data['artists']['edges'][0]['node']['performances']['pageInfo']['hasPreviousPage']); + $this->assertEquals(2, count($data['artists']['edges'][0]['node']['performances']['edges'])); }