Skip to content

Commit 3e99b06

Browse files
committed
Merge branch 'master' into 179-resource-exists-exception
# Conflicts: # src/Generators/NovaTestGenerator.php # tests/NovaTestGeneratorTest.php
2 parents 7da2670 + a875233 commit 3e99b06

File tree

10 files changed

+312
-200
lines changed

10 files changed

+312
-200
lines changed

src/Generators/EntityGenerator.php

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

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

src/Generators/NovaTestGenerator.php

Lines changed: 90 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,61 @@
66
use Laravel\Nova\NovaServiceProvider;
77
use Laravel\Nova\Http\Requests\NovaRequest;
88
use RonasIT\Support\Events\SuccessCreateMessage;
9+
use RonasIT\Support\Exceptions\ClassAlreadyExistsException;
910
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;
1016
use RonasIT\Support\Exceptions\ResourceAlreadyExistsException;
1117

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

1631
public function generate(): void
1732
{
1833
if (class_exists(NovaServiceProvider::class)) {
19-
if (!$this->doesNovaResourceExists()) {
34+
if ($this->classExists('nova', "Nova{$this->model}ResourceTest")) {
35+
36+
$path = $this->getClassPath('nova', "Nova{$this->model}ResourceTest");
37+
38+
throw new ResourceAlreadyExistsException($path);
39+
}
40+
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
47+
$this->throwFailureException(
48+
EntityCreateException::class,
49+
"Cannot create Nova{$this->model}ResourceTest cause was found a lot of suitable resources: {$foundedResources}.",
50+
'Make test by yourself.'
51+
);
52+
}
53+
54+
if (empty($novaResources)) {
2055
// TODO: pass $this->modelSubfolder to Exception after refactoring in https://github.com/RonasIT/laravel-entity-generator/issues/179
2156
$this->throwFailureException(
2257
ClassNotExistsException::class,
23-
"Cannot create Nova{$this->model}Test cause {$this->model} Nova resource does not exist.",
58+
"Cannot create Nova{$this->model}ResourceTest cause {$this->model} Nova resource does not exist.",
2459
"Create {$this->model} Nova resource."
2560
);
2661
}
2762

28-
if ($this->classExists('nova', "Nova{$this->model}Test")) {
29-
$path = $this->getClassPath('nova', "Nova{$this->model}Test");
30-
31-
throw new ResourceAlreadyExistsException($path);
32-
}
63+
$this->novaResourceClassName = Arr::first($novaResources);
3364

3465
parent::generate();
3566
} else {
@@ -46,21 +77,23 @@ public function generateTests(): void
4677
$actions = $this->getActions();
4778
$filters = $this->collectFilters();
4879

80+
$resourceClass = Str::afterLast($this->novaResourceClassName, '\\');
81+
4982
$fileContent = $this->getStub('nova_test', [
50-
'url_path' => Str::kebab($this->model) . '-resources',
5183
'entity_namespace' => $this->getNamespace('models', $this->modelSubFolder),
5284
'entity' => $this->model,
53-
'entities' => $this->getPluralName($this->model),
54-
'snake_entity' => Str::snake($this->model),
85+
'resource_name' => $resourceClass,
86+
'resource_namespace' => $this->novaResourceClassName,
87+
'snake_resource' => Str::snake($resourceClass),
5588
'dromedary_entity' => Str::lcfirst($this->model),
5689
'lower_entities' => $this->getPluralName(Str::snake($this->model)),
5790
'actions' => $actions,
5891
'filters' => $filters,
5992
]);
6093

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

63-
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"));
6497
}
6598

6699
protected function getActions(): array
@@ -81,19 +114,59 @@ protected function getActions(): array
81114
}, $actions);
82115
}
83116

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+
84157
protected function loadNovaActions()
85158
{
86-
return app("\\App\\Nova\\{$this->novaModelName}")->actions(new NovaRequest());
159+
return app($this->novaResourceClassName)->actions(new NovaRequest());
87160
}
88161

89162
protected function loadNovaFields()
90163
{
91-
return app("\\App\\Nova\\{$this->novaModelName}")->fields(new NovaRequest());
164+
return app($this->novaResourceClassName)->fields(new NovaRequest());
92165
}
93166

94167
protected function loadNovaFilters()
95168
{
96-
return app("\\App\\Nova\\{$this->novaModelName}")->filters(new NovaRequest());
169+
return app($this->novaResourceClassName)->filters(new NovaRequest());
97170
}
98171

99172
public function getTestClassName(): string
@@ -106,27 +179,6 @@ protected function isFixtureNeeded($type): bool
106179
return true;
107180
}
108181

109-
protected function doesNovaResourceExists(): bool
110-
{
111-
$subFolder = $this->modelSubFolder ? $this->modelSubFolder . '/' : '';
112-
113-
$possibleNovaModelNames = [
114-
"{$this->model}NovaResource",
115-
"{$subFolder}{$this->model}Resource",
116-
$this->model
117-
];
118-
119-
foreach ($possibleNovaModelNames as $modelName) {
120-
if ($this->classExists('nova', $modelName)) {
121-
$this->novaModelName = $this->pathToNamespace($modelName);
122-
123-
return true;
124-
}
125-
}
126-
127-
return false;
128-
}
129-
130182
protected function collectFilters(): array
131183
{
132184
$filtersFromFields = $this->getFiltersFromFields();
@@ -162,7 +214,7 @@ protected function getFiltersFromFields(): array
162214

163215
protected function getFilters(): array
164216
{
165-
$filters= [];
217+
$filters = [];
166218
$novaResourceFilters = $this->loadNovaFilters();
167219

168220
foreach ($novaResourceFilters as $filter) {

0 commit comments

Comments
 (0)