Skip to content

Commit

Permalink
Added Deprecated middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
freost committed Aug 29, 2024
1 parent 0366f4c commit 33195c7
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The major version bump is due to upping the required PHP version from `8.1` to `
* It is now possible to customize how JSON request bodies are decoded using the following methods:
- `Body::setJsonMaxDepth()` to set the maximum JSON nesting level.
- `Body::setJsonFlags()` to set the JSON decoding options.
* Added `Deprecated` middleware that allows you to easily set the `Deprecation` and `Sunset` HTTP headers.

#### Improvements

Expand Down
65 changes: 65 additions & 0 deletions src/mako/http/routing/middleware/Deprecated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* @copyright Frederic G. Østby
* @license http://www.makoframework.com/license
*/

namespace mako\http\routing\middleware;

use Closure;
use DateTime;
use DateTimeInterface;
use mako\http\Request;
use mako\http\Response;
use RuntimeException;

class Deprecated implements MiddlewareInterface
{
/**
* Deprecation date.
*/
protected null|DateTimeInterface $deprecationDate = null;

/**
* Sunset date.
*/
protected null|DateTimeInterface $sunsetDate = null;

/**
* Constructor.
*/
public function __construct(null|DateTimeInterface|string $deprecationDate = null, null|DateTimeInterface|string $sunsetDate = null)
{
if ($deprecationDate === null && $sunsetDate === null) {
throw new RuntimeException('You must specify either a deprecation date or a sunset date or both.');
}

if ($deprecationDate !== null) {
$this->deprecationDate = $deprecationDate instanceof DateTimeInterface ? $deprecationDate : new DateTime($deprecationDate);
}

if ($sunsetDate !== null) {
$this->sunsetDate = $sunsetDate instanceof DateTimeInterface ? $sunsetDate : new DateTime($sunsetDate);
}

if ($deprecationDate !== null && $sunsetDate !== null && $this->deprecationDate->getTimestamp() >= $this->sunsetDate->getTimestamp()) {
throw new RuntimeException('The deprecation date must be earlier than the sunset date.');
}
}
/**
* {@inheritDoc}
*/
public function execute(Request $request, Response $response, Closure $next): Response
{
if ($this->deprecationDate !== null) {
$response->headers->add('Deprecation', "@{$this->deprecationDate->getTimestamp()}");
}

if ($this->sunsetDate !== null) {
$response->headers->add('Sunset', $this->sunsetDate->format(DateTime::RFC7231));
}

return $next($request, $response);
}
}
119 changes: 119 additions & 0 deletions tests/unit/http/routing/middleware/DeprecatedTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

/**
* @copyright Frederic G. Østby
* @license http://www.makoframework.com/license
*/

namespace mako\tests\unit\http\routing\middleware;

use mako\http\Request;
use mako\http\Response;
use mako\http\response\Headers;
use mako\http\routing\middleware\Deprecated;
use mako\tests\TestCase;
use Mockery;

/**
* @group unit
*/
class DeprecatedTest extends TestCase
{
/**
*
*/
public function testConstructorWithoutArgs(): void
{
$this->expectExceptionMessage('You must specify either a deprecation date or a sunset date or both.');

new Deprecated;
}

/**
*
*/
public function testConstructorWithSunsetBeforeDeprecation(): void
{
$this->expectExceptionMessage('The deprecation date must be earlier than the sunset date.');

new Deprecated('2021-02-01', '2020-01-01');
}

/**
*
*/
public function testDeprecatedWithDeprecationDate(): void
{
$middleware = new Deprecated('2021-02-01');

/** @var \mako\http\Request|\Mockery\MockInterface $request */
$request = Mockery::mock(Request::class);

/** @var \mako\http\Response|\Mockery\MockInterface $response */
$response = Mockery::mock(Response::class);

/** @var \mako\http\response\Headers|\Mockery\MockInterface $headers */
$headers = Mockery::mock(Headers::class);

(function () use ($headers): void {
$this->headers = $headers;
})->bindTo($response, Response::class)();

$headers->shouldReceive('add')->once()->with('Deprecation', '@1612137600');

$middleware->execute($request, $response, fn ($request, $response) => $response);

}

/**
*
*/
public function testDeprecatedWithSunsetDate(): void
{
$middleware = new Deprecated(null, '2021-02-01');

/** @var \mako\http\Request|\Mockery\MockInterface $request */
$request = Mockery::mock(Request::class);

/** @var \mako\http\Response|\Mockery\MockInterface $response */
$response = Mockery::mock(Response::class);

/** @var \mako\http\response\Headers|\Mockery\MockInterface $headers */
$headers = Mockery::mock(Headers::class);

(function () use ($headers): void {
$this->headers = $headers;
})->bindTo($response, Response::class)();

$headers->shouldReceive('add')->once()->with('Sunset', 'Mon, 01 Feb 2021 00:00:00 GMT');

$middleware->execute($request, $response, fn ($request, $response) => $response);
}

/**
*
*/
public function testDeprecatedWithDeprecationAndSunsetDate(): void
{
$middleware = new Deprecated('2020-01-01', '2021-02-01');

/** @var \mako\http\Request|\Mockery\MockInterface $request */
$request = Mockery::mock(Request::class);

/** @var \mako\http\Response|\Mockery\MockInterface $response */
$response = Mockery::mock(Response::class);

/** @var \mako\http\response\Headers|\Mockery\MockInterface $headers */
$headers = Mockery::mock(Headers::class);

(function () use ($headers): void {
$this->headers = $headers;
})->bindTo($response, Response::class)();

$headers->shouldReceive('add')->once()->with('Deprecation', '@1577836800');

$headers->shouldReceive('add')->once()->with('Sunset', 'Mon, 01 Feb 2021 00:00:00 GMT');

$middleware->execute($request, $response, fn ($request, $response) => $response);
}
}

0 comments on commit 33195c7

Please sign in to comment.