Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented PHPStan #349

Merged
merged 12 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
on:
- push

name: Run PHPStan checks

jobs:
mutation:
name: PHPStan ${{ matrix.php }}-${{ matrix.os }}

runs-on: ${{ matrix.os }}

strategy:
matrix:
os:
- ubuntu-latest

php:
- "8.2"
- "8.3"

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
coverage: pcov
ini-values: assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On
tools: composer:v2, cs2pr

- 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@v4
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: Setup project
run: |
mv config/autoload/local.php.dist config/autoload/local.php
mv config/autoload/mail.local.php.dist config/autoload/mail.local.php
mv config/autoload/local.test.php.dist config/autoload/local.test.php

- name: Run static analysis with PHPStan
run: vendor/bin/phpstan analyse
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ Based on Enrico Zimuel's [Zend Expressive API - Skeleton example](https://github
[![Build Static](https://github.com/dotkernel/api/actions/workflows/continuous-integration.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/api/actions/workflows/continuous-integration.yml)
[![codecov](https://codecov.io/gh/dotkernel/api/graph/badge.svg?token=53FN78G5CK)](https://codecov.io/gh/dotkernel/api)
[![Qodana](https://github.com/dotkernel/api/actions/workflows/qodana_code_quality.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/api/actions/workflows/qodana_code_quality.yml)

[![SymfonyInsight](https://insight.symfony.com/projects/7f9143cc-5e3c-4cfc-992c-377a001fde3e/big.svg)](https://insight.symfony.com/projects/7f9143cc-5e3c-4cfc-992c-377a001fde3e)
[![PHPStan](https://github.com/dotkernel/api/actions/workflows/static-analysis.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/api/actions/workflows/static-analysis.yml)

## Getting Started

Expand Down
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@
"laminas/laminas-development-mode": "^3.12.0",
"laminas/laminas-http": "^2.19.0",
"mezzio/mezzio-tooling": "^2.9.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-doctrine": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^10.5.10",
"roave/security-advisories": "dev-latest",
"symfony/var-dumper": "^7.1",
"vimeo/psalm": "^5.22.0"
"symfony/var-dumper": "^7.1"
},
"autoload": {
"psr-4": {
Expand Down
16 changes: 16 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
includes:
- vendor/phpstan/phpstan-doctrine/extension.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
parameters:
level: 5
paths:
- src
- test
treatPhpDocTypesAsCertain: false
ignoreErrors:
-
message: '#Call to an undefined method.*setAllowOverride#'
path: test/Functional/AbstractFunctionalTest.php
-
message: '#Call to an undefined method.*setService#'
path: test/Functional/AbstractFunctionalTest.php
25 changes: 0 additions & 25 deletions psalm-baseline.xml

This file was deleted.

17 changes: 0 additions & 17 deletions psalm.xml

This file was deleted.

6 changes: 1 addition & 5 deletions src/Admin/src/Service/AdminService.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,7 @@ public function deleteAdmin(Admin $admin): void

public function exists(string $identity = ''): bool
{
try {
return $this->findOneBy(['identity' => $identity]) instanceof Admin;
} catch (NotFoundException) {
return false;
}
return $this->adminRepository->findOneBy(['identity' => $identity]) instanceof Admin;
}

public function existsOther(string $identity = '', string $uuid = ''): bool
Expand Down
6 changes: 3 additions & 3 deletions src/App/src/Entity/OAuthAuthCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function setId(int $id): self
return $this;
}

public function getId(): ?int
public function getId(): int
{
return $this->id;
}
Expand All @@ -74,9 +74,9 @@ public function getClient(): ClientEntityInterface
return $this->client;
}

public function getIdentifier(): ?int
public function getIdentifier(): string
{
return $this->getId();
return (string) $this->getId();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/App/src/Repository/OAuthClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function getClientEntity($clientIdentifier): ?ClientEntityInterface
public function validateClient($clientIdentifier, $clientSecret, $grantType): bool
{
$client = $this->getClientEntity($clientIdentifier);
if (! $client instanceof ClientEntityInterface) {
if (! $client instanceof OAuthClient) {
alexmerlin marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion src/App/src/UserIdentity.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class UserIdentity implements UserInterface
{
protected string $identity;
/** @var iterable<int|string, string> $roles */
/** @var array<int|string, string> $roles */
protected array $roles;
protected array $details;

Expand Down
18 changes: 6 additions & 12 deletions test/Functional/AbstractFunctionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
use Fig\Http\Message\RequestMethodInterface;
use Fig\Http\Message\StatusCodeInterface;
use Laminas\Diactoros\ServerRequest;
use Laminas\ServiceManager\ServiceManager;
use Mezzio\Application;
use Mezzio\MiddlewareFactory;
use PHPUnit\Framework\TestCase;
Expand All @@ -31,7 +30,6 @@

use function array_merge;
use function getenv;
use function method_exists;
use function putenv;
use function realpath;

Expand All @@ -41,7 +39,7 @@ class AbstractFunctionalTest extends TestCase
use DatabaseTrait;

protected Application $app;
protected ContainerInterface|ServiceManager $container;
protected ContainerInterface $container;
protected const DEFAULT_PASSWORD = 'dotkernel';

/**
Expand All @@ -59,12 +57,8 @@ public function setUp(): void

$this->ensureTestMode();

if (method_exists($this, 'runMigrations')) {
$this->runMigrations();
}
if (method_exists($this, 'runSeeders')) {
$this->runSeeders();
}
$this->runMigrations();
$this->runSeeders();
}

public function tearDown(): void
Expand Down Expand Up @@ -132,7 +126,7 @@ protected function getEntityManager(): EntityManagerInterface
return $this->container->get(EntityManagerInterface::class);
}

protected function getContainer(): ContainerInterface|ServiceManager
protected function getContainer(): ContainerInterface
{
return $this->container;
}
Expand All @@ -150,7 +144,7 @@ private function ensureTestMode(): void
);
}

if (! $this->getEntityManager()->getConnection()->getParams()['memory'] ?? false) {
if (! ($this->getEntityManager()->getConnection()->getParams()['memory'] ?? false)) {
throw new RuntimeException(
'You are running tests in a non in-memory database. Did you forget to create local.test.php?'
);
Expand Down Expand Up @@ -271,7 +265,7 @@ private function createRequest(
string $body = 'php://input',
string $protocol = '1.1'
): ServerRequestInterface {
if (method_exists($this, 'isAuthenticated') && $this->isAuthenticated()) {
if ($this->isAuthenticated()) {
$headers = array_merge($headers, $this->getAuthorizationHeader());
}

Expand Down
4 changes: 2 additions & 2 deletions test/Unit/Admin/Service/AdminServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
class AdminServiceTest extends TestCase
{
private Subject|MockObject $subject;
private AdminRoleService $adminRoleService;
private AdminRepository $adminRepository;
private AdminRoleService|MockObject $adminRoleService;
private AdminRepository|MockObject $adminRepository;

/**
* @throws \PHPUnit\Framework\MockObject\Exception
Expand Down
7 changes: 4 additions & 3 deletions test/Unit/App/Middleware/AuthenticationMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Mezzio\Authentication\AuthenticationInterface;
use Mezzio\Authentication\UserInterface;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -18,10 +19,10 @@
class AuthenticationMiddlewareTest extends TestCase
{
private Subject $subject;
private AuthenticationInterface $auth;
private AuthenticationInterface|MockObject $auth;
private ServerRequestInterface $request;
private RequestHandlerInterface $handler;
private ResponseInterface $response;
private RequestHandlerInterface|MockObject $handler;
private ResponseInterface|MockObject $response;

/**
* @throws Exception
Expand Down
11 changes: 6 additions & 5 deletions test/Unit/App/Middleware/AuthorizationMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Mezzio\Authentication\UserInterface;
use Mezzio\Authorization\AuthorizationInterface;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -29,12 +30,12 @@

class AuthorizationMiddlewareTest extends TestCase
{
private Subject $subject;
private UserRepository $userRepository;
private AdminRepository $adminRepository;
private AuthorizationInterface $authorization;
private Subject|MockObject $subject;
private UserRepository|MockObject $userRepository;
private AdminRepository|MockObject $adminRepository;
private AuthorizationInterface|MockObject $authorization;
private ServerRequestInterface $request;
private RequestHandlerInterface $handler;
private RequestHandlerInterface|MockObject $handler;
private ResponseInterface $response;

/**
Expand Down
7 changes: 4 additions & 3 deletions test/Unit/App/Middleware/ContentNegotiationMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ public function testCannotResolveRepresentation(): void

public function testFormatAcceptRequest(): void
MarioRadu marked this conversation as resolved.
Show resolved Hide resolved
{
$this->assertIsArray(
$this->subject->formatAcceptRequest('application/json')
);
$accept = $this->subject->formatAcceptRequest('application/json');

$this->assertNotEmpty($accept);
alexmerlin marked this conversation as resolved.
Show resolved Hide resolved
$this->assertSame(['application/json'], $accept);
}

public function testCheckAccept(): void
Expand Down
13 changes: 4 additions & 9 deletions test/Unit/App/Middleware/DeprecationMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Mezzio\Router\Route;
use Mezzio\Router\RouteResult;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
Expand All @@ -31,9 +32,9 @@

class DeprecationMiddlewareTest extends TestCase
{
private Subject $subject;
private ServerRequestInterface $request;
private RequestHandlerInterface $handler;
private Subject|MockObject $subject;
private ServerRequestInterface|MockObject $request;
private RequestHandlerInterface|MockObject $handler;
private ResponseInterface $response;

private const VERSIONING_CONFIG = [
Expand Down Expand Up @@ -131,8 +132,6 @@ public function handle(ServerRequestInterface $request): ResponseInterface

$response = $this->subject->process($this->request, $this->handler);

$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertIsArray($response->getHeaders());
$this->assertTrue($response->hasHeader('sunset'));
$this->assertTrue($response->hasHeader('link'));
$this->assertSame('2038-01-01', $response->getHeader('sunset')[0]);
Expand Down Expand Up @@ -196,8 +195,6 @@ public function process(

$response = $this->subject->process($this->request, $this->handler);

$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertIsArray($response->getHeaders());
$this->assertTrue($response->hasHeader('sunset'));
$this->assertTrue($response->hasHeader('link'));
$this->assertSame('2038-01-01', $response->getHeader('sunset')[0]);
Expand Down Expand Up @@ -255,8 +252,6 @@ public function post(): ResponseInterface

$response = $this->subject->process($this->request, $this->handler);

$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertIsArray($response->getHeaders());
$this->assertTrue($response->hasHeader('sunset'));
$this->assertTrue($response->hasHeader('link'));
$this->assertSame('2038-01-01', $response->getHeader('sunset')[0]);
Expand Down
Loading