Skip to content

Commit

Permalink
Merge pull request #3038 from alanpoulain/merge-2.4
Browse files Browse the repository at this point in the history
Merge 2.4 into master
  • Loading branch information
teohhanhui committed Sep 5, 2019
2 parents 6e9ccf7 + b0cd959 commit 5245c1a
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 14 deletions.
2 changes: 1 addition & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ parameters:
# Real problems, hard to fix
- '#Parameter \#2 \$dqlPart of method Doctrine\\ORM\\QueryBuilder::add\(\) expects array\|object, string given\.#'
-
message: '#Return type \(int\) of method ApiPlatform\\Core\\Identifier\\Normalizer\\IntegerDenormalizer::denormalize\(\) should be compatible with return type \(object\) of method Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::denormalize\(\)#'
message: '#Return type \(int\) of method ApiPlatform\\Core\\Identifier\\Normalizer\\IntegerDenormalizer::denormalize\(\) should be compatible with return type \(array\|object\) of method Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::denormalize\(\)#'
path: %currentWorkingDirectory%/src/Identifier/Normalizer/IntegerDenormalizer.php

# False positives
Expand Down
3 changes: 1 addition & 2 deletions src/Bridge/Doctrine/Orm/CollectionDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\Exception\RuntimeException;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\EntityManagerInterface;

/**
Expand Down Expand Up @@ -56,7 +55,7 @@ public function supports(string $resourceClass, string $operationName = null, ar
*/
public function getCollection(string $resourceClass, string $operationName = null, array $context = [])
{
/** @var ObjectManager $manager */
/** @var EntityManagerInterface $manager */
$manager = $this->managerRegistry->getManagerForClass($resourceClass);

$repository = $manager->getRepository($resourceClass);
Expand Down
7 changes: 6 additions & 1 deletion src/Bridge/Elasticsearch/DataProvider/ItemDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ public function getItem(string $resourceClass, $id, ?string $operationName = nul
return null;
}

return $this->denormalizer->denormalize($document, $resourceClass, ItemNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true]);
$item = $this->denormalizer->denormalize($document, $resourceClass, ItemNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true]);
if (!\is_object($item) && null !== $item) {
throw new \UnexpectedValueException('Expected item to be an object or null.');
}

return $item;
}
}
2 changes: 1 addition & 1 deletion src/Bridge/Symfony/Bundle/Resources/config/test.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="test.api_platform.client" class="ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client" public="true">
<service id="test.api_platform.client" class="ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client" shared="false" public="true">
<argument type="service" id="test.client" />
</service>
</services>
Expand Down
8 changes: 6 additions & 2 deletions src/Bridge/Symfony/Bundle/Test/ApiTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ abstract class ApiTestCase extends KernelTestCase
{
use ApiTestAssertionsTrait;

protected function doTearDown(): void
/**
* {@inheritdoc}
*/
protected function tearDown(): void
{
parent::doTearDown();
parent::tearDown();

self::getClient(null);
}

Expand Down
30 changes: 27 additions & 3 deletions src/Bridge/Symfony/Bundle/Test/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@ public function request(string $method, string $url, array $options = []): Respo
$basic = $options['auth_basic'] ?? null;
[$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions);
$resolvedUrl = implode('', $url);

$server = [];

// Convert headers to a $_SERVER-like array
foreach ($options['headers'] as $key => $value) {
foreach (self::extractHeaders($options) as $key => $value) {
if ('content-type' === $key) {
$server['CONTENT_TYPE'] = $value[0] ?? '';

continue;
}

// BrowserKit doesn't support setting several headers with the same name
$server['HTTP_'.strtoupper(str_replace('-', '_', $key))] = $value[0] ?? '';
$server['HTTP_'.strtoupper(strtr($key, '-', '_'))] = $value[0] ?? '';
}

if ($basic) {
Expand Down Expand Up @@ -212,4 +212,28 @@ public function enableReboot(): void
{
$this->kernelBrowser->enableReboot();
}

/**
* Extracts headers depending on the symfony/http-client version being used.
*
* @return array<string, string[]>
*/
private static function extractHeaders(array $options): array
{
if (!isset($options['normalized_headers'])) {
return $options['headers'];
}

$headers = [];

/** @var string $key */
foreach ($options['normalized_headers'] as $key => $values) {
foreach ($values as $value) {
[, $value] = explode(': ', $value, 2);
$headers[$key][] = $value;
}
}

return $headers;
}
}
2 changes: 1 addition & 1 deletion src/Bridge/Symfony/Bundle/Test/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public function __construct(HttpFoundationResponse $httpFoundationResponse, Brow
}
}

$this->content = $httpFoundationResponse->getContent();
$this->content = (string) $httpFoundationResponse->getContent();
$this->info = [
'http_code' => $httpFoundationResponse->getStatusCode(),
'error' => null,
Expand Down
8 changes: 7 additions & 1 deletion src/GraphQl/Resolver/Stage/DeserializeStage.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ public function __invoke($objectToPopulate, string $resourceClass, string $opera
$denormalizationContext[AbstractNormalizer::OBJECT_TO_POPULATE] = $objectToPopulate;
}

return $this->denormalizer->denormalize($context['args']['input'], $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);
$item = $this->denormalizer->denormalize($context['args']['input'], $resourceClass, ItemNormalizer::FORMAT, $denormalizationContext);

if (!\is_object($item)) {
throw new \UnexpectedValueException('Expected item to be an object.');
}

return $item;
}
}
2 changes: 1 addition & 1 deletion src/HttpCache/EventListener/AddHeadersListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function onKernelResponse(FilterResponseEvent $event): void
}

