type = new ArticleType('Notebook'); } public function test_new_article_has_ingesting_status(): 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 test_valid_status_transition(): 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 test_invalid_status_transition_throws(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $this->expectException(\DomainException::class); $article->transitionTo(ArticleStatus::Sold); } public function test_decrement_stock(): 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 test_decrement_to_zero_marks_out_of_stock(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 1, ArticleCondition::Good); $article->decrementStock(); $this->assertTrue($article->isOutOfStock()); } public function test_decrement_below_zero_throws(): void { $article = new Article($this->type, 'NB-001', 'INV-001', 0, ArticleCondition::Good); $this->expectException(\DomainException::class); $article->decrementStock(); } }