Files
radarsargasses/backend/tests/Unit/Controller/PushControllerTest.php
Gwadaking eff47f14bc test: éliminer les PHPUnit Notices (createMock → createStub)
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>
2026-04-10 01:05:48 -04:00

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();
}
}