createMock(BookingStatusRuleInterface::class); $rule->method('evaluate')->willReturn(false); $rule->method('getPriority')->willReturn(100); $registry = new BookingStatusRuleRegistry([$rule]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('F', $registry->evaluateStatus($bookingDto)); } public function testReturnsMatchingRuleStatus(): void { $rule = $this->createMock(BookingStatusRuleInterface::class); $rule->method('evaluate')->willReturn(true); $rule->method('getStatus')->willReturn('O'); $rule->method('getPriority')->willReturn(100); $registry = new BookingStatusRuleRegistry([$rule]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('O', $registry->evaluateStatus($bookingDto)); } public function testHigherPriorityRuleTakesPrecedence(): void { $lowPriorityRule = $this->createMock(BookingStatusRuleInterface::class); $lowPriorityRule->method('evaluate')->willReturn(true); $lowPriorityRule->method('getStatus')->willReturn('L'); $lowPriorityRule->method('getPriority')->willReturn(50); $highPriorityRule = $this->createMock(BookingStatusRuleInterface::class); $highPriorityRule->method('evaluate')->willReturn(true); $highPriorityRule->method('getStatus')->willReturn('H'); $highPriorityRule->method('getPriority')->willReturn(100); $registry = new BookingStatusRuleRegistry([$lowPriorityRule, $highPriorityRule]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('H', $registry->evaluateStatus($bookingDto)); } public function testEmptyRulesArrayReturnsDefaultStatus(): void { $registry = new BookingStatusRuleRegistry([]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('F', $registry->evaluateStatus($bookingDto)); } public function testFirstMatchingRuleWinsForSamePriority(): void { $firstMatchingRule = $this->createMock(BookingStatusRuleInterface::class); $firstMatchingRule->method('evaluate')->willReturn(true); $firstMatchingRule->method('getStatus')->willReturn('A'); $firstMatchingRule->method('getPriority')->willReturn(100); $secondMatchingRule = $this->createMock(BookingStatusRuleInterface::class); $secondMatchingRule->method('evaluate')->willReturn(true); $secondMatchingRule->method('getStatus')->willReturn('B'); $secondMatchingRule->method('getPriority')->willReturn(100); $registry = new BookingStatusRuleRegistry([$firstMatchingRule, $secondMatchingRule]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('A', $registry->evaluateStatus($bookingDto)); } public function testNonMatchingHighPriorityRuleDoesNotBlockLowerPriority(): void { $highPriorityRule = $this->createMock(BookingStatusRuleInterface::class); $highPriorityRule->method('evaluate')->willReturn(false); $highPriorityRule->method('getStatus')->willReturn('H'); $highPriorityRule->method('getPriority')->willReturn(100); $lowPriorityRule = $this->createMock(BookingStatusRuleInterface::class); $lowPriorityRule->method('evaluate')->willReturn(true); $lowPriorityRule->method('getStatus')->willReturn('L'); $lowPriorityRule->method('getPriority')->willReturn(50); $registry = new BookingStatusRuleRegistry([$highPriorityRule, $lowPriorityRule]); $bookingDto = new BookingDto($this->createMockTravel(), 1); $this->assertSame('L', $registry->evaluateStatus($bookingDto)); } private function createMockTravel(): \App\BusProNet\Model\Travel { $travel = new \App\BusProNet\Model\Travel(); $travel->id = 1; $travel->hotelId = 1; $travel->dateFrom = new \DateTimeImmutable('2030-01-01'); $travel->dateTo = new \DateTimeImmutable('2030-01-08'); return $travel; } }