diff --git a/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetCallerCommandHandler.php b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetCallerCommandHandler.php new file mode 100644 index 000000000..ae37f3945 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetCallerCommandHandler.php @@ -0,0 +1,50 @@ +getCaller(); + if ($currentCaller === $command->caller) { + return $ticket; + } + + // End the current caller history (if any) + foreach ($ticket->getCallerHistories() as $callerHistory) { + if (null === $callerHistory->getEndDate()) { + $callerHistory->setEndDate($this->clock->now()); + } + } + + // Create a new caller history with the new caller + new CallerHistory( + $command->caller, + $ticket, + $this->clock->now(), + ); + + return $ticket; + } +} diff --git a/src/Bundle/ChillTicketBundle/src/Action/Ticket/SetCallerCommand.php b/src/Bundle/ChillTicketBundle/src/Action/Ticket/SetCallerCommand.php new file mode 100644 index 000000000..2589abac4 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/Action/Ticket/SetCallerCommand.php @@ -0,0 +1,29 @@ +now = new \DateTimeImmutable('2023-01-01 12:00:00'); + $this->clock = new MockClock($this->now); + $this->handler = new SetCallerCommandHandler($this->clock); + } + + public function testSetPersonAsCaller(): void + { + // Arrange + $ticket = new Ticket(); + $person = new Person(); + $command = new SetCallerCommand($person); + + // Act + $result = ($this->handler)($ticket, $command); + + // Assert + self::assertSame($ticket, $result); + self::assertSame($person, $ticket->getCaller()); + self::assertCount(1, $ticket->getCallerHistories()); + + $callerHistory = $ticket->getCallerHistories()->first(); + self::assertInstanceOf(CallerHistory::class, $callerHistory); + self::assertSame($person, $callerHistory->getPerson()); + self::assertNull($callerHistory->getThirdParty()); + self::assertEquals($this->now->getTimestamp(), $callerHistory->getStartDate()->getTimestamp()); + self::assertNull($callerHistory->getEndDate()); + } + + public function testSetThirdPartyAsCaller(): void + { + // Arrange + $ticket = new Ticket(); + $thirdParty = new ThirdParty(); + $command = new SetCallerCommand($thirdParty); + + // Act + $result = ($this->handler)($ticket, $command); + + // Assert + self::assertSame($ticket, $result); + self::assertSame($thirdParty, $ticket->getCaller()); + self::assertCount(1, $ticket->getCallerHistories()); + + $callerHistory = $ticket->getCallerHistories()->first(); + self::assertInstanceOf(CallerHistory::class, $callerHistory); + self::assertNull($callerHistory->getPerson()); + self::assertSame($thirdParty, $callerHistory->getThirdParty()); + self::assertEquals($this->now->getTimestamp(), $callerHistory->getStartDate()->getTimestamp()); + self::assertNull($callerHistory->getEndDate()); + } + + public function testChangeCallerFromPersonToThirdParty(): void + { + // Arrange + $ticket = new Ticket(); + $person = new Person(); + $thirdParty = new ThirdParty(); + + // Set initial person caller + $initialCallerHistory = new CallerHistory($person, $ticket, $this->now); + $initialCallerHistory->setPerson($person); + + // Create command to change to third party + $command = new SetCallerCommand($thirdParty); + + // Act + $this->clock->modify('+ 10 minutes'); + $result = ($this->handler)($ticket, $command); + + // Assert + self::assertSame($ticket, $result); + self::assertSame($thirdParty, $ticket->getCaller()); + self::assertCount(2, $ticket->getCallerHistories()); + + // Check that the first history is ended + $firstCallerHistory = $ticket->getCallerHistories()->first(); + self::assertSame($person, $firstCallerHistory->getPerson()); + self::assertEquals($this->clock->now()->getTimestamp(), $firstCallerHistory->getEndDate()->getTimestamp()); + + // Check that the new history is created correctly + $lastCallerHistory = $ticket->getCallerHistories()->last(); + self::assertNull($lastCallerHistory->getPerson()); + self::assertSame($thirdParty, $lastCallerHistory->getThirdParty()); + self::assertSame($this->clock->now()->getTimestamp(), $lastCallerHistory->getStartDate()->getTimestamp()); + self::assertNull($lastCallerHistory->getEndDate()); + } + + public function testRemoveCaller(): void + { + // Arrange + $ticket = new Ticket(); + $person = new Person(); + + // Set initial person caller + $initialCallerHistory = new CallerHistory($person, $ticket, $this->now); + + // Create command to remove caller + $command = new SetCallerCommand(null); + + // Act + $result = ($this->handler)($ticket, $command); + + // Assert + self::assertSame($ticket, $result); + self::assertNull($ticket->getCaller()); + self::assertCount(2, $ticket->getCallerHistories()); + + // Check that the history is ended + $callerHistory = $ticket->getCallerHistories()->first(); + self::assertSame($person, $callerHistory->getPerson()); + self::assertEquals($this->now->getTimestamp(), $callerHistory->getEndDate()->getTimestamp()); + } + + public function testNoChangeWhenCallerIsAlreadySet(): void + { + // Arrange + $ticket = new Ticket(); + $person = new Person(); + + // Set initial person caller + $initialCallerHistory = new CallerHistory($person, $ticket, $this->now); + + // Create command with the same person + $command = new SetCallerCommand($person); + + // Act + $result = ($this->handler)($ticket, $command); + + // Assert + self::assertSame($ticket, $result); + self::assertSame($person, $ticket->getCaller()); + self::assertCount(1, $ticket->getCallerHistories()); + + // Check that the history is unchanged + $callerHistory = $ticket->getCallerHistories()->first(); + self::assertSame($person, $callerHistory->getPerson()); + self::assertNull($callerHistory->getEndDate()); + } +}