From b5b15d269ea7e2ce1bdad2200f7430c40d285d7a Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Wed, 26 Jul 2023 14:53:16 +0300 Subject: [PATCH 1/6] implement tests, psalm, code sniffer --- .github/workflows/cs-tests.yml | 46 ++++++++++ .github/workflows/static-analisys.yml | 46 ++++++++++ .github/workflows/unit-tests.yml | 46 ++++++++++ .gitignore | 5 ++ README.md | 4 +- composer.json | 20 ++++- phpcs.xml | 20 +++++ phpunit.xml | 12 +++ psalm.xml | 17 ++++ src/ConfigProvider.php | 44 +++------- src/Exception/ExceptionInterface.php | 12 +-- src/Exception/InvalidArgumentException.php | 12 +-- src/Exception/RuntimeException.php | 12 +-- .../ContainerAbstractServiceFactory.php | 29 ++++--- src/Factory/SessionMiddlewareFactory.php | 29 +++---- src/Factory/SessionOptionsFactory.php | 37 +++++--- src/Options/SessionOptions.php | 20 +---- src/SessionMiddleware.php | 53 ++++------- test/ConfigProviderTest.php | 50 +++++++++++ .../ContainerAbstractServiceFactoryTest.php | 67 ++++++++++++++ test/Factory/SessionMiddlewareFactoryTest.php | 87 +++++++++++++++++++ test/Factory/SessionOptionsFactoryTest.php | 78 +++++++++++++++++ test/Options/SessionOptionsTest.php | 24 +++++ test/SessionMiddlewareTest.php | 55 +++++++++--- 24 files changed, 652 insertions(+), 173 deletions(-) create mode 100644 .github/workflows/cs-tests.yml create mode 100644 .github/workflows/static-analisys.yml create mode 100644 .github/workflows/unit-tests.yml create mode 100644 phpcs.xml create mode 100644 phpunit.xml create mode 100644 psalm.xml create mode 100644 test/ConfigProviderTest.php create mode 100644 test/Factory/ContainerAbstractServiceFactoryTest.php create mode 100644 test/Factory/SessionMiddlewareFactoryTest.php create mode 100644 test/Factory/SessionOptionsFactoryTest.php create mode 100644 test/Options/SessionOptionsTest.php 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-analisys.yml b/.github/workflows/static-analisys.yml new file mode 100644 index 0000000..74550fc --- /dev/null +++ b/.github/workflows/static-analisys.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.yml b/.github/workflows/unit-tests.yml new file mode 100644 index 0000000..593bed9 --- /dev/null +++ b/.github/workflows/unit-tests.yml @@ -0,0 +1,46 @@ +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 f3e6777..734d003 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +clover.xml +coveralls-upload.json +.phpcs-cache +.phpunit.result.cache + # Created by .ignore support plugin (hsz.mobi) ### Composer template composer.phar diff --git a/README.md b/README.md index 5ae3707..b96fe6a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # dot-session ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-session) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-session/5.2.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-session/5.3.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/network) [![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/stargazers) [![GitHub license](https://img.shields.io/github/license/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/blob/5.0/LICENSE.md) +[![SymfonyInsight](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a/big.svg)](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a) + DotKernel session component extending and customizing [laminas-session](https://github.com/laminas/laminas-session) diff --git a/composer.json b/composer.json index 0d3801a..391a1c8 100644 --- a/composer.json +++ b/composer.json @@ -24,12 +24,30 @@ }, "require-dev": { "phpunit/phpunit": "^9.5.20", - "squizlabs/php_codesniffer": "^3.6.2", + "laminas/laminas-coding-standard": "^2.5", + "vimeo/psalm": "^5.13", "laminas/laminas-stdlib": "^3.7.1" }, "autoload": { "psr-4": { "Dot\\Session\\": "src/" } + }, + "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" + }, + "config": { + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } 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..4d86f46 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,12 @@ + + + + + ./test + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..7272b57 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php index 8dad5d3..c46aa67 100644 --- a/src/ConfigProvider.php +++ b/src/ConfigProvider.php @@ -1,11 +1,6 @@ $this->getDependencyConfig(), - - 'session_manager' => [ + 'dependencies' => $this->getDependencyConfig(), + 'session_manager' => [ 'validators' => [], - 'options' => [], + 'options' => [], ], - - 'session_storage' => [ + 'session_storage' => [ 'type' => SessionArrayStorage::class, ], - 'session_containers' => [], ]; } - /** - * Merge our config with Laminas Session dependencies - * @return array - */ public function getDependencyConfig(): array { return [ - 'aliases' => [ + 'aliases' => [ SessionManager::class => ManagerInterface::class, ], - 'factories' => [ - ConfigInterface::class => SessionConfigFactory::class, - ManagerInterface::class => SessionManagerFactory::class, - StorageInterface::class => StorageFactory::class, - - SessionOptions::class => SessionOptionsFactory::class, + 'factories' => [ + ConfigInterface::class => SessionConfigFactory::class, + ManagerInterface::class => SessionManagerFactory::class, + StorageInterface::class => StorageFactory::class, + SessionOptions::class => SessionOptionsFactory::class, SessionMiddleware::class => SessionMiddlewareFactory::class, ], 'abstract_factories' => [ ContainerAbstractServiceFactory::class, - ] + ], ]; } } diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php index 363d234..ac3feac 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Exception/ExceptionInterface.php @@ -1,19 +1,9 @@ has(ManagerInterface::class) ? $container->get(ManagerInterface::class) : Container::getDefaultManager(); $options = $container->get(SessionOptions::class); + + if (! $options instanceof SessionOptions) { + throw new Exception('Unable to find ' . SessionOptions::class); + } + return new SessionMiddleware( $sessionManager, $options diff --git a/src/Factory/SessionOptionsFactory.php b/src/Factory/SessionOptionsFactory.php index 265a868..ceda6a8 100644 --- a/src/Factory/SessionOptionsFactory.php +++ b/src/Factory/SessionOptionsFactory.php @@ -1,29 +1,38 @@ get('config')['dot_session']); + if (! $container->has('config')) { + throw new Exception('Unable to find config'); + } + + $config = $container->get('config'); + + if (! isset($config['dot_session']) || ! is_array($config['dot_session'])) { + throw new Exception('Unable to find dot_session config'); + } + + $config = $config['dot_session']; + + return new SessionOptions($config); } } diff --git a/src/Options/SessionOptions.php b/src/Options/SessionOptions.php index c81a009..682b6ac 100644 --- a/src/Options/SessionOptions.php +++ b/src/Options/SessionOptions.php @@ -1,37 +1,25 @@ rememberMeInactive; } - /** - * @param int $rememberMeInactive - */ - public function setRememberMeInactive(int $rememberMeInactive) + public function setRememberMeInactive(int $rememberMeInactive): void { $this->rememberMeInactive = $rememberMeInactive; } diff --git a/src/SessionMiddleware.php b/src/SessionMiddleware.php index ce9a319..1212d7e 100644 --- a/src/SessionMiddleware.php +++ b/src/SessionMiddleware.php @@ -1,65 +1,48 @@ defaultSessionManager = $sessionManager; - $this->options = $options; + $this->options = $options; Container::setDefaultManager($sessionManager); } - /** - * @param ServerRequestInterface $request - * @param RequestHandlerInterface $handler - * @return ResponseInterface - */ - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { + public function process( + ServerRequestInterface $request, + RequestHandlerInterface $handler + ): ResponseInterface { $now = time(); - if (isset($this->defaultSessionManager->getStorage()['LAST_ACTIVITY']) - && $now - $this->defaultSessionManager->getStorage()['LAST_ACTIVITY'] > $this->options->getRememberMeInactive() + if ( + isset($this->defaultSessionManager->getStorage()['LAST_ACTIVITY']) + && + ($now - $this->defaultSessionManager->getStorage()['LAST_ACTIVITY']) + > $this->options->getRememberMeInactive() ) { $this->defaultSessionManager->destroy(['send_expire_cookie' => true, 'clear_storage' => true]); $this->defaultSessionManager->start(); } - $this->defaultSessionManager->getStorage()['LAST_ACTIVITY'] = $now; return $handler->handle($request); } } diff --git a/test/ConfigProviderTest.php b/test/ConfigProviderTest.php new file mode 100644 index 0000000..9701f88 --- /dev/null +++ b/test/ConfigProviderTest.php @@ -0,0 +1,50 @@ +config = (new ConfigProvider())(); + } + + public function testHasDependencies(): void + { + $this->assertArrayHasKey('dependencies', $this->config); + } + + public function testDependenciesHasFactories(): void + { + $this->assertArrayHasKey('factories', $this->config['dependencies']); + $this->assertArrayHasKey(ConfigInterface::class, $this->config['dependencies']['factories']); + $this->assertArrayHasKey(ManagerInterface::class, $this->config['dependencies']['factories']); + $this->assertArrayHasKey(StorageInterface::class, $this->config['dependencies']['factories']); + $this->assertArrayHasKey(SessionOptions::class, $this->config['dependencies']['factories']); + $this->assertArrayHasKey(SessionMiddleware::class, $this->config['dependencies']['factories']); + } + + public function testDependenciesHasAliases() + { + $this->assertArrayHasKey('aliases', $this->config['dependencies']); + $this->assertArrayHasKey(SessionManager::class, $this->config['dependencies']['aliases']); + } + + public function testDependenciesHasAbstractFactories() + { + $this->assertArrayHasKey('abstract_factories', $this->config['dependencies']); + } +} diff --git a/test/Factory/ContainerAbstractServiceFactoryTest.php b/test/Factory/ContainerAbstractServiceFactoryTest.php new file mode 100644 index 0000000..7e065e7 --- /dev/null +++ b/test/Factory/ContainerAbstractServiceFactoryTest.php @@ -0,0 +1,67 @@ + [ + 'name' => 'test', + ], + ]; + + /** + * @throws Exception + */ + protected function setUp(): void + { + $this->container = $this->createMock(ContainerInterface::class); + $this->factory = new ContainerAbstractServiceFactory(); + } + + public function testInstantiate(): void + { + $this->container->expects($this->once()) + ->method('has') + ->with(ManagerInterface::class) + ->willReturn(true); + + $this->container->expects($this->once()) + ->method('get') + ->with(ManagerInterface::class) + ->willReturnMap([ManagerInterface::class]); + + $factory = (new ContainerAbstractServiceFactory())($this->container, 'dot-session.test'); + $this->assertInstanceOf(Container::class, $factory); + } + + public function testCanCreate(): void + { + $this->container->expects($this->once()) + ->method('has') + ->with('config') + ->willReturn(true); + + $this->container->expects($this->once()) + ->method('get') + ->with('config') + ->willReturn($this->config); + + $this->assertFalse($this->factory->canCreate($this->container, 'dot-session.not_in_config_name')); + $this->assertTrue($this->factory->canCreate($this->container, 'dot-session.test')); + } +} diff --git a/test/Factory/SessionMiddlewareFactoryTest.php b/test/Factory/SessionMiddlewareFactoryTest.php new file mode 100644 index 0000000..1f1ab9b --- /dev/null +++ b/test/Factory/SessionMiddlewareFactoryTest.php @@ -0,0 +1,87 @@ +container = $this->createMock(ContainerInterface::class); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillInstantiateWithDefaultManager(): void + { + $this->container->expects($this->once())->method('has') + ->with(ManagerInterface::class) + ->willReturn(false); + + $this->container->expects($this->once())->method('get') + ->with(SessionOptions::class) + ->willReturn(new SessionOptions()); + + $factory = (new SessionMiddlewareFactory())($this->container); + + $this->assertInstanceOf(SessionMiddleware::class, $factory); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillInstantiateWithManagerInterface(): void + { + $managerInterface = $this->createMock(SessionManager::class); + $this->container->expects($this->once())->method('has') + ->with(ManagerInterface::class) + ->willReturn(true); + + $this->container->method('get') + ->willReturnMap([ + [ManagerInterface::class, $managerInterface], + [SessionOptions::class, new SessionOptions()], + ]); + + $factory = (new SessionMiddlewareFactory())($this->container); + + $this->assertInstanceOf(SessionMiddleware::class, $factory); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillReturnException(): void + { + $this->container->expects($this->once())->method('has') + ->with(ManagerInterface::class) + ->willReturn(false); + + $this->container->expects($this->once())->method('get') + ->with(SessionOptions::class) + ->willReturn(null); + + $this->expectException(Exception::class); + $this->expectExceptionMessage('Unable to find ' . SessionOptions::class); + (new SessionMiddlewareFactory())($this->container); + } +} diff --git a/test/Factory/SessionOptionsFactoryTest.php b/test/Factory/SessionOptionsFactoryTest.php new file mode 100644 index 0000000..01f78c2 --- /dev/null +++ b/test/Factory/SessionOptionsFactoryTest.php @@ -0,0 +1,78 @@ +container = $this->createMock(ContainerInterface::class); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillNotInstantiateWithoutConfig(): void + { + $this->container->expects($this->once()) + ->method('has') + ->with('config') + ->willReturn(false); + + $this->expectExceptionMessage('Unable to find config'); + $this->expectException(Exception::class); + (new SessionOptionsFactory())($this->container); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillNotInstantiateWithoutDotLog(): void + { + $this->container->expects($this->once()) + ->method('has') + ->with('config') + ->willReturn(true); + + $this->container->method('get')->willReturnMap([]); + + $this->expectExceptionMessage('Unable to find dot_session config'); + $this->expectException(Exception::class); + (new SessionOptionsFactory())($this->container); + } + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function testWillInstantiate(): void + { + $this->container->expects($this->once()) + ->method('has') + ->with('config') + ->willReturn(true); + + $this->container->method('get')->willReturn([ + 'dot_session' => [], + ]); + + $factory = (new SessionOptionsFactory())($this->container); + + $this->assertInstanceOf(SessionOptions::class, $factory); + } +} diff --git a/test/Options/SessionOptionsTest.php b/test/Options/SessionOptionsTest.php new file mode 100644 index 0000000..9be7bda --- /dev/null +++ b/test/Options/SessionOptionsTest.php @@ -0,0 +1,24 @@ +assertIsInt($sessionOptions->getRememberMeInactive()); + } + + public function testSetRememberMeInactive(): void + { + $sessionOptions = new SessionOptions(); + $sessionOptions->setRememberMeInactive(100); + $this->assertEquals(100, $sessionOptions->getRememberMeInactive()); + } +} diff --git a/test/SessionMiddlewareTest.php b/test/SessionMiddlewareTest.php index 7dcbe09..5d29af3 100644 --- a/test/SessionMiddlewareTest.php +++ b/test/SessionMiddlewareTest.php @@ -1,20 +1,51 @@ sessionManager = $this->createMock(SessionManager::class); + $this->sessionOptions = $this->createMock(SessionOptions::class); + + $this->sessionMiddleware = new SessionMiddleware($this->sessionManager, $this->sessionOptions); + } + + public function testProcess() + { + $requestInterface = $this->createMock(ServerRequestInterface::class); + $handlerInterface = $this->createMock(RequestHandlerInterface::class); + $process = $this->sessionMiddleware->process($requestInterface, $handlerInterface); + $this->assertInstanceOf(ResponseInterface::class, $process); + } + + public function testProcessWithLastActivity() + { + $this->sessionManager->method('getStorage') + ->willReturn(['LAST_ACTIVITY' => 1689849724]); + + $this->sessionOptions->method('getRememberMeInactive') + ->willReturn(600); + + $requestInterface = $this->createMock(ServerRequestInterface::class); + $handlerInterface = $this->createMock(RequestHandlerInterface::class); + $process = $this->sessionMiddleware->process($requestInterface, $handlerInterface); + $this->assertInstanceOf(ResponseInterface::class, $process); } } From 1bd36e4fe4840c35a112b9f278544b9c844356be Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Wed, 26 Jul 2023 14:55:36 +0300 Subject: [PATCH 2/6] implement tests, psalm, code sniffer --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 391a1c8..a6423e1 100644 --- a/composer.json +++ b/composer.json @@ -20,13 +20,13 @@ "psr/http-message": "^1.0.1", "laminas/laminas-servicemanager": "^3.11.1", "laminas/laminas-session": "^2.12.1", - "psr/http-server-middleware": "^1.0.1" + "psr/http-server-middleware": "^1.0.1", + "laminas/laminas-stdlib": "^3.7.1" }, "require-dev": { "phpunit/phpunit": "^9.5.20", "laminas/laminas-coding-standard": "^2.5", "vimeo/psalm": "^5.13", - "laminas/laminas-stdlib": "^3.7.1" }, "autoload": { "psr-4": { From 582328d935faf4b0ff7861860015c36c93a9c6e9 Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Wed, 26 Jul 2023 15:14:11 +0300 Subject: [PATCH 3/6] implement tests, psalm, code sniffer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a6423e1..fd59167 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "require-dev": { "phpunit/phpunit": "^9.5.20", "laminas/laminas-coding-standard": "^2.5", - "vimeo/psalm": "^5.13", + "vimeo/psalm": "^5.13" }, "autoload": { "psr-4": { From 1907c78c5f89976d15fdb729258536a6cfa0601b Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Thu, 27 Jul 2023 16:43:45 +0300 Subject: [PATCH 4/6] changes from the review --- README.md | 70 ++++++++++++++++++- composer.json | 7 +- src/Options/SessionOptions.php | 4 -- test/ConfigProviderTest.php | 12 +++- .../ContainerAbstractServiceFactoryTest.php | 1 + test/Factory/SessionMiddlewareFactoryTest.php | 4 ++ test/Factory/SessionOptionsFactoryTest.php | 3 + test/SessionMiddlewareTest.php | 14 +++- 8 files changed, 103 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b96fe6a..01ee199 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # dot-session ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-session) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-session/5.3.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-session/5.4.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/network) [![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/stargazers) [![GitHub license](https://img.shields.io/github/license/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/blob/5.0/LICENSE.md) + [![SymfonyInsight](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a/big.svg)](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a) @@ -18,10 +19,73 @@ Run the following command in your project folder ```bash $ composer require dotkernel/dot-session ``` +## Configuration + +Add this: + + $app->pipe(Dot\Session\SessionMiddleware::class) to config/pipeline.php + + \Dot\Session\ConfigProvider::class to config/config.php + ## Usage -Next, inject this service in you classes, wherever you need session. +Basic usage to access and use the session object in your services + +### Method #1 - Factory +Step 1 +Create a factory that retrieves from container the SessionManger + +```php +class ExampleFactory +{ + // code + + public function __invoke(ContainerInterface $container) + { + //return Session Service with Session Manager from container + return new ExampleService( + $container->get(SessionManager::class) + ) + } +} +``` + +Register the factory in any mode you register factories on your project. + +Step 2 Access through your Service + +```php + +class ExampleService +{ + private SessionManager $session; + + public function __construct(SessionManager $session) + { + $this->session = $session; + } + + //you methods +} +``` + +### Method 2 - Injection +If you use annotated injection you can inject the Session Manager in your services. + ```php -$app->pipe(SessionMiddleware::class); +class ExampleService +{ + private SessionManager $session; + + /** + * @Inject({SessionManager::class}) + */ + public function __construct(SessionManager $session) + { + $this->session = $session; + } + + //you methods +} ``` diff --git a/composer.json b/composer.json index fd59167..034100e 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "laminas/laminas-stdlib": "^3.7.1" }, "require-dev": { - "phpunit/phpunit": "^9.5.20", + "phpunit/phpunit": "^10.2", "laminas/laminas-coding-standard": "^2.5", "vimeo/psalm": "^5.13" }, @@ -33,6 +33,11 @@ "Dot\\Session\\": "src/" } }, + "autoload-dev": { + "psr-4": { + "DotTest\\Session\\": "test/" + } + }, "scripts": { "check": [ "@cs-check", diff --git a/src/Options/SessionOptions.php b/src/Options/SessionOptions.php index 682b6ac..bbf18fe 100644 --- a/src/Options/SessionOptions.php +++ b/src/Options/SessionOptions.php @@ -1,9 +1,5 @@ assertArrayHasKey(SessionMiddleware::class, $this->config['dependencies']['factories']); } - public function testDependenciesHasAliases() + public function testDependenciesHasAliases(): void { $this->assertArrayHasKey('aliases', $this->config['dependencies']); $this->assertArrayHasKey(SessionManager::class, $this->config['dependencies']['aliases']); } - public function testDependenciesHasAbstractFactories() + public function testDependenciesHasAbstractFactories(): void { $this->assertArrayHasKey('abstract_factories', $this->config['dependencies']); } + + public function testConfigHasSessionStorage(): void + { + $this->assertArrayHasKey('session_storage', $this->config); + $this->assertIsArray($this->config['session_storage']); + $this->assertArrayHasKey('type', $this->config['session_storage']); + $this->assertNotEmpty($this->config['session_storage']['type'] ); + } } diff --git a/test/Factory/ContainerAbstractServiceFactoryTest.php b/test/Factory/ContainerAbstractServiceFactoryTest.php index 7e065e7..cb4a6ad 100644 --- a/test/Factory/ContainerAbstractServiceFactoryTest.php +++ b/test/Factory/ContainerAbstractServiceFactoryTest.php @@ -26,6 +26,7 @@ class ContainerAbstractServiceFactoryTest extends TestCase /** * @throws Exception + * @throws \PHPUnit\Framework\MockObject\Exception */ protected function setUp(): void { diff --git a/test/Factory/SessionMiddlewareFactoryTest.php b/test/Factory/SessionMiddlewareFactoryTest.php index 1f1ab9b..38a8095 100644 --- a/test/Factory/SessionMiddlewareFactoryTest.php +++ b/test/Factory/SessionMiddlewareFactoryTest.php @@ -20,6 +20,9 @@ class SessionMiddlewareFactoryTest extends TestCase { private ContainerInterface|MockObject $container; + /** + * @throws \PHPUnit\Framework\MockObject\Exception + */ protected function setUp(): void { $this->container = $this->createMock(ContainerInterface::class); @@ -47,6 +50,7 @@ public function testWillInstantiateWithDefaultManager(): void /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface + * @throws \PHPUnit\Framework\MockObject\Exception */ public function testWillInstantiateWithManagerInterface(): void { diff --git a/test/Factory/SessionOptionsFactoryTest.php b/test/Factory/SessionOptionsFactoryTest.php index 01f78c2..501c282 100644 --- a/test/Factory/SessionOptionsFactoryTest.php +++ b/test/Factory/SessionOptionsFactoryTest.php @@ -17,6 +17,9 @@ class SessionOptionsFactoryTest extends TestCase { private ContainerInterface|MockObject $container; + /** + * @throws \PHPUnit\Framework\MockObject\Exception + */ protected function setUp(): void { $this->container = $this->createMock(ContainerInterface::class); diff --git a/test/SessionMiddlewareTest.php b/test/SessionMiddlewareTest.php index 5d29af3..29fd263 100644 --- a/test/SessionMiddlewareTest.php +++ b/test/SessionMiddlewareTest.php @@ -7,6 +7,7 @@ use Dot\Session\Options\SessionOptions; use Dot\Session\SessionMiddleware; use Laminas\Session\SessionManager; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -19,6 +20,9 @@ class SessionMiddlewareTest extends TestCase private SessionManager $sessionManager; private SessionOptions $sessionOptions; + /** + * @throws Exception + */ protected function setUp(): void { $this->sessionManager = $this->createMock(SessionManager::class); @@ -27,7 +31,10 @@ protected function setUp(): void $this->sessionMiddleware = new SessionMiddleware($this->sessionManager, $this->sessionOptions); } - public function testProcess() + /** + * @throws Exception + */ + public function testProcess(): void { $requestInterface = $this->createMock(ServerRequestInterface::class); $handlerInterface = $this->createMock(RequestHandlerInterface::class); @@ -35,7 +42,10 @@ public function testProcess() $this->assertInstanceOf(ResponseInterface::class, $process); } - public function testProcessWithLastActivity() + /** + * @throws Exception + */ + public function testProcessWithLastActivity(): void { $this->sessionManager->method('getStorage') ->willReturn(['LAST_ACTIVITY' => 1689849724]); From c5819860f0a3f9c8aa68429f5e827df55da65118 Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Thu, 27 Jul 2023 16:49:09 +0300 Subject: [PATCH 5/6] analysis badge --- README.md | 3 +++ test/ConfigProviderTest.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01ee199..8057e3b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ [![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/stargazers) [![GitHub license](https://img.shields.io/github/license/dotkernel/dot-session)](https://github.com/dotkernel/dot-session/blob/5.0/LICENSE.md) +[![Build Static](https://github.com/dotkernel/dot-session/actions/workflows/static-analysis.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/dot-session/actions/workflows/static-analysis.yml) + + [![SymfonyInsight](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a/big.svg)](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a) diff --git a/test/ConfigProviderTest.php b/test/ConfigProviderTest.php index c172b32..e0deeaf 100644 --- a/test/ConfigProviderTest.php +++ b/test/ConfigProviderTest.php @@ -53,6 +53,6 @@ public function testConfigHasSessionStorage(): void $this->assertArrayHasKey('session_storage', $this->config); $this->assertIsArray($this->config['session_storage']); $this->assertArrayHasKey('type', $this->config['session_storage']); - $this->assertNotEmpty($this->config['session_storage']['type'] ); + $this->assertNotEmpty($this->config['session_storage']['type']); } } From b03415f95e5852c33190eb64a0fcd0b74063898c Mon Sep 17 00:00:00 2001 From: Claudiu Pintiuta Date: Fri, 28 Jul 2023 11:37:44 +0300 Subject: [PATCH 6/6] changes from git review --- README.md | 32 +++++++++++++++++--------------- test/SessionMiddlewareTest.php | 5 +++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 8057e3b..9c263a7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ [![Build Static](https://github.com/dotkernel/dot-session/actions/workflows/static-analysis.yml/badge.svg?branch=5.0)](https://github.com/dotkernel/dot-session/actions/workflows/static-analysis.yml) - [![SymfonyInsight](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a/big.svg)](https://insight.symfony.com/projects/f6038340-d76b-4da8-9016-0472d4899f0a) @@ -19,25 +18,26 @@ DotKernel session component extending and customizing [laminas-session](https:// ## Installation Run the following command in your project folder -```bash -$ composer require dotkernel/dot-session -``` + + composer require dotkernel/dot-session + + ## Configuration +Register `SessionMiddleware` in your application's pipeline by adding the following line to `config/pipeline.php`: -Add this: + $app->pipe(Dot\Session\SessionMiddleware::class); - $app->pipe(Dot\Session\SessionMiddleware::class) to config/pipeline.php - \Dot\Session\ConfigProvider::class to config/config.php +Register `dot-session`'s ConfigProvider in your application's configurations by adding the following line to `config/config.php`: + \Dot\Session\ConfigProvider::class, -## Usage -Basic usage to access and use the session object in your services +## Usage +Basic usage to access and use the session object in your services: ### Method #1 - Factory -Step 1 -Create a factory that retrieves from container the SessionManger +#### Step 1: Create a factory that retrieves the SessionManger from the container ```php class ExampleFactory @@ -46,7 +46,6 @@ class ExampleFactory public function __invoke(ContainerInterface $container) { - //return Session Service with Session Manager from container return new ExampleService( $container->get(SessionManager::class) ) @@ -56,7 +55,7 @@ class ExampleFactory Register the factory in any mode you register factories on your project. -Step 2 Access through your Service +#### Step 2: Access through your Service ```php @@ -77,6 +76,9 @@ class ExampleService If you use annotated injection you can inject the Session Manager in your services. ```php +use Dot\AnnotatedServices\Annotation\Inject; +use Laminas\Session\SessionManager; + class ExampleService { private SessionManager $session; @@ -89,6 +91,6 @@ class ExampleService $this->session = $session; } - //you methods + //your methods } -``` +``` \ No newline at end of file diff --git a/test/SessionMiddlewareTest.php b/test/SessionMiddlewareTest.php index 29fd263..30dba89 100644 --- a/test/SessionMiddlewareTest.php +++ b/test/SessionMiddlewareTest.php @@ -8,6 +8,7 @@ use Dot\Session\SessionMiddleware; use Laminas\Session\SessionManager; use PHPUnit\Framework\MockObject\Exception; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -17,8 +18,8 @@ class SessionMiddlewareTest extends TestCase { private SessionMiddleware $sessionMiddleware; - private SessionManager $sessionManager; - private SessionOptions $sessionOptions; + private SessionManager|MockObject $sessionManager; + private SessionOptions|MockObject $sessionOptions; /** * @throws Exception