diff --git a/src/Fields/BlueprintRepository.php b/src/Fields/BlueprintRepository.php index f899460d99..05a76d5f10 100644 --- a/src/Fields/BlueprintRepository.php +++ b/src/Fields/BlueprintRepository.php @@ -239,20 +239,16 @@ protected function filesIn($namespace) $directory = "{$this->additionalNamespaces[$namespace]}"; } - $files = File::withAbsolutePaths()->getFilesByType($directory, 'yaml'); + $files = File::withAbsolutePaths() + ->getFilesByType($directory, 'yaml') + ->mapWithKeys(fn ($path) => [Str::after($path, $directory.'/') => $path]); - if ($files->isNotEmpty() && File::exists($overrideDir = $this->directory.'/vendor/'.$namespaceDir)) { - $overrides = File::withAbsolutePaths()->getFilesByType($overrideDir, 'yaml'); + if (File::exists($directory = $this->directory.'/vendor/'.$namespaceDir)) { + $overrides = File::withAbsolutePaths() + ->getFilesByType($directory, 'yaml') + ->mapWithKeys(fn ($path) => [Str::after($path, $directory.'/') => $path]); - $files = $files->map(function ($path) use ($overrides, $overrideDir, $directory) { - $filename = str($path)->after($directory.'/'); - - if ($overrides->contains($overridePath = $overrideDir.'/'.$filename)) { - return $overridePath; - } - - return $path; - }); + $files = $files->merge($overrides)->values(); } return $files; diff --git a/tests/Fields/BlueprintRepositoryTest.php b/tests/Fields/BlueprintRepositoryTest.php index beb3be3eb8..a7004a74cd 100644 --- a/tests/Fields/BlueprintRepositoryTest.php +++ b/tests/Fields/BlueprintRepositoryTest.php @@ -291,6 +291,7 @@ public function it_returns_empty_collection_if_directory_doesnt_exist() { File::shouldReceive('withAbsolutePaths')->once()->andReturnSelf(); File::shouldReceive('getFilesByType')->with('/path/to/resources/blueprints/test', 'yaml')->once()->andReturn(new FileCollection); + File::shouldReceive('exists')->with('/path/to/resources/blueprints/vendor/test')->once()->andReturnFalse(); $all = $this->repo->in('test'); @@ -337,11 +338,42 @@ public function it_gets_blueprints_in_a_custom_namespace_with_overrides() File::shouldReceive('getFilesByType')->with($overrideDir, 'yaml')->once()->andReturn( new FileCollection([ $overrideDir.'/second.yaml', - $overrideDir.'/third.yaml', // This one exists as an override but since there's no original it will be ignored. This behavior is up for debate. + $overrideDir.'/third.yaml', ]) ); File::shouldReceive('get')->with($dir.'/first.yaml')->once()->andReturn('title: First Blueprint'); File::shouldReceive('get')->with($overrideDir.'/second.yaml')->once()->andReturn('title: Overridden Second Blueprint'); + File::shouldReceive('get')->with($overrideDir.'/third.yaml')->once()->andReturn('title: Third Blueprint only in overrides'); + + $this->repo->addNamespace('custom', $dir); + + $blueprints = $this->repo->in('custom'); + + $this->assertInstanceOf(Collection::class, $blueprints); + $this->assertCount(3, $blueprints); + $this->assertEveryItemIsInstanceOf(Blueprint::class, $blueprints); + $this->assertEquals(['first', 'second', 'third'], $blueprints->keys()->all()); + $this->assertEquals(['first', 'second', 'third'], $blueprints->map->handle()->values()->all()); + $this->assertEquals(['custom', 'custom', 'custom'], $blueprints->map->namespace()->values()->all()); + $this->assertEquals(['First Blueprint', 'Overridden Second Blueprint', 'Third Blueprint only in overrides'], $blueprints->map->title()->values()->all()); + } + + #[Test] + public function it_gets_blueprints_in_a_custom_namespace_where_there_are_no_original_files_but_only_overrides() + { + File::shouldReceive('withAbsolutePaths')->twice()->andReturnSelf(); + $dir = '/path/to/custom'; + $overrideDir = '/path/to/resources/blueprints/vendor/custom'; + File::shouldReceive('exists')->with($overrideDir)->andReturnTrue(); + File::shouldReceive('getFilesByType')->with($dir, 'yaml')->once()->andReturn(new FileCollection); + File::shouldReceive('getFilesByType')->with($overrideDir, 'yaml')->once()->andReturn( + new FileCollection([ + $overrideDir.'/first.yaml', + $overrideDir.'/second.yaml', + ]) + ); + File::shouldReceive('get')->with($overrideDir.'/first.yaml')->once()->andReturn('title: First Blueprint only in overrides'); + File::shouldReceive('get')->with($overrideDir.'/second.yaml')->once()->andReturn('title: Second Blueprint only in overrides'); $this->repo->addNamespace('custom', $dir); @@ -353,7 +385,7 @@ public function it_gets_blueprints_in_a_custom_namespace_with_overrides() $this->assertEquals(['first', 'second'], $blueprints->keys()->all()); $this->assertEquals(['first', 'second'], $blueprints->map->handle()->values()->all()); $this->assertEquals(['custom', 'custom'], $blueprints->map->namespace()->values()->all()); - $this->assertEquals(['First Blueprint', 'Overridden Second Blueprint'], $blueprints->map->title()->values()->all()); + $this->assertEquals(['First Blueprint only in overrides', 'Second Blueprint only in overrides'], $blueprints->map->title()->values()->all()); } #[Test]