Skip to content

Commit

Permalink
roles tests done, next permissions tests
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattCast44 committed Dec 13, 2024
1 parent 6edd265 commit 378e231
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 11 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ Please review [our security policy](../../security/policy) on how to report secu
## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

## Todo

- make it easier to assign a super-admin role, kinda of like the before method in laravel policies
3 changes: 0 additions & 3 deletions src/Attributes/BaseDescribe.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

namespace Statix\Sentra\Attributes;

use Attribute;

#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
abstract class BaseDescribe
{
public ?string $label = null;
Expand Down
2 changes: 2 additions & 0 deletions src/Attributes/Permissions/Describe.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Statix\Sentra\Attributes\Permissions;

use Attribute;
use BackedEnum;
use Illuminate\Support\Collection;
use Statix\Sentra\Attributes\BaseDescribe;

#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Describe extends BaseDescribe
{
public Collection $roles;
Expand Down
2 changes: 2 additions & 0 deletions src/Attributes/Roles/Describe.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace Statix\Sentra\Attributes\Roles;

use Attribute;
use BackedEnum;
use Illuminate\Support\Collection;
use Statix\Sentra\Attributes\BaseDescribe;

#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Describe extends BaseDescribe
{
public Collection $permissions;
Expand Down
12 changes: 9 additions & 3 deletions src/Concerns/AsRole.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,22 @@ public function hasIndirectPermission(BackedEnum $permission): bool
*/
public function hasAnyPermission(array $permissions): bool
{
return $this->getPermissions()->intersect($permissions)->isNotEmpty();
$assigned = $this->getPermissions()->map(fn ($permission) => $permission->value);

$check = collect($permissions)->map(fn ($permission) => $permission->value);

return $assigned->intersect($check)->isNotEmpty();
}

/**
* @param BackedEnum[] $permissions
*/
public function hasAllPermissions(array $permissions): bool
{
$permissions = collect($permissions);
$assigned = $this->getPermissions()->map(fn ($permission) => $permission->value);

$check = collect($permissions)->map(fn ($permission) => $permission->value);

return $this->getPermissions()->intersect($permissions)->count() === $permissions->count();
return $assigned->intersect($check)->count() === $check->count();
}
}
47 changes: 47 additions & 0 deletions tests/Permissions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Statix\Sentra\Tests;

use Statix\Sentra\Attributes\Permissions\Describe;
use Statix\Sentra\Concerns\AsPermission;

enum Permissions: string
{
use AsPermission;

#[Describe(
label: 'Create Post',
description: 'Ability to create a new post',
roles: [
Roles::SuperAdmin,
]
)]
case CREATE_POST = 'create_post';

#[Describe(
label: 'Update Post',
description: 'Ability to update a post',
roles: [
Roles::SuperAdmin,
]
)]
case UPDATE_POST = 'update_post';

#[Describe(
label: 'Delete Post',
description: 'Ability to delete a post',
roles: [
Roles::SuperAdmin,
]
)]
case DELETE_POST = 'delete_post';

#[Describe(
label: 'Permission One',
description: 'Permission one description',
roles: [
Roles::SuperAdmin,
]
)]
case PermissionOne = 'permission_one';
}
2 changes: 1 addition & 1 deletion tests/PermissionsTest.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php

//
//
62 changes: 62 additions & 0 deletions tests/Roles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Statix\Sentra\Tests;

use Statix\Sentra\Attributes\Roles\Describe;
use Statix\Sentra\Concerns\AsRole;

enum Roles: string
{
use AsRole;

#[Describe(
label: 'Super Admin',
description: 'Super admin role, can access all features. Can access admin features.',
)]
case SuperAdmin = 'super_admin';

#[Describe(
label: 'Standard User',
description: 'Standard user role, can access basic features. Can not access admin features.',
permissions: [
Permissions::CREATE_POST,
Permissions::UPDATE_POST,
]
)]
case StandardUser = 'standard_user';

#[Describe(
label: 'Admin User',
description: 'Admin user role, can access all features. Can access admin features.',
permissions: [
Permissions::CREATE_POST,
Permissions::UPDATE_POST,
Permissions::DELETE_POST,
]
)]
case AdminUser = 'admin_user';

#[Describe(
description: 'No set label role',
)]
case NoSetLabel = 'no_set_label';

#[Describe(
label: 'No Set Description',
)]
case NoSetDescription = 'no_set_description';

