Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Functional Testing Symfony Controllers with JWT and Symfony Messenger
<?php
namespace Tests\Acme\PersonnelManagement\Infrastructure\Symfony\AcmePersonnelManagementBundle\Controller;
use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
abstract class AbstractControllerTest extends WebTestCase
{
/** @var KernelBrowser|null */
protected $client = null;
public function setUp(): void
{
$this->client = static::createClient([], [
'HTTP_HOST' => 'dev.personnel.acme.com'
]);
\DG\BypassFinals::enable();
}
public function logInUnauthorizedUser(): void
{
/** @var JWTEncoderInterface $jwtEncoder */
$jwtEncoder = $this->client->getContainer()->get('lexik_jwt_authentication.encoder');
$token = $jwtEncoder->encode([
'username' => 'm.mustermann',
'permissions' => [],
'user_id' => 1,
'first_name' => 'Max',
'last_name' => 'Mustermann',
'email' => 'm.mustermann@acme.com',
'locale' => 'de'
]);
$this->client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $token));
}
public function logInAuthorizedUser(string $role): void
{
/** @var JWTEncoderInterface $jwtEncoder */
$jwtEncoder = $this->client->getContainer()->get('lexik_jwt_authentication.encoder');
$token = $jwtEncoder->encode([
'username' => 'm.mustermann',
'permissions' => [$role],
'user_id' => 1,
'first_name' => 'Max',
'last_name' => 'Mustermann',
'email' => 'm.mustermann@acme.com',
'locale' => 'de'
]);
$this->client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $token));
}
public function logInAdmin(): void
{
/** @var JWTEncoderInterface $jwtEncoder */
$jwtEncoder = $this->client->getContainer()->get('lexik_jwt_authentication.encoder');
$token = $jwtEncoder->encode([
'username' => 'm.mustermann',
'permissions' => [
'personnel__module_show',
'personnel__agency__list',
'personnel__agency__details',
'personnel__agency__hire'
],
'user_id' => 1,
'first_name' => 'Max',
'last_name' => 'Mustermann',
'email' => 'm.mustermann@acme.com',
'locale' => 'de'
]);
$this->client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $token));
}
}
<?php
namespace Acme\PersonnelManagement\Infrastructure\Symfony\AcmePersonnelManagementBundle\Controller;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
final class AgencyController
{
/** @var AuthorizationCheckerInterface */
private $authorizationChecker;
/** @var MessageBusInterface */
private $commandBus;
public function __construct(AuthorizationCheckerInterface $authorizationChecker, MessageBusInterface $commandBus)
{
$this->authorizationChecker = $authorizationChecker;
$this->commandBus = $commandBus;
}
public function hireAction(Request $request): Response
{
if (!$this->authorizationChecker->isGranted('ROLE_PERSONNEL__AGENCY__HIRE')) {
throw new AccessDeniedHttpException();
}
$command = new HireAgency(json_decode($request->getContent(), true));
$this->commandBus->dispatch($command);
return new JsonResponse(null, Response::HTTP_CREATED);
}
}
<?php
namespace Tests\Acme\PersonnelManagement\Infrastructure\Symfony\AcmePersonnelManagementBundle\Controller;
use Acme\TemporaryWork\Application\Service\Agency\HireAgencyHandler;
use Symfony\Component\HttpFoundation\Response;
class AgencyControllerTest extends AbstractControllerTest
{
/** @test */
public function hireIsUnauthorized(): void
{
$this->client->request('POST', '/personnel/agencies');
$this->assertSame(Response::HTTP_UNAUTHORIZED, $this->client->getResponse()->getStatusCode());
}
/** @test */
public function hireIsForbidden(): void
{
$this->logInUnauthorizedUser();
$this->client->request('POST', '/personnel/agencies');
$this->assertTrue($this->client->getResponse()->isForbidden());
}
/** @test */
public function hireIsSuccessful(): void
{
$commandHandlerMock = $this->getMockBuilder(HireAgencyHandler::class)
->disableOriginalConstructor()
->getMock();
$this->client->getContainer()->set(HireAgencyHandler::class, $commandHandlerMock);
$this->logInAuthorizedUser('personnel__agency__hire');
$content = [
'agencyId' => 'a95dd3f1-7d89-4bc0-a3c6-b69e987d71ca',
'name' => 'Acme GmbH',
'vatId' => 'DE123456789',
'contactPerson' => 'Max Mustermann',
'contactDetails' => ['email' => null, 'phone' => null, 'fax' => null],
'address' => ['street' => null,'postcode' => null,'city' => null,'countryCode' => 'DE'],
];
$this->client->request('POST', '/personnel/agencies', [], [], [], json_encode($content));
$this->assertTrue($this->client->getResponse()->isSuccessful());
}
}
<?php
namespace Acme\TemporaryWork\Application\Service\Agency;
use Acme\TemporaryWork\Domain\Model\Agency\Agency;
use Acme\TemporaryWork\Domain\Model\Agency\AgencyRepository;
final class HireAgencyHandler
{
/** @var AgencyRepository */
private $agencyCollection;
public function __construct(AgencyRepository $agencyCollection)
{
$this->agencyCollection = $agencyCollection;
}
public function __invoke(HireAgency $command): void
{
$agency = Agency::hire(
$command->agencyId(), $command->name(), $command->vatId(),
$command->contactPerson(), $command->contactDetails(), $command->address()
);
$this->agencyCollection->save($agency);
}
}
@webdevilopers

This comment has been minimized.

Copy link
Owner Author

@webdevilopers webdevilopers commented May 8, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment