diff --git a/umap/static/umap/test/Polygon.js b/umap/static/umap/test/Polygon.js index f0c1124c..d0860167 100644 --- a/umap/static/umap/test/Polygon.js +++ b/umap/static/umap/test/Polygon.js @@ -108,260 +108,4 @@ describe('U.Polygon', function () { }) }) - describe('#contextmenu', function () { - afterEach(function () { - // Make sure contextmenu is hidden - happen.once(document, { type: 'keydown', keyCode: 27 }) - }) - - describe('#in edit mode', function () { - it('should allow to remove shape when multi', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]], - [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], - ], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.equal(qst('Remove shape from the multi'), 1) - }) - - it('should not allow to remove shape when not multi', function () { - var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.notOk(qst('Remove shape from the multi')) - }) - - it('should not allow to isolate shape when not multi', function () { - var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.notOk(qst('Extract shape to separate feature')) - }) - - it('should allow to isolate shape when multi', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]], - [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], - ], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.ok(qst('Extract shape to separate feature')) - }) - - it('should not allow to transform to lines when multi', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]], - [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], - ], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.notOk(qst('Transform to lines')) - }) - - it('should not allow to transform to lines when hole', function () { - var latlngs = [ - [ - [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)], - [p2ll(120, 150), p2ll(150, 180), p2ll(180, 120)], - ], - ], - layer = new U.Polygon(map, latlngs, { - datalayer: datalayer, - }).addTo(datalayer) - happen.once(layer._path, { type: 'contextmenu' }) - assert.notOk(qst('Transform to lines')) - }) - - it('should allow to transform to lines when not multi', function () { - var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]] - new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ) - happen.at('contextmenu', 150, 150) - assert.equal(qst('Transform to lines'), 1) - }) - - it('should not allow to transfer shape when not editedFeature', function () { - new U.Polygon(map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], { - datalayer: datalayer, - }).addTo(datalayer) - happen.at('contextmenu', 110, 160) - assert.equal(qst('Delete this feature'), 1) // Make sure we have right clicked on the polygon. - assert.notOk(qst('Transfer shape to edited feature')) - }) - - it('should not allow to transfer shape when editedFeature is not a polygon', function () { - var layer = new U.Polygon( - map, - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], - { datalayer: datalayer } - ).addTo(datalayer), - other = new U.Polyline(map, [p2ll(200, 250), p2ll(200, 300)], { - datalayer: datalayer, - }).addTo(datalayer) - other.edit() - happen.once(layer._path, { type: 'contextmenu' }) - assert.equal(qst('Delete this feature'), 1) // Make sure we have right clicked on the polygon. - assert.notOk(qst('Transfer shape to edited feature')) - }) - - it('should allow to transfer shape when another polygon is edited', function () { - datalayer.empty() - var layer = new U.Polygon( - map, - [p2ll(200, 300), p2ll(300, 200), p2ll(200, 100)], - { datalayer: datalayer } - ).addTo(datalayer) - layer.edit() // This moves the map to put "other" at the center. - var other = new U.Polygon( - map, - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], - { datalayer: datalayer } - ).addTo(datalayer) - happen.once(other._path, { type: 'contextmenu' }) - assert.equal(qst('Transfer shape to edited feature'), 1) - layer.remove() - }) - }) - }) - - describe('#addShape', function () { - it('"add shape" control should not be visible by default', function () { - assert.notOk(qs('.umap-draw-polygon-multi')) - }) - - it('"add shape" control should be visible when editing a Polygon', function () { - var layer = new U.Polygon(map, [p2ll(100, 100), p2ll(100, 200)], { - datalayer: datalayer, - }).addTo(datalayer) - layer.edit() - assert.ok(qs('.umap-draw-polygon-multi')) - }) - - it('"add shape" control should extend the same multi', function () { - var layer = new U.Polygon( - map, - [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)], - { datalayer: datalayer } - ).addTo(datalayer) - layer.edit() - assert.notOk(layer.isMulti()) - happen.click(qs('.umap-draw-polygon-multi')) - happen.at('mousemove', 300, 300) - happen.at('click', 300, 300) - happen.at('mousemove', 350, 300) - happen.at('click', 350, 300) - happen.at('click', 350, 300) - assert.ok(layer.isMulti()) - assert.equal(datalayer._index.length, 1) - }) - }) - - describe('#transferShape', function () { - it('should transfer simple polygon shape to another polygon', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ), - other = new U.Polygon( - map, - [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], - { datalayer: datalayer } - ).addTo(datalayer) - assert.ok(map.hasLayer(layer)) - layer.transferShape(p2ll(150, 150), other) - assert.equal(other._latlngs.length, 2) - assert.deepEqual(other._latlngs[1][0], latlngs) - assert.notOk(map.hasLayer(layer)) - }) - - it('should transfer multipolygon shape to another polygon', function () { - var latlngs = [ - [ - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - [p2ll(120, 150), p2ll(150, 180), p2ll(180, 120)], - ], - [[p2ll(200, 300), p2ll(300, 200)]], - ], - layer = new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ), - other = new U.Polygon( - map, - [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], - { datalayer: datalayer } - ).addTo(datalayer) - assert.ok(map.hasLayer(layer)) - layer.transferShape(p2ll(150, 150), other) - assert.equal(other._latlngs.length, 2) - assert.deepEqual(other._latlngs[1][0], latlngs[0][0]) - assert.ok(map.hasLayer(layer)) - assert.equal(layer._latlngs.length, 1) - }) - }) - - describe('#isolateShape', function () { - it('should not allow to isolate simple polygon', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ) - assert.equal(datalayer._index.length, 1) - assert.ok(map.hasLayer(layer)) - layer.isolateShape(p2ll(150, 150)) - assert.equal(layer._latlngs[0].length, 3) - assert.equal(datalayer._index.length, 1) - }) - - it('should isolate multipolygon shape', function () { - var latlngs = [ - [ - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - [p2ll(120, 150), p2ll(150, 180), p2ll(180, 120)], - ], - [[p2ll(200, 300), p2ll(300, 200)]], - ], - layer = new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ) - assert.equal(datalayer._index.length, 1) - assert.ok(map.hasLayer(layer)) - var other = layer.isolateShape(p2ll(150, 150)) - assert.equal(datalayer._index.length, 2) - assert.equal(other._latlngs.length, 2) - assert.deepEqual(other._latlngs[0], latlngs[0][0]) - assert.ok(map.hasLayer(layer)) - assert.ok(map.hasLayer(other)) - assert.equal(layer._latlngs.length, 1) - other.remove() - }) - }) - - describe('#clone', function () { - it('should clone polygon', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new U.Polygon(map, latlngs, { datalayer: datalayer }).addTo( - datalayer - ) - assert.equal(datalayer._index.length, 1) - other = layer.clone() - assert.ok(map.hasLayer(other)) - assert.equal(datalayer._index.length, 2) - // Must not be the same reference - assert.notEqual(layer._latlngs, other._latlngs) - assert.equal(L.Util.formatNum(layer._latlngs[0][0].lat), other._latlngs[0][0].lat) - assert.equal(L.Util.formatNum(layer._latlngs[0][0].lng), other._latlngs[0][0].lng) - }) - }) }) diff --git a/umap/tests/integration/test_drawing.py b/umap/tests/integration/test_drawing.py index 4b04ea74..d84d9b3d 100644 --- a/umap/tests/integration/test_drawing.py +++ b/umap/tests/integration/test_drawing.py @@ -119,125 +119,3 @@ def test_clicking_esc_should_delete_line_if_invalid(page, live_server, tilelayer page.keyboard.press("Escape") expect(lines).to_have_count(0) expect(guide).to_have_count(0) - - -def test_draw_polygon(page, live_server, tilelayer): - page.goto(f"{live_server.url}/en/map/new/") - - # Click on the Draw a polygon button on a new map. - create_line = page.locator(".leaflet-control-toolbar ").get_by_title( - "Draw a polygon" - ) - create_line.click() - - # Check no polygon is present by default. - # We target with the color, because there is also the drawing line guide (dash-array) - # around - lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") - guide = page.locator(".leaflet-overlay-pane > svg > g > path") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) - - # Click on the map, it will create a polygon. - map = page.locator("#map") - map.click(position={"x": 200, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(1) - map.click(position={"x": 100, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(2) - map.click(position={"x": 100, "y": 100}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(2) - # Click again to finish - map.click(position={"x": 100, "y": 100}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(0) - - -def test_clicking_esc_should_finish_polygon(page, live_server, tilelayer): - page.goto(f"{live_server.url}/en/map/new/") - - # Click on the Draw a polygon button on a new map. - create_line = page.locator(".leaflet-control-toolbar ").get_by_title( - "Draw a polygon" - ) - create_line.click() - - # Check no polygon is present by default. - # We target with the color, because there is also the drawing line guide (dash-array) - # around - lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") - guide = page.locator(".leaflet-overlay-pane > svg > g > path") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) - - # Click on the map, it will create a polygon. - map = page.locator("#map") - map.click(position={"x": 200, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(1) - map.click(position={"x": 100, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(2) - map.click(position={"x": 100, "y": 100}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(2) - # Click ESC to finish - page.keyboard.press("Escape") - expect(lines).to_have_count(1) - expect(guide).to_have_count(0) - - -def test_clicking_esc_should_delete_polygon_if_empty(page, live_server, tilelayer): - page.goto(f"{live_server.url}/en/map/new/") - - # Click on the Draw a polygon button on a new map. - create_line = page.locator(".leaflet-control-toolbar ").get_by_title( - "Draw a polygon" - ) - create_line.click() - - # Check no polygon is present by default. - # We target with the color, because there is also the drawing line guide (dash-array) - # around - lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") - guide = page.locator(".leaflet-overlay-pane > svg > g > path") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) - - # Click ESC to finish, no polygon should have been created - page.keyboard.press("Escape") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) - - -def test_clicking_esc_should_delete_polygon_if_invalid(page, live_server, tilelayer): - page.goto(f"{live_server.url}/en/map/new/") - - # Click on the Draw a polygon button on a new map. - create_line = page.locator(".leaflet-control-toolbar ").get_by_title( - "Draw a polygon" - ) - create_line.click() - - # Check no polygon is present by default. - # We target with the color, because there is also the drawing line guide (dash-array) - # around - lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") - guide = page.locator(".leaflet-overlay-pane > svg > g > path") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) - - # Click on the map twice, it will start a polygon. - map = page.locator("#map") - map.click(position={"x": 200, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(1) - map.click(position={"x": 100, "y": 200}) - expect(lines).to_have_count(1) - expect(guide).to_have_count(2) - # Click ESC to finish, the polygon is invalid, it should not be persisted - page.keyboard.press("Escape") - expect(lines).to_have_count(0) - expect(guide).to_have_count(0) diff --git a/umap/tests/integration/test_polygon.py b/umap/tests/integration/test_polygon.py new file mode 100644 index 00000000..7dfbe96c --- /dev/null +++ b/umap/tests/integration/test_polygon.py @@ -0,0 +1,358 @@ +import json +import re +from pathlib import Path + +import pytest +from playwright.sync_api import expect + +from umap.models import DataLayer + +pytestmark = pytest.mark.django_db + + +def save_and_get_json(page): + with page.expect_response(re.compile(r".*/datalayer/create/.*")): + page.get_by_role("button", name="Save").click() + datalayer = DataLayer.objects.last() + return json.loads(Path(datalayer.geojson.path).read_text()) + + +def test_draw_polygon(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + # Click on the Draw a polygon button on a new map. + create_line = page.locator(".leaflet-control-toolbar ").get_by_title( + "Draw a polygon" + ) + create_line.click() + + # Check no polygon is present by default. + # We target with the color, because there is also the drawing line guide (dash-array) + # around + lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") + guide = page.locator(".leaflet-overlay-pane > svg > g > path") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + # Click on the map, it will create a polygon. + map = page.locator("#map") + map.click(position={"x": 200, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(1) + map.click(position={"x": 100, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(2) + map.click(position={"x": 100, "y": 100}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(2) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(0) + + +def test_clicking_esc_should_finish_polygon(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + # Click on the Draw a polygon button on a new map. + create_line = page.locator(".leaflet-control-toolbar ").get_by_title( + "Draw a polygon" + ) + create_line.click() + + # Check no polygon is present by default. + # We target with the color, because there is also the drawing line guide (dash-array) + # around + lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") + guide = page.locator(".leaflet-overlay-pane > svg > g > path") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + # Click on the map, it will create a polygon. + map = page.locator("#map") + map.click(position={"x": 200, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(1) + map.click(position={"x": 100, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(2) + map.click(position={"x": 100, "y": 100}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(2) + # Click ESC to finish + page.keyboard.press("Escape") + expect(lines).to_have_count(1) + expect(guide).to_have_count(0) + + +def test_clicking_esc_should_delete_polygon_if_empty(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + # Click on the Draw a polygon button on a new map. + create_line = page.locator(".leaflet-control-toolbar ").get_by_title( + "Draw a polygon" + ) + create_line.click() + + # Check no polygon is present by default. + # We target with the color, because there is also the drawing line guide (dash-array) + # around + lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") + guide = page.locator(".leaflet-overlay-pane > svg > g > path") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + # Click ESC to finish, no polygon should have been created + page.keyboard.press("Escape") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + +def test_clicking_esc_should_delete_polygon_if_invalid(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + # Click on the Draw a polygon button on a new map. + create_line = page.locator(".leaflet-control-toolbar ").get_by_title( + "Draw a polygon" + ) + create_line.click() + + # Check no polygon is present by default. + # We target with the color, because there is also the drawing line guide (dash-array) + # around + lines = page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']") + guide = page.locator(".leaflet-overlay-pane > svg > g > path") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + # Click on the map twice, it will start a polygon. + map = page.locator("#map") + map.click(position={"x": 200, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(1) + map.click(position={"x": 100, "y": 200}) + expect(lines).to_have_count(1) + expect(guide).to_have_count(2) + # Click ESC to finish, the polygon is invalid, it should not be persisted + page.keyboard.press("Escape") + expect(lines).to_have_count(0) + expect(guide).to_have_count(0) + + +def test_can_draw_multi(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + multi_button = page.get_by_title("Add a polygon to the current multi") + expect(multi_button).to_be_hidden() + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 150, "y": 100}) + map.click(position={"x": 150, "y": 150}) + map.click(position={"x": 100, "y": 150}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(multi_button).to_be_visible() + expect(polygons).to_have_count(1) + multi_button.click() + map.click(position={"x": 250, "y": 200}) + map.click(position={"x": 250, "y": 250}) + map.click(position={"x": 200, "y": 250}) + map.click(position={"x": 200, "y": 200}) + # Click again to finish + map.click(position={"x": 200, "y": 200}) + expect(polygons).to_have_count(1) + page.keyboard.press("Escape") + expect(multi_button).to_be_hidden() + polygons.first.click(button="right", position={"x": 10, "y": 10}) + expect(page.get_by_role("link", name="Transform to lines")).to_be_hidden() + expect(page.get_by_role("link", name="Remove shape from multi")).to_be_hidden() + + +def test_can_draw_hole(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + page.get_by_title("Draw a polygon").click() + + polygons = page.locator(".leaflet-overlay-pane path") + vertices = page.locator(".leaflet-vertex-icon") + + # Click on the map, it will create a polygon. + map = page.locator("#map") + map.click(position={"x": 200, "y": 100}) + map.click(position={"x": 200, "y": 200}) + map.click(position={"x": 100, "y": 200}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + expect(vertices).to_have_count(4) + + # First vertex of the hole will be created here + map.click(position={"x": 180, "y": 120}) + page.get_by_role("link", name="Start a hole here").click() + map.click(position={"x": 180, "y": 180}) + map.click(position={"x": 120, "y": 180}) + map.click(position={"x": 120, "y": 120}) + # Click again to finish + map.click(position={"x": 120, "y": 120}) + expect(polygons).to_have_count(1) + expect(vertices).to_have_count(8) + # Click on the polygon but not in the hole + polygons.first.click(button="right", position={"x": 10, "y": 10}) + expect(page.get_by_role("link", name="Transform to lines")).to_be_hidden() + + +def test_can_transfer_shape_from_simple_polygon(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + + # Draw a first polygon + map.click(position={"x": 150, "y": 100}) + map.click(position={"x": 150, "y": 150}) + map.click(position={"x": 100, "y": 150}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + + # Draw another polygon + page.get_by_title("Draw a polygon").click() + map.click(position={"x": 250, "y": 200}) + map.click(position={"x": 250, "y": 250}) + map.click(position={"x": 200, "y": 250}) + map.click(position={"x": 200, "y": 200}) + # Click again to finish + map.click(position={"x": 200, "y": 200}) + expect(polygons).to_have_count(2) + + # Now that polygon 2 is selected, right click on first one + # and transfer shape + polygons.first.click(position={"x": 20, "y": 20}, button="right") + page.get_by_role("link", name="Transfer shape to edited feature").click() + expect(polygons).to_have_count(1) + + +def test_can_transfer_shape(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 150, "y": 100}) + map.click(position={"x": 150, "y": 150}) + map.click(position={"x": 100, "y": 150}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + extract_button = page.get_by_role("link", name="Extract shape to separate feature") + expect(extract_button).to_be_hidden() + page.get_by_title("Add a polygon to the current multi").click() + map.click(position={"x": 250, "y": 200}) + map.click(position={"x": 250, "y": 250}) + map.click(position={"x": 200, "y": 250}) + map.click(position={"x": 200, "y": 200}) + # Click again to finish + map.click(position={"x": 200, "y": 200}) + expect(polygons).to_have_count(1) + polygons.first.click(position={"x": 20, "y": 20}, button="right") + extract_button.click() + expect(polygons).to_have_count(2) + + +def test_cannot_transfer_shape_to_line(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 150, "y": 100}) + map.click(position={"x": 150, "y": 150}) + map.click(position={"x": 100, "y": 150}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + extract_button = page.get_by_role("link", name="Extract shape to separate feature") + polygons.first.click(position={"x": 20, "y": 20}, button="right") + expect(extract_button).to_be_hidden() + page.get_by_title("Draw a polyline").click() + map.click(position={"x": 200, "y": 250}) + map.click(position={"x": 200, "y": 200}) + # Click again to finish + map.click(position={"x": 200, "y": 200}) + expect(polygons).to_have_count(2) + polygons.first.click(position={"x": 20, "y": 20}, button="right") + expect(extract_button).to_be_hidden() + + +def test_cannot_transfer_shape_to_marker(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 150, "y": 100}) + map.click(position={"x": 150, "y": 150}) + map.click(position={"x": 100, "y": 150}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + extract_button = page.get_by_role("link", name="Extract shape to separate feature") + polygons.first.click(position={"x": 20, "y": 20}, button="right") + expect(extract_button).to_be_hidden() + page.get_by_title("Draw a marker").click() + map.click(position={"x": 250, "y": 200}) + expect(polygons).to_have_count(1) + polygons.first.click(position={"x": 20, "y": 20}, button="right") + expect(extract_button).to_be_hidden() + + +def test_can_clone_polygon(live_server, page, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + polygons = page.locator(".leaflet-overlay-pane path") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 200, "y": 100}) + map.click(position={"x": 200, "y": 200}) + map.click(position={"x": 100, "y": 200}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + polygons.first.click(button="right") + page.get_by_role("link", name="Clone this feature").click() + expect(polygons).to_have_count(2) + + +def test_can_transform_polygon_to_line(live_server, page, tilelayer, settings): + settings.UMAP_ALLOW_ANONYMOUS = True + page.goto(f"{live_server.url}/en/map/new/") + paths = page.locator(".leaflet-overlay-pane path") + polygons = page.locator(".leaflet-overlay-pane path[fill='DarkBlue']") + expect(polygons).to_have_count(0) + page.get_by_title("Draw a polygon").click() + map = page.locator("#map") + map.click(position={"x": 200, "y": 100}) + map.click(position={"x": 200, "y": 200}) + map.click(position={"x": 100, "y": 200}) + map.click(position={"x": 100, "y": 100}) + # Click again to finish + map.click(position={"x": 100, "y": 100}) + expect(polygons).to_have_count(1) + expect(paths).to_have_count(1) + polygons.first.click(button="right") + page.get_by_role("link", name="Transform to lines").click() + # No more polygons (will fill), but one path, it must be a line + expect(polygons).to_have_count(0) + expect(paths).to_have_count(1) + data = save_and_get_json(page) + assert len(data["features"]) == 1 + assert data["features"][0]["geometry"]["type"] == "LineString"