2026-05-14 04:28:06 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace App\Tests\Unit\Domain\Article;
|
|
|
|
|
|
|
|
|
|
use App\Domain\Article\Article;
|
|
|
|
|
use App\Domain\Article\ArticleCondition;
|
|
|
|
|
use App\Domain\Article\ArticleStatus;
|
|
|
|
|
use App\Domain\Article\ArticleType;
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
|
|
final class ArticleTest extends TestCase
|
|
|
|
|
{
|
|
|
|
|
private ArticleType $type;
|
|
|
|
|
|
|
|
|
|
protected function setUp(): void
|
|
|
|
|
{
|
|
|
|
|
$this->type = new ArticleType('Notebook');
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testNewArticleHasIngestingStatus(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good);
|
|
|
|
|
|
|
|
|
|
$this->assertSame(ArticleStatus::Ingesting, $article->getStatus());
|
|
|
|
|
$this->assertSame(1, $article->getStock());
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testValidStatusTransition(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good);
|
|
|
|
|
$article->transitionTo(ArticleStatus::Draft);
|
|
|
|
|
|
|
|
|
|
$this->assertSame(ArticleStatus::Draft, $article->getStatus());
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testInvalidStatusTransitionThrows(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good);
|
|
|
|
|
|
|
|
|
|
$this->expectException(\DomainException::class);
|
|
|
|
|
$article->transitionTo(ArticleStatus::Sold);
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testDecrementStock(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 3, ArticleCondition::Good);
|
|
|
|
|
$article->decrementStock();
|
|
|
|
|
|
|
|
|
|
$this->assertSame(2, $article->getStock());
|
|
|
|
|
$this->assertFalse($article->isOutOfStock());
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testDecrementToZeroMarksOutOfStock(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good);
|
|
|
|
|
$article->decrementStock();
|
|
|
|
|
|
|
|
|
|
$this->assertTrue($article->isOutOfStock());
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-17 22:44:16 +00:00
|
|
|
public function testDecrementBelowZeroThrows(): void
|
2026-05-14 04:28:06 +00:00
|
|
|
{
|
|
|
|
|
$article = new Article($this->type, 'NB-001', 'INV-001', 0, ArticleCondition::Good);
|
|
|
|
|
|
|
|
|
|
$this->expectException(\DomainException::class);
|
|
|
|
|
$article->decrementStock();
|
|
|
|
|
}
|
|
|
|
|
}
|