Skip to content

Commit

Permalink
feat: Updates PHP version, refactor models, add event emission and ot…
Browse files Browse the repository at this point in the history
…her adjustments.
  • Loading branch information
gustavofreze committed Feb 25, 2024
1 parent 787f2cf commit 7599ecb
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment;

use CheapDelivery\Application\Handlers\CalculateShipmentHandler;
use CheapDelivery\Application\Ports\Inbound\CommandHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TinyBlocks\Http\HttpResponse;

final readonly class CalculateShipment implements RequestHandlerInterface
{
public function __construct(private CalculateShipmentHandler $useCase)
public function __construct(private CalculateShipmentHandler|CommandHandler $useCase)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Test\Integration\Query\Shipment;
namespace Test\Integration\Query\Shipment\Factories;

use Doctrine\DBAL\Connection;
use Psr\Container\ContainerInterface;
Expand Down
23 changes: 23 additions & 0 deletions tests/Integration/Query/Shipment/Factories/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Test\Integration\Query\Shipment\Factories;

use Psr\Http\Message\ServerRequestInterface;
use Slim\Psr7\Headers;
use Slim\Psr7\Request as SlimRequest;
use Slim\Psr7\Stream;
use Slim\Psr7\Uri;

final class Request
{
public static function getFrom(array $parameters): ServerRequestInterface
{
$stream = fopen('php://memory', 'r+');

$uri = new Uri('https', 'cheap-delivery.localhost', null, '/', http_build_query($parameters));
$body = new Stream($stream);
$headers = new Headers(['Content-Type' => 'application/json']);

return new SlimRequest('GET', $uri, $headers, [], [], $body);
}
}
20 changes: 4 additions & 16 deletions tests/Integration/Query/Shipment/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace Test\Integration\Query\Shipment;

use CheapDelivery\Query\Shipment\Resource;
use Psr\Http\Message\ServerRequestInterface;
use Test\Integration\IntegrationTestCapabilities;
use Test\Integration\Query\Shipment\Factories\IsoDate;
use Test\Integration\Query\Shipment\Factories\QueryAdapter;
use Test\Integration\Query\Shipment\Factories\Request;

final class ResourceTest extends IntegrationTestCapabilities
{
Expand Down Expand Up @@ -50,7 +51,7 @@ public function testFindShipmentsWithoutFilters(): void
$this->query->saveShipments(shipments: $shipments);

/** @And I have a request to fetch the persisted shipments without filters */
$request = $this->requestWith(parameters: []);
$request = Request::getFrom(parameters: []);

/** @When I make the request */
$response = $this->resource->handle(request: $request);
Expand Down Expand Up @@ -88,7 +89,7 @@ public function testFindShipmentsWithFilters(): void
$this->query->saveShipments(shipments: $shipments);

/** @And I have a request to fetch the persisted shipments with filters */
$request = $this->requestWith(parameters: ['carrierName' => 'DHL']);
$request = Request::getFrom(parameters: ['carrierName' => 'DHL']);

/** @When I make the request */
$response = $this->resource->handle(request: $request);
Expand All @@ -102,17 +103,4 @@ public function testFindShipmentsWithFilters(): void
self::assertEquals($shipments[0]['carrier'], $actual[0]['carrier']);
self::assertEquals($shipments[0]['createdAt'], $actual[0]['createdAt']);
}

private function requestWith(array $parameters): ServerRequestInterface
{
$request = $this->getMockBuilder(ServerRequestInterface::class)
->disableOriginalConstructor()
->getMock();

$request->expects(self::once())
->method('getQueryParams')
->willReturn($parameters);

return $request;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment;

use CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Factories\Request;
use CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Mocks\CalculateShipmentHandlerMock;
use CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Mocks\Exceptions;
use CheapDelivery\Driver\Http\Middlewares\ErrorHandling;
use PHPUnit\Framework\TestCase;
use TinyBlocks\Http\HttpCode;

class CalculateShipmentExceptionHandlerTest extends TestCase
{
private CalculateShipment $endpoint;

private ErrorHandling $middleware;

protected function setUp(): void
{
$useCase = new CalculateShipmentHandlerMock();
$this->endpoint = new CalculateShipment(useCase: $useCase);
$exceptionHandler = new CalculateShipmentExceptionHandler();
$this->middleware = new ErrorHandling(exceptionHandler: $exceptionHandler);
}

public function testExceptionWhenNoEligibleCarriers(): void
{
/** @Given that I have data to calculate a shipment */
$payload = [
'person' => [
'name' => 'Gustavo',
'distance' => Exceptions::NO_ELIGIBLE_CARRIERS
],
'product' => [
'name' => 'Notebook',
'weight' => 1.0
]
];

/** @And that I use this data in the request */
$request = Request::postFrom(payload: $payload);

/** @When I process the request with this handler */
$actual = $this->middleware->process(request: $request, handler: $this->endpoint);

/** @Then the response should be an error indicating no eligible carriers */
$expected = ['error' => 'There are no eligible carriers for the shipment.'];

self::assertEquals(HttpCode::BAD_REQUEST->value, $actual->getStatusCode());
self::assertEquals(json_encode($expected), $actual->getBody()->__toString());
}

public function testExceptionWhenNoCarriersAvailable(): void
{
/** @Given that I have data to calculate a shipment */
$payload = [
'person' => [
'name' => 'Gustavo',
'distance' => Exceptions::NO_CARRIERS_AVAILABLE
],
'product' => [
'name' => 'Notebook',
'weight' => 1.0
]
];

/** @And that I use this data in the request */
$request = Request::postFrom(payload: $payload);

/** @When I process the request with this handler */
$actual = $this->middleware->process(request: $request, handler: $this->endpoint);

/** @Then the response should be an error indicating no carriers available */
$expected = ['error' => 'No carriers available for shipment.'];

self::assertEquals(HttpCode::NOT_FOUND->value, $actual->getStatusCode());
self::assertEquals(json_encode($expected), $actual->getBody()->__toString());
}

public function testExceptionWhenUnknownError(): void
{
/** @Given that I have data to calculate a shipment */
$payload = [
'person' => [
'name' => 'Gustavo',
'distance' => Exceptions::UNKNOWN_ERROR
],
'product' => [
'name' => 'Notebook',
'weight' => 1.0
]
];

/** @And that I use this data in the request */
$request = Request::postFrom(payload: $payload);

/** @When I process the request with this handler */
$actual = $this->middleware->process(request: $request, handler: $this->endpoint);

/** @Then the response should be an error indicating error */
$expected = ['error' => 'Any error.'];

self::assertEquals(HttpCode::INTERNAL_SERVER_ERROR->value, $actual->getStatusCode());
self::assertEquals(json_encode($expected), $actual->getBody()->__toString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment;

use CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Factories\Request;
use CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Mocks\CalculateShipmentHandlerMock;
use PHPUnit\Framework\TestCase;
use TinyBlocks\Http\HttpCode;

class CalculateShipmentTest extends TestCase
{
private CalculateShipment $endpoint;

private CalculateShipmentHandlerMock $useCase;

protected function setUp(): void
{
$this->useCase = new CalculateShipmentHandlerMock();
$this->endpoint = new CalculateShipment(useCase: $this->useCase);
}

public function testCalculateShipment(): void
{
/** @Given that I have data to calculate a shipment */
$payload = [
'person' => [
'name' => 'Gustavo',
'distance' => 100.0
],
'product' => [
'name' => 'Notebook',
'weight' => 1.0
]
];

/** @And that I use this data in the request */
$request = Request::postFrom(payload: $payload);

/** @When I execute the request */
$actual = $this->endpoint->handle(request: $request);

/** @Then the request should be successful */
self::assertEquals(HttpCode::NO_CONTENT->value, $actual->getStatusCode());

/** @And a command should be registered */
$person = $this->useCase->lastCommand->person;
$product = $this->useCase->lastCommand->product;

self::assertEquals($payload['person']['name'], $person->name->value);
self::assertEquals($payload['person']['distance'], $person->distance->value);
self::assertEquals($payload['product']['name'], $product->name->value);
self::assertEquals($payload['product']['weight'], $product->weight->value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Factories;

use Psr\Http\Message\ServerRequestInterface;
use Slim\Psr7\Headers;
use Slim\Psr7\Request as SlimRequest;
use Slim\Psr7\Stream;
use Slim\Psr7\Uri;

final class Request
{
public static function postFrom(array $payload): ServerRequestInterface
{
$encode = json_encode($payload);
$stream = fopen('php://memory', 'r+');

fwrite($stream, $encode);
rewind($stream);

$uri = new Uri('https', 'cheap-delivery.localhost');
$body = new Stream($stream);
$headers = new Headers(['Content-Type' => 'application/json']);

return new SlimRequest('POST', $uri, $headers, [], [], $body);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Mocks;

use CheapDelivery\Application\Commands\CalculateShipment;
use CheapDelivery\Application\Commands\Command;
use CheapDelivery\Application\Domain\Exceptions\NoCarriersAvailable;
use CheapDelivery\Application\Domain\Exceptions\NoEligibleCarriers;
use CheapDelivery\Application\Ports\Inbound\CommandHandler;
use RuntimeException;

final class CalculateShipmentHandlerMock implements CommandHandler
{
public CalculateShipment $lastCommand;

public function handle(Command|CalculateShipment $command): void
{
$this->lastCommand = $command;

match ($command->person->distance->value) {
Exceptions::UNKNOWN_ERROR => throw new RuntimeException('Any error.'),
Exceptions::NO_ELIGIBLE_CARRIERS => throw new NoEligibleCarriers(),
Exceptions::NO_CARRIERS_AVAILABLE => throw new NoCarriersAvailable(),
default => null
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace CheapDelivery\Driver\Http\Endpoints\CalculateShipment\Mocks;

final class Exceptions
{
public const UNKNOWN_ERROR = 100000.00;
public const NO_ELIGIBLE_CARRIERS = 200000.00;
public const NO_CARRIERS_AVAILABLE = 300000.00;
}

0 comments on commit 7599ecb

Please sign in to comment.