PHP Classes

File: tests/Unit/Data/PayrexCursorPaginatorTest.php

Recommend this page to a friend!
  Packages of Daryl Legion   PayRex Laravel   tests/Unit/Data/PayrexCursorPaginatorTest.php   Download  
File: tests/Unit/Data/PayrexCursorPaginatorTest.php
Role: Example script
Content type: text/plain
Description: Example script
Class: PayRex Laravel
Request payments using the PayRex service
Author: By
Last change:
Date: 12 days ago
Size: 5,383 bytes
 

Contents

Class file image Download
<?php

declare(strict_types=1);

use
Illuminate\Pagination\Cursor;
use
LegionHQ\LaravelPayrex\Data\PayrexCursorPaginator;
use
LegionHQ\LaravelPayrex\Data\PayrexObject;

it('uses the API has_more flag instead of item count', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
       
PayrexObject::from(['id' => 'obj_2']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 2, apiHasMore: true);

   
expect($paginator->hasMorePages())->toBeTrue()
        ->
and($paginator->items())->toHaveCount(2);
});

it('reports no more pages when API says has_more is false', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 10, apiHasMore: false);

   
expect($paginator->hasMorePages())->toBeFalse();
});

it('generates next cursor from the last item id', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
       
PayrexObject::from(['id' => 'obj_2']),
       
PayrexObject::from(['id' => 'obj_3']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 3, apiHasMore: true);

   
$nextCursor = $paginator->nextCursor();

   
expect($nextCursor)->not->toBeNull()
        ->
and($nextCursor->parameter('id'))->toBe('obj_3')
        ->
and($nextCursor->pointsToNextItems())->toBeTrue();
});

it('returns null next cursor when no more pages', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 10, apiHasMore: false);

   
expect($paginator->nextCursor())->toBeNull();
});

it('generates previous cursor from the first item id when navigating forward', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_4']),
       
PayrexObject::from(['id' => 'obj_5']),
    ];

   
$cursor = new Cursor(['id' => 'obj_3'], pointsToNextItems: true);
   
$paginator = new PayrexCursorPaginator($items, 2, apiHasMore: true, cursor: $cursor);

   
$prevCursor = $paginator->previousCursor();

   
expect($prevCursor)->not->toBeNull()
        ->
and($prevCursor->parameter('id'))->toBe('obj_4')
        ->
and($prevCursor->pointsToPreviousItems())->toBeTrue();
});

it('returns null previous cursor on the first page', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 10, apiHasMore: false);

   
expect($paginator->previousCursor())->toBeNull();
});

it('serializes to the expected array structure', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
       
PayrexObject::from(['id' => 'obj_2']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 2, apiHasMore: true);
   
$array = $paginator->toArray();

   
expect($array)->toHaveKeys(['data', 'path', 'per_page', 'next_cursor', 'next_page_url', 'prev_cursor', 'prev_page_url'])
        ->
and($array['per_page'])->toBe(2)
        ->
and($array['next_cursor'])->not->toBeNull()
        ->
and($array['prev_cursor'])->toBeNull();
});

it('handles empty items', function () {
   
$paginator = new PayrexCursorPaginator([], 10, apiHasMore: false);

   
expect($paginator->items())->toHaveCount(0)
        ->
and($paginator->hasMorePages())->toBeFalse()
        ->
and($paginator->nextCursor())->toBeNull();
});

it('does not slice items like the base CursorPaginator', function () {
   
// Base CursorPaginator fetches perPage+1 items and slices. Ours should keep all items.
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
       
PayrexObject::from(['id' => 'obj_2']),
       
PayrexObject::from(['id' => 'obj_3']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 3, apiHasMore: true);

   
expect($paginator->items())->toHaveCount(3);
});

it('appends query parameters to pagination URLs', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 1, apiHasMore: true, options: ['path' => '/customers']);
   
$paginator->appends(['limit' => 5, 'name' => 'Juan']);

   
$nextUrl = $paginator->nextPageUrl();

   
expect($nextUrl)->toContain('/customers')
        ->
and($nextUrl)->toContain('limit=5')
        ->
and($nextUrl)->toContain('name=Juan')
        ->
and($nextUrl)->toContain('cursor=');
});

it('defaults path to root when no path option provided', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 1, apiHasMore: true);

   
expect($paginator->path())->toBe('/');
});

it('accepts a custom path via options', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$paginator = new PayrexCursorPaginator($items, 1, apiHasMore: true, options: ['path' => '/api/customers']);

   
expect($paginator->path())->toBe('/api/customers');
});

it('reverses items when cursor points to previous items', function () {
   
$items = [
       
PayrexObject::from(['id' => 'obj_3']),
       
PayrexObject::from(['id' => 'obj_2']),
       
PayrexObject::from(['id' => 'obj_1']),
    ];

   
$cursor = new Cursor(['id' => 'obj_4'], pointsToNextItems: false);
   
$paginator = new PayrexCursorPaginator($items, 3, apiHasMore: false, cursor: $cursor);

   
$ids = collect($paginator->items())->map(fn ($item) => $item->id)->all();

   
expect($ids)->toBe(['obj_1', 'obj_2', 'obj_3']);
});