3 Bounded Contexts (Sales, Invoicing, LegacyFulfillment) avec : - Domaines complets (agrégats, VOs, événements, invariants) - Couche application (commands, queries, ports) - Infrastructure in-memory (repos, gateway fake) - Controllers HTTP Symfony - Couplage naïf synchrone entre BC via NaiveSalesEventPublisher - 20 tests unitaires et d'intégration passants
89 lines
3.8 KiB
PHP
89 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MiniShop\Tests\Integration;
|
|
|
|
use MiniShop\Invoicing\Application\Command\IssueInvoiceForExternalOrderHandler;
|
|
use MiniShop\Invoicing\Infrastructure\Persistence\InMemoryInvoiceRepository;
|
|
use MiniShop\Invoicing\Infrastructure\SequentialInvoiceNumberGenerator;
|
|
use MiniShop\LegacyFulfillment\Application\Command\RequestShipmentFromSalesOrderHandler;
|
|
use MiniShop\LegacyFulfillment\Domain\Model\LegacyOrderRef;
|
|
use MiniShop\LegacyFulfillment\Domain\Model\ShipmentStatus;
|
|
use MiniShop\LegacyFulfillment\Infrastructure\Gateway\FakeLegacyFulfillmentGateway;
|
|
use MiniShop\LegacyFulfillment\Infrastructure\Persistence\InMemoryShipmentRequestRepository;
|
|
use MiniShop\Sales\Application\Command\ConfirmOrder;
|
|
use MiniShop\Sales\Application\Command\ConfirmOrderHandler;
|
|
use MiniShop\Sales\Application\Command\PlaceOrder;
|
|
use MiniShop\Sales\Application\Command\PlaceOrderHandler;
|
|
use MiniShop\Sales\Domain\Model\OrderId;
|
|
use MiniShop\Sales\Domain\Model\OrderStatus;
|
|
use MiniShop\Sales\Infrastructure\Messaging\NaiveSalesEventPublisher;
|
|
use MiniShop\Sales\Infrastructure\Persistence\InMemoryOrderRepository;
|
|
use MiniShop\Shared\Technical\SystemClock;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Test d'integration naif : PlaceOrder -> ConfirmOrder -> Invoice + Shipment.
|
|
* Illustre le couplage direct entre BC (episode 00).
|
|
*/
|
|
final class NaiveWorkflowTest extends TestCase
|
|
{
|
|
public function test_full_naive_workflow(): void
|
|
{
|
|
// --- Setup : cablage naif synchrone ---
|
|
$clock = new SystemClock();
|
|
$orderRepo = new InMemoryOrderRepository();
|
|
$invoiceRepo = new InMemoryInvoiceRepository();
|
|
$shipmentRepo = new InMemoryShipmentRequestRepository();
|
|
$gateway = new FakeLegacyFulfillmentGateway();
|
|
|
|
$issueInvoiceHandler = new IssueInvoiceForExternalOrderHandler(
|
|
$invoiceRepo,
|
|
new SequentialInvoiceNumberGenerator(),
|
|
$clock,
|
|
);
|
|
$requestShipmentHandler = new RequestShipmentFromSalesOrderHandler(
|
|
$shipmentRepo,
|
|
$gateway,
|
|
$clock,
|
|
);
|
|
$publisher = new NaiveSalesEventPublisher($issueInvoiceHandler, $requestShipmentHandler);
|
|
|
|
$placeOrderHandler = new PlaceOrderHandler($orderRepo, $publisher, $clock);
|
|
$confirmOrderHandler = new ConfirmOrderHandler($orderRepo, $publisher);
|
|
|
|
$orderId = 'test-order-001';
|
|
|
|
// --- Act : passer et confirmer une commande ---
|
|
($placeOrderHandler)(new PlaceOrder(
|
|
orderId: $orderId,
|
|
customerId: 'cust-001',
|
|
lines: [
|
|
['productName' => 'Widget', 'quantity' => 2, 'unitPriceInCents' => 1500, 'currency' => 'EUR'],
|
|
['productName' => 'Gadget', 'quantity' => 1, 'unitPriceInCents' => 2500, 'currency' => 'EUR'],
|
|
],
|
|
));
|
|
|
|
($confirmOrderHandler)(new ConfirmOrder(orderId: $orderId));
|
|
|
|
// --- Assert : ordre confirme ---
|
|
$order = $orderRepo->get(OrderId::fromString($orderId));
|
|
self::assertSame(OrderStatus::Confirmed, $order->status());
|
|
|
|
// --- Assert : facture creee ---
|
|
$invoice = $invoiceRepo->findByExternalOrderId($orderId);
|
|
self::assertNotNull($invoice, 'An invoice should have been created for the confirmed order.');
|
|
self::assertSame($orderId, $invoice->externalOrderId);
|
|
self::assertCount(2, $invoice->lines());
|
|
|
|
// --- Assert : expedition demandee ---
|
|
$shipment = $shipmentRepo->findByOrderRef(LegacyOrderRef::fromExternalId($orderId));
|
|
self::assertNotNull($shipment, 'A shipment request should have been created.');
|
|
self::assertSame(ShipmentStatus::Requested, $shipment->status());
|
|
|
|
// --- Assert : gateway legacy appele ---
|
|
self::assertCount(1, $gateway->sentRequests());
|
|
}
|
|
}
|