#[Describe(
label: 'Canned Label',
description: 'Canned description',
)]
case CannedDescription = 'canned_description';

#[Describe(
label: 'With Permissions',
permissions: [
Permissions::PermissionOne,
]
)]
case WithPermissions = 'with_permissions';
}
2 changes: 1 addition & 1 deletion tests/RolesAndPermissionsTest.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<?php

//
//
170 changes: 168 additions & 2 deletions tests/RolesTest.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,169 @@
<?php
<?php

//
use Illuminate\Support\Collection;
use Statix\Sentra\Tests\Permissions;
use Statix\Sentra\Tests\Roles;

it('can use the config file to get the roles enum', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$this->assertNotNull($roleEnum);

expect($roleEnum::cases())->toBeArray();
});

// it can get the label of a role
it('can get the label of a role', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

expect($role->getLabel())->toBe('Super Admin');
});

// if a role does not have a label, it will convert the name to a human readable label
it('can convert the name of a role to a human readable label', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::NoSetLabel;

expect($role->getLabel())->toBe('No Set Label');
});

// it can get the description of a role
it('can get the description of a role', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::CannedDescription;

expect($role->getDescription())->toBe('Canned description');
});

// if a role does not have a description, it will return null
it('can return null if a role does not have a description', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::NoSetDescription;

expect($role->getDescription())->toBeNull();
});

// it can get the permissions of a role
it('can get the permissions of a role', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::WithPermissions;

$permissions = $role->getPermissions();
expect($permissions)->toBeInstanceOf(Collection::class);
expect($permissions)->toHaveCount(1);
expect($permissions->first())->toBe(Permissions::PermissionOne);
});

// it can get only the direct permissions of a role
it('can get only the direct permissions of a role', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

$permissions = $role->directPermissions();

expect($permissions)->toBeInstanceOf(Collection::class);
expect($permissions)->toHaveCount(0);
});

// it can get only the indirect permissions of a role
it('can get only the indirect permissions of a role', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

$permissions = $role->indirectPermissions();

expect($permissions)->toBeInstanceOf(Collection::class);
expect($permissions->count())->toBeGreaterThan(0);
});

// it can use the can method to check for a permission
it('can use the can method to check for a permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

expect($role->can(Permissions::CREATE_POST))->toBeTrue();
});

// it can use the cannot method to check for a permission
it('can use the cannot method to check for lack of a permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::StandardUser;

expect($role->cannot(Permissions::DELETE_POST))->toBeTrue();
});

// it can use the hasPermission method to check for a permission
it('can use the hasPermission method to check for a permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::AdminUser;

expect($role->hasPermission(Permissions::DELETE_POST))->toBeTrue();
});

// it can use the hasDirectPermission method to check for a direct permission
it('can use the hasDirectPermission method to check for a direct permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

expect($role->hasDirectPermission(Permissions::DELETE_POST))->toBeFalse();
});

// it can use the hasIndirectPermission method to check for an indirect permission
it('can use the hasIndirectPermission method to check for an indirect permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::SuperAdmin;

expect($role->hasIndirectPermission(Permissions::DELETE_POST))->toBeTrue();
});

// it can use the hasAnyPermission method to check for any permission
it('can use the hasAnyPermission method to check for any permission', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::StandardUser;

// dd((array) $role->getPermissions(), (array) [Permissions::CREATE_POST, Permissions::DELETE_POST]);

expect($role->hasAnyPermission([Permissions::CREATE_POST, Permissions::DELETE_POST]))->toBeTrue();
});

// it can use the hasAllPermissions method to check for all permissions
it('can use the hasAllPermissions method to check for all permissions', function () {
/** @var Roles $roleEnum */
$roleEnum = config('sentra.roles_enum');

$role = $roleEnum::AdminUser;

expect($role->hasAllPermissions([Permissions::CREATE_POST, Permissions::UPDATE_POST, Permissions::DELETE_POST]))->toBeTrue();

$role = $roleEnum::StandardUser;

expect($role->hasAllPermissions([Permissions::CREATE_POST, Permissions::UPDATE_POST, Permissions::DELETE_POST]))->toBeFalse();
});
3 changes: 2 additions & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ protected function getPackageProviders($app)

public function getEnvironmentSetUp($app)
{
//
config()->set('sentra.roles_enum', Roles::class);
config()->set('sentra.permissions_enum', Permissions::class);
}
}

0 comments on commit 378e231

Please sign in to comment.