iteo/tests/App/Service/OrderServiceTest.php
2024-04-14 21:15:42 +02:00

111 lines
3.8 KiB
PHP

<?php
namespace App\Service;
use App\Aggregate\AcceptOrderCommand;
use App\Contract\Order;
use App\Contract\ProductEntry;
use App\Entity\Client;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Uid\Uuid;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class OrderServiceTest extends TestCase
{
private const ORDER_ID = '018eddae-ff52-7813-9f88-ada9e61a76f3';
private const CLIENT_ID = '018edd2e-894a-78d7-b10c-16e05ca933a3';
private function createClient(int $balance): Client
{
return new Client(
clientId: Uuid::fromRfc4122(self::CLIENT_ID),
name: 'Stub',
initialBalance: $balance,
currentBalance: $balance
);
}
private function createValidOrderDto(): Order
{
return new Order(
orderId: Uuid::fromRfc4122(self::ORDER_ID),
clientId: Uuid::fromRfc4122(self::CLIENT_ID),
products: [
new ProductEntry('p1', 1, 100.00, 100),
new ProductEntry('p2', 2, 300.00, 100),
new ProductEntry('p3', 3, 200.00, 100),
new ProductEntry('p4', 4, 400.00, 700),
new ProductEntry('p5', 5, 800.00, 700),
]
);
}
private function createOrderService(
?HttpClientInterface $httpClientMock = null,
?SerializerInterface $serializerMock = null,
?PricingStrategy $pricingStrategyMock = null,
?ClientService $clientServiceMock = null,
) {
$httpClientMock ??= $this->createMock(HttpClientInterface::class);
$serializerMock ??= $this->createMock(SerializerInterface::class);
$pricingStrategyMock ??= $this->createMock(PricingStrategy::class);
$clientServiceMock ??= $this->createMock(ClientService::class);
return new OrderService($httpClientMock, $serializerMock, $pricingStrategyMock, $clientServiceMock);
}
public function testCrmGetsCalledOnValidOrderRequest()
{
$httpClientMock = $this->createMock(HttpClientInterface::class);
$httpClientMock->expects($this->once())->method('request')->with('POST', '/order');
$order = new AcceptOrderCommand(
$this->createValidOrderDto(),
$this->createClient(balance: 100_00)
);
$sut = $this->createOrderService(httpClientMock: $httpClientMock);
$sut->acceptOrder($order);
}
public function testTotalPriceIsDeducedFromClientBalance()
{
$initialBalance = 10000_00;
$price = 6900_00;
$command = new AcceptOrderCommand(
$order = $this->createValidOrderDto(),
$client = $this->createClient($initialBalance),
);
$pricingStrategyMock = $this->createMock(PricingStrategy::class);
$pricingStrategyMock
->expects($this->atLeastOnce())
->method('calculateTotalPriceOfOrder')
->with($order)
->willReturn($price);
$sut = $this->createOrderService(pricingStrategyMock: $pricingStrategyMock);
$sut->acceptOrder($command);
$this->assertEquals($initialBalance, $client->getInitialBalance(), 'Initial balance got changed after placing order');
$this->assertEquals($initialBalance - $price, $client->getBalance(), 'Current balance not changed after placing order');
}
public function testClientIsUpdatedAfterPlacingOrder()
{
$command = new AcceptOrderCommand(
$this->createValidOrderDto(),
$client = $this->createClient(10000_00),
);
$clientServiceMock = $this->createMock(ClientService::class);
$clientServiceMock->expects($this->once())->method('save')->with($client);
$sut = $this->createOrderService(clientServiceMock: $clientServiceMock);
$sut->acceptOrder($command);
}
}