diff --git a/pyproject.toml b/pyproject.toml index 2b4852d2..dbf0914f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,6 +62,7 @@ test = [ "pytest-django==4.8.0", "pytest-playwright==0.5.0", "pytest-xdist>=3.5.0,<4", + "pytest-xprocess>=1.0.1", ] docker = [ "uwsgi==2.0.26", diff --git a/umap/tests/integration/conftest.py b/umap/tests/integration/conftest.py index 34e3545b..756cc44d 100644 --- a/umap/tests/integration/conftest.py +++ b/umap/tests/integration/conftest.py @@ -1,7 +1,9 @@ import os +from pathlib import Path import pytest from playwright.sync_api import expect +from xprocess import ProcessStarter @pytest.fixture(autouse=True) @@ -33,3 +35,20 @@ def login(context, settings, live_server): return page return do_login + + +@pytest.fixture(scope="session") +def websocket_server(xprocess): + class Starter(ProcessStarter): + settings_path = ( + (Path(__file__).parent.parent / "settings.py").absolute().as_posix() + ) + os.environ["UMAP_SETTINGS"] = settings_path + pattern = "Waiting for connections*" + args = ["python", "-m", "umap.ws"] + timeout = 5 + + logfile = xprocess.ensure("websocket_server", Starter) + print(logfile) + yield + xprocess.getinfo("websocket_server").terminate() diff --git a/umap/tests/integration/test_websocket_sync.py b/umap/tests/integration/test_websocket_sync.py new file mode 100644 index 00000000..0d66b269 --- /dev/null +++ b/umap/tests/integration/test_websocket_sync.py @@ -0,0 +1,43 @@ +import re + +from playwright.sync_api import expect + +from umap.models import Map + +from ..base import DataLayerFactory, MapFactory + +DATALAYER_UPDATE = re.compile(r".*/datalayer/update/.*") + + +def test_websocket_connection_can_sync_markers( + context, live_server, websocket_server, tilelayer +): + # Create a new map + map = MapFactory(name="sync", edit_status=Map.ANONYMOUS) + map.settings["properties"]["syncEnabled"] = True + map.save() + DataLayerFactory(map=map, data={}) + + # Now navigate to this map from two tabs + peerA = context.new_page() + peerA.goto(f"{live_server.url}{map.get_absolute_url()}?edit") + + # Now navigate to this map from another tab + peerB = context.new_page() + peerB.goto(f"{live_server.url}{map.get_absolute_url()}?edit") + + a_marker_pane = peerA.locator(".leaflet-marker-pane > div") + b_marker_pane = peerB.locator(".leaflet-marker-pane > div") + expect(a_marker_pane).to_have_count(0) + expect(b_marker_pane).to_have_count(0) + + # Click on the Draw a marker button on a new map. + a_create_marker = peerA.get_by_title("Draw a marker") + expect(a_create_marker).to_be_visible() + a_create_marker.click() + + # Click on the map, it will place a marker at the given position. + a_map_el = peerA.locator("#map") + a_map_el.click(position={"x": 220, "y": 220}) + expect(a_marker_pane).to_have_count(1) + expect(b_marker_pane).to_have_count(1) diff --git a/umap/tests/settings.py b/umap/tests/settings.py index 479737a9..4a5f0130 100644 --- a/umap/tests/settings.py +++ b/umap/tests/settings.py @@ -24,3 +24,8 @@ if os.environ.get("GITHUB_ACTIONS", False) == "true": PASSWORD_HASHERS = [ "django.contrib.auth.hashers.MD5PasswordHasher", ] + + +WEBSOCKET_ENABLED = True +WEBSOCKET_PORT = "8010" +WEBSOCKET_URI = "ws://localhost:8010"