Parse and validate AT Protocol Lexicons with DTO generation for Laravel
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Implement BlobReference class

+344
+139
src/Data/BlobReference.php
··· 1 + <?php 2 + 3 + namespace SocialDept\Schema\Data; 4 + 5 + use SocialDept\Schema\Exceptions\SchemaValidationException; 6 + 7 + class BlobReference 8 + { 9 + /** 10 + * CID of the blob. 11 + */ 12 + public readonly string $ref; 13 + 14 + /** 15 + * MIME type of the blob. 16 + */ 17 + public readonly string $mimeType; 18 + 19 + /** 20 + * Size of the blob in bytes. 21 + */ 22 + public readonly int $size; 23 + 24 + /** 25 + * Create a new BlobReference. 26 + */ 27 + public function __construct( 28 + string $ref, 29 + string $mimeType, 30 + int $size 31 + ) { 32 + $this->ref = $ref; 33 + $this->mimeType = $mimeType; 34 + $this->size = $size; 35 + } 36 + 37 + /** 38 + * Create from array data. 39 + */ 40 + public static function fromArray(array $data): self 41 + { 42 + // Extract ref - can be a string or array with $link 43 + $ref = null; 44 + if (isset($data['ref'])) { 45 + if (is_string($data['ref'])) { 46 + $ref = $data['ref']; 47 + } elseif (is_array($data['ref']) && isset($data['ref']['$link'])) { 48 + $ref = $data['ref']['$link']; 49 + } 50 + } 51 + 52 + if ($ref === null) { 53 + throw SchemaValidationException::missingField('blob', 'ref'); 54 + } 55 + 56 + if (! isset($data['mimeType'])) { 57 + throw SchemaValidationException::missingField('blob', 'mimeType'); 58 + } 59 + 60 + if (! isset($data['size'])) { 61 + throw SchemaValidationException::missingField('blob', 'size'); 62 + } 63 + 64 + return new self( 65 + ref: $ref, 66 + mimeType: $data['mimeType'], 67 + size: (int) $data['size'] 68 + ); 69 + } 70 + 71 + /** 72 + * Convert to array. 73 + */ 74 + public function toArray(): array 75 + { 76 + return [ 77 + '$type' => 'blob', 78 + 'ref' => [ 79 + '$link' => $this->ref, 80 + ], 81 + 'mimeType' => $this->mimeType, 82 + 'size' => $this->size, 83 + ]; 84 + } 85 + 86 + /** 87 + * Get the CID. 88 + */ 89 + public function getCid(): string 90 + { 91 + return $this->ref; 92 + } 93 + 94 + /** 95 + * Get the MIME type. 96 + */ 97 + public function getMimeType(): string 98 + { 99 + return $this->mimeType; 100 + } 101 + 102 + /** 103 + * Get the size in bytes. 104 + */ 105 + public function getSize(): int 106 + { 107 + return $this->size; 108 + } 109 + 110 + /** 111 + * Check if blob is an image. 112 + */ 113 + public function isImage(): bool 114 + { 115 + return str_starts_with($this->mimeType, 'image/'); 116 + } 117 + 118 + /** 119 + * Check if blob is a video. 120 + */ 121 + public function isVideo(): bool 122 + { 123 + return str_starts_with($this->mimeType, 'video/'); 124 + } 125 + 126 + /** 127 + * Check if blob matches a MIME type pattern. 128 + */ 129 + public function matchesMimeType(string $pattern): bool 130 + { 131 + if (str_contains($pattern, '*')) { 132 + $regex = '/^'.str_replace('\\*', '.*', preg_quote($pattern, '/')).'$/'; 133 + 134 + return (bool) preg_match($regex, $this->mimeType); 135 + } 136 + 137 + return $this->mimeType === $pattern; 138 + } 139 + }
+205
tests/Unit/Data/BlobReferenceTest.php
··· 1 + <?php 2 + 3 + namespace SocialDept\Schema\Tests\Unit\Data; 4 + 5 + use Orchestra\Testbench\TestCase; 6 + use SocialDept\Schema\Data\BlobReference; 7 + use SocialDept\Schema\Exceptions\SchemaValidationException; 8 + 9 + class BlobReferenceTest extends TestCase 10 + { 11 + public function test_it_creates_from_constructor(): void 12 + { 13 + $blob = new BlobReference( 14 + 'bafyreig...', 15 + 'image/png', 16 + 12345 17 + ); 18 + 19 + $this->assertEquals('bafyreig...', $blob->ref); 20 + $this->assertEquals('image/png', $blob->mimeType); 21 + $this->assertEquals(12345, $blob->size); 22 + } 23 + 24 + public function test_it_creates_from_array_with_link_object(): void 25 + { 26 + $data = [ 27 + '$type' => 'blob', 28 + 'ref' => [ 29 + '$link' => 'bafyreig...', 30 + ], 31 + 'mimeType' => 'image/jpeg', 32 + 'size' => 54321, 33 + ]; 34 + 35 + $blob = BlobReference::fromArray($data); 36 + 37 + $this->assertEquals('bafyreig...', $blob->ref); 38 + $this->assertEquals('image/jpeg', $blob->mimeType); 39 + $this->assertEquals(54321, $blob->size); 40 + } 41 + 42 + public function test_it_creates_from_array_with_string_ref(): void 43 + { 44 + $data = [ 45 + 'ref' => 'bafyreig...', 46 + 'mimeType' => 'video/mp4', 47 + 'size' => 999, 48 + ]; 49 + 50 + $blob = BlobReference::fromArray($data); 51 + 52 + $this->assertEquals('bafyreig...', $blob->ref); 53 + $this->assertEquals('video/mp4', $blob->mimeType); 54 + $this->assertEquals(999, $blob->size); 55 + } 56 + 57 + public function test_it_throws_exception_when_ref_is_missing(): void 58 + { 59 + $this->expectException(SchemaValidationException::class); 60 + 61 + BlobReference::fromArray([ 62 + 'mimeType' => 'image/png', 63 + 'size' => 123, 64 + ]); 65 + } 66 + 67 + public function test_it_throws_exception_when_mime_type_is_missing(): void 68 + { 69 + $this->expectException(SchemaValidationException::class); 70 + 71 + BlobReference::fromArray([ 72 + 'ref' => 'bafyreig...', 73 + 'size' => 123, 74 + ]); 75 + } 76 + 77 + public function test_it_throws_exception_when_size_is_missing(): void 78 + { 79 + $this->expectException(SchemaValidationException::class); 80 + 81 + BlobReference::fromArray([ 82 + 'ref' => 'bafyreig...', 83 + 'mimeType' => 'image/png', 84 + ]); 85 + } 86 + 87 + public function test_it_converts_to_array(): void 88 + { 89 + $blob = new BlobReference( 90 + 'bafyreig...', 91 + 'image/png', 92 + 12345 93 + ); 94 + 95 + $array = $blob->toArray(); 96 + 97 + $this->assertEquals([ 98 + '$type' => 'blob', 99 + 'ref' => [ 100 + '$link' => 'bafyreig...', 101 + ], 102 + 'mimeType' => 'image/png', 103 + 'size' => 12345, 104 + ], $array); 105 + } 106 + 107 + public function test_it_gets_cid(): void 108 + { 109 + $blob = new BlobReference('bafyreig123', 'image/png', 100); 110 + 111 + $this->assertEquals('bafyreig123', $blob->getCid()); 112 + } 113 + 114 + public function test_it_gets_mime_type(): void 115 + { 116 + $blob = new BlobReference('bafyreig...', 'video/webm', 100); 117 + 118 + $this->assertEquals('video/webm', $blob->getMimeType()); 119 + } 120 + 121 + public function test_it_gets_size(): void 122 + { 123 + $blob = new BlobReference('bafyreig...', 'image/png', 54321); 124 + 125 + $this->assertEquals(54321, $blob->getSize()); 126 + } 127 + 128 + public function test_it_checks_if_is_image(): void 129 + { 130 + $imageBlob = new BlobReference('cid1', 'image/png', 100); 131 + $videoBlob = new BlobReference('cid2', 'video/mp4', 200); 132 + 133 + $this->assertTrue($imageBlob->isImage()); 134 + $this->assertFalse($videoBlob->isImage()); 135 + } 136 + 137 + public function test_it_checks_if_is_video(): void 138 + { 139 + $imageBlob = new BlobReference('cid1', 'image/png', 100); 140 + $videoBlob = new BlobReference('cid2', 'video/mp4', 200); 141 + 142 + $this->assertFalse($imageBlob->isVideo()); 143 + $this->assertTrue($videoBlob->isVideo()); 144 + } 145 + 146 + public function test_it_matches_exact_mime_type(): void 147 + { 148 + $blob = new BlobReference('cid', 'image/png', 100); 149 + 150 + $this->assertTrue($blob->matchesMimeType('image/png')); 151 + $this->assertFalse($blob->matchesMimeType('image/jpeg')); 152 + } 153 + 154 + public function test_it_matches_wildcard_mime_type(): void 155 + { 156 + $imageBlob = new BlobReference('cid1', 'image/png', 100); 157 + $videoBlob = new BlobReference('cid2', 'video/mp4', 200); 158 + 159 + $this->assertTrue($imageBlob->matchesMimeType('image/*')); 160 + $this->assertFalse($imageBlob->matchesMimeType('video/*')); 161 + $this->assertTrue($videoBlob->matchesMimeType('video/*')); 162 + $this->assertFalse($videoBlob->matchesMimeType('image/*')); 163 + } 164 + 165 + public function test_it_matches_universal_wildcard(): void 166 + { 167 + $blob = new BlobReference('cid', 'application/json', 100); 168 + 169 + $this->assertTrue($blob->matchesMimeType('*/*')); 170 + } 171 + 172 + public function test_it_handles_different_image_types(): void 173 + { 174 + $pngBlob = new BlobReference('cid1', 'image/png', 100); 175 + $jpegBlob = new BlobReference('cid2', 'image/jpeg', 200); 176 + $webpBlob = new BlobReference('cid3', 'image/webp', 300); 177 + 178 + $this->assertTrue($pngBlob->isImage()); 179 + $this->assertTrue($jpegBlob->isImage()); 180 + $this->assertTrue($webpBlob->isImage()); 181 + } 182 + 183 + public function test_it_handles_different_video_types(): void 184 + { 185 + $mp4Blob = new BlobReference('cid1', 'video/mp4', 100); 186 + $webmBlob = new BlobReference('cid2', 'video/webm', 200); 187 + 188 + $this->assertTrue($mp4Blob->isVideo()); 189 + $this->assertTrue($webmBlob->isVideo()); 190 + } 191 + 192 + public function test_it_converts_size_to_integer(): void 193 + { 194 + $data = [ 195 + 'ref' => 'cid', 196 + 'mimeType' => 'image/png', 197 + 'size' => '12345', 198 + ]; 199 + 200 + $blob = BlobReference::fromArray($data); 201 + 202 + $this->assertIsInt($blob->size); 203 + $this->assertEquals(12345, $blob->size); 204 + } 205 + }