if ($this->etag && !$response->getEtag()) {
$response->setEtag(md5($response->getContent()));
$response->setEtag(md5((string) $response->getContent()));
}

if (null !== ($maxAge = $resourceCacheHeaders['max_age'] ?? $this->maxAge) && !$response->headers->hasCacheControlDirective('max-age')) {
Expand Down
10 changes: 9 additions & 1 deletion src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ public function denormalize($data, $class, $format = null, array $context = [])
throw new LogicException('Cannot denormalize the input because the injected serializer is not a denormalizer');
}
$denormalizedInput = $this->serializer->denormalize($data, $inputClass, $format, $context);
if (!\is_object($denormalizedInput)) {
throw new \UnexpectedValueException('Expected denormalized input to be an object.');
}

return $dataTransformer->transform($denormalizedInput, $resourceClass, $dataTransformerContext);
}
Expand Down Expand Up @@ -437,7 +440,12 @@ protected function denormalizeRelation(string $attributeName, PropertyMetadata $
}

try {
return $this->serializer->denormalize($value, $className, $format, $context);
$item = $this->serializer->denormalize($value, $className, $format, $context);
if (!\is_object($item) && null !== $item) {
throw new \UnexpectedValueException('Expected item to be an object or null.');
}

return $item;
} catch (InvalidValueException $e) {
if (!$supportsPlainIdentifiers) {
throw $e;
Expand Down
60 changes: 60 additions & 0 deletions tests/Fixtures/TestBundle/BrowserKit/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Core\Tests\Fixtures\TestBundle\BrowserKit;

use Symfony\Bundle\FrameworkBundle\Client as BaseClient;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\BrowserKit\Request as DomRequest;
use Symfony\Component\HttpFoundation\Request;

if (class_exists(AbstractBrowser::class)) {
class Client extends KernelBrowser
{
/**
* {@inheritdoc}
*/
protected function filterRequest(DomRequest $request): Request
{
$request = parent::filterRequest($request);

foreach ($request->headers->all() as $key => $value) {
if ([null] === $value) {
$request->headers->remove($key);
}
}

return $request;
}
}
} else {
class Client extends BaseClient
{
/**
* {@inheritdoc}
*/
protected function filterRequest(DomRequest $request): Request
{
$request = parent::filterRequest($request);

foreach ($request->headers->all() as $key => $value) {
if ([null] === $value) {
$request->headers->remove($key);
}
}

return $request;
}
}
}
10 changes: 10 additions & 0 deletions tests/Fixtures/app/config/config_common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@ parameters:
container.dumper.inline_class_loader: true

services:
test.client:
class: ApiPlatform\Core\Tests\Fixtures\TestBundle\BrowserKit\Client
shared: false
public: true
arguments:
- '@kernel'
- '%test.client.parameters%'
- '@test.client.history'
- '@test.client.cookiejar'

ApiPlatform\Core\Tests\Fixtures\TestBundle\MessageHandler\:
resource: '../../TestBundle/MessageHandler'
autowire: true
Expand Down

0 comments on commit 5245c1a

Please sign in to comment.