chill-bundles/src/Bundle/ChillMainBundle/Tests/Controller/WorkflowViewSendPublicControllerTest.php

274 lines
10 KiB
PHP

<?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\MainBundle\Tests\Controller;
use Chill\MainBundle\Controller\WorkflowViewSendPublicController;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSend;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowSendView;
use Chill\MainBundle\Workflow\EntityWorkflowHandlerInterface;
use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Chill\MainBundle\Workflow\EntityWorkflowWithPublicViewInterface;
use Chill\MainBundle\Workflow\Messenger\PostPublicViewMessage;
use Chill\MainBundle\Workflow\Templating\EntityWorkflowViewMetadataDTO;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\EntityManagerInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Log\NullLogger;
use Symfony\Component\Clock\MockClock;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Workflow\Registry;
use Twig\Environment;
/**
* @internal
*
* @coversNothing
*/
class WorkflowViewSendPublicControllerTest extends TestCase
{
use ProphecyTrait;
public function testTooMuchTrials(): void
{
$environment = $this->prophesize(Environment::class);
$entityManager = $this->prophesize(EntityManagerInterface::class);
$entityManager->flush()->shouldNotBeCalled();
$messageBus = $this->prophesize(MessageBusInterface::class);
$messageBus->dispatch(Argument::type(PostPublicViewMessage::class))->shouldNotBeCalled();
$controller = new WorkflowViewSendPublicController($entityManager->reveal(), new NullLogger(), new EntityWorkflowManager([], new Registry()), new MockClock(), $environment->reveal(), $messageBus->reveal());
self::expectException(AccessDeniedHttpException::class);
$send = $this->buildEntityWorkflowSend();
for ($i = 0; $i < 51; ++$i) {
$send->increaseErrorTrials();
}
$controller($send, $send->getPrivateToken(), new Request());
}
public function testInvalidVerificationKey(): void
{
$environment = $this->prophesize(Environment::class);
$entityManager = $this->prophesize(EntityManagerInterface::class);
$entityManager->flush()->shouldBeCalled();
$messageBus = $this->prophesize(MessageBusInterface::class);
$messageBus->dispatch(Argument::type(PostPublicViewMessage::class))->shouldNotBeCalled();
$controller = new WorkflowViewSendPublicController($entityManager->reveal(), new NullLogger(), new EntityWorkflowManager([], new Registry()), new MockClock(), $environment->reveal(), $messageBus->reveal());
self::expectException(AccessDeniedHttpException::class);
$send = $this->buildEntityWorkflowSend();
try {
$controller($send, 'some-token', new Request());
} catch (AccessDeniedHttpException $e) {
self::assertEquals(1, $send->getNumberOfErrorTrials());
throw $e;
}
}
public function testExpiredLink(): void
{
$environment = $this->prophesize(Environment::class);
$environment->render('@ChillMain/Workflow/workflow_view_send_public_expired.html.twig')->willReturn('test');
$entityManager = $this->prophesize(EntityManagerInterface::class);
$entityManager->flush()->shouldNotBeCalled();
$messageBus = $this->prophesize(MessageBusInterface::class);
$messageBus->dispatch(Argument::type(PostPublicViewMessage::class))->shouldNotBeCalled();
$controller = new WorkflowViewSendPublicController($entityManager->reveal(), new NullLogger(), new EntityWorkflowManager([], new Registry()), new MockClock('next year'), $environment->reveal(), $messageBus->reveal());
$send = $this->buildEntityWorkflowSend();
$response = $controller($send, $send->getPrivateToken(), new Request());
self::assertEquals('test', $response->getContent());
self::assertEquals(409, $response->getStatusCode());
}
public function testNoHandlerFound(): void
{
$environment = $this->prophesize(Environment::class);
$entityManager = $this->prophesize(EntityManagerInterface::class);
$entityManager->flush()->shouldNotBeCalled();
$messageBus = $this->prophesize(MessageBusInterface::class);
$messageBus->dispatch(Argument::type(PostPublicViewMessage::class))->shouldNotBeCalled();
$controller = new WorkflowViewSendPublicController(
$entityManager->reveal(),
new NullLogger(),
new EntityWorkflowManager([], new Registry()),
new MockClock(),
$environment->reveal(),
$messageBus->reveal(),
);
self::expectException(\RuntimeException::class);
$send = $this->buildEntityWorkflowSend();
$controller($send, $send->getPrivateToken(), new Request());
}
public function testHappyScenario(): void
{
$send = $this->buildEntityWorkflowSend();
$environment = $this->prophesize(Environment::class);
$entityManager = $this->prophesize(EntityManagerInterface::class);
$entityManager->persist(Argument::that(function (EntityWorkflowSendView $view) use ($send) {
$reflection = new \ReflectionClass($view);
$idProperty = $reflection->getProperty('id');
$idProperty->setAccessible(true);
$idProperty->setValue($view, 5);
return $send === $view->getSend();
}))->shouldBeCalled();
$entityManager->flush()->shouldBeCalled();
$messageBus = $this->prophesize(MessageBusInterface::class);
$messageBus->dispatch(Argument::type(PostPublicViewMessage::class))->shouldBeCalled()
->will(fn ($args) => new Envelope($args[0]));
$controller = new WorkflowViewSendPublicController(
$entityManager->reveal(),
new NullLogger(),
new EntityWorkflowManager([
$this->buildFakeHandler(),
], new Registry()),
new MockClock(),
$environment->reveal(),
$messageBus->reveal(),
);
$response = $controller($send, $send->getPrivateToken(), $this->buildRequest());
self::assertEquals(200, $response->getStatusCode());
self::assertEquals('content', $response->getContent());
}
private function buildFakeHandler(): EntityWorkflowHandlerInterface&EntityWorkflowWithPublicViewInterface
{
return new class () implements EntityWorkflowWithPublicViewInterface, EntityWorkflowHandlerInterface {
public function getDeletionRoles(): array
{
throw new \BadMethodCallException('not implemented');
}
public function getEntityData(EntityWorkflow $entityWorkflow, array $options = []): array
{
throw new \BadMethodCallException('not implemented');
}
public function getEntityTitle(EntityWorkflow $entityWorkflow, array $options = []): string
{
throw new \BadMethodCallException('not implemented');
}
public function getRelatedEntity(EntityWorkflow $entityWorkflow): ?object
{
throw new \BadMethodCallException('not implemented');
}
public function getRelatedAccompanyingPeriod(EntityWorkflow $entityWorkflow): ?AccompanyingPeriod
{
throw new \BadMethodCallException('not implemented');
}
public function getRelatedObjects(object $object): array
{
throw new \BadMethodCallException('not implemented');
}
public function getRoleShow(EntityWorkflow $entityWorkflow): ?string
{
throw new \BadMethodCallException('not implemented');
}
public function getSuggestedUsers(EntityWorkflow $entityWorkflow): array
{
throw new \BadMethodCallException('not implemented');
}
public function getTemplate(EntityWorkflow $entityWorkflow, array $options = []): string
{
throw new \BadMethodCallException('not implemented');
}
public function getTemplateData(EntityWorkflow $entityWorkflow, array $options = []): array
{
throw new \BadMethodCallException('not implemented');
}
public function isObjectSupported(object $object): bool
{
throw new \BadMethodCallException('not implemented');
}
public function supports(EntityWorkflow $entityWorkflow, array $options = []): bool
{
return true;
}
public function supportsFreeze(EntityWorkflow $entityWorkflow, array $options = []): bool
{
return false;
}
public function findByRelatedEntity(object $object): array
{
throw new \BadMethodCallException('not implemented');
}
public function renderPublicView(EntityWorkflowSend $entityWorkflowSend, EntityWorkflowViewMetadataDTO $metadata): string
{
return 'content';
}
public function getSuggestedPersons(EntityWorkflow $entityWorkflow): array
{
return [];
}
public function getSuggestedThirdParties(EntityWorkflow $entityWorkflow): array
{
return [];
}
};
}
private function buildRequest(): Request
{
return Request::create('/test', server: ['REMOTE_ADDR' => '10.0.0.10']);
}
private function buildEntityWorkflowSend(): EntityWorkflowSend
{
$entityWorkflow = new EntityWorkflow();
$step = $entityWorkflow->getCurrentStep();
return new EntityWorkflowSend($step, new ThirdParty(), new \DateTimeImmutable('next month'));
}
}