From b431fb6f15adae45eeab925a85cadd023e4dce56 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 25 Jun 2025 15:49:05 +0300 Subject: [PATCH 01/30] refactor: use resource in generate only nova tests --- src/Commands/MakeEntityCommand.php | 15 +++++- src/Generators/NovaTestGenerator.php | 72 ++++++++++++++++++++-------- tests/NovaTestGeneratorTest.php | 47 +++++++++++++----- tests/Support/GeneratorMockTrait.php | 9 ++++ 4 files changed, 111 insertions(+), 32 deletions(-) diff --git a/src/Commands/MakeEntityCommand.php b/src/Commands/MakeEntityCommand.php index 680a28b4..e7ac1b66 100644 --- a/src/Commands/MakeEntityCommand.php +++ b/src/Commands/MakeEntityCommand.php @@ -55,6 +55,7 @@ class MakeEntityCommand extends Command {--only-seeder : Set this flag if you want to create only seeder.} {--only-nova-resource : Set this flag if you want to create only nova resource.} {--only-nova-tests : Set this flag if you want to create only nova resource tests.} + {resourceName? : The name of the Nova resource, used only with --only-nova-tests.} {--methods=CRUD : Set types of methods to create. Affect on routes, requests classes, controller\'s methods and tests methods.} @@ -213,7 +214,19 @@ protected function generate() protected function runGeneration($generator) { - app($generator) + $resourceName = "{$this->argument('name')}Resource"; + + if (!empty($this->argument('resourceName'))){ + $resourceName = $this->argument('resourceName'); + } + + $generatorInstance = app($generator); + + if (method_exists($generatorInstance, 'setResource')) { + $generatorInstance->setResource($resourceName); + } + + $generatorInstance ->setModel($this->argument('name')) ->setFields($this->getFields()) ->setRelations($this->getRelations()) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 080336ba..64ab87d6 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -8,10 +8,14 @@ use RonasIT\Support\Events\SuccessCreateMessage; use RonasIT\Support\Exceptions\ClassAlreadyExistsException; use RonasIT\Support\Exceptions\ClassNotExistsException; +use RecursiveIteratorIterator; +use RecursiveDirectoryIterator; class NovaTestGenerator extends AbstractTestsGenerator { - protected $novaModelName; + protected string $novaResourceName; + + protected ?string $fullNovaResourcePath = null; public function generate(): void { @@ -19,16 +23,24 @@ public function generate(): void if (!$this->doesNovaResourceExists()) { $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->model}Test cause {$this->model} Nova resource does not exist.", - "Create {$this->model} Nova resource." + "Cannot create Nova{$this->novaResourceName}Test cause {$this->novaResourceName} Nova resource does not exist.", + "Create {$this->novaResourceName} Nova resource." ); } - if ($this->classExists('nova', "Nova{$this->model}Test")) { + if ($this->classExists('nova', "Nova{$this->novaResourceName}Test")) { $this->throwFailureException( ClassAlreadyExistsException::class, - "Cannot create Nova{$this->model}Test cause it's already exist.", - "Remove Nova{$this->model}Test." + "Cannot create Nova{$this->novaResourceName}Test cause it's already exist.", + "Remove Nova{$this->novaResourceName}Test." + ); + } + + if (!$this->classExists('models', $this->model)) { + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->novaResourceName}Test cause {$this->model} does not exist.", + "Create a {$this->model} Model by himself or run command 'php artisan make:entity {$this->model} --only-model'." ); } @@ -38,6 +50,13 @@ public function generate(): void } } + public function setResource($novaResourceName) + { + $this->novaResourceName = Str::studly($novaResourceName); + + return $this; + } + public function generateTests(): void { if (!$this->isStubExists('nova_test')) { @@ -58,9 +77,9 @@ public function generateTests(): void 'filters' => $filters, ]); - $this->saveClass('tests', "Nova{$this->model}Test", $fileContent); + $this->saveClass('tests', "Nova{$this->novaResourceName}Test", $fileContent); - event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->model}Test")); + event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->novaResourceName}Test")); } protected function getActions(): array @@ -83,22 +102,22 @@ protected function getActions(): array protected function loadNovaActions() { - return app("\\App\\Nova\\{$this->novaModelName}")->actions(new NovaRequest()); + return app("{$this->fullNovaResourcePath}")->actions(new NovaRequest()); } protected function loadNovaFields() { - return app("\\App\\Nova\\{$this->novaModelName}")->fields(new NovaRequest()); + return app("{$this->fullNovaResourcePath}")->fields(new NovaRequest()); } protected function loadNovaFilters() { - return app("\\App\\Nova\\{$this->novaModelName}")->filters(new NovaRequest()); + return app("{$this->fullNovaResourcePath}")->filters(new NovaRequest()); } public function getTestClassName(): string { - return "Nova{$this->model}Test"; + return "Nova{$this->novaResourceName}Test"; } protected function isFixtureNeeded($type): bool @@ -108,16 +127,13 @@ protected function isFixtureNeeded($type): bool protected function doesNovaResourceExists(): bool { - $possibleNovaModelNames = [ - "{$this->model}NovaResource", - "{$this->model}Resource", - $this->model - ]; + $novaDirectory = app_path('Nova'); - foreach ($possibleNovaModelNames as $modelName) { - if ($this->classExists('nova', $modelName)) { - $this->novaModelName = $modelName; + $allNovaClasses = $this->getAllNovaClasses($novaDirectory); + foreach ($allNovaClasses as $class) { + if (Str::contains($class, $this->novaResourceName)) { + $this->fullNovaResourcePath = $class; return true; } } @@ -125,6 +141,22 @@ protected function doesNovaResourceExists(): bool return false; } + protected function getAllNovaClasses(string $directory): array + { + $classes = []; + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); + + foreach ($iterator as $file) { + if ($file->isFile() && $file->getExtension() === 'php') { + $relativePath = str_replace(app_path() . DIRECTORY_SEPARATOR, '', $file->getPathname()); + $class = 'App\\' . str_replace(['/', '.php'], ['\\', ''], $relativePath); + $classes[] = $class; + } + } + + return $classes; + } + protected function collectFilters(): array { $filtersFromFields = $this->getFiltersFromFields(); diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index d953040a..e4ee5be5 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -2,7 +2,6 @@ namespace RonasIT\Support\Tests; -use RonasIT\Support\Tests\Support\Models\WelcomeBonus; use RonasIT\Support\Events\SuccessCreateMessage; use RonasIT\Support\Events\WarningEvent; use RonasIT\Support\Exceptions\ClassAlreadyExistsException; @@ -10,6 +9,7 @@ use RonasIT\Support\Generators\NovaTestGenerator; use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\NovaTestGeneratorMockTrait; use Laravel\Nova\NovaServiceProvider; +use RonasIT\Support\Tests\Support\Models\WelcomeBonus; use Mockery; class NovaTestGeneratorTest extends TestCase @@ -28,9 +28,7 @@ public function testGenerateResourceNotExists() $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'PostNovaResource'], false), - $this->classExistsMethodCall(['nova', 'PostResource'], false), - $this->classExistsMethodCall(['nova', 'Post'], false), + $this->doesNovaResourceExistsCall(false), ]); $this->assertExceptionThrew( @@ -40,6 +38,7 @@ className: ClassNotExistsException::class, app(NovaTestGenerator::class) ->setModel('Post') + ->setResource('Post') ->generate(); } @@ -48,8 +47,7 @@ public function testGenerateNovaTestAlreadyExists() $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'PostNovaResource']), - $this->classExistsMethodCall(['nova', 'NovaPostTest']) + $this->classExistsMethodCall(['nova', 'NovaPostTest']), ]); $this->assertExceptionThrew( @@ -59,23 +57,32 @@ className: ClassAlreadyExistsException::class, app(NovaTestGenerator::class) ->setModel('Post') + ->setResource('Post') ->generate(); } public function testNovaTestStubNotExist() { + config([ + 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', + 'entity-generator.stubs.nova_test' => 'incorrect_stub', + ]); + $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), ); - $this->mockNovaRequestClassCall(); - - config([ - 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', - 'entity-generator.stubs.nova_test' => 'incorrect_stub', + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), ]); + $this->mockNovaRequestClassCall(); + $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); $mock ->shouldReceive('beginTransaction', 'rollBack') @@ -83,6 +90,7 @@ public function testNovaTestStubNotExist() app(NovaTestGenerator::class) ->setModel('WelcomeBonus') + ->setResource('WelcomeBonus') ->generate(); $this->assertFileDoesNotExist('tests/NovaWelcomeBonusTest.php'); @@ -108,8 +116,16 @@ public function testDumpStubNotExist() 'entity-generator.stubs.dump' => 'incorrect_stub', ]); + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + ]); + app(NovaTestGenerator::class) ->setModel('WelcomeBonus') + ->setResource('WelcomeBonus') ->generate(); $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusTest.php'); @@ -130,6 +146,14 @@ public function testSuccess() 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', ]); + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + ]); + $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); $mock ->shouldReceive('beginTransaction', 'rollBack') @@ -144,6 +168,7 @@ public function testSuccess() app(NovaTestGenerator::class) ->setModel('WelcomeBonus') + ->setResource('WelcomeBonus') ->generate(); $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusTest.php'); diff --git a/tests/Support/GeneratorMockTrait.php b/tests/Support/GeneratorMockTrait.php index 09ef73bc..65c6dda4 100644 --- a/tests/Support/GeneratorMockTrait.php +++ b/tests/Support/GeneratorMockTrait.php @@ -30,6 +30,15 @@ public function classExistsMethodCall(array $arguments, bool $result = true): ar ]; } + public function doesNovaResourceExistsCall(bool $result = true): array + { + return [ + 'function' => 'doesNovaResourceExists', + 'arguments' => [], + 'result' => $result + ]; + } + public function nativeClassExistsMethodCall(array $arguments, bool $result = true): array { return [ From 563f2c20ae975bee7ffb456d2fed0afabb08e244 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 27 Jun 2025 13:36:56 +0300 Subject: [PATCH 02/30] fix: tests --- tests/CommandTest.php | 53 ++++++++++++++++++++-- tests/Support/Command/CommandMockTrait.php | 41 ++++++++++++++++- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 8c90745e..4b011513 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -77,11 +77,11 @@ public function testCallCommand() $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/PostTest/update_post_request.json'); $this->assertGeneratedFileEquals('validation.php', 'lang/en/validation.php'); $this->assertGeneratedFileEquals('nova_resource.php', 'app/Nova/PostResource.php'); - $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostTest.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostResourceTest.php'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); } public function testMakeOnly() @@ -121,6 +121,49 @@ public function testMakeOnly() $this->assertFileDoesNotExist('tests/fixtures/NovaPostTest/update_post_request.json'); } + public function testMakeOnlyNovaTest(): void + { + $this->mockFilesystemWithPostModelAndResource(); + + config([ + 'entity-generator.paths.models' => 'RonasIT\Support\Tests\Support\Command\Models', + ]); + + $this->mockGeneratorOnlyNovaTests(); + + $this + ->artisan('make:entity Post PostResource --only-nova-tests') + ->assertSuccessful(); + + $this->assertFileDoesNotExist('app/Repositories/PostRepository.php'); + $this->assertFileDoesNotExist('database/migrations/2016_10_20_110500_posts_create_table.php'); + $this->assertFileDoesNotExist('database/factories/PostFactory.php'); + $this->assertFileDoesNotExist('database/seeders/PostSeeder.php'); + $this->assertFileDoesNotExist('app/Models/Post.php'); + $this->assertFileDoesNotExist('app/Services/PostService.php'); + $this->assertFileDoesNotExist('app/Http/Requests/Post/CreatePostRequest.php'); + $this->assertFileDoesNotExist('app/Http/Requests/Post/GetPostRequest.php'); + $this->assertFileDoesNotExist('app/Http/Requests/Post/SearchPostsRequest.php'); + $this->assertFileDoesNotExist('app/Http/Requests/Post/UpdatePostRequest.php'); + $this->assertFileDoesNotExist('app/Http/Requests/Post/DeletePostRequest.php'); + $this->assertFileDoesNotExist('app/Http/Controllers/PostController.php'); + $this->assertFileDoesNotExist('app/Http/Resources/Post/PostResource.php'); + $this->assertFileDoesNotExist('app/Http/Resources/Post/PostsCollectionResource.php'); + $this->assertFileDoesNotExist('routes/api.php'); + $this->assertFileDoesNotExist('tests/PostTest.php'); + $this->assertFileDoesNotExist('tests/fixtures/PostTest/dump.sql'); + $this->assertFileDoesNotExist('tests/fixtures/PostTest/create_post_request.json'); + $this->assertFileDoesNotExist('tests/fixtures/PostTest/create_post_response.json'); + $this->assertFileDoesNotExist('tests/fixtures/PostTest/update_post_request.json'); + $this->assertFileDoesNotExist('lang/en/validation.php'); + $this->assertFileDoesNotExist('app/Nova/PostResource.php'); + $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostResourceTest.php'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); + } + public function testCallWithNotDefaultConfig() { $this->app->instance('path.base', $this->generatedFileBasePath); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index b1c94412..57f54b6e 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -25,11 +25,22 @@ public function mockFilesystemPostModelExists(): void $fileSystemMock->setStructure(); } + public function mockFilesystemWithPostModelAndResource(): void + { + $fileSystemMock = new FileSystemMock(); + + $fileSystemMock->models = ['Post.php' => $this->mockPhpFileContent()]; + $fileSystemMock->novaModels = ['PostResource.php' => $this->mockPhpFileContent()]; + $fileSystemMock->config = ['entity-generator.php' => '']; + + $fileSystemMock->setStructure(); + } + public function mockFilesystem(): void { $fileSystemMock = new FileSystemMock(); - $fileSystemMock->routes = [ 'api.php' => $this->mockPhpFileContent()]; + $fileSystemMock->routes = ['api.php' => $this->mockPhpFileContent()]; $fileSystemMock->config = ['entity-generator.php' => '']; $fileSystemMock->translations = []; @@ -61,6 +72,34 @@ public function mockGenerator(): void ); } + public function mockGeneratorOnlyNovaTests(): void + { + $this->mockClass(NovaTestGenerator::class, [ + $this->functionCall( + name: 'loadNovaActions', + result: [], + ), + $this->functionCall( + name: 'loadNovaFields', + result: [], + ), + $this->functionCall( + name: 'loadNovaFilters', + result: [], + ), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), + $this->classExistsMethodCall(['models', 'Post']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'PostFactory'], false), + $this->classExistsMethodCall(['factories', 'PostFactory'], false), + ]); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), + $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), + ); + } + public function mockGettingModelInstance(): void { $connectionMock = Mockery::mock(Connection::class)->makePartial(); From 8a19c3a4e25d80ae7e996dbe5139587a2d455e5c Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 27 Jun 2025 14:20:38 +0300 Subject: [PATCH 03/30] fix:tests --- tests/Support/Command/CommandMockTrait.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index 57f54b6e..19655363 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -94,6 +94,11 @@ public function mockGeneratorOnlyNovaTests(): void $this->classExistsMethodCall(['factories', 'PostFactory'], false), ]); + $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); + $mock + ->shouldReceive('beginTransaction', 'rollBack') + ->once(); + $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), From 33ca7bcc4d3aa9e6e43fd5111e720f53f0768251 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 27 Jun 2025 14:35:02 +0300 Subject: [PATCH 04/30] fix:Tests --- tests/CommandTest.php | 1 + tests/Support/Command/CommandMockTrait.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 4b011513..2b33b9a5 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -127,6 +127,7 @@ public function testMakeOnlyNovaTest(): void config([ 'entity-generator.paths.models' => 'RonasIT\Support\Tests\Support\Command\Models', + 'entity-generator.paths.factories' => 'RonasIT\Support\Tests\Support\Command\Factories', ]); $this->mockGeneratorOnlyNovaTests(); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index 19655363..c0d3eee1 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -90,8 +90,8 @@ public function mockGeneratorOnlyNovaTests(): void $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), $this->classExistsMethodCall(['models', 'Post']), $this->classExistsMethodCall(['models', 'User'], false), - $this->classExistsMethodCall(['factories', 'PostFactory'], false), - $this->classExistsMethodCall(['factories', 'PostFactory'], false), + $this->classExistsMethodCall(['factories', 'PostFactory']), + $this->classExistsMethodCall(['factories', 'PostFactory']), ]); $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); From 516473bdd1ee43b6e0eb939fe1a5d19bfe306e40 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 27 Jun 2025 14:51:22 +0300 Subject: [PATCH 05/30] fix:tests --- tests/CommandTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 2b33b9a5..3ea0c840 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -123,6 +123,8 @@ public function testMakeOnly() public function testMakeOnlyNovaTest(): void { + Carbon::setTestNow('2016-10-20 11:05:00'); + $this->mockFilesystemWithPostModelAndResource(); config([ From b5d870d380912fa9389186b68897e19722020585 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 1 Jul 2025 17:06:12 +0300 Subject: [PATCH 06/30] refactor: change set resource from argument ot option --- src/Commands/MakeEntityCommand.php | 8 ++++---- tests/CommandTest.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Commands/MakeEntityCommand.php b/src/Commands/MakeEntityCommand.php index e7ac1b66..466593ec 100644 --- a/src/Commands/MakeEntityCommand.php +++ b/src/Commands/MakeEntityCommand.php @@ -55,8 +55,8 @@ class MakeEntityCommand extends Command {--only-seeder : Set this flag if you want to create only seeder.} {--only-nova-resource : Set this flag if you want to create only nova resource.} {--only-nova-tests : Set this flag if you want to create only nova resource tests.} - {resourceName? : The name of the Nova resource, used only with --only-nova-tests.} - + {--resource-name= : Override the default Nova resource name. Used only with --only-nova-tests.} + {--methods=CRUD : Set types of methods to create. Affect on routes, requests classes, controller\'s methods and tests methods.} {--i|integer=* : Add integer field to entity.} @@ -216,8 +216,8 @@ protected function runGeneration($generator) { $resourceName = "{$this->argument('name')}Resource"; - if (!empty($this->argument('resourceName'))){ - $resourceName = $this->argument('resourceName'); + if (!empty($this->option('resource-name'))){ + $resourceName = $this->option('resource-name'); } $generatorInstance = app($generator); diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 3ea0c840..3b4fe7c4 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -135,7 +135,7 @@ public function testMakeOnlyNovaTest(): void $this->mockGeneratorOnlyNovaTests(); $this - ->artisan('make:entity Post PostResource --only-nova-tests') + ->artisan('make:entity Post --only-nova-tests --resource-name=PostResource') ->assertSuccessful(); $this->assertFileDoesNotExist('app/Repositories/PostRepository.php'); From 1f250a242f2dffd6f3c302d5d004b16bc9d98edb Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 1 Jul 2025 17:28:11 +0300 Subject: [PATCH 07/30] style: fix --- src/Generators/NovaTestGenerator.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 64ab87d6..a2f2da9b 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -134,6 +134,7 @@ protected function doesNovaResourceExists(): bool foreach ($allNovaClasses as $class) { if (Str::contains($class, $this->novaResourceName)) { $this->fullNovaResourcePath = $class; + return true; } } @@ -144,12 +145,15 @@ protected function doesNovaResourceExists(): bool protected function getAllNovaClasses(string $directory): array { $classes = []; + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { $relativePath = str_replace(app_path() . DIRECTORY_SEPARATOR, '', $file->getPathname()); + $class = 'App\\' . str_replace(['/', '.php'], ['\\', ''], $relativePath); + $classes[] = $class; } } From 5c49cecb86282ba2a24b334471a40ace03186008 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 2 Jul 2025 10:58:01 +0300 Subject: [PATCH 08/30] refactor: remove useless --- src/Generators/NovaTestGenerator.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index a2f2da9b..9126af1a 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -127,9 +127,7 @@ protected function isFixtureNeeded($type): bool protected function doesNovaResourceExists(): bool { - $novaDirectory = app_path('Nova'); - - $allNovaClasses = $this->getAllNovaClasses($novaDirectory); + $allNovaClasses = $this->getAllNovaClasses(); foreach ($allNovaClasses as $class) { if (Str::contains($class, $this->novaResourceName)) { @@ -142,11 +140,11 @@ protected function doesNovaResourceExists(): bool return false; } - protected function getAllNovaClasses(string $directory): array + protected function getAllNovaClasses(): array { $classes = []; - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(app_path('Nova'))); foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { From a66d9ce796e22300ca2e7b86fe3377e6972e4a59 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 8 Jul 2025 13:35:32 +0300 Subject: [PATCH 09/30] fix:tests --- src/Commands/MakeEntityCommand.php | 15 +- src/Generators/EntityGenerator.php | 5 + src/Generators/NovaTestGenerator.php | 76 +++++++--- tests/NovaTestGeneratorTest.php | 143 ++++++++++++++---- tests/Support/Command/CommandMockTrait.php | 5 +- tests/Support/FileSystemMock.php | 13 ++ tests/Support/Nova/Resource.php | 8 + .../Resources/WelcomeBonusDraftResource.php | 58 +++++++ tests/Support/Nova/WelcomeBonusResource.php | 2 +- .../NovaTestGeneratorMockTrait.php | 7 + 10 files changed, 256 insertions(+), 76 deletions(-) create mode 100644 tests/Support/Nova/Resource.php create mode 100644 tests/Support/Nova/Resources/WelcomeBonusDraftResource.php diff --git a/src/Commands/MakeEntityCommand.php b/src/Commands/MakeEntityCommand.php index 466593ec..3da3a153 100644 --- a/src/Commands/MakeEntityCommand.php +++ b/src/Commands/MakeEntityCommand.php @@ -214,23 +214,12 @@ protected function generate() protected function runGeneration($generator) { - $resourceName = "{$this->argument('name')}Resource"; - - if (!empty($this->option('resource-name'))){ - $resourceName = $this->option('resource-name'); - } - - $generatorInstance = app($generator); - - if (method_exists($generatorInstance, 'setResource')) { - $generatorInstance->setResource($resourceName); - } - - $generatorInstance + app($generator) ->setModel($this->argument('name')) ->setFields($this->getFields()) ->setRelations($this->getRelations()) ->setCrudOptions($this->getCrudOptions()) + ->setMetaData(['resource_name' => $this->option('resource-name')]) ->generate(); } diff --git a/src/Generators/EntityGenerator.php b/src/Generators/EntityGenerator.php index e8dd2366..aed5228e 100644 --- a/src/Generators/EntityGenerator.php +++ b/src/Generators/EntityGenerator.php @@ -90,6 +90,11 @@ public function setRelations(RelationsDTO $relations) return $this; } + public function setMetaData(array $data): self + { + return $this; + } + public function __construct() { $this->paths = config('entity-generator.paths'); diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 9126af1a..dc78753d 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -10,36 +10,48 @@ use RonasIT\Support\Exceptions\ClassNotExistsException; use RecursiveIteratorIterator; use RecursiveDirectoryIterator; +use RonasIT\Support\Exceptions\EntityCreateException; class NovaTestGenerator extends AbstractTestsGenerator { - protected string $novaResourceName; + protected string $resourceName; protected ?string $fullNovaResourcePath = null; + protected string $shortNovaResourceName; + + protected string $novaPath; + + public function __construct() + { + $this->novaPath = app_path('Nova'); + + parent::__construct(); + } + public function generate(): void { if (class_exists(NovaServiceProvider::class)) { if (!$this->doesNovaResourceExists()) { $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->novaResourceName}Test cause {$this->novaResourceName} Nova resource does not exist.", - "Create {$this->novaResourceName} Nova resource." + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", + "Create {$this->resourceName} Nova resource." ); } - if ($this->classExists('nova', "Nova{$this->novaResourceName}Test")) { + if ($this->classExists('nova', "Nova{$this->shortNovaResourceName}Test")) { $this->throwFailureException( ClassAlreadyExistsException::class, - "Cannot create Nova{$this->novaResourceName}Test cause it's already exist.", - "Remove Nova{$this->novaResourceName}Test." + "Cannot create Nova{$this->shortNovaResourceName}Test cause it's already exist.", + "Remove Nova{$this->resourceName}Test." ); } if (!$this->classExists('models', $this->model)) { $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->novaResourceName}Test cause {$this->model} does not exist.", + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->model} does not exist.", "Create a {$this->model} Model by himself or run command 'php artisan make:entity {$this->model} --only-model'." ); } @@ -50,9 +62,13 @@ public function generate(): void } } - public function setResource($novaResourceName) + public function setMetaData(array $data): self { - $this->novaResourceName = Str::studly($novaResourceName); + $resourceName = empty($data['resource_name']) ? "{$this->model}Resource" : $data['resource_name']; + + $this->resourceName = Str::studly($resourceName); + + $this->shortNovaResourceName = Str::afterLast($this->resourceName, '\\'); return $this; } @@ -77,9 +93,9 @@ public function generateTests(): void 'filters' => $filters, ]); - $this->saveClass('tests', "Nova{$this->novaResourceName}Test", $fileContent); + $this->saveClass('tests', "Nova{$this->shortNovaResourceName}Test", $fileContent); - event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->novaResourceName}Test")); + event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->shortNovaResourceName}Test")); } protected function getActions(): array @@ -117,7 +133,7 @@ protected function loadNovaFilters() public function getTestClassName(): string { - return "Nova{$this->novaResourceName}Test"; + return "Nova{$this->shortNovaResourceName}Test"; } protected function isFixtureNeeded($type): bool @@ -129,34 +145,44 @@ protected function doesNovaResourceExists(): bool { $allNovaClasses = $this->getAllNovaClasses(); + $resources = []; + foreach ($allNovaClasses as $class) { - if (Str::contains($class, $this->novaResourceName)) { - $this->fullNovaResourcePath = $class; + if ($class === $this->resourceName) { + $this->fullNovaResourcePath = "App\\Nova\\{$this->resourceName}"; return true; } + + if (Str::contains($class, $this->model) && is_subclass_of("App\\Nova\\{$class}", "App\\Nova\\Resource")) { + $resources[] = $class; + } + } + + if (count($resources) > 1) { + $resources = implode(', ', $resources); + + $this->throwFailureException( + EntityCreateException::class, + "Cannot create Nova{$this->shortNovaResourceName}Test cause I found a lot of suitable resources: $resources", + "Please, use --resource-name option" + ); } return false; } - protected function getAllNovaClasses(): array + protected function getAllNovaClasses(): \Generator { - $classes = []; - - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(app_path('Nova'))); + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->novaPath)); foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { - $relativePath = str_replace(app_path() . DIRECTORY_SEPARATOR, '', $file->getPathname()); - - $class = 'App\\' . str_replace(['/', '.php'], ['\\', ''], $relativePath); + $relativePath = Str::after($file->getPathname(), $this->novaPath . DIRECTORY_SEPARATOR); - $classes[] = $class; + yield str_replace(['/', '.php'], ['\\', ''], $relativePath); } } - - return $classes; } protected function collectFilters(): array @@ -194,7 +220,7 @@ protected function getFiltersFromFields(): array protected function getFilters(): array { - $filters= []; + $filters = []; $novaResourceFilters = $this->loadNovaFilters(); foreach ($novaResourceFilters as $filter) { diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 0ce297c2..4004acb1 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -11,6 +11,7 @@ use Laravel\Nova\NovaServiceProvider; use RonasIT\Support\Tests\Support\Models\WelcomeBonus; use Mockery; +use RonasIT\Support\Exceptions\EntityCreateException; class NovaTestGeneratorTest extends TestCase { @@ -33,12 +34,12 @@ public function testGenerateResourceNotExists() $this->assertExceptionThrew( className: ClassNotExistsException::class, - message: 'Cannot create NovaPostTest cause Post Nova resource does not exist. Create Post Nova resource.', + message: 'Cannot create NovaPostResourceTest cause PostResource Nova resource does not exist. Create PostResource Nova resource.', ); app(NovaTestGenerator::class) ->setModel('Post') - ->setResource('Post') + ->setMetaData(['resource_name' => 'PostResource']) ->generate(); } @@ -47,17 +48,17 @@ public function testGenerateNovaTestAlreadyExists() $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaPostTest']), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), ]); $this->assertExceptionThrew( className: ClassAlreadyExistsException::class, - message: "Cannot create NovaPostTest cause it's already exist. Remove NovaPostTest.", + message: "Cannot create NovaPostResourceTest cause it's already exist. Remove NovaPostResourceTest.", ); app(NovaTestGenerator::class) ->setModel('Post') - ->setResource('Post') + ->setMetaData(['resource_name' => 'PostResource']) ->generate(); } @@ -74,7 +75,7 @@ public function testNovaTestStubNotExist() ); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -83,22 +84,18 @@ public function testNovaTestStubNotExist() $this->mockNovaRequestClassCall(); - $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); - $mock - ->shouldReceive('beginTransaction', 'rollBack') - ->once(); $this->mockDBTransactionStartRollback(); app(NovaTestGenerator::class) ->setModel('WelcomeBonus') - ->setResource('WelcomeBonus') + ->setMetaData(['resource_name' => 'WelcomeBonusResource']) ->generate(); $this->assertFileDoesNotExist('tests/NovaWelcomeBonusTest.php'); - $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); $this->assertEventPushed( className: WarningEvent::class, @@ -118,7 +115,7 @@ public function testDumpStubNotExist() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -126,14 +123,14 @@ public function testDumpStubNotExist() app(NovaTestGenerator::class) ->setModel('WelcomeBonus') - ->setResource('WelcomeBonus') + ->setMetaData(['resource_name' => 'WelcomeBonusResource']) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusTest.php'); - $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); $this->assertEventPushed( className: WarningEvent::class, @@ -148,17 +145,97 @@ public function testSuccess() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusTest'], false), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), ]); - $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); - $mock - ->shouldReceive('beginTransaction', 'rollBack') - ->once(); + $this->mockDBTransactionStartRollback(); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), + ); + + $this->mockNovaRequestClassCall(); + + app(NovaTestGenerator::class) + ->setModel('WelcomeBonus') + ->setMetaData(['resource_name' => 'WelcomeBonusResource']) + ->generate(); + + $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); + } + + public function testWithManySameResources() + { + $this->mockNovaServiceProviderExists(); + + $this->assertExceptionThrew( + className: EntityCreateException::class, + message: 'Cannot create NovaPostResourceTest cause I found a lot of suitable resources: Resources\PostResource Please, use --resource-name option', + ); + + app(NovaTestGenerator::class) + ->setModel('Post') + ->setMetaData(['resource_name' => 'PostResource']) + ->generate(); + } + + public function testSuccessWithoutSetMetaData() + { + config([ + 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', + ]); + + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + ]); + + $this->mockDBTransactionStartRollback(); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), + ); + + $this->mockNovaRequestClassCall(); + + app(NovaTestGenerator::class) + ->setModel('WelcomeBonus') + ->setMetaData(['resource_name' => null]) + ->generate(); + + $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); + } + + public function testSuccessWithNestedFile(): void + { + config([ + 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', + ]); + + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusDraftResourceTest'], false), + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + ]); $this->mockDBTransactionStartRollback(); @@ -171,14 +248,14 @@ public function testSuccess() app(NovaTestGenerator::class) ->setModel('WelcomeBonus') - ->setResource('WelcomeBonus') + ->setMetaData(['resource_name' => 'Resources\WelcomeBonusDraftResource']) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusTest.php'); - $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusDraftResourceTest.php'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/nova_welcome_bonus_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/update_welcome_bonus_request.json'); } public function testGenerateNovaPackageNotInstall() diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index bd2881a1..738c80da 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -89,10 +89,7 @@ public function mockGeneratorOnlyNovaTests(): void $this->classExistsMethodCall(['factories', 'PostFactory']), ]); - $mock = Mockery::mock('alias:Illuminate\Support\Facades\DB'); - $mock - ->shouldReceive('beginTransaction', 'rollBack') - ->once(); + $this->mockDBTransactionStartRollback(); $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), diff --git a/tests/Support/FileSystemMock.php b/tests/Support/FileSystemMock.php index 11c84f27..425cbf5d 100644 --- a/tests/Support/FileSystemMock.php +++ b/tests/Support/FileSystemMock.php @@ -8,6 +8,7 @@ class FileSystemMock { public ?array $novaModels = null; + public ?array $novaResources = null; public ?array $novaActions = null; public ?array $models = null; public ?array $controllers = null; @@ -32,6 +33,18 @@ public function setStructure(): void } } + if (!is_null($this->novaResources)) { + if (!array_key_exists('Nova', $structure['app'])) { + $structure['app']['Nova'] = []; + } + + $structure['app']['Nova']['Resources'] = []; + + foreach ($this->novaResources as $novaResource => $content) { + $structure['app']['Nova']['Resources'][$novaResource] = $content; + } + } + if (!is_null($this->novaActions)) { if (!array_key_exists('Nova', $structure['app'])) { $structure['app']['Nova'] = []; diff --git a/tests/Support/Nova/Resource.php b/tests/Support/Nova/Resource.php new file mode 100644 index 00000000..15bcf285 --- /dev/null +++ b/tests/Support/Nova/Resource.php @@ -0,0 +1,8 @@ +novaModels = [ 'WelcomeBonusResource.php' => $this->mockPhpFileContent(), + 'PostResource.php' => $this->mockPhpFileContent(), + ]; + + $fileSystemMock->novaResources = [ + 'WelcomeBonusDraftResource.php' => $this->mockPhpFileContent(), + 'PostResource.php' => $this->mockPhpFileContent(), ]; $fileSystemMock->models = [ 'WelcomeBonus.php' => $this->mockPhpFileContent(), + 'WelcomeBonusResource.php' => $this->mockPhpFileContent(), ]; $fileSystemMock->testFixtures = [ From c45d415da86d6dfdea4848e4801147ece266cdff Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 8 Jul 2025 16:24:00 +0300 Subject: [PATCH 10/30] refactor: check only nova resources --- src/Generators/NovaTestGenerator.php | 22 +++---- tests/NovaTestGeneratorTest.php | 46 ++++++++++----- tests/Support/Command/CommandMockTrait.php | 4 +- tests/Support/Models/Post.php | 25 ++++++++ tests/Support/Nova/Resources/PostResource.php | 59 +++++++++++++++++++ .../Resources/WelcomeBonusDraftResource.php | 3 +- .../NovaTestGeneratorMockTrait.php | 4 +- 7 files changed, 133 insertions(+), 30 deletions(-) create mode 100644 tests/Support/Models/Post.php create mode 100644 tests/Support/Nova/Resources/PostResource.php diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index dc78753d..745ff722 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -32,6 +32,14 @@ public function __construct() public function generate(): void { if (class_exists(NovaServiceProvider::class)) { + if (!$this->classExists('models', $this->model)) { + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->model} does not exist.", + "Create a {$this->model} Model by himself or run command 'php artisan make:entity {$this->model} --only-model'." + ); + } + if (!$this->doesNovaResourceExists()) { $this->throwFailureException( ClassNotExistsException::class, @@ -44,15 +52,7 @@ public function generate(): void $this->throwFailureException( ClassAlreadyExistsException::class, "Cannot create Nova{$this->shortNovaResourceName}Test cause it's already exist.", - "Remove Nova{$this->resourceName}Test." - ); - } - - if (!$this->classExists('models', $this->model)) { - $this->throwFailureException( - ClassNotExistsException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->model} does not exist.", - "Create a {$this->model} Model by himself or run command 'php artisan make:entity {$this->model} --only-model'." + "Remove Nova{$this->shortNovaResourceName}Test." ); } @@ -159,12 +159,12 @@ protected function doesNovaResourceExists(): bool } } - if (count($resources) > 1) { + if (!empty($resources)) { $resources = implode(', ', $resources); $this->throwFailureException( EntityCreateException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause I found a lot of suitable resources: $resources", + "Cannot create Nova{$this->shortNovaResourceName}Test cause I am found a lot of suitable resources: $resources", "Please, use --resource-name option" ); } diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 4004acb1..cd42a184 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -10,7 +10,6 @@ use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\NovaTestGeneratorMockTrait; use Laravel\Nova\NovaServiceProvider; use RonasIT\Support\Tests\Support\Models\WelcomeBonus; -use Mockery; use RonasIT\Support\Exceptions\EntityCreateException; class NovaTestGeneratorTest extends TestCase @@ -29,17 +28,17 @@ public function testGenerateResourceNotExists() $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ - $this->doesNovaResourceExistsCall(false), + $this->classExistsMethodCall(['models', 'News']), ]); $this->assertExceptionThrew( className: ClassNotExistsException::class, - message: 'Cannot create NovaPostResourceTest cause PostResource Nova resource does not exist. Create PostResource Nova resource.', + message: 'Cannot create NovaNewsResourceTest cause NewsResource Nova resource does not exist. Create NewsResource Nova resource.', ); app(NovaTestGenerator::class) - ->setModel('Post') - ->setMetaData(['resource_name' => 'PostResource']) + ->setModel('News') + ->setMetaData(['resource_name' => 'NewsResource']) ->generate(); } @@ -48,6 +47,7 @@ public function testGenerateNovaTestAlreadyExists() $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['models', 'Post']), $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), ]); @@ -58,7 +58,7 @@ className: ClassAlreadyExistsException::class, app(NovaTestGenerator::class) ->setModel('Post') - ->setMetaData(['resource_name' => 'PostResource']) + ->setMetaData(['resource_name' => 'Resources\PostResource']) ->generate(); } @@ -75,8 +75,8 @@ public function testNovaTestStubNotExist() ); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -115,8 +115,8 @@ public function testDumpStubNotExist() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), ]); @@ -145,8 +145,8 @@ public function testSuccess() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -175,16 +175,18 @@ public function testSuccess() public function testWithManySameResources() { - $this->mockNovaServiceProviderExists(); + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + ); $this->assertExceptionThrew( className: EntityCreateException::class, - message: 'Cannot create NovaPostResourceTest cause I found a lot of suitable resources: Resources\PostResource Please, use --resource-name option', + message: 'Cannot create NovaPostResourceTest cause I am found a lot of suitable resources: Resources\PostResource Please, use --resource-name option', ); app(NovaTestGenerator::class) ->setModel('Post') - ->setMetaData(['resource_name' => 'PostResource']) + ->setMetaData(['resource_name' => null]) ->generate(); } @@ -195,8 +197,8 @@ public function testSuccessWithoutSetMetaData() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -230,8 +232,8 @@ public function testSuccessWithNestedFile(): void ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusDraftResourceTest'], false), $this->classExistsMethodCall(['models', 'WelcomeBonus']), + $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusDraftResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), @@ -258,6 +260,22 @@ public function testSuccessWithNestedFile(): void $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/update_welcome_bonus_request.json'); } + public function testSetIncorrectModel(): void + { + $this->mockNovaServiceProviderExists(); + + $this->assertExceptionThrew( + className: ClassNotExistsException::class, + message: "Cannot create NovaSomeUndefinedModelResourceTest cause SomeUndefinedModel does not exist. " + . "Create a SomeUndefinedModel Model by himself or run command 'php artisan make:entity SomeUndefinedModel --only-model'.", + ); + + app(NovaTestGenerator::class) + ->setModel('SomeUndefinedModel') + ->setMetaData(['resource_name' => null]) + ->generate(); + } + public function testGenerateNovaPackageNotInstall() { $this->mockNovaServiceProviderExists(false); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index 738c80da..7fe38067 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -5,7 +5,6 @@ use RonasIT\Support\Generators\NovaTestGenerator; use RonasIT\Support\Tests\Support\FileSystemMock; use RonasIT\Support\Tests\Support\GeneratorMockTrait; -use Mockery; trait CommandMockTrait { @@ -67,6 +66,7 @@ public function mockGenerator(): void $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), ); } + public function mockGeneratorOnlyNovaTests(): void { $this->mockClass(NovaTestGenerator::class, [ @@ -82,8 +82,8 @@ public function mockGeneratorOnlyNovaTests(): void name: 'loadNovaFilters', result: [], ), - $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), $this->classExistsMethodCall(['models', 'Post']), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), $this->classExistsMethodCall(['factories', 'PostFactory']), $this->classExistsMethodCall(['factories', 'PostFactory']), diff --git a/tests/Support/Models/Post.php b/tests/Support/Models/Post.php new file mode 100644 index 00000000..5273b878 --- /dev/null +++ b/tests/Support/Models/Post.php @@ -0,0 +1,25 @@ +novaModels = [ 'WelcomeBonusResource.php' => $this->mockPhpFileContent(), - 'PostResource.php' => $this->mockPhpFileContent(), ]; $fileSystemMock->novaResources = [ @@ -40,7 +39,8 @@ public function mockFilesystem(): void $fileSystemMock->models = [ 'WelcomeBonus.php' => $this->mockPhpFileContent(), - 'WelcomeBonusResource.php' => $this->mockPhpFileContent(), + 'Post.php' => $this->mockPhpFileContent(), + 'News.php' => $this->mockPhpFileContent(), ]; $fileSystemMock->testFixtures = [ From 0fa88db85fb19e7751a94dffe482b13ae8aff625 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 8 Jul 2025 16:26:18 +0300 Subject: [PATCH 11/30] refactor: change isNovaResourceExists method --- src/Generators/NovaTestGenerator.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 745ff722..674d35cb 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -40,13 +40,7 @@ public function generate(): void ); } - if (!$this->doesNovaResourceExists()) { - $this->throwFailureException( - ClassNotExistsException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", - "Create {$this->resourceName} Nova resource." - ); - } + $this->isNovaResourceExists(); if ($this->classExists('nova', "Nova{$this->shortNovaResourceName}Test")) { $this->throwFailureException( @@ -141,7 +135,7 @@ protected function isFixtureNeeded($type): bool return true; } - protected function doesNovaResourceExists(): bool + protected function isNovaResourceExists(): true { $allNovaClasses = $this->getAllNovaClasses(); @@ -169,7 +163,11 @@ protected function doesNovaResourceExists(): bool ); } - return false; + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", + "Create {$this->resourceName} Nova resource." + ); } protected function getAllNovaClasses(): \Generator From 47aed4fbb1bb99b3178ed5cfe64268c2d5343400 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 9 Jul 2025 13:43:30 +0300 Subject: [PATCH 12/30] fix: remove useless --- tests/Support/GeneratorMockTrait.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/Support/GeneratorMockTrait.php b/tests/Support/GeneratorMockTrait.php index 86834f1e..33cec554 100644 --- a/tests/Support/GeneratorMockTrait.php +++ b/tests/Support/GeneratorMockTrait.php @@ -41,15 +41,6 @@ public function classExistsMethodCall(array $arguments, bool $result = true): ar ]; } - public function doesNovaResourceExistsCall(bool $result = true): array - { - return [ - 'function' => 'doesNovaResourceExists', - 'arguments' => [], - 'result' => $result - ]; - } - public function nativeClassExistsMethodCall(array $arguments, bool $result = true): array { return [ From bf4bfc9091d67d78073ee532f9ba2c9dcac47fb5 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 9 Jul 2025 13:47:00 +0300 Subject: [PATCH 13/30] style: import generator --- src/Generators/NovaTestGenerator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 674d35cb..25e97701 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -11,6 +11,7 @@ use RecursiveIteratorIterator; use RecursiveDirectoryIterator; use RonasIT\Support\Exceptions\EntityCreateException; +use Generator; class NovaTestGenerator extends AbstractTestsGenerator { @@ -170,7 +171,7 @@ protected function isNovaResourceExists(): true ); } - protected function getAllNovaClasses(): \Generator + protected function getAllNovaClasses(): Generator { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->novaPath)); From fd12be453b376911b448798f1ddd6fc22ded7f68 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 9 Jul 2025 14:39:38 +0300 Subject: [PATCH 14/30] chore:update readme --- ReadMe.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index ba443670..9b22c8b8 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -123,6 +123,14 @@ Syntax: --only-resource : Set this flag if you want to create only resource. + --only-nova-resource : Set this flag if you want to create only nova resource. + + --only-nova-tests : Set this flag if you want to create only nova resource tests. + + --resource-name[=RESOURCE-NAME] : Override the default (App\\Nova\\ModelResource) Nova resource name. Used only with --only-nova-tests. + + please, use flag variable with double screening and double quotes without Nova directory, for example --resource-name="Resources\\Banner\\BannerResource" + #### Mode combination options --only-entity : Generate stack of classes to work with entity inside the app (Migration/Model/Service/Repository) From a6a2747debbe1c9eaa7b44e39861c5310728fc7e Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 11 Jul 2025 14:26:28 +0300 Subject: [PATCH 15/30] refactor:use common resources --- composer.json | 3 +- src/Generators/NovaTestGenerator.php | 92 +++--- stubs/nova_resource.blade.php | 1 + tests/CommandTest.php | 2 + tests/NovaTestGeneratorTest.php | 64 +++-- tests/Support/Command/CommandMockTrait.php | 2 + tests/Support/Models/News.php | 25 ++ tests/Support/Nova/PostResource.php | 59 ++++ tests/Support/Nova/Resources/PostResource.php | 2 +- tests/Support/Nova/Resources/WelcomeBonus.php | 59 ++++ .../Resources/WelcomeBonusDraftResource.php | 2 +- tests/Support/Nova/WelcomeBonusResource.php | 1 + .../{Nova => NovaResource}/Resource.php | 2 +- .../NovaTestGeneratorMockTrait.php | 1 + tests/fixtures/CommandTest/nova_resource.php | 1 + .../created_resource.php | 1 + ...d_resource_without_command_line_fields.php | 1 + .../create_post_request.json | 4 + .../create_post_response.json | 5 + .../created_post_resource_test.php | 261 ++++++++++++++++++ .../NovaTestGeneratorTest/post_dump.sql | 3 + .../update_post_request.json | 4 + 22 files changed, 533 insertions(+), 62 deletions(-) create mode 100644 tests/Support/Models/News.php create mode 100644 tests/Support/Nova/PostResource.php create mode 100644 tests/Support/Nova/Resources/WelcomeBonus.php rename tests/Support/{Nova => NovaResource}/Resource.php (52%) create mode 100644 tests/fixtures/NovaTestGeneratorTest/create_post_request.json create mode 100644 tests/fixtures/NovaTestGeneratorTest/create_post_response.json create mode 100644 tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php create mode 100644 tests/fixtures/NovaTestGeneratorTest/post_dump.sql create mode 100644 tests/fixtures/NovaTestGeneratorTest/update_post_request.json diff --git a/composer.json b/composer.json index 825c5857..8053b2aa 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,8 @@ "psr-4": { "RonasIT\\Support\\Tests\\": "tests/", "RonasIT\\Support\\Tests\\Support\\": "tests/Support/", - "App\\Nova\\": "tests/Support/Nova/" + "App\\Nova\\": "tests/Support/Nova/", + "Laravel\\Nova\\": "tests/Support/NovaResource" }, "files": [ "tests/TestCase.php" diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 25e97701..b009b9ce 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -15,11 +15,11 @@ class NovaTestGenerator extends AbstractTestsGenerator { - protected string $resourceName; + protected ?string $resourceName; protected ?string $fullNovaResourcePath = null; - protected string $shortNovaResourceName; + protected ?string $shortNovaResourceName; protected string $novaPath; @@ -36,7 +36,7 @@ public function generate(): void if (!$this->classExists('models', $this->model)) { $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->model} does not exist.", + "Cannot create Nova{$this->model}Resource Test cause {$this->model} does not exist.", "Create a {$this->model} Model by himself or run command 'php artisan make:entity {$this->model} --only-model'." ); } @@ -59,11 +59,7 @@ public function generate(): void public function setMetaData(array $data): self { - $resourceName = empty($data['resource_name']) ? "{$this->model}Resource" : $data['resource_name']; - - $this->resourceName = Str::studly($resourceName); - - $this->shortNovaResourceName = Str::afterLast($this->resourceName, '\\'); + $this->resourceName = !empty($data['resource_name']) ? Str::studly($data['resource_name']) : null; return $this; } @@ -136,42 +132,44 @@ protected function isFixtureNeeded($type): bool return true; } - protected function isNovaResourceExists(): true + protected function isNovaResourceExists(): void { - $allNovaClasses = $this->getAllNovaClasses(); + $resource = $this->getNovaResource(); - $resources = []; + $this->shortNovaResourceName = Str::afterLast($resource, '\\'); + $this->fullNovaResourcePath = "App\\Nova\\{$resource}"; - foreach ($allNovaClasses as $class) { - if ($class === $this->resourceName) { - $this->fullNovaResourcePath = "App\\Nova\\{$this->resourceName}"; + if (!class_exists($this->fullNovaResourcePath)) { + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", + "Create {$this->resourceName} Nova resource." + ); + } + } - return true; - } + protected function getNovaResource(): ?string + { + if (!empty($this->resourceName)) { + return $this->resourceName; + } else { + $commonResources = $this->getCommonNovaResources(); - if (Str::contains($class, $this->model) && is_subclass_of("App\\Nova\\{$class}", "App\\Nova\\Resource")) { - $resources[] = $class; - } - } + if (count($commonResources) > 1) { + $commonResources = implode(', ', $commonResources); - if (!empty($resources)) { - $resources = implode(', ', $resources); + $this->throwFailureException( + EntityCreateException::class, + "Cannot create Nova{$this->model}Resource Test cause was found a lot of suitable resources: $commonResources", + "Please, use --resource-name option" + ); + } - $this->throwFailureException( - EntityCreateException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause I am found a lot of suitable resources: $resources", - "Please, use --resource-name option" - ); + return $commonResources[0]; } - - $this->throwFailureException( - ClassNotExistsException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", - "Create {$this->resourceName} Nova resource." - ); } - protected function getAllNovaClasses(): Generator + protected function allCommonNovaResources(): Generator { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->novaPath)); @@ -179,11 +177,35 @@ protected function getAllNovaClasses(): Generator if ($file->isFile() && $file->getExtension() === 'php') { $relativePath = Str::after($file->getPathname(), $this->novaPath . DIRECTORY_SEPARATOR); - yield str_replace(['/', '.php'], ['\\', ''], $relativePath); + $class = str_replace(['/', '.php'], ['\\', ''], $relativePath); + + if($this->isValidCommonResourceCheck($class)){ + yield $class; + } } } } + protected function getCommonNovaResources(): array + { + $commonNovaResources = $this->allCommonNovaResources(); + + $resources = []; + + foreach ($commonNovaResources as $resource) { + $resources[] = $resource; + } + + return $resources; + } + + protected function isValidCommonResourceCheck(string $resource) + { + $isContainModel = Str::afterLast(str_replace('Resource', '', $resource), '\\') === $this->model; + + return is_subclass_of("App\\Nova\\{$resource}", "Laravel\\Nova\\Resource") && $isContainModel; + } + protected function collectFilters(): array { $filtersFromFields = $this->getFiltersFromFields(); diff --git a/stubs/nova_resource.blade.php b/stubs/nova_resource.blade.php index 760d5af9..c51e3512 100644 --- a/stubs/nova_resource.blade.php +++ b/stubs/nova_resource.blade.php @@ -6,6 +6,7 @@ @foreach($types as $fieldType) use Laravel\Nova\Fields\{{$fieldType}}; @endforeach +use Laravel\Nova\Resource; class {{$model}}Resource extends Resource { diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 7502a507..f60804db 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -8,6 +8,7 @@ use RonasIT\Support\Tests\Support\Command\CommandMockTrait; use RonasIT\Support\Tests\Support\Command\Models\Post; use UnexpectedValueException; +use App\Nova\PostResource; class CommandTest extends TestCase { @@ -51,6 +52,7 @@ public function testCallCommand() $this->mockGenerator(); $this->mockGettingModelInstance(new Post()); + $this->app->instance(PostResource::class, new PostResource()); $this->mockDBTransactionStartRollback(2); $this diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index cd42a184..af06d88a 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -11,6 +11,7 @@ use Laravel\Nova\NovaServiceProvider; use RonasIT\Support\Tests\Support\Models\WelcomeBonus; use RonasIT\Support\Exceptions\EntityCreateException; +use RonasIT\Support\Tests\Support\Models\Post; class NovaTestGeneratorTest extends TestCase { @@ -25,12 +26,15 @@ public function setUp(): void public function testGenerateResourceNotExists() { - $this->mockNovaServiceProviderExists(); - $this->mockClass(NovaTestGenerator::class, [ $this->classExistsMethodCall(['models', 'News']), ]); + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\NewsResource"], false), + ); + $this->assertExceptionThrew( className: ClassNotExistsException::class, message: 'Cannot create NovaNewsResourceTest cause NewsResource Nova resource does not exist. Create NewsResource Nova resource.', @@ -44,13 +48,16 @@ className: ClassNotExistsException::class, public function testGenerateNovaTestAlreadyExists() { - $this->mockNovaServiceProviderExists(); - $this->mockClass(NovaTestGenerator::class, [ $this->classExistsMethodCall(['models', 'Post']), $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), ]); + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\Resources\PostResource"]), + ); + $this->assertExceptionThrew( className: ClassAlreadyExistsException::class, message: "Cannot create NovaPostResourceTest cause it's already exist. Remove NovaPostResourceTest.", @@ -71,6 +78,7 @@ public function testNovaTestStubNotExist() $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\WelcomeBonusResource"]), $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), ); @@ -105,8 +113,6 @@ className: WarningEvent::class, public function testDumpStubNotExist() { - $this->mockNovaServiceProviderExists(); - $this->mockNovaRequestClassCall(); config([ @@ -121,6 +127,11 @@ public function testDumpStubNotExist() $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), ]); + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\WelcomeBonusResource"]), + ); + app(NovaTestGenerator::class) ->setModel('WelcomeBonus') ->setMetaData(['resource_name' => 'WelcomeBonusResource']) @@ -156,6 +167,7 @@ public function testSuccess() $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\WelcomeBonusResource"]), $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), ); @@ -175,17 +187,21 @@ public function testSuccess() public function testWithManySameResources() { - $this->mockNativeGeneratorFunctions( - $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), - ); + $this->mockNovaServiceProviderExists(); + + $this->mockNovaRequestClassCall(); + + $this->mockClass(NovaTestGenerator::class, [ + $this->classExistsMethodCall(['models', 'WelcomeBonus']), + ]); $this->assertExceptionThrew( className: EntityCreateException::class, - message: 'Cannot create NovaPostResourceTest cause I am found a lot of suitable resources: Resources\PostResource Please, use --resource-name option', + message: 'Cannot create NovaWelcomeBonusResource Test cause was found a lot of suitable resources: WelcomeBonusResource, Resources\WelcomeBonus Please, use --resource-name option', ); app(NovaTestGenerator::class) - ->setModel('Post') + ->setModel('WelcomeBonus') ->setMetaData(['resource_name' => null]) ->generate(); } @@ -197,32 +213,33 @@ public function testSuccessWithoutSetMetaData() ]); $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['models', 'WelcomeBonus']), - $this->classExistsMethodCall(['nova', 'NovaWelcomeBonusResourceTest'], false), + $this->classExistsMethodCall(['models', 'Post']), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), - $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), - $this->classExistsMethodCall(['factories', 'WelcomeBonusFactory'], false), + $this->classExistsMethodCall(['factories', 'PostFactory'], false), + $this->classExistsMethodCall(['factories', 'PostFactory'], false), ]); $this->mockDBTransactionStartRollback(); $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), - $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), + $this->nativeClassExistsMethodCall(["App\Nova\Resources\PostResource"]), + $this->nativeClassExistsMethodCall([Post::class, true]), ); $this->mockNovaRequestClassCall(); app(NovaTestGenerator::class) - ->setModel('WelcomeBonus') + ->setModel('Post') ->setMetaData(['resource_name' => null]) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); - $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('created_post_resource_test.php', 'tests/NovaPostResourceTest.php'); + $this->assertGeneratedFileEquals('post_dump.sql', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); + $this->assertGeneratedFileEquals('create_post_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); + $this->assertGeneratedFileEquals('create_post_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); + $this->assertGeneratedFileEquals('update_post_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); } public function testSuccessWithNestedFile(): void @@ -243,6 +260,7 @@ public function testSuccessWithNestedFile(): void $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall(['App\Nova\Resources\WelcomeBonusDraftResource']), $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), ); @@ -266,7 +284,7 @@ public function testSetIncorrectModel(): void $this->assertExceptionThrew( className: ClassNotExistsException::class, - message: "Cannot create NovaSomeUndefinedModelResourceTest cause SomeUndefinedModel does not exist. " + message: "Cannot create NovaSomeUndefinedModelResource Test cause SomeUndefinedModel does not exist. " . "Create a SomeUndefinedModel Model by himself or run command 'php artisan make:entity SomeUndefinedModel --only-model'.", ); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index 7fe38067..e7ab624a 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -63,6 +63,7 @@ public function mockGenerator(): void $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), + $this->nativeClassExistsMethodCall(['App\Nova\PostResource']), $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), ); } @@ -93,6 +94,7 @@ public function mockGeneratorOnlyNovaTests(): void $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), + $this->nativeClassExistsMethodCall(['App\Nova\PostResource']), $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), ); } diff --git a/tests/Support/Models/News.php b/tests/Support/Models/News.php new file mode 100644 index 00000000..e1c6c5ac --- /dev/null +++ b/tests/Support/Models/News.php @@ -0,0 +1,25 @@ +novaResources = [ 'WelcomeBonusDraftResource.php' => $this->mockPhpFileContent(), + 'WelcomeBonus.php' => $this->mockPhpFileContent(), 'PostResource.php' => $this->mockPhpFileContent(), ]; diff --git a/tests/fixtures/CommandTest/nova_resource.php b/tests/fixtures/CommandTest/nova_resource.php index b653b10b..a43b5419 100644 --- a/tests/fixtures/CommandTest/nova_resource.php +++ b/tests/fixtures/CommandTest/nova_resource.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use Laravel\Nova\Fields\ID; use Laravel\Nova\Fields\Text; +use Laravel\Nova\Resource; class PostResource extends Resource { diff --git a/tests/fixtures/NovaResourceGeneratorTest/created_resource.php b/tests/fixtures/NovaResourceGeneratorTest/created_resource.php index 742c6158..f0de6419 100644 --- a/tests/fixtures/NovaResourceGeneratorTest/created_resource.php +++ b/tests/fixtures/NovaResourceGeneratorTest/created_resource.php @@ -7,6 +7,7 @@ use Laravel\Nova\Fields\Boolean; use Laravel\Nova\Fields\Text; use Laravel\Nova\Fields\ID; +use Laravel\Nova\Resource; class PostResource extends Resource { diff --git a/tests/fixtures/NovaResourceGeneratorTest/created_resource_without_command_line_fields.php b/tests/fixtures/NovaResourceGeneratorTest/created_resource_without_command_line_fields.php index 9d3f57e1..7ae28fb4 100644 --- a/tests/fixtures/NovaResourceGeneratorTest/created_resource_without_command_line_fields.php +++ b/tests/fixtures/NovaResourceGeneratorTest/created_resource_without_command_line_fields.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use Laravel\Nova\Fields\ID; use Laravel\Nova\Fields\Text; +use Laravel\Nova\Resource; class PostResource extends Resource { diff --git a/tests/fixtures/NovaTestGeneratorTest/create_post_request.json b/tests/fixtures/NovaTestGeneratorTest/create_post_request.json new file mode 100644 index 00000000..538b482c --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/create_post_request.json @@ -0,0 +1,4 @@ +{ + "title": 1, + "name": 1 +} \ No newline at end of file diff --git a/tests/fixtures/NovaTestGeneratorTest/create_post_response.json b/tests/fixtures/NovaTestGeneratorTest/create_post_response.json new file mode 100644 index 00000000..ea1ee8ea --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/create_post_response.json @@ -0,0 +1,5 @@ +{ + "id": 1, + "title": 1, + "name": 1 +} \ No newline at end of file diff --git a/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php new file mode 100644 index 00000000..c3ce5c8d --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php @@ -0,0 +1,261 @@ +skipDocumentationCollecting(); + } + + public function testCreate(): void + { + $data = $this->getJsonFixture('create_post_request'); + + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(Post::class, $data); + + $response->assertCreated(); + + $this->assertEqualsFixture('create_post_response', $response->json()); + + // TODO: Need to remove last argument after first successful start + self::$postState->assertChangesEqualsFixture('create_posts_state', true); + } + + public function testCreateNoAuth(): void + { + $response = $this->novaCreateResourceAPICall(Post::class); + + $response->assertUnauthorized(); + + self::$postState->assertNotChanged(); + } + + public function testCreateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(Post::class); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('create_validation_response', $response->json(), true); + + self::$postState->assertNotChanged(); + } + + public function testUpdate(): void + { + $data = $this->getJsonFixture('update_post_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 1, $data); + + $response->assertNoContent(); + + // TODO: Need to remove last argument after first successful start + self::$postState->assertChangesEqualsFixture('update_posts_state', true); + } + + public function testUpdateNotExists(): void + { + $data = $this->getJsonFixture('update_post_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 0, $data); + + $response->assertNotFound(); + } + + public function testUpdateNoAuth(): void + { + $response = $this->novaUpdateResourceAPICall(Post::class, 1); + + $response->assertUnauthorized(); + } + + public function testUpdateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 4); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('update_validation_response', $response->json(), true); + } + + public function testGetUpdatableFields(): void + { + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(Post::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_updatable_fields_response', $response->json(), true); + } + + public function testDelete(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(Post::class, [1, 2]); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + self::$postState->assertChangesEqualsFixture('delete_posts_state', true); + } + + public function testDeleteNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(Post::class, [0]); + + $response->assertNotFound(); + } + + public function testDeleteNoAuth(): void + { + $response = $this->novaDeleteResourceAPICall(Post::class, [1, 2]); + + $response->assertUnauthorized(); + } + + public function testGet(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(Post::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_post_response', $response->json(), true); + } + + public function testGetNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(Post::class, 0); + + $response->assertNotFound(); + } + + public function testGetNoAuth(): void + { + $response = $this->novaGetResourceAPICall(Post::class, 1); + + $response->assertUnauthorized(); + } + + public function testSearchUnauthorized(): void + { + $response = $this->novaSearchResourceAPICall(Post::class); + + $response->assertUnauthorized(); + } + + public function testGetFieldsVisibleOnCreate(): void + { + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(Post::class); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); + } + + public static function getRunPostActionsData(): array + { + return [ + [ + 'action' => PublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_publish_post_action_state', + ], + [ + 'action' => UnPublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_un_publish_post_action_state', + ], + ]; + } + + #[DataProvider('getRunPostActionsData')] + public function testRunPostActions($action, $request, $state): void + { + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(Post::class, $action, $request); + + $response->assertOk(); + + $this->assertEmpty($response->getContent()); + + // TODO: Need to remove last argument after first successful start + self::$postState->assertChangesEqualsFixture($state, true); + } + + public static function getPostActionsData(): array + { + return [ + [ + 'resources' => [1, 2], + 'fixture' => 'get_post_actions_publish_post_action', + ], + [ + 'resources' => [1, 2], + 'fixture' => 'get_post_actions_un_publish_post_action', + ], + ]; + } + + #[DataProvider('getPostActionsData')] + public function testGetPostActions(array $resources, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(Post::class, $resources); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } + + public static function getPostFiltersData(): array + { + return [ + [ + 'request' => [ + 'TextField:description_field' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_post_by_text_field', + ], + [ + 'request' => [ + 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_post_by_created_at_filter', + ], + ]; + } + + #[DataProvider('getPostFiltersData')] + public function testFilterPost(array $request, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(Post::class, $request); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } +} diff --git a/tests/fixtures/NovaTestGeneratorTest/post_dump.sql b/tests/fixtures/NovaTestGeneratorTest/post_dump.sql new file mode 100644 index 00000000..15371a53 --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/post_dump.sql @@ -0,0 +1,3 @@ +INSERT INTO "posts"(id, title, name, created_at, updated_at) VALUES + (1, 1, 1, '2016-10-20 11:05:00', '2016-10-20 11:05:00'); + diff --git a/tests/fixtures/NovaTestGeneratorTest/update_post_request.json b/tests/fixtures/NovaTestGeneratorTest/update_post_request.json new file mode 100644 index 00000000..538b482c --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/update_post_request.json @@ -0,0 +1,4 @@ +{ + "title": 1, + "name": 1 +} \ No newline at end of file From f3fa391a173fd50c33fb72554890711d69d0b7b3 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Fri, 11 Jul 2025 15:46:37 +0300 Subject: [PATCH 16/30] style:fix --- src/Generators/NovaTestGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index b009b9ce..ce8c4bdc 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -179,7 +179,7 @@ protected function allCommonNovaResources(): Generator $class = str_replace(['/', '.php'], ['\\', ''], $relativePath); - if($this->isValidCommonResourceCheck($class)){ + if ($this->isValidCommonResourceCheck($class)) { yield $class; } } From d0cc813915f8e2ad4805a16df0fb567febb1dcf0 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 2 Sep 2025 15:45:58 +0300 Subject: [PATCH 17/30] refactor: remove useless from generator --- src/Generators/NovaTestGenerator.php | 81 +++++++++++++--------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index ce8c4bdc..d37ec09b 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -41,7 +41,19 @@ public function generate(): void ); } - $this->isNovaResourceExists(); + $resource = $this->resourceName ?? $this->getNovaResource(); + + $this->shortNovaResourceName = Str::afterLast($resource, '\\'); + + $this->fullNovaResourcePath = "App\\Nova\\{$resource}"; + + if (!class_exists($this->fullNovaResourcePath)) { + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", + "Create {$this->resourceName} Nova resource." + ); + } if ($this->classExists('nova', "Nova{$this->shortNovaResourceName}Test")) { $this->throwFailureException( @@ -132,78 +144,59 @@ protected function isFixtureNeeded($type): bool return true; } - protected function isNovaResourceExists(): void + protected function getNovaResource(): string { - $resource = $this->getNovaResource(); + $commonResources = $this->getCommonNovaResources(); - $this->shortNovaResourceName = Str::afterLast($resource, '\\'); - $this->fullNovaResourcePath = "App\\Nova\\{$resource}"; + if (count($commonResources) > 1) { + $commonResources = implode(', ', $commonResources); - if (!class_exists($this->fullNovaResourcePath)) { $this->throwFailureException( - ClassNotExistsException::class, - "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->resourceName} Nova resource does not exist.", - "Create {$this->resourceName} Nova resource." + EntityCreateException::class, + "Cannot create Nova{$this->model}Resource Test cause was found a lot of suitable resources: $commonResources", + "Please, use --resource-name option" ); } - } - - protected function getNovaResource(): ?string - { - if (!empty($this->resourceName)) { - return $this->resourceName; - } else { - $commonResources = $this->getCommonNovaResources(); - - if (count($commonResources) > 1) { - $commonResources = implode(', ', $commonResources); - $this->throwFailureException( - EntityCreateException::class, - "Cannot create Nova{$this->model}Resource Test cause was found a lot of suitable resources: $commonResources", - "Please, use --resource-name option" - ); - } - - return $commonResources[0]; - } + return array_pop($commonResources); } - protected function allCommonNovaResources(): Generator + protected function getNovaFiles(): Generator { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->novaPath)); foreach ($iterator as $file) { if ($file->isFile() && $file->getExtension() === 'php') { - $relativePath = Str::after($file->getPathname(), $this->novaPath . DIRECTORY_SEPARATOR); - - $class = str_replace(['/', '.php'], ['\\', ''], $relativePath); - - if ($this->isValidCommonResourceCheck($class)) { - yield $class; - } + yield $file; } } } protected function getCommonNovaResources(): array { - $commonNovaResources = $this->allCommonNovaResources(); - $resources = []; - foreach ($commonNovaResources as $resource) { - $resources[] = $resource; + foreach ($this->getNovaFiles() as $file) { + $relativePath = Str::after($file->getPathname(), $this->novaPath . DIRECTORY_SEPARATOR); + + $class = str_replace(['/', '.php'], ['\\', ''], $relativePath); + + if ($this->isNovaResource($class) && $this->isResourceNameContainModel($class)) { + $resources[] = $class; + } } return $resources; } - protected function isValidCommonResourceCheck(string $resource) + protected function isNovaResource(string $resource): bool { - $isContainModel = Str::afterLast(str_replace('Resource', '', $resource), '\\') === $this->model; + return is_subclass_of("App\\Nova\\{$resource}", "Laravel\\Nova\\Resource"); + } - return is_subclass_of("App\\Nova\\{$resource}", "Laravel\\Nova\\Resource") && $isContainModel; + protected function isResourceNameContainModel(string $resource): bool + { + return Str::afterLast(str_replace('Resource', '', $resource), '\\') === $this->model; } protected function collectFilters(): array From 316eed104dbc9466979efc3dd70a98ca619a16fa Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 16 Sep 2025 18:22:35 +0300 Subject: [PATCH 18/30] refactor: correct set resource instead model --- .env.testing | 1 + src/Generators/NovaTestGenerator.php | 76 +++-- tests/CommandTest.php | 16 +- tests/NovaTestGeneratorTest.php | 50 +--- tests/Support/Command/CommandMockTrait.php | 1 + tests/Support/Nova/Forum/PostResource.php | 46 +-- tests/Support/Nova/Resources/PostResource.php | 1 - tests/Support/Nova/Resources/WelcomeBonus.php | 1 - .../NovaTestGeneratorMockTrait.php | 4 - .../created_post_resource_test.php | 79 +++--- .../created_resource_test.php | 78 +++--- .../created_welcome_bonus_resource_test.php | 262 ++++++++++++++++++ ...ted_welcome_bonuse_draft_resource_test.php | 262 ++++++++++++++++++ 13 files changed, 686 insertions(+), 191 deletions(-) create mode 100644 .env.testing create mode 100644 tests/fixtures/NovaTestGeneratorTest/created_welcome_bonus_resource_test.php create mode 100644 tests/fixtures/NovaTestGeneratorTest/created_welcome_bonuse_draft_resource_test.php diff --git a/.env.testing b/.env.testing new file mode 100644 index 00000000..b0c62306 --- /dev/null +++ b/.env.testing @@ -0,0 +1 @@ +FAIL_EXPORT_JSON=false \ No newline at end of file diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index ea00cb6a..f1168e50 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -33,7 +33,7 @@ public function __construct() public function generate(): void { if (class_exists(NovaServiceProvider::class)) { - if (!$this->classExists('models', $this->model)) { + if (!$this->classExists('models', $this->model, $this->modelSubFolder)) { $this->throwFailureException( ClassNotExistsException::class, "Cannot create Nova{$this->model}Resource Test cause {$this->model} does not exist.", @@ -41,30 +41,45 @@ public function generate(): void ); } - $novaResources = $this->getCommonNovaResources(); + if (empty($this->novaResourceName)) { - if (count($novaResources) > 1){ - $foundedResources = implode(', ', $novaResources); + $novaResources = $this->getCommonNovaResources(); - // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 - $this->throwFailureException( - EntityCreateException::class, - "Cannot create Nova{$this->model}ResourceTest cause was found a lot of suitable resources: {$foundedResources}.", - 'Make test by yourself.' - ); + if (count($novaResources) > 1) { + $foundedResources = implode(', ', $novaResources); + + // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 + $this->throwFailureException( + EntityCreateException::class, + "Cannot create Nova{$this->model}ResourceTest cause was found a lot of suitable resources: {$foundedResources}.", + 'Please, use --resource-name option.' + ); + } + + if (empty($novaResources)) { + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.", + "Create {$this->model} Nova resource." + ); + } + + $this->novaResourceName = array_pop($novaResources); } - if (empty($novaResources)) { + $this->shortNovaResourceName = Str::afterLast($this->novaResourceName, '\\'); + + $this->fullNovaResourcePath = "App\\Nova\\{$this->novaResourceName}"; + + if (!class_exists($this->fullNovaResourcePath)) { $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.", - "Create {$this->model} Nova resource." + "Cannot create Nova{$this->shortNovaResourceName}Test cause {$this->novaResourceName} Nova resource does not exist.", + "Create {$this->novaResourceName} Nova resource." ); } - $this->novaResourceName = array_pop($novaResources); - - if ($this->classExists('nova', "Nova{$this->model}Test")) { + if ($this->classExists('nova', "Nova{$this->shortNovaResourceName}Test")) { $this->throwFailureException( ClassAlreadyExistsException::class, "Cannot create Nova{$this->model}ResourceTest cause it's already exist.", @@ -94,25 +109,23 @@ public function generateTests(): void $actions = $this->getActions(); $filters = $this->collectFilters(); - $resourceClass = Str::afterLast($this->novaResourceName, '\\'); - $fileContent = $this->getStub('nova_test', [ 'url_path' => Str::kebab($this->model) . '-resources', 'entity_namespace' => $this->getOrCreateNamespace('models', $this->modelSubFolder), 'entity' => $this->model, - 'resource' => $resourceClass, + 'resource' => $this->shortNovaResourceName, 'resource_path' => "App\\Nova\\{$this->novaResourceName}", 'entities' => $this->getPluralName($this->model), - 'snake_resource' => Str::snake($resourceClass), + 'snake_resource' => Str::snake($this->shortNovaResourceName), 'dromedary_entity' => Str::lcfirst($this->model), 'lower_entities' => $this->getPluralName(Str::snake($this->model)), 'actions' => $actions, 'filters' => $filters, ]); - $this->saveClass('tests', "Nova{$resourceClass}Test", $fileContent); + $this->saveClass('tests', "Nova{$this->shortNovaResourceName}Test", $fileContent); - event(new SuccessCreateMessage("Created a new Nova test: Nova{$resourceClass}Test")); + event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->shortNovaResourceName}Test")); } protected function getActions(): array @@ -198,23 +211,6 @@ protected function isFixtureNeeded($type): bool return true; } - protected function getNovaResource(): string - { - $commonResources = $this->getCommonNovaResources(); - - if (count($commonResources) > 1) { - $commonResources = implode(', ', $commonResources); - - $this->throwFailureException( - EntityCreateException::class, - "Cannot create Nova{$this->model}Resource Test cause was found a lot of suitable resources: $commonResources", - "Please, use --resource-name option" - ); - } - - return array_pop($commonResources); - } - protected function collectFilters(): array { $filtersFromFields = $this->getFiltersFromFields(); @@ -250,7 +246,7 @@ protected function getFiltersFromFields(): array protected function getFilters(): array { - $filters = []; + $filters= []; $novaResourceFilters = $this->loadNovaFilters(); foreach ($novaResourceFilters as $filter) { diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 0a97fbe9..1ba1220c 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -92,10 +92,10 @@ public function testCallCommand() $this->assertGeneratedFileEquals('validation.php', 'lang/en/validation.php'); $this->assertGeneratedFileEquals('nova_resource.php', 'app/Nova/PostResource.php'); $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostResourceTest.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); } public function testCallCommandSubFoldersModel() @@ -138,10 +138,10 @@ public function testCallCommandSubFoldersModel() $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/PostTest/create_post_response.json'); $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/PostTest/update_post_request.json'); $this->assertGeneratedFileEquals('validation.php', 'lang/en/validation.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); } public function testMakeOnly() diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 635ead2d..1aacddce 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -10,10 +10,8 @@ use RonasIT\Support\Generators\NovaTestGenerator; use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\NovaTestGeneratorMockTrait; use Laravel\Nova\NovaServiceProvider; -use RonasIT\Support\Tests\Support\Models\WelcomeBonus; use RonasIT\Support\Exceptions\EntityCreateException; use RonasIT\Support\Tests\Support\Models\Post; -use RonasIT\Support\Exceptions\EntityCreateException; class NovaTestGeneratorTest extends TestCase { @@ -44,41 +42,16 @@ className: ClassNotExistsException::class, ->generate(); } - public function testGenerateToManyResources(): void - { - $this->mockNovaServiceProviderExists(); - - $this->mockClass(NovaTestGenerator::class, [ - $this->getCommonNovaResourcesMock([ - 'BasePostResource', - 'PublishPostResource', - ]), - ]); - - $this->assertExceptionThrew( - className: EntityCreateException::class, - message: 'Cannot create NovaNewsResourceTest cause NewsResource Nova resource does not exist. Create NewsResource Nova resource.', - ); - - app(NovaTestGenerator::class) - ->setModel('News') - ->setMetaData(['resource_name' => 'NewsResource']) - ->generate(); - } - public function testGenerateNovaTestAlreadyExists() { - $this->mockNovaServiceProviderExists(); - $this->mockClass(NovaTestGenerator::class, [ - $this->classExistsMethodCall(['nova', 'NovaPostTest']), $this->classExistsMethodCall(['models', 'Post']), $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), ]); $this->mockNativeGeneratorFunctions( - $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), - $this->nativeClassExistsMethodCall(["App\Nova\Resources\PostResource"]), + $this->nativeClassExistsMethodCall([NovaServiceProvider::class]), + $this->nativeClassExistsMethodCall(["App\Nova\PostResource"]), ); $this->assertExceptionThrew( @@ -88,7 +61,7 @@ className: ClassAlreadyExistsException::class, app(NovaTestGenerator::class) ->setModel('Post') - ->setMetaData(['resource_name' => 'Resources\PostResource']) + ->setMetaData(['resource_name' => 'PostResource']) ->generate(); } @@ -165,11 +138,11 @@ public function testDumpStubNotExist() ->setMetaData(['resource_name' => 'WelcomeBonusResource']) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('created_welcome_bonus_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_request.json'); $this->assertEventPushed( className: WarningEvent::class, @@ -206,7 +179,7 @@ public function testSuccess() ->setMetaData(['resource_name' => 'WelcomeBonusResource']) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('created_welcome_bonus_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_dump.sql'); $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_request.json'); $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_response.json'); @@ -225,7 +198,7 @@ public function testWithManySameResources() $this->assertExceptionThrew( className: EntityCreateException::class, - message: 'Cannot create NovaWelcomeBonusResource Test cause was found a lot of suitable resources: WelcomeBonusResource, Resources\WelcomeBonus Please, use --resource-name option', + message: 'Cannot create NovaWelcomeBonusResourceTest cause was found a lot of suitable resources: WelcomeBonusResource, Resources\WelcomeBonus. Please, use --resource-name option.', ); app(NovaTestGenerator::class) @@ -241,6 +214,9 @@ public function testSuccessWithoutSetMetaData() ]); $this->mockClass(NovaTestGenerator::class, [ + $this->getCommonNovaResourcesMock([ + 'Resources\PostResource', + ]), $this->classExistsMethodCall(['models', 'Post']), $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), $this->classExistsMethodCall(['models', 'User'], false), @@ -299,7 +275,7 @@ public function testSuccessWithNestedFile(): void ->setMetaData(['resource_name' => 'Resources\WelcomeBonusDraftResource']) ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusDraftResourceTest.php'); + $this->assertGeneratedFileEquals('created_welcome_bonuse_draft_resource_test.php', 'tests/NovaWelcomeBonusDraftResourceTest.php'); $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/nova_welcome_bonus_dump.sql'); $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_request.json'); $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_response.json'); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index 645614fa..8cecdd96 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -120,6 +120,7 @@ public function mockGeneratorSubFolders(): void $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Forum\Post', true]), $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), + $this->nativeClassExistsMethodCall(['App\Nova\Forum\PostResource']), $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Forum\Post', true]), ); } diff --git a/tests/Support/Nova/Forum/PostResource.php b/tests/Support/Nova/Forum/PostResource.php index 59b444e5..74cbb371 100644 --- a/tests/Support/Nova/Forum/PostResource.php +++ b/tests/Support/Nova/Forum/PostResource.php @@ -2,57 +2,59 @@ namespace App\Nova\Forum; +use RonasIT\Support\Tests\Support\Command\Models\Forum\Post; +use Illuminate\Http\Request; use Laravel\Nova\Fields\ID; use Laravel\Nova\Fields\Text; -use Laravel\Nova\Http\Requests\NovaRequest; -use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter; -use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\DateField; -use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\PublishPostAction; -use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\TextField; -use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\UnPublishPostAction; use Laravel\Nova\Resource; class PostResource extends Resource { + public static $model = Post::class; + + //TODO change field for the title if it required public static $title = 'name'; + //TODO change query fields if it required public static $search = ['id', 'name']; public static function label(): string { - return 'Post'; + return 'Posts'; } - public function fields(NovaRequest $request): array + public function fields(Request $request): array { return [ - new TextField, - new DateField, + ID::make('Id') + ->required() + ->sortable(), + Text::make('Title') + ->required() + ->sortable(), + Text::make('Created At') + ->required() + ->sortable(), ]; } - public function cards(NovaRequest $request): array + public function cards(Request $request): array { return []; } - public function filters(NovaRequest $request): array + public function filters(Request $request): array { - return [ - new CreatedAtFilter, - ]; + return []; } - public function lenses(NovaRequest $request): array + public function lenses(Request $request): array { return []; } - public function actions(NovaRequest $request): array + public function actions(Request $request): array { - return [ - new PublishPostAction, - new UnPublishPostAction, - ]; + return []; } -} \ No newline at end of file +} diff --git a/tests/Support/Nova/Resources/PostResource.php b/tests/Support/Nova/Resources/PostResource.php index 5fc5c260..4c339447 100644 --- a/tests/Support/Nova/Resources/PostResource.php +++ b/tests/Support/Nova/Resources/PostResource.php @@ -53,7 +53,6 @@ public function actions(NovaRequest $request): array return [ new PublishPostAction, new UnPublishPostAction, - new UnPublishPostAction, ]; } } diff --git a/tests/Support/Nova/Resources/WelcomeBonus.php b/tests/Support/Nova/Resources/WelcomeBonus.php index 9fff772e..15722be9 100644 --- a/tests/Support/Nova/Resources/WelcomeBonus.php +++ b/tests/Support/Nova/Resources/WelcomeBonus.php @@ -53,7 +53,6 @@ public function actions(NovaRequest $request): array return [ new PublishPostAction, new UnPublishPostAction, - new UnPublishPostAction, ]; } } diff --git a/tests/Support/NovaTestGeneratorTest/NovaTestGeneratorMockTrait.php b/tests/Support/NovaTestGeneratorTest/NovaTestGeneratorMockTrait.php index 0e0748ce..d6c58450 100644 --- a/tests/Support/NovaTestGeneratorTest/NovaTestGeneratorMockTrait.php +++ b/tests/Support/NovaTestGeneratorTest/NovaTestGeneratorMockTrait.php @@ -45,10 +45,6 @@ public function mockFilesystem(): void 'News.php' => $this->mockPhpFileContent(), ]; - $fileSystemMock->testFixtures = [ - 'NovaWelcomeBonusTest' => [] - ]; - $fileSystemMock->setStructure(); } } diff --git a/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php index c3ce5c8d..e17d2518 100644 --- a/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php +++ b/tests/fixtures/NovaTestGeneratorTest/created_post_resource_test.php @@ -2,12 +2,13 @@ namespace App\Tests; -use App\Models\Post; +use RonasIT\Support\Tests\Support\Models\Post; use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; +use App\Nova\Resources\PostResource; -class NovaPostTest extends TestCase +class NovaPostResourceTest extends TestCase { use NovaTestTrait; @@ -26,13 +27,13 @@ public function setUp(): void public function testCreate(): void { - $data = $this->getJsonFixture('create_post_request'); + $data = $this->getJsonFixture('create_post_resource_request'); - $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(Post::class, $data); + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(PostResource::class, $data); $response->assertCreated(); - $this->assertEqualsFixture('create_post_response', $response->json()); + $this->assertEqualsFixture('create_post_resource_response', $response->json()); // TODO: Need to remove last argument after first successful start self::$postState->assertChangesEqualsFixture('create_posts_state', true); @@ -40,7 +41,7 @@ public function testCreate(): void public function testCreateNoAuth(): void { - $response = $this->novaCreateResourceAPICall(Post::class); + $response = $this->novaCreateResourceAPICall(PostResource::class); $response->assertUnauthorized(); @@ -49,7 +50,7 @@ public function testCreateNoAuth(): void public function testCreateValidationError(): void { - $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(Post::class); + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(PostResource::class); $response->assertUnprocessable(); @@ -61,9 +62,9 @@ public function testCreateValidationError(): void public function testUpdate(): void { - $data = $this->getJsonFixture('update_post_request'); + $data = $this->getJsonFixture('update_post_resource_request'); - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 1, $data); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(PostResource::class, 1, $data); $response->assertNoContent(); @@ -73,23 +74,23 @@ public function testUpdate(): void public function testUpdateNotExists(): void { - $data = $this->getJsonFixture('update_post_request'); + $data = $this->getJsonFixture('update_post_resource_request'); - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 0, $data); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(PostResource::class, 0, $data); $response->assertNotFound(); } public function testUpdateNoAuth(): void { - $response = $this->novaUpdateResourceAPICall(Post::class, 1); + $response = $this->novaUpdateResourceAPICall(PostResource::class, 1); $response->assertUnauthorized(); } public function testUpdateValidationError(): void { - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(Post::class, 4); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(PostResource::class, 4); $response->assertUnprocessable(); @@ -99,7 +100,7 @@ public function testUpdateValidationError(): void public function testGetUpdatableFields(): void { - $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(Post::class, 1); + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(PostResource::class, 1); $response->assertOk(); @@ -109,7 +110,7 @@ public function testGetUpdatableFields(): void public function testDelete(): void { - $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(Post::class, [1, 2]); + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(PostResource::class, [1, 2]); $response->assertOk(); @@ -119,52 +120,52 @@ public function testDelete(): void public function testDeleteNotExists(): void { - $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(Post::class, [0]); + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(PostResource::class, [0]); $response->assertNotFound(); } public function testDeleteNoAuth(): void { - $response = $this->novaDeleteResourceAPICall(Post::class, [1, 2]); + $response = $this->novaDeleteResourceAPICall(PostResource::class, [1, 2]); $response->assertUnauthorized(); } public function testGet(): void { - $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(Post::class, 1); + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(PostResource::class, 1); $response->assertOk(); // TODO: Need to remove last argument after first successful start - $this->assertEqualsFixture('get_post_response', $response->json(), true); + $this->assertEqualsFixture('get_post_resource_response', $response->json(), true); } public function testGetNotExists(): void { - $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(Post::class, 0); + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(PostResource::class, 0); $response->assertNotFound(); } public function testGetNoAuth(): void { - $response = $this->novaGetResourceAPICall(Post::class, 1); + $response = $this->novaGetResourceAPICall(PostResource::class, 1); $response->assertUnauthorized(); } public function testSearchUnauthorized(): void { - $response = $this->novaSearchResourceAPICall(Post::class); + $response = $this->novaSearchResourceAPICall(PostResource::class); $response->assertUnauthorized(); } public function testGetFieldsVisibleOnCreate(): void { - $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(Post::class); + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(PostResource::class); $response->assertOk(); @@ -172,7 +173,7 @@ public function testGetFieldsVisibleOnCreate(): void $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); } - public static function getRunPostActionsData(): array + public static function getRunPostResourceActionsData(): array { return [ [ @@ -192,10 +193,10 @@ public static function getRunPostActionsData(): array ]; } - #[DataProvider('getRunPostActionsData')] - public function testRunPostActions($action, $request, $state): void + #[DataProvider('getRunPostResourceActionsData')] + public function testRunPostResourceActions($action, $request, $state): void { - $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(Post::class, $action, $request); + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(PostResource::class, $action, $request); $response->assertOk(); @@ -205,24 +206,24 @@ public function testRunPostActions($action, $request, $state): void self::$postState->assertChangesEqualsFixture($state, true); } - public static function getPostActionsData(): array + public static function getPostResourceActionsData(): array { return [ [ 'resources' => [1, 2], - 'fixture' => 'get_post_actions_publish_post_action', + 'fixture' => 'get_post_resource_actions_publish_post_action', ], [ 'resources' => [1, 2], - 'fixture' => 'get_post_actions_un_publish_post_action', + 'fixture' => 'get_post_resource_actions_un_publish_post_action', ], ]; } - #[DataProvider('getPostActionsData')] - public function testGetPostActions(array $resources, string $fixture): void + #[DataProvider('getPostResourceActionsData')] + public function testGetPostResourceActions(array $resources, string $fixture): void { - $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(Post::class, $resources); + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(PostResource::class, $resources); $response->assertOk(); @@ -230,28 +231,28 @@ public function testGetPostActions(array $resources, string $fixture): void $this->assertEqualsFixture($fixture, $response->json(), true); } - public static function getPostFiltersData(): array + public static function getPostResourceFiltersData(): array { return [ [ 'request' => [ 'TextField:description_field' => $this->novaSearchParams(['search term']), ], - 'fixture' => 'filter_post_by_text_field', + 'fixture' => 'filter_post_resource_by_text_field', ], [ 'request' => [ 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), ], - 'fixture' => 'filter_post_by_created_at_filter', + 'fixture' => 'filter_post_resource_by_created_at_filter', ], ]; } - #[DataProvider('getPostFiltersData')] - public function testFilterPost(array $request, string $fixture): void + #[DataProvider('getPostResourceFiltersData')] + public function testFilterPostResource(array $request, string $fixture): void { - $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(Post::class, $request); + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(PostResource::class, $request); $response->assertOk(); diff --git a/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php index 0357559a..e478293e 100644 --- a/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php +++ b/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php @@ -6,9 +6,9 @@ use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; -use App\Nova\WelcomeBonusResource; +use App\Nova\Resources\WelcomeBonusDraftResource; -class NovaWelcomeBonusResourceTest extends TestCase +class NovaWelcomeBonusDraftResourceTest extends TestCase { use NovaTestTrait; @@ -27,13 +27,13 @@ public function setUp(): void public function testCreate(): void { - $data = $this->getJsonFixture('create_welcome_bonus_resource_request'); + $data = $this->getJsonFixture('create_welcome_bonus_draft_resource_request'); - $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class, $data); + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusDraftResource::class, $data); $response->assertCreated(); - $this->assertEqualsFixture('create_welcome_bonus_resource_response', $response->json()); + $this->assertEqualsFixture('create_welcome_bonus_draft_resource_response', $response->json()); // TODO: Need to remove last argument after first successful start self::$welcomeBonusState->assertChangesEqualsFixture('create_welcome_bonuses_state', true); @@ -41,7 +41,7 @@ public function testCreate(): void public function testCreateNoAuth(): void { - $response = $this->novaCreateResourceAPICall(WelcomeBonusResource::class); + $response = $this->novaCreateResourceAPICall(WelcomeBonusDraftResource::class); $response->assertUnauthorized(); @@ -50,7 +50,7 @@ public function testCreateNoAuth(): void public function testCreateValidationError(): void { - $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class); + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusDraftResource::class); $response->assertUnprocessable(); @@ -62,9 +62,9 @@ public function testCreateValidationError(): void public function testUpdate(): void { - $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + $data = $this->getJsonFixture('update_welcome_bonus_draft_resource_request'); - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1, $data); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 1, $data); $response->assertNoContent(); @@ -74,23 +74,23 @@ public function testUpdate(): void public function testUpdateNotExists(): void { - $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + $data = $this->getJsonFixture('update_welcome_bonus_draft_resource_request'); - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 0, $data); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 0, $data); $response->assertNotFound(); } public function testUpdateNoAuth(): void { - $response = $this->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1); + $response = $this->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 1); $response->assertUnauthorized(); } public function testUpdateValidationError(): void { - $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 4); + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 4); $response->assertUnprocessable(); @@ -100,7 +100,7 @@ public function testUpdateValidationError(): void public function testGetUpdatableFields(): void { - $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(WelcomeBonusResource::class, 1); + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(WelcomeBonusDraftResource::class, 1); $response->assertOk(); @@ -110,7 +110,7 @@ public function testGetUpdatableFields(): void public function testDelete(): void { - $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [1, 2]); $response->assertOk(); @@ -120,52 +120,52 @@ public function testDelete(): void public function testDeleteNotExists(): void { - $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [0]); + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [0]); $response->assertNotFound(); } public function testDeleteNoAuth(): void { - $response = $this->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + $response = $this->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [1, 2]); $response->assertUnauthorized(); } public function testGet(): void { - $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 1); $response->assertOk(); // TODO: Need to remove last argument after first successful start - $this->assertEqualsFixture('get_welcome_bonus_resource_response', $response->json(), true); + $this->assertEqualsFixture('get_welcome_bonus_draft_resource_response', $response->json(), true); } public function testGetNotExists(): void { - $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 0); + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 0); $response->assertNotFound(); } public function testGetNoAuth(): void { - $response = $this->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + $response = $this->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 1); $response->assertUnauthorized(); } public function testSearchUnauthorized(): void { - $response = $this->novaSearchResourceAPICall(WelcomeBonusResource::class); + $response = $this->novaSearchResourceAPICall(WelcomeBonusDraftResource::class); $response->assertUnauthorized(); } public function testGetFieldsVisibleOnCreate(): void { - $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(WelcomeBonusResource::class); + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(WelcomeBonusDraftResource::class); $response->assertOk(); @@ -173,7 +173,7 @@ public function testGetFieldsVisibleOnCreate(): void $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); } - public static function getRunWelcomeBonusResourceActionsData(): array + public static function getRunWelcomeBonusDraftResourceActionsData(): array { return [ [ @@ -193,10 +193,10 @@ public static function getRunWelcomeBonusResourceActionsData(): array ]; } - #[DataProvider('getRunWelcomeBonusResourceActionsData')] - public function testRunWelcomeBonusResourceActions($action, $request, $state): void + #[DataProvider('getRunWelcomeBonusDraftResourceActionsData')] + public function testRunWelcomeBonusDraftResourceActions($action, $request, $state): void { - $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(WelcomeBonusResource::class, $action, $request); + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(WelcomeBonusDraftResource::class, $action, $request); $response->assertOk(); @@ -206,24 +206,24 @@ public function testRunWelcomeBonusResourceActions($action, $request, $state): v self::$welcomeBonusState->assertChangesEqualsFixture($state, true); } - public static function getWelcomeBonusResourceActionsData(): array + public static function getWelcomeBonusDraftResourceActionsData(): array { return [ [ 'resources' => [1, 2], - 'fixture' => 'get_welcome_bonus_resource_actions_publish_post_action', + 'fixture' => 'get_welcome_bonus_draft_resource_actions_publish_post_action', ], [ 'resources' => [1, 2], - 'fixture' => 'get_welcome_bonus_resource_actions_un_publish_post_action', + 'fixture' => 'get_welcome_bonus_draft_resource_actions_un_publish_post_action', ], ]; } - #[DataProvider('getWelcomeBonusResourceActionsData')] - public function testGetWelcomeBonusResourceActions(array $resources, string $fixture): void + #[DataProvider('getWelcomeBonusDraftResourceActionsData')] + public function testGetWelcomeBonusDraftResourceActions(array $resources, string $fixture): void { - $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(WelcomeBonusResource::class, $resources); + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(WelcomeBonusDraftResource::class, $resources); $response->assertOk(); @@ -231,28 +231,28 @@ public function testGetWelcomeBonusResourceActions(array $resources, string $fix $this->assertEqualsFixture($fixture, $response->json(), true); } - public static function getWelcomeBonusResourceFiltersData(): array + public static function getWelcomeBonusDraftResourceFiltersData(): array { return [ [ 'request' => [ 'TextField:description_field' => $this->novaSearchParams(['search term']), ], - 'fixture' => 'filter_welcome_bonus_resource_by_text_field', + 'fixture' => 'filter_welcome_bonus_draft_resource_by_text_field', ], [ 'request' => [ 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), ], - 'fixture' => 'filter_welcome_bonus_resource_by_created_at_filter', + 'fixture' => 'filter_welcome_bonus_draft_resource_by_created_at_filter', ], ]; } - #[DataProvider('getWelcomeBonusResourceFiltersData')] - public function testFilterWelcomeBonusResource(array $request, string $fixture): void + #[DataProvider('getWelcomeBonusDraftResourceFiltersData')] + public function testFilterWelcomeBonusDraftResource(array $request, string $fixture): void { - $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(WelcomeBonusResource::class, $request); + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(WelcomeBonusDraftResource::class, $request); $response->assertOk(); diff --git a/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonus_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonus_resource_test.php new file mode 100644 index 00000000..0357559a --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonus_resource_test.php @@ -0,0 +1,262 @@ +skipDocumentationCollecting(); + } + + public function testCreate(): void + { + $data = $this->getJsonFixture('create_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class, $data); + + $response->assertCreated(); + + $this->assertEqualsFixture('create_welcome_bonus_resource_response', $response->json()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('create_welcome_bonuses_state', true); + } + + public function testCreateNoAuth(): void + { + $response = $this->novaCreateResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnauthorized(); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testCreateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('create_validation_response', $response->json(), true); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testUpdate(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1, $data); + + $response->assertNoContent(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('update_welcome_bonuses_state', true); + } + + public function testUpdateNotExists(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 0, $data); + + $response->assertNotFound(); + } + + public function testUpdateNoAuth(): void + { + $response = $this->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testUpdateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 4); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('update_validation_response', $response->json(), true); + } + + public function testGetUpdatableFields(): void + { + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(WelcomeBonusResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_updatable_fields_response', $response->json(), true); + } + + public function testDelete(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('delete_welcome_bonuses_state', true); + } + + public function testDeleteNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [0]); + + $response->assertNotFound(); + } + + public function testDeleteNoAuth(): void + { + $response = $this->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + + $response->assertUnauthorized(); + } + + public function testGet(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_welcome_bonus_resource_response', $response->json(), true); + } + + public function testGetNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 0); + + $response->assertNotFound(); + } + + public function testGetNoAuth(): void + { + $response = $this->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testSearchUnauthorized(): void + { + $response = $this->novaSearchResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnauthorized(); + } + + public function testGetFieldsVisibleOnCreate(): void + { + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(WelcomeBonusResource::class); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); + } + + public static function getRunWelcomeBonusResourceActionsData(): array + { + return [ + [ + 'action' => PublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_publish_post_action_state', + ], + [ + 'action' => UnPublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_un_publish_post_action_state', + ], + ]; + } + + #[DataProvider('getRunWelcomeBonusResourceActionsData')] + public function testRunWelcomeBonusResourceActions($action, $request, $state): void + { + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(WelcomeBonusResource::class, $action, $request); + + $response->assertOk(); + + $this->assertEmpty($response->getContent()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture($state, true); + } + + public static function getWelcomeBonusResourceActionsData(): array + { + return [ + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_resource_actions_publish_post_action', + ], + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_resource_actions_un_publish_post_action', + ], + ]; + } + + #[DataProvider('getWelcomeBonusResourceActionsData')] + public function testGetWelcomeBonusResourceActions(array $resources, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(WelcomeBonusResource::class, $resources); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } + + public static function getWelcomeBonusResourceFiltersData(): array + { + return [ + [ + 'request' => [ + 'TextField:description_field' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_resource_by_text_field', + ], + [ + 'request' => [ + 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_resource_by_created_at_filter', + ], + ]; + } + + #[DataProvider('getWelcomeBonusResourceFiltersData')] + public function testFilterWelcomeBonusResource(array $request, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(WelcomeBonusResource::class, $request); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } +} diff --git a/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonuse_draft_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonuse_draft_resource_test.php new file mode 100644 index 00000000..e478293e --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/created_welcome_bonuse_draft_resource_test.php @@ -0,0 +1,262 @@ +skipDocumentationCollecting(); + } + + public function testCreate(): void + { + $data = $this->getJsonFixture('create_welcome_bonus_draft_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusDraftResource::class, $data); + + $response->assertCreated(); + + $this->assertEqualsFixture('create_welcome_bonus_draft_resource_response', $response->json()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('create_welcome_bonuses_state', true); + } + + public function testCreateNoAuth(): void + { + $response = $this->novaCreateResourceAPICall(WelcomeBonusDraftResource::class); + + $response->assertUnauthorized(); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testCreateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusDraftResource::class); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('create_validation_response', $response->json(), true); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testUpdate(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_draft_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 1, $data); + + $response->assertNoContent(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('update_welcome_bonuses_state', true); + } + + public function testUpdateNotExists(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_draft_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 0, $data); + + $response->assertNotFound(); + } + + public function testUpdateNoAuth(): void + { + $response = $this->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testUpdateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusDraftResource::class, 4); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('update_validation_response', $response->json(), true); + } + + public function testGetUpdatableFields(): void + { + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(WelcomeBonusDraftResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_updatable_fields_response', $response->json(), true); + } + + public function testDelete(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [1, 2]); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('delete_welcome_bonuses_state', true); + } + + public function testDeleteNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [0]); + + $response->assertNotFound(); + } + + public function testDeleteNoAuth(): void + { + $response = $this->novaDeleteResourceAPICall(WelcomeBonusDraftResource::class, [1, 2]); + + $response->assertUnauthorized(); + } + + public function testGet(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_welcome_bonus_draft_resource_response', $response->json(), true); + } + + public function testGetNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 0); + + $response->assertNotFound(); + } + + public function testGetNoAuth(): void + { + $response = $this->novaGetResourceAPICall(WelcomeBonusDraftResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testSearchUnauthorized(): void + { + $response = $this->novaSearchResourceAPICall(WelcomeBonusDraftResource::class); + + $response->assertUnauthorized(); + } + + public function testGetFieldsVisibleOnCreate(): void + { + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(WelcomeBonusDraftResource::class); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); + } + + public static function getRunWelcomeBonusDraftResourceActionsData(): array + { + return [ + [ + 'action' => PublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_publish_post_action_state', + ], + [ + 'action' => UnPublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_un_publish_post_action_state', + ], + ]; + } + + #[DataProvider('getRunWelcomeBonusDraftResourceActionsData')] + public function testRunWelcomeBonusDraftResourceActions($action, $request, $state): void + { + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(WelcomeBonusDraftResource::class, $action, $request); + + $response->assertOk(); + + $this->assertEmpty($response->getContent()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture($state, true); + } + + public static function getWelcomeBonusDraftResourceActionsData(): array + { + return [ + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_draft_resource_actions_publish_post_action', + ], + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_draft_resource_actions_un_publish_post_action', + ], + ]; + } + + #[DataProvider('getWelcomeBonusDraftResourceActionsData')] + public function testGetWelcomeBonusDraftResourceActions(array $resources, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(WelcomeBonusDraftResource::class, $resources); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } + + public static function getWelcomeBonusDraftResourceFiltersData(): array + { + return [ + [ + 'request' => [ + 'TextField:description_field' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_draft_resource_by_text_field', + ], + [ + 'request' => [ + 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_draft_resource_by_created_at_filter', + ], + ]; + } + + #[DataProvider('getWelcomeBonusDraftResourceFiltersData')] + public function testFilterWelcomeBonusDraftResource(array $request, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(WelcomeBonusDraftResource::class, $request); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } +} From 6330b2307c7baa6e0ae0141a7fec11f7775f7ea4 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 16 Sep 2025 18:22:56 +0300 Subject: [PATCH 19/30] fix: remove useless --- .env.testing | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .env.testing diff --git a/.env.testing b/.env.testing deleted file mode 100644 index b0c62306..00000000 --- a/.env.testing +++ /dev/null @@ -1 +0,0 @@ -FAIL_EXPORT_JSON=false \ No newline at end of file From 79baddf94301600a11f6dc2b72c69b944b42eed1 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Mon, 20 Oct 2025 14:55:14 +0300 Subject: [PATCH 20/30] refactor: set resource name in dump/fixtures --- src/Generators/AbstractTestsGenerator.php | 4 ++-- src/Generators/NovaTestGenerator.php | 14 ++++++------- src/Generators/TestsGenerator.php | 7 +++++++ tests/CommandTest.php | 16 +++++++-------- tests/NovaTestGeneratorTest.php | 24 +++++++++++------------ 5 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/Generators/AbstractTestsGenerator.php b/src/Generators/AbstractTestsGenerator.php index d64520c7..6ea85de8 100644 --- a/src/Generators/AbstractTestsGenerator.php +++ b/src/Generators/AbstractTestsGenerator.php @@ -13,6 +13,7 @@ abstract class AbstractTestsGenerator extends EntityGenerator protected array $fakerProperties = []; protected array $getFields = []; protected bool $withAuth = false; + protected string $entity; const array FIXTURE_TYPES = [ 'create' => ['request', 'response'], @@ -186,7 +187,6 @@ protected function getMockModel($model): array protected function generateFixtures(): void { $object = $this->getFixtureValuesList($this->model); - $entity = Str::snake($this->model); $this->createFixtureFolder(); @@ -195,7 +195,7 @@ protected function generateFixtures(): void foreach ($modifications as $modification) { $excepts = ($modification === 'request') ? ['id'] : []; - $this->generateFixture("{$type}_{$entity}_{$modification}.json", Arr::except($object, $excepts)); + $this->generateFixture("{$type}_" . Str::snake($this->entity) . "_{$modification}.json", Arr::except($object, $excepts)); } } } diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 5e97db10..7905fa0d 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -51,6 +51,8 @@ public function generate(): void $this->novaResourceClassName = Arr::first($novaResources); + $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); + parent::generate(); } else { event(new SuccessCreateMessage("Nova is not installed and NovaTest is skipped")); @@ -66,14 +68,12 @@ public function generateTests(): void $actions = $this->getActions(); $filters = $this->collectFilters(); - $resourceClass = Str::afterLast($this->novaResourceClassName, '\\'); - $fileContent = $this->getStub('nova_test', [ 'entity_namespace' => $this->getNamespace('models', $this->modelSubFolder), 'entity' => $this->model, - 'resource_name' => $resourceClass, + 'resource_name' => $this->entity, 'resource_namespace' => $this->novaResourceClassName, - 'snake_resource' => Str::snake($resourceClass), + 'snake_resource' => Str::snake($this->entity), 'dromedary_entity' => Str::lcfirst($this->model), 'lower_entities' => $this->getPluralName(Str::snake($this->model)), 'actions' => $actions, @@ -160,7 +160,7 @@ protected function loadNovaFilters() public function getTestClassName(): string { - return "Nova{$this->model}Test"; + return "Nova{$this->entity}Test"; } protected function isFixtureNeeded($type): bool @@ -218,8 +218,8 @@ protected function getFilters(): array protected function getDumpName(): string { - $modelName = Str::snake($this->model); + $entityName = Str::snake($this->entity); - return "nova_{$modelName}_dump.sql"; + return "nova_{$entityName}_dump.sql"; } } diff --git a/src/Generators/TestsGenerator.php b/src/Generators/TestsGenerator.php index 1fc58d60..afe82cb3 100644 --- a/src/Generators/TestsGenerator.php +++ b/src/Generators/TestsGenerator.php @@ -6,6 +6,13 @@ class TestsGenerator extends AbstractTestsGenerator { + public function generate(): void + { + $this->entity = $this->model; + + parent::generate(); + } + public function getTestClassName(): string { return "{$this->model}Test"; diff --git a/tests/CommandTest.php b/tests/CommandTest.php index b289dce1..6ef6feb5 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -91,10 +91,10 @@ public function testCallCommand() $this->assertGeneratedFileEquals('validation.php', 'lang/en/validation.php'); $this->assertGeneratedFileEquals('nova_resource.php', 'app/Nova/PostResource.php'); $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostResourceTest.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_resource_request.json'); } public function testCallCommandSubFoldersModel() @@ -137,10 +137,10 @@ public function testCallCommandSubFoldersModel() $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/PostTest/create_post_response.json'); $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/PostTest/update_post_request.json'); $this->assertGeneratedFileEquals('validation.php', 'lang/en/validation.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_resource_request.json'); } public function testMakeOnly() diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 84d1b59e..658f6c93 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -107,10 +107,10 @@ public function testNovaTestStubNotExist() ->generate(); $this->assertFileDoesNotExist('tests/NovaWelcomeBonusTest.php'); - $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_resource_request.json'); $this->assertEventPushed( className: WarningEvent::class, @@ -140,10 +140,10 @@ public function testDumpStubNotExist() ->generate(); $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); - $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_resource_request.json'); $this->assertEventPushed( className: WarningEvent::class, @@ -177,10 +177,10 @@ public function testSuccess() ->generate(); $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); - $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusTest/nova_welcome_bonus_dump.sql'); - $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_request.json'); - $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusTest/create_welcome_bonus_response.json'); - $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusTest/update_welcome_bonus_request.json'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_resource_request.json'); } public function testGenerateNovaPackageNotInstall() From 558c187ace0848664a5a1917a236e45fe8b509a5 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Wed, 22 Oct 2025 15:04:17 +0300 Subject: [PATCH 21/30] refactor: use set entity in setMetaData --- src/Generators/NovaTestGenerator.php | 69 +++-- tests/CommandTest.php | 10 +- tests/NovaTestGeneratorTest.php | 88 +++++- tests/Support/Command/CommandMockTrait.php | 40 ++- tests/Support/GeneratorMockTrait.php | 5 + .../Resources/WelcomeBonusDraftResource.php | 3 +- ...esource_test_without_set_resource_name.php | 262 ++++++++++++++++++ 7 files changed, 433 insertions(+), 44 deletions(-) create mode 100644 tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 9bbb6962..e0f88225 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -16,42 +16,59 @@ class NovaTestGenerator extends AbstractTestsGenerator { - protected string $novaResourceClassName; + protected ?string $novaResourceClassName; public function generate(): void { if (class_exists(NovaServiceProvider::class)) { - if ($this->classExists('nova', "Nova{$this->model}ResourceTest")) { + if (empty($this->novaResourceClassName)) { + $novaResources = $this->getCommonNovaResources(); - $path = $this->getClassPath('nova', "Nova{$this->model}ResourceTest"); + if (count($novaResources) > 1) { + $foundedResources = implode(', ', $novaResources); - throw new ResourceAlreadyExistsException($path); - } - - $novaResources = $this->getCommonNovaResources(); - - if (count($novaResources) > 1) { - $foundedResources = implode(', ', $novaResources); - - // TODO: Change exception message after https://github.com/RonasIT/laravel-entity-generator/issues/159 will be ready $this->throwFailureException( EntityCreateException::class, "Cannot create Nova{$this->model}ResourceTest cause was found a lot of suitable resources: {$foundedResources}.", 'Please, use --resource-name option.' ); - } + } - if (empty($novaResources)) { - $this->throwFailureException( - ClassNotExistsException::class, - "Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.", - "Create {$this->model} Nova resource." - ); - } + if (empty($novaResources)) { + // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.", + "Create {$this->model} Nova resource." + ); + } - $this->novaResourceClassName = Arr::first($novaResources); + $this->novaResourceClassName = Arr::first($novaResources); - $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); + $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); + + if ($this->classExists('nova', "Nova{$this->entity}ResourceTest")) { + $path = $this->getClassPath('nova', "Nova{$this->entity}ResourceTest"); + + throw new ResourceAlreadyExistsException($path); + } + + } else { + if ($this->classExists('nova', "Nova{$this->entity}Test")) { + $path = $this->getClassPath('nova', "Nova{$this->entity}Test"); + + throw new ResourceAlreadyExistsException($path); + } + + if (!$this->isNovaResource($this->novaResourceClassName) || !$this->isResourceNameContainModel($this->novaResourceClassName)) { + // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 + $this->throwFailureException( + ClassNotExistsException::class, + "Cannot create Nova{$this->entity}Test cause {$this->entity} Nova resource does not exist.", + "Create {$this->entity} Nova resource." + ); + } + } parent::generate(); } else { @@ -61,7 +78,11 @@ public function generate(): void public function setMetaData(array $data): self { - $this->novaResourceName = !empty($data['resource_name']) ? Str::studly($data['resource_name']) : null; + if (!empty($data['resource_name'])) { + $this->novaResourceClassName = $this->pathToNamespace($this->paths['nova'] . DIRECTORY_SEPARATOR . Str::studly($data['resource_name'])); + + $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); + } return $this; } @@ -87,7 +108,7 @@ public function generateTests(): void 'filters' => $filters, ]); - $this->saveClass('tests', "Nova{$this->model}ResourceTest", $fileContent); + $this->saveClass('tests', "Nova{$this->entity}Test", $fileContent); event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->model}ResourceTest")); } diff --git a/tests/CommandTest.php b/tests/CommandTest.php index 457ff41d..53dcae03 100644 --- a/tests/CommandTest.php +++ b/tests/CommandTest.php @@ -113,7 +113,7 @@ public function testCallCommandSubFoldersModel() $this ->artisan('make:entity Forum/Post --methods=CRUD') ->assertSuccessful(); - + $this->assertGeneratedFileEquals('subfolder/model.php', 'RonasIT/Support/Tests/Support/Command/Models/Forum/Post.php'); $this->assertGeneratedFileEquals('subfolder/factory.php', 'RonasIT/Support/Tests/Support/Command/Factories/PostFactory.php'); $this->assertGeneratedFileEquals('subfolder/repository.php', 'app/Repositories/PostRepository.php'); @@ -220,10 +220,10 @@ public function testMakeOnlyNovaTest(): void $this->assertFileDoesNotExist('lang/en/validation.php'); $this->assertFileDoesNotExist('app/Nova/PostResource.php'); $this->assertGeneratedFileEquals('nova_test.php', 'tests/NovaPostResourceTest.php'); - $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_dump.sql'); - $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_request.json'); - $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_response.json'); - $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_request.json'); + $this->assertGeneratedFileEquals('nova_dump.php', 'tests/fixtures/NovaPostResourceTest/nova_post_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_request.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_request.json'); + $this->assertGeneratedFileEquals('create_response.json', 'tests/fixtures/NovaPostResourceTest/create_post_resource_response.json'); + $this->assertGeneratedFileEquals('update_request.json', 'tests/fixtures/NovaPostResourceTest/update_post_resource_request.json'); } public function testCallWithNotDefaultConfig() diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 79ada071..935f920b 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -41,24 +41,40 @@ className: ClassNotExistsException::class, ->generate(); } - public function testGenerateToManyResources(): void + public function testGenerateResourceWithSetResourceNameNotExists() + { + $this->assertExceptionThrew( + className: ClassNotExistsException::class, + message: 'Cannot create NovaWelcomeBonusDraftResourceTest cause WelcomeBonusDraftResource Nova resource does not exist. Create WelcomeBonusDraftResource Nova resource.', + ); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeIsSubClassOfMethodCall(['App\Nova\Resources\WelcomeBonusDraftResource', 'Laravel\\Nova\\Resource'], false), + ); + + app(NovaTestGenerator::class) + ->setModel('Post') + ->setMetaData(['resource_name' => 'Resources\WelcomeBonusDraftResource']) + ->generate(); + } + + public function testGenerateNovaTestWithSetResourceNameAlreadyExists() { $this->mockNovaServiceProviderExists(); $this->mockClass(NovaTestGenerator::class, [ - $this->getCommonNovaResourcesMock([ - 'BasePostResource', - 'PublishPostResource', - ]), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), ]); $this->assertExceptionThrew( - className: EntityCreateException::class, - message: 'Cannot create NovaPostResourceTest cause was found a lot of suitable resources: BasePostResource, PublishPostResource. Make test by yourself.', + className: ResourceAlreadyExistsException::class, + message: "Cannot create NovaPostResourceTest cause it already exists. Remove app/Nova/NovaPostResourceTest.php and run command again.", ); app(NovaTestGenerator::class) ->setModel('Post') + ->setMetaData(['resource_name' => 'PostResource']) ->generate(); } @@ -72,7 +88,29 @@ public function testGenerateNovaTestAlreadyExists() $this->assertExceptionThrew( className: ResourceAlreadyExistsException::class, - message: "Cannot create NovaPostResourceTest cause it already exists. Remove vfs://root/app/Nova/NovaPostResourceTest.php and run command again.", + message: "Cannot create NovaPostResourceTest cause it already exists. Remove app/Nova/NovaPostResourceTest.php and run command again.", + ); + + app(NovaTestGenerator::class) + ->setModel('Post') + ->setMetaData(['resource_name' => 'PostResource']) + ->generate(); + } + + public function testGenerateToManyResources(): void + { + $this->mockNovaServiceProviderExists(); + + $this->mockClass(NovaTestGenerator::class, [ + $this->getCommonNovaResourcesMock([ + 'BasePostResource', + 'PublishPostResource', + ]), + ]); + + $this->assertExceptionThrew( + className: EntityCreateException::class, + message: 'Cannot create NovaPostResourceTest cause was found a lot of suitable resources: BasePostResource, PublishPostResource. Please, use --resource-name option.', ); app(NovaTestGenerator::class) @@ -89,7 +127,7 @@ public function testNovaTestStubNotExist() $this->mockNativeGeneratorFunctions( $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), - $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), + $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Models\WelcomeBonus']), ); $this->mockClass(NovaTestGenerator::class, [ @@ -139,7 +177,7 @@ public function testDumpStubNotExist() ->setModel('WelcomeBonus') ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('created_resource_test_without_set_resource_name.php', 'tests/NovaWelcomeBonusResourceTest.php'); $this->assertFileDoesNotExist('tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); @@ -176,13 +214,41 @@ public function testSuccess() ->setModel('WelcomeBonus') ->generate(); - $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusResourceTest.php'); + $this->assertGeneratedFileEquals('created_resource_test_without_set_resource_name.php', 'tests/NovaWelcomeBonusResourceTest.php'); $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/update_welcome_bonus_resource_request.json'); } + public function testSuccessWithSetResourceName() + { + config([ + 'entity-generator.paths.models' => 'RonasIT/Support/Tests/Support/Models', + ]); + + $this->mockDBTransactionStartRollback(); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall([NovaServiceProvider::class, true]), + $this->nativeClassExistsMethodCall([WelcomeBonus::class, true]), + $this->nativeIsSubClassOfMethodCall(['App\Nova\Resources\WelcomeBonusDraftResource', 'Laravel\\Nova\\Resource']), + ); + + $this->mockNovaRequestClassCall(); + + app(NovaTestGenerator::class) + ->setModel('WelcomeBonus') + ->setMetaData(['resource_name' => 'Resources\WelcomeBonusDraftResource']) + ->generate(); + + $this->assertGeneratedFileEquals('created_resource_test.php', 'tests/NovaWelcomeBonusDraftResourceTest.php'); + $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/nova_welcome_bonus_draft_resource_dump.sql'); + $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_draft_resource_request.json'); + $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/create_welcome_bonus_draft_resource_response.json'); + $this->assertGeneratedFileEquals('update_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusDraftResourceTest/update_welcome_bonus_draft_resource_request.json'); + } + public function testGenerateNovaPackageNotInstall() { $this->mockNovaServiceProviderExists(false); diff --git a/tests/Support/Command/CommandMockTrait.php b/tests/Support/Command/CommandMockTrait.php index d04f3fed..900dc78d 100644 --- a/tests/Support/Command/CommandMockTrait.php +++ b/tests/Support/Command/CommandMockTrait.php @@ -20,6 +20,17 @@ public function mockFilesystemPostModelExists(): void $fileSystemMock->setStructure(); } + public function mockFilesystemWithPostModelAndResource(): void + { + $fileSystemMock = new FileSystemMock(); + + $fileSystemMock->models = ['Post.php' => $this->mockPhpFileContent()]; + $fileSystemMock->novaModels = ['PostResource.php' => $this->mockPhpFileContent()]; + $fileSystemMock->config = ['entity-generator.php' => '']; + + $fileSystemMock->setStructure(); + } + public function mockFilesystem(): void { $fileSystemMock = new FileSystemMock(); @@ -83,8 +94,33 @@ public function mockGeneratorSubFolders(): void ); } - public function nativeIsSubClassOfMethodCall(array $arguments, bool $result = true): array + public function mockGeneratorOnlyNovaTests(): void { - return $this->functionCall('is_subclass_of', $arguments, $result); + $this->mockClass(NovaTestGenerator::class, [ + $this->functionCall( + name: 'loadNovaActions', + result: [], + ), + $this->functionCall( + name: 'loadNovaFields', + result: [], + ), + $this->functionCall( + name: 'loadNovaFilters', + result: [], + ), + $this->classExistsMethodCall(['nova', 'NovaPostResourceTest'], false), + $this->classExistsMethodCall(['models', 'User'], false), + $this->classExistsMethodCall(['factories', 'PostFactory']), + $this->classExistsMethodCall(['factories', 'PostFactory']), + ]); + + $this->mockDBTransactionStartRollback(); + + $this->mockNativeGeneratorFunctions( + $this->nativeClassExistsMethodCall(['Laravel\Nova\NovaServiceProvider', true]), + $this->nativeIsSubClassOfMethodCall(['App\Nova\PostResource', 'Laravel\\Nova\\Resource']), + $this->nativeClassExistsMethodCall(['RonasIT\Support\Tests\Support\Command\Models\Post', true]), + ); } } diff --git a/tests/Support/GeneratorMockTrait.php b/tests/Support/GeneratorMockTrait.php index 33cec554..641a0be9 100644 --- a/tests/Support/GeneratorMockTrait.php +++ b/tests/Support/GeneratorMockTrait.php @@ -32,6 +32,11 @@ public function mockNovaServiceProviderExists(bool $result = true): void ); } + public function nativeIsSubClassOfMethodCall(array $arguments, bool $result = true): array + { + return $this->functionCall('is_subclass_of', $arguments, $result); + } + public function classExistsMethodCall(array $arguments, bool $result = true): array { return [ diff --git a/tests/Support/Nova/Resources/WelcomeBonusDraftResource.php b/tests/Support/Nova/Resources/WelcomeBonusDraftResource.php index 81ad378c..3c02de0c 100644 --- a/tests/Support/Nova/Resources/WelcomeBonusDraftResource.php +++ b/tests/Support/Nova/Resources/WelcomeBonusDraftResource.php @@ -10,9 +10,8 @@ use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\PublishPostAction; use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\TextField; use RonasIT\Support\Tests\Support\NovaTestGeneratorTest\UnPublishPostAction; -use Laravel\Nova\Resource; -class WelcomeBonusDraftResource extends Resource +class WelcomeBonusDraftResource { public static $title = 'name'; diff --git a/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php b/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php new file mode 100644 index 00000000..0357559a --- /dev/null +++ b/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php @@ -0,0 +1,262 @@ +skipDocumentationCollecting(); + } + + public function testCreate(): void + { + $data = $this->getJsonFixture('create_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class, $data); + + $response->assertCreated(); + + $this->assertEqualsFixture('create_welcome_bonus_resource_response', $response->json()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('create_welcome_bonuses_state', true); + } + + public function testCreateNoAuth(): void + { + $response = $this->novaCreateResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnauthorized(); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testCreateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaCreateResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('create_validation_response', $response->json(), true); + + self::$welcomeBonusState->assertNotChanged(); + } + + public function testUpdate(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1, $data); + + $response->assertNoContent(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('update_welcome_bonuses_state', true); + } + + public function testUpdateNotExists(): void + { + $data = $this->getJsonFixture('update_welcome_bonus_resource_request'); + + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 0, $data); + + $response->assertNotFound(); + } + + public function testUpdateNoAuth(): void + { + $response = $this->novaUpdateResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testUpdateValidationError(): void + { + $response = $this->novaActingAs(self::$user)->novaUpdateResourceAPICall(WelcomeBonusResource::class, 4); + + $response->assertUnprocessable(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('update_validation_response', $response->json(), true); + } + + public function testGetUpdatableFields(): void + { + $response = $this->novaActingAs(self::$user)->novaGetUpdatableFieldsAPICall(WelcomeBonusResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_updatable_fields_response', $response->json(), true); + } + + public function testDelete(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture('delete_welcome_bonuses_state', true); + } + + public function testDeleteNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaDeleteResourceAPICall(WelcomeBonusResource::class, [0]); + + $response->assertNotFound(); + } + + public function testDeleteNoAuth(): void + { + $response = $this->novaDeleteResourceAPICall(WelcomeBonusResource::class, [1, 2]); + + $response->assertUnauthorized(); + } + + public function testGet(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_welcome_bonus_resource_response', $response->json(), true); + } + + public function testGetNotExists(): void + { + $response = $this->novaActingAs(self::$user)->novaGetResourceAPICall(WelcomeBonusResource::class, 0); + + $response->assertNotFound(); + } + + public function testGetNoAuth(): void + { + $response = $this->novaGetResourceAPICall(WelcomeBonusResource::class, 1); + + $response->assertUnauthorized(); + } + + public function testSearchUnauthorized(): void + { + $response = $this->novaSearchResourceAPICall(WelcomeBonusResource::class); + + $response->assertUnauthorized(); + } + + public function testGetFieldsVisibleOnCreate(): void + { + $response = $this->novaActingAs(self::$user)->novaGetCreationFieldsAPICall(WelcomeBonusResource::class); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture('get_fields_visible_on_create_response', $response->json(), true); + } + + public static function getRunWelcomeBonusResourceActionsData(): array + { + return [ + [ + 'action' => PublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_publish_post_action_state', + ], + [ + 'action' => UnPublishPostAction::class, + 'request' => [ + 'resources' => '1,2', + ], + 'state' => 'run_un_publish_post_action_state', + ], + ]; + } + + #[DataProvider('getRunWelcomeBonusResourceActionsData')] + public function testRunWelcomeBonusResourceActions($action, $request, $state): void + { + $response = $this->novaActingAs(self::$user)->novaRunActionAPICall(WelcomeBonusResource::class, $action, $request); + + $response->assertOk(); + + $this->assertEmpty($response->getContent()); + + // TODO: Need to remove last argument after first successful start + self::$welcomeBonusState->assertChangesEqualsFixture($state, true); + } + + public static function getWelcomeBonusResourceActionsData(): array + { + return [ + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_resource_actions_publish_post_action', + ], + [ + 'resources' => [1, 2], + 'fixture' => 'get_welcome_bonus_resource_actions_un_publish_post_action', + ], + ]; + } + + #[DataProvider('getWelcomeBonusResourceActionsData')] + public function testGetWelcomeBonusResourceActions(array $resources, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaGetActionsAPICall(WelcomeBonusResource::class, $resources); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } + + public static function getWelcomeBonusResourceFiltersData(): array + { + return [ + [ + 'request' => [ + 'TextField:description_field' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_resource_by_text_field', + ], + [ + 'request' => [ + 'RonasIT\Support\Tests\Support\NovaTestGeneratorTest\CreatedAtFilter' => $this->novaSearchParams(['search term']), + ], + 'fixture' => 'filter_welcome_bonus_resource_by_created_at_filter', + ], + ]; + } + + #[DataProvider('getWelcomeBonusResourceFiltersData')] + public function testFilterWelcomeBonusResource(array $request, string $fixture): void + { + $response = $this->novaActingAs(self::$user)->novaSearchResourceAPICall(WelcomeBonusResource::class, $request); + + $response->assertOk(); + + // TODO: Need to remove last argument after first successful start + $this->assertEqualsFixture($fixture, $response->json(), true); + } +} From 6b3eefecb60446b55207a751d8564c704b434c6e Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Thu, 23 Oct 2025 14:07:38 +0300 Subject: [PATCH 22/30] refactor: use getTestingEntityName --- src/Generators/AbstractTestsGenerator.php | 5 ++-- src/Generators/NovaTestGenerator.php | 30 ++++++++++++----------- src/Generators/TestsGenerator.php | 5 ++++ tests/NovaTestGeneratorTest.php | 3 +++ 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/Generators/AbstractTestsGenerator.php b/src/Generators/AbstractTestsGenerator.php index 6ea85de8..31df9c8b 100644 --- a/src/Generators/AbstractTestsGenerator.php +++ b/src/Generators/AbstractTestsGenerator.php @@ -13,7 +13,6 @@ abstract class AbstractTestsGenerator extends EntityGenerator protected array $fakerProperties = []; protected array $getFields = []; protected bool $withAuth = false; - protected string $entity; const array FIXTURE_TYPES = [ 'create' => ['request', 'response'], @@ -195,7 +194,7 @@ protected function generateFixtures(): void foreach ($modifications as $modification) { $excepts = ($modification === 'request') ? ['id'] : []; - $this->generateFixture("{$type}_" . Str::snake($this->entity) . "_{$modification}.json", Arr::except($object, $excepts)); + $this->generateFixture("{$type}_" . Str::snake($this->getTestingEntityName()) . "_{$modification}.json", Arr::except($object, $excepts)); } } } @@ -259,6 +258,8 @@ abstract protected function isFixtureNeeded($type): bool; abstract protected function generateTests(): void; + abstract protected function getTestingEntityName(): string; + private function filterBadModelField($fields): array { return array_diff($fields, [ diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 0b213a31..9e19147d 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -21,13 +21,6 @@ class NovaTestGenerator extends AbstractTestsGenerator public function generate(): void { if (class_exists(NovaServiceProvider::class)) { - if ($this->classExists('nova', "Nova{$this->model}ResourceTest")) { - - $path = $this->getClassPath('nova', "Nova{$this->model}ResourceTest"); - - throw new ResourceAlreadyExistsException($path); - } - $novaResources = $this->getCommonNovaResources(); if (count($novaResources) > 1) { @@ -51,7 +44,11 @@ public function generate(): void $this->novaResourceClassName = Arr::first($novaResources); - $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); + if ($this->classExists('nova', "Nova{$this->getTestingEntityName()}Test")) { + $path = $this->getClassPath('nova', "Nova{$this->getTestingEntityName()}Test"); + + throw new ResourceAlreadyExistsException($path); + } parent::generate(); } else { @@ -71,9 +68,9 @@ public function generateTests(): void $fileContent = $this->getStub('nova_test', [ 'entity_namespace' => $this->getNamespace('models', $this->modelSubFolder), 'entity' => $this->model, - 'resource_name' => $this->entity, + 'resource_name' => $this->getTestingEntityName(), 'resource_namespace' => $this->novaResourceClassName, - 'snake_resource' => Str::snake($this->entity), + 'snake_resource' => Str::snake($this->getTestingEntityName()), 'dromedary_entity' => Str::lcfirst($this->model), 'lower_entities' => $this->getPluralName(Str::snake($this->model)), 'actions' => $actions, @@ -81,9 +78,9 @@ public function generateTests(): void 'models_namespace' => $this->getNamespace('models'), ]); - $this->saveClass('tests', "Nova{$this->model}ResourceTest", $fileContent); + $this->saveClass('tests', $this->getTestClassName(), $fileContent); - event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->model}ResourceTest")); + event(new SuccessCreateMessage("Created a new Nova test: {$this->getTestClassName()}")); } protected function getActions(): array @@ -161,7 +158,7 @@ protected function loadNovaFilters() public function getTestClassName(): string { - return "Nova{$this->entity}Test"; + return "Nova{$this->getTestingEntityName()}Test"; } protected function isFixtureNeeded($type): bool @@ -219,8 +216,13 @@ protected function getFilters(): array protected function getDumpName(): string { - $entityName = Str::snake($this->entity); + $entityName = Str::snake($this->getTestingEntityName()); return "nova_{$entityName}_dump.sql"; } + + protected function getTestingEntityName(): string + { + return Str::afterLast($this->novaResourceClassName, '\\'); + } } diff --git a/src/Generators/TestsGenerator.php b/src/Generators/TestsGenerator.php index afe82cb3..8227a00f 100644 --- a/src/Generators/TestsGenerator.php +++ b/src/Generators/TestsGenerator.php @@ -60,4 +60,9 @@ protected function generateTests(): void event(new SuccessCreateMessage($createMessage)); } + + protected function getTestingEntityName(): string + { + return $this->model; + } } diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 658f6c93..c2be886f 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -68,6 +68,9 @@ public function testGenerateNovaTestAlreadyExists() $this->mockClass(NovaTestGenerator::class, [ $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), + $this->getCommonNovaResourcesMock([ + 'PostResource', + ]), ]); $this->assertExceptionThrew( From 4d704fab12f6d652afcda5d09301aae2e97fb3f2 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sun, 26 Oct 2025 15:31:59 +0300 Subject: [PATCH 23/30] fix: remove useless --- src/Generators/TestsGenerator.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Generators/TestsGenerator.php b/src/Generators/TestsGenerator.php index 8227a00f..dcb267cb 100644 --- a/src/Generators/TestsGenerator.php +++ b/src/Generators/TestsGenerator.php @@ -6,13 +6,6 @@ class TestsGenerator extends AbstractTestsGenerator { - public function generate(): void - { - $this->entity = $this->model; - - parent::generate(); - } - public function getTestClassName(): string { return "{$this->model}Test"; From a43a514580b2e73ff23c00fc21c0595468d1c0d8 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Sun, 2 Nov 2025 22:59:28 +0300 Subject: [PATCH 24/30] style:fix --- src/Generators/AbstractTestsGenerator.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Generators/AbstractTestsGenerator.php b/src/Generators/AbstractTestsGenerator.php index 31df9c8b..9d118518 100644 --- a/src/Generators/AbstractTestsGenerator.php +++ b/src/Generators/AbstractTestsGenerator.php @@ -189,12 +189,14 @@ protected function generateFixtures(): void $this->createFixtureFolder(); + $entity = Str::snake($this->getTestingEntityName()); + foreach (self::FIXTURE_TYPES as $type => $modifications) { if ($this->isFixtureNeeded($type)) { foreach ($modifications as $modification) { $excepts = ($modification === 'request') ? ['id'] : []; - $this->generateFixture("{$type}_" . Str::snake($this->getTestingEntityName()) . "_{$modification}.json", Arr::except($object, $excepts)); + $this->generateFixture("{$type}_{$entity}_{$modification}.json", Arr::except($object, $excepts)); } } } From 16f9a24a146e4a7fcad3bfa13194892eb8391370 Mon Sep 17 00:00:00 2001 From: Anton Zabolotnikov <110885041+AZabolotnikov@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:37:31 +0500 Subject: [PATCH 25/30] Apply suggestion from @AZabolotnikov --- src/Generators/NovaTestGenerator.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 9e19147d..cb67418c 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -44,8 +44,10 @@ public function generate(): void $this->novaResourceClassName = Arr::first($novaResources); - if ($this->classExists('nova', "Nova{$this->getTestingEntityName()}Test")) { - $path = $this->getClassPath('nova', "Nova{$this->getTestingEntityName()}Test"); + $entityName = $this->getTestingEntityName(); + + if ($this->classExists('nova', "Nova{$entityName}Test")) { + $path = $this->getClassPath('nova', "Nova{$entityName}Test"); throw new ResourceAlreadyExistsException($path); } From 32988da30dd1468c067eec4072fc353e4a207b8b Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 4 Nov 2025 14:24:05 +0300 Subject: [PATCH 26/30] style:fix --- src/Generators/NovaTestGenerator.php | 6 ++---- tests/NovaTestGeneratorTest.php | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index cb67418c..df153d17 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -44,10 +44,8 @@ public function generate(): void $this->novaResourceClassName = Arr::first($novaResources); - $entityName = $this->getTestingEntityName(); - - if ($this->classExists('nova', "Nova{$entityName}Test")) { - $path = $this->getClassPath('nova', "Nova{$entityName}Test"); + if ($this->classExists('nova', $this->getTestClassName())) { + $path = $this->getClassPath('nova', $this->getTestClassName()); throw new ResourceAlreadyExistsException($path); } diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index c2be886f..4cc90741 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -109,7 +109,7 @@ public function testNovaTestStubNotExist() ->setModel('WelcomeBonus') ->generate(); - $this->assertFileDoesNotExist('tests/NovaWelcomeBonusTest.php'); + $this->assertFileDoesNotExist('tests/NovaWelcomeBonusResourceTest.php'); $this->assertGeneratedFileEquals('dump.sql', 'tests/fixtures/NovaWelcomeBonusResourceTest/nova_welcome_bonus_resource_dump.sql'); $this->assertGeneratedFileEquals('create_welcome_bonus_request.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_request.json'); $this->assertGeneratedFileEquals('create_welcome_bonus_response.json', 'tests/fixtures/NovaWelcomeBonusResourceTest/create_welcome_bonus_resource_response.json'); From 1d3b358da9a9ae89885cbeadf5729c626c3d0bda Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 4 Nov 2025 14:43:54 +0300 Subject: [PATCH 27/30] fix: imports in nova test stub --- src/Generators/NovaTestGenerator.php | 10 +++------- stubs/nova_test.blade.php | 2 +- tests/fixtures/CommandTest/nova_test.php | 4 ++-- tests/fixtures/CommandTest/subfolder/nova_test.php | 4 ++-- .../NovaTestGeneratorTest/created_resource_test.php | 4 ++-- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index df153d17..0b396bbf 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -44,11 +44,7 @@ public function generate(): void $this->novaResourceClassName = Arr::first($novaResources); - if ($this->classExists('nova', $this->getTestClassName())) { - $path = $this->getClassPath('nova', $this->getTestClassName()); - - throw new ResourceAlreadyExistsException($path); - } + $this->checkResourceExists('nova', $this->getTestClassName(), $this->modelSubFolder); parent::generate(); } else { @@ -66,7 +62,7 @@ public function generateTests(): void $filters = $this->collectFilters(); $fileContent = $this->getStub('nova_test', [ - 'entity_namespace' => $this->getNamespace('models', $this->modelSubFolder), + 'entity_namespace' => $this->generateNamespace('models', $this->modelSubFolder), 'entity' => $this->model, 'resource_name' => $this->getTestingEntityName(), 'resource_namespace' => $this->novaResourceClassName, @@ -75,7 +71,7 @@ public function generateTests(): void 'lower_entities' => $this->getPluralName(Str::snake($this->model)), 'actions' => $actions, 'filters' => $filters, - 'models_namespace' => $this->getNamespace('models'), + 'models_namespace' => $this->generateNamespace('models', $this->modelSubFolder), ]); $this->saveClass('tests', $this->getTestClassName(), $fileContent); diff --git a/stubs/nova_test.blade.php b/stubs/nova_test.blade.php index 6e81e8aa..03a2c248 100644 --- a/stubs/nova_test.blade.php +++ b/stubs/nova_test.blade.php @@ -5,7 +5,7 @@ use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; use {{ $resource_namespace }}; -use {{ $models_namespace }}\User; +use Models\User; class Nova{{ $resource_name }}Test extends TestCase { diff --git a/tests/fixtures/CommandTest/nova_test.php b/tests/fixtures/CommandTest/nova_test.php index 67b3183c..30799a7c 100644 --- a/tests/fixtures/CommandTest/nova_test.php +++ b/tests/fixtures/CommandTest/nova_test.php @@ -2,12 +2,12 @@ namespace App\Tests; -use RonasIT\Support\Tests\Support\Command\Models\Post; +use Models\Post; use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; use App\Nova\PostResource; -use RonasIT\Support\Tests\Support\Command\Models\User; +use Models\User; class NovaPostResourceTest extends TestCase { diff --git a/tests/fixtures/CommandTest/subfolder/nova_test.php b/tests/fixtures/CommandTest/subfolder/nova_test.php index b26f67b0..7bca9e92 100644 --- a/tests/fixtures/CommandTest/subfolder/nova_test.php +++ b/tests/fixtures/CommandTest/subfolder/nova_test.php @@ -2,12 +2,12 @@ namespace App\Tests; -use RonasIT\Support\Tests\Support\Command\Models\Forum\Post; +use Models\Forum\Post; use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; use App\Nova\Forum\PostResource; -use RonasIT\Support\Tests\Support\Command\Models\User; +use Models\User; class NovaPostResourceTest extends TestCase { diff --git a/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php b/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php index 158f73c1..c8c1188a 100644 --- a/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php +++ b/tests/fixtures/NovaTestGeneratorTest/created_resource_test.php @@ -2,12 +2,12 @@ namespace App\Tests; -use RonasIT\Support\Tests\Support\Models\WelcomeBonus; +use Models\WelcomeBonus; use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; use App\Nova\WelcomeBonusResource; -use RonasIT\Support\Tests\Support\Models\User; +use Models\User; class NovaWelcomeBonusResourceTest extends TestCase { From c5a3c41f87862c557e1cdf250646b43f74306648 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 4 Nov 2025 14:49:42 +0300 Subject: [PATCH 28/30] style: remove useless --- src/Generators/NovaTestGenerator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 0b396bbf..6f2d05cb 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -12,7 +12,6 @@ use RecursiveIteratorIterator; use RecursiveDirectoryIterator; use Illuminate\Support\Arr; -use RonasIT\Support\Exceptions\ResourceAlreadyExistsException; class NovaTestGenerator extends AbstractTestsGenerator { From 9a90e131213f91dfc7ea52738322785d9681168b Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 4 Nov 2025 15:35:27 +0300 Subject: [PATCH 29/30] fix: use abstract getEntityName method --- src/Generators/NovaTestGenerator.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index f49c9b5d..8d38344e 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -51,10 +51,14 @@ public function generate(): void if (!$this->isNovaResource($this->novaResourceClassName) || !$this->isResourceNameContainModel($this->novaResourceClassName)) { // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 + + $entityName = $this->getTestingEntityName(); + $entityTestName = $this->getTestingEntityName(); + $this->throwFailureException( ClassNotExistsException::class, - "Cannot create Nova{$this->entity}Test cause {$this->entity} Nova resource does not exist.", - "Create {$this->entity} Nova resource." + "Cannot create {$entityTestName} cause {$entityName} Nova resource does not exist.", + "Create {$entityName} Nova resource." ); } } @@ -69,8 +73,6 @@ public function setMetaData(array $data): self { if (!empty($data['resource_name'])) { $this->novaResourceClassName = $this->pathToNamespace($this->paths['nova'] . DIRECTORY_SEPARATOR . Str::studly($data['resource_name'])); - - $this->entity = Str::afterLast($this->novaResourceClassName, '\\'); } return $this; From 01346cb6a4c2a34e10772362ee7639d3371c0746 Mon Sep 17 00:00:00 2001 From: Ruslan Guskov Date: Tue, 4 Nov 2025 16:13:36 +0300 Subject: [PATCH 30/30] fix:tests --- src/Generators/NovaTestGenerator.php | 2 +- tests/NovaTestGeneratorTest.php | 3 --- .../created_resource_test_without_set_resource_name.php | 3 ++- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Generators/NovaTestGenerator.php b/src/Generators/NovaTestGenerator.php index 8d38344e..053821c9 100644 --- a/src/Generators/NovaTestGenerator.php +++ b/src/Generators/NovaTestGenerator.php @@ -53,7 +53,7 @@ public function generate(): void // TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179 $entityName = $this->getTestingEntityName(); - $entityTestName = $this->getTestingEntityName(); + $entityTestName = $this->getTestClassName(); $this->throwFailureException( ClassNotExistsException::class, diff --git a/tests/NovaTestGeneratorTest.php b/tests/NovaTestGeneratorTest.php index 588f2b65..f1816613 100644 --- a/tests/NovaTestGeneratorTest.php +++ b/tests/NovaTestGeneratorTest.php @@ -84,9 +84,6 @@ public function testGenerateNovaTestAlreadyExists() $this->mockClass(NovaTestGenerator::class, [ $this->classExistsMethodCall(['nova', 'NovaPostResourceTest']), - $this->getCommonNovaResourcesMock([ - 'PostResource', - ]), ]); $this->assertExceptionThrew( diff --git a/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php b/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php index 0357559a..c8c1188a 100644 --- a/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php +++ b/tests/fixtures/NovaTestGeneratorTest/created_resource_test_without_set_resource_name.php @@ -2,11 +2,12 @@ namespace App\Tests; -use RonasIT\Support\Tests\Support\Models\WelcomeBonus; +use Models\WelcomeBonus; use PHPUnit\Framework\Attributes\DataProvider; use RonasIT\Support\Testing\ModelTestState; use RonasIT\Support\Traits\NovaTestTrait; use App\Nova\WelcomeBonusResource; +use Models\User; class NovaWelcomeBonusResourceTest extends TestCase {