createStub(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->createStub(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->createStub(BookingStatusRuleInterface::class); $lowPriorityRule->method('evaluate')->willReturn(true); $lowPriorityRule->method('getStatus')->willReturn('L'); $lowPriorityRule->method('getPriority')->willReturn(50); $highPriorityRule = $this->createStub(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->createStub(BookingStatusRuleInterface::class); $firstMatchingRule->method('evaluate')->willReturn(true); $firstMatchingRule->method('getStatus')->willReturn('A'); $firstMatchingRule->method('getPriority')->willReturn(100); $secondMatchingRule = $this->createStub(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->createStub(BookingStatusRuleInterface::class); $highPriorityRule->method('evaluate')->willReturn(false); $highPriorityRule->method('getStatus')->willReturn('H'); $highPriorityRule->method('getPriority')->willReturn(100); $lowPriorityRule = $this->createStub(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)); } public function testSelection1473RuleWinsOverLowerPriorityRule(): void { $lowerPriorityRule = $this->createStub(BookingStatusRuleInterface::class); $lowerPriorityRule->method('evaluate')->willReturn(true); $lowerPriorityRule->method('getStatus')->willReturn('X'); $lowerPriorityRule->method('getPriority')->willReturn(100); $registry = new BookingStatusRuleRegistry([ $lowerPriorityRule, new Selection1473StatusRule(), ]); $bookingDto = new BookingDto($this->createMockTravelWithSelection1473(), 1); $this->assertSame('O', $registry->evaluateStatus($bookingDto)); } private function createMockTravel(): Travel { $travel = new Travel(); $travel->id = 1; $travel->hotelId = 1; $travel->dateFrom = new \DateTimeImmutable('2030-01-01'); $travel->dateTo = new \DateTimeImmutable('2030-01-08'); return $travel; } private function createMockTravelWithSelection1473(): Travel { $travel = $this->createMockTravel(); $travel->selectionGroups = [ 1 => $this->createSelectionGroup(1, [1473]), ]; return $travel; } /** * @param list $selectionIds */ private function createSelectionGroup(int $groupId, array $selectionIds): \App\BusProNet\Model\CrmSelectionGroup { $group = new \App\BusProNet\Model\CrmSelectionGroup(); $group->id = $groupId; $group->selections = []; foreach ($selectionIds as $selectionId) { $selection = new \App\BusProNet\Model\CrmSelection(); $selection->id = $selectionId; $group->selections[] = $selection; } return $group; } }