type = new ArticleType('Notebook'); } public function testNewArticleHasIngestingStatus(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $this->assertSame(ArticleStatus::Ingesting, $article->getStatus()); $this->assertSame(1, $article->getStock()); } public function testValidStatusTransition(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $article->transitionTo(ArticleStatus::Draft); $this->assertSame(ArticleStatus::Draft, $article->getStatus()); } public function testInvalidStatusTransitionThrows(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $this->expectException(\DomainException::class); $article->transitionTo(ArticleStatus::Sold); } public function testDecrementStock(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 3, ArticleCondition::Good); $article->decrementStock(); $this->assertSame(2, $article->getStock()); $this->assertFalse($article->isOutOfStock()); } public function testDecrementToZeroMarksOutOfStock(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $article->decrementStock(); $this->assertTrue($article->isOutOfStock()); } public function testDecrementBelowZeroThrows(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 0, ArticleCondition::Good); $this->expectException(\DomainException::class); $article->decrementStock(); } }