diff --git a/.gitattributes b/.gitattributes index 2b7b41d..01f14ae 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,7 +7,6 @@ .gitattributes export-ignore .gitignore export-ignore .scrutinizer.yml export-ignore -.travis.yml export-ignore phpcs.xml.dist export-ignore phpunit.xml.dist export-ignore CONTRIBUTING.md export-ignore diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..10b997e --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,46 @@ +name: run-tests + +on: [push] + +jobs: + tests: + runs-on: ubuntu-latest + + strategy: + fail-fast: true + matrix: + php: [7.2, 7.3, 7.4] + laravel: [6.*] + dependency-version: [prefer-lowest, prefer-stable] + + name: PHP ${{ matrix.php }} - ${{ matrix.dependency-version }} + + steps: + - name: Checkout code + uses: actions/checkout@v1 + + - name: Cache dependencies + uses: actions/cache@v1 + with: + path: ~/.composer/cache/files + key: dependencies-laravel-${{ matrix.laravel }}-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@v1 + with: + php-version: ${{ matrix.php }} + extensions: curl, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, iconv + coverage: xdebug + + - name: Install dependencies + run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-suggest + + - name: Execute tests + run: | + mkdir -p build/logs + vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover + + - name: Scrutinizer CI + run: | + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover coverage.clover diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 2880858..a34f2cb 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -23,7 +23,7 @@ checks: tools: external_code_coverage: timeout: 600 - runs: 2 + runs: 6 php_code_sniffer: enabled: true config: diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d407e33..0000000 --- a/.travis.yml +++ /dev/null @@ -1,25 +0,0 @@ -language: php - -sudo: false - -php: - - 7.2 - - 7.3 - - nightly - -matrix: - allow_failures: - - php: nightly - -before_script: - - travis_retry composer self-update - - travis_retry composer install --prefer-source --no-interaction - -script: - - composer validate - - mkdir -p build/logs - - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover - -after_script: - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi - - if [ "$TRAVIS_PHP_VERSION" != "nightly" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi diff --git a/README.md b/README.md index 873ba0c..3ecb415 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Laravel Policies [![Packagist License][badge_license]](LICENSE.md) [![For Laravel][badge_laravel]][link-github-repo] -[![Travis Status][badge_build]][link-travis] +[![Github Workflow Status][badge_build]][link-github-status] [![Coverage Status][badge_coverage]][link-scrutinizer] [![Scrutinizer Code Quality][badge_quality]][link-scrutinizer] [![SensioLabs Insight][badge_insight]][link-insight] @@ -21,7 +21,7 @@ This package allows to create & manage policies/abilities in a modular way. * Well tested with maximum code quality. * Laravel `6.x` is supported. * Made with :heart: & :coffee:. - + ## Table of contents 1. [Installation and Setup](_docs/1-Installation-and-Setup.md) @@ -47,7 +47,7 @@ If you discover any security related issues, please email arcanedev.maroc@gmail. [badge_laravel]: https://img.shields.io/badge/Laravel-6.x-orange.svg?style=flat-square [badge_license]: https://img.shields.io/packagist/l/arcanedev/laravel-policies.svg?style=flat-square -[badge_build]: https://img.shields.io/travis/ARCANEDEV/LaravelPolicies.svg?style=flat-square +[badge_build]: https://img.shields.io/github/workflow/status/ARCANEDEV/LaravelPolicies/run-tests?style=flat-square [badge_coverage]: https://img.shields.io/scrutinizer/coverage/g/ARCANEDEV/LaravelPolicies.svg?style=flat-square [badge_quality]: https://img.shields.io/scrutinizer/g/ARCANEDEV/LaravelPolicies.svg?style=flat-square [badge_insight]: https://img.shields.io/sensiolabs/i/ee623172-802f-4775-b48b-122df1571b1b.svg?style=flat-square @@ -58,9 +58,9 @@ If you discover any security related issues, please email arcanedev.maroc@gmail. [link-author]: https://github.com/arcanedev-maroc [link-github-repo]: https://github.com/ARCANEDEV/LaravelPolicies +[link-github-status]: https://github.com/ARCANEDEV/LaravelPolicies/actions [link-github-issues]: https://github.com/ARCANEDEV/LaravelPolicies/issues [link-contributors]: https://github.com/ARCANEDEV/LaravelPolicies/graphs/contributors [link-packagist]: https://packagist.org/packages/arcanedev/laravel-policies -[link-travis]: https://travis-ci.org/ARCANEDEV/LaravelPolicies [link-scrutinizer]: https://scrutinizer-ci.com/g/ARCANEDEV/LaravelPolicies/?branch=master [link-insight]: https://insight.sensiolabs.com/projects/ee623172-802f-4775-b48b-122df1571b1b diff --git a/composer.json b/composer.json index d9a1709..0487bf2 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "require": { "php": ">=7.2.0", "ext-json": "*", - "arcanedev/support": "~5.0" + "arcanedev/support": "~5.1" }, "require-dev": { "orchestra/testbench": "~4.0", diff --git a/src/Ability.php b/src/Ability.php index aeaf3a8..6a23599 100644 --- a/src/Ability.php +++ b/src/Ability.php @@ -4,10 +4,9 @@ namespace Arcanedev\LaravelPolicies; -use Illuminate\Contracts\Support\{Arrayable, Jsonable}; +use Arcanedev\LaravelPolicies\Contracts\Ability as AbilityContract; use Closure; use Illuminate\Support\Arr; -use JsonSerializable; /** * Class Ability @@ -15,7 +14,7 @@ * @package Arcanedev\LaravelPolicies * @author ARCANEDEV */ -class Ability implements Arrayable, JsonSerializable, Jsonable +class Ability implements AbilityContract { /* ----------------------------------------------------------------- | Properties @@ -93,7 +92,7 @@ public function setKey(string $key): self /** * Get the ability's method. * - * @return string|Closure + * @return \Closure|string */ public function method() { @@ -115,7 +114,7 @@ public function callback(Closure $callback): self /** * Set the ability's method. * - * @param string|\Closure $method + * @param \Closure|string $method * * @return self */ diff --git a/src/Contracts/Ability.php b/src/Contracts/Ability.php new file mode 100644 index 0000000..4672309 --- /dev/null +++ b/src/Contracts/Ability.php @@ -0,0 +1,113 @@ + + */ +interface Ability extends Arrayable, JsonSerializable, Jsonable +{ + /* ----------------------------------------------------------------- + | Getters & Setters + | ----------------------------------------------------------------- + */ + + /** + * Get the ability's key. + * + * @return string + */ + public function key(): string; + + /** + * Set the ability's key. + * + * @param string $key + * + * @return $this + */ + public function setKey(string $key); + + /** + * Get the ability's method. + * + * @return \Closure|string + */ + public function method(); + + /** + * Set the callback as method. + * + * @param \Closure $callback + * + * @return $this + */ + public function callback(Closure $callback); + + /** + * Set the ability's method. + * + * @param \Closure|string $method + * + * @return $this + */ + public function setMethod($method); + + /** + * Get the ability's meta. + * + * @return array + */ + public function metas(): array; + + /** + * Set the ability's meta. + * + * @param array $metas + * @param bool $keepMetas + * + * @return $this + */ + public function setMetas(array $metas, bool $keepMetas = true); + + /** + * Get a meta. + * + * @param string $key + * @param mixed|null $default + * + * @return mixed + */ + public function meta(string $key, $default = null); + + /** + * Set a meta. + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function setMeta(string $key, $value); + + /* ----------------------------------------------------------------- + | Check Methods + | ----------------------------------------------------------------- + */ + + /** + * Check if the ability is a callback method. + * + * @return bool + */ + public function isClosure(): bool; +} diff --git a/src/PoliciesServiceProvider.php b/src/PoliciesServiceProvider.php index 573bc55..22a07d8 100644 --- a/src/PoliciesServiceProvider.php +++ b/src/PoliciesServiceProvider.php @@ -4,7 +4,7 @@ namespace Arcanedev\LaravelPolicies; -use Arcanedev\Support\PackageServiceProvider; +use Arcanedev\Support\Providers\PackageServiceProvider; use Illuminate\Contracts\Support\DeferrableProvider; /** diff --git a/src/Policy.php b/src/Policy.php index 5fc7b89..95b0588 100644 --- a/src/Policy.php +++ b/src/Policy.php @@ -4,6 +4,7 @@ namespace Arcanedev\LaravelPolicies; +use Arcanedev\LaravelPolicies\Contracts\Ability as AbilityContract; use Arcanedev\LaravelPolicies\Contracts\Policy as PolicyContract; use Illuminate\Support\Str; @@ -94,9 +95,9 @@ public static function ability($keys) * @param string $key * @param string|null $method * - * @return \Arcanedev\LaravelPolicies\Ability + * @return \Arcanedev\LaravelPolicies\Contracts\Ability */ - protected function makeAbility(string $key, $method = null): Ability + protected function makeAbility(string $key, $method = null): AbilityContract { return Ability::make( static::prefixedKey($key), diff --git a/src/PolicyManager.php b/src/PolicyManager.php index 291cbcd..797ac93 100644 --- a/src/PolicyManager.php +++ b/src/PolicyManager.php @@ -4,13 +4,12 @@ namespace Arcanedev\LaravelPolicies; -use Arcanedev\LaravelPolicies\Contracts\{ - Policy as PolicyContract, - PolicyManager as PolicyManagerContract -}; +use Arcanedev\LaravelPolicies\Contracts\Ability as AbilityContract; +use Arcanedev\LaravelPolicies\Contracts\Policy as PolicyContract; +use Arcanedev\LaravelPolicies\Contracts\PolicyManager as PolicyManagerContract; +use Illuminate\Contracts\Auth\Access\Gate; use Illuminate\Contracts\Foundation\Application; use Illuminate\Support\Collection; -use Illuminate\Contracts\Auth\Access\Gate; /** * Class PolicyManager @@ -147,11 +146,11 @@ public function register(PolicyContract $policy): PolicyManagerContract /** * Register the ability object. * - * @param \Arcanedev\LaravelPolicies\Ability $ability + * @param \Arcanedev\LaravelPolicies\Contracts\Ability $ability * * @return $this */ - protected function registerAbility(Ability $ability) + protected function registerAbility(AbilityContract $ability) { $this->abilities->put($ability->key(), $ability); $this->gate()->define($ability->key(), $ability->method()); diff --git a/tests/AbilityTest.php b/tests/AbilityTest.php index 2b5dcae..ca14fd2 100644 --- a/tests/AbilityTest.php +++ b/tests/AbilityTest.php @@ -1,5 +1,7 @@ key()); static::assertSame('create', $ability->method()); } /** @test */ - public function it_can_make() + public function it_can_make(): void { $ability = Ability::make('posts.create', 'create'); @@ -37,7 +47,7 @@ public function it_can_make() } /** @test */ - public function it_can_create_with_closure_method() + public function it_can_create_with_closure_method(): void { $ability = Ability::make('posts.create', function (User $user) { return true; @@ -49,7 +59,7 @@ public function it_can_create_with_closure_method() } /** @test */ - public function it_can_set_and_get_metas() + public function it_can_set_and_get_metas(): void { $metas = [ 'name' => 'List posts', @@ -62,7 +72,7 @@ public function it_can_set_and_get_metas() } /** @test */ - public function it_can_set_and_get_single_meta() + public function it_can_set_and_get_single_meta(): void { $name = 'List posts'; $description = 'Ability to list all the posts'; @@ -76,7 +86,7 @@ public function it_can_set_and_get_single_meta() } /** @test */ - public function it_can_get_meta_with_default_value() + public function it_can_get_meta_with_default_value(): void { $ability = Ability::make('posts.list', 'index'); @@ -85,7 +95,7 @@ public function it_can_get_meta_with_default_value() } /** @test */ - public function it_can_set_and_get_nested_metas() + public function it_can_set_and_get_nested_metas(): void { $ability = Ability::make('posts.update', 'update')->setMeta('roles', [ 'administrator' => true, @@ -106,7 +116,7 @@ public function it_can_set_and_get_nested_metas() } /** @test */ - public function it_can_convert_toArray() + public function it_can_convert_toArray(): void { $metas = [ 'name' => 'List posts', @@ -126,7 +136,7 @@ public function it_can_convert_toArray() } /** @test */ - public function it_can_convert_to_json() + public function it_can_convert_to_json(): void { $metas = [ 'name' => 'List posts', diff --git a/tests/AuthorizationTest.php b/tests/AuthorizationTest.php index e591d7c..ccea189 100644 --- a/tests/AuthorizationTest.php +++ b/tests/AuthorizationTest.php @@ -1,9 +1,10 @@ abilities(); diff --git a/tests/Fixtures/Policies/Abilities/DedicatedAbility.php b/tests/Fixtures/Policies/Abilities/DedicatedAbility.php index 52eb11b..3c1fb92 100644 --- a/tests/Fixtures/Policies/Abilities/DedicatedAbility.php +++ b/tests/Fixtures/Policies/Abilities/DedicatedAbility.php @@ -1,5 +1,7 @@ manager->parsePolicies([ Fixtures\Policies\PrefixedPolicy::class, @@ -97,7 +99,7 @@ public function it_can_parse_multiple_policy_classes() } /** @test */ - public function it_can_register_policy_class() + public function it_can_register_policy_class(): void { static::assertCount(0, Gate::abilities()); @@ -113,7 +115,7 @@ public function it_can_register_policy_class() } /** @test */ - public function it_can_register_multiple_policy_classes() + public function it_can_register_multiple_policy_classes(): void { static::assertCount(0, Gate::abilities()); @@ -130,7 +132,7 @@ public function it_can_register_multiple_policy_classes() } /** @test */ - public function it_can_register_policy_instance() + public function it_can_register_policy_instance(): void { static::assertCount(0, Gate::abilities()); @@ -149,7 +151,7 @@ public function it_can_register_policy_instance() } /** @test */ - public function it_can_check_authorizations() + public function it_can_check_authorizations(): void { $this->manager->registerClass(Fixtures\Policies\PostsPolicy::class); $this->manager->registerClass(Fixtures\Policies\PrefixedPolicy::class); @@ -166,7 +168,7 @@ public function it_can_check_authorizations() } /** @test */ - public function it_can_inspect_authorization() + public function it_can_inspect_authorization(): void { $this->manager->registerClass(Fixtures\Policies\PrefixedPolicy::class); diff --git a/tests/PolicyTest.php b/tests/PolicyTest.php index 6e66b55..e2b2c1d 100644 --- a/tests/PolicyTest.php +++ b/tests/PolicyTest.php @@ -1,5 +1,7 @@ abilities(); @@ -54,7 +56,7 @@ public function it_can_get_abilities() } /** @test */ - public function it_can_get_single_ability_key() + public function it_can_get_single_ability_key(): void { $expectations = [ 'list-posts' => PostsPolicy::ability('list-posts'), @@ -67,7 +69,7 @@ public function it_can_get_single_ability_key() } /** @test */ - public function it_can_get_multiple_ability_keys() + public function it_can_get_multiple_ability_keys(): void { static::assertEquals( ['list-posts', 'create-posts'], diff --git a/tests/TestCase.php b/tests/TestCase.php index f98f5a4..5b77456 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,7 @@