mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-07-01 14:36:13 +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