Skip to content

Commit

Permalink
Add AutowireClient
Browse files Browse the repository at this point in the history
  • Loading branch information
DumitracheAdrian committed May 21, 2024
1 parent d525f33 commit 7881a62
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,35 @@

namespace Draw\Bundle\TesterBundle\PHPStan\Rules\Properties;

use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireService;
use PHPStan\Reflection\PropertyReflection;
use PHPStan\Rules\Properties\ReadWritePropertiesExtension;

class AutowireReadWritePropertiesExtension implements ReadWritePropertiesExtension
{
public function __construct(
private string $attribute
) {
}

public function isAlwaysRead(PropertyReflection $property, string $propertyName): bool
{
return false;
}

public function isAlwaysWritten(PropertyReflection $property, string $propertyName): bool
{
return $this->hasProperAttribute($property, $propertyName, AutowireService::class);
return $this->hasProperAttribute($property, $propertyName);
}

public function isInitialized(PropertyReflection $property, string $propertyName): bool
{
return $this->hasProperAttribute($property, $propertyName, AutowireService::class);
return $this->hasProperAttribute($property, $propertyName);
}

private function hasProperAttribute(PropertyReflection $property, string $propertyName, string $attribute): bool
private function hasProperAttribute(PropertyReflection $property, string $propertyName): bool
{
$properReflection = $property->getDeclaringClass()->getNativeProperty($propertyName)->getNativeReflection();

return 0 !== \count($properReflection->getAttributes($attribute, \ReflectionAttribute::IS_INSTANCEOF));
return 0 !== \count($properReflection->getAttributes($this->attribute, \ReflectionAttribute::IS_INSTANCEOF));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
class AutowireClient
{
public function __construct(
private array $options = [],
private array $server = [],
) {
}

public function getOptions(): array
{
return $this->options;
}

public function getServer(): array
{
return $this->server;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire;

use Draw\Bundle\TesterBundle\WebTestCase as DrawWebTestCase;
use Draw\Component\Core\Reflection\ReflectionAccessor;
use Draw\Component\Core\Reflection\ReflectionExtractor;
use PHPUnit\Event\Code\TestMethod;
Expand All @@ -14,6 +15,7 @@
use PHPUnit\Runner\Extension\ParameterCollection;
use PHPUnit\TextUI\Configuration\Configuration;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class SetUpAutowireExtension implements Extension
{
Expand Down Expand Up @@ -58,6 +60,8 @@ public function notify(TestPrepared $event): void
return;
}

$this->initializeClients($testCase);

$container = null;

foreach ($this->getPropertyAttributes($testCase) as [$property, $serviceId]) {
Expand Down Expand Up @@ -96,6 +100,55 @@ public function notify(TestPrepared $event): void
}
}

private function initializeClients(TestCase $testCase): void
{
if (!$testCase instanceof WebTestCase && !$testCase instanceof DrawWebTestCase) {
if (!empty(iterator_to_array($this->getClientAttributes($testCase), false))) {
throw new \RuntimeException(
sprintf(
'AutowireClient attribute can only be used in %s or %s.',
WebTestCase::class,
DrawWebTestCase::class
)
);
}

return;
}

foreach ($this->getClientAttributes($testCase) as [$property, $attribute]) {
\assert($property instanceof \ReflectionProperty);
\assert($attribute instanceof \ReflectionAttribute);

$autoWireClient = $attribute->newInstance();
\assert($autoWireClient instanceof AutowireClient);

$property->setValue(
$testCase,
ReflectionAccessor::callMethod(
$testCase,
'createClient',
$autoWireClient->getOptions(),
$autoWireClient->getServer()
)
);
}
}

private function getClientAttributes(TestCase $testCase): \Generator
{
foreach ((new \ReflectionObject($testCase))->getProperties() as $property) {
$attribute = $property->getAttributes(
AutowireClient::class,
\ReflectionAttribute::IS_INSTANCEOF
)[0] ?? null;

if (null !== $attribute) {
yield [$property, $attribute];
}
}
}

/**
* @return iterable<array{\ReflectionProperty, string|AutowireMock}>
*/
Expand Down
4 changes: 4 additions & 0 deletions packages/tester-bundle/WebTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
namespace Draw\Bundle\TesterBundle;

use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\DomCrawlerAssertionsTrait;
use Symfony\Bundle\FrameworkBundle\Test\HttpClientAssertionsTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;

abstract class WebTestCase extends KernelTestCase
{
use DomCrawlerAssertionsTrait;
use HttpClientAssertionsTrait;
use JsonResponseAssertionsTrait;

protected function tearDown(): void
Expand Down
11 changes: 10 additions & 1 deletion packages/tester-bundle/extension.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
services:
draw.tester_bundle.autowire_read_write_properties_extension:
draw.tester_bundle.autowire_client_read_write_properties_extension:
class: Draw\Bundle\TesterBundle\PHPStan\Rules\Properties\AutowireReadWritePropertiesExtension
arguments:
- 'Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient'
tags:
- phpstan.properties.readWriteExtension

draw.tester_bundle.autowire_service_read_write_properties_extension:
class: Draw\Bundle\TesterBundle\PHPStan\Rules\Properties\AutowireReadWritePropertiesExtension
arguments:
- 'Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireService'
tags:
- phpstan.properties.readWriteExtension
10 changes: 8 additions & 2 deletions tests/Controller/Api/TestDocumentControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@

use App\Message\NewTestDocumentMessage;
use Draw\Bundle\TesterBundle\Messenger\MessengerTesterTrait;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;
use Draw\Bundle\TesterBundle\WebTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;

class TestDocumentControllerTest extends WebTestCase
class TestDocumentControllerTest extends WebTestCase implements AutowiredInterface
{
use MessengerTesterTrait;

#[AutowireClient]
private KernelBrowser $client;

public function testCreate(): void
{
static::createClient()
$this->client
->jsonRequest(
'POST',
'/api/test-documents',
Expand Down
12 changes: 8 additions & 4 deletions tests/Controller/OpenApiControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

namespace App\Tests\Controller;

use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;
use Draw\Bundle\TesterBundle\WebTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;

class OpenApiControllerTest extends WebTestCase
class OpenApiControllerTest extends WebTestCase implements AutowiredInterface
{
#[AutowireClient]
private KernelBrowser $client;

private bool $writeFile = false;

public function testApiDocScopeAll(): void
Expand All @@ -22,9 +28,7 @@ public function assertApiDocIsTheSame(string $scope): void
{
$file = __DIR__.sprintf('/fixtures/api-doc-scope-%s.json', $scope);

$client = static::createClient();

$client->request('get', '/api-doc.json?scope='.$scope);
$this->client->request('get', '/api-doc.json?scope='.$scope);

static::assertResponseIsSuccessful();
static::assertResponseIsJson();
Expand Down
19 changes: 12 additions & 7 deletions tests/Controller/PingActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

namespace App\Tests\Controller;

use Draw\Bundle\TesterBundle\JsonResponseAssertionsTrait;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;
use Draw\Bundle\TesterBundle\WebTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\HttpFoundation\Response;

class PingActionTest extends WebTestCase
class PingActionTest extends WebTestCase implements AutowiredInterface
{
use JsonResponseAssertionsTrait;

#[AutowireClient]
private KernelBrowser $client;

public function testPing(): void
{
$client = static::createClient();

$client->request('GET', '/ping');
$this->client->request('GET', '/ping');

static::assertResponseStatusCodeSame(207);

Expand All @@ -36,9 +43,7 @@ public static function provideTestPingWithContext(): iterable
*/
public function testPingWithContext(string $context, int $statusCode): void
{
$client = static::createClient();

$client->request('GET', '/ping/'.$context);
$this->client->request('GET', '/ping/'.$context);

static::assertResponseStatusCodeSame($statusCode);

Expand Down
19 changes: 14 additions & 5 deletions tests/Controller/Security/UserRequestInterceptedSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@
namespace App\Tests\Controller\Security;

use App\Tests\AuthenticatorTestTrait;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;
use Draw\Bundle\TesterBundle\WebTestCase;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Component\HttpFoundation\Response;

class UserRequestInterceptedSubscriberTest extends WebTestCase
class UserRequestInterceptedSubscriberTest extends WebTestCase implements AutowiredInterface
{
use AuthenticatorTestTrait;

#[AutowireClient(
server: [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
]
)]
private KernelBrowser $client;

public function testRedirectedErrorMessage(): void
{
$client = static::createJsonClient();

static::setAuthorizationHeader($client, '[email protected]');
static::setAuthorizationHeader($this->client, '[email protected]');

$client->request('get', '/api/users');
$this->client->request('get', '/api/users');

static::assertResponseStatusCodeSame(Response::HTTP_FORBIDDEN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,17 @@ public function testRetry(): void
);
static::assertSame(FailedMessage::class, $failedMessage->getMessageClass());

static::$client->request('GET', sprintf('/admin/app/messengermessage/%s/retry', $failedMessage->getId()));
$this->client->request(
'GET',
sprintf('/admin/app/messengermessage/%s/retry', $failedMessage->getId())
);

static::assertResponseStatusCodeSame(302);

static::getTransportTester('async')
->assertMessageMatch(RetryFailedMessageMessage::class);

static::$client->followRedirect();
$this->client->followRedirect();

static::assertSelectorTextContains('.alert-success', 'Retry message successfully dispatched.');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ public function testUnlock(): void

$userLock->setUnlockUntil(null);

static::$client->request('GET', sprintf('/admin/app/user/%s/unlock', $user->getId()));
$this->client->request(
'GET',
sprintf('/admin/app/user/%s/unlock', $user->getId())
);

static::assertResponseStatusCodeSame(302);
static::assertResponseHeaderSame(
'Location',
sprintf('/admin/app/user/%s/show', $user->getId())
);

static::$client->followRedirect();
$this->client->followRedirect();

static::assertResponseIsSuccessful();

Expand All @@ -49,7 +52,10 @@ public function testNoAccess(): void

$user = $this->getUser('[email protected]');

static::$client->request('GET', sprintf('/admin/app/user/%s/unlock', $user->getId()));
$this->client->request(
'GET',
sprintf('/admin/app/user/%s/unlock', $user->getId())
);

static::assertResponseStatusCodeSame(403);
}
Expand Down
14 changes: 4 additions & 10 deletions tests/SonataIntegrationBundle/WebTestCaseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,17 @@

use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireClient;
use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireService;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;

/**
* @method static KernelBrowser createClient(array $options = [], array $server = [])
*/
trait WebTestCaseTrait
{
protected static ?KernelBrowser $client = null;

#[AutowireService]
protected EntityManagerInterface $entityManager;

protected function setUp(): void
{
static::$client = static::createClient();
}
#[AutowireClient]
private KernelBrowser $client;

protected function getUser(string $email): User
{
Expand All @@ -33,7 +27,7 @@ protected function getUser(string $email): User

protected function login(string $email): void
{
static::$client->loginUser(
$this->client->loginUser(
$this->getUser($email),
'user'
);
Expand Down

0 comments on commit 7881a62

Please sign in to comment.