mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-30 22:16:14 +00:00
Add SetCallerCommand and handler with tests to manage ticket caller changes
This commit is contained in:
parent
df745a1c6a
commit
de18f4e3aa
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\TicketBundle\Action\Ticket\Handler;
|
||||
|
||||
use Chill\TicketBundle\Action\Ticket\SetCallerCommand;
|
||||
use Chill\TicketBundle\Entity\CallerHistory;
|
||||
use Chill\TicketBundle\Entity\Ticket;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
|
||||
/**
|
||||
* Handler for setting the caller of a ticket.
|
||||
*/
|
||||
class SetCallerCommandHandler
|
||||
{
|
||||
public function __construct(private readonly ClockInterface $clock) {}
|
||||
|
||||
public function __invoke(Ticket $ticket, SetCallerCommand $command): Ticket
|
||||
{
|
||||
// If the ticket already has the requested caller, return it without changes
|
||||
$currentCaller = $ticket->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;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\TicketBundle\Action\Ticket;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
|
||||
/**
|
||||
* Command to set the caller of a ticket.
|
||||
* The caller can be either a Person or a ThirdParty.
|
||||
*/
|
||||
final readonly class SetCallerCommand
|
||||
{
|
||||
/**
|
||||
* @param Person|ThirdParty|null $caller The caller to associate with the ticket
|
||||
*/
|
||||
public function __construct(
|
||||
public Person|ThirdParty|null $caller,
|
||||
) {}
|
||||
}
|
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\TicketBundle\Tests\Action\Ticket\Handler;
|
||||
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Chill\TicketBundle\Action\Ticket\Handler\SetCallerCommandHandler;
|
||||
use Chill\TicketBundle\Action\Ticket\SetCallerCommand;
|
||||
use Chill\TicketBundle\Entity\CallerHistory;
|
||||
use Chill\TicketBundle\Entity\Ticket;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Symfony\Component\Clock\ClockInterface;
|
||||
use Symfony\Component\Clock\MockClock;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @coversNothing
|
||||
*/
|
||||
class SetCallerCommandHandlerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
private \DateTimeImmutable $now;
|
||||
private ClockInterface $clock;
|
||||
private SetCallerCommandHandler $handler;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->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());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user