Skip to content
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: 2 additions & 2 deletions Classes/Exception/OperationNotAllowedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class OperationNotAllowedException extends AbstractException implements OpenApiS
public static function getOpenApiResponse(): OpenApiResponse
{
return parent::getOpenApiResponse()
->statusCode(SymfonyResponse::HTTP_NOT_FOUND)
->description(self::translate('exception.resource_not_found.title'));
->statusCode(SymfonyResponse::HTTP_FORBIDDEN)
->description(self::translate('exception.operation_not_allowed.title'));
}

public function __construct(OperationInterface $operation, int $code)
Expand Down
1 change: 1 addition & 0 deletions Documentation/Miscellaneous/Changelog/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Changelog

5.0.0
=====
- OpenAPI specification documents ``403 Forbidden`` (instead of ``404 Not Found``) for operations with ``security`` or ``security_post_denormalize``, the same status as returned by the API.
- [!!!] A new file reference created by ``uidLocal`` requires ``fileToken`` returned for the file by the API, otherwise ``400 Bad Request`` is returned. The same applies to a new file of a property of type ``File`` or a class extending it (``{"uid": 101, "fileToken": "..."}``). The token is returned in the response of upload endpoints and of operations with ``"fileTokens"=true`` in ``normalizationContext`` (files offered for selection, ``file.fileToken`` for file references). Pass ``fileToken`` when saving a reference. Custom upload code has to grant tokens with ``FileTokenService::grant()``. See :ref:`handling_file_upload_file_token`.
- Invalid values of file and file reference properties (e.g. a text or a boolean instead of an identifier or an object) return ``400 Bad Request`` instead of HTTP 500 or clearing the property.
- Files (classes extending Extbase's ``File``) nested in a response (e.g. members of a collection) are serialized like other objects, the same as in an item response, instead of the file reference output.
Expand Down
53 changes: 53 additions & 0 deletions Tests/Unit/Exception/OpenApiSupportingExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace SourceBroker\T3api\Tests\Unit\Exception;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use SourceBroker\T3api\Exception\AbstractException;
use SourceBroker\T3api\Exception\BadRequestException;
use SourceBroker\T3api\Exception\InvalidPaginationParameterException;
use SourceBroker\T3api\Exception\OpenApiSupportingExceptionInterface;
use SourceBroker\T3api\Exception\OperationNotAllowedException;
use SourceBroker\T3api\Exception\OriginNotAllowedException;
use SourceBroker\T3api\Exception\ResourceNotFoundException;
use SourceBroker\T3api\Exception\UnsupportedMediaTypeException;
use SourceBroker\T3api\Exception\ValidationException;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

class OpenApiSupportingExceptionTest extends UnitTestCase
{
// translation of the response description creates `Locales` singleton
protected bool $resetSingletonInstances = true;

/**
* @return array<string, array{class-string<AbstractException&OpenApiSupportingExceptionInterface>}>
*/
public static function exceptionClassDataProvider(): array
{
return [
'BadRequestException' => [BadRequestException::class],
'InvalidPaginationParameterException' => [InvalidPaginationParameterException::class],
'OperationNotAllowedException' => [OperationNotAllowedException::class],
'OriginNotAllowedException' => [OriginNotAllowedException::class],
'ResourceNotFoundException' => [ResourceNotFoundException::class],
'UnsupportedMediaTypeException' => [UnsupportedMediaTypeException::class],
'ValidationException' => [ValidationException::class],
];
}

/**
* @param class-string<AbstractException&OpenApiSupportingExceptionInterface> $exceptionClass
*/
#[Test]
#[DataProvider('exceptionClassDataProvider')]
public function openApiResponseHasStatusCodeOfException(string $exceptionClass): void
{
// `getStatusCode()` does not depend on constructor arguments
$exception = (new \ReflectionClass($exceptionClass))->newInstanceWithoutConstructor();

self::assertSame($exception->getStatusCode(), $exceptionClass::getOpenApiResponse()->statusCode);
}
}
Loading