Skip to content

Commit 08b8b8d

Browse files
committed
cleaning and imporovenment
1 parent 9f9dcc6 commit 08b8b8d

12 files changed

+630
-18
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bugover/ship",
3-
"version": "1.9.12",
3+
"version": "1.9.13",
44
"type": "library",
55
"description": "Core package for Porto architecture.",
66
"keywords": [

src/Abstracts/Provider/MiddlewareServiceProvider.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
use Illuminate\Contracts\Container\BindingResolutionException;
88
use Nucleus\Loaders\MiddlewaresLoaderTrait;
9+
use Illuminate\Support\ServiceProvider as LaravelAppServiceProvider;
910

10-
abstract class MiddlewareServiceProvider extends MainServiceProvider
11+
abstract class MiddlewareServiceProvider extends LaravelAppServiceProvider
1112
{
1213
use MiddlewaresLoaderTrait;
1314

src/Loaders/AliasesLoaderTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ trait AliasesLoaderTrait
1010
{
1111
public function loadAliases(): void
1212
{
13-
foreach ($this->aliases ?? [] as $aliasKey => $aliasValue) {
13+
foreach ($this->aliases as $aliasKey => $aliasValue) {
1414
if (class_exists($aliasValue)) {
1515
$this->loadAlias($aliasKey, $aliasValue);
1616
}
1717
}
1818
}
1919

2020
/**
21-
* @param $aliasKey
22-
* @param $aliasValue
21+
* @param string $aliasKey
22+
* @param string $aliasValue
2323
*/
2424
private function loadAlias(string $aliasKey, string $aliasValue): void
2525
{

src/Loaders/CommandsLoaderTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
trait CommandsLoaderTrait
1313
{
1414
/**
15-
* @param $containerPath
15+
* @param string $containerPath
1616
* @return void
1717
*/
1818
public function loadCommandsFromContainers(string $containerPath): void

src/Loaders/MiddlewaresLoaderTrait.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ trait MiddlewaresLoaderTrait
1515
*/
1616
public function loadMiddlewares(): void
1717
{
18-
$this->registerMiddleware($this->middlewares);
19-
$this->registerMiddlewareGroups($this->middlewareGroups);
20-
$this->registerMiddlewarePriority($this->middlewarePriority);
21-
$this->registerRouteMiddleware($this->routeMiddleware);
18+
if (!empty($this->middlewares)) {
19+
$this->registerMiddleware($this->middlewares);
20+
}
21+
if (!empty($this->middlewareGroups)) {
22+
$this->registerMiddlewareGroups($this->middlewareGroups);
23+
}
24+
if (!empty($this->middlewarePriority)) {
25+
$this->registerMiddlewarePriority($this->middlewarePriority);
26+
}
27+
if (!empty($this->routeMiddleware)) {
28+
$this->registerRouteMiddleware($this->routeMiddleware);
29+
}
2230
}
2331

2432
/**

src/Loaders/MigrationsLoaderTrait.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ private function loadMigrations(string $directory): void
3131
*/
3232
public function loadMigrationsFromShip(): void
3333
{
34-
$ship_migration_directory = config('app.path') . MainNuclear::SHIP_NAME . DIRECTORY_SEPARATOR . 'Migrations';
35-
$this->loadMigrations($ship_migration_directory);
34+
$shipMigrationDirectory = config('app.path') . MainNuclear::SHIP_NAME . DIRECTORY_SEPARATOR . 'Migrations';
35+
$this->loadMigrations($shipMigrationDirectory);
3636
}
3737
}

src/Loaders/ModelMapLoader.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@
1212

1313
trait ModelMapLoader
1414
{
15+
private static array $loadedModels = [];
16+
1517
/**
1618
* @param string $containerPath
1719
* @return void
1820
*/
1921
private function loadModelMapsFromContainers(string $containerPath): void
2022
{
23+
if (!empty(self::$loadedModels)) {
24+
return;
25+
}
26+
2127
$containerModelsDirectory = $containerPath . DIRECTORY_SEPARATOR . 'Model';
2228
$this->loadModels($containerModelsDirectory);
2329
}
@@ -37,12 +43,12 @@ private function loadModels(string $directory): void
3743
$modelClass = Nuclear::getClassFullNameFromFile($modelFile->getPathname());
3844
$instance = (new $modelClass());
3945
if ($instance instanceof EntityContract && property_exists($instance, 'map')) {
40-
$result[$instance->getMap()] = $modelFile;
46+
self::$loadedModels[$instance->getMap()] = $modelFile;
4147
}
4248
}
4349
}
4450

45-
Relation::morphMap($result);
51+
Relation::morphMap(self::$loadedModels);
4652
}
4753

4854
/**

src/Loaders/ProvidersLoaderTrait.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ trait ProvidersLoaderTrait
1818
* loaded from the `boot()` function on the parent of the Main
1919
* Service Providers.
2020
*
21-
* @param $containerPath
21+
* @param string $containerPath
2222
*/
2323
public function loadOnlyMainProvidersFromContainers(string $containerPath): void
2424
{
@@ -52,12 +52,12 @@ private function loadProviders(string $directory): void
5252
}
5353

5454
/**
55-
* @param $provider_full_name
55+
* @param string $providerFullName
5656
* @return void
5757
*/
58-
private function loadProvider(string $provider_full_name): void
58+
private function loadProvider(string $providerFullName): void
5959
{
60-
App::register($provider_full_name);
60+
App::register($providerFullName);
6161
}
6262

6363
/**
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
3+
namespace Nucleus\Traits\TestsTraits\PhpUnit;
4+
5+
use Illuminate\Support\Facades\Config;
6+
use Illuminate\Support\Facades\Hash;
7+
use Nucleus\Abstracts\Model\AuthModel;
8+
9+
trait TestsAuthHelperTrait
10+
{
11+
/**
12+
* Logged in user object.
13+
*/
14+
protected AuthModel|null $testingUser = null;
15+
16+
/**
17+
* User class used by factory to create testing user
18+
*/
19+
protected ?string $userClass = null;
20+
21+
/**
22+
* Roles and permissions, to be attached on the user
23+
*/
24+
protected array $access = [
25+
'permissions' => '',
26+
'roles' => '',
27+
];
28+
29+
/**
30+
* state name on User factory
31+
*/
32+
private ?string $userAdminState = null;
33+
34+
/**
35+
* create testing user as Admin.
36+
*/
37+
private ?bool $createUserAsAdmin = null;
38+
39+
/**
40+
* Same as `getTestingUser()` but always overrides the User Access
41+
* (roles and permissions) with null. So the user can be used to test
42+
* if unauthorized user tried to access your protected endpoint.
43+
*
44+
* @param null $userDetails
45+
* @param bool $createUserAsAdmin
46+
* @return AuthModel
47+
*/
48+
public function getTestingUserWithoutAccess($userDetails = null, bool $createUserAsAdmin = false): AuthModel
49+
{
50+
return $this->getTestingUser($userDetails, $this->getNullAccess(), $createUserAsAdmin);
51+
}
52+
53+
/**
54+
* Try to get the last logged-in User, if not found then create new one.
55+
* Note: if $userDetails are provided it will always create new user, even
56+
* if another one was previously created during the execution of your test.
57+
*
58+
* By default, Users will be given the Roles and Permissions found in the class
59+
* `$access` property. But the $access parameter can be used to override the
60+
* defined roles and permissions in the `$access` property of your class.
61+
*
62+
* @param array|null $userDetails what to be attached on the User object
63+
* @param array|null $access roles and permissions you'd like to provide this user with
64+
* @param bool $createUserAsAdmin should create testing user as admin
65+
* @return AuthModel
66+
*/
67+
public function getTestingUser(
68+
?array $userDetails = null,
69+
?array $access = null,
70+
bool $createUserAsAdmin = false
71+
): AuthModel
72+
{
73+
$this->createUserAsAdmin = $createUserAsAdmin;
74+
$this->userClass = $this->userclass ?? Config::get('nucleus.tests.user-class');
75+
$this->userAdminState = Config::get('nucleus.tests.user-admin-state');
76+
77+
return is_null($userDetails) ? $this->findOrCreateTestingUser($userDetails, $access)
78+
: $this->createTestingUser($userDetails, $access);
79+
}
80+
81+
private function findOrCreateTestingUser($userDetails, $access): AuthModel
82+
{
83+
return $this->testingUser ?: $this->createTestingUser($userDetails, $access);
84+
}
85+
86+
private function createTestingUser(?array $userDetails = null, ?array $access = null): AuthModel
87+
{
88+
// create new user
89+
$user = $this->factoryCreateUser($userDetails);
90+
91+
// assign user roles and permissions based on the access property
92+
$user = $this->setupTestingUserAccess($user, $access);
93+
94+
// authentication the user
95+
$this->actingAs($user, 'api');
96+
97+
// set the created user
98+
return $this->testingUser = $user;
99+
}
100+
101+
private function factoryCreateUser(?array $userDetails = null): AuthModel
102+
{
103+
$user = str_replace('::class', '', $this->userClass);
104+
if ($this->createUserAsAdmin) {
105+
$state = $this->userAdminState;
106+
107+
return $user::factory()->$state()->create($this->prepareUserDetails($userDetails));
108+
}
109+
110+
return $user::factory()->create($this->prepareUserDetails($userDetails));
111+
}
112+
113+
private function prepareUserDetails(?array $userDetails = null): array
114+
{
115+
$defaultUserDetails = [
116+
'name' => $this->faker->name,
117+
'email' => $this->faker->email,
118+
'password' => 'testing-password',
119+
];
120+
121+
// if no user detail provided, use the default details, to find the password or generate one before encoding it
122+
return $this->prepareUserPassword($userDetails ?: $defaultUserDetails);
123+
}
124+
125+
private function prepareUserPassword(?array $userDetails): ?array
126+
{
127+
// get password from the user details or generate one
128+
$password = $userDetails['password'] ?? $this->faker->password;
129+
130+
// hash the password and set it back at the user details
131+
$userDetails['password'] = Hash::make($password);
132+
133+
return $userDetails;
134+
}
135+
136+
private function setupTestingUserAccess($user, ?array $access = null)
137+
{
138+
$access = $access ?: $this->getAccess();
139+
140+
$user = $this->setupTestingUserPermissions($user, $access);
141+
$user = $this->setupTestingUserRoles($user, $access);
142+
143+
return $user;
144+
}
145+
146+
private function getAccess(): ?array
147+
{
148+
return $this->access ?? null;
149+
}
150+
151+
private function setupTestingUserPermissions($user, ?array $access)
152+
{
153+
if (!empty($access['permissions'])) {
154+
$user->givePermissionTo($access['permissions']);
155+
$user = $user->fresh();
156+
}
157+
158+
return $user;
159+
}
160+
161+
private function setupTestingUserRoles($user, ?array $access)
162+
{
163+
if (!empty($access['roles']) && !$user->hasRole($access['roles'])) {
164+
$user->assignRole($access['roles']);
165+
$user = $user->fresh();
166+
}
167+
168+
return $user;
169+
}
170+
171+
private function getNullAccess(): array
172+
{
173+
return [
174+
'permissions' => null,
175+
'roles' => null,
176+
];
177+
}
178+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Nucleus\Traits\TestsTraits\PhpUnit;
6+
7+
use Illuminate\Support\Facades\App;
8+
use Mockery;
9+
use Mockery\MockInterface;
10+
11+
trait TestsMockHelperTrait
12+
{
13+
public function mockIt($class): MockInterface
14+
{
15+
$mock = Mockery::mock($class);
16+
App::instance($class, $mock);
17+
18+
return $mock;
19+
}
20+
}

0 commit comments

Comments
 (0)