Files
points-of-interest/server/tests/Functional/SignalControllerTest.php
T
2025-10-10 08:48:27 +02:00

124 lines
4.0 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Functional;
use App\DataFixtures\SignalFixtures;
use App\Entity\Signal;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Tools\SchemaTool;
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\HttpFoundation\Response;
class SignalControllerTest extends WebTestCase
{
private KernelBrowser $client;
private EntityManagerInterface $entityManager;
protected function setUp(): void
{
$this->client = static::createClient();
$entityManager = $this->client->getContainer()->get(EntityManagerInterface::class);
self::assertInstanceOf(EntityManagerInterface::class, $entityManager);
$this->entityManager = $entityManager;
$metadata = $this->entityManager->getMetadataFactory()->getAllMetadata();
$schemaTool = new SchemaTool($this->entityManager);
$schemaTool->dropDatabase();
if ($metadata !== []) {
$schemaTool->createSchema($metadata);
}
new SignalFixtures()->load($this->entityManager);
}
#[\Override]
protected function tearDown(): void
{
parent::tearDown();
if (isset($this->entityManager)) {
$this->entityManager->close();
unset($this->entityManager);
}
}
public function testIndexReturnsRecentSignals(): void
{
$this->client->request('GET', '/api/signals');
self::assertResponseIsSuccessful();
$content = $this->client->getResponse()->getContent();
self::assertIsString($content);
$payload = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
self::assertSame(substr(hash('sha256', '127.0.0.1'), 0, 12), $payload['clientKey']);
self::assertCount(3, $payload['points']);
self::assertSame(3, $payload['totals']['points']);
self::assertSame(2, $payload['totals']['contributors']);
self::assertSame(-11.6852, $payload['points'][0]['lat']);
}
public function testIndexRespectsLimitQueryParameter(): void
{
$this->client->request('GET', '/api/signals?limit=1');
self::assertResponseIsSuccessful();
$content = $this->client->getResponse()->getContent();
self::assertIsString($content);
$payload = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
self::assertCount(1, $payload['points']);
self::assertSame(1, $payload['totals']['points']);
}
public function testStorePersistsNewSignal(): void
{
$body = [
'lat' => -11.6901,
'lng' => 27.4959,
];
$this->client->request('POST', '/api/signals', [], [], [
'CONTENT_TYPE' => 'application/json',
], json_encode($body, JSON_THROW_ON_ERROR));
self::assertResponseStatusCodeSame(Response::HTTP_CREATED);
$content = $this->client->getResponse()->getContent();
self::assertIsString($content);
$payload = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
self::assertSame('stored', $payload['status']);
self::assertSame($body['lat'], $payload['point']['lat']);
self::assertSame($body['lng'], $payload['point']['lng']);
$repository = $this->entityManager->getRepository(Signal::class);
$signals = $repository->findAll();
self::assertCount(4, $signals);
}
public function testStoreRejectsInvalidCoordinates(): void
{
$body = [
'lat' => 181,
'lng' => 10,
];
$this->client->request('POST', '/api/signals', [], [], [
'CONTENT_TYPE' => 'application/json',
], json_encode($body, JSON_THROW_ON_ERROR));
self::assertResponseStatusCodeSame(Response::HTTP_UNPROCESSABLE_ENTITY);
$content = $this->client->getResponse()->getContent();
self::assertIsString($content);
$payload = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
self::assertSame('out_of_bounds', $payload['error']);
}
}