From ad79d1370fc961dd37529531f52453a583ac2fa0 Mon Sep 17 00:00:00 2001 From: 3m5/frohberg Date: Tue, 22 Oct 2024 18:01:20 +0200 Subject: [PATCH] TASK: Add tests for CorsHeaderMiddleware.php --- Classes/Http/CorsHeaderMiddleware.php | 4 +- Tests/Unit/Http/CorsHeaderMiddlewareTest.php | 117 +++++++++++++++++++ composer.json | 3 + 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 Tests/Unit/Http/CorsHeaderMiddlewareTest.php diff --git a/Classes/Http/CorsHeaderMiddleware.php b/Classes/Http/CorsHeaderMiddleware.php index e333fa8..9e81ddd 100644 --- a/Classes/Http/CorsHeaderMiddleware.php +++ b/Classes/Http/CorsHeaderMiddleware.php @@ -4,6 +4,7 @@ namespace Flowpack\Cors\Http; +use GuzzleHttp\Psr7\MessageTrait; use Neos\Flow\Annotations as Flow; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -126,10 +127,11 @@ private function initializeConfiguration(): void private function handlePreflight(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { $headersToAdd = []; - /* + /** * Always set Vary headers, see * https://github.com/rs/cors/issues/10 and * https://github.com/rs/cors/commit/dbdca4d95feaa7511a46e6f1efb3b3aa505bc43f#commitcomment-12352001 + * @var MessageTrait $response */ $response = $response->withHeader( 'Vary', ['Origin', 'Access-Control-Request-Method', 'Access-Control-Request-Headers'] diff --git a/Tests/Unit/Http/CorsHeaderMiddlewareTest.php b/Tests/Unit/Http/CorsHeaderMiddlewareTest.php new file mode 100644 index 0000000..d56f400 --- /dev/null +++ b/Tests/Unit/Http/CorsHeaderMiddlewareTest.php @@ -0,0 +1,117 @@ +middleware = new CorsHeaderMiddleware(); + $this->mockRequest = $this->createMock(ServerRequestInterface::class); + $this->mockResponse = $this->createMock(ResponseInterface::class); + $this->mockHandler = $this->createMock(RequestHandlerInterface::class); + $this->logger = $this->createMock(LoggerInterface::class); + $this->response = new Response(); + + ObjectAccess::setProperty($this->middleware, 'enabled', true, true); + ObjectAccess::setProperty($this->middleware, 'logger', $this->logger, true); + } + + private function injectConfiguration(): void + { + ObjectAccess::setProperty( + $this->middleware, + 'allowedOrigins', + [ + 0 => 'https://google.com', + ], + true + ); + ObjectAccess::setProperty( + $this->middleware, + 'allowedMethods', + [ + 0 => 'GET', + 1 => 'POST', + ], + true + ); + } + + + public function testMiddlewareIsNotEnabled(): void + { + $this->mockHandler->expects($this->once())->method('handle')->willReturn($this->response); + + ObjectAccess::setProperty($this->middleware, 'enabled', false, true); + $response = $this->middleware->process($this->mockRequest, $this->mockHandler); + + $this->assertSame($response->getHeader('Access-Control-Allow-Origin'), []); + $this->assertSame($response->getHeader('Access-Control-Allow-Methods'), []); + $this->assertSame($response->getHeader('Access-Control-Allow-Headers'), []); + $this->assertSame($response->getHeader('Access-Control-Allow-Credentials'), []); + $this->assertSame($response->getHeader('Access-Control-Max-Age'), []); + } + + public function testMiddlewarePreflightWithConfig(): void + { + $this->injectConfiguration(); + $this->mockHandler->expects($this->once())->method('handle')->willReturn($this->response); + $this->mockRequest->expects($this->once())->method('getMethod')->willReturn('OPTIONS'); + $this->mockRequest->expects($this->any())->method('getHeader')->willReturnCallback(function (string $value) { + return match($value) { + 'Origin' => ['https://google.com'], + 'Access-Control-Request-Method' => ['GET'], + 'Access-Control-Request-Headers' => [], + }; + }); + + $response = $this->middleware->process($this->mockRequest, $this->mockHandler); + $this->assertCount(3, $response->getHeaders()); + $this->assertSame($response->getHeader('Vary'), [ + 0 => 'Origin', + 1 => 'Access-Control-Request-Method', + 2 => 'Access-Control-Request-Headers', + ]); + $this->assertSame($response->getHeader('Access-Control-Allow-Origin'), ['https://google.com']); + $this->assertSame($response->getHeader('Access-Control-Allow-Methods'), ['GET']); + } + + public function testMiddlewareActualRequestWithConfig(): void + { + $this->injectConfiguration(); + $this->mockHandler->expects($this->once())->method('handle')->willReturn($this->response); + $this->mockRequest->expects($this->any())->method('getMethod')->willReturn('POST'); + $this->mockRequest->expects($this->any())->method('getHeader')->willReturnCallback(function (string $value) { + return match($value) { + 'Origin' => ['https://google.com'], + 'Access-Control-Request-Method' => ['GET'], + 'Access-Control-Request-Headers' => [], + }; + }); + $response = $this->middleware->process($this->mockRequest, $this->mockHandler); + $this->assertCount(3, $response->getHeaders()); + $this->assertSame($response->getHeader('Access-Control-Allow-Credentials'), ['true']); + $this->assertSame($response->getHeader('Vary'), ['Origin']); + $this->assertSame($response->getHeader('Access-Control-Allow-Origin'), ['https://google.com']); + } +} diff --git a/composer.json b/composer.json index be5f7f9..1aee3dd 100644 --- a/composer.json +++ b/composer.json @@ -21,5 +21,8 @@ "allow-plugins": { "neos/composer-plugin": true } + }, + "require-dev": { + "phpunit/phpunit": "^11.4" } }