Remplace createMock() par createStub() pour tous les collaborateurs sans expectations configurées. Les mocks avec expects() restent des mocks locaux créés dans le test concerné. 0 notices sur 49 tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
138 lines
5.1 KiB
PHP
138 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Tests\Unit\Controller;
|
|
|
|
use App\Controller\PushController;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Container\ContainerInterface;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\RateLimiter\RateLimiterFactory;
|
|
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
|
|
|
|
class PushControllerTest extends TestCase
|
|
{
|
|
private EntityManagerInterface $em;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->em = $this->createStub(EntityManagerInterface::class);
|
|
}
|
|
|
|
private function makeController(bool $exhaust = false, ?EntityManagerInterface $em = null): PushController
|
|
{
|
|
$storage = new InMemoryStorage();
|
|
$factory = new RateLimiterFactory([
|
|
'id' => 'push_test',
|
|
'policy' => 'token_bucket',
|
|
'limit' => 5,
|
|
'rate' => ['interval' => '1 minute'],
|
|
], $storage);
|
|
|
|
if ($exhaust) {
|
|
$limiter = $factory->create('1.2.3.4');
|
|
for ($i = 0; $i < 6; $i++) {
|
|
$limiter->consume();
|
|
}
|
|
}
|
|
|
|
$controller = new PushController($em ?? $this->em, $factory, 'fake-vapid-public-key');
|
|
|
|
$container = $this->createStub(ContainerInterface::class);
|
|
$container->method('has')->willReturn(false);
|
|
$controller->setContainer($container);
|
|
|
|
return $controller;
|
|
}
|
|
|
|
private function makeRequest(string $method, string $body, string $ip = '1.2.3.4'): Request
|
|
{
|
|
$request = Request::create('/api/push/subscribe', $method, [], [], [], [], $body);
|
|
$request->server->set('REMOTE_ADDR', $ip);
|
|
return $request;
|
|
}
|
|
|
|
// ── subscribe ─────────────────────────────────────────────────────────────
|
|
|
|
public function testSubscribeBodyTooLargeReturns413(): void
|
|
{
|
|
$body = json_encode([
|
|
'endpoint' => 'https://push.example.com/sub',
|
|
'keys' => ['auth' => 'a', 'p256dh' => 'b'],
|
|
'pad' => str_repeat('x', 4100),
|
|
]);
|
|
self::assertSame(413, $this->controller()->subscribe($this->makeRequest('POST', $body))->getStatusCode());
|
|
}
|
|
|
|
public function testSubscribeMissingFieldsReturns422(): void
|
|
{
|
|
self::assertSame(422, $this->controller()->subscribe(
|
|
$this->makeRequest('POST', json_encode(['endpoint' => 'https://push.example.com']))
|
|
)->getStatusCode());
|
|
}
|
|
|
|
public function testSubscribeInvalidEndpointUrlReturns422(): void
|
|
{
|
|
$body = json_encode(['endpoint' => 'not-a-url', 'keys' => ['auth' => 'a', 'p256dh' => 'b']]);
|
|
self::assertSame(422, $this->controller()->subscribe($this->makeRequest('POST', $body))->getStatusCode());
|
|
}
|
|
|
|
public function testSubscribeValidRequestReturns201(): void
|
|
{
|
|
$em = $this->createMock(EntityManagerInterface::class);
|
|
$em->method('getRepository')->willReturn(
|
|
$this->createConfiguredStub(\Doctrine\ORM\EntityRepository::class, ['findOneBy' => null])
|
|
);
|
|
$em->expects(self::once())->method('persist');
|
|
$em->expects(self::once())->method('flush');
|
|
|
|
$body = json_encode([
|
|
'endpoint' => 'https://fcm.googleapis.com/fcm/send/abc123',
|
|
'keys' => ['auth' => 'authtoken', 'p256dh' => 'p256key'],
|
|
]);
|
|
self::assertSame(201, $this->makeController(em: $em)->subscribe($this->makeRequest('POST', $body))->getStatusCode());
|
|
}
|
|
|
|
public function testSubscribeRateLimitExceededReturns429(): void
|
|
{
|
|
self::assertSame(429, $this->makeController(exhaust: true)->subscribe(
|
|
$this->makeRequest('POST', json_encode([
|
|
'endpoint' => 'https://push.example.com/sub',
|
|
'keys' => ['auth' => 'a', 'p256dh' => 'b'],
|
|
]))
|
|
)->getStatusCode());
|
|
}
|
|
|
|
// ── unsubscribe ───────────────────────────────────────────────────────────
|
|
|
|
public function testUnsubscribeMissingEndpointReturns422(): void
|
|
{
|
|
self::assertSame(422, $this->controller()->unsubscribe(
|
|
$this->makeRequest('DELETE', json_encode([]))
|
|
)->getStatusCode());
|
|
}
|
|
|
|
public function testUnsubscribeUnknownEndpointReturns204(): void
|
|
{
|
|
$this->em->method('getRepository')->willReturn(
|
|
$this->createConfiguredStub(\Doctrine\ORM\EntityRepository::class, ['findOneBy' => null])
|
|
);
|
|
|
|
self::assertSame(204, $this->controller()->unsubscribe(
|
|
$this->makeRequest('DELETE', json_encode(['endpoint' => 'https://push.example.com/sub']))
|
|
)->getStatusCode());
|
|
}
|
|
|
|
public function testUnsubscribeRateLimitExceededReturns429(): void
|
|
{
|
|
self::assertSame(429, $this->makeController(exhaust: true)->unsubscribe(
|
|
$this->makeRequest('DELETE', json_encode(['endpoint' => 'https://push.example.com/sub']))
|
|
)->getStatusCode());
|
|
}
|
|
|
|
private function controller(): PushController
|
|
{
|
|
return $this->makeController();
|
|
}
|
|
}
|