diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index b0f323f..821d2bf 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1,11 +1,2 @@
-
-
-
- object
-
-
- $locator()
-
-
-
+
diff --git a/psalm.xml b/psalm.xml
index c090de7..1015d2f 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,5 +1,8 @@
diff --git a/src/Api.php b/src/Api.php
index f596653..4f9dc05 100644
--- a/src/Api.php
+++ b/src/Api.php
@@ -8,6 +8,7 @@
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Prismic\Document\Fragment\DocumentLink;
+use Prismic\Exception\InvalidArgument;
use Prismic\Exception\InvalidPreviewToken;
use Prismic\Exception\JsonError;
use Prismic\Exception\PrismicError;
@@ -121,44 +122,64 @@ public static function get(
?ResultSetFactory $resultSetFactory = null,
?CacheItemPoolInterface $cache = null
): self {
- /**
- * @return ClientInterface|RequestFactoryInterface|UriFactoryInterface
- */
- $factory = static function (?object $given, callable $locator, string $message): object {
- if ($given) {
- return $given;
- }
-
- /** @psalm-suppress InvalidCatch */
- try {
- return $locator();
- } catch (DiscoveryError $error) {
- throw new RuntimeError(
- $message,
- (int) $error->getCode(),
- $error
- );
- }
- };
-
- /** @psalm-suppress ArgumentTypeCoercion */
+ /** @psalm-suppress PossiblyInvalidArgument */
return new self(
$apiBaseUri,
- $factory($httpClient, static function (): ClientInterface {
- return Psr18ClientDiscovery::find();
- }, 'An HTTP client cannot be determined.'),
+ $httpClient ?? self::psrFactory(
+ ClientInterface::class,
+ 'An HTTP client cannot be determined.'
+ ),
(string) $accessToken === '' ? null : $accessToken,
- $factory($requestFactory, static function (): RequestFactoryInterface {
- return Psr17FactoryDiscovery::findRequestFactory();
- }, 'A request factory cannot be determined'),
- $factory($uriFactory, static function (): UriFactoryInterface {
- return Psr17FactoryDiscovery::findUriFactory();
- }, 'A URI factory cannot be determined'),
+ $requestFactory ?? self::psrFactory(
+ RequestFactoryInterface::class,
+ 'A request factory cannot be determined'
+ ),
+ $uriFactory ?? self::psrFactory(
+ UriFactoryInterface::class,
+ 'A URI factory cannot be determined'
+ ),
$resultSetFactory ?? new StandardResultSetFactory(),
$cache
);
}
+ /**
+ * phpcs:disable Generic.Files.LineLength.TooLong, Squiz.Commenting.FunctionComment.SpacingAfterParamType
+ * @param T|null $instance
+ * @param class-string|class-string|class-string $type
+ *
+ * @return ClientInterface|RequestFactoryInterface|UriFactoryInterface
+ *
+ * @template T of object
+ */
+ private static function psrFactory(string $type, string $message)
+ {
+ try {
+ switch ($type) {
+ case ClientInterface::class:
+ return Psr18ClientDiscovery::find();
+
+ case RequestFactoryInterface::class:
+ return Psr17FactoryDiscovery::findRequestFactory();
+
+ case UriFactoryInterface::class:
+ return Psr17FactoryDiscovery::findUriFactory();
+
+ default:
+ throw new InvalidArgument(sprintf(
+ 'Invalid class-string: "%s"',
+ $type
+ ));
+ }
+ } catch (DiscoveryError $error) {
+ throw new RuntimeError(
+ $message,
+ (int) $error->getCode(),
+ $error
+ );
+ }
+ }
+
public function host(): string
{
return $this->baseUri->getHost();
diff --git a/src/ApiClient.php b/src/ApiClient.php
index 89eeec4..ba0e46f 100644
--- a/src/ApiClient.php
+++ b/src/ApiClient.php
@@ -30,6 +30,11 @@ interface ApiClient
*/
public const EXPERIMENTS_COOKIE = 'io.prismic.experiment';
+ /**
+ * The maximum page size of result sets returned by the API
+ */
+ public const MAX_PAGE_SIZE = 100;
+
/** Return the host name of the api endpoint */
public function host(): string;
diff --git a/src/Document/Fragment/Embed.php b/src/Document/Fragment/Embed.php
index e48cc80..363a974 100644
--- a/src/Document/Fragment/Embed.php
+++ b/src/Document/Fragment/Embed.php
@@ -73,7 +73,6 @@ private function setAttributes(iterable $attributes): void
private function setAttribute(string $name, $value): void
{
/**
- * @psalm-suppress RedundantConditionGivenDocblockType
* @psalm-suppress DocblockTypeContradiction
*/
if ($value !== null && ! is_scalar($value)) {
diff --git a/src/Query.php b/src/Query.php
index b8b2524..6f96e10 100644
--- a/src/Query.php
+++ b/src/Query.php
@@ -19,6 +19,7 @@
/**
* @psalm-type QueryParams = array|null>
+ * @final
*/
class Query
{
@@ -145,6 +146,8 @@ private function defaultParameters(): array
* Limit document count per page.
*
* The default is 20 per page and the maximum is 100
+ *
+ * @param positive-int $count
*/
public function resultsPerPage(int $count): self
{
@@ -153,6 +156,8 @@ public function resultsPerPage(int $count): self
/**
* Set the result page to retrieve.
+ *
+ * @param positive-int $page
*/
public function page(int $page): self
{
diff --git a/test/Smoke/TestCase.php b/test/Smoke/TestCase.php
index e66c416..325aa8a 100644
--- a/test/Smoke/TestCase.php
+++ b/test/Smoke/TestCase.php
@@ -15,8 +15,11 @@
use Psr\Http\Client\ClientInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use function assert;
use function file_exists;
use function getenv;
+use function is_array;
+use function is_string;
class TestCase extends PHPUnitTestCase
{
@@ -65,11 +68,23 @@ protected function compileEndPoints(): array
/** @psalm-suppress MissingFile $content */
$content = require $configPath;
+ if (! is_array($content)) {
+ return $endpoints;
+ }
$configured = $content['endpoints'] ?? [];
+ assert(is_array($configured));
foreach ($configured as $spec) {
- $endpoints[$spec['url']] = $spec['token'];
+ assert(is_array($spec));
+ $url = isset($spec['url']) && is_string($spec['url']) ? $spec['url'] : null;
+ $token = isset($spec['token']) && is_string($spec['token']) ? $spec['token'] : null;
+
+ if (! $url) {
+ continue;
+ }
+
+ $endpoints[$url] = $token;
}
return $endpoints;
diff --git a/test/Unit/ResultSet/StandardResultTest.php b/test/Unit/ResultSet/StandardResultTest.php
index ee209fb..3d9eeaa 100644
--- a/test/Unit/ResultSet/StandardResultTest.php
+++ b/test/Unit/ResultSet/StandardResultTest.php
@@ -4,6 +4,8 @@
namespace PrismicTest\ResultSet;
+use DateTimeImmutable;
+use DateTimeZone;
use Prismic\Document;
use Prismic\Json;
use Prismic\ResultSet\StandardResultSet;
@@ -27,13 +29,21 @@ public function testBasicAccessors(): void
$this->assertSame(1, $this->resultSet->currentPageNumber());
$this->assertSame(99, $this->resultSet->totalResults());
$this->assertSame(99, $this->resultSet->pageCount());
- $this->assertNotNull($this->resultSet->expiresAt());
$this->assertSame('https://example.com/next', $this->resultSet->nextPage());
$this->assertSame('https://example.com/prev', $this->resultSet->previousPage());
$this->assertCount(2, $this->resultSet->results());
$this->assertContainsOnlyInstancesOf(DocumentData::class, $this->resultSet->results());
}
+ public function testThatTheCacheExpiryDateWillBeTheCurrentTimeInUTC(): void
+ {
+ $now = new DateTimeImmutable('now', new DateTimeZone('UTC'));
+ self::assertInstanceOf(DateTimeImmutable::class, $now);
+
+ self::assertEqualsWithDelta($now, $this->resultSet->expiresAt(), 0.0001);
+ self::assertEquals('UTC', $this->resultSet->expiresAt()->getTimezone()->getName());
+ }
+
public function testThatResultSetsAreCountable(): void
{
$this->assertCount(2, $this->resultSet);