Files
archived-ux-map/tests/MapTest.php
Hugo Alliaume 0a7f3a1b4e [Map] Deprecate option title from Polygon, Polyline, Rectangle and Circle in favor of infoWindow
While writing E2E tests for Map, I found that our `title` option from `Polygon`, `Polyline`, `Rectangle` and `Circle` was wrongly used, and does not make sense.

Using `title` won't add an HTML attribute `title` as I expected, it's not something supported by Google nor Leaflet.
Instead, we used it to display a popup, like the `infoWindow` (which is more complete).

I suggest deprecating `title` from 2.x and remove it in 3.0.
2025-08-21 08:30:19 +02:00

435 lines
16 KiB
PHP

<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\UX\Map\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\UX\Map\Circle;
use Symfony\UX\Map\Exception\InvalidArgumentException;
use Symfony\UX\Map\InfoWindow;
use Symfony\UX\Map\Map;
use Symfony\UX\Map\Marker;
use Symfony\UX\Map\Point;
use Symfony\UX\Map\Polygon;
use Symfony\UX\Map\Polyline;
use Symfony\UX\Map\Rectangle;
class MapTest extends TestCase
{
protected function setUp(): void
{
DummyOptions::registerToNormalizer();
}
protected function tearDown(): void
{
DummyOptions::unregisterFromNormalizer();
}
public function testCenterValidation()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('The map "center" must be explicitly set when not enabling "fitBoundsToMarkers" feature.');
$map = new Map();
$map->toArray();
}
public function testZoomValidation()
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage('The map "zoom" must be explicitly set when not enabling "fitBoundsToMarkers" feature.');
$map = new Map(
center: new Point(48.8566, 2.3522)
);
$map->toArray();
}
public function testZoomAndCenterCanBeOmittedIfFitBoundsToMarkers()
{
$map = new Map(
fitBoundsToMarkers: true
);
$array = $map->toArray();
self::assertSame([
'center' => null,
'zoom' => null,
'fitBoundsToMarkers' => true,
'options' => $array['options'],
'markers' => [],
'polygons' => [],
'polylines' => [],
'circles' => [],
'rectangles' => [],
'extra' => null,
'minZoom' => null,
'maxZoom' => null,
], $array);
}
public function testWithMinimumConfiguration()
{
$map = new Map();
$map
->center(new Point(48.8566, 2.3522))
->zoom(6);
$array = $map->toArray();
self::assertSame([
'center' => ['lat' => 48.8566, 'lng' => 2.3522],
'zoom' => 6.0,
'fitBoundsToMarkers' => false,
'options' => $array['options'],
'markers' => [],
'polygons' => [],
'polylines' => [],
'circles' => [],
'rectangles' => [],
'extra' => null,
'minZoom' => null,
'maxZoom' => null,
], $array);
}
public function testWithMaximumConfiguration()
{
$map = new Map();
$map
->center(new Point(48.8566, 2.3522))
->zoom(6)
->minZoom(3)
->maxZoom(15)
->fitBoundsToMarkers()
->options(new DummyOptions(mapId: '1a2b3c4d5e', mapType: 'roadmap'))
->addMarker(new Marker(
position: new Point(48.8566, 2.3522),
title: 'Paris',
infoWindow: new InfoWindow(headerContent: '<b>Paris</b>', content: 'Paris', position: new Point(48.8566, 2.3522), extra: ['baz' => 'qux']),
extra: ['foo' => 'bar'],
))
->addMarker(new Marker(
position: new Point(45.764, 4.8357),
title: 'Lyon',
infoWindow: new InfoWindow(headerContent: '<b>Lyon</b>', content: 'Lyon', position: new Point(45.764, 4.8357), opened: true)
))
->addMarker(new Marker(
position: new Point(43.2965, 5.3698),
title: 'Marseille',
infoWindow: new InfoWindow(headerContent: '<b>Marseille</b>', content: 'Marseille', position: new Point(43.2965, 5.3698), opened: true)
))
->addPolygon(new Polygon(
points: [
new Point(48.858844, 2.294351),
new Point(48.853, 2.3499),
new Point(48.8566, 2.3522),
],
infoWindow: null,
))
->addPolygon(new Polygon(
points: [
new Point(45.764043, 4.835659),
new Point(45.75, 4.85),
new Point(45.77, 4.82),
],
infoWindow: new InfoWindow(
headerContent: '<b>Polygon 2</b>',
content: 'A polygon around Lyon with some additional info.',
position: new Point(45.764, 4.8357),
opened: true,
autoClose: true,
),
))
->addPolyline(new Polyline(
points: [
new Point(48.858844, 2.294351),
new Point(48.853, 2.3499),
new Point(48.8566, 2.3522),
],
infoWindow: null,
))
->addPolyline(new Polyline(
points: [
new Point(45.764043, 4.835659),
new Point(45.75, 4.85),
new Point(45.77, 4.82),
],
infoWindow: new InfoWindow(
headerContent: '<b>Polyline 2</b>',
content: 'A polyline around Lyon with some additional info.',
position: new Point(45.764, 4.8357),
opened: true,
autoClose: true,
),
))
->addCircle(new Circle(
center: new Point(48.8566, 2.3522),
radius: 500,
infoWindow: new InfoWindow(
headerContent: '<b>Circle around Paris</b>',
content: 'A circle with a radius of 500 meters around Paris.',
position: new Point(48.8566, 2.3522),
opened: true,
autoClose: true,
),
))
->addCircle(new Circle(
center: new Point(45.764, 4.8357),
radius: 300,
infoWindow: new InfoWindow(
headerContent: '<b>Circle around Lyon</b>',
content: 'A circle with a radius of 300 meters around Lyon.',
position: new Point(45.764, 4.8357),
opened: true,
autoClose: true,
),
))
->addRectangle(new Rectangle(
southWest: new Point(48.853, 2.3499),
northEast: new Point(48.8566, 2.3522),
infoWindow: new InfoWindow(
headerContent: '<b>Rectangle around Paris</b>',
content: 'A rectangle around Paris.',
position: new Point(48.8566, 2.3522),
opened: true,
autoClose: true,
),
))
->addRectangle(new Rectangle(
southWest: new Point(45.75, 4.85),
northEast: new Point(45.77, 4.82),
infoWindow: new InfoWindow(
headerContent: '<b>Rectangle around Lyon</b>',
content: 'A rectangle around Lyon.',
position: new Point(45.764, 4.8357),
opened: true,
autoClose: true,
),
))
->extra([
'foo' => 'bar',
'bar' => true,
'baz' => ['qux' => 'quux'],
])
;
self::assertEquals([
'center' => ['lat' => 48.8566, 'lng' => 2.3522],
'zoom' => 6.0,
'minZoom' => 3.0,
'maxZoom' => 15.0,
'fitBoundsToMarkers' => true,
'options' => [
'@provider' => 'dummy',
'mapId' => '1a2b3c4d5e',
'mapType' => 'roadmap',
],
'markers' => [
[
'position' => ['lat' => 48.8566, 'lng' => 2.3522],
'title' => 'Paris',
'infoWindow' => [
'headerContent' => '<b>Paris</b>',
'content' => 'Paris',
'position' => ['lat' => 48.8566, 'lng' => 2.3522],
'opened' => false,
'autoClose' => true,
'extra' => ['baz' => 'qux'],
],
'icon' => null,
'extra' => ['foo' => 'bar'],
'id' => null,
],
[
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'title' => 'Lyon',
'infoWindow' => [
'headerContent' => '<b>Lyon</b>',
'content' => 'Lyon',
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'icon' => null,
'extra' => [],
'id' => null,
],
[
'position' => ['lat' => 43.2965, 'lng' => 5.3698],
'title' => 'Marseille',
'infoWindow' => [
'headerContent' => '<b>Marseille</b>',
'content' => 'Marseille',
'position' => ['lat' => 43.2965, 'lng' => 5.3698],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'icon' => null,
'extra' => [],
'id' => null,
],
],
'polygons' => [
[
'points' => [
['lat' => 48.858844, 'lng' => 2.294351],
['lat' => 48.853, 'lng' => 2.3499],
['lat' => 48.8566, 'lng' => 2.3522],
],
'title' => null,
'infoWindow' => null,
'extra' => [],
'id' => null,
],
[
'points' => [
['lat' => 45.764043, 'lng' => 4.835659],
['lat' => 45.75, 'lng' => 4.85],
['lat' => 45.77, 'lng' => 4.82],
],
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Polygon 2</b>',
'content' => 'A polygon around Lyon with some additional info.',
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
],
'polylines' => [
[
'points' => [
['lat' => 48.858844, 'lng' => 2.294351],
['lat' => 48.853, 'lng' => 2.3499],
['lat' => 48.8566, 'lng' => 2.3522],
],
'title' => null,
'infoWindow' => null,
'extra' => [],
'id' => null,
],
[
'points' => [
['lat' => 45.764043, 'lng' => 4.835659],
['lat' => 45.75, 'lng' => 4.85],
['lat' => 45.77, 'lng' => 4.82],
],
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Polyline 2</b>',
'content' => 'A polyline around Lyon with some additional info.',
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
],
'circles' => [
[
'center' => ['lat' => 48.8566, 'lng' => 2.3522],
'radius' => 500,
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Circle around Paris</b>',
'content' => 'A circle with a radius of 500 meters around Paris.',
'position' => ['lat' => 48.8566, 'lng' => 2.3522],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
[
'center' => ['lat' => 45.764, 'lng' => 4.8357],
'radius' => 300,
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Circle around Lyon</b>',
'content' => 'A circle with a radius of 300 meters around Lyon.',
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
],
'rectangles' => [
[
'southWest' => ['lat' => 48.853, 'lng' => 2.3499],
'northEast' => ['lat' => 48.8566, 'lng' => 2.3522],
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Rectangle around Paris</b>',
'content' => 'A rectangle around Paris.',
'position' => ['lat' => 48.8566, 'lng' => 2.3522],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
[
'southWest' => ['lat' => 45.75, 'lng' => 4.85],
'northEast' => ['lat' => 45.77, 'lng' => 4.82],
'title' => null,
'infoWindow' => [
'headerContent' => '<b>Rectangle around Lyon</b>',
'content' => 'A rectangle around Lyon.',
'position' => ['lat' => 45.764, 'lng' => 4.8357],
'opened' => true,
'autoClose' => true,
'extra' => [],
],
'extra' => [],
'id' => null,
],
],
'extra' => [
'foo' => 'bar',
'bar' => true,
'baz' => ['qux' => 'quux'],
],
], $map->toArray());
}
/**
* @testWith [-1, null, null, "The \"minZoom\" must be greater than or equal to 0."]
* [null, -1, null, "The \"zoom\" must be greater than or equal to 0."]
* [null, null, -1, "The \"maxZoom\" must be greater than or equal to 0."]
* [5, 2, null, "The \"zoom\" must be greater than or equal to \"minZoom\"."]
* [null, 5, 2, "The \"zoom\" must be less than or equal to \"maxZoom\"."]
* [2.1, null, 2.0, "The \"minZoom\" must be less than or equal to \"maxZoom\"."]
*/
public function testZoomsValidation(?float $minZoom, ?float $zoom, ?float $maxZoom, string $expectedExceptionMessage)
{
self::expectException(InvalidArgumentException::class);
self::expectExceptionMessage($expectedExceptionMessage);
new Map(zoom: $zoom, minZoom: $minZoom, maxZoom: $maxZoom);
}
}