diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index 46193200..5da209da 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -39,11 +39,10 @@ U.Importer = L.Class.extend({ this.container, L._('Choose the layer to import in') ) - this.clearLabel = L.DomUtil.add( + this.clearLabel = L.DomUtil.element( 'label', - '', - this.container, - L._('Replace layer content') + { textContent: L._('Replace layer content'), for: 'datalayer-clear-check' }, + this.container ) this.submitInput = L.DomUtil.element( 'input', @@ -59,7 +58,7 @@ U.Importer = L.Class.extend({ ) this.clearFlag = L.DomUtil.element( 'input', - { type: 'checkbox', name: 'clear' }, + { type: 'checkbox', name: 'clear', id: 'datalayer-clear-check' }, this.clearLabel ) let option diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 7383f74c..77bda086 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -1540,7 +1540,7 @@ U.Map = L.Map.extend({ metadataFields = ['options.name', 'options.description'], title = L.DomUtil.create('h3', '', container) title.textContent = L._('Edit map properties') - const builder = new U.FormBuilder(this, metadataFields) + const builder = new U.FormBuilder(this, metadataFields, {className: 'map-metadata'}) const form = builder.build() container.appendChild(form) this._editControls(container) diff --git a/umap/static/umap/test/Map.js b/umap/static/umap/test/Map.js index e6350721..c6e6fc53 100644 --- a/umap/static/umap/test/Map.js +++ b/umap/static/umap/test/Map.js @@ -19,310 +19,6 @@ describe('U.Map', () => { resetMap() }) - describe('#init()', () => { - it('should be initialized', function () { - assert.equal(map.options.umap_id, 99) - }) - - it('should have created the edit button', function () { - assert.ok(qs('div.leaflet-control-edit-enable')) - }) - - it('should have datalayer control div', function () { - assert.ok(qs('div.leaflet-control-browse')) - }) - - it('should have datalayer actions div', function () { - assert.ok(qs('div.umap-browse-actions')) - }) - - it('should have icon container div', function () { - assert.ok(qs('div.icon_container')) - }) - - it('should hide icon container div when hiding datalayer', function () { - var el = qs( - '.leaflet-control-browse #browse_data_toggle_' + - L.stamp(datalayer) + - ' .layer-toggle' - ) - happen.click(el) - assert.notOk(qs('div.icon_container')) - }) - - it('enable edit on click on toggle button', function () { - var el = qs('div.leaflet-control-edit-enable button') - happen.click(el) - assert.isTrue(L.DomUtil.hasClass(document.body, 'umap-edit-enabled')) - }) - - it('should have only one datalayer in its index', function () { - assert.equal(map.datalayers_index.length, 1) - }) - }) - - describe('#editMetadata()', function () { - var form, input - - it('should build a form on editMetadata control click', function (done) { - var button = qs('a.update-map-settings') - assert.ok(button) - happen.click(button) - form = qs('form.umap-form') - input = qs('form[class="umap-form"] input[name="name"]') - assert.ok(form) - assert.ok(input) - done() - }) - - it('should update map name on input change', function () { - var new_name = 'This is a new name' - input.value = new_name - happen.once(input, { type: 'input' }) - assert.equal(map.options.name, new_name) - }) - - it('should have made Map dirty', function () { - assert.ok(map.isDirty) - }) - - it('should have added dirty class on map container', function () { - assert.ok(L.DomUtil.hasClass(map._container, 'umap-is-dirty')) - }) - }) - - describe('#delete()', function () { - let path = '/map/99/update/delete/', - oldConfirm, - newConfirm = function () { - return true - } - - before(function () { - oldConfirm = window.confirm - window.confirm = newConfirm - }) - after(function () { - window.confirm = oldConfirm - }) - - it('should ask for confirmation on delete link click', async function () { - let button = qs('a.update-map-settings') - assert.ok(button, 'update map info button exists') - happen.click(button) - let deleteLink = qs('button.umap-delete') - assert.ok(deleteLink, 'delete map button exists') - sinon.spy(window, 'confirm') - await fetchMock.post(path, { redirect: '#' }) - happen.click(deleteLink) - assert(window.confirm.calledOnce) - window.confirm.restore() - }) - }) - - describe('#importData()', function () { - let fileInput, textarea, submit, formatSelect, layerSelect, clearFlag - - it('should build a form on click', function () { - happen.click(qs('a.upload-data')) - fileInput = qs('.umap-upload input[type="file"]') - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - layerSelect = qs('.umap-upload select[name="datalayer"]') - assert.ok(fileInput) - assert.ok(submit) - assert.ok(textarea) - assert.ok(formatSelect) - assert.ok(layerSelect) - }) - - it('should import geojson from textarea', function () { - datalayer.empty() - assert.equal(datalayer._index.length, 0) - textarea.value = - '{"type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates": [6.922931671142578, 47.481161607175736]}, "type": "Feature", "properties": {"color": "", "name": "Chez R\u00e9my", "description": ""}}, {"geometry": {"type": "LineString", "coordinates": [[2.4609375, 48.88639177703194], [2.48291015625, 48.76343113791796], [2.164306640625, 48.719961222646276]]}, "type": "Feature", "properties": {"color": "", "name": "P\u00e9rif", "description": ""}}]}' - changeSelectValue(formatSelect, 'geojson') - happen.click(submit) - assert.equal(datalayer._index.length, 2) - }) - - it('should remove dot in property name', function () { - datalayer.empty() - assert.equal(datalayer._index.length, 0) - textarea.value = - '{"type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates": [6.922931671142578, 47.481161607175736]}, "type": "Feature", "properties": {"color": "", "name": "Chez R\u00e9my", "A . in the name": ""}}, {"geometry": {"type": "LineString", "coordinates": [[2.4609375, 48.88639177703194], [2.48291015625, 48.76343113791796], [2.164306640625, 48.719961222646276]]}, "type": "Feature", "properties": {"color": "", "name": "P\u00e9rif", "with a dot.": ""}}]}' - changeSelectValue(formatSelect, 'geojson') - happen.click(submit) - assert.equal(datalayer._index.length, 2) - assert.ok(datalayer._propertiesIndex.includes('A _ in the name')) - assert.ok(datalayer._propertiesIndex.includes('with a dot_')) - }) - - it('should import osm from textarea', function () { - datalayer.empty() - happen.click(qs('a.upload-data')) - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - assert.equal(datalayer._index.length, 0) - textarea.value = - '{"version": 0.6,"generator": "Overpass API 0.7.55.4 3079d8ea","osm3s": {"timestamp_osm_base": "2018-09-22T05:26:02Z","copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."},"elements": [{"type": "node","id": 3619112991,"lat": 48.9352995,"lon": 2.3570684,"tags": {"information": "map","map_size": "city","map_type": "scheme","tourism": "information"}},{"type": "node","id": 3682500756,"lat": 48.9804426,"lon": 2.2719725,"tags": {"information": "map","level": "0","tourism": "information"}}]}' - changeSelectValue(formatSelect, 'osm') - happen.click(submit) - assert.equal(datalayer._index.length, 2) - assert.equal( - datalayer._layers[datalayer._index[0]].properties.tourism, - 'information' - ) - }) - - it('should import kml from textarea', function () { - datalayer.empty() - happen.click(qs('a.upload-data')) - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - assert.equal(datalayer._index.length, 0) - textarea.value = kml_example - changeSelectValue(formatSelect, 'kml') - happen.click(submit) - assert.equal(datalayer._index.length, 3) - }) - - it('should import gpx from textarea', function () { - datalayer.empty() - happen.click(qs('a.upload-data')) - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - assert.equal(datalayer._index.length, 0) - textarea.value = gpx_example - changeSelectValue(formatSelect, 'gpx') - happen.click(submit) - assert.equal(datalayer._index.length, 2) - }) - - it('should import csv from textarea', function () { - datalayer.empty() - happen.click(qs('a.upload-data')) - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - assert.equal(datalayer._index.length, 0) - textarea.value = csv_example - changeSelectValue(formatSelect, 'csv') - happen.click(submit) - assert.equal(datalayer._index.length, 1) - }) - - it('should replace content if asked so', function () { - happen.click(qs('a.upload-data')) - textarea = qs('.umap-upload textarea') - submit = qs('.umap-upload input[type="button"]') - formatSelect = qs('.umap-upload select[name="format"]') - clearFlag = qs('.umap-upload input[name="clear"]') - clearFlag.checked = true - assert.equal(datalayer._index.length, 1) - textarea.value = csv_example - changeSelectValue(formatSelect, 'csv') - happen.click(submit) - assert.equal(datalayer._index.length, 1) - }) - - it('should import GeometryCollection from textarea', function () { - datalayer.empty() - textarea.value = - '{"type": "GeometryCollection","geometries": [{"type": "Point","coordinates": [-80.66080570220947,35.04939206472683]},{"type": "Polygon","coordinates": [[[-80.66458225250244,35.04496519190309],[-80.66344499588013,35.04603679820616],[-80.66258668899536,35.045580049697556],[-80.66387414932251,35.044280059194946],[-80.66458225250244,35.04496519190309]]]},{"type": "LineString","coordinates": [[-80.66237211227417,35.05950973022538],[-80.66269397735596,35.0592638296087],[-80.66284418106079,35.05893010615862],[-80.66308021545409,35.05833291342246],[-80.66359519958496,35.057753281001425],[-80.66387414932251,35.05740198662245],[-80.66441059112549,35.05703312589789],[-80.66486120223999,35.056787217822475],[-80.66541910171509,35.05650617911516],[-80.66563367843628,35.05631296444281],[-80.66601991653441,35.055891403570705],[-80.66619157791138,35.05545227534804],[-80.66619157791138,35.05517123204622],[-80.66625595092773,35.05489018777713],[-80.6662130355835,35.054222703761525],[-80.6662130355835,35.05392409072499],[-80.66595554351807,35.05290528508858],[-80.66569805145262,35.052044560077285],[-80.66550493240356,35.0514824490509],[-80.665762424469,35.05048117920187],[-80.66617012023926,35.04972582715769],[-80.66651344299316,35.049286665781096],[-80.66692113876343,35.0485313026898],[-80.66700696945189,35.048215102112344],[-80.66707134246826,35.04777593261294],[-80.66704988479614,35.04738946150025],[-80.66696405410767,35.04698542156371],[-80.66681385040283,35.046353007216055],[-80.66659927368164,35.04596652937105],[-80.66640615463257,35.04561518428889],[-80.6659984588623,35.045193568195565],[-80.66552639007568,35.044877354697526],[-80.6649899482727,35.04454357245502],[-80.66449642181396,35.04417465365292],[-80.66385269165039,35.04387600387859],[-80.66303730010986,35.043717894732545]]}]}' - formatSelect = qs('.umap-upload select[name="format"]') - changeSelectValue(formatSelect, 'geojson') - happen.click(submit) - assert.equal(datalayer._index.length, 3) - }) - - it('should import multipolygon', function () { - datalayer.empty() - textarea.value = - '{"type": "Feature", "properties": { "name": "Some states" }, "geometry": { "type": "MultiPolygon", "coordinates": [[[[-109, 36], [-109, 40], [-102, 37], [-109, 36]], [[-108, 39], [-107, 37], [-104, 37], [-108, 39]]], [[[-119, 42], [-120, 39], [-114, 41], [-119, 42]]]] }}' - changeSelectValue(formatSelect, 'geojson') - happen.click(submit) - assert.equal(datalayer._index.length, 1) - var layer = datalayer.getFeatureByIndex(0) - assert.equal(layer._latlngs.length, 2) // Two shapes. - assert.equal(layer._latlngs[0].length, 2) // Hole. - }) - - it('should import multipolyline', function () { - datalayer.empty() - textarea.value = - '{"type": "FeatureCollection", "features": [{ "type": "Feature", "properties": {}, "geometry": { "type": "MultiLineString", "coordinates": [[[-108, 46], [-113, 43]], [[-112, 45], [-115, 44]]] } }]}' - changeSelectValue(formatSelect, 'geojson') - happen.click(submit) - assert.equal(datalayer._index.length, 1) - var layer = datalayer.getFeatureByIndex(0) - assert.equal(layer._latlngs.length, 2) // Two shapes. - }) - - it('should import raw umap data from textarea', function () { - //Right now, the import function will try to save and reload. Stop this from happening. - var disabledSaveFunction = map.save - map.save = function () {} - happen.click(qs('a.upload-data')) - var initialLayerCount = Object.keys(map.datalayers).length - formatSelect = qs('.umap-upload select[name="format"]') - textarea = qs('.umap-upload textarea') - textarea.value = - '{ "type": "umap", "geometry": { "type": "Point", "coordinates": [3.0528, 50.6269] }, "properties": { "umap_id": 666, "longCredit": "the illustrious mapmaker", "shortCredit": "the mapmaker", "slideshow": {}, "captionBar": true, "dashArray": "5,5", "fillOpacity": "0.5", "fillColor": "Crimson", "fill": true, "weight": "2", "opacity": "0.9", "smoothFactor": "1", "iconClass": "Drop", "color": "Red", "limitBounds": {}, "tilelayer": { "maxZoom": 18, "url_template": "http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg", "minZoom": 0, "attribution": "Map tiles by [[http://stamen.com|Stamen Design]], under [[http://creativecommons.org/licenses/by/3.0|CC BY 3.0]]. Data by [[http://openstreetmap.org|OpenStreetMap]], under [[http://creativecommons.org/licenses/by-sa/3.0|CC BY SA]].", "name": "Watercolor" }, "licence": { "url": "", "name": "No licence set" }, "description": "Map description", "name": "Imported map", "tilelayersControl": true, "onLoadPanel": "caption", "displayPopupFooter": true, "miniMap": true, "moreControl": true, "scaleControl": true, "zoomControl": true, "scrollWheelZoom": true, "datalayersControl": true, "zoom": 6 }, "layers": [{ "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ [ [4.2939, 50.8893], [4.2441, 50.8196], [4.3869, 50.7642], [4.4813, 50.7929], [4.413, 50.9119], [4.2939, 50.8893] ] ] }, "properties": { "name": "Bruxelles", "description": "polygon" } }, { "type": "Feature", "geometry": { "type": "Point", "coordinates": [3.0528, 50.6269] }, "properties": { "_umap_options": { "color": "Orange" }, "name": "Lille", "description": "une ville" } }], "_umap_options": { "displayOnLoad": true, "name": "Cities", "id": 108, "remoteData": {}, "description": "A layer with some cities", "color": "Navy", "iconClass": "Drop", "smoothFactor": "1", "dashArray": "5,1", "fillOpacity": "0.5", "fillColor": "Blue", "fill": true } }, { "type": "FeatureCollection", "features": [{ "type": "Feature", "geometry": { "type": "LineString", "coordinates": [ [1.7715, 50.9255], [1.6589, 50.9696], [1.4941, 51.0128], [1.4199, 51.0638], [1.2881, 51.1104] ] }, "properties": { "_umap_options": { "weight": "4" }, "name": "tunnel sous la Manche" } }], "_umap_options": { "displayOnLoad": true, "name": "Tunnels", "id": 109, "remoteData": {} } }]}' - formatSelect.value = 'umap' - submit = qs('.umap-upload input[type="button"]') - happen.click(submit) - assert.equal(Object.keys(map.datalayers).length, initialLayerCount + 2) - assert.equal(map.options.name, 'Imported map') - var foundFirstLayer = false - var foundSecondLayer = false - for (var idx in map.datalayers) { - var datalayer = map.datalayers[idx] - if (datalayer.options.name === 'Cities') { - foundFirstLayer = true - assert.equal(datalayer._index.length, 2) - } - if (datalayer.options.name === 'Tunnels') { - foundSecondLayer = true - assert.equal(datalayer._index.length, 1) - } - } - assert.equal(foundFirstLayer, true) - assert.equal(foundSecondLayer, true) - }) - - it('should only import options on the whitelist (umap format import)', function () { - assert.equal(map.options.umap_id, 99) - }) - - it('should update title bar (umap format import)', function () { - var title = qs('#map div.umap-main-edit-toolbox button.map-name') - assert.equal(title.innerHTML, 'Imported map') - }) - - it('should reinitialize controls (umap format import)', function () { - var minimap = qs('#map div.leaflet-control-container div.leaflet-control-minimap') - assert.ok(minimap) - }) - - it('should update the tilelayer switcher control (umap format import)', function () { - //The tilelayer in the imported data isn't in the tilelayer list (set in _pre.js), there should be no selection on the tilelayer switcher - var selectedLayer = qs('.umap-tilelayer-switcher-container li.selected') - assert.equal(selectedLayer, null) - }) - - it('should set the tilelayer (umap format import)', function () { - assert.equal( - map.selected_tilelayer._url, - 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg' - ) - }) - }) - describe('#localizeUrl()', function () { it('should replace known variables', function () { assert.equal( diff --git a/umap/tests/fixtures/test_upload_data.csv b/umap/tests/fixtures/test_upload_data.csv index 107f2510..c6266599 100644 --- a/umap/tests/fixtures/test_upload_data.csv +++ b/umap/tests/fixtures/test_upload_data.csv @@ -1,2 +1,3 @@ Foo,Latitude,geo_Longitude,title,description -bar,41.34,122.86,a point somewhere,the description of this point \ No newline at end of file +bar,41.34,122.86,a point somewhere,the description of this point +bar,43.34,121.86,a point somewhere else,the description of this other point diff --git a/umap/tests/fixtures/test_upload_data.umap b/umap/tests/fixtures/test_upload_data.umap new file mode 100644 index 00000000..0392e2c2 --- /dev/null +++ b/umap/tests/fixtures/test_upload_data.umap @@ -0,0 +1,171 @@ +{ + "type": "umap", + "geometry": { + "type": "Point", + "coordinates": [ + 3.0528, + 50.6269 + ] + }, + "properties": { + "umap_id": 666, + "longCredit": "the illustrious mapmaker", + "shortCredit": "the mapmaker", + "slideshow": {}, + "captionBar": true, + "dashArray": "5,5", + "fillOpacity": "0.5", + "fillColor": "Crimson", + "fill": true, + "weight": "2", + "opacity": "0.9", + "smoothFactor": "1", + "iconClass": "Drop", + "color": "Red", + "limitBounds": {}, + "tilelayer": { + "maxZoom": 20, + "url_template": "https://tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", + "minZoom": 0, + "attribution": "map data © [[https://osm.org/copyright|OpenStreetMap contributors]] under ODbL - Tiles © HOT", + "name": "OSM Humanitarian (OSM-FR)" + }, + "licence": { + "url": "", + "name": "No licence set" + }, + "description": "Map description", + "name": "Imported map", + "tilelayersControl": true, + "onLoadPanel": "caption", + "displayPopupFooter": true, + "miniMap": true, + "moreControl": true, + "scaleControl": true, + "zoomControl": true, + "scrollWheelZoom": true, + "datalayersControl": true, + "zoom": 6 + }, + "layers": [ + { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 4.2939, + 50.8893 + ], + [ + 4.2441, + 50.8196 + ], + [ + 4.3869, + 50.7642 + ], + [ + 4.4813, + 50.7929 + ], + [ + 4.413, + 50.9119 + ], + [ + 4.2939, + 50.8893 + ] + ] + ] + }, + "properties": { + "name": "Bruxelles", + "description": "polygon" + } + }, + { + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 3.0528, + 50.6269 + ] + }, + "properties": { + "_umap_options": { + "color": "Orange" + }, + "name": "Lille", + "description": "une ville" + } + } + ], + "_umap_options": { + "displayOnLoad": true, + "name": "Cities", + "id": 108, + "remoteData": {}, + "description": "A layer with some cities", + "color": "Navy", + "iconClass": "Drop", + "smoothFactor": "1", + "dashArray": "5,1", + "fillOpacity": "0.5", + "fillColor": "Blue", + "fill": true + } + }, + { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "geometry": { + "type": "LineString", + "coordinates": [ + [ + 1.7715, + 50.9255 + ], + [ + 1.6589, + 50.9696 + ], + [ + 1.4941, + 51.0128 + ], + [ + 1.4199, + 51.0638 + ], + [ + 1.2881, + 51.1104 + ] + ] + }, + "properties": { + "_umap_options": { + "weight": "4" + }, + "name": "tunnel sous la Manche" + } + } + ], + "_umap_options": { + "displayOnLoad": true, + "name": "Tunnels", + "id": 109, + "remoteData": {} + } + } + ] +} diff --git a/umap/tests/fixtures/test_upload_data_osm.json b/umap/tests/fixtures/test_upload_data_osm.json new file mode 100644 index 00000000..dff71593 --- /dev/null +++ b/umap/tests/fixtures/test_upload_data_osm.json @@ -0,0 +1,33 @@ +{ + "version": 0.6, + "generator": "Overpass API 0.7.55.4 3079d8ea", + "osm3s": { + "timestamp_osm_base": "2018-09-22T05:26:02Z", + "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." + }, + "elements": [ + { + "type": "node", + "id": 3619112991, + "lat": 48.9352995, + "lon": 2.3570684, + "tags": { + "information": "map", + "map_size": "city", + "map_type": "scheme", + "tourism": "information" + } + }, + { + "type": "node", + "id": 3682500756, + "lat": 48.9804426, + "lon": 2.2719725, + "tags": { + "information": "map", + "level": "0", + "tourism": "information" + } + } + ] +} diff --git a/umap/tests/integration/test_edit_map.py b/umap/tests/integration/test_edit_map.py new file mode 100644 index 00000000..4820d469 --- /dev/null +++ b/umap/tests/integration/test_edit_map.py @@ -0,0 +1,15 @@ +from playwright.sync_api import expect + + +def test_can_edit_name(page, live_server, tilelayer): + page.goto(f"{live_server.url}/en/map/new/") + + page.get_by_title("Edit map properties").click() + name_input = page.locator('.map-metadata input[name="name"]') + expect(name_input).to_be_visible() + name_input.click() + name_input.press("Control+a") + name_input.fill("New map name") + expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( + "New map name" + ) diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 2f56b99c..a8852c4d 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -1,12 +1,16 @@ +import json +import re from pathlib import Path import pytest from playwright.sync_api import expect +from umap.models import DataLayer, Map + pytestmark = pytest.mark.django_db -def test_umap_import_from_file(live_server, datalayer, page): +def test_umap_import_from_file(live_server, tilelayer, page): page.goto(f"{live_server.url}/map/new/") button = page.get_by_title("Import data") expect(button).to_be_visible() @@ -28,9 +32,40 @@ def test_umap_import_from_file(live_server, datalayer, page): # Close the import panel page.keyboard.press("Escape") assert not file_input.input_value() + expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( + "Carte sans nom" + ) -def test_umap_import_geojson_from_textarea(live_server, datalayer, page): +def test_umap_import_from_textarea(live_server, tilelayer, page, settings): + settings.UMAP_ALLOW_ANONYMOUS = True + page.goto(f"{live_server.url}/map/new/") + page.get_by_title("Import data").click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.umap" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("umap") + page.get_by_role("button", name="Import", exact=True).click() + layers = page.locator(".umap-browse-datalayers li") + expect(layers).to_have_count(2) + expect(page.locator(".umap-main-edit-toolbox .map-name")).to_have_text( + "Imported map" + ) + page.get_by_role("button", name="See data layers").click() + expect(page.get_by_text("Tunnels")).to_be_visible() + expect(page.get_by_text("Cities")).to_be_visible() + expect(page.locator(".leaflet-control-minimap")).to_be_visible() + expect( + page.locator('img[src="https://tile.openstreetmap.fr/hot/6/32/21.png"]') + ).to_be_visible() + # Should not have imported umap_id, while in the file options + assert not page.evaluate("U.MAP.options.umap_id") + with page.expect_response(re.compile(r".*/datalayer/create/.*")): + page.get_by_role("button", name="Save").click() + assert page.evaluate("U.MAP.options.umap_id") + + +def test_import_geojson_from_textarea(tilelayer, live_server, page): page.goto(f"{live_server.url}/map/new/") layers = page.locator(".umap-browse-datalayers li") markers = page.locator(".leaflet-marker-icon") @@ -52,3 +87,322 @@ def test_umap_import_geojson_from_textarea(live_server, datalayer, page): expect(layers).to_have_count(1) expect(markers).to_have_count(2) expect(paths).to_have_count(3) + + +def test_import_kml_from_textarea(tilelayer, live_server, page): + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + paths = page.locator("path") + expect(markers).to_have_count(0) + expect(paths).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.kml" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("kml") + button = page.get_by_role("button", name="Import", exact=True) + expect(button).to_be_visible() + button.click() + # A layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(1) + expect(paths).to_have_count(2) + + +def test_import_gpx_from_textarea(tilelayer, live_server, page): + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + paths = page.locator("path") + expect(markers).to_have_count(0) + expect(paths).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.gpx" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("gpx") + button = page.get_by_role("button", name="Import", exact=True) + expect(button).to_be_visible() + button.click() + # A layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(1) + expect(paths).to_have_count(1) + + +def test_import_osm_from_textarea(tilelayer, live_server, page): + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + expect(markers).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data_osm.json" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("osm") + page.get_by_role("button", name="Import", exact=True).click() + # A layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(2) + + +def test_import_csv_from_textarea(tilelayer, live_server, page): + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + expect(markers).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("csv") + page.get_by_role("button", name="Import", exact=True).click() + # A layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(2) + + +def test_can_import_in_existing_datalayer(live_server, datalayer, page, map): + # Faster than doing a login + map.edit_status = Map.ANONYMOUS + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + expect(markers).to_have_count(1) + expect(layers).to_have_count(1) + page.get_by_role("button", name="Edit").click() + page.get_by_title("Import data").click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("csv") + page.get_by_role("button", name="Import", exact=True).click() + # No layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(3) + + +def test_can_replace_datalayer_data(live_server, datalayer, page, map): + # Faster than doing a login + map.edit_status = Map.ANONYMOUS + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + expect(markers).to_have_count(1) + expect(layers).to_have_count(1) + page.get_by_role("button", name="Edit").click() + page.get_by_title("Import data").click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("csv") + page.get_by_label("Replace layer content").check() + page.get_by_role("button", name="Import", exact=True).click() + # No layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(2) + + +def test_can_import_in_new_datalayer(live_server, datalayer, page, map): + # Faster than doing a login + map.edit_status = Map.ANONYMOUS + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + expect(markers).to_have_count(1) + expect(layers).to_have_count(1) + page.get_by_role("button", name="Edit").click() + page.get_by_title("Import data").click() + textarea = page.locator(".umap-upload textarea") + path = Path(__file__).parent.parent / "fixtures/test_upload_data.csv" + textarea.fill(path.read_text()) + page.locator('select[name="format"]').select_option("csv") + page.get_by_label("Choose the layer to import").select_option( + label="Import in a new layer" + ) + page.get_by_role("button", name="Import", exact=True).click() + # A new layer has been created + expect(layers).to_have_count(2) + expect(markers).to_have_count(3) + + +def test_should_remove_dot_in_property_names(live_server, page, settings, tilelayer): + settings.UMAP_ALLOW_ANONYMOUS = True + data = { + "type": "FeatureCollection", + "features": [ + { + "geometry": { + "type": "Point", + "coordinates": [6.922931671142578, 47.481161607175736], + }, + "type": "Feature", + "properties": { + "color": "", + "name": "Chez Rémy", + "A . in the name": "", + }, + }, + { + "geometry": { + "type": "LineString", + "coordinates": [ + [2.4609375, 48.88639177703194], + [2.48291015625, 48.76343113791796], + [2.164306640625, 48.719961222646276], + ], + }, + "type": "Feature", + "properties": {"color": "", "name": "Périf", "with a dot.": ""}, + }, + ], + } + page.goto(f"{live_server.url}/map/new/") + page.get_by_title("Import data").click() + textarea = page.locator(".umap-upload textarea") + textarea.fill(json.dumps(data)) + page.locator('select[name="format"]').select_option("geojson") + page.get_by_role("button", name="Import", exact=True).click() + with page.expect_response(re.compile(r".*/datalayer/create/.*")): + page.get_by_role("button", name="Save").click() + datalayer = DataLayer.objects.last() + saved_data = json.loads(Path(datalayer.geojson.path).read_text()) + assert saved_data["features"][0]["properties"] == { + "color": "", + "name": "Chez Rémy", + "A _ in the name": "", + } + assert saved_data["features"][1]["properties"] == { + "color": "", + "name": "Périf", + "with a dot_": "", + } + + +def test_import_geometry_collection(live_server, page, tilelayer): + data = { + "type": "GeometryCollection", + "geometries": [ + {"type": "Point", "coordinates": [-80.6608, 35.0493]}, + { + "type": "Polygon", + "coordinates": [ + [ + [-80.6645, 35.0449], + [-80.6634, 35.0460], + [-80.6625, 35.0455], + [-80.6638, 35.0442], + [-80.6645, 35.0449], + ] + ], + }, + { + "type": "LineString", + "coordinates": [ + [-80.66237, 35.05950], + [-80.66269, 35.05926], + [-80.66284, 35.05893], + [-80.66308, 35.05833], + [-80.66385, 35.04387], + [-80.66303, 35.04371], + ], + }, + ], + } + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + markers = page.locator(".leaflet-marker-icon") + paths = page.locator("path") + expect(markers).to_have_count(0) + expect(paths).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + textarea.fill(json.dumps(data)) + page.locator('select[name="format"]').select_option("geojson") + page.get_by_role("button", name="Import", exact=True).click() + # A layer has been created + expect(layers).to_have_count(1) + expect(markers).to_have_count(1) + expect(paths).to_have_count(2) + + +def test_import_multipolygon(live_server, page, tilelayer): + data = { + "type": "Feature", + "properties": {"name": "Some states"}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [[-109, 36], [-109, 40], [-102, 37], [-109, 36]], + [[-108, 39], [-107, 37], [-104, 37], [-108, 39]], + ], + [[[-119, 42], [-120, 39], [-114, 41], [-119, 42]]], + ], + }, + } + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + paths = page.locator("path") + expect(paths).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + textarea.fill(json.dumps(data)) + page.locator('select[name="format"]').select_option("geojson") + page.get_by_role("button", name="Import", exact=True).click() + # A layer has been created + expect(layers).to_have_count(1) + expect(paths).to_have_count(1) + + +def test_import_multipolyline(live_server, page, tilelayer): + data = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiLineString", + "coordinates": [[[-108, 46], [-113, 43]], [[-112, 45], [-115, 44]]], + }, + } + ], + } + page.goto(f"{live_server.url}/map/new/") + layers = page.locator(".umap-browse-datalayers li") + paths = page.locator("path") + expect(paths).to_have_count(0) + expect(layers).to_have_count(0) + button = page.get_by_title("Import data") + expect(button).to_be_visible() + button.click() + textarea = page.locator(".umap-upload textarea") + textarea.fill(json.dumps(data)) + page.locator('select[name="format"]').select_option("geojson") + page.get_by_role("button", name="Import", exact=True).click() + # A layer has been created + expect(layers).to_have_count(1) + expect(paths).to_have_count(1)