diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5172429 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 570ceef..e925804 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +build/ vendor/ composer.lock /.idea/* \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 0000000..d088919 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +C:37:"PHPUnit\Runner\DefaultTestResultCache":14334:{a:2:{s:7:"defects";a:57:{s:61:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::it_returns_true";i:4;s:66:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::it_has_a_users_table";i:3;s:88:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_permissions_to_roles";i:3;s:90:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role";i:4;s:98:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_multiple_permissions_to_a_role";i:4;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role_by_id";i:4;s:98:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role_by_slug";i:4;s:107:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_multiple_permissions_to_a_role_by_slugs";i:4;s:97:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_has_a_given_permission";i:4;s:110:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_with_no_access_never_has_permission";i:4;s:107:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_does_not_have_a_given_permission";i:4;s:112:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_with_all_access_always_has_permission";i:4;s:92:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_a_permission_from_a_role";i:4;s:88:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_a_permission_to_a_role";i:4;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_a_permission_to_a_role_by_slug";i:4;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role";i:4;s:105:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role_by_slugs";i:4;s:100:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_a_permission_from_a_role_by_slug";i:4;s:100:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role";i:4;s:109:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role_by_slugs";i:4;s:64:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_a_permission";i:4;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_assert_has_a_given_permission";i:4;s:82:"Caffeinated\Shinobi\Tests\UserTest::it_can_assert_does_not_have_a_given_permission";i:4;s:61:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_a_role";i:4;s:100:"Caffeinated\Shinobi\Tests\UserTest::it_has_no_permissions_when_assigned_a_role_with_a_no_access_flag";i:4;s:90:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_with_no_access_flag_never_has_permission";i:4;s:92:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_with_all_access_flag_always_has_permission";i:4;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_has_a_given_permission_through_role";i:4;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_has_a_given_permission";i:4;s:82:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_does_not_have_a_given_permission";i:4;s:53:"Caffeinated\Shinobi\Tests\GrumpyTest::it_returns_true";i:4;s:61:"Caffeinated\Shinobi\Tests\GrumpyTest::it_has_necessary_tables";i:3;s:64:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_a_permission";i:4;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_a_permission_by_slug";i:4;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_multiple_permissions";i:4;s:80:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_multiple_permissions_by_slug";i:4;s:66:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_a_permission";i:4;s:74:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_a_permission_by_slug";i:4;s:74:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_multiple_permissions";i:4;s:83:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_multiple_permissions_by_slugs";i:4;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_a_permission_by_slug";i:4;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_multiple_permissions";i:4;s:80:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_multiple_permissions_by_slug";i:4;s:66:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_a_permission";i:4;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_a_permission_by_slug";i:4;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_multiple_permissions";i:4;s:83:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_multiple_permissions_by_slugs";i:4;s:69:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_a_role_by_slug";i:4;s:69:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_multiple_roles";i:4;s:78:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_multiple_roles_by_slugs";i:4;s:94:"Caffeinated\Shinobi\Tests\BladeTest::the_can_directive_evaluates_true_when_permissions_are_met";i:3;s:101:"Caffeinated\Shinobi\Tests\BladeTest::the_cannot_directive_evaluates_true_when_permissions_are_not_met";i:4;s:98:"Caffeinated\Shinobi\Tests\BladeTest::the_cannot_directive_evaluates_false_when_permissions_are_met";i:3;s:99:"Caffeinated\Shinobi\Tests\BladeTest::the_can_directive_evaluates_false_when_permissions_are_not_met";i:4;s:95:"Caffeinated\Shinobi\Tests\BladeTest::the_role_directive_evaluates_true_when_user_has_given_role";i:4;s:107:"Caffeinated\Shinobi\Tests\BladeTest::the_role_directive_evaluates_false_when_user_does_not_have_given_roles";i:4;s:61:"Caffeinated\Shinobi\Tests\BladeTest::guests_do_not_have_roles";i:4;}s:5:"times";a:87:{s:61:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::it_returns_true";d:0.124;s:66:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::is_has_a_users_table";d:0.11;s:66:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::it_has_a_users_table";d:0.017;s:69:"Caffeinated\Shinobi\Tests\Feature\GrumpyTest::it_has_necessary_tables";d:0.015;s:69:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_returns_true";d:0.018;s:88:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_permissions_to_roles";d:0.025;s:98:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_multiple_permissions_to_a_role";d:0.019;s:90:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role";d:0.024;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role_by_id";d:0.022;s:98:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_a_permission_to_a_role_by_slug";d:0.016;s:107:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assign_multiple_permissions_to_a_role_by_slugs";d:0.02;s:97:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_has_a_given_permission";d:0.02;s:107:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_does_not_have_a_given_permission";d:0.016;s:110:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_with_no_access_never_has_permission";d:0.017;s:112:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_assert_a_role_with_all_access_always_has_permission";d:0.016;s:92:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_a_permission_from_a_role";d:0.017;s:88:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_a_permission_to_a_role";d:0.025;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_a_permission_to_a_role_by_slug";d:0.02;s:96:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role";d:0.019;s:105:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role_by_slugs";d:0.019;s:100:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_a_permission_from_a_role_by_slug";d:0.019;s:100:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role";d:0.02;s:109:"Caffeinated\Shinobi\Tests\Feature\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role_by_slugs";d:0.022;s:53:"Caffeinated\Shinobi\Tests\GrumpyTest::it_returns_true";d:0.014;s:61:"Caffeinated\Shinobi\Tests\GrumpyTest::it_has_necessary_tables";d:0.015;s:80:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_give_a_permission_to_a_role";d:0.026;s:88:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_give_a_permission_to_a_role_by_slug";d:0.017;s:88:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role";d:0.02;s:97:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_give_multiple_permissions_to_a_role_by_slugs";d:0.021;s:84:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_revoke_a_permission_from_a_role";d:0.017;s:92:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_revoke_a_permission_from_a_role_by_slug";d:0.02;s:92:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role";d:0.02;s:101:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_revoke_multiple_permissions_from_a_role_by_slugs";d:0.023;s:89:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_assert_a_role_has_a_given_permission";d:0.018;s:99:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_assert_a_role_does_not_have_a_given_permission";d:0.017;s:102:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_assert_a_role_with_no_access_never_has_permission";d:0.016;s:104:"Caffeinated\Shinobi\Tests\HasPermissionsTest::it_can_assert_a_role_with_all_access_always_has_permission";d:0.017;s:70:"Caffeinated\Shinobi\Tests\RoleTest::it_can_give_a_permission_to_a_role";d:0.027;s:78:"Caffeinated\Shinobi\Tests\RoleTest::it_can_give_a_permission_to_a_role_by_slug";d:0.017;s:78:"Caffeinated\Shinobi\Tests\RoleTest::it_can_give_multiple_permissions_to_a_role";d:0.022;s:87:"Caffeinated\Shinobi\Tests\RoleTest::it_can_give_multiple_permissions_to_a_role_by_slugs";d:0.027;s:74:"Caffeinated\Shinobi\Tests\RoleTest::it_can_revoke_a_permission_from_a_role";d:0.018;s:82:"Caffeinated\Shinobi\Tests\RoleTest::it_can_revoke_a_permission_from_a_role_by_slug";d:0.018;s:82:"Caffeinated\Shinobi\Tests\RoleTest::it_can_revoke_multiple_permissions_from_a_role";d:0.018;s:91:"Caffeinated\Shinobi\Tests\RoleTest::it_can_revoke_multiple_permissions_from_a_role_by_slugs";d:0.021;s:79:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_a_role_has_a_given_permission";d:0.018;s:89:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_a_role_does_not_have_a_given_permission";d:0.016;s:92:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_a_role_with_no_access_never_has_permission";d:0.016;s:94:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_a_role_with_all_access_always_has_permission";d:0.016;s:64:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_a_permission";d:0.017;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_a_permission_by_slug";d:0.018;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_multiple_permissions";d:0.018;s:80:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_given_multiple_permissions_by_slug";d:0.02;s:66:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_a_permission";d:0.022;s:74:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_a_permission_by_slug";d:0.016;s:74:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_multiple_permissions";d:0.017;s:83:"Caffeinated\Shinobi\Tests\RoleTest::it_can_be_revoked_multiple_permissions_by_slugs";d:0.02;s:72:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_has_a_given_permission";d:0.018;s:82:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_does_not_have_a_given_permission";d:0.015;s:90:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_with_no_access_flag_never_has_permission";d:0.017;s:92:"Caffeinated\Shinobi\Tests\RoleTest::it_can_assert_with_all_access_flag_always_has_permission";d:0.014;s:64:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_a_permission";d:0.018;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_a_permission_by_slug";d:0.017;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_multiple_permissions";d:0.02;s:80:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_given_multiple_permissions_by_slug";d:0.022;s:66:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_a_permission";d:0.018;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_a_permission_by_slug";d:0.019;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_multiple_permissions";d:0.021;s:83:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_revoked_multiple_permissions_by_slugs";d:0.027;s:72:"Caffeinated\Shinobi\Tests\UserTest::it_can_assert_has_a_given_permission";d:0.018;s:82:"Caffeinated\Shinobi\Tests\UserTest::it_can_assert_does_not_have_a_given_permission";d:0.019;s:61:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_a_role";d:0.017;s:69:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_a_role_by_slug";d:0.018;s:69:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_multiple_roles";d:0.019;s:78:"Caffeinated\Shinobi\Tests\UserTest::it_can_be_assigned_multiple_roles_by_slugs";d:0.021;s:85:"Caffeinated\Shinobi\Tests\UserTest::it_can_assert_has_a_given_permission_through_role";d:0.02;s:74:"Caffeinated\Shinobi\Tests\UserTest::it_has_a_given_permission_through_role";d:0.02;s:100:"Caffeinated\Shinobi\Tests\UserTest::it_has_no_permissions_when_assigned_a_role_with_a_no_access_flag";d:0.018;s:87:"Caffeinated\Shinobi\Tests\BladeTest::the_can_directive_renders_when_permissions_are_met";d:0.128;s:94:"Caffeinated\Shinobi\Tests\BladeTest::the_can_directive_evaluates_true_when_permissions_are_met";d:0.13;s:99:"Caffeinated\Shinobi\Tests\BladeTest::the_can_directive_evaluates_false_when_permissions_are_not_met";d:0.019;s:101:"Caffeinated\Shinobi\Tests\BladeTest::the_cannot_directive_evaluates_true_when_permissions_are_not_met";d:0.02;s:98:"Caffeinated\Shinobi\Tests\BladeTest::the_cannot_directive_evaluates_false_when_permissions_are_met";d:0.037;s:95:"Caffeinated\Shinobi\Tests\BladeTest::the_role_directive_evaluates_true_when_user_has_given_role";d:0.018;s:121:"Caffeinated\Shinobi\Tests\BladeTest::the_role_directive_evaluates_true_if_previous_evaluations_didnt_pass_when_using_else";d:0.036;s:107:"Caffeinated\Shinobi\Tests\BladeTest::the_role_directive_evaluates_false_when_user_does_not_have_given_roles";d:0.017;s:61:"Caffeinated\Shinobi\Tests\BladeTest::guests_do_not_have_roles";d:0.016;}}} \ No newline at end of file diff --git a/composer.json b/composer.json index 6bd70d1..0cd1989 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,11 @@ "Caffeinated\\Shinobi\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "Caffeinated\\Shinobi\\Tests\\": "tests/" + } + }, "extra": { "laravel": { "providers": [ @@ -25,5 +30,9 @@ } } }, - "minimum-stability": "dev" + "minimum-stability": "dev", + "require-dev": { + "orchestra/testbench": "^3.7", + "doctrine/dbal": "^2.10@dev" + } } diff --git a/config/shinobi.php b/config/shinobi.php index a93ac5d..b71a8b3 100644 --- a/config/shinobi.php +++ b/config/shinobi.php @@ -3,6 +3,7 @@ return [ 'models' => [ + /* |-------------------------------------------------------------------------- | Model References @@ -18,6 +19,26 @@ ], + 'tables' => [ + + /* + |-------------------------------------------------------------------------- + | Table References + |-------------------------------------------------------------------------- + | + | When customizing the models used by Shinobi, you may also wish to + | customize the table names as well. You will want to publish the + | bundled migrations and update the references here for use. + */ + + 'roles' => 'roles', + 'permissions' => 'permissions', + 'role_user' => 'role_user', + 'permission_role' => 'permission_role', + 'permission_user' => 'permission_user', + + ], + /* |-------------------------------------------------------------------------- | Use Migrations diff --git a/migrations/2015_01_20_084450_create_roles_table.php b/migrations/2015_01_20_084450_create_roles_table.php index 75b14f5..41fd040 100644 --- a/migrations/2015_01_20_084450_create_roles_table.php +++ b/migrations/2015_01_20_084450_create_roles_table.php @@ -12,7 +12,9 @@ class CreateRolesTable extends Migration */ public function up() { - Schema::create('roles', function (Blueprint $table) { + $name = config('shinobi.tables.roles'); + + Schema::create($name, function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name')->unique(); $table->string('slug')->unique(); @@ -28,6 +30,8 @@ public function up() */ public function down() { - Schema::drop('roles'); + $name = config('shinobi.tables.roles'); + + Schema::drop($name); } } diff --git a/migrations/2015_01_20_084525_create_role_user_table.php b/migrations/2015_01_20_084525_create_role_user_table.php index 554a356..78be113 100644 --- a/migrations/2015_01_20_084525_create_role_user_table.php +++ b/migrations/2015_01_20_084525_create_role_user_table.php @@ -12,7 +12,9 @@ class CreateRoleUserTable extends Migration */ public function up() { - Schema::create('role_user', function (Blueprint $table) { + $name = config('shinobi.tables.role_user'); + + Schema::create($name, function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('role_id')->index(); $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade'); @@ -29,6 +31,8 @@ public function up() */ public function down() { - Schema::drop('role_user'); + $name = config('shinobi.tables.role_user'); + + Schema::drop($name); } } diff --git a/migrations/2015_01_24_080208_create_permissions_table.php b/migrations/2015_01_24_080208_create_permissions_table.php index 9350f60..abe8cbb 100644 --- a/migrations/2015_01_24_080208_create_permissions_table.php +++ b/migrations/2015_01_24_080208_create_permissions_table.php @@ -12,7 +12,9 @@ class CreatePermissionsTable extends Migration */ public function up() { - Schema::create('permissions', function (Blueprint $table) { + $name = config('shinobi.tables.permissions'); + + Schema::create($name, function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name'); $table->string('slug')->unique(); @@ -28,6 +30,8 @@ public function up() */ public function down() { - Schema::drop('permissions'); + $name = config('shinobi.tables.permissions'); + + Schema::drop($name); } } diff --git a/migrations/2015_01_24_080433_create_permission_role_table.php b/migrations/2015_01_24_080433_create_permission_role_table.php index 99bce39..9a06be1 100644 --- a/migrations/2015_01_24_080433_create_permission_role_table.php +++ b/migrations/2015_01_24_080433_create_permission_role_table.php @@ -12,7 +12,9 @@ class CreatePermissionRoleTable extends Migration */ public function up() { - Schema::create('permission_role', function (Blueprint $table) { + $name = config('shinobi.tables.permission_role'); + + Schema::create($name, function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('permission_id')->index(); $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); @@ -29,6 +31,8 @@ public function up() */ public function down() { - Schema::drop('permission_role'); + $name = config('shinobi.tables.permission_role'); + + Schema::drop($name); } } diff --git a/migrations/2015_12_04_003040_add_special_role_column.php b/migrations/2015_12_04_003040_add_special_role_column.php index 2d6ff27..1c4c872 100644 --- a/migrations/2015_12_04_003040_add_special_role_column.php +++ b/migrations/2015_12_04_003040_add_special_role_column.php @@ -11,7 +11,9 @@ class AddSpecialRoleColumn extends Migration */ public function up() { - Schema::table('roles', function ($table) { + $name = config('shinobi.tables.roles'); + + Schema::table($name, function ($table) { $table->enum('special', ['all-access', 'no-access'])->nullable(); }); } @@ -23,7 +25,9 @@ public function up() */ public function down() { - Schema::table('roles', function ($table) { + $name = config('shinobi.tables.roles'); + + Schema::table($name, function ($table) { $table->dropColumn('special'); }); } diff --git a/migrations/2017_10_17_170735_create_permission_user_table.php b/migrations/2017_10_17_170735_create_permission_user_table.php index 0cc8986..bfefc5d 100644 --- a/migrations/2017_10_17_170735_create_permission_user_table.php +++ b/migrations/2017_10_17_170735_create_permission_user_table.php @@ -8,7 +8,9 @@ class CreatePermissionUserTable extends Migration { public function up() { - Schema::create('permission_user', function (Blueprint $table) { + $name = config('shinobi.tables.permission_user'); + + Schema::create($name, function (Blueprint $table) { $table->bigIncrements('id'); $table->unsignedBigInteger('permission_id')->index(); $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade'); @@ -25,7 +27,9 @@ public function up() */ public function down() { - Schema::drop('permission_user'); + $name = config('shinobi.tables.permission_user'); + + Schema::drop($name); } } diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..7f58de9 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,32 @@ + + + + + tests + + + + + src/ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Concerns/HasPermissions.php b/src/Concerns/HasPermissions.php index c39c5e3..1847952 100644 --- a/src/Concerns/HasPermissions.php +++ b/src/Concerns/HasPermissions.php @@ -3,6 +3,7 @@ namespace Caffeinated\Shinobi\Concerns; use Caffeinated\Shinobi\Facades\Shinobi; +use Caffeinated\Shinobi\Contracts\Permission; use Illuminate\Database\Eloquent\Relations\BelongsToMany; trait HasPermissions @@ -22,21 +23,36 @@ public function permissions(): BelongsToMany * by Shinobi - checking for special flags, role permissions, and * individual user permissions; in that order. * - * @param Permission $permission + * @param Permission|String $permission * @return boolean */ public function hasPermissionTo($permission): bool { // Check role flags - if ($this->hasPermissionFlags()) { - return $this->hasPermissionThroughFlag(); + if ((method_exists($this, 'hasPermissionRoleFlags') and $this->hasPermissionRoleFlags())) { + return $this->hasPermissionThroughRoleFlag(); } + if ((method_exists($this, 'hasPermissionFlags') and $this->hasPermissionFlags())) { + return $this->hasPermissionThroughFlag(); + } + + // Fetch permission if we pass through a string + if (is_string($permission)) { + try { + $model = $this->getPermissionModel(); + + $permission = $model->where('slug', $permission)->firstOrFail(); + } catch (\Exception $e) { + // + } + } + // Check role permissions - if ($this->hasPermissionThroughRole($permission)) { - return true; + if (method_exists($this, 'hasPermissionThroughRole') and $this->hasPermissionThroughRole($permission)) { + return $this->hasPermissionThroughRole($permission); } - + // Check user permission if ($this->hasPermission($permission)) { return true; @@ -45,8 +61,14 @@ public function hasPermissionTo($permission): bool return false; } + /** + * Give the specified permissions to the model. + * + * @param array $permissions + * @return self + */ public function givePermissionTo(...$permissions): self - { + { $permissions = array_flatten($permissions); $permissions = $this->getPermissions($permissions); @@ -59,6 +81,12 @@ public function givePermissionTo(...$permissions): self return $this; } + /** + * Revoke the specified permissions from the model. + * + * @param array $permissions + * @return self + */ public function revokePermissionTo(...$permissions): self { $permissions = array_flatten($permissions); @@ -69,6 +97,12 @@ public function revokePermissionTo(...$permissions): self return $this; } + /** + * Sync the specified permissions against the model. + * + * @param array $permissions + * @return self + */ public function syncPermissions(...$permissions): self { $permissions = array_flatten($permissions); @@ -80,14 +114,24 @@ public function syncPermissions(...$permissions): self } /** - * Get specified permissions. + * Get the specified permissions. * * @param array $permissions * @return Permission */ protected function getPermissions(array $permissions) { - return Shinobi::permission()->whereIn('slug', $permissions)->get(); + return array_map(function($permission) { + $model = $this->getPermissionModel(); + + if ($permission instanceof $model) { + return $permission->id; + } + + $permission = $model->where('slug', $permission)->first(); + + return $permission->id; + }, $permissions); } /** @@ -98,6 +142,22 @@ protected function getPermissions(array $permissions) */ protected function hasPermission($permission): bool { - return (bool) $this->permissions->where('slug', $permission->slug)->count(); + $model = $this->getPermissionModel(); + + if ($permission instanceof $model) { + $permission = $permission->slug; + } + + return (bool) $this->permissions->where('slug', $permission)->count(); + } + + /** + * Get the model instance responsible for permissions. + * + * @return \Caffeinated\Shinobi\Contracts\Permission + */ + protected function getPermissionModel(): Permission + { + return app()->make(config('shinobi.models.permission')); } } \ No newline at end of file diff --git a/src/Concerns/HasRoles.php b/src/Concerns/HasRoles.php index ab09f85..7a32111 100644 --- a/src/Concerns/HasRoles.php +++ b/src/Concerns/HasRoles.php @@ -2,7 +2,7 @@ namespace Caffeinated\Shinobi\Concerns; -use Caffeinated\Shinobi\Facades\Shinobi; +use Caffeinated\Shinobi\Contracts\Role; use Illuminate\Database\Eloquent\Relations\BelongsToMany; trait HasRoles @@ -30,6 +30,11 @@ public function hasRole($role): bool return (bool) $this->roles->where('slug', $slug)->count(); } + public function hasRoles(): bool + { + return (bool) $this->roles->count(); + } + /** * Assign the specified roles to the model. * @@ -90,6 +95,38 @@ public function syncRoles(...$roles): self */ protected function getRoles(array $roles) { - return Shinobi::role()->whereIn('slug', $roles)->get(); + return array_map(function($role) { + $model = $this->getRoleModel(); + + if ($role instanceof $model) { + return $role->id; + } + + $role = $model->where('slug', $role)->first(); + + return $role->id; + }, $roles); + } + + public function hasPermissionRoleFlags() + { + if ($this->hasRoles()) { + return ($this->roles + ->filter(function($role) { + return ! is_null($role->special); + })->count()) >= 1; + } + + return false; + } + + /** + * Get the model instance responsible for permissions. + * + * @return \Caffeinated\Shinobi\Contracts\Role + */ + protected function getRoleModel(): Role + { + return app()->make(config('shinobi.models.role')); } } \ No newline at end of file diff --git a/src/Concerns/HasRolesAndPermissions.php b/src/Concerns/HasRolesAndPermissions.php index 5c7d81b..a4227fa 100644 --- a/src/Concerns/HasRolesAndPermissions.php +++ b/src/Concerns/HasRolesAndPermissions.php @@ -15,29 +15,28 @@ trait HasRolesAndPermissions */ protected function hasPermissionThroughRole($permission): bool { - foreach ($permission->roles as $role) { - if ($this->roles->contains($role)) { - return true; + if ($this->hasRoles()) { + foreach ($this->roles as $role) { + if ($this->roles->contains($role)) { + return true; + } } } return false; } - protected function hasPermissionFlags(): bool + protected function hasPermissionThroughRoleFlag(): bool { - return (bool) (auth()->user()->roles->filter(function($role) { - return ! is_null($role->special); - })->count()); - } + if ($this->hasRoles()) { + return ! ($this->roles + ->filter(function($role) { + return ! is_null($role->special); + }) + ->pluck('special') + ->contains('no-access')); + } - protected function hasPermissionThroughFlag(): bool - { - return ! (auth()->user()->roles - ->filter(function($role) { - return ! is_null($role->special); - }) - ->pluck('special') - ->contains('no-access')); + return false; } } \ No newline at end of file diff --git a/src/Contracts/Role.php b/src/Contracts/Role.php index a617423..31f7cad 100644 --- a/src/Contracts/Role.php +++ b/src/Contracts/Role.php @@ -12,4 +12,7 @@ interface Role * @return Model */ public function users(): BelongsToMany; + + public function hasPermissionFlags(): bool; + public function hasPermissionThroughFlag(): bool; } \ No newline at end of file diff --git a/src/Models/Permission.php b/src/Models/Permission.php index ac8c694..d623d74 100644 --- a/src/Models/Permission.php +++ b/src/Models/Permission.php @@ -16,11 +16,17 @@ class Permission extends Model implements PermissionContract protected $fillable = ['name', 'slug', 'description']; /** - * The database table used by the model. - * - * @var string + * Create a new Permission instance. + * + * @param array $attributes + * @return void */ - protected $table = 'permissions'; + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $this->setTable(config('shinobi.tables.permissions')); + } /** * Permissions can belong to many roles. diff --git a/src/Models/Role.php b/src/Models/Role.php index ca50ee7..1643afc 100644 --- a/src/Models/Role.php +++ b/src/Models/Role.php @@ -19,11 +19,17 @@ class Role extends Model implements RoleContract protected $fillable = ['name', 'slug', 'description', 'special']; /** - * The database table used by the model. - * - * @var string + * Create a new Role instance. + * + * @param array $attributes + * @return void */ - protected $table = 'roles'; + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $this->setTable(config('shinobi.tables.roles')); + } /** * Roles can belong to many users. @@ -34,4 +40,29 @@ public function users(): BelongsToMany { return $this->belongsToMany(config('auth.model') ?: config('auth.providers.users.model'))->withTimestamps(); } + + /** + * Determine if role has permission flags. + * + * @return bool + */ + public function hasPermissionFlags(): bool + { + return ! is_null($this->special); + } + + /** + * Determine if the requested permission is permitted or denied + * through a special role flag. + * + * @return bool + */ + public function hasPermissionThroughFlag(): bool + { + if ($this->hasPermissionFlags()) { + return ! ($this->special === 'no-access'); + } + + return true; + } } diff --git a/src/ShinobiServiceProvider.php b/src/ShinobiServiceProvider.php index 8114f3f..d7bf3f7 100644 --- a/src/ShinobiServiceProvider.php +++ b/src/ShinobiServiceProvider.php @@ -11,6 +11,7 @@ use Illuminate\Support\ServiceProvider; use Caffeinated\Shinobi\Facades\Shinobi; use Caffeinated\Shinobi\Models\Permission; +use Illuminate\Contracts\Auth\Access\Authorizable; class ShinobiServiceProvider extends ServiceProvider { @@ -54,11 +55,9 @@ public function register() */ protected function registerGates() { - Gate::before(function($user, $permission) { + Gate::before(function(Authorizable $user, String $permission) { try { if (method_exists($user, 'hasPermissionTo')) { - $permission = Shinobi::permission()->where('slug', $permission)->firstOrFail(); - return $user->hasPermissionTo($permission) ?: null; } } catch (Exception $e) { @@ -74,12 +73,8 @@ protected function registerGates() */ protected function registerBladeDirectives() { - Blade::directive('role', function ($expression) { - return ""; - }); - - Blade::directive('endrole', function ($expression) { - return ''; + Blade::if('role', function($role) { + return auth()->user() and auth()->user()->hasRole($role); }); } diff --git a/tests/BladeTest.php b/tests/BladeTest.php new file mode 100644 index 0000000..20c34df --- /dev/null +++ b/tests/BladeTest.php @@ -0,0 +1,130 @@ +create(); + $permission = factory(Permission::class)->create([ + 'name' => 'Test Permission', + 'slug' => 'test.permission', + ]); + + $user->givePermissionTo($permission); + + $this->actingAs($user); + + $result = $this->renderView('can_directive'); + + $this->assertEquals($result, 'has permission'); + } + + /** @test */ + public function the_can_directive_evaluates_false_when_permissions_are_not_met() + { + $user = factory(User::class)->create(); + + $this->actingAs($user); + + $result = $this->renderView('can_directive'); + + $this->assertEquals($result, 'does not have permission'); + } + + /** @test */ + public function the_cannot_directive_evaluates_true_when_permissions_are_not_met() + { + $user = factory(User::class)->create(); + + $this->actingAs($user); + + $result = $this->renderView('cannot_directive'); + + $this->assertEquals($result, 'does not have permission'); + } + + /** @test */ + public function the_cannot_directive_evaluates_false_when_permissions_are_met() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create([ + 'name' => 'Test Permission', + 'slug' => 'test.permission', + ]); + + $user->givePermissionTo($permission); + + $this->actingAs($user); + + $result = $this->renderView('cannot_directive'); + + $this->assertEquals($result, 'has permission'); + } + + /** @test */ + public function the_role_directive_evaluates_true_when_user_has_given_role() + { + $user = factory(User::class)->create(); + $role = factory(Role::class)->create([ + 'name' => 'Admin', + 'slug' => 'admin', + ]); + + $user->assignRoles($role); + + $this->actingAs($user); + + $result = $this->renderView('role_directive'); + + $this->assertEquals($result, 'has admin role'); + } + + /** @test */ + public function the_role_directive_evaluates_true_if_previous_evaluations_didnt_pass_when_using_else() + { + $user = factory(User::class)->create(); + $role = factory(Role::class)->create([ + 'name' => 'Moderator', + 'slug' => 'moderator', + ]); + + $user->assignRoles($role); + + $this->actingAs($user); + + $result = $this->renderView('role_directive'); + + $this->assertEquals($result, 'has moderator role'); + } + + /** @test */ + public function the_role_directive_evaluates_false_when_user_does_not_have_given_roles() + { + $user = factory(User::class)->create(); + + $this->actingAs($user); + + $result = $this->renderView('role_directive'); + + $this->assertEquals($result, 'does not have admin or moderator roles'); + } + + /** @test */ + public function guests_do_not_have_roles() + { + $result = $this->renderView('role_directive'); + + $this->assertEquals($result, 'does not have admin or moderator roles'); + } +} \ No newline at end of file diff --git a/tests/GrumpyTest.php b/tests/GrumpyTest.php new file mode 100644 index 0000000..f0a9317 --- /dev/null +++ b/tests/GrumpyTest.php @@ -0,0 +1,28 @@ +assertTrue(true); + } + + /** @test */ + public function it_has_necessary_tables() + { + $this->assertTrue(Schema::hasTable('roles')); + $this->assertTrue(Schema::hasTable('permissions')); + $this->assertTrue(Schema::hasTable('role_user')); + $this->assertTrue(Schema::hasTable('permission_role')); + $this->assertTrue(Schema::hasTable('permission_user')); + } +} \ No newline at end of file diff --git a/tests/RoleTest.php b/tests/RoleTest.php new file mode 100644 index 0000000..0ce82be --- /dev/null +++ b/tests/RoleTest.php @@ -0,0 +1,171 @@ +create(); + $permission = factory(Permission::class)->create(); + + $this->assertCount(0, $role->permissions); + + $role->givePermissionTo($permission); + + $this->assertCount(1, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_a_permission_by_slug() + { + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertCount(0, $role->permissions); + + $role->givePermissionTo($permission->slug); + + $this->assertCount(1, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_multiple_permissions() + { + $role = factory(Role::class)->create(); + $permissions = factory(Permission::class, 5)->create(); + + $this->assertCount(0, $role->permissions); + + $role->givePermissionTo($permissions); + + $this->assertCount(5, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_multiple_permissions_by_slug() + { + $role = factory(Role::class)->create(); + $permissions = factory(Permission::class, 5)->create()->pluck('slug'); + + $this->assertCount(0, $role->permissions); + + $role->givePermissionTo($permissions); + + $this->assertCount(5, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_a_permission() + { + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $role->givePermissionTo($permission); + + $this->assertCount(1, $role->permissions); + + $role->revokePermissionTo($permission); + + $this->assertCount(0, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_a_permission_by_slug() + { + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $role->givePermissionTo($permission->slug); + + $this->assertCount(1, $role->permissions); + + $role->revokePermissionTo($permission->slug); + + $this->assertCount(0, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_multiple_permissions() + { + $role = factory(Role::class)->create(); + $permissions = factory(Permission::class, 5)->create(); + + $role->givePermissionTo($permissions); + + $this->assertCount(5, $role->permissions); + + $role->revokePermissionTo($permissions); + + $this->assertCount(0, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_multiple_permissions_by_slugs() + { + $role = factory(Role::class)->create(); + $permissions = factory(Permission::class, 5)->create()->pluck('slug'); + + $role->givePermissionTo($permissions); + + $this->assertCount(5, $role->permissions); + + $role->revokePermissionTo($permissions); + + $this->assertCount(0, $role->fresh()->permissions); + } + + /** @test */ + public function it_can_assert_has_a_given_permission() + { + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertFalse($role->hasPermissionTo($permission->slug)); + + $role->givePermissionTo($permission); + + $this->assertTrue($role->fresh()->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_can_assert_does_not_have_a_given_permission() + { + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertFalse($role->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_can_assert_with_no_access_flag_never_has_permission() + { + $permission = factory(Permission::class)->create(); + $role = factory(Role::class)->create([ + 'special' => 'no-access', + ]); + + $role->givePermissionTo($permission); + + $this->assertFalse($role->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_can_assert_with_all_access_flag_always_has_permission() + { + $permission = factory(Permission::class)->create(); + $role = factory(Role::class)->create([ + 'special' => 'all-access', + ]); + + $this->assertTrue($role->hasPermissionTo($permission->slug)); + } +} \ No newline at end of file diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..0f7f313 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,81 @@ +withFactories(__DIR__.'/factories'); + + $this->loadLaravelMigrations(['--database' => 'testing']); + $this->loadMigrationsFrom([ + '--database' => 'testing', + '--path' => realpath(__DIR__.'/../migrations'), + ]); + + View::addLocation(__DIR__.'/resources/views'); + } + + /** + * Define the environment setup. + * + * @param \Illuminate\Foundation\Application $app + * @return void + */ + protected function getEnvironmentSetUp($app) + { + $app['config']->set('database.default', 'testing'); + } + + /** + * Get package providers. + * + * @param \Illuminate\Foundation\Application $app + * @return array + */ + protected function getPackageProviders($app) + { + return [ + ShinobiServiceProvider::class + ]; + } + + /** + * Get package aliases. + * + * @param \Illuminate\Foundation\Application $app + * @return array + */ + protected function getPackageAliases($app) + { + return [ + 'Shinobi' => Shinobi::class, + ]; + } + + /** + * Render a blade view file to a string. + * + * @param string $path + * @return string + */ + protected function renderView($path) + { + $html = view($path)->render(); + + return trim($html); + } +} \ No newline at end of file diff --git a/tests/User.php b/tests/User.php new file mode 100644 index 0000000..538983c --- /dev/null +++ b/tests/User.php @@ -0,0 +1,15 @@ +create(); + $permission = factory(Permission::class)->create(); + + $this->assertCount(0, $user->permissions); + + $user->givePermissionTo($permission); + + $this->assertCount(1, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_a_permission_by_slug() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertCount(0, $user->permissions); + + $user->givePermissionTo($permission->slug); + + $this->assertCount(1, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_multiple_permissions() + { + $user = factory(User::class)->create(); + $permissions = factory(Permission::class, 5)->create(); + + $this->assertCount(0, $user->permissions); + + $user->givePermissionTo($permissions); + + $this->assertCount(5, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_given_multiple_permissions_by_slug() + { + $user = factory(User::class)->create(); + $permissions = factory(Permission::class, 5)->create()->pluck('slug'); + + $this->assertCount(0, $user->permissions); + + $user->givePermissionTo($permissions); + + $this->assertCount(5, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_a_permission() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create(); + + $user->givePermissionTo($permission); + + $this->assertCount(1, $user->permissions); + + $user->revokePermissionTo($permission); + + $this->assertCount(0, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_a_permission_by_slug() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create(); + + $user->givePermissionTo($permission->slug); + + $this->assertCount(1, $user->permissions); + + $user->revokePermissionTo($permission->slug); + + $this->assertCount(0, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_multiple_permissions() + { + $user = factory(User::class)->create(); + $permissions = factory(Permission::class, 5)->create(); + + $user->givePermissionTo($permissions); + + $this->assertCount(5, $user->permissions); + + $user->revokePermissionTo($permissions); + + $this->assertCount(0, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_be_revoked_multiple_permissions_by_slugs() + { + $user = factory(User::class)->create(); + $permissions = factory(Permission::class, 5)->create()->pluck('slug'); + + $user->givePermissionTo($permissions); + + $this->assertCount(5, $user->permissions); + + $user->revokePermissionTo($permissions); + + $this->assertCount(0, $user->fresh()->permissions); + } + + /** @test */ + public function it_can_assert_has_a_given_permission() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertFalse($user->hasPermissionTo($permission->slug)); + + $user->givePermissionTo($permission); + + $this->assertTrue($user->fresh()->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_can_assert_does_not_have_a_given_permission() + { + $user = factory(User::class)->create(); + $permission = factory(Permission::class)->create(); + + $this->assertFalse($user->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_can_be_assigned_a_role() + { + $user = factory(User::class)->create(); + $role = factory(Role::class)->create(); + + $this->assertCount(0, $user->roles); + + $user->assignRoles($role); + + $this->assertCount(1, $user->fresh()->roles); + } + + /** @test */ + public function it_can_be_assigned_a_role_by_slug() + { + $user = factory(User::class)->create(); + $role = factory(Role::class)->create(); + + $this->assertCount(0, $user->roles); + + $user->assignRoles($role->slug); + + $this->assertCount(1, $user->fresh()->roles); + } + + /** @test */ + public function it_can_be_assigned_multiple_roles() + { + $user = factory(User::class)->create(); + $roles = factory(Role::class, 3)->create(); + + $this->assertCount(0, $user->roles); + + $user->assignRoles($roles); + + $this->assertCount(3, $user->fresh()->roles); + } + + /** @test */ + public function it_can_be_assigned_multiple_roles_by_slugs() + { + $user = factory(User::class)->create(); + $roles = factory(Role::class, 3)->create()->pluck('slug'); + + $this->assertCount(0, $user->roles); + + $user->assignRoles($roles); + + $this->assertCount(3, $user->fresh()->roles); + } + + /** @test */ + public function it_has_a_given_permission_through_role() + { + $this->withoutExceptionHandling(); + + $user = factory(User::class)->create(); + $role = factory(Role::class)->create(); + $permission = factory(Permission::class)->create(); + + $role->givePermissionTo($permission); + + $this->assertFalse($user->hasPermissionTo($permission->slug)); + + $user->assignRoles($role); + + // dd($permission->slug); + + $this->assertTrue($user->fresh()->hasPermissionTo($permission->slug)); + } + + /** @test */ + public function it_has_no_permissions_when_assigned_a_role_with_a_no_access_flag() + { + $user = factory(User::class)->create(); + $role = factory(Role::class)->create(['special' => 'no-access']); + $permission = factory(Permission::class)->create(); + + $user->givePermissionTo($permission); + + $this->assertTrue($user->fresh()->hasPermissionTo($permission->slug)); + + $user->assignRoles($role); + + $this->assertFalse($user->fresh()->hasPermissionTo($permission->slug)); + } +} \ No newline at end of file diff --git a/tests/factories/PermissionFactory.php b/tests/factories/PermissionFactory.php new file mode 100644 index 0000000..b622d11 --- /dev/null +++ b/tests/factories/PermissionFactory.php @@ -0,0 +1,13 @@ +define(Permission::class, function(Faker\Generator $faker) { + $name = $faker->unique()->sentence(2); + + return [ + 'name' => $name, + 'slug' => str_slug($name, '.'), + 'description' => $faker->sentence, + ]; +}); \ No newline at end of file diff --git a/tests/factories/RoleFactory.php b/tests/factories/RoleFactory.php new file mode 100644 index 0000000..f599285 --- /dev/null +++ b/tests/factories/RoleFactory.php @@ -0,0 +1,14 @@ +define(Role::class, function(Faker\Generator $faker) { + $name = $faker->unique()->jobTitle; + + return [ + 'name' => $name, + 'slug' => str_slug($name), + 'description' => $faker->sentence, + 'special' => null, + ]; +}); \ No newline at end of file diff --git a/tests/factories/UserFactory.php b/tests/factories/UserFactory.php new file mode 100644 index 0000000..cc49aab --- /dev/null +++ b/tests/factories/UserFactory.php @@ -0,0 +1,11 @@ +define(User::class, function(Faker\Generator $faker) { + return [ + 'name' => $faker->name, + 'email' => $faker->unique()->safeEmail, + 'password' => bcrypt($faker->password), + ]; +}); \ No newline at end of file diff --git a/tests/resources/views/can_directive.blade.php b/tests/resources/views/can_directive.blade.php new file mode 100644 index 0000000..282a775 --- /dev/null +++ b/tests/resources/views/can_directive.blade.php @@ -0,0 +1,5 @@ +@can('test.permission') +has permission +@else +does not have permission +@endcan \ No newline at end of file diff --git a/tests/resources/views/cannot_directive.blade.php b/tests/resources/views/cannot_directive.blade.php new file mode 100644 index 0000000..52b338a --- /dev/null +++ b/tests/resources/views/cannot_directive.blade.php @@ -0,0 +1,5 @@ +@cannot('test.permission') +does not have permission +@else +has permission +@endcannot \ No newline at end of file diff --git a/tests/resources/views/role_directive.blade.php b/tests/resources/views/role_directive.blade.php new file mode 100644 index 0000000..104dbea --- /dev/null +++ b/tests/resources/views/role_directive.blade.php @@ -0,0 +1,7 @@ +@role('admin') +has admin role +@elserole('moderator') +has moderator role +@else +does not have admin or moderator roles +@endrole \ No newline at end of file