Issue #3002352 by longwave, andypost, gabesullice, googletorp, daffie, alexpott, borisson_: CacheableHttpException must pass a $headers argument to HttpException

merge-requests/622/merge
catch 2021-08-05 21:27:51 +01:00
parent bcfecbbfa6
commit 5cd5a9d0ae
3 changed files with 84 additions and 10 deletions

View File

@ -16,15 +16,9 @@ class CacheableHttpException extends HttpException implements CacheableDependenc
/**
* {@inheritdoc}
*/
public function __construct(CacheableDependencyInterface $cacheability, $statusCode = 0, $message = NULL, \Exception $previous = NULL, $code = 0) {
public function __construct(CacheableDependencyInterface $cacheability, $statusCode = 0, $message = NULL, \Exception $previous = NULL, array $headers = [], $code = 0) {
$this->setCacheability($cacheability);
// @todo Remove condition in https://www.drupal.org/node/3002352
if (is_array($code)) {
parent::__construct($statusCode, $message, $previous, $code);
}
else {
parent::__construct($statusCode, $message, $previous, [], $code);
}
parent::__construct($statusCode, $message, $previous, $headers, $code);
}
}

View File

@ -105,7 +105,7 @@ final class ResourceVersionRouteEnhancer implements EnhancerInterface {
$message = 'JSON:API does not yet support resource versioning for this resource type.';
$message .= ' For context, see https://www.drupal.org/project/drupal/issues/2992833#comment-12818258.';
$message .= ' To contribute, see https://www.drupal.org/project/drupal/issues/2350939 and https://www.drupal.org/project/drupal/issues/2809177.';
throw new CacheableHttpException($cacheability, 501, $message, NULL, 0);
throw new CacheableHttpException($cacheability, 501, $message);
}
return $defaults;
}
@ -151,7 +151,7 @@ final class ResourceVersionRouteEnhancer implements EnhancerInterface {
];
$cacheability = (new CacheableMetadata())->addCacheContexts($cache_contexts);
$message = 'JSON:API does not support filtering on revisions other than the latest version because a secure Drupal core API does not yet exist to do so.';
throw new CacheableHttpException($cacheability, 501, $message, NULL, 0);
throw new CacheableHttpException($cacheability, 501, $message);
}
// 'latest-version' and 'working-copy' are the only acceptable version
// identifiers for a collection resource.

View File

@ -0,0 +1,80 @@
<?php
namespace Drupal\Tests\Core\Http;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Http\Exception\CacheableAccessDeniedHttpException;
use Drupal\Core\Http\Exception\CacheableBadRequestHttpException;
use Drupal\Core\Http\Exception\CacheableConflictHttpException;
use Drupal\Core\Http\Exception\CacheableGoneHttpException;
use Drupal\Core\Http\Exception\CacheableHttpException;
use Drupal\Core\Http\Exception\CacheableLengthRequiredHttpException;
use Drupal\Core\Http\Exception\CacheableMethodNotAllowedHttpException;
use Drupal\Core\Http\Exception\CacheableNotAcceptableHttpException;
use Drupal\Core\Http\Exception\CacheableNotFoundHttpException;
use Drupal\Core\Http\Exception\CacheablePreconditionFailedHttpException;
use Drupal\Core\Http\Exception\CacheablePreconditionRequiredHttpException;
use Drupal\Core\Http\Exception\CacheableServiceUnavailableHttpException;
use Drupal\Core\Http\Exception\CacheableTooManyRequestsHttpException;
use Drupal\Core\Http\Exception\CacheableUnauthorizedHttpException;
use Drupal\Core\Http\Exception\CacheableUnprocessableEntityHttpException;
use Drupal\Core\Http\Exception\CacheableUnsupportedMediaTypeHttpException;
use Drupal\Tests\UnitTestCase;
/**
* @group Http
*/
class CacheableExceptionTest extends UnitTestCase {
/**
* @covers \Drupal\Core\Http\Exception\CacheableHttpException
*/
public function testCacheableHttpException() {
$exception = new CacheableHttpException((new CacheableMetadata())->setCacheContexts(['route']), 500, 'test message', NULL, ['X-Drupal-Exception' => 'Test'], 123);
$this->assertSame(['route'], $exception->getCacheContexts());
$this->assertSame(500, $exception->getStatusCode());
$this->assertSame('test message', $exception->getMessage());
$this->assertSame(['X-Drupal-Exception' => 'Test'], $exception->getHeaders());
$this->assertSame(123, $exception->getCode());
}
/**
* @dataProvider providerTestExceptions
*/
public function testExceptions($status_code, $class, $argument = NULL, $expected_headers = []) {
$cacheable_metadata = (new CacheableMetadata())->setCacheContexts(['route']);
$message = "$class test message";
if ($argument) {
$exception = new $class($cacheable_metadata, $argument, $message, NULL, 123);
}
else {
$exception = new $class($cacheable_metadata, $message, NULL, 123);
}
$this->assertSame(['route'], $exception->getCacheContexts());
$this->assertSame($message, $exception->getMessage());
$this->assertSame($status_code, $exception->getStatusCode());
$this->assertSame($expected_headers, $exception->getHeaders());
$this->assertSame(123, $exception->getCode());
}
public function providerTestExceptions() {
return [
[400, CacheableBadRequestHttpException::class],
[401, CacheableUnauthorizedHttpException::class, 'test challenge', ['WWW-Authenticate' => 'test challenge']],
[403, CacheableAccessDeniedHttpException::class],
[404, CacheableNotFoundHttpException::class],
[405, CacheableMethodNotAllowedHttpException::Class, ['POST', 'PUT'], ['Allow' => 'POST, PUT']],
[406, CacheableNotAcceptableHttpException::class],
[409, CacheableConflictHttpException::class],
[410, CacheableGoneHttpException::class],
[411, CacheableLengthRequiredHttpException::class],
[412, CacheablePreconditionFailedHttpException::class],
[415, CacheableUnsupportedMediaTypeHttpException::class],
[422, CacheableUnprocessableEntityHttpException::class],
[428, CacheablePreconditionRequiredHttpException::class],
[429, CacheableTooManyRequestsHttpException::class, 60, ['Retry-After' => 60]],
[503, CacheableServiceUnavailableHttpException::class, 60, ['Retry-After' => 60]],
];
}
}