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

ORC-400: Add headers checks to existing composer behat package #20

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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@
/.idea/
/package-lock.json
.DS_Store
/phpunit.xml
/phpcs.xml
/phpstan.neon
/coverage
10 changes: 10 additions & 0 deletions .infrastructure/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ARG from_image

FROM $from_image

ENV XDEBUG_MODE=off

RUN apk add --no-cache bash linux-headers $PHPIZE_DEPS \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& curl --silent https://getcomposer.org/composer-stable.phar -o /usr/bin/composer && chmod a+x /usr/bin/composer
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"code-style": "./vendor/bin/phpcs",
"code-style-fix": "./vendor/bin/phpcbf",
"phpunit": "./vendor/bin/phpunit",
"phpunit-html-coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html=coverage",
"dev-checks": [
"composer validate",
"@phpstan",
Expand Down
14 changes: 14 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3.9'

services:
php80:
build:
context: .infrastructure
dockerfile: docker/Dockerfile
args:
from_image: php:8.0-fpm-alpine
working_dir: /app
environment:
PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/app/vendor/bin"
volumes:
- ./:/app
6 changes: 4 additions & 2 deletions src/Context/ApiContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

use Behat\Behat\Context\Context;
use Behat\Gherkin\Node\PyStringNode;
use BehatApiContext\Service\StringManager;
use BehatApiContext\Service\ResetManager\ResetManagerInterface;
use BehatApiContext\Service\StringManager;
use RuntimeException;
use SimilarArrays\SimilarArray;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -136,7 +136,7 @@

if (Request::METHOD_GET === $method) {
$queryString = http_build_query($this->requestParams);
} elseif (Request::METHOD_POST === $method || Request::METHOD_PATCH === $method || Request::METHOD_PUT === $method) {
} elseif (in_array($method, [Request::METHOD_POST, Request::METHOD_PATCH, Request::METHOD_PUT], true)) {

Check warning on line 139 in src/Context/ApiContext.php

View check run for this annotation

Codecov / codecov/patch

src/Context/ApiContext.php#L139

Added line #L139 was not covered by tests
$postFields = $this->requestParams;
}

Expand Down Expand Up @@ -374,7 +374,9 @@
$command = substr(trim($value), 1, -1);

try {
// phpcs:disable
$resultValue = eval('return ' . $command . ';');
// phpcs:enable
} catch (Throwable $exception) {
throw new RuntimeException(
sprintf(
Expand Down
41 changes: 41 additions & 0 deletions tests/Unit/Context/AbstractApiContextTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace BehatApiContext\Tests\Unit\Context;

use BehatApiContext\Context\ApiContext;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\RouterInterface;

abstract class AbstractApiContextTest extends TestCase
{
protected ApiContext $apiContext;

protected function setUp(): void
{
parent::setUp();

/** @var RequestStack $requestStackMock */
$requestStackMock = $this->createMock(RequestStack::class);
$this->apiContext = new ApiContext($this->configureRouter(), $requestStackMock, $this->getKernelMock());
}

protected function configureRouter(): RouterInterface
{
/** @var RouterInterface $routerMock */
$routerMock = $this->createMock(RouterInterface::class);

return $routerMock;
}

protected function getKernelMock(): KernelInterface
{
$kernel = $this->createMock(KernelInterface::class);
assert($kernel instanceof KernelInterface);

return $kernel;
}
}
55 changes: 20 additions & 35 deletions tests/Unit/Context/ApiContextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,12 @@
namespace BehatApiContext\Tests\Unit\Context;

use Behat\Gherkin\Node\PyStringNode;
use BehatApiContext\Context\ApiContext;
use PHPUnit\Framework\TestCase;
use RuntimeException;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\RouterInterface;

class ApiContextTest extends TestCase
class ApiContextTest extends AbstractApiContextTest
{
private const PARAMS_VALUES = 'paramsValues';
private const INITIAL_PARAM_VALUE = 'initialParamValue';
private ApiContext $apiContext;

protected function setUp(): void
{
$routerMock = $this->createMock(RouterInterface::class);
$requestStackMock = $this->createMock(RequestStack::class);
$kernelMock = $this->createMock(KernelInterface::class);

$this->apiContext = new ApiContext($routerMock, $requestStackMock, $kernelMock);
}

/**
* @param PyStringNode $paramsValues
Expand All @@ -47,40 +32,40 @@ public function testTheRequestContainsParamsSuccess(PyStringNode $paramsValues,

$this->assertEquals(
10,
strlen((string)$this->apiContext->geRequestParams()['dateFrom'])
strlen((string)$this->apiContext->geRequestParams()['dateFrom']),
);
$this->assertEquals(
10,
strlen((string)$this->apiContext->geRequestParams()['levelOne']['dateFrom'])
strlen((string)$this->apiContext->geRequestParams()['levelOne']['dateFrom']),
);
$this->assertEquals(
10,
strlen((string)$this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateFrom'])
strlen((string)$this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateFrom']),
);

$this->assertTrue(
str_contains(
$paramsValues->getStrings()[1],
$this->apiContext->geRequestParams()['tripId']
)
$this->apiContext->geRequestParams()['tripId'],
),
);
$this->assertTrue(
str_contains(
$paramsValues->getStrings()[2],
strval($this->apiContext->geRequestParams()['dateTo'])
)
strval($this->apiContext->geRequestParams()['dateTo']),
),
);
$this->assertTrue(
str_contains(
$paramsValues->getStrings()[5],
strval($this->apiContext->geRequestParams()['levelOne']['dateTo'])
)
strval($this->apiContext->geRequestParams()['levelOne']['dateTo']),
),
);
$this->assertTrue(
str_contains(
$paramsValues->getStrings()[8],
strval($this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateTo'])
)
strval($this->apiContext->geRequestParams()['levelOne']['levelTwo']['dateTo']),
),
);
}

Expand Down Expand Up @@ -115,7 +100,7 @@ public function getTheRequestContainsParamsSuccess(): array
' }',
'}',
],
12
12,
),
self::INITIAL_PARAM_VALUE => '<(new DateTimeImmutable())->getTimestamp()>',
],
Expand All @@ -134,8 +119,8 @@ public function getTheRequestContainsParamsRuntimeException(): array
' "dateFrom": "<(new DateTimeImutable())->getTimestamp()>"',
'}',
],
12
)
12,
),
],
[
self::PARAMS_VALUES => new PyStringNode(
Expand All @@ -146,8 +131,8 @@ public function getTheRequestContainsParamsRuntimeException(): array
' "dateFrom": "<(DateTimeImmutable)->getTimestamp()>"',
'}',
],
12
)
12,
),
],
[
self::PARAMS_VALUES => new PyStringNode(
Expand All @@ -162,7 +147,7 @@ public function getTheRequestContainsParamsRuntimeException(): array
' }',
'}',
],
12
12,
),
],
[
Expand All @@ -174,8 +159,8 @@ public function getTheRequestContainsParamsRuntimeException(): array
' "dateFrom": "<>"',
'}',
],
12
)
12,
),
],
];
}
Expand Down
66 changes: 66 additions & 0 deletions tests/Unit/Context/GivenApiContextsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace BehatApiContext\Tests\Unit\Context;

use Behat\Gherkin\Node\PyStringNode;
use ReflectionClass;
use ReflectionException;

final class GivenApiContextsTest extends AbstractApiContextTest
{
/**
* @throws ReflectionException
*/
public function testGivenHeader(): void
{
$reflectionClass = new ReflectionClass($this->apiContext);
$headersProp = $reflectionClass->getProperty('headers');
$headersProp->setAccessible(true);

$this->assertEmpty($headersProp->getValue($this->apiContext));

$this->apiContext->theRequestHeaderContains('key', 'value');

$this->assertNotEmpty($headersProp->getValue($this->apiContext));

$headersProp->setAccessible(false);
}

/**
* @throws ReflectionException
*/
public function testGivenMultilineHeader(): void
{
$reflectionClass = new ReflectionClass($this->apiContext);
$headersProp = $reflectionClass->getProperty('headers');
$headersProp->setAccessible(true);

$this->assertEmpty($headersProp->getValue($this->apiContext));

$this->apiContext->theRequestHeaderContainsMultiline('key', new PyStringNode(['value', 'value'], 2));

$this->assertNotEmpty($headersProp->getValue($this->apiContext));

$headersProp->setAccessible(false);
}

public function testGivenIps(): void
{
$reflectionClass = new ReflectionClass($this->apiContext);
$serverParamsProp = $reflectionClass->getProperty('serverParams');
$serverParamsProp->setAccessible(true);

$params = $serverParamsProp->getValue($this->apiContext);
$this->assertIsArray($params);
$this->assertArrayNotHasKey('REMOTE_ADDR', $params);

$this->apiContext->theRequestIpIs('10.10.10.10');

$params = $serverParamsProp->getValue($this->apiContext);
$this->assertIsArray($params);
$this->assertArrayHasKey('REMOTE_ADDR', $params);
$this->assertEquals('10.10.10.10', $params['REMOTE_ADDR']);
}
}
60 changes: 60 additions & 0 deletions tests/Unit/Context/InitApiContextsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace BehatApiContext\Tests\Unit\Context;

use BehatApiContext\Service\ResetManager\ResetManagerInterface;
use ReflectionClass;
use ReflectionException;

final class InitApiContextsTest extends AbstractApiContextTest
{
/**
* @throws ReflectionException
*/
public function testInitBefore(): void
{
$reflectionClass = new ReflectionClass($this->apiContext);
$savedValuesProp = $reflectionClass->getProperty('savedValues');
$savedValuesProp->setAccessible(true);
$headersProp = $reflectionClass->getProperty('headers');
$headersProp->setAccessible(true);
$serverParamsProp = $reflectionClass->getProperty('serverParams');
$serverParamsProp->setAccessible(true);
$requestParamsProp = $reflectionClass->getProperty('requestParams');
$requestParamsProp->setAccessible(true);

$savedValuesProp->setValue($this->apiContext, ['key' => 'value']);
$headersProp->setValue($this->apiContext, ['key' => 'value']);
$serverParamsProp->setValue($this->apiContext, ['key' => 'value']);
$requestParamsProp->setValue($this->apiContext, ['key' => 'value']);

$this->assertNotEmpty($savedValuesProp->getValue($this->apiContext));
$this->assertNotEmpty($headersProp->getValue($this->apiContext));
$this->assertNotEmpty($serverParamsProp->getValue($this->apiContext));
$this->assertNotEmpty($requestParamsProp->getValue($this->apiContext));

$this->apiContext->beforeScenario();
$this->assertEmpty($savedValuesProp->getValue($this->apiContext));
$this->assertEmpty($headersProp->getValue($this->apiContext));
$this->assertEmpty($serverParamsProp->getValue($this->apiContext));
$this->assertEmpty($requestParamsProp->getValue($this->apiContext));
}

public function testAddResetManager(): void
{
/** @var ResetManagerInterface $resetManager */
$resetManager = $this->createMock(ResetManagerInterface::class);

$reflectionClass = new ReflectionClass($this->apiContext);
$resetManagersProp = $reflectionClass->getProperty('resetManagers');
$resetManagersProp->setAccessible(true);

$this->assertEmpty($resetManagersProp->getValue($this->apiContext));

$this->apiContext->addKernelResetManager($resetManager);

$this->assertNotEmpty($resetManagersProp->getValue($this->apiContext));
}
}
Loading
Loading