feat: record application deleted event for statistics
This commit is contained in:
@@ -6,13 +6,16 @@ namespace App\Tests\EventListener;
|
||||
|
||||
use App\Entity\Application;
|
||||
use App\Entity\Assignment;
|
||||
use App\Entity\Destination;
|
||||
use App\Entity\Disposition;
|
||||
use App\Entity\JobProfile;
|
||||
use App\Entity\Teamer;
|
||||
use App\Enum\ApplicationDeletionOutcome;
|
||||
use App\Enum\CallOffScope;
|
||||
use App\Enum\StatisticsEventName;
|
||||
use App\EventListener\StatisticsChangeSetListener;
|
||||
use App\Service\Statistics\Collector\ApplicationCreatedCollector;
|
||||
use App\Service\Statistics\Collector\ApplicationDeletedCollector;
|
||||
use App\Service\Statistics\Collector\CallOffCollector;
|
||||
use App\Service\Statistics\Collector\DispositionDeletedCollector;
|
||||
use App\Service\Statistics\Collector\JobProfileChangeCollector;
|
||||
@@ -345,6 +348,111 @@ class StatisticsChangeSetListenerTest extends TestCase
|
||||
$this->flush([[$this->disposition(), ['remarks' => ['alt', 'neu']]]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* A teamer withdrawing leaves nothing behind - the application row is hard deleted - so
|
||||
* this is the only trace that they applied and then thought better of it.
|
||||
*/
|
||||
public function testRecordsAWithdrawnApplicationAsALoss(): void
|
||||
{
|
||||
$application = new Application(new Assignment(), new Teamer());
|
||||
$application->setStatus(Application::STATUS_PENDING);
|
||||
|
||||
$this->recorder
|
||||
->expects($this->once())
|
||||
->method('record')
|
||||
->with(
|
||||
StatisticsEventName::APPLICATION_DELETED,
|
||||
$this->anything(),
|
||||
$this->callback(static function (array $payload) use ($application): bool {
|
||||
return ApplicationDeletionOutcome::REMOVED->value === $payload['outcome']
|
||||
&& Application::STATUS_PENDING === $payload['previous_status']
|
||||
&& $application->getUuid() === $payload['application_uuid']
|
||||
&& null === $payload['disposition_uuid'];
|
||||
})
|
||||
)
|
||||
;
|
||||
|
||||
$this->flush([], [], [$application]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Staffing somebody deletes their application too: the dispose controller persists the
|
||||
* placement and removes the application in one flush. Counting that as a lost application
|
||||
* would turn every success into a failure.
|
||||
*/
|
||||
public function testAnApplicationTurnedIntoAPlacementIsNotALoss(): void
|
||||
{
|
||||
$assignment = new Assignment();
|
||||
$teamer = new Teamer();
|
||||
$application = new Application($assignment, $teamer);
|
||||
$disposition = new Disposition($application);
|
||||
|
||||
$this->recorder
|
||||
->expects($this->once())
|
||||
->method('record')
|
||||
->with(
|
||||
StatisticsEventName::APPLICATION_DELETED,
|
||||
$this->anything(),
|
||||
$this->callback(static function (array $payload) use ($disposition): bool {
|
||||
return ApplicationDeletionOutcome::DISPOSED->value === $payload['outcome']
|
||||
&& $disposition->getUuid() === $payload['disposition_uuid'];
|
||||
})
|
||||
)
|
||||
;
|
||||
|
||||
$this->flush([], [$disposition], [$application]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Two unrelated things happening in one flush do not make one the cause of the other. The
|
||||
* application still counts as lost.
|
||||
*/
|
||||
public function testAPlacementForSomebodyElseDoesNotExcuseTheDeletion(): void
|
||||
{
|
||||
$assignment = new Assignment();
|
||||
$application = new Application($assignment, new Teamer());
|
||||
$disposition = new Disposition(new Application($assignment, new Teamer()));
|
||||
|
||||
$this->recorder
|
||||
->expects($this->once())
|
||||
->method('record')
|
||||
->with(
|
||||
StatisticsEventName::APPLICATION_DELETED,
|
||||
$this->anything(),
|
||||
$this->callback(static function (array $payload): bool {
|
||||
return ApplicationDeletionOutcome::REMOVED->value === $payload['outcome']
|
||||
&& null === $payload['disposition_uuid'];
|
||||
})
|
||||
)
|
||||
;
|
||||
|
||||
$this->flush([], [$disposition], [$application]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The dimensions have to be frozen while the entity is still whole. Going through
|
||||
* recordForApplication() instead would resolve them in postFlush, by which time Doctrine
|
||||
* has detached the application and nulled its id, and the row would name nothing.
|
||||
*/
|
||||
public function testADeletedApplicationCarriesDimensionsFrozenDuringTheFlush(): void
|
||||
{
|
||||
$assignment = (new Assignment())->setDestination((new Destination())->setHotelCode('SERZIL'));
|
||||
|
||||
$this->recorder->expects($this->never())->method('recordForApplication');
|
||||
|
||||
$this->recorder
|
||||
->expects($this->once())
|
||||
->method('record')
|
||||
->with(
|
||||
StatisticsEventName::APPLICATION_DELETED,
|
||||
$this->callback(static fn (array $dimensions): bool => 'ZIL' === $dimensions['hotel_code']),
|
||||
$this->anything()
|
||||
)
|
||||
;
|
||||
|
||||
$this->flush([], [], [new Application($assignment, new Teamer())]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Editing an application later is not a second application.
|
||||
*/
|
||||
@@ -423,6 +531,7 @@ class StatisticsChangeSetListenerTest extends TestCase
|
||||
new CallOffCollector(),
|
||||
new DispositionDeletedCollector(),
|
||||
new ApplicationCreatedCollector(),
|
||||
new ApplicationDeletedCollector(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user