diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 5e5525bc..37c7c85f 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -396,7 +396,7 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({ getOptions: function () { const options = [] this.builder.map.eachDataLayerReverse((datalayer) => { - if (datalayer.isLoaded() && !datalayer.isReadOnly() && datalayer.canBrowse()) { + if (datalayer.isLoaded() && !datalayer.isDataReadOnly() && datalayer.canBrowse()) { options.push([L.stamp(datalayer), datalayer.getName()]) } }) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 765f8d65..df1b0c16 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -1310,14 +1310,14 @@ L.U.Map.include({ datalayer = this.lastUsedDataLayer if ( datalayer && - !datalayer.isReadOnly() && + !datalayer.isDataReadOnly() && datalayer.canBrowse() && datalayer.isVisible() ) { return datalayer } datalayer = this.findDataLayer((datalayer) => { - if (!datalayer.isReadOnly() && datalayer.canBrowse()) { + if (!datalayer.isDataReadOnly() && datalayer.canBrowse()) { fallback = datalayer if (datalayer.isVisible()) return true } diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 417cb01f..bc4b5684 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1199,6 +1199,11 @@ L.U.DataLayer = L.Evented.extend({ return this.options.editMode === 'disabled' }, + isDataReadOnly: function () { + // This layer cannot accept features + return this.isReadOnly() || this.isRemoteLayer() + }, + save: function () { if (this.isDeleted) return this.saveDelete() if (!this.isLoaded()) { diff --git a/umap/tests/integration/test_map.py b/umap/tests/integration/test_map.py new file mode 100644 index 00000000..a5dd0dbc --- /dev/null +++ b/umap/tests/integration/test_map.py @@ -0,0 +1,37 @@ +import pytest +from playwright.sync_api import expect + +from umap.models import Map + +pytestmark = pytest.mark.django_db + + +def test_remote_layer_should_not_be_used_as_datalayer_for_created_features( + map, live_server, datalayer, page +): + # Faster than doing a login + map.edit_status = Map.ANONYMOUS + map.save() + datalayer.settings["remoteData"] = { + "url": "https://overpass-api.de/api/interpreter?data=[out:xml];node[harbour=yes]({south},{west},{north},{east});out body;", + "format": "osm", + "from": "10", + } + datalayer.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}?edit") + toggle = page.get_by_title("See data layers") + expect(toggle).to_be_visible() + toggle.click() + layers = page.locator(".umap-browse-datalayers li") + expect(layers).to_have_count(1) + map_el = page.locator("#map") + add_marker = page.get_by_title("Draw a marker") + expect(add_marker).to_be_visible() + marker = page.locator(".leaflet-marker-icon") + expect(marker).to_have_count(0) + add_marker.click() + map_el.click(position={"x": 100, "y": 100}) + expect(marker).to_have_count(1) + # A new datalayer has been created to host this created feature + # given the remote one cannot accept new features + expect(layers).to_have_count(2)