Something went wrong. Try again.
Parse and validate AT Protocol Lexicons with DTO generation for Laravel
Something went wrong. Try again.
6.7 kB · 204 lines
PHP
at dev
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205<?php
namespace SocialDept\AtpSchema\Tests\Unit\Parser;
use Illuminate\Support\Facades\Cache;use Orchestra\Testbench\TestCase;use SocialDept\AtpSchema\Data\LexiconDocument;use SocialDept\AtpSchema\Exceptions\SchemaNotFoundException;use SocialDept\AtpSchema\Exceptions\SchemaParseException;use SocialDept\AtpSchema\Parser\SchemaLoader;
class SchemaLoaderTest extends TestCase{ protected string $fixturesPath;
protected function setUp(): void { parent::setUp();
$this->fixturesPath = __DIR__ . '/../../fixtures';
// Clear cache before each test Cache::flush(); }
public function test_it_loads_schema_from_hierarchical_json(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
$schema = $loader->load('app.bsky.feed.post');
$this->assertInstanceOf(LexiconDocument::class, $schema); $this->assertSame(1, $schema->lexicon); $this->assertSame('app.bsky.feed.post', $schema->getNsid()); }
public function test_it_loads_schema_from_flat_php(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
$schema = $loader->load('com.atproto.repo.getRecord');
$this->assertInstanceOf(LexiconDocument::class, $schema); $this->assertSame(1, $schema->lexicon); $this->assertSame('com.atproto.repo.getRecord', $schema->getNsid()); }
public function test_it_checks_if_schema_exists(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
$this->assertTrue($loader->exists('app.bsky.feed.post')); $this->assertTrue($loader->exists('com.atproto.repo.getRecord')); $this->assertFalse($loader->exists('nonexistent.schema')); }
public function test_it_throws_when_schema_not_found(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
$this->expectException(SchemaNotFoundException::class); $this->expectExceptionMessage('Schema not found for NSID: nonexistent.schema');
$loader->load('nonexistent.schema'); }
public function test_it_caches_schemas_in_memory(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
// First load $schema1 = $loader->load('app.bsky.feed.post');
// Second load should come from memory $schema2 = $loader->load('app.bsky.feed.post');
$this->assertSame($schema1, $schema2); $this->assertContains('app.bsky.feed.post', $loader->getCachedNsids()); }
public function test_it_caches_schemas_in_laravel_cache(): void { $loader = new SchemaLoader([$this->fixturesPath], true, 3600, 'schema');
// First load - should store in cache $schema = $loader->load('app.bsky.feed.post');
// Clear memory cache to force Laravel cache lookup $loader->clearCache('app.bsky.feed.post');
// Manually put raw array back in Laravel cache Cache::put('schema:parsed:app.bsky.feed.post', $schema->toArray(), 3600);
// This should retrieve from Laravel cache $cached = $loader->load('app.bsky.feed.post');
// The schemas should be equivalent (different object instances but same data) $this->assertEquals($schema->toArray(), $cached->toArray()); }
public function test_it_retrieves_from_laravel_cache(): void { $loader = new SchemaLoader([$this->fixturesPath], true);
// First load to cache it $originalSchema = $loader->load('app.bsky.feed.post');
// Clear memory cache $loader->clearCache('app.bsky.feed.post');
// Second load should come from Laravel cache $cachedSchema = $loader->load('app.bsky.feed.post');
$this->assertEquals($originalSchema->toArray(), $cachedSchema->toArray()); $this->assertSame('app.bsky.feed.post', $cachedSchema->getNsid()); }
public function test_it_clears_specific_schema_cache(): void { $loader = new SchemaLoader([$this->fixturesPath], true);
// Load to populate caches $loader->load('app.bsky.feed.post');
$this->assertContains('app.bsky.feed.post', $loader->getCachedNsids());
// Clear cache $loader->clearCache('app.bsky.feed.post');
// Memory cache should be cleared $this->assertNotContains('app.bsky.feed.post', $loader->getCachedNsids());
// Laravel cache should also be cleared (verify by loading again and checking it comes from file) $this->assertFalse(Cache::has('schema:parsed:app.bsky.feed.post')); }
public function test_it_clears_all_memory_cache(): void { $loader = new SchemaLoader([$this->fixturesPath], false);
// Load multiple schemas $loader->load('app.bsky.feed.post'); $loader->load('com.atproto.repo.getRecord');
$this->assertCount(2, $loader->getCachedNsids());
// Clear all $loader->clearCache();
$this->assertCount(0, $loader->getCachedNsids()); }
public function test_it_searches_multiple_sources_in_order(): void { $source1 = $this->fixturesPath . '/source1'; $source2 = $this->fixturesPath;
// Schema only exists in source2 $loader = new SchemaLoader([$source1, $source2], false);
$schema = $loader->load('app.bsky.feed.post');
$this->assertSame('app.bsky.feed.post', $schema->getNsid()); }
public function test_it_throws_on_invalid_json(): void { $invalidPath = $this->fixturesPath . '/invalid'; @mkdir($invalidPath, 0755, true); file_put_contents($invalidPath . '/invalid.json', '{invalid json}');
$loader = new SchemaLoader([$invalidPath], false);
$this->expectException(SchemaParseException::class); $this->expectExceptionMessage('Failed to parse schema JSON');
try { $loader->load('invalid'); } finally { @unlink($invalidPath . '/invalid.json'); @rmdir($invalidPath); } }
public function test_it_throws_on_php_file_not_returning_array(): void { $invalidPath = $this->fixturesPath . '/invalid'; @mkdir($invalidPath, 0755, true); file_put_contents($invalidPath . '/invalid.php', '<?php return "not an array";');
$loader = new SchemaLoader([$invalidPath], false);
$this->expectException(SchemaParseException::class); $this->expectExceptionMessage('PHP file must return an array');
try { $loader->load('invalid'); } finally { @unlink($invalidPath . '/invalid.php'); @rmdir($invalidPath); } }
}