From 70c9708f78a0546b476afa359d09723da635a91d Mon Sep 17 00:00:00 2001 From: George Steel Date: Thu, 18 May 2023 11:44:08 +0100 Subject: [PATCH] Refs can possibly have null labels - Updates the Ref class so that null is allowed for the label - Marks all `Ref` properties as `public readonly` since we're now on 8.1 minimum - Marks `Ref` as immutable - Makes types more precise for `Ref` Whilst this is possibly a BC break, i.e. the remote API has changed, it could also be due to Scheduled Releases, which may always have carried a null label. If this turns out to be a fix, then it may need back-porting to older versions --- src/Api.php | 1 + src/Value/Ref.php | 31 +++++++++++++++++----- test/Unit/Value/RefTest.php | 52 +++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/Api.php b/src/Api.php index 666e5fa..0d20b0a 100644 --- a/src/Api.php +++ b/src/Api.php @@ -341,6 +341,7 @@ private function previewRef(): Ref|null } $cookiePayload = (string) $this->requestCookies[$cookieName]; + assert($cookiePayload !== ''); // Fuck this. If you have the toolbar installed on your website. Prismic set the preview cookie for // *every single request*. This means that if you rely on determining whether a preview is active or not // by inspecting cookies in order to disable caching for example, this fucks things. It does not matter diff --git a/src/Value/Ref.php b/src/Value/Ref.php index f25f038..5ad9760 100644 --- a/src/Value/Ref.php +++ b/src/Value/Ref.php @@ -10,17 +10,28 @@ use function is_bool; use function is_string; +/** @psalm-immutable */ final class Ref implements Stringable { + /** + * @param non-empty-string $id + * @param non-empty-string $ref + * @param non-empty-string|null $label + */ private function __construct( - private string $id, - private string $ref, - private string $label, - private bool $isMasterRef, + public readonly string $id, + public readonly string $ref, + public readonly string|null $label, + public readonly bool $isMasterRef, ) { } - public static function new(string $id, string $ref, string $label, bool $isMasterRef): self + /** + * @param non-empty-string $id + * @param non-empty-string $ref + * @param non-empty-string|null $label + */ + public static function new(string $id, string $ref, string|null $label, bool $isMasterRef): self { return new self($id, $ref, $label, $isMasterRef); } @@ -32,24 +43,30 @@ public static function factory(object $object): self $label = $object->label ?? null; $isMaster = $object->isMasterRef ?? false; assert(is_string($id)); + assert($id !== ''); assert(is_string($ref)); - assert(is_string($label)); + assert($ref !== ''); + assert(is_string($label) || $label === null); + $label = $label === '' ? null : $label; assert(is_bool($isMaster)); return self::new($id, $ref, $label, $isMaster); } + /** @return non-empty-string */ public function id(): string { return $this->id; } + /** @return non-empty-string */ public function ref(): string { return $this->ref; } - public function label(): string + /** @return non-empty-string|null */ + public function label(): string|null { return $this->label; } diff --git a/test/Unit/Value/RefTest.php b/test/Unit/Value/RefTest.php index f462da2..02547e3 100644 --- a/test/Unit/Value/RefTest.php +++ b/test/Unit/Value/RefTest.php @@ -23,4 +23,56 @@ public function testRefCanBeCastToAString(): void $ref = Ref::new('foo', 'bar', 'baz', true); $this->assertSame('bar', (string) $ref); } + + public function testThatTheRefCanBeNull(): void + { + $ref = Ref::new('foo', 'bar', null, false); + $this->assertSame('bar', (string) $ref); + } + + public function testFactory(): void + { + $input = (object) [ + 'id' => 'foo', + 'ref' => 'ref', + 'label' => 'Master', + 'isMasterRef' => false, + ]; + + $ref = Ref::factory($input); + + self::assertSame('foo', $ref->id()); + self::assertSame('ref', $ref->ref()); + self::assertSame('Master', $ref->label()); + self::assertFalse($ref->isMaster()); + } + + public function testFactoryWithNullLabel(): void + { + $input = (object) [ + 'id' => 'foo', + 'ref' => 'ref', + 'label' => null, + 'isMasterRef' => false, + ]; + + $ref = Ref::factory($input); + + self::assertSame('foo', $ref->id()); + self::assertSame('ref', $ref->ref()); + self::assertNull($ref->label()); + self::assertFalse($ref->isMaster()); + } + + public function testFactoryWithMissingIsMasterRefAndLabel(): void + { + $input = (object) [ + 'id' => 'foo', + 'ref' => 'ref', + ]; + + $ref = Ref::factory($input); + + self::assertFalse($ref->isMaster()); + } }