feat: assignments with disabled formalities
addresses #869dnvm8c
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Security\Voter;
|
||||
|
||||
use App\Entity\Application;
|
||||
use App\Entity\Assignment;
|
||||
use App\Entity\Disposition;
|
||||
use App\Entity\Teamer;
|
||||
use App\Security\Voter\DispositionVoter;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||
|
||||
/**
|
||||
* The documents and the feedback simply do not exist on a skip-formalities assignment, so the
|
||||
* voter is where that is enforced: it closes the blank-PDF routes and the upload and feedback
|
||||
* screens at once, and every template that gates on is_granted() follows without a change.
|
||||
*/
|
||||
class DispositionVoterTest extends TestCase
|
||||
{
|
||||
private Security&MockObject $security;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->security = $this->createMock(Security::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider documentAndFeedbackAttributes
|
||||
*/
|
||||
public function testAnAdminIsDeniedOnASkipFormalitiesAssignment(string $attribute): void
|
||||
{
|
||||
$this->security->method('isGranted')->willReturn(true);
|
||||
|
||||
$this->assertSame(
|
||||
VoterInterface::ACCESS_DENIED,
|
||||
$this->vote($attribute, $this->createDisposition(skipFormalities: true)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The same admin on a normal assignment must still get through - the flag is the only thing
|
||||
* that may take these away.
|
||||
*
|
||||
* @dataProvider documentAndFeedbackAttributes
|
||||
*/
|
||||
public function testTheSameAdminIsGrantedOnANormalAssignment(string $attribute): void
|
||||
{
|
||||
$this->security->method('isGranted')->willReturn(true);
|
||||
|
||||
$this->assertSame(
|
||||
VoterInterface::ACCESS_GRANTED,
|
||||
$this->vote($attribute, $this->createDisposition(skipFormalities: false)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{string}>
|
||||
*/
|
||||
public static function documentAndFeedbackAttributes(): array
|
||||
{
|
||||
return [
|
||||
'contract pdf and upload' => [DispositionVoter::CONTRACT],
|
||||
'invoice pdf and upload' => [DispositionVoter::INVOICE],
|
||||
'office upload on behalf of the teamer' => [DispositionVoter::CONTRACT_SUPPLEMENTARY],
|
||||
'office upload of either document' => [DispositionVoter::ADMIN_DOCUMENT_UPLOAD],
|
||||
'providing the feedback' => [DispositionVoter::FEEDBACK],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Viewing the placement and calling it off are unrelated to the formalities and have to keep
|
||||
* working, or an admin could no longer cancel a teamer on such an assignment.
|
||||
*/
|
||||
public function testViewingAndCallingOffAreUnaffected(): void
|
||||
{
|
||||
$this->security->method('isGranted')->willReturn(true);
|
||||
$disposition = $this->createDisposition(skipFormalities: true);
|
||||
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->vote(DispositionVoter::VIEW, $disposition));
|
||||
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->vote(DispositionVoter::CALL_OFF, $disposition));
|
||||
}
|
||||
|
||||
private function vote(string $attribute, Disposition $disposition): int
|
||||
{
|
||||
return (new DispositionVoter($this->security))->vote(
|
||||
$this->createMock(TokenInterface::class),
|
||||
$disposition,
|
||||
[$attribute],
|
||||
);
|
||||
}
|
||||
|
||||
private function createDisposition(bool $skipFormalities): Disposition
|
||||
{
|
||||
$assignment = (new Assignment())->setSkipFormalities($skipFormalities);
|
||||
|
||||
return new Disposition(new Application($assignment, new Teamer()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user