diff --git a/.github/workflows/cs-tests.yml b/.github/workflows/cs-tests.yml new file mode 100644 index 0000000..3da9965 --- /dev/null +++ b/.github/workflows/cs-tests.yml @@ -0,0 +1,46 @@ +on: + - push + +name: Run phpcs checks + +jobs: + mutation: + name: PHP ${{ matrix.php }}-${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - "8.1" + - "8.2" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + tools: composer:v2, cs2pr + coverage: none + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + - name: Install dependencies with composer + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run phpcs checks + run: vendor/bin/phpcs diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..74550fc --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,46 @@ +on: + - push + +name: Run static analysis + +jobs: + mutation: + name: PHP ${{ matrix.php }}-${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - "8.1" + - "8.2" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + tools: composer:v2, cs2pr + coverage: none + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + - name: Install dependencies with composer + run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run static analysis + run: vendor/bin/psalm --no-cache --output-format=github --show-info=false --threads=4 diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml new file mode 100644 index 0000000..d2ab8e7 --- /dev/null +++ b/.github/workflows/unit-tests.yaml @@ -0,0 +1,47 @@ +on: + - push + +name: Run PHPUnit tests + +jobs: + mutation: + name: PHP ${{ matrix.php }}-${{ matrix.os }} + + runs-on: ${{ matrix.os }} + + strategy: + matrix: + os: + - ubuntu-latest + + php: + - "8.1" + - "8.2" + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php }}" + tools: composer:v2, cs2pr + coverage: none + + - name: Determine composer cache directory + run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV + + - name: Cache dependencies installed with composer + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_DIR }} + key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: | + php${{ matrix.php }}-composer- + + - name: Install dependencies with composer + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi + + - name: Run PHPUnit tests + run: vendor/bin/phpunit --colors=always diff --git a/.gitignore b/.gitignore index 6000c91..08f9dfa 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ crashlytics.properties crashlytics-build.properties fabric.properties # Created by .ignore support plugin (hsz.mobi) +.phpunit.result.cache +.phpcs-cache diff --git a/README.md b/README.md index 06f6bd5..baac88e 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,18 @@ Authorization base package defining interfaces for authorization services to be used with DotKernel applications. ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-authorization) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-authorization/3.2.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-authorization/3.4.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-authorization)](https://github.com/dotkernel/dot-authorization/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-authorization)](https://github.com/dotkernel/dot-authorization/network) [![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-authorization)](https://github.com/dotkernel/dot-authorization/stargazers) [![GitHub license](https://img.shields.io/github/license/dotkernel/dot-authorization)](https://github.com/dotkernel/dot-authorization/blob/3.0/LICENSE.md) +[![Build Static](https://github.com/dotkernel/dot-authorization/actions/workflows/static-analysis.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-authorization/actions/workflows/static-analysis.yml) + +[![SymfonyInsight](https://insight.symfony.com/projects/014df510-1cf7-4876-b1a8-303fbef2f364/big.svg)](https://insight.symfony.com/projects/014df510-1cf7-4876-b1a8-303fbef2f364) + + ## Installation Run the following command in you project directory diff --git a/composer.json b/composer.json index 542e2a4..3896f86 100644 --- a/composer.json +++ b/composer.json @@ -16,11 +16,12 @@ "laminas-dependency" ], "require": { - "php": "^7.4 || ~8.0.0 || ~8.1.0" + "php": "~8.1.0 || ~8.2.0" }, "require-dev": { - "phpunit/phpunit": "^9.1", - "squizlabs/php_codesniffer": "^3.5" + "laminas/laminas-coding-standard": "^2.5", + "phpunit/phpunit": "10.2", + "vimeo/psalm": "^5.13" }, "autoload": { "psr-4": { @@ -33,8 +34,20 @@ } }, "config": { + "sort-packages": true, "allow-plugins": { - "laminas/laminas-dependency-plugin": true + "dealerdirect/phpcodesniffer-composer-installer": true } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml", + "static-analysis": "psalm --shepherd --stats" } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..1efe663 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + src + test + + + + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..00092cd --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,10 @@ + + + + + ./test + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..df50202 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,15 @@ + + + + + + + + + diff --git a/src/AuthorizationInterface.php b/src/AuthorizationInterface.php index fd233e2..88cdba1 100644 --- a/src/AuthorizationInterface.php +++ b/src/AuthorizationInterface.php @@ -1,25 +1,10 @@ mockAuthorizationInterface = $this->createMock(AuthorizationInterface::class); + $this->mockAuthorizationInterface->method('isGranted')->willReturn(false); + } + + public function testCreate(): void + { + $this->assertInstanceOf(AuthorizationInterface::class, $this->mockAuthorizationInterface); + } + + public function testFunction(): void + { + $this->assertFalse($this->mockAuthorizationInterface->isGranted('no', ['admin'])); + } +} diff --git a/test/Exception/ExceptionInterfaceTest.php b/test/Exception/ExceptionInterfaceTest.php new file mode 100644 index 0000000..c5aa126 --- /dev/null +++ b/test/Exception/ExceptionInterfaceTest.php @@ -0,0 +1,28 @@ +exceptionInterfaceMock = $this->createMock(ExceptionInterface::class); + } + + public function testCreate(): void + { + $this->assertInstanceOf(ExceptionInterface::class, $this->exceptionInterfaceMock); + } +} diff --git a/test/Exception/ForbiddenExceptionTest.php b/test/Exception/ForbiddenExceptionTest.php new file mode 100644 index 0000000..2ba3b38 --- /dev/null +++ b/test/Exception/ForbiddenExceptionTest.php @@ -0,0 +1,30 @@ +forbiddenExceptionMock = $this->createMock(ForbiddenException::class); + } + + public function testCreate(): void + { + $this->assertInstanceOf(ForbiddenException::class, $this->forbiddenExceptionMock); + $this->assertInstanceOf(ExceptionInterface::class, $this->forbiddenExceptionMock); + } +} diff --git a/test/Exception/RuntimeExceptionTest.php b/test/Exception/RuntimeExceptionTest.php new file mode 100644 index 0000000..067a200 --- /dev/null +++ b/test/Exception/RuntimeExceptionTest.php @@ -0,0 +1,19 @@ +assertInstanceOf(RuntimeException::class, $exception); + $this->assertInstanceOf(ExceptionInterface::class, $exception); + } +} diff --git a/test/Identity/IdentityInterfaceTest.php b/test/Identity/IdentityInterfaceTest.php new file mode 100644 index 0000000..e7066d9 --- /dev/null +++ b/test/Identity/IdentityInterfaceTest.php @@ -0,0 +1,36 @@ +identityInterfaceMock = $this->createMock(IdentityInterface::class); + $this->identityInterfaceMock->method('getRoles')->willReturn(['admin']); + } + + public function testCreate(): void + { + $this->assertInstanceOf(IdentityInterface::class, $this->identityInterfaceMock); + } + + public function testFunctions(): void + { + $role = $this->identityInterfaceMock->getRoles(); + $this->assertIsArray($role); + $this->assertSame(['admin'], $role); + } +} diff --git a/test/Role/RoleInterfaceTest.php b/test/Role/RoleInterfaceTest.php new file mode 100644 index 0000000..9ed5823 --- /dev/null +++ b/test/Role/RoleInterfaceTest.php @@ -0,0 +1,35 @@ +roleInterfaceMock = $this->createMock(RoleInterface::class); + $this->roleInterfaceMock->method('getName')->willReturn('Test'); + } + + public function testCreate(): void + { + $this->assertInstanceOf(RoleInterface::class, $this->roleInterfaceMock); + } + + public function testFunctions(): void + { + $name = $this->roleInterfaceMock->getName(); + $this->assertSame('Test', $name); + } +}