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 fa9ca6a commit 787f2cf
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 21 deletions.
2 changes: 0 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ LABEL author="Gustavo Freze" \

ARG FLYWAY_VERSION=10.8.1

RUN docker-php-ext-install pdo_mysql

RUN apk --no-cache add tar curl mysql-client openjdk21-jre \
&& mkdir -p /opt/flyway \
&& curl -L "https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/${FLYWAY_VERSION}/flyway-commandline-${FLYWAY_VERSION}-linux-x64.tar.gz" | tar -xz --strip-components=1 -C /opt/flyway \
Expand Down
21 changes: 13 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,29 @@ IMAGE = gustavofreze/php:8.2
DOCKER_RUN = docker run -u root --rm -it --net=host -v ${PWD}:/app -w /app ${IMAGE}
DOCKER_EXEC = docker exec -it cheap-delivery

INTEGRATION_TEST = docker run -u root --rm -it --name cheap-delivery-integration-test --link cheap-delivery-adm --network=cheap-delivery_default -v ${PWD}:/app -w /app ${IMAGE}

FLYWAY = docker run --rm -v ${PWD}/db/mysql/migrations:/flyway/sql --env-file=config/local.env --link cheap-delivery-adm --network=cheap-delivery_default -e FLYWAY_EDITION="community" flyway/flyway:10.8.1
MIGRATE_DB = ${FLYWAY} -locations=filesystem:/flyway/sql -schemas=cheap_delivery_adm

.PHONY: configure run test test-no-coverage review fix-style show-coverage clean migrate-database clean-database
MIGRATE_TEST_DB = ${FLYWAY} -locations=filesystem:/flyway/sql -schemas=cheap_delivery_adm_test

configure:
@docker-compose up -d --build

configure-local:
@${DOCKER_RUN} composer update --optimize-autoloader

test:
@${DOCKER_RUN} composer run tests
test: migrate-test-database
@${INTEGRATION_TEST} composer run tests

test-no-coverage:
@${DOCKER_RUN} composer run test-no-coverage
test-no-coverage: migrate-test-database
@${INTEGRATION_TEST} composer run test-no-coverage

test-unit:
@${DOCKER_RUN} composer run test-unit

test-integration:
@${DOCKER_RUN} composer run test-integration
test-integration: migrate-test-database
@${INTEGRATION_TEST} composer run test-integration

review:
@${DOCKER_RUN} composer review
Expand All @@ -43,3 +44,7 @@ migrate-database:

clean-database:
@${MIGRATE_DB} clean

migrate-test-database:
@${MIGRATE_TEST_DB} clean
@${MIGRATE_TEST_DB} migrate
6 changes: 2 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@
},
"autoload-dev": {
"psr-4": {
"CheapDelivery\\": [
"tests/Unit/",
"tests/Integration/"
]
"Test\\": "tests/",
"CheapDelivery\\": "tests/Unit/"
}
},
"require": {
Expand Down
19 changes: 14 additions & 5 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
colors="true"
bootstrap="tests/bootstrap.php"
backupGlobals="false"
colors="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
executionOrder="default"
cacheResultFile="report/.phpunit.result.cache"
processIsolation="false"
backupStaticProperties="false">

<testsuites>
Expand All @@ -26,9 +27,17 @@
<directory suffix=".php">src</directory>
</include>
<exclude>
<file>src/routes.php</file>
<file>src/bootstrap.php</file>
<file>src/Routes.php</file>
<file>src/Dependencies.php</file>
</exclude>
</source>

<php>
<env name="MYSQL_DATABASE_HOST" value="cheap-delivery-adm"/>
<env name="MYSQL_DATABASE_PORT" value="3306"/>
<env name="MYSQL_DATABASE_NAME" value="cheap_delivery_adm_test"/>
<env name="MYSQL_DATABASE_USER" value="root"/>
<env name="MYSQL_DATABASE_PASSWORD" value="root"/>
</php>

</phpunit>
3 changes: 2 additions & 1 deletion src/Query/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@

final class QueryBuilder extends DoctrineQueryBuilder
{
private const AND_WHERE = '%s = :%';
private const AND_WHERE = '%s = :%s';

public function applyFilters(Filters $filters): QueryBuilder
{
foreach ($filters->toArray() as $column => $value) {
$this->andWhere(sprintf(self::AND_WHERE, $column, $column))->setParameter($column, $value);
}

return $this;
}
}
2 changes: 1 addition & 1 deletion src/Query/Shipment/Database/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static function from(array $shipments): array
'carrier' => [
'name' => $shipment['carrierName']
],
'createdAt' => $shipment['createdAt']
'createdAt' => date('c', strtotime($shipment['createdAt']))
];

return array_map(fn(array $shipment) => $mapper(shipment: $shipment), $shipments);
Expand Down
1 change: 1 addition & 0 deletions src/Query/Shipment/Database/Facade.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function findAll(ShipmentFilters $filters): array
])
->from('shipment')
->applyFilters($filters)
->orderBy('created_at', 'DESC')
->executeQuery()
->fetchAllAssociative();

Expand Down
18 changes: 18 additions & 0 deletions tests/Integration/IntegrationTestCapabilities.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace Test\Integration;

use CheapDelivery\Dependencies;
use DI\Container;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;

abstract class IntegrationTestCapabilities extends TestCase
{
protected static ContainerInterface $container;

public static function setUpBeforeClass(): void
{
self::$container = new Container(Dependencies::definitions());
}
}
25 changes: 25 additions & 0 deletions tests/Integration/Query/Shipment/Factories/IsoDate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Test\Integration\Query\Shipment\Factories;

use DateInterval;
use DateTime;

final class IsoDate extends DateTime
{
public static function now(): IsoDate
{
return new IsoDate('now');
}

public function subtract(string $duration): IsoDate
{
$this->sub(new DateInterval($duration));
return $this;
}

public function toString(): string
{
return $this->format('c');
}
}
38 changes: 38 additions & 0 deletions tests/Integration/Query/Shipment/QueryAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Test\Integration\Query\Shipment;

use Doctrine\DBAL\Connection;
use Psr\Container\ContainerInterface;

final readonly class QueryAdapter
{
private const INSERT_SHIPMENT = '
INSERT INTO shipment (id, cost, carrier_name, created_at)
VALUES (UUID_TO_BIN(:id), :cost, :carrierName, :createdAt);';

protected Connection $connection;

public function __construct(ContainerInterface $container)
{
$this->connection = $container->get(Connection::class);
$this->connection->beginTransaction();
}

public function saveShipments(array $shipments): void
{
foreach ($shipments as $shipment) {
$this->connection->executeStatement(self::INSERT_SHIPMENT, [
'id' => $shipment['id'],
'cost' => $shipment['cost'],
'createdAt' => $shipment['createdAt'],
'carrierName' => $shipment['carrier']['name']
]);
}
}

public function rollBack(): void
{
$this->connection->rollBack();
}
}
118 changes: 118 additions & 0 deletions tests/Integration/Query/Shipment/ResourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

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;

final class ResourceTest extends IntegrationTestCapabilities
{
private Resource $resource;

private QueryAdapter $query;

protected function setUp(): void
{
$this->query = new QueryAdapter(self::$container);
$this->resource = self::$container->get(Resource::class);
}

protected function tearDown(): void
{
$this->query->rollBack();
}

public function testFindShipmentsWithoutFilters(): void
{
/** @Given I have some shipments */
$shipments = [
[
'id' => '03ec1cfc-5546-45ae-925d-eb36211965d9',
'cost' => floatval(rand(100, 150)),
'carrier' => [
'name' => 'DHL'
],
'createdAt' => IsoDate::now()->toString()
],
[
'id' => '9a33a5f5-3d4b-4777-afa7-fbdadd9620d3',
'cost' => floatval(rand(100, 150)),
'carrier' => [
'name' => 'FedEx'
],
'createdAt' => IsoDate::now()->subtract(duration: 'PT10M')->toString()
]
];

/** @And these shipments are persisted */
$this->query->saveShipments(shipments: $shipments);

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

/** @When I make the request */
$response = $this->resource->handle(request: $request);

/** @Then the shipments should be returned */
$actual = json_decode($response->getBody()->__toString(), true);

self::assertCount(2, $actual);
self::assertEquals($shipments, $actual);
}

public function testFindShipmentsWithFilters(): void
{
/** @Given I have some shipments */
$shipments = [
[
'id' => 'ca83b7f1-4d54-4447-85a1-6cfb59122899',
'cost' => floatval(rand(100, 150)),
'carrier' => [
'name' => 'DHL'
],
'createdAt' => IsoDate::now()->toString()
],
[
'id' => '73440f3c-2d29-42dd-9094-130d04e98712',
'cost' => floatval(rand(100, 150)),
'carrier' => [
'name' => 'FedEx'
],
'createdAt' => IsoDate::now()->toString()
]
];

/** @And these shipments are persisted */
$this->query->saveShipments(shipments: $shipments);

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

/** @When I make the request */
$response = $this->resource->handle(request: $request);

/** @Then the shipments should be returned */
$actual = json_decode($response->getBody()->__toString(), true);

self::assertCount(1, $actual);
self::assertEquals($shipments[0]['id'], $actual[0]['id']);
self::assertEquals($shipments[0]['cost'], $actual[0]['cost']);
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;
}
}

0 comments on commit 787f2cf

Please sign in to comment.