Skip to content

Commit a875233

Browse files
authored
Merge pull request #181 from RonasIT/140-use-NovaResource-class-in-NovaTestGenerator-instead-of-Model
140 use nova resource class in nova test generator instead of model
2 parents f347aa6 + 1ac42e3 commit a875233

File tree

10 files changed

+313
-203
lines changed

10 files changed

+313
-203
lines changed

src/Generators/EntityGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,6 @@ protected function prepareRelations(): array
303303

304304
protected function pathToNamespace(string $name): string
305305
{
306-
return Str::replace('/', '\\', $name);
306+
return ucwords(Str::replace('/', '\\', $name), '\\');
307307
}
308308
}

src/Generators/NovaTestGenerator.php

Lines changed: 91 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,60 @@
88
use RonasIT\Support\Events\SuccessCreateMessage;
99
use RonasIT\Support\Exceptions\ClassAlreadyExistsException;
1010
use RonasIT\Support\Exceptions\ClassNotExistsException;
11+
use RonasIT\Support\Exceptions\EntityCreateException;
12+
use Generator;
13+
use RecursiveIteratorIterator;
14+
use RecursiveDirectoryIterator;
15+
use Illuminate\Support\Arr;
1116

1217
class NovaTestGenerator extends AbstractTestsGenerator
1318
{
14-
protected $novaModelName;
19+
protected string $novaPath;
20+
21+
protected string $novaResourceClassName;
22+
23+
public function __construct()
24+
{
25+
parent::__construct();
26+
27+
$this->novaPath = base_path($this->paths['nova']);
28+
}
1529

1630
public function generate(): void
1731
{
1832
if (class_exists(NovaServiceProvider::class)) {
19-
if (!$this->doesNovaResourceExists()) {
20-
// TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179
33+
if ($this->classExists('nova', "Nova{$this->model}ResourceTest")) {
2134
$this->throwFailureException(
22-
ClassNotExistsException::class,
23-
"Cannot create Nova{$this->model}Test cause {$this->model} Nova resource does not exist.",
24-
"Create {$this->model} Nova resource."
35+
ClassAlreadyExistsException::class,
36+
"Cannot create Nova{$this->model}ResourceTest cause it's already exist.",
37+
"Remove Nova{$this->model}ResourceTest."
2538
);
2639
}
2740

28-
if ($this->classExists('nova', "Nova{$this->model}Test")) {
41+
$novaResources = $this->getCommonNovaResources();
42+
43+
if (count($novaResources) > 1) {
44+
$foundedResources = implode(', ', $novaResources);
45+
46+
// TODO: Change exception message after https://github.com/RonasIT/laravel-entity-generator/issues/159 will be ready
2947
$this->throwFailureException(
30-
ClassAlreadyExistsException::class,
31-
"Cannot create Nova{$this->model}Test cause it's already exist.",
32-
"Remove Nova{$this->model}Test."
48+
EntityCreateException::class,
49+
"Cannot create Nova{$this->model}ResourceTest cause was found a lot of suitable resources: {$foundedResources}.",
50+
'Make test by yourself.'
3351
);
3452
}
3553

54+
if (empty($novaResources)) {
55+
// TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179
56+
$this->throwFailureException(
57+
ClassNotExistsException::class,
58+
"Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.",
59+
"Create {$this->model} Nova resource."
60+
);
61+
}
62+
63+
$this->novaResourceClassName = Arr::first($novaResources);
64+
3665
parent::generate();
3766
} else {
3867
event(new SuccessCreateMessage("Nova is not installed and NovaTest is skipped"));
@@ -48,21 +77,23 @@ public function generateTests(): void
4877
$actions = $this->getActions();
4978
$filters = $this->collectFilters();
5079

80+
$resourceClass = Str::afterLast($this->novaResourceClassName, '\\');
81+
5182
$fileContent = $this->getStub('nova_test', [
52-
'url_path' => Str::kebab($this->model) . '-resources',
5383
'entity_namespace' => $this->getNamespace('models', $this->modelSubFolder),
5484
'entity' => $this->model,
55-
'entities' => $this->getPluralName($this->model),
56-
'snake_entity' => Str::snake($this->model),
85+
'resource_name' => $resourceClass,
86+
'resource_namespace' => $this->novaResourceClassName,
87+
'snake_resource' => Str::snake($resourceClass),
5788
'dromedary_entity' => Str::lcfirst($this->model),
5889
'lower_entities' => $this->getPluralName(Str::snake($this->model)),
5990
'actions' => $actions,
6091
'filters' => $filters,
6192
]);
6293

63-
$this->saveClass('tests', "Nova{$this->model}Test", $fileContent);
94+
$this->saveClass('tests', "Nova{$this->model}ResourceTest", $fileContent);
6495

65-
event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->model}Test"));
96+
event(new SuccessCreateMessage("Created a new Nova test: Nova{$this->model}ResourceTest"));
6697
}
6798

6899
protected function getActions(): array
@@ -83,19 +114,59 @@ protected function getActions(): array
83114
}, $actions);
84115
}
85116

117+
protected function getNovaFiles(): Generator
118+
{
119+
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->novaPath));
120+
121+
foreach ($iterator as $file) {
122+
if ($file->isFile() && $file->getExtension() === 'php') {
123+
yield $file;
124+
}
125+
}
126+
}
127+
128+
protected function getCommonNovaResources(): array
129+
{
130+
$resources = [];
131+
132+
foreach ($this->getNovaFiles() as $file) {
133+
$relativePath = Str::after($file->getPathname(), $this->novaPath . DIRECTORY_SEPARATOR);
134+
135+
$class = Str::before($relativePath, '.');
136+
137+
$className = $this->pathToNamespace($this->novaPath . DIRECTORY_SEPARATOR . $class);
138+
139+
if ($this->isResourceNameContainModel($className) && $this->isNovaResource($className)) {
140+
$resources[] = $className;
141+
}
142+
}
143+
144+
return $resources;
145+
}
146+
147+
protected function isResourceNameContainModel(string $className): bool
148+
{
149+
return str_contains($className, $this->model);
150+
}
151+
152+
protected function isNovaResource(string $className): bool
153+
{
154+
return is_subclass_of($className, 'Laravel\\Nova\\Resource');
155+
}
156+
86157
protected function loadNovaActions()
87158
{
88-
return app("\\App\\Nova\\{$this->novaModelName}")->actions(new NovaRequest());
159+
return app($this->novaResourceClassName)->actions(new NovaRequest());
89160
}
90161

91162
protected function loadNovaFields()
92163
{
93-
return app("\\App\\Nova\\{$this->novaModelName}")->fields(new NovaRequest());
164+
return app($this->novaResourceClassName)->fields(new NovaRequest());
94165
}
95166

96167
protected function loadNovaFilters()
97168
{
98-
return app("\\App\\Nova\\{$this->novaModelName}")->filters(new NovaRequest());
169+
return app($this->novaResourceClassName)->filters(new NovaRequest());
99170
}
100171

101172
public function getTestClassName(): string
@@ -107,28 +178,7 @@ protected function isFixtureNeeded($type): bool
107178
{
108179
return true;
109180
}
110-
111-
protected function doesNovaResourceExists(): bool
112-
{
113-
$subFolder = $this->modelSubFolder ? $this->modelSubFolder . '/' : '';
114-
115-
$possibleNovaModelNames = [
116-
"{$this->model}NovaResource",
117-
"{$subFolder}{$this->model}Resource",
118-
$this->model
119-
];
120-
121-
foreach ($possibleNovaModelNames as $modelName) {
122-
if ($this->classExists('nova', $modelName)) {
123-
$this->novaModelName = $this->pathToNamespace($modelName);
124-
125-
return true;
126-
}
127-
}
128-
129-
return false;
130-
}
131-
181+
132182
protected function collectFilters(): array
133183
{
134184
$filtersFromFields = $this->getFiltersFromFields();
@@ -164,7 +214,7 @@ protected function getFiltersFromFields(): array
164214

165215
protected function getFilters(): array
166216
{
167-
$filters= [];
217+
$filters = [];
168218
$novaResourceFilters = $this->loadNovaFilters();
169219

170220
foreach ($novaResourceFilters as $filter) {

0 commit comments

Comments
 (0)