Merge pull request 'Adding a functional test which covers all functions' (#1) from feature/tests into develop

Reviewed-on: #1
This commit is contained in:
Ferdinand Kuhl 2022-05-19 11:01:33 +02:00
commit aaacd95a06
4 changed files with 148 additions and 0 deletions

View file

@ -1,3 +1,5 @@
DigiComp:
FlowSessionLock:
lockStoreConnection: "flock://%FLOW_PATH_DATA%Temporary/Testing/SessionLocks/"
readOnlyExpressions:
TestUnprotected: "method(DigiComp\\FlowSessionLock\\Tests\\Functional\\Fixtures\\Controller\\ExampleController->unprotectedByConfigurationAction())"

View file

@ -0,0 +1,43 @@
<?php
namespace DigiComp\FlowSessionLock\Tests\Functional\Fixtures\Controller;
use DigiComp\FlowSessionLock\Annotations as FlowSessionLock;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Controller\ActionController;
class ExampleController extends ActionController
{
public const CONTROLLER_TIME = 200;
/**
* @Flow\Session(autoStart=true);
* @return string
*/
public function protectedAction()
{
\usleep(static::CONTROLLER_TIME * 1000);
return 'Hello World!';
}
/**
* @Flow\Session(autoStart=true);
* @FlowSessionLock\ReadOnly
* @return string
*/
public function unprotectedByAnnotationAction()
{
\usleep(static::CONTROLLER_TIME * 1000);
return 'Hello World!';
}
/**
* @Flow\Session(autoStart=true);
* @return string
*/
public function unprotectedByConfigurationAction()
{
\usleep(static::CONTROLLER_TIME * 1000);
return 'Hello World!';
}
}

View file

@ -0,0 +1,100 @@
<?php
namespace DigiComp\FlowSessionLock\Tests\Functional;
use DigiComp\FlowSessionLock\Tests\Functional\Fixtures\Controller\ExampleController;
use GuzzleHttp\Psr7\Uri;
use Neos\Flow\Http\Cookie;
use Neos\Flow\Mvc\Routing\Route;
use Neos\Flow\Tests\FunctionalTestCase;
use Psr\Http\Message\ServerRequestFactoryInterface;
class SessionLockRequestComponentTest extends FunctionalTestCase
{
protected ServerRequestFactoryInterface $serverRequestFactory;
protected function setUp(): void
{
parent::setUp();
$this->serverRequestFactory = $this->objectManager->get(ServerRequestFactoryInterface::class);
$route = new Route();
$route->setName('Functional Test - SessionRequestComponent::Restricted');
$route->setUriPattern('test/sessionlock/{@action}');
$route->setDefaults([
'@package' => 'DigiComp.FlowSessionLock',
'@subpackage' => 'Tests\Functional\Fixtures',
'@controller' => 'Example',
'@action' => 'protected',
'@format' => 'html',
]);
$route->setAppendExceedingArguments(true);
$this->router->addRoute($route);
}
public function expectedDuration(): array
{
$parallelChecker = function ($allRequests, $oneRequest) {
self::assertGreaterThan(ExampleController::CONTROLLER_TIME, $oneRequest * 1000);
self::assertLessThan(ExampleController::CONTROLLER_TIME * 4, $allRequests * 1000);
};
return [
[
'http://localhost/test/sessionlock/protected',
function ($allRequests, $oneRequest) {
self::assertGreaterThan(ExampleController::CONTROLLER_TIME, $oneRequest * 1000);
self::assertGreaterThan(ExampleController::CONTROLLER_TIME * 4, $allRequests * 1000);
}
],
[
'http://localhost/test/sessionlock/unprotectedbyannotation',
$parallelChecker
],
[
'http://localhost/test/sessionlock/unprotectedbyconfiguration',
$parallelChecker
]
];
}
/**
* @dataProvider expectedDuration
* @test
*/
public function itDoesNotAllowToEnterMoreThanOneWithTheSameSession(string $url, \Closure $checker): void
{
$request = $this->serverRequestFactory
->createServerRequest('GET', new Uri($url));
$start = microtime(true);
$response = $this->browser->sendRequest($request);
$neededForOne = microtime(true) - $start;
$sessionCookies = array_map(static function ($cookie) {
return Cookie::createFromRawSetCookieHeader($cookie);
}, $response->getHeader('Set-Cookie'));
self::assertNotEmpty($sessionCookies);
$cookies = array_reduce($sessionCookies, static function ($out, $cookie) {
$out[$cookie->getName()] = $cookie->getValue();
return $out;
}, []);
$nextRequest = $this->serverRequestFactory
->createServerRequest('GET', new Uri($url))
->withCookieParams($cookies);
$childs = [];
$start = microtime(true);
for ($i = 0; $i < 4; $i++) {
$child = \pcntl_fork();
if ($child === 0) {
$this->browser->sendRequest($nextRequest);
exit();
}
$childs[] = $child;
}
foreach ($childs as $child) {
\pcntl_waitpid($child, $status);
}
$neededForAll = microtime(true) - $start;
$checker($neededForAll, $neededForOne);
}
}

View file

@ -7,6 +7,9 @@
"php": ">=7.4",
"symfony/lock": "^5.2.0"
},
"require-dev": {
"ext-pcntl": "*"
},
"autoload": {
"psr-4": {
"DigiComp\\FlowSessionLock\\": "Classes/"