Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 5.2 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Tests\Unit; 4 5use Orchestra\Testbench\TestCase; 6use SocialDept\AtpSchema\Data\LexiconDocument; 7use SocialDept\AtpSchema\Generator\DTOGenerator; 8use SocialDept\AtpSchema\Parser\SchemaLoader; 9use SocialDept\AtpSchema\SchemaManager; 10use SocialDept\AtpSchema\Validation\LexiconValidator; 11 12class SchemaManagerTest extends TestCase 13{ 14 protected string $fixturesPath; 15 16 protected SchemaLoader $loader; 17 18 protected LexiconValidator $validator; 19 20 protected DTOGenerator $generator; 21 22 protected SchemaManager $manager; 23 24 protected function setUp(): void 25 { 26 parent::setUp(); 27 28 $this->fixturesPath = __DIR__.'/../fixtures'; 29 30 // Create mock dependencies 31 $this->loader = new SchemaLoader([$this->fixturesPath], false); 32 $this->validator = new LexiconValidator($this->loader); 33 $this->generator = new DTOGenerator($this->loader, 'App\\Lexicon', 'app/Lexicon'); 34 35 // Create manager 36 $this->manager = new SchemaManager( 37 $this->loader, 38 $this->validator, 39 $this->generator 40 ); 41 } 42 43 public function test_it_loads_schema(): void 44 { 45 $schema = $this->manager->load('app.bsky.feed.post'); 46 47 $this->assertInstanceOf(LexiconDocument::class, $schema); 48 $this->assertSame('app.bsky.feed.post', $schema->getNsid()); 49 } 50 51 public function test_it_checks_if_schema_exists(): void 52 { 53 $this->assertTrue($this->manager->exists('app.bsky.feed.post')); 54 $this->assertFalse($this->manager->exists('nonexistent.schema')); 55 } 56 57 public function test_it_parses_schema_into_document(): void 58 { 59 $document = $this->manager->load('app.bsky.feed.post'); 60 61 $this->assertInstanceOf(LexiconDocument::class, $document); 62 $this->assertSame('app.bsky.feed.post', $document->getNsid()); 63 $this->assertSame(1, $document->lexicon); 64 } 65 66 public function test_it_validates_data_against_schema(): void 67 { 68 $validData = [ 69 'text' => 'Hello, world!', 70 'createdAt' => '2024-01-01T12:00:00Z', 71 ]; 72 73 $result = $this->manager->validate('app.bsky.feed.post', $validData); 74 75 $this->assertTrue($result); 76 } 77 78 public function test_it_validates_data_with_errors(): void 79 { 80 $invalidData = [ 81 'text' => '', // Required field 82 ]; 83 84 $errors = $this->manager->validateWithErrors('app.bsky.feed.post', $invalidData); 85 86 $this->assertIsArray($errors); 87 $this->assertNotEmpty($errors); 88 } 89 90 public function test_it_generates_dto_code(): void 91 { 92 $code = $this->manager->generate('app.bsky.feed.post'); 93 94 $this->assertIsString($code); 95 $this->assertStringContainsString('namespace', $code); 96 $this->assertStringContainsString('class', $code); 97 } 98 99 public function test_it_throws_when_generator_not_available(): void 100 { 101 $managerWithoutGenerator = new SchemaManager( 102 $this->loader, 103 $this->validator, 104 null 105 ); 106 107 $this->expectException(\RuntimeException::class); 108 $this->expectExceptionMessage('Generator not available'); 109 110 $managerWithoutGenerator->generate('app.bsky.feed.post'); 111 } 112 113 public function test_it_clears_cache_for_specific_nsid(): void 114 { 115 // Load to cache 116 $this->manager->load('app.bsky.feed.post'); 117 118 $this->assertContains('app.bsky.feed.post', $this->loader->getCachedNsids()); 119 120 // Clear cache 121 $this->manager->clearCache('app.bsky.feed.post'); 122 123 $this->assertNotContains('app.bsky.feed.post', $this->loader->getCachedNsids()); 124 } 125 126 public function test_it_clears_all_cache(): void 127 { 128 // Load multiple schemas 129 $this->manager->load('app.bsky.feed.post'); 130 $this->manager->load('com.atproto.repo.getRecord'); 131 132 $this->assertCount(2, $this->loader->getCachedNsids()); 133 134 // Clear all 135 $this->manager->clearCache(); 136 137 $this->assertCount(0, $this->loader->getCachedNsids()); 138 } 139 140 public function test_it_gets_loader(): void 141 { 142 $loader = $this->manager->getLoader(); 143 144 $this->assertSame($this->loader, $loader); 145 } 146 147 public function test_it_gets_validator(): void 148 { 149 $validator = $this->manager->getValidator(); 150 151 $this->assertSame($this->validator, $validator); 152 } 153 154 public function test_it_gets_generator(): void 155 { 156 $generator = $this->manager->getGenerator(); 157 158 $this->assertSame($this->generator, $generator); 159 } 160 161 public function test_it_sets_generator(): void 162 { 163 $newGenerator = new DTOGenerator($this->loader, 'Custom\\Namespace', 'custom/path'); 164 165 $this->manager->setGenerator($newGenerator); 166 167 $this->assertSame($newGenerator, $this->manager->getGenerator()); 168 } 169 170 public function test_it_gets_null_generator_when_not_set(): void 171 { 172 $managerWithoutGenerator = new SchemaManager( 173 $this->loader, 174 $this->validator, 175 null 176 ); 177 178 $this->assertNull($managerWithoutGenerator->getGenerator()); 179 } 180}