Step 00 — Squelette + intégration naïve
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
This commit is contained in:
97
tests/Unit/Invoicing/Domain/InvoiceTest.php
Normal file
97
tests/Unit/Invoicing/Domain/InvoiceTest.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MiniShop\Tests\Unit\Invoicing\Domain;
|
||||
|
||||
use MiniShop\Invoicing\Domain\Event\InvoiceIssued;
|
||||
use MiniShop\Invoicing\Domain\Model\BillingParty;
|
||||
use MiniShop\Invoicing\Domain\Model\Invoice;
|
||||
use MiniShop\Invoicing\Domain\Model\InvoiceId;
|
||||
use MiniShop\Invoicing\Domain\Model\InvoiceLine;
|
||||
use MiniShop\Invoicing\Domain\Model\InvoiceStatus;
|
||||
use MiniShop\Invoicing\Domain\Model\TaxRate;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class InvoiceTest extends TestCase
|
||||
{
|
||||
public function test_issue_invoice_for_external_order(): void
|
||||
{
|
||||
$invoice = $this->issueInvoice();
|
||||
|
||||
self::assertSame(InvoiceStatus::Issued, $invoice->status());
|
||||
self::assertSame('ext-order-1', $invoice->externalOrderId);
|
||||
self::assertCount(1, $invoice->lines());
|
||||
}
|
||||
|
||||
public function test_issue_invoice_records_event(): void
|
||||
{
|
||||
$invoice = $this->issueInvoice();
|
||||
|
||||
$events = $invoice->releaseEvents();
|
||||
self::assertCount(1, $events);
|
||||
self::assertInstanceOf(InvoiceIssued::class, $events[0]);
|
||||
}
|
||||
|
||||
public function test_invoice_without_lines_throws(): void
|
||||
{
|
||||
$this->expectException(\DomainException::class);
|
||||
|
||||
Invoice::issueForExternalOrder(
|
||||
InvoiceId::fromString('inv-1'),
|
||||
'INV-000001',
|
||||
'ext-order-1',
|
||||
new BillingParty('Acme', '1 Rue Test'),
|
||||
[],
|
||||
new \DateTimeImmutable(),
|
||||
);
|
||||
}
|
||||
|
||||
public function test_total_coherent_with_lines(): void
|
||||
{
|
||||
$invoice = Invoice::issueForExternalOrder(
|
||||
InvoiceId::fromString('inv-1'),
|
||||
'INV-000001',
|
||||
'ext-order-1',
|
||||
new BillingParty('Acme', '1 Rue Test'),
|
||||
[
|
||||
new InvoiceLine('Widget', 2, 1000, 'EUR', TaxRate::standard()),
|
||||
new InvoiceLine('Gadget', 1, 2500, 'EUR', TaxRate::standard()),
|
||||
],
|
||||
new \DateTimeImmutable(),
|
||||
);
|
||||
|
||||
self::assertSame(4500, $invoice->totalExclTax());
|
||||
self::assertSame(5400, $invoice->totalInclTax());
|
||||
}
|
||||
|
||||
public function test_mark_as_sent(): void
|
||||
{
|
||||
$invoice = $this->issueInvoice();
|
||||
|
||||
$invoice->markAsSent();
|
||||
|
||||
self::assertSame(InvoiceStatus::Sent, $invoice->status());
|
||||
}
|
||||
|
||||
public function test_mark_as_sent_twice_throws(): void
|
||||
{
|
||||
$this->expectException(\DomainException::class);
|
||||
|
||||
$invoice = $this->issueInvoice();
|
||||
$invoice->markAsSent();
|
||||
$invoice->markAsSent();
|
||||
}
|
||||
|
||||
private function issueInvoice(): Invoice
|
||||
{
|
||||
return Invoice::issueForExternalOrder(
|
||||
InvoiceId::fromString('inv-1'),
|
||||
'INV-000001',
|
||||
'ext-order-1',
|
||||
new BillingParty('Acme', '1 Rue Test'),
|
||||
[new InvoiceLine('Widget', 2, 1500, 'EUR', TaxRate::standard())],
|
||||
new \DateTimeImmutable(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user