mirror of
https://github.com/nextcloud/server.git
synced 2026-11-04 22:17:32 +01:00
138 lines
5.1 KiB
PHP
138 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
/**
|
|
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
namespace Test\AppFramework\Http;
|
|
|
|
use OC\AppFramework\Http\PaginationTrait;
|
|
use OCP\IRequest;
|
|
use OCP\IURLGenerator;
|
|
use Test\TestCase;
|
|
|
|
class PaginationTraitTest extends TestCase {
|
|
private IRequest&\PHPUnit\Framework\MockObject\MockObject $request;
|
|
private IURLGenerator&\PHPUnit\Framework\MockObject\MockObject $urlGenerator;
|
|
private object $subject;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->request = $this->createMock(IRequest::class);
|
|
$this->urlGenerator = $this->createMock(IURLGenerator::class);
|
|
|
|
$this->subject = new class($this->request, $this->urlGenerator) {
|
|
use PaginationTrait;
|
|
|
|
public function __construct(
|
|
protected IRequest $request,
|
|
private IURLGenerator $urlGenerator,
|
|
) {
|
|
}
|
|
|
|
public function hasMore(array $items, ?int $limit): bool {
|
|
return $this->hasMoreResults($items, $limit);
|
|
}
|
|
|
|
public function nextLinkHeaders(array|bool $items, array $params, ?int $limit, int $offset, ?int $forceOffset = null): array {
|
|
return $this->buildOffsetNextPageLinkHeader($items, $params, $limit, $offset, $forceOffset);
|
|
}
|
|
|
|
public function cursorLinkHeaders(array|bool $items, array $params, ?int $limit, int|string|null $lastId): array {
|
|
return $this->buildCursorNextPageLinkHeader($items, $params, $limit, $lastId);
|
|
}
|
|
};
|
|
}
|
|
|
|
public function testNullLimitNeverReportsMore(): void {
|
|
$this->assertFalse($this->subject->hasMore(['a', 'b', 'c'], null));
|
|
}
|
|
|
|
public function testZeroLimitNeverReportsMore(): void {
|
|
$this->assertFalse($this->subject->hasMore([], 0));
|
|
}
|
|
|
|
public function testFewerResultsThanLimitReportsNoMore(): void {
|
|
$this->assertFalse($this->subject->hasMore(['a', 'b'], 5));
|
|
}
|
|
|
|
public function testExactlyLimitResultsReportsMore(): void {
|
|
$this->assertTrue($this->subject->hasMore(['a', 'b', 'c'], 3));
|
|
}
|
|
|
|
public function testEmptyResultWithPositiveLimitReportsNoMore(): void {
|
|
$this->assertFalse($this->subject->hasMore([], 5));
|
|
}
|
|
|
|
public function testAssociativeArrayIsCountedByEntries(): void {
|
|
$this->assertTrue($this->subject->hasMore(['uid1' => 'Alice', 'uid2' => 'Bob'], 2));
|
|
}
|
|
|
|
public function testNextLinkKeepsRequestPathAndAppliesGivenQuery(): void {
|
|
$this->request->method('getRequestUri')->willReturn('/ocs/v2.php/apps/provisioning_api/api/v1/groups?search=foo&limit=5&offset=0');
|
|
|
|
$this->urlGenerator->method('getAbsoluteURL')
|
|
->with('/ocs/v2.php/apps/provisioning_api/api/v1/groups')
|
|
->willReturn('https://cloud.example.com/ocs/v2.php/apps/provisioning_api/api/v1/groups');
|
|
|
|
$headers = $this->subject->nextLinkHeaders(['a', 'b', 'c', 'd', 'e'], ['search' => 'foo'], 5, 0);
|
|
|
|
$this->assertSame([
|
|
'Link' => '<https://cloud.example.com/ocs/v2.php/apps/provisioning_api/api/v1/groups?search=foo&limit=5&offset=5>; rel="next"',
|
|
], $headers);
|
|
}
|
|
|
|
public function testNextLinkUsesForcedOffset(): void {
|
|
$this->request->method('getRequestUri')->willReturn('/ocs/v2.php/cloud/users/details?limit=5&offset=10');
|
|
$this->urlGenerator->method('getAbsoluteURL')
|
|
->with('/ocs/v2.php/cloud/users/details')
|
|
->willReturn('https://cloud.example.com/ocs/v2.php/cloud/users/details');
|
|
|
|
$headers = $this->subject->nextLinkHeaders(true, ['enabled' => 1], 5, 10, 23);
|
|
|
|
$this->assertSame([
|
|
'Link' => '<https://cloud.example.com/ocs/v2.php/cloud/users/details?enabled=1&limit=5&offset=23>; rel="next"',
|
|
], $headers);
|
|
}
|
|
|
|
public function testNextLinkReturnsEmptyHeadersWhenFewerItemsThanLimit(): void {
|
|
$this->assertSame([], $this->subject->nextLinkHeaders(['a', 'b'], ['search' => 'foo'], 5, 0));
|
|
}
|
|
|
|
public function testNextLinkAcceptsAPrecomputedBool(): void {
|
|
$this->assertSame([], $this->subject->nextLinkHeaders(false, ['search' => 'foo'], 5, 0));
|
|
|
|
$this->request->method('getRequestUri')->willReturn('/ocs/v2.php/core/autocomplete/get');
|
|
$this->urlGenerator->method('getAbsoluteURL')
|
|
->with('/ocs/v2.php/core/autocomplete/get')
|
|
->willReturn('https://cloud.example.com/ocs/v2.php/core/autocomplete/get');
|
|
|
|
$this->assertArrayHasKey('Link', $this->subject->nextLinkHeaders(true, ['search' => 'foo'], 5, 0));
|
|
}
|
|
|
|
public function testCursorLinkKeepsRequestPathAndUsesLastId(): void {
|
|
$this->request->method('getRequestUri')->willReturn('/ocs/v2.php/apps/user_status/api/v1/statuses?limit=1&lastId=1336');
|
|
|
|
$this->urlGenerator->method('getAbsoluteURL')
|
|
->with('/ocs/v2.php/apps/user_status/api/v1/statuses')
|
|
->willReturn('https://cloud.example.com/ocs/v2.php/apps/user_status/api/v1/statuses');
|
|
|
|
$headers = $this->subject->cursorLinkHeaders(['a'], [], 1, 1337);
|
|
|
|
$this->assertSame([
|
|
'Link' => '<https://cloud.example.com/ocs/v2.php/apps/user_status/api/v1/statuses?limit=1&lastId=1337>; rel="next"',
|
|
], $headers);
|
|
}
|
|
|
|
public function testCursorLinkReturnsEmptyHeadersWhenFewerItemsThanLimit(): void {
|
|
$this->assertSame([], $this->subject->cursorLinkHeaders(['a', 'b'], [], 5, 1337));
|
|
}
|
|
|
|
public function testCursorLinkReturnsEmptyHeadersWhenLastIdIsMissing(): void {
|
|
$this->assertSame([], $this->subject->cursorLinkHeaders(['a'], [], 1, null));
|
|
}
|
|
}
|