Skip to content

Commit

Permalink
feat: add http error middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
ksassnowski committed Apr 4, 2024
1 parent 80f250b commit f937d89
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/Downloader/Middleware/HttpErrorMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2024 Kai Sassnowski
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @see https://github.com/roach-php/roach
*/

namespace RoachPHP\Downloader\Middleware;

use Psr\Log\LoggerInterface;
use RoachPHP\Http\Response;
use RoachPHP\Support\Configurable;

final class HttpErrorMiddleware implements ResponseMiddlewareInterface
{
use Configurable;

public function __construct(private readonly LoggerInterface $logger)
{
}

public function handleResponse(Response $response): Response
{
$status = $response->getStatus();

if (200 <= $status && 300 > $status) {
return $response;
}

/** @var array<int, int> $allowedStatus */
$allowedStatus = $this->option('handleStatus');

if (\in_array($status, $allowedStatus, true)) {
return $response;
}

$this->logger->info(
'[HttpErrorMiddleware] Dropping unsuccessful response',
[
'uri' => $response->getRequest()->getUri(),
'status' => $status,
],
);

return $response->drop('Unallowed HTTP status: ' . $status);
}

private function defaultOptions(): array
{
return [
'handleStatus' => [],
];
}
}
179 changes: 179 additions & 0 deletions tests/Downloader/Middleware/HttpErrorMiddlewareTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2024 Kai Sassnowski
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*
* @see https://github.com/roach-php/roach
*/

namespace RoachPHP\Tests\Downloader\Middleware;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use RoachPHP\Downloader\Middleware\HttpErrorMiddleware;
use RoachPHP\Testing\Concerns\InteractsWithRequestsAndResponses;
use RoachPHP\Testing\FakeLogger;

/**
* @internal
*/
final class HttpErrorMiddlewareTest extends TestCase
{
use InteractsWithRequestsAndResponses;

private HttpErrorMiddleware $middleware;

private FakeLogger $logger;

protected function setUp(): void
{
$this->logger = new FakeLogger();
$this->middleware = new HttpErrorMiddleware($this->logger);
}

public static function successfulHTTPStatus(): \Generator
{
yield from [
[200],
[201],
[202],
[203],
[204],
[205],
[206],
[207],
[208],
];
}

public static function unsuccessfulHTTPStatus(): \Generator
{
yield from [
[100],
[101],
[102],
[103],
[300],
[301],
[302],
[303],
[304],
[305],
[306],
[307],
[308],
[400],
[401],
[402],
[403],
[404],
[405],
[406],
[407],
[408],
[409],
[410],
[411],
[412],
[413],
[414],
[415],
[416],
[417],
[418],
[421],
[422],
[423],
[424],
[425],
[426],
[428],
[429],
[431],
[451],
[500],
[501],
[502],
[503],
[504],
[505],
[506],
[507],
[508],
[510],
[511],
];
}

#[DataProvider('successfulHTTPStatus')]
public function testAllowResponseWithSuccessfulHTTPStatus(int $status): void
{
$response = $this->makeResponse(status: $status);
$this->middleware->configure([]);

$result = $this->middleware->handleResponse($response);

self::assertSame($result, $response);
self::assertFalse($result->wasDropped());
}

#[DataProvider('unsuccessfulHTTPStatus')]
public function testDropResponseWithNonSuccessfulHTTPStatus(int $status): void
{
$response = $this->makeResponse(status: $status);
$this->middleware->configure([]);

$result = $this->middleware->handleResponse($response);

self::assertNotSame($result, $response);
self::assertTrue($result->wasDropped());
}

public function testLogDroppedResponses(): void
{
$request = $this->makeRequest('https://example.com');
$response = $this->makeResponse(request: $request, status: 400);
$this->middleware->configure([]);

$this->middleware->handleResponse($response);

self::assertTrue(
$this->logger->messageWasLogged(
'info',
'[HttpErrorMiddleware] Dropping unsuccessful response',
['uri' => 'https://example.com', 'status' => 400],
),
);
}

public function testDontLogAllowedResponses(): void
{
$response = $this->makeResponse(status: 200);
$this->middleware->configure([]);

$this->middleware->handleResponse($response);

self::assertFalse(
$this->logger->messageWasLogged(
'info',
'[AllowedHttpStatusMiddleware] Dropping response with unallowed HTTP status',
),
);
}

public function testAllowResponsesWithCustomAllowedStatuses(): void
{
$response = $this->makeResponse(status: 404);
$this->middleware->configure(['handleStatus' => [404]]);

$result = $this->middleware->handleResponse($response);

self::assertSame($result, $response);
self::assertFalse($result->wasDropped());
}
}

0 comments on commit f937d89

Please sign in to comment.