diff --git a/umap/static/umap/test/Controls.js b/umap/static/umap/test/Controls.js index a0611f65..50a6eb92 100644 --- a/umap/static/umap/test/Controls.js +++ b/umap/static/umap/test/Controls.js @@ -1,50 +1,48 @@ -describe('L.Utorage.Controls', function(){ +describe('L.Utorage.Controls', function () { + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith('/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)) + this.map = initMap({ umap_id: 99 }) + this.server.respond() + this.datalayer = this.map.getDataLayerByUmapId(62) + }) + after(function () { + this.server.restore() + resetMap() + }) - before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.map = initMap({umap_id: 99}); - this.server.respond(); - this.datalayer = this.map.getDataLayerByUmapId(62); - }); - after(function () { - this.server.restore(); - resetMap(); - }); + describe('#databrowser()', function () { + it('should be opened at datalayer button click', function () { + var button = qs('.umap-browse-actions .umap-browse-link') + assert.ok(button) + happen.click(button) + assert.ok(qs('#umap-ui-container .umap-browse-data')) + }) - describe('#databrowser()', function(){ + it('should contain datalayer section', function () { + assert.ok(qs('#browse_data_datalayer_62')) + }) - it('should be opened at datalayer button click', function() { - var button = qs('.umap-browse-actions .umap-browse-link'); - assert.ok(button); - happen.click(button); - assert.ok(qs('#umap-ui-container .umap-browse-data')); - }); + it("should contain datalayer's features list", function () { + assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 3) + }) - it('should contain datalayer section', function() { - assert.ok(qs('#browse_data_datalayer_62')); - }); + it("should redraw datalayer's features list at feature delete", function () { + var oldConfirm = window.confirm + window.confirm = function () { + return true + } + enableEdit() + happen.once(qs('path[fill="DarkBlue"]'), { type: 'contextmenu' }) + happen.click(qs('.leaflet-contextmenu .umap-delete')) + assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 2) + window.confirm = oldConfirm + }) - it('should contain datalayer\'s features list', function() { - assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 3); - }); - - it('should redraw datalayer\'s features list at feature delete', function() { - var oldConfirm = window.confirm; - window.confirm = function () {return true;}; - enableEdit(); - happen.once(qs('path[fill="DarkBlue"]'), {type: 'contextmenu'}); - happen.click(qs('.leaflet-contextmenu .umap-delete')); - assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 2); - window.confirm = oldConfirm; - }); - - it('should redraw datalayer\'s features list on edit cancel', function() { - clickCancel(); - happen.click(qs('.umap-browse-actions .umap-browse-link')); - assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 3); - }); - - }); - -}); + it("should redraw datalayer's features list on edit cancel", function () { + clickCancel() + happen.click(qs('.umap-browse-actions .umap-browse-link')) + assert.equal(qsa('#browse_data_datalayer_62 ul li').length, 3) + }) + }) +}) diff --git a/umap/static/umap/test/DataLayer.js b/umap/static/umap/test/DataLayer.js index 72ece389..d046ab45 100644 --- a/umap/static/umap/test/DataLayer.js +++ b/umap/static/umap/test/DataLayer.js @@ -1,334 +1,377 @@ describe('L.U.DataLayer', function () { - var path = '/map/99/datalayer/edit/62/'; + var path = '/map/99/datalayer/edit/62/' + + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith( + 'GET', + '/datalayer/62/', + JSON.stringify(RESPONSES.datalayer62_GET) + ) + this.map = initMap({ umap_id: 99 }) + this.datalayer = this.map.getDataLayerByUmapId(62) + this.server.respond() + enableEdit() + }) + after(function () { + this.server.restore() + resetMap() + }) + + describe('#init()', function () { + it('should be added in datalayers index', function () { + assert.notEqual(this.map.datalayers_index.indexOf(this.datalayer), -1) + }) + }) + + describe('#edit()', function () { + var editButton, form, input, forceButton + + it('row in control should be active', function () { + assert.notOk( + qs( + '.leaflet-control-browse #browse_data_toggle_' + + L.stamp(this.datalayer) + + '.off' + ) + ) + }) + + it('should have edit button', function () { + editButton = qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit') + assert.ok(editButton) + }) + + it('should have toggle visibility element', function () { + assert.ok(qs('.leaflet-control-browse i.layer-toggle')) + }) + + it('should exist only one datalayer', function () { + assert.equal(qsa('.leaflet-control-browse i.layer-toggle').length, 1) + }) + + it('should build a form on edit button click', function () { + happen.click(editButton) + form = qs('form.umap-form') + input = qs('form.umap-form input[name="name"]') + assert.ok(form) + assert.ok(input) + }) + + it('should update name on input change', function () { + var new_name = 'This is a new name' + input.value = new_name + happen.once(input, { type: 'input' }) + assert.equal(this.datalayer.options.name, new_name) + }) + + it('should have made datalayer dirty', function () { + assert.ok(this.datalayer.isDirty) + assert.notEqual(this.map.dirty_datalayers.indexOf(this.datalayer), -1) + }) + + it('should have made Map dirty', function () { + assert.ok(this.map.isDirty) + }) + + it('should call datalayer.save on save button click', function (done) { + sinon.spy(this.datalayer, 'save') + this.server.flush() + this.server.respondWith( + 'POST', + '/map/99/update/settings/', + JSON.stringify({ id: 99 }) + ) + this.server.respondWith( + 'POST', + '/map/99/datalayer/update/62/', + JSON.stringify(defaultDatalayerData()) + ) + clickSave() + this.server.respond() + this.server.respond() + assert(this.datalayer.save.calledOnce) + this.datalayer.save.restore() + done() + }) + + it('should show alert if server respond 412', function () { + cleanAlert() + this.server.flush() + this.server.respondWith( + 'POST', + '/map/99/update/settings/', + JSON.stringify({ id: 99 }) + ) + this.server.respondWith('POST', '/map/99/datalayer/update/62/', [412, {}, '']) + happen.click(editButton) + input = qs('form.umap-form input[name="name"]') + input.value = 'a new name' + happen.once(input, { type: 'input' }) + clickSave() + this.server.respond() + this.server.respond() + assert(L.DomUtil.hasClass(this.map._container, 'umap-alert')) + assert.notEqual(this.map.dirty_datalayers.indexOf(this.datalayer), -1) + forceButton = qs('#umap-alert-container .umap-action') + assert.ok(forceButton) + }) + + it('should save anyway on force save button click', function () { + sinon.spy(this.map, 'continueSaving') + happen.click(forceButton) + this.server.flush() + this.server.respond( + 'POST', + '/map/99/datalayer/update/62/', + JSON.stringify(defaultDatalayerData()) + ) + assert.notOk(qs('#umap-alert-container .umap-action')) + assert(this.map.continueSaving.calledOnce) + this.map.continueSaving.restore() + assert.equal(this.map.dirty_datalayers.indexOf(this.datalayer), -1) + }) + }) + + describe('#save() new', function () { + var newLayerButton, form, input, newDatalayer, editButton, manageButton + + it('should have a manage datalayers action', function () { + enableEdit() + manageButton = qs('.manage-datalayers') + assert.ok(manageButton) + happen.click(manageButton) + }) + + it('should have a new layer button', function () { + newLayerButton = qs('#umap-ui-container .add-datalayer') + assert.ok(newLayerButton) + }) + + it('should build a form on new layer button click', function () { + happen.click(newLayerButton) + form = qs('form.umap-form') + input = qs('form.umap-form input[name="name"]') + assert.ok(form) + assert.ok(input) + }) + + it('should have an empty name', function () { + assert.notOk(input.value) + }) + + it('should have created a new datalayer', function () { + assert.equal(this.map.datalayers_index.length, 2) + newDatalayer = this.map.datalayers_index[1] + }) + + it('should have made Map dirty', function () { + assert.ok(this.map.isDirty) + }) + + it('should update name on input change', function () { + var new_name = 'This is a new name' + input.value = new_name + happen.once(input, { type: 'input' }) + assert.equal(newDatalayer.options.name, new_name) + }) + + it('should set umap_id on save callback', function () { + assert.notOk(newDatalayer.umap_id) + this.server.flush() + this.server.respondWith( + 'POST', + '/map/99/update/settings/', + JSON.stringify({ id: 99 }) + ) + this.server.respondWith( + 'POST', + '/map/99/datalayer/create/', + JSON.stringify(defaultDatalayerData({ id: 63 })) + ) + clickSave() + this.server.respond() + this.server.respond() // First respond will then trigger another Xhr request (continueSaving) + assert.equal(newDatalayer.umap_id, 63) + }) + + it('should have unset map dirty', function () { + assert.notOk(this.map.isDirty) + }) + + it('should have edit button', function () { + editButton = qs('#browse_data_toggle_' + L.stamp(newDatalayer) + ' .layer-edit') + assert.ok(editButton) + }) + + it('should call update if we edit again', function () { + happen.click(editButton) + assert.notOk(this.map.isDirty) + input = qs('form.umap-form input[name="name"]') + input.value = "a new name again but we don't care which" + happen.once(input, { type: 'input' }) + assert.ok(this.map.isDirty) + var response = function (request) { + return request.respond( + 200, + {}, + JSON.stringify(defaultDatalayerData({ pk: 63 })) + ) + } + var spy = sinon.spy(response) + this.server.flush() + this.server.respondWith( + 'POST', + '/map/99/update/settings/', + JSON.stringify({ id: 99 }) + ) + this.server.respondWith('POST', '/map/99/datalayer/update/63/', spy) + clickSave() + this.server.respond() + this.server.respond() + assert.ok(spy.calledOnce) + }) + }) + + describe('#iconClassChange()', function () { + it('should change icon class', function () { + happen.click(qs('[data-id="' + this.datalayer._leaflet_id + '"] .layer-edit')) + changeSelectValue( + qs('form#datalayer-advanced-properties select[name=iconClass]'), + 'Circle' + ) + assert.notOk(qs('div.umap-div-icon')) + assert.ok(qs('div.umap-circle-icon')) + happen.click( + qs('form#datalayer-advanced-properties .umap-field-iconClass .undefine') + ) + assert.notOk(qs('div.umap-circle-icon')) + assert.ok(qs('div.umap-div-icon')) + clickCancel() + }) + }) + + describe('#show/hide', function () { + it('should hide features on hide', function () { + assert.ok(qs('div.umap-div-icon')) + assert.ok(qs('path[fill="none"]')) + this.datalayer.hide() + assert.notOk(qs('div.umap-div-icon')) + assert.notOk(qs('path[fill="none"]')) + }) + + it('should show features on show', function () { + assert.notOk(qs('div.umap-div-icon')) + assert.notOk(qs('path[fill="none"]')) + this.datalayer.show() + assert.ok(qs('div.umap-div-icon')) + assert.ok(qs('path[fill="none"]')) + }) + }) + + describe('#clone()', function () { + it('should clone everything but the id and the name', function () { + enableEdit() + var clone = this.datalayer.clone() + assert.notOk(clone.umap_id) + assert.notEqual(clone.options.name, this.datalayer.name) + assert.ok(clone.options.name) + assert.equal(clone.options.color, this.datalayer.options.color) + assert.equal(clone.options.stroke, this.datalayer.options.stroke) + clone._delete() + clickSave() + }) + }) + + describe('#restore()', function () { + var oldConfirm, + newConfirm = function () { + return true + } before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.map = initMap({umap_id: 99}); - this.datalayer = this.map.getDataLayerByUmapId(62); - this.server.respond(); - enableEdit(); - }); + oldConfirm = window.confirm + window.confirm = newConfirm + }) after(function () { - this.server.restore(); - resetMap(); - }); + window.confirm = oldConfirm + }) - describe('#init()', function () { + it('should restore everything', function () { + enableEdit() + var geojson = L.Util.CopyJSON(RESPONSES.datalayer62_GET) + geojson.features.push({ + geometry: { + type: 'Point', + coordinates: [-1.274658203125, 50.57634993749885], + }, + type: 'Feature', + id: 1807, + properties: { _umap_options: {}, name: 'new point from restore' }, + }) + geojson._umap_options.color = 'Chocolate' + this.server.respondWith( + 'GET', + '/datalayer/62/olderversion.geojson', + JSON.stringify(geojson) + ) + sinon.spy(window, 'confirm') + this.datalayer.restore('olderversion.geojson') + this.server.respond() + assert(window.confirm.calledOnce) + window.confirm.restore() + assert.equal(this.datalayer.umap_id, 62) + assert.ok(this.datalayer.isDirty) + assert.equal(this.datalayer._index.length, 4) + assert.ok(qs('path[fill="Chocolate"]')) + }) - it('should be added in datalayers index', function () { - assert.notEqual(this.map.datalayers_index.indexOf(this.datalayer), -1); - }); + it('should revert anything on cancel click', function () { + clickCancel() + assert.equal(this.datalayer._index.length, 3) + assert.notOk(qs('path[fill="Chocolate"]')) + }) + }) - }); + describe('#delete()', function () { + var deleteLink, + deletePath = '/map/99/datalayer/delete/62/' - describe('#edit()', function () { - var editButton, form, input, forceButton; + it('should have a delete link in update form', function () { + enableEdit() + happen.click( + qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit') + ) + deleteLink = qs('a.delete_datalayer_button') + assert.ok(deleteLink) + }) - it('row in control should be active', function () { - assert.notOk(qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(this.datalayer) + '.off')); - }); + it('should delete features on datalayer delete', function () { + happen.click(deleteLink) + assert.notOk(qs('div.icon_container')) + }) - it('should have edit button', function () { - editButton = qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit'); - assert.ok(editButton); - }); + it('should have set map dirty', function () { + assert.ok(this.map.isDirty) + }) - it('should have toggle visibility element', function () { - assert.ok(qs('.leaflet-control-browse i.layer-toggle')); - }); + it('should delete layer control row on delete', function () { + assert.notOk( + qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(this.datalayer)) + ) + }) - it('should exist only one datalayer', function () { - assert.equal(qsa('.leaflet-control-browse i.layer-toggle').length, 1); - }); + it('should be removed from map.datalayers_index', function () { + assert.equal(this.map.datalayers_index.indexOf(this.datalayer), -1) + }) - it('should build a form on edit button click', function () { - happen.click(editButton); - form = qs('form.umap-form'); - input = qs('form.umap-form input[name="name"]'); - assert.ok(form); - assert.ok(input); - }); + it('should be removed from map.datalayers', function () { + assert.notOk(this.map.datalayers[L.stamp(this.datalayer)]) + }) - it('should update name on input change', function () { - var new_name = 'This is a new name'; - input.value = new_name; - happen.once(input, {type: 'input'}); - assert.equal(this.datalayer.options.name, new_name); - }); - - it('should have made datalayer dirty', function () { - assert.ok(this.datalayer.isDirty); - assert.notEqual(this.map.dirty_datalayers.indexOf(this.datalayer), -1); - }); - - it('should have made Map dirty', function () { - assert.ok(this.map.isDirty); - }); - - it('should call datalayer.save on save button click', function (done) { - sinon.spy(this.datalayer, 'save'); - this.server.flush(); - this.server.respondWith('POST', '/map/99/update/settings/', JSON.stringify({id: 99})); - this.server.respondWith('POST', '/map/99/datalayer/update/62/', JSON.stringify(defaultDatalayerData())); - clickSave(); - this.server.respond(); - this.server.respond(); - assert(this.datalayer.save.calledOnce); - this.datalayer.save.restore(); - done(); - }); - - it('should show alert if server respond 412', function () { - cleanAlert(); - this.server.flush(); - this.server.respondWith('POST', '/map/99/update/settings/', JSON.stringify({id: 99})); - this.server.respondWith('POST', '/map/99/datalayer/update/62/', [412, {}, '']); - happen.click(editButton); - input = qs('form.umap-form input[name="name"]'); - input.value = 'a new name'; - happen.once(input, {type: 'input'}); - clickSave(); - this.server.respond(); - this.server.respond(); - assert(L.DomUtil.hasClass(this.map._container, 'umap-alert')); - assert.notEqual(this.map.dirty_datalayers.indexOf(this.datalayer), -1); - forceButton = qs('#umap-alert-container .umap-action'); - assert.ok(forceButton); - }); - - it('should save anyway on force save button click', function () { - sinon.spy(this.map, 'continueSaving'); - happen.click(forceButton); - this.server.flush(); - this.server.respond('POST', '/map/99/datalayer/update/62/', JSON.stringify(defaultDatalayerData())); - assert.notOk(qs('#umap-alert-container .umap-action')); - assert(this.map.continueSaving.calledOnce); - this.map.continueSaving.restore(); - assert.equal(this.map.dirty_datalayers.indexOf(this.datalayer), -1); - }); - - }); - - describe('#save() new', function () { - var newLayerButton, form, input, newDatalayer, editButton, manageButton; - - it('should have a manage datalayers action', function () { - enableEdit(); - manageButton = qs('.manage-datalayers'); - assert.ok(manageButton); - happen.click(manageButton); - }); - - it('should have a new layer button', function () { - newLayerButton = qs('#umap-ui-container .add-datalayer'); - assert.ok(newLayerButton); - }); - - it('should build a form on new layer button click', function () { - happen.click(newLayerButton); - form = qs('form.umap-form'); - input = qs('form.umap-form input[name="name"]'); - assert.ok(form); - assert.ok(input); - }); - - it('should have an empty name', function () { - assert.notOk(input.value); - }); - - it('should have created a new datalayer', function () { - assert.equal(this.map.datalayers_index.length, 2); - newDatalayer = this.map.datalayers_index[1]; - }); - - it('should have made Map dirty', function () { - assert.ok(this.map.isDirty); - }); - - it('should update name on input change', function () { - var new_name = 'This is a new name'; - input.value = new_name; - happen.once(input, {type: 'input'}); - assert.equal(newDatalayer.options.name, new_name); - }); - - it('should set umap_id on save callback', function () { - assert.notOk(newDatalayer.umap_id); - this.server.flush(); - this.server.respondWith('POST', '/map/99/update/settings/', JSON.stringify({id: 99})); - this.server.respondWith('POST', '/map/99/datalayer/create/', JSON.stringify(defaultDatalayerData({id: 63}))); - clickSave(); - this.server.respond(); - this.server.respond(); // First respond will then trigger another Xhr request (continueSaving) - assert.equal(newDatalayer.umap_id, 63); - }); - - it('should have unset map dirty', function () { - assert.notOk(this.map.isDirty); - }); - - it('should have edit button', function () { - editButton = qs('#browse_data_toggle_' + L.stamp(newDatalayer) + ' .layer-edit'); - assert.ok(editButton); - }); - - it('should call update if we edit again', function () { - happen.click(editButton); - assert.notOk(this.map.isDirty); - input = qs('form.umap-form input[name="name"]'); - input.value = 'a new name again but we don\'t care which'; - happen.once(input, {type: 'input'}); - assert.ok(this.map.isDirty); - var response = function (request) { - return request.respond(200, {}, JSON.stringify(defaultDatalayerData({pk: 63}))); - }; - var spy = sinon.spy(response); - this.server.flush(); - this.server.respondWith('POST', '/map/99/update/settings/', JSON.stringify({id: 99})); - this.server.respondWith('POST', '/map/99/datalayer/update/63/', spy); - clickSave(); - this.server.respond(); - this.server.respond(); - assert.ok(spy.calledOnce); - }); - - }); - - describe('#iconClassChange()', function () { - - it('should change icon class', function () { - happen.click(qs('[data-id="' + this.datalayer._leaflet_id +'"] .layer-edit')); - changeSelectValue(qs('form#datalayer-advanced-properties select[name=iconClass]'), 'Circle'); - assert.notOk(qs('div.umap-div-icon')); - assert.ok(qs('div.umap-circle-icon')); - happen.click(qs('form#datalayer-advanced-properties .umap-field-iconClass .undefine')); - assert.notOk(qs('div.umap-circle-icon')); - assert.ok(qs('div.umap-div-icon')); - clickCancel(); - }); - - }); - - describe('#show/hide', function () { - - it('should hide features on hide', function () { - assert.ok(qs('div.umap-div-icon')); - assert.ok(qs('path[fill="none"]')); - this.datalayer.hide(); - assert.notOk(qs('div.umap-div-icon')); - assert.notOk(qs('path[fill="none"]')); - }); - - it('should show features on show', function () { - assert.notOk(qs('div.umap-div-icon')); - assert.notOk(qs('path[fill="none"]')); - this.datalayer.show(); - assert.ok(qs('div.umap-div-icon')); - assert.ok(qs('path[fill="none"]')); - }); - - }); - - describe('#clone()', function () { - - it('should clone everything but the id and the name', function () { - enableEdit(); - var clone = this.datalayer.clone(); - assert.notOk(clone.umap_id); - assert.notEqual(clone.options.name, this.datalayer.name); - assert.ok(clone.options.name); - assert.equal(clone.options.color, this.datalayer.options.color); - assert.equal(clone.options.stroke, this.datalayer.options.stroke); - clone._delete(); - clickSave(); - }); - - }); - - describe('#restore()', function () { - var oldConfirm, - newConfirm = function () { - return true; - }; - - before(function () { - oldConfirm = window.confirm; - window.confirm = newConfirm; - }); - after(function () { - window.confirm = oldConfirm; - }); - - it('should restore everything', function () { - enableEdit(); - var geojson = L.Util.CopyJSON(RESPONSES.datalayer62_GET); - geojson.features.push({ - 'geometry': { - 'type': 'Point', - 'coordinates': [-1.274658203125, 50.57634993749885] - }, - 'type': 'Feature', - 'id': 1807, - 'properties': {_umap_options: {}, name: 'new point from restore'} - }); - geojson._umap_options.color = 'Chocolate'; - this.server.respondWith('GET', '/datalayer/62/olderversion.geojson', JSON.stringify(geojson)); - sinon.spy(window, 'confirm'); - this.datalayer.restore('olderversion.geojson'); - this.server.respond(); - assert(window.confirm.calledOnce); - window.confirm.restore(); - assert.equal(this.datalayer.umap_id, 62); - assert.ok(this.datalayer.isDirty); - assert.equal(this.datalayer._index.length, 4); - assert.ok(qs('path[fill="Chocolate"]')); - }); - - it('should revert anything on cancel click', function () { - clickCancel(); - assert.equal(this.datalayer._index.length, 3); - assert.notOk(qs('path[fill="Chocolate"]')); - }); - - }); - - describe('#delete()', function () { - var deleteLink, deletePath = '/map/99/datalayer/delete/62/'; - - it('should have a delete link in update form', function () { - enableEdit(); - happen.click(qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit')); - deleteLink = qs('a.delete_datalayer_button'); - assert.ok(deleteLink); - }); - - it('should delete features on datalayer delete', function () { - happen.click(deleteLink); - assert.notOk(qs('div.icon_container')); - }); - - it('should have set map dirty', function () { - assert.ok(this.map.isDirty); - }); - - it('should delete layer control row on delete', function () { - assert.notOk(qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(this.datalayer))); - }); - - it('should be removed from map.datalayers_index', function () { - assert.equal(this.map.datalayers_index.indexOf(this.datalayer), -1); - }); - - it('should be removed from map.datalayers', function () { - assert.notOk(this.map.datalayers[L.stamp(this.datalayer)]); - }); - - it('should be visible again on edit cancel', function () { - clickCancel(); - assert.ok(qs('div.icon_container')); - }); - - }); - -}); + it('should be visible again on edit cancel', function () { + clickCancel() + assert.ok(qs('div.icon_container')) + }) + }) +}) diff --git a/umap/static/umap/test/Feature.js b/umap/static/umap/test/Feature.js index ee908e4f..1757909e 100644 --- a/umap/static/umap/test/Feature.js +++ b/umap/static/umap/test/Feature.js @@ -1,245 +1,285 @@ describe('L.U.FeatureMixin', function () { + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith( + 'GET', + '/datalayer/62/', + JSON.stringify(RESPONSES.datalayer62_GET) + ) + this.map = initMap({ umap_id: 99 }) + this.datalayer = this.map.getDataLayerByUmapId(62) + this.server.respond() + }) + after(function () { + this.server.restore() + resetMap() + }) - before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.map = initMap({umap_id: 99}); - this.datalayer = this.map.getDataLayerByUmapId(62); - this.server.respond(); - }); - after(function () { - this.server.restore(); - resetMap(); - }); + describe('#edit()', function () { + var link - describe('#edit()', function () { - var link; + it('should have datalayer features created', function () { + assert.equal( + document.querySelectorAll( + '#map > .leaflet-map-pane > .leaflet-overlay-pane path.leaflet-interactive' + ).length, + 2 + ) + assert.ok(qs('path[fill="none"]')) // Polyline + assert.ok(qs('path[fill="DarkBlue"]')) // Polygon + }) - it('should have datalayer features created', function () { - assert.equal(document.querySelectorAll('#map > .leaflet-map-pane > .leaflet-overlay-pane path.leaflet-interactive').length, 2); - assert.ok(qs('path[fill="none"]')); // Polyline - assert.ok(qs('path[fill="DarkBlue"]')); // Polygon - }); + it('should take into account styles changes made in the datalayer', function () { + enableEdit() + happen.click( + qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit') + ) + var colorInput = qs('form#datalayer-advanced-properties input[name=color]') + changeInputValue(colorInput, 'DarkRed') + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + assert.notOk(qs('path[fill="DarkBlue"]')) + assert.ok(qs('path[fill="DarkRed"]')) + }) - it('should take into account styles changes made in the datalayer', function () { - enableEdit(); - happen.click(qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit')); - var colorInput = qs('form#datalayer-advanced-properties input[name=color]'); - changeInputValue(colorInput, 'DarkRed'); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - assert.notOk(qs('path[fill="DarkBlue"]')); - assert.ok(qs('path[fill="DarkRed"]')); - }); + it('should open a popup toolbar on feature click', function () { + enableEdit() + happen.click(qs('path[fill="DarkRed"]')) + var toolbar = qs('ul.leaflet-inplace-toolbar') + assert.ok(toolbar) + link = qs('a.umap-toggle-edit', toolbar) + assert.ok(link) + }) - it('should open a popup toolbar on feature click', function () { - enableEdit(); - happen.click(qs('path[fill="DarkRed"]')); - var toolbar = qs('ul.leaflet-inplace-toolbar'); - assert.ok(toolbar); - link = qs('a.umap-toggle-edit', toolbar); - assert.ok(link); - }); + it('should open a form on popup toolbar toggle edit click', function () { + happen.click(link) + var form = qs('form#umap-feature-properties') + var input = qs('form#umap-feature-properties input[name="name"]') + assert.ok(form) + assert.ok(input) + }) - it('should open a form on popup toolbar toggle edit click', function () { - happen.click(link); - var form = qs('form#umap-feature-properties'); - var input = qs('form#umap-feature-properties input[name="name"]'); - assert.ok(form); - assert.ok(input); - }); + it('should not handle _umap_options has normal property', function () { + assert.notOk(qs('form#umap-feature-properties input[name="_umap_options"]')) + }) - it('should not handle _umap_options has normal property', function () { - assert.notOk(qs('form#umap-feature-properties input[name="_umap_options"]')); - }); + it('should give precedence to feature style over datalayer styles', function () { + var input = qs('#umap-ui-container form input[name="color"]') + assert.ok(input) + changeInputValue(input, 'DarkGreen') + assert.notOk(qs('path[fill="DarkRed"]')) + assert.notOk(qs('path[fill="DarkBlue"]')) + assert.ok(qs('path[fill="DarkGreen"]')) + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + }) - it('should give precedence to feature style over datalayer styles', function () { - var input = qs('#umap-ui-container form input[name="color"]'); - assert.ok(input); - changeInputValue(input, 'DarkGreen'); - assert.notOk(qs('path[fill="DarkRed"]')); - assert.notOk(qs('path[fill="DarkBlue"]')); - assert.ok(qs('path[fill="DarkGreen"]')); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - }); + it('should remove stroke if set to no', function () { + assert.notOk(qs('path[stroke="none"]')) + var defineButton = qs( + '#umap-feature-shape-properties .formbox:nth-child(4) .define' + ) + happen.click(defineButton) + var input = qs('#umap-feature-shape-properties input[name="stroke"]') + assert.ok(input) + input.checked = false + happen.once(input, { type: 'change' }) + assert.ok(qs('path[stroke="none"]')) + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + }) - it('should remove stroke if set to no', function () { - assert.notOk(qs('path[stroke="none"]')); - var defineButton = qs('#umap-feature-shape-properties .formbox:nth-child(4) .define'); - happen.click(defineButton); - var input = qs('#umap-feature-shape-properties input[name="stroke"]'); - assert.ok(input); - input.checked = false; - happen.once(input, {type: 'change'}); - assert.ok(qs('path[stroke="none"]')); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - }); + it('should not override already set style on features', function () { + happen.click( + qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit') + ) + changeInputValue(qs('#umap-ui-container form input[name=color]'), 'Chocolate') + assert.notOk(qs('path[fill="DarkBlue"]')) + assert.notOk(qs('path[fill="DarkRed"]')) + assert.notOk(qs('path[fill="Chocolate"]')) + assert.ok(qs('path[fill="DarkGreen"]')) + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + }) - it('should not override already set style on features', function () { - happen.click(qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-edit')); - changeInputValue(qs('#umap-ui-container form input[name=color]'), 'Chocolate'); - assert.notOk(qs('path[fill="DarkBlue"]')); - assert.notOk(qs('path[fill="DarkRed"]')); - assert.notOk(qs('path[fill="Chocolate"]')); - assert.ok(qs('path[fill="DarkGreen"]')); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - }); + it('should reset style on cancel click', function () { + clickCancel() + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + assert.ok(qs('path[fill="DarkBlue"]')) + assert.notOk(qs('path[fill="DarkRed"]')) + }) - it('should reset style on cancel click', function () { - clickCancel(); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - assert.ok(qs('path[fill="DarkBlue"]')); - assert.notOk(qs('path[fill="DarkRed"]')); - }); + it('should set map.editedFeature on edit', function () { + enableEdit() + assert.notOk(this.map.editedFeature) + happen.click(qs('path[fill="DarkBlue"]')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + assert.ok(this.map.editedFeature) + disableEdit() + }) - it('should set map.editedFeature on edit', function () { - enableEdit(); - assert.notOk(this.map.editedFeature); - happen.click(qs('path[fill="DarkBlue"]')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - assert.ok(this.map.editedFeature); - disableEdit(); - }); + it('should reset map.editedFeature on panel open', function (done) { + enableEdit() + assert.notOk(this.map.editedFeature) + happen.click(qs('path[fill="DarkBlue"]')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + assert.ok(this.map.editedFeature) + this.map.displayCaption() + window.setTimeout(function () { + assert.notOk(this.map.editedFeature) + disableEdit() + done() + }, 1001) // CSS transition time. + }) + }) - it('should reset map.editedFeature on panel open', function (done) { - enableEdit(); - assert.notOk(this.map.editedFeature); - happen.click(qs('path[fill="DarkBlue"]')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - assert.ok(this.map.editedFeature); - this.map.displayCaption(); - window.setTimeout(function () { - assert.notOk(this.map.editedFeature); - disableEdit(); - done(); - }, 1001); // CSS transition time. - }); - - }); - - describe('#utils()', function () { - var poly, marker; - function setFeatures (datalayer) { - datalayer.eachLayer(function (layer) { - if (!poly && layer instanceof L.Polygon) { - poly = layer; - } - if (!marker && layer instanceof L.Marker) { - marker = layer; - } - }); + describe('#utils()', function () { + var poly, marker + function setFeatures(datalayer) { + datalayer.eachLayer(function (layer) { + if (!poly && layer instanceof L.Polygon) { + poly = layer } - it('should generate a valid geojson', function () { - setFeatures(this.datalayer); - assert.ok(poly); - assert.deepEqual(poly.toGeoJSON().geometry, {'type': 'Polygon', 'coordinates': [[[11.25, 53.585984], [10.151367, 52.975108], [12.689209, 52.167194], [14.084473, 53.199452], [12.634277, 53.618579], [11.25, 53.585984], [11.25, 53.585984]]]}); - // Ensure original latlngs has not been modified - assert.equal(poly.getLatLngs()[0].length, 6); - }); + if (!marker && layer instanceof L.Marker) { + marker = layer + } + }) + } + it('should generate a valid geojson', function () { + setFeatures(this.datalayer) + assert.ok(poly) + assert.deepEqual(poly.toGeoJSON().geometry, { + type: 'Polygon', + coordinates: [ + [ + [11.25, 53.585984], + [10.151367, 52.975108], + [12.689209, 52.167194], + [14.084473, 53.199452], + [12.634277, 53.618579], + [11.25, 53.585984], + [11.25, 53.585984], + ], + ], + }) + // Ensure original latlngs has not been modified + assert.equal(poly.getLatLngs()[0].length, 6) + }) - it('should remove empty _umap_options from exported geojson', function () { - setFeatures(this.datalayer); - assert.ok(poly); - assert.deepEqual(poly.toGeoJSON().properties, {name: 'name poly'}); - assert.ok(marker); - assert.deepEqual(marker.toGeoJSON().properties, {_umap_options: {color: 'OliveDrab'}, name: 'test'}); - }); + it('should remove empty _umap_options from exported geojson', function () { + setFeatures(this.datalayer) + assert.ok(poly) + assert.deepEqual(poly.toGeoJSON().properties, { name: 'name poly' }) + assert.ok(marker) + assert.deepEqual(marker.toGeoJSON().properties, { + _umap_options: { color: 'OliveDrab' }, + name: 'test', + }) + }) + }) - }); + describe('#changeDataLayer()', function () { + it('should change style on datalayer select change', function () { + enableEdit() + happen.click(qs('.manage-datalayers')) + happen.click(qs('#umap-ui-container .add-datalayer')) + changeInputValue(qs('form.umap-form input[name="name"]'), 'New layer') + changeInputValue( + qs('form#datalayer-advanced-properties input[name=color]'), + 'MediumAquaMarine' + ) + happen.click(qs('path[fill="DarkBlue"]')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + var select = qs('select[name=datalayer]') + select.selectedIndex = 0 + happen.once(select, { type: 'change' }) + assert.ok(qs('path[fill="none"]')) // Polyline fill is unchanged + assert.notOk(qs('path[fill="DarkBlue"]')) + assert.ok(qs('path[fill="MediumAquaMarine"]')) + clickCancel() + }) + }) - describe('#changeDataLayer()', function () { + describe('#openPopup()', function () { + it('should open a popup on click', function () { + assert.notOk(qs('.leaflet-popup-content')) + happen.click(qs('path[fill="DarkBlue"]')) + var title = qs('.leaflet-popup-content') + assert.ok(title) + assert.ok(title.innerHTML.indexOf('name poly')) + }) + }) - it('should change style on datalayer select change', function () { - enableEdit(); - happen.click(qs('.manage-datalayers')); - happen.click(qs('#umap-ui-container .add-datalayer')); - changeInputValue(qs('form.umap-form input[name="name"]'), 'New layer'); - changeInputValue(qs('form#datalayer-advanced-properties input[name=color]'), 'MediumAquaMarine'); - happen.click(qs('path[fill="DarkBlue"]')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - var select = qs('select[name=datalayer]'); - select.selectedIndex = 0; - happen.once(select, {type: 'change'}); - assert.ok(qs('path[fill="none"]')); // Polyline fill is unchanged - assert.notOk(qs('path[fill="DarkBlue"]')); - assert.ok(qs('path[fill="MediumAquaMarine"]')); - clickCancel(); - }); + describe('#tooltip', function () { + it('should have a tooltip when active and allow variables', function () { + this.map.options.showLabel = true + this.map.options.labelKey = 'Foo {name}' + this.datalayer.redraw() + assert.equal( + qs('.leaflet-tooltip-pane .leaflet-tooltip').textContent, + 'Foo name poly' + ) + }) + }) - }); + describe('#properties()', function () { + it('should rename property', function () { + var poly = this.datalayer._lineToLayer({}, [ + [0, 0], + [0, 1], + [0, 2], + ]) + poly.properties.prop1 = 'xxx' + poly.renameProperty('prop1', 'prop2') + assert.equal(poly.properties.prop2, 'xxx') + assert.ok(typeof poly.properties.prop1 === 'undefined') + }) - describe('#openPopup()', function () { + it('should not create property when renaming', function () { + var poly = this.datalayer._lineToLayer({}, [ + [0, 0], + [0, 1], + [0, 2], + ]) + delete poly.properties.prop2 // Make sure it doesn't exist + poly.renameProperty('prop1', 'prop2') + assert.ok(typeof poly.properties.prop2 === 'undefined') + }) - it('should open a popup on click', function () { - assert.notOk(qs('.leaflet-popup-content')); - happen.click(qs('path[fill="DarkBlue"]')); - var title = qs('.leaflet-popup-content'); - assert.ok(title); - assert.ok(title.innerHTML.indexOf('name poly')); - }); + it('should delete property', function () { + var poly = this.datalayer._lineToLayer({}, [ + [0, 0], + [0, 1], + [0, 2], + ]) + poly.properties.prop = 'xxx' + assert.equal(poly.properties.prop, 'xxx') + poly.deleteProperty('prop') + assert.ok(typeof poly.properties.prop === 'undefined') + }) + }) - }); + describe('#matchFilter()', function () { + var poly - describe('#tooltip', function () { + it('should filter on properties', function () { + poly = this.datalayer._lineToLayer({}, [ + [0, 0], + [0, 1], + [0, 2], + ]) + poly.properties.name = 'mooring' + assert.ok(poly.matchFilter('moo', ['name'])) + assert.notOk(poly.matchFilter('foo', ['name'])) + }) - it('should have a tooltip when active and allow variables', function () { - this.map.options.showLabel = true; - this.map.options.labelKey = "Foo {name}"; - this.datalayer.redraw(); - assert.equal(qs('.leaflet-tooltip-pane .leaflet-tooltip').textContent, "Foo name poly"); - }); + it('should be case unsensitive', function () { + assert.ok(poly.matchFilter('Moo', ['name'])) + }) - }); + it('should match also in the middle of a string', function () { + assert.ok(poly.matchFilter('oor', ['name'])) + }) - describe('#properties()', function () { - - it('should rename property', function () { - var poly = this.datalayer._lineToLayer({}, [[0, 0], [0, 1], [0, 2]]); - poly.properties.prop1 = 'xxx'; - poly.renameProperty('prop1', 'prop2'); - assert.equal(poly.properties.prop2, 'xxx'); - assert.ok(typeof poly.properties.prop1 === 'undefined'); - }); - - it('should not create property when renaming', function () { - var poly = this.datalayer._lineToLayer({}, [[0, 0], [0, 1], [0, 2]]); - delete poly.properties.prop2; // Make sure it doesn't exist - poly.renameProperty('prop1', 'prop2'); - assert.ok(typeof poly.properties.prop2 === 'undefined'); - }); - - it('should delete property', function () { - var poly = this.datalayer._lineToLayer({}, [[0, 0], [0, 1], [0, 2]]); - poly.properties.prop = 'xxx'; - assert.equal(poly.properties.prop, 'xxx'); - poly.deleteProperty('prop'); - assert.ok(typeof poly.properties.prop === 'undefined'); - }); - - }); - - describe('#matchFilter()', function () { - var poly; - - it('should filter on properties', function () { - poly = this.datalayer._lineToLayer({}, [[0, 0], [0, 1], [0, 2]]); - poly.properties.name = 'mooring'; - assert.ok(poly.matchFilter('moo', ['name'])); - assert.notOk(poly.matchFilter('foo', ['name'])); - }); - - it('should be case unsensitive', function () { - assert.ok(poly.matchFilter('Moo', ['name'])); - }); - - it('should match also in the middle of a string', function () { - assert.ok(poly.matchFilter('oor', ['name'])); - }); - - it('should handle multiproperties', function () { - poly.properties.city = 'Teulada'; - assert.ok(poly.matchFilter('eul', ['name', 'city', 'foo'])); - }); - - }); - -}); + it('should handle multiproperties', function () { + poly.properties.city = 'Teulada' + assert.ok(poly.matchFilter('eul', ['name', 'city', 'foo'])) + }) + }) +}) diff --git a/umap/static/umap/test/Map.js b/umap/static/umap/test/Map.js index e0135684..1a5fa4bf 100644 --- a/umap/static/umap/test/Map.js +++ b/umap/static/umap/test/Map.js @@ -1,316 +1,327 @@ -describe('L.U.Map', function(){ +describe('L.U.Map', function () { + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith('/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)) + this.options = { + umap_id: 99, + } + this.map = initMap({ umap_id: 99 }) + this.server.respond() + this.datalayer = this.map.getDataLayerByUmapId(62) + }) + after(function () { + this.server.restore() + clickCancel() + resetMap() + }) + + describe('#init()', function () { + it('should be initialized', function () { + assert.equal(this.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(this.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 a') + 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(this.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(this.map.options.name, new_name) + }) + + it('should have made Map dirty', function () { + assert.ok(this.map.isDirty) + }) + + it('should have added dirty class on map container', function () { + assert.ok(L.DomUtil.hasClass(this.map._container, 'umap-is-dirty')) + }) + }) + + describe('#delete()', function () { + var path = '/map/99/delete/', + oldConfirm, + newConfirm = function () { + return true + } before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.options = { - umap_id: 99 - }; - this.map = initMap({umap_id: 99}); - this.server.respond(); - this.datalayer = this.map.getDataLayerByUmapId(62); - }); + oldConfirm = window.confirm + window.confirm = newConfirm + }) after(function () { - this.server.restore(); - clickCancel(); - resetMap(); - }); + window.confirm = oldConfirm + }) - describe('#init()', function(){ + it('should ask for confirmation on delete link click', function (done) { + var button = qs('a.update-map-settings') + assert.ok(button, 'update map info button exists') + happen.click(button) + var deleteLink = qs('a.umap-delete') + assert.ok(deleteLink, 'delete map button exists') + sinon.spy(window, 'confirm') + this.server.respondWith('POST', path, JSON.stringify({ redirect: '#' })) + happen.click(deleteLink) + this.server.respond() + assert(window.confirm.calledOnce) + window.confirm.restore() + done() + }) + }) - it('should be initialized', function(){ - assert.equal(this.map.options.umap_id, 99); - }); + describe('#importData()', function () { + var fileInput, textarea, submit, formatSelect, layerSelect, clearFlag - it('should have created the edit button', function(){ - assert.ok(qs('div.leaflet-control-edit-enable')); - }); + 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 have datalayer control div', function(){ - assert.ok(qs('div.leaflet-control-browse')); - }); + it('should import geojson from textarea', function () { + this.datalayer.empty() + assert.equal(this.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(this.datalayer._index.length, 2) + }) - it('should have datalayer actions div', function(){ - assert.ok(qs('div.umap-browse-actions')); - }); + it('should import osm from textarea', function () { + this.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(this.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(this.datalayer._index.length, 2) + assert.equal( + this.datalayer._layers[this.datalayer._index[0]].properties.tourism, + 'information' + ) + }) - it('should have icon container div', function(){ - assert.ok(qs('div.icon_container')); - }); + it('should import kml from textarea', function () { + this.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(this.datalayer._index.length, 0) + textarea.value = kml_example + changeSelectValue(formatSelect, 'kml') + happen.click(submit) + assert.equal(this.datalayer._index.length, 3) + }) - it('should hide icon container div when hiding datalayer', function() { - var el = qs('.leaflet-control-browse #browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-toggle'); - happen.click(el); - assert.notOk(qs('div.icon_container')); - }); + it('should import gpx from textarea', function () { + this.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(this.datalayer._index.length, 0) + textarea.value = gpx_example + changeSelectValue(formatSelect, 'gpx') + happen.click(submit) + assert.equal(this.datalayer._index.length, 2) + }) - it('enable edit on click on toggle button', function () { - var el = qs('div.leaflet-control-edit-enable a'); - happen.click(el); - assert.isTrue(L.DomUtil.hasClass(document.body, 'umap-edit-enabled')); - }); + it('should import csv from textarea', function () { + this.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(this.datalayer._index.length, 0) + textarea.value = csv_example + changeSelectValue(formatSelect, 'csv') + happen.click(submit) + assert.equal(this.datalayer._index.length, 1) + }) - it('should have only one datalayer in its index', function () { - assert.equal(this.map.datalayers_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(this.datalayer._index.length, 1) + textarea.value = csv_example + changeSelectValue(formatSelect, 'csv') + happen.click(submit) + assert.equal(this.datalayer._index.length, 1) + }) - describe('#editMetadata()', function () { - var form, input; + it('should import GeometryCollection from textarea', function () { + this.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(this.datalayer._index.length, 3) + }) - 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 import multipolygon', function () { + this.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(this.datalayer._index.length, 1) + var layer = this.datalayer.getFeatureByIndex(0) + assert.equal(layer._latlngs.length, 2) // Two shapes. + assert.equal(layer._latlngs[0].length, 2) // Hole. + }) - 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(this.map.options.name, new_name); - }); + it('should import multipolyline', function () { + this.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(this.datalayer._index.length, 1) + var layer = this.datalayer.getFeatureByIndex(0) + assert.equal(layer._latlngs.length, 2) // Two shapes. + }) - it('should have made Map dirty', function () { - assert.ok(this.map.isDirty); - }); + 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 = this.map.save + this.map.save = function () {} + happen.click(qs('a.upload-data')) + var initialLayerCount = Object.keys(this.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(this.map.datalayers).length, initialLayerCount + 2) + assert.equal(this.map.options.name, 'Imported map') + var foundFirstLayer = false + var foundSecondLayer = false + for (var idx in this.map.datalayers) { + var datalayer = this.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 have added dirty class on map container', function () { - assert.ok(L.DomUtil.hasClass(this.map._container, 'umap-is-dirty')); - }); + it('should only import options on the whitelist (umap format import)', function () { + assert.equal(this.map.options.umap_id, 99) + }) - }); + it('should update title bar (umap format import)', function () { + var title = qs('#map div.umap-main-edit-toolbox h3 a.umap-click-to-edit') + assert.equal(title.innerHTML, 'Imported map') + }) - describe('#delete()', function () { - var path = '/map/99/delete/', - oldConfirm, - newConfirm = function () { - return true; - }; + it('should reinitialize controls (umap format import)', function () { + var minimap = qs('#map div.leaflet-control-container div.leaflet-control-minimap') + assert.ok(minimap) + }) - before(function () { - oldConfirm = window.confirm; - window.confirm = newConfirm; - }); - after(function () { - window.confirm = oldConfirm; - }); + 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 ask for confirmation on delete link click', function (done) { - var button = qs('a.update-map-settings'); - assert.ok(button, 'update map info button exists'); - happen.click(button); - var deleteLink = qs('a.umap-delete'); - assert.ok(deleteLink, 'delete map button exists'); - sinon.spy(window, 'confirm'); - this.server.respondWith('POST', path, JSON.stringify({redirect: '#'})); - happen.click(deleteLink); - this.server.respond(); - assert(window.confirm.calledOnce); - window.confirm.restore(); - done(); - }); + it('should set the tilelayer (umap format import)', function () { + assert.equal( + this.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( + this.map.localizeUrl('http://example.org/{zoom}'), + 'http://example.org/' + this.map.getZoom() + ) + }) - describe('#importData()', function () { - var 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 () { - this.datalayer.empty() - assert.equal(this.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(this.datalayer._index.length, 2); - }); - - it('should import osm from textarea', function () { - this.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(this.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(this.datalayer._index.length, 2); - assert.equal(this.datalayer._layers[this.datalayer._index[0]].properties.tourism, 'information'); - }); - - it('should import kml from textarea', function () { - this.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(this.datalayer._index.length, 0); - textarea.value = kml_example; - changeSelectValue(formatSelect, 'kml'); - happen.click(submit); - assert.equal(this.datalayer._index.length, 3); - }); - - it('should import gpx from textarea', function () { - this.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(this.datalayer._index.length, 0); - textarea.value = gpx_example; - changeSelectValue(formatSelect, 'gpx'); - happen.click(submit); - assert.equal(this.datalayer._index.length, 2); - }); - - it('should import csv from textarea', function () { - this.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(this.datalayer._index.length, 0); - textarea.value = csv_example; - changeSelectValue(formatSelect, 'csv'); - happen.click(submit); - assert.equal(this.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(this.datalayer._index.length, 1); - textarea.value = csv_example; - changeSelectValue(formatSelect, 'csv'); - happen.click(submit); - assert.equal(this.datalayer._index.length, 1); - }); - - - it('should import GeometryCollection from textarea', function () { - this.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(this.datalayer._index.length, 3); - }); - - it('should import multipolygon', function () { - this.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(this.datalayer._index.length, 1); - var layer = this.datalayer.getFeatureByIndex(0); - assert.equal(layer._latlngs.length, 2); // Two shapes. - assert.equal(layer._latlngs[0].length, 2); // Hole. - }); - - it('should import multipolyline', function () { - this.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(this.datalayer._index.length, 1); - var layer = this.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 = this.map.save; - this.map.save = function(){}; - happen.click(qs('a.upload-data')); - var initialLayerCount = Object.keys(this.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(this.map.datalayers).length, initialLayerCount + 2); - assert.equal(this.map.options.name, "Imported map"); - var foundFirstLayer = false; - var foundSecondLayer = false; - for (var idx in this.map.datalayers) { - var datalayer = this.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(this.map.options.umap_id, 99); - }); - - it('should update title bar (umap format import)', function () { - var title = qs("#map div.umap-main-edit-toolbox h3 a.umap-click-to-edit"); - 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(this.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(this.map.localizeUrl('http://example.org/{zoom}'), 'http://example.org/' + this.map.getZoom()); - }); - - it('should keep unknown variables', function () { - assert.equal(this.map.localizeUrl('http://example.org/{unkown}'), 'http://example.org/{unkown}'); - }); - - }); - - -}); + it('should keep unknown variables', function () { + assert.equal( + this.map.localizeUrl('http://example.org/{unkown}'), + 'http://example.org/{unkown}' + ) + }) + }) +}) diff --git a/umap/static/umap/test/Marker.js b/umap/static/umap/test/Marker.js index 9d607621..ee76421b 100644 --- a/umap/static/umap/test/Marker.js +++ b/umap/static/umap/test/Marker.js @@ -1,82 +1,98 @@ describe('L.U.Marker', function () { + before(function () { + this.server = sinon.fakeServer.create() + var datalayer_response = JSON.parse(JSON.stringify(RESPONSES.datalayer62_GET)) // Copy. + datalayer_response._umap_options.iconClass = 'Drop' + this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(datalayer_response)) + this.map = initMap({ umap_id: 99 }) + this.datalayer = this.map.getDataLayerByUmapId(62) + this.server.respond() + }) + after(function () { + this.server.restore() + resetMap() + }) - before(function () { - this.server = sinon.fakeServer.create(); - var datalayer_response = JSON.parse(JSON.stringify(RESPONSES.datalayer62_GET)); // Copy. - datalayer_response._umap_options.iconClass = 'Drop'; - this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(datalayer_response)); - this.map = initMap({umap_id: 99}); - this.datalayer = this.map.getDataLayerByUmapId(62); - this.server.respond(); - }); - after(function () { - this.server.restore(); - resetMap(); - }); + describe('#iconClassChange()', function () { + it('should change icon class', function () { + enableEdit() + happen.click(qs('div.umap-drop-icon')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + changeSelectValue( + qs( + 'form#umap-feature-shape-properties .umap-field-iconClass select[name=iconClass]' + ), + 'Circle' + ) + assert.notOk(qs('div.umap-drop-icon')) + assert.ok(qs('div.umap-circle-icon')) + happen.click( + qs('form#umap-feature-shape-properties .umap-field-iconClass .undefine') + ) + assert.notOk(qs('div.umap-circle-icon')) + assert.ok(qs('div.umap-drop-icon')) + clickCancel() + }) + }) - describe('#iconClassChange()', function () { + describe('#iconSymbolChange()', function () { + it('should change icon symbol', function () { + enableEdit() + happen.click(qs('div.umap-drop-icon')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + changeInputValue( + qs( + 'form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]' + ), + '1' + ) + assert.equal(qs('div.umap-drop-icon span').textContent, '1') + changeInputValue( + qs( + 'form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]' + ), + '{name}' + ) + assert.equal(qs('div.umap-drop-icon span').textContent, 'test') + clickCancel() + }) + }) - it('should change icon class', function () { - enableEdit(); - happen.click(qs('div.umap-drop-icon')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - changeSelectValue(qs('form#umap-feature-shape-properties .umap-field-iconClass select[name=iconClass]'), 'Circle'); - assert.notOk(qs('div.umap-drop-icon')); - assert.ok(qs('div.umap-circle-icon')); - happen.click(qs('form#umap-feature-shape-properties .umap-field-iconClass .undefine')); - assert.notOk(qs('div.umap-circle-icon')); - assert.ok(qs('div.umap-drop-icon')); - clickCancel(); - }); + describe('#iconClassChange()', function () { + it('should change icon class', function () { + enableEdit() + happen.click(qs('div.umap-drop-icon')) + happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')) + changeSelectValue( + qs( + 'form#umap-feature-shape-properties .umap-field-iconClass select[name=iconClass]' + ), + 'Circle' + ) + assert.notOk(qs('div.umap-drop-icon')) + assert.ok(qs('div.umap-circle-icon')) + happen.click( + qs('form#umap-feature-shape-properties .umap-field-iconClass .undefine') + ) + assert.notOk(qs('div.umap-circle-icon')) + assert.ok(qs('div.umap-drop-icon')) + clickCancel() + }) + }) - }); - - describe('#iconSymbolChange()', function () { - - it('should change icon symbol', function () { - enableEdit(); - happen.click(qs('div.umap-drop-icon')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - changeInputValue(qs('form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]'), '1'); - assert.equal(qs('div.umap-drop-icon span').textContent, '1'); - changeInputValue(qs('form#umap-feature-shape-properties .umap-field-iconUrl input[name=iconUrl]'), '{name}'); - assert.equal(qs('div.umap-drop-icon span').textContent, 'test'); - clickCancel(); - }); - - }); - - describe('#iconClassChange()', function () { - - it('should change icon class', function () { - enableEdit(); - happen.click(qs('div.umap-drop-icon')); - happen.click(qs('ul.leaflet-inplace-toolbar a.umap-toggle-edit')); - changeSelectValue(qs('form#umap-feature-shape-properties .umap-field-iconClass select[name=iconClass]'), 'Circle'); - assert.notOk(qs('div.umap-drop-icon')); - assert.ok(qs('div.umap-circle-icon')); - happen.click(qs('form#umap-feature-shape-properties .umap-field-iconClass .undefine')); - assert.notOk(qs('div.umap-circle-icon')); - assert.ok(qs('div.umap-drop-icon')); - clickCancel(); - }); - - }); - - describe('#clone', function () { - - it('should clone marker', function () { - var layer = new L.U.Marker(this.map, [10, 20], {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 4); - other = layer.clone(); - assert.ok(this.map.hasLayer(other)); - assert.equal(this.datalayer._index.length, 5); - // Must not be the same reference - assert.notEqual(layer._latlng, other._latlng); - assert.equal(L.Util.formatNum(layer._latlng.lat), other._latlng.lat); - assert.equal(L.Util.formatNum(layer._latlng.lng), other._latlng.lng); - }); - - }); - -}); + describe('#clone', function () { + it('should clone marker', function () { + var layer = new L.U.Marker(this.map, [10, 20], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.equal(this.datalayer._index.length, 4) + other = layer.clone() + assert.ok(this.map.hasLayer(other)) + assert.equal(this.datalayer._index.length, 5) + // Must not be the same reference + assert.notEqual(layer._latlng, other._latlng) + assert.equal(L.Util.formatNum(layer._latlng.lat), other._latlng.lat) + assert.equal(L.Util.formatNum(layer._latlng.lng), other._latlng.lng) + }) + }) +}) diff --git a/umap/static/umap/test/Permissions.js b/umap/static/umap/test/Permissions.js index 7ead6bc7..91112e1d 100644 --- a/umap/static/umap/test/Permissions.js +++ b/umap/static/umap/test/Permissions.js @@ -1,77 +1,76 @@ describe('L.Permissions', function () { - var path = '/map/99/datalayer/edit/62/'; + var path = '/map/99/datalayer/edit/62/' - before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.map = initMap({umap_id: 99}); - this.datalayer = this.map.getDataLayerByUmapId(62); - this.server.respond(); - enableEdit(); - }); - after(function () { - clickCancel(); - this.server.restore(); - resetMap(); - }); + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith( + 'GET', + '/datalayer/62/', + JSON.stringify(RESPONSES.datalayer62_GET) + ) + this.map = initMap({ umap_id: 99 }) + this.datalayer = this.map.getDataLayerByUmapId(62) + this.server.respond() + enableEdit() + }) + after(function () { + clickCancel() + this.server.restore() + resetMap() + }) - describe('#open()', function () { - var button; + describe('#open()', function () { + var button - it('should exist update permissions link', function () { - button = qs('a.update-map-permissions'); - expect(button).to.be.ok; - }); + it('should exist update permissions link', function () { + button = qs('a.update-map-permissions') + expect(button).to.be.ok + }) - it('should open table button click', function () { - happen.click(button); - expect(qs('.permissions-panel')).to.be.ok; - }); + it('should open table button click', function () { + happen.click(button) + expect(qs('.permissions-panel')).to.be.ok + }) + }) + describe('#anonymous with cookie', function () { + var button - }); - describe('#anonymous with cookie', function () { - var button; + it('should only allow edit_status', function () { + this.map.permissions.options.anonymous_edit_url = 'http://anonymous.url' + button = qs('a.update-map-permissions') + happen.click(button) + expect(qs('select[name="edit_status"]')).to.be.ok + expect(qs('select[name="share_status"]')).not.to.be.ok + expect(qs('input.edit-owner')).not.to.be.ok + }) + }) - it('should only allow edit_status', function () { - this.map.permissions.options.anonymous_edit_url = 'http://anonymous.url'; - button = qs('a.update-map-permissions'); - happen.click(button); - expect(qs('select[name="edit_status"]')).to.be.ok; - expect(qs('select[name="share_status"]')).not.to.be.ok; - expect(qs('input.edit-owner')).not.to.be.ok; - }); + describe('#editor', function () { + var button - }); + it('should only allow editors', function () { + this.map.permissions.options.owner = { id: 1, url: '/url', name: 'jojo' } + button = qs('a.update-map-permissions') + happen.click(button) + expect(qs('select[name="edit_status"]')).not.to.be.ok + expect(qs('select[name="share_status"]')).not.to.be.ok + expect(qs('input.edit-owner')).not.to.be.ok + expect(qs('input.edit-editors')).to.be.ok + }) + }) - describe('#editor', function () { - var button; + describe('#owner', function () { + var button - it('should only allow editors', function () { - this.map.permissions.options.owner = {id: 1, url: '/url', name: 'jojo'}; - button = qs('a.update-map-permissions'); - happen.click(button); - expect(qs('select[name="edit_status"]')).not.to.be.ok; - expect(qs('select[name="share_status"]')).not.to.be.ok; - expect(qs('input.edit-owner')).not.to.be.ok; - expect(qs('input.edit-editors')).to.be.ok; - }); - - }); - - describe('#owner', function () { - var button; - - it('should allow everything', function () { - this.map.permissions.options.owner = {id: 1, url: '/url', name: 'jojo'}; - this.map.options.user = {id: 1, url: '/url', name: 'jojo'}; - button = qs('a.update-map-permissions'); - happen.click(button); - expect(qs('select[name="edit_status"]')).to.be.ok; - expect(qs('select[name="share_status"]')).to.be.ok; - expect(qs('input.edit-owner')).to.be.ok; - expect(qs('input.edit-editors')).to.be.ok; - }); - - }); - -}); + it('should allow everything', function () { + this.map.permissions.options.owner = { id: 1, url: '/url', name: 'jojo' } + this.map.options.user = { id: 1, url: '/url', name: 'jojo' } + button = qs('a.update-map-permissions') + happen.click(button) + expect(qs('select[name="edit_status"]')).to.be.ok + expect(qs('select[name="share_status"]')).to.be.ok + expect(qs('input.edit-owner')).to.be.ok + expect(qs('input.edit-editors')).to.be.ok + }) + }) +}) diff --git a/umap/static/umap/test/Polygon.js b/umap/static/umap/test/Polygon.js index 2dfdbc60..9b2070db 100644 --- a/umap/static/umap/test/Polygon.js +++ b/umap/static/umap/test/Polygon.js @@ -1,288 +1,367 @@ describe('L.U.Polygon', function () { - var p2ll, map; + var p2ll, map - before(function () { - this.map = map = initMap({umap_id: 99}); - enableEdit(); - p2ll = function (x, y) { - return map.containerPointToLatLng([x, y]); - }; - this.datalayer = this.map.createDataLayer(); - this.datalayer.connectToMap();; - }); + before(function () { + this.map = map = initMap({ umap_id: 99 }) + enableEdit() + p2ll = function (x, y) { + return map.containerPointToLatLng([x, y]) + } + this.datalayer = this.map.createDataLayer() + this.datalayer.connectToMap() + }) - after(function () { - clickCancel(); - resetMap(); - }); + after(function () { + clickCancel() + resetMap() + }) + afterEach(function () { + this.datalayer.empty() + }) + + describe('#isMulti()', function () { + it('should return false for basic Polygon', function () { + var layer = new L.U.Polygon( + this.map, + [ + [1, 2], + [3, 4], + [5, 6], + ], + { datalayer: this.datalayer } + ) + assert.notOk(layer.isMulti()) + }) + + it('should return false for nested basic Polygon', function () { + var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]], + layer = new L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }) + assert.notOk(layer.isMulti()) + }) + + it('should return false for simple Polygon with hole', function () { + var layer = new L.U.Polygon( + this.map, + [ + [ + [1, 2], + [3, 4], + [5, 6], + ], + [ + [7, 8], + [9, 10], + [11, 12], + ], + ], + { datalayer: this.datalayer } + ) + assert.notOk(layer.isMulti()) + }) + + it('should return true for multi Polygon', function () { + var latLngs = [ + [ + [ + [1, 2], + [3, 4], + [5, 6], + ], + ], + [ + [ + [7, 8], + [9, 10], + [11, 12], + ], + ], + ] + var layer = new L.U.Polygon(this.map, latLngs, { datalayer: this.datalayer }) + assert.ok(layer.isMulti()) + }) + + it('should return true for multi Polygon with hole', function () { + var latLngs = [ + [ + [ + [10, 20], + [30, 40], + [50, 60], + ], + ], + [ + [ + [0, 10], + [10, 10], + [10, 0], + ], + [ + [2, 3], + [2, 4], + [3, 4], + ], + ], + ] + var layer = new L.U.Polygon(this.map, latLngs, { datalayer: this.datalayer }) + assert.ok(layer.isMulti()) + }) + }) + + describe('#contextmenu', function () { afterEach(function () { - this.datalayer.empty(); - }); + // Make sure contextmenu is hidden + happen.once(document, { type: 'keydown', keyCode: 27 }) + }) - describe('#isMulti()', function () { + 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 L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.equal(qst('Remove shape from the multi'), 1) + }) - it('should return false for basic Polygon', function () { - var layer = new L.U.Polygon(this.map, [[1, 2], [3, 4], [5, 6]], {datalayer: this.datalayer}); - assert.notOk(layer.isMulti()) - }); + it('should not allow to remove shape when not multi', function () { + var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]], + layer = new L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Remove shape from the multi')) + }) - it('should return false for nested basic Polygon', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]] - ], - layer = new L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}); - assert.notOk(layer.isMulti()) - }); + it('should not allow to isolate shape when not multi', function () { + var latlngs = [[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]]], + layer = new L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Extract shape to separate feature')) + }) - it('should return false for simple Polygon with hole', function () { - var layer = new L.U.Polygon(this.map, [[[1, 2], [3, 4], [5, 6]], [[7, 8], [9, 10], [11, 12]]], {datalayer: this.datalayer}); - assert.notOk(layer.isMulti()) - }); + 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 L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.ok(qst('Extract shape to separate feature')) + }) - it('should return true for multi Polygon', function () { - var latLngs = [ - [ - [[1, 2], [3, 4], [5, 6]] - ], - [ - [[7, 8], [9, 10], [11, 12]] - ] - ]; - var layer = new L.U.Polygon(this.map, latLngs, {datalayer: this.datalayer}); - assert.ok(layer.isMulti()) - }); + 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 L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Transform to lines')) + }) - it('should return true for multi Polygon with hole', function () { - var latLngs = [ - [[[10, 20], [30, 40], [50, 60]]], - [[[0, 10], [10, 10], [10, 0]], [[2, 3], [2, 4], [3, 4]]] - ]; - var layer = new L.U.Polygon(this.map, latLngs, {datalayer: this.datalayer}); - assert.ok(layer.isMulti()) - }); + 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 L.U.Polygon(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.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 L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ) + happen.at('contextmenu', 150, 150) + assert.equal(qst('Transform to lines'), 1) + }) - describe('#contextmenu', function () { + it('should not allow to transfer shape when not editedFeature', function () { + new L.U.Polygon(this.map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], { + datalayer: this.datalayer, + }).addTo(this.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')) + }) - afterEach(function () { - // Make sure contextmenu is hidden - happen.once(document, {type: 'keydown', keyCode: 27}); - }); + it('should not allow to transfer shape when editedFeature is not a polygon', function () { + var layer = new L.U.Polygon( + this.map, + [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], + { datalayer: this.datalayer } + ).addTo(this.datalayer), + other = new L.U.Polyline(this.map, [p2ll(200, 250), p2ll(200, 300)], { + datalayer: this.datalayer, + }).addTo(this.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')) + }) - describe('#in edit mode', function () { + it('should allow to transfer shape when another polygon is edited', function (done) { + this.datalayer.empty() + var layer = new L.U.Polygon( + this.map, + [p2ll(200, 300), p2ll(300, 200), p2ll(200, 100)], + { datalayer: this.datalayer } + ).addTo(this.datalayer) + layer.edit() // This moves the map to put "other" at the center. + var other = new L.U.Polygon( + this.map, + [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], + { datalayer: this.datalayer } + ).addTo(this.datalayer) + happen.once(other._path, { type: 'contextmenu' }) + assert.equal(qst('Transfer shape to edited feature'), 1) + done() + }) + }) + }) - 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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.equal(qst('Remove shape from the multi'), 1); - }); + describe('#addShape', function () { + it('"add shape" control should not be visible by default', function () { + assert.notOk(qs('.umap-draw-polygon-multi')) + }) - it('should not allow to remove shape when not multi', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]] - ], - layer = new L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Remove shape from the multi')); - }); + it('"add shape" control should be visible when editing a Polygon', function () { + var layer = new L.U.Polygon(this.map, [p2ll(100, 100), p2ll(100, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.edit() + assert.ok(qs('.umap-draw-polygon-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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Extract shape to separate feature')); - }); + it('"add shape" control should extend the same multi', function () { + var layer = new L.U.Polygon( + this.map, + [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)], + { datalayer: this.datalayer } + ).addTo(this.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(this.datalayer._index.length, 1) + }) + }) - 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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.ok(qst('Extract shape to separate feature')); - }); + 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 L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ), + other = new L.U.Polygon( + this.map, + [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], + { datalayer: this.datalayer } + ).addTo(this.datalayer) + assert.ok(this.map.hasLayer(layer)) + layer.transferShape(p2ll(150, 150), other) + assert.equal(other._latlngs.length, 2) + assert.deepEqual(other._latlngs[1][0], latlngs) + assert.notOk(this.map.hasLayer(layer)) + }) - 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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Transform to lines')); - }); + 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 L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ), + other = new L.U.Polygon( + this.map, + [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], + { datalayer: this.datalayer } + ).addTo(this.datalayer) + assert.ok(this.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(this.map.hasLayer(layer)) + assert.equal(layer._latlngs.length, 1) + }) + }) - 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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Transform to lines')); - }); + 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 L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ) + assert.equal(this.datalayer._index.length, 1) + assert.ok(this.map.hasLayer(layer)) + layer.isolateShape(p2ll(150, 150)) + assert.equal(layer._latlngs[0].length, 3) + assert.equal(this.datalayer._index.length, 1) + }) - it('should allow to transform to lines when not multi', function () { - var latlngs = [ - [[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]] - ]; - new L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.at('contextmenu', 150, 150); - assert.equal(qst('Transform to lines'), 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 L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ) + assert.equal(this.datalayer._index.length, 1) + assert.ok(this.map.hasLayer(layer)) + var other = layer.isolateShape(p2ll(150, 150)) + assert.equal(this.datalayer._index.length, 2) + assert.equal(other._latlngs.length, 2) + assert.deepEqual(other._latlngs[0], latlngs[0][0]) + assert.ok(this.map.hasLayer(layer)) + assert.ok(this.map.hasLayer(other)) + assert.equal(layer._latlngs.length, 1) + other.remove() + }) + }) - it('should not allow to transfer shape when not editedFeature', function () { - new L.U.Polygon(this.map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], {datalayer: this.datalayer}).addTo(this.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 L.U.Polygon(this.map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polyline(this.map, [p2ll(200, 250), p2ll(200, 300)], {datalayer: this.datalayer}).addTo(this.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 (done) { - this.datalayer.empty(); - var layer = new L.U.Polygon(this.map, [p2ll(200, 300), p2ll(300, 200), p2ll(200, 100)], {datalayer: this.datalayer}).addTo(this.datalayer); - layer.edit(); // This moves the map to put "other" at the center. - var other = new L.U.Polygon(this.map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 150)], {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(other._path, {type: 'contextmenu'}); - assert.equal(qst('Transfer shape to edited feature'), 1); - done(); - }); - - }); - - }); - - 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 L.U.Polygon(this.map, [p2ll(100, 100), p2ll(100, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - layer.edit(); - assert.ok(qs('.umap-draw-polygon-multi')); - }); - - it('"add shape" control should extend the same multi', function () { - var layer = new L.U.Polygon(this.map, [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)], {datalayer: this.datalayer}).addTo(this.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(this.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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polygon(this.map, [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - assert.ok(this.map.hasLayer(layer)); - layer.transferShape(p2ll(150, 150), other); - assert.equal(other._latlngs.length, 2); - assert.deepEqual(other._latlngs[1][0], latlngs); - assert.notOk(this.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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polygon(this.map, [p2ll(200, 350), p2ll(200, 300), p2ll(300, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - assert.ok(this.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(this.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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - assert.ok(this.map.hasLayer(layer)); - layer.isolateShape(p2ll(150, 150)); - assert.equal(layer._latlngs[0].length, 3); - assert.equal(this.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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - assert.ok(this.map.hasLayer(layer)); - var other = layer.isolateShape(p2ll(150, 150)); - assert.equal(this.datalayer._index.length, 2); - assert.equal(other._latlngs.length, 2); - assert.deepEqual(other._latlngs[0], latlngs[0][0]); - assert.ok(this.map.hasLayer(layer)); - assert.ok(this.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 L.U.Polygon(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - other = layer.clone(); - assert.ok(this.map.hasLayer(other)); - assert.equal(this.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); - }); - - }); - -}); + describe('#clone', function () { + it('should clone polygon', function () { + var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + layer = new L.U.Polygon(this.map, latlngs, { datalayer: this.datalayer }).addTo( + this.datalayer + ) + assert.equal(this.datalayer._index.length, 1) + other = layer.clone() + assert.ok(this.map.hasLayer(other)) + assert.equal(this.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/static/umap/test/Polyline.js b/umap/static/umap/test/Polyline.js index c92b19d0..8e8d4607 100644 --- a/umap/static/umap/test/Polyline.js +++ b/umap/static/umap/test/Polyline.js @@ -1,326 +1,400 @@ describe('L.Utorage.Polyline', function () { - var p2ll, map; + var p2ll, map - before(function () { - this.map = map = initMap({umap_id: 99}); - enableEdit(); - p2ll = function (x, y) { - return map.containerPointToLatLng([x, y]); - }; - this.datalayer = this.map.createDataLayer(); - this.datalayer.connectToMap();; - }); + before(function () { + this.map = map = initMap({ umap_id: 99 }) + enableEdit() + p2ll = function (x, y) { + return map.containerPointToLatLng([x, y]) + } + this.datalayer = this.map.createDataLayer() + this.datalayer.connectToMap() + }) - after(function () { - clickCancel(); - resetMap(); - }); + after(function () { + clickCancel() + resetMap() + }) + afterEach(function () { + this.datalayer.empty() + }) + + describe('#isMulti()', function () { + it('should return false for basic Polyline', function () { + var layer = new L.U.Polyline( + this.map, + [ + [1, 2], + [3, 4], + [5, 6], + ], + { datalayer: this.datalayer } + ) + assert.notOk(layer.isMulti()) + }) + + it('should return false for nested basic Polyline', function () { + var layer = new L.U.Polyline( + this.map, + [ + [ + [1, 2], + [3, 4], + [5, 6], + ], + ], + { datalayer: this.datalayer } + ) + assert.notOk(layer.isMulti()) + }) + + it('should return true for multi Polyline', function () { + var latLngs = [ + [ + [ + [1, 2], + [3, 4], + [5, 6], + ], + ], + [ + [ + [7, 8], + [9, 10], + [11, 12], + ], + ], + ] + var layer = new L.U.Polyline(this.map, latLngs, { datalayer: this.datalayer }) + assert.ok(layer.isMulti()) + }) + }) + + describe('#contextmenu', function () { afterEach(function () { - this.datalayer.empty(); - }); + // Make sure contextmenu is hidden. + happen.once(document, { type: 'keydown', keyCode: 27 }) + }) - describe('#isMulti()', function () { + describe('#in edit mode', function () { + it('should allow to remove shape when multi', function () { + var latlngs = [ + [p2ll(100, 100), p2ll(100, 200)], + [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.equal(qst('Remove shape from the multi'), 1) + }) - it('should return false for basic Polyline', function () { - var layer = new L.U.Polyline(this.map, [[1, 2], [3, 4], [5, 6]], {datalayer: this.datalayer}); - assert.notOk(layer.isMulti()) - }); + it('should not allow to remove shape when not multi', function () { + var latlngs = [[p2ll(100, 100), p2ll(100, 200)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Remove shape from the multi')) + }) - it('should return false for nested basic Polyline', function () { - var layer = new L.U.Polyline(this.map, [[[1, 2], [3, 4], [5, 6]]], {datalayer: this.datalayer}); - assert.notOk(layer.isMulti()) - }); + it('should not allow to isolate shape when not multi', function () { + var latlngs = [[p2ll(100, 100), p2ll(100, 200)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Extract shape to separate feature')) + }) - it('should return true for multi Polyline', function () { - var latLngs = [ - [ - [[1, 2], [3, 4], [5, 6]] - ], - [ - [[7, 8], [9, 10], [11, 12]] - ] - ]; - var layer = new L.U.Polyline(this.map, latLngs, {datalayer: this.datalayer}); - assert.ok(layer.isMulti()) - }); + it('should allow to isolate shape when multi', function () { + var latlngs = [ + [p2ll(100, 150), p2ll(100, 200)], + [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.ok(qst('Extract shape to separate feature')) + }) - }); + it('should not allow to transform to polygon when multi', function () { + var latlngs = [ + [p2ll(100, 150), p2ll(100, 200)], + [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Transform to polygon')) + }) - describe('#contextmenu', function () { + it('should allow to transform to polygon when not multi', function () { + var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.equal(qst('Transform to polygon'), 1) + }) - afterEach(function () { - // Make sure contextmenu is hidden. - happen.once(document, {type: 'keydown', keyCode: 27}); - }); + it('should not allow to transfer shape when not editedFeature', function () { + var layer = new L.U.Polyline(this.map, [p2ll(100, 150), p2ll(100, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Transfer shape to edited feature')) + }) - describe('#in edit mode', function () { + it('should not allow to transfer shape when editedFeature is not a line', function () { + var layer = new L.U.Polyline(this.map, [p2ll(100, 150), p2ll(100, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer), + other = new L.U.Polygon( + this.map, + [p2ll(200, 300), p2ll(300, 200), p2ll(200, 100)], + { datalayer: this.datalayer } + ).addTo(this.datalayer) + other.edit() + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Transfer shape to edited feature')) + }) - it('should allow to remove shape when multi', function () { - var latlngs = [ - [p2ll(100, 100), p2ll(100, 200)], - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}) - assert.equal(qst('Remove shape from the multi'), 1); - }); + it('should allow to transfer shape when another line is edited', function () { + var layer = new L.U.Polyline( + this.map, + [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + { datalayer: this.datalayer } + ).addTo(this.datalayer), + other = new L.U.Polyline(this.map, [p2ll(200, 300), p2ll(300, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + other.edit() + happen.once(layer._path, { type: 'contextmenu' }) + assert.equal(qst('Transfer shape to edited feature'), 1) + }) - it('should not allow to remove shape when not multi', function () { - var latlngs = [ - [p2ll(100, 100), p2ll(100, 200)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}) - assert.notOk(qst('Remove shape from the multi')); - }); + it('should allow to merge lines when multi', function () { + var latlngs = [ + [p2ll(100, 100), p2ll(100, 200)], + [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.equal(qst('Merge lines'), 1) + }) - it('should not allow to isolate shape when not multi', function () { - var latlngs = [ - [p2ll(100, 100), p2ll(100, 200)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}) - assert.notOk(qst('Extract shape to separate feature')); - }); + it('should not allow to merge lines when not multi', function () { + var latlngs = [[p2ll(100, 100), p2ll(100, 200)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + happen.once(layer._path, { type: 'contextmenu' }) + assert.notOk(qst('Merge lines')) + }) - it('should allow to isolate shape when multi', function () { - var latlngs = [ - [p2ll(100, 150), p2ll(100, 200)], - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.ok(qst('Extract shape to separate feature')); - }); + it('should allow to split lines when clicking on vertex', function () { + var latlngs = [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.enableEdit() + happen.at('contextmenu', 350, 400) + assert.equal(qst('Split line'), 1) + }) - it('should not allow to transform to polygon when multi', function () { - var latlngs = [ - [p2ll(100, 150), p2ll(100, 200)], - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Transform to polygon')); - }); + it('should not allow to split lines when clicking on first vertex', function () { + var latlngs = [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.enableEdit() + happen.at('contextmenu', 300, 350) + assert.equal(qst('Delete this feature'), 1) // Make sure we have clicked on the vertex. + assert.notOk(qst('Split line')) + }) - it('should allow to transform to polygon when not multi', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.equal(qst('Transform to polygon'), 1); - }); + it('should not allow to split lines when clicking on last vertex', function () { + var latlngs = [[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.enableEdit() + happen.at('contextmenu', 400, 300) + assert.equal(qst('Delete this feature'), 1) // Make sure we have clicked on the vertex. + assert.notOk(qst('Split line')) + }) + }) + }) - it('should not allow to transfer shape when not editedFeature', function () { - var layer = new L.U.Polyline(this.map, [p2ll(100, 150), p2ll(100, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Transfer shape to edited feature')); - }); + describe('#addShape', function () { + it('"add shape" control should not be visible by default', function () { + assert.notOk(qs('.umap-draw-polyline-multi')) + }) - it('should not allow to transfer shape when editedFeature is not a line', function () { - var layer = new L.U.Polyline(this.map, [p2ll(100, 150), p2ll(100, 200)], {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polygon(this.map, [p2ll(200, 300), p2ll(300, 200), p2ll(200, 100)], {datalayer: this.datalayer}).addTo(this.datalayer); - other.edit(); - happen.once(layer._path, {type: 'contextmenu'}); - assert.notOk(qst('Transfer shape to edited feature')); - }); + it('"add shape" control should be visible when editing a Polyline', function () { + var layer = new L.U.Polyline(this.map, [p2ll(100, 100), p2ll(100, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.edit() + assert.ok(qs('.umap-draw-polyline-multi')) + }) - it('should allow to transfer shape when another line is edited', function () { - var layer = new L.U.Polyline(this.map, [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polyline(this.map, [p2ll(200, 300), p2ll(300, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - other.edit(); - happen.once(layer._path, {type: 'contextmenu'}); - assert.equal(qst('Transfer shape to edited feature'), 1); - }); + it('"add shape" control should extend the same multi', function () { + var layer = new L.U.Polyline(this.map, [p2ll(100, 100), p2ll(100, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.edit() + assert.notOk(layer.isMulti()) + happen.click(qs('.umap-draw-polyline-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(this.datalayer._index.length, 1) + }) + }) - it('should allow to merge lines when multi', function () { - var latlngs = [ - [p2ll(100, 100), p2ll(100, 200)], - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}) - assert.equal(qst('Merge lines'), 1); - }); + describe('#transferShape', function () { + it('should transfer simple line shape to another line', function () { + var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer), + other = new L.U.Polyline(this.map, [p2ll(200, 300), p2ll(300, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.ok(this.map.hasLayer(layer)) + layer.transferShape(p2ll(150, 150), other) + assert.equal(other._latlngs.length, 2) + assert.deepEqual(other._latlngs[1], latlngs) + assert.notOk(this.map.hasLayer(layer)) + }) - it('should not allow to merge lines when not multi', function () { - var latlngs = [ - [p2ll(100, 100), p2ll(100, 200)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - happen.once(layer._path, {type: 'contextmenu'}) - assert.notOk(qst('Merge lines')); - }); + it('should transfer multi line shape to another line', function () { + var latlngs = [ + [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + [p2ll(200, 300), p2ll(300, 200)], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer), + other = new L.U.Polyline(this.map, [p2ll(250, 300), p2ll(350, 200)], { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.ok(this.map.hasLayer(layer)) + layer.transferShape(p2ll(150, 150), other) + assert.equal(other._latlngs.length, 2) + assert.deepEqual(other._latlngs[1], latlngs[0]) + assert.ok(this.map.hasLayer(layer)) + assert.equal(layer._latlngs.length, 1) + }) + }) - it('should allow to split lines when clicking on vertex', function () { - var latlngs = [ - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - layer.enableEdit(); - happen.at('contextmenu', 350, 400); - assert.equal(qst('Split line'), 1); - }); + describe('#mergeShapes', function () { + it('should remove duplicated join point when merging', function () { + var latlngs = [ + [ + [0, 0], + [0, 1], + ], + [ + [0, 1], + [0, 2], + ], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.mergeShapes() + layer.disableEdit() // Remove vertex from latlngs to compare them. + assert.deepEqual(layer.getLatLngs(), [ + L.latLng([0, 0]), + L.latLng([0, 1]), + L.latLng([0, 2]), + ]) + assert(this.map.isDirty) + }) - it('should not allow to split lines when clicking on first vertex', function () { - var latlngs = [ - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - layer.enableEdit(); - happen.at('contextmenu', 300, 350); - assert.equal(qst('Delete this feature'), 1); // Make sure we have clicked on the vertex. - assert.notOk(qst('Split line')); - }); + it('should revert candidate if first point is closer', function () { + var latlngs = [ + [ + [0, 0], + [0, 1], + ], + [ + [0, 2], + [0, 1], + ], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + layer.mergeShapes() + layer.disableEdit() + assert.deepEqual(layer.getLatLngs(), [ + L.latLng([0, 0]), + L.latLng([0, 1]), + L.latLng([0, 2]), + ]) + }) + }) - it('should not allow to split lines when clicking on last vertex', function () { - var latlngs = [ - [p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - layer.enableEdit(); - happen.at('contextmenu', 400, 300); - assert.equal(qst('Delete this feature'), 1); // Make sure we have clicked on the vertex. - assert.notOk(qst('Split line')); - }); + describe('#isolateShape', function () { + it('should not allow to isolate simple line', function () { + var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.equal(this.datalayer._index.length, 1) + assert.ok(this.map.hasLayer(layer)) + layer.isolateShape(p2ll(150, 150)) + assert.equal(layer._latlngs.length, 3) + assert.equal(this.datalayer._index.length, 1) + }) - }); + it('should isolate multipolyline shape', function () { + var latlngs = [ + [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + [[p2ll(200, 300), p2ll(300, 200)]], + ], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.equal(this.datalayer._index.length, 1) + assert.ok(this.map.hasLayer(layer)) + var other = layer.isolateShape(p2ll(150, 150)) + assert.equal(this.datalayer._index.length, 2) + assert.equal(other._latlngs.length, 3) + assert.deepEqual(other._latlngs, latlngs[0]) + assert.ok(this.map.hasLayer(layer)) + assert.ok(this.map.hasLayer(other)) + assert.equal(layer._latlngs.length, 1) + other.remove() + }) + }) - }); - - describe('#addShape', function () { - - it('"add shape" control should not be visible by default', function () { - assert.notOk(qs('.umap-draw-polyline-multi')); - }); - - it('"add shape" control should be visible when editing a Polyline', function () { - var layer = new L.U.Polyline(this.map, [p2ll(100, 100), p2ll(100, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - layer.edit(); - assert.ok(qs('.umap-draw-polyline-multi')); - }); - - it('"add shape" control should extend the same multi', function () { - var layer = new L.U.Polyline(this.map, [p2ll(100, 100), p2ll(100, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - layer.edit(); - assert.notOk(layer.isMulti()); - happen.click(qs('.umap-draw-polyline-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(this.datalayer._index.length, 1); - }); - - }); - - describe('#transferShape', function () { - - it('should transfer simple line shape to another line', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polyline(this.map, [p2ll(200, 300), p2ll(300, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - assert.ok(this.map.hasLayer(layer)); - layer.transferShape(p2ll(150, 150), other); - assert.equal(other._latlngs.length, 2); - assert.deepEqual(other._latlngs[1], latlngs); - assert.notOk(this.map.hasLayer(layer)); - }); - - it('should transfer multi line shape to another line', function () { - var latlngs = [ - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - [p2ll(200, 300), p2ll(300, 200)] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer), - other = new L.U.Polyline(this.map, [p2ll(250, 300), p2ll(350, 200)], {datalayer: this.datalayer}).addTo(this.datalayer); - assert.ok(this.map.hasLayer(layer)); - layer.transferShape(p2ll(150, 150), other); - assert.equal(other._latlngs.length, 2); - assert.deepEqual(other._latlngs[1], latlngs[0]); - assert.ok(this.map.hasLayer(layer)); - assert.equal(layer._latlngs.length, 1); - }); - - }); - - describe('#mergeShapes', function () { - - it('should remove duplicated join point when merging', function () { - var latlngs = [ - [[0, 0], [0, 1]], - [[0, 1], [0, 2]], - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - layer.mergeShapes(); - layer.disableEdit(); // Remove vertex from latlngs to compare them. - assert.deepEqual(layer.getLatLngs(), [L.latLng([0, 0]), L.latLng([0, 1]), L.latLng([0, 2])]); - assert(this.map.isDirty); - }); - - it('should revert candidate if first point is closer', function () { - var latlngs = [ - [[0, 0], [0, 1]], - [[0, 2], [0, 1]], - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - layer.mergeShapes(); - layer.disableEdit(); - assert.deepEqual(layer.getLatLngs(), [L.latLng([0, 0]), L.latLng([0, 1]), L.latLng([0, 2])]); - }); - - }); - - - describe('#isolateShape', function () { - - it('should not allow to isolate simple line', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - assert.ok(this.map.hasLayer(layer)); - layer.isolateShape(p2ll(150, 150)); - assert.equal(layer._latlngs.length, 3); - assert.equal(this.datalayer._index.length, 1); - }); - - it('should isolate multipolyline shape', function () { - var latlngs = [ - [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - [[p2ll(200, 300), p2ll(300, 200)]] - ], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - assert.ok(this.map.hasLayer(layer)); - var other = layer.isolateShape(p2ll(150, 150)); - assert.equal(this.datalayer._index.length, 2); - assert.equal(other._latlngs.length, 3); - assert.deepEqual(other._latlngs, latlngs[0]); - assert.ok(this.map.hasLayer(layer)); - assert.ok(this.map.hasLayer(other)); - assert.equal(layer._latlngs.length, 1); - other.remove(); - }); - - }); - - describe('#clone', function () { - - it('should clone polyline', function () { - var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], - layer = new L.U.Polyline(this.map, latlngs, {datalayer: this.datalayer}).addTo(this.datalayer); - assert.equal(this.datalayer._index.length, 1); - other = layer.clone(); - assert.ok(this.map.hasLayer(other)); - assert.equal(this.datalayer._index.length, 2); - // Must not be the same reference - assert.notEqual(layer._latlngs, other._latlngs); - assert.equal(L.Util.formatNum(layer._latlngs[0].lat), other._latlngs[0].lat); - assert.equal(L.Util.formatNum(layer._latlngs[0].lng), other._latlngs[0].lng); - }); - - }); - -}); + describe('#clone', function () { + it('should clone polyline', function () { + var latlngs = [p2ll(100, 150), p2ll(100, 200), p2ll(200, 100)], + layer = new L.U.Polyline(this.map, latlngs, { + datalayer: this.datalayer, + }).addTo(this.datalayer) + assert.equal(this.datalayer._index.length, 1) + other = layer.clone() + assert.ok(this.map.hasLayer(other)) + assert.equal(this.datalayer._index.length, 2) + // Must not be the same reference + assert.notEqual(layer._latlngs, other._latlngs) + assert.equal(L.Util.formatNum(layer._latlngs[0].lat), other._latlngs[0].lat) + assert.equal(L.Util.formatNum(layer._latlngs[0].lng), other._latlngs[0].lng) + }) + }) +}) diff --git a/umap/static/umap/test/TableEditor.js b/umap/static/umap/test/TableEditor.js index 6672c16a..c6f112b5 100644 --- a/umap/static/umap/test/TableEditor.js +++ b/umap/static/umap/test/TableEditor.js @@ -1,94 +1,101 @@ describe('L.TableEditor', function () { - var path = '/map/99/datalayer/edit/62/'; + var path = '/map/99/datalayer/edit/62/' + + before(function () { + this.server = sinon.fakeServer.create() + this.server.respondWith( + 'GET', + '/datalayer/62/', + JSON.stringify(RESPONSES.datalayer62_GET) + ) + this.map = initMap({ umap_id: 99 }) + this.datalayer = this.map.getDataLayerByUmapId(62) + this.server.respond() + enableEdit() + }) + after(function () { + clickCancel() + this.server.restore() + resetMap() + }) + + describe('#open()', function () { + var button + + it('should exist table click on edit mode', function () { + button = qs( + '#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-table-edit' + ) + expect(button).to.be.ok + }) + + it('should open table button click', function () { + happen.click(button) + expect(qs('#umap-ui-container div.table')).to.be.ok + expect(qsa('#umap-ui-container div.table form').length).to.eql(3) // One per feature. + expect(qsa('#umap-ui-container div.table input').length).to.eql(3) // One per feature and per property. + }) + }) + describe('#properties()', function () { + var feature before(function () { - this.server = sinon.fakeServer.create(); - this.server.respondWith('GET', '/datalayer/62/', JSON.stringify(RESPONSES.datalayer62_GET)); - this.map = initMap({umap_id: 99}); - this.datalayer = this.map.getDataLayerByUmapId(62); - this.server.respond(); - enableEdit(); - }); - after(function () { - clickCancel(); - this.server.restore(); - resetMap(); - }); + var firstIndex = this.datalayer._index[0] + feature = this.datalayer._layers[firstIndex] + }) - describe('#open()', function () { - var button; + it('should create new property column', function () { + var newPrompt = function () { + return 'newprop' + } + var oldPrompt = window.prompt + window.prompt = newPrompt + var button = qs('#umap-ui-container .add-property') + expect(button).to.be.ok + happen.click(button) + expect(qsa('#umap-ui-container div.table input').length).to.eql(6) // One per feature and per property. + window.prompt = oldPrompt + }) - it('should exist table click on edit mode', function () { - button = qs('#browse_data_toggle_' + L.stamp(this.datalayer) + ' .layer-table-edit'); - expect(button).to.be.ok; - }); + it('should populate feature property on fill', function () { + var input = qs( + 'form#umap-feature-properties_' + L.stamp(feature) + ' input[name=newprop]' + ) + changeInputValue(input, 'the value') + expect(feature.properties.newprop).to.eql('the value') + }) - it('should open table button click', function () { - happen.click(button); - expect(qs('#umap-ui-container div.table')).to.be.ok; - expect(qsa('#umap-ui-container div.table form').length).to.eql(3); // One per feature. - expect(qsa('#umap-ui-container div.table input').length).to.eql(3); // One per feature and per property. - }); + it('should update property name on update click', function () { + var newPrompt = function () { + return 'newname' + } + var oldPrompt = window.prompt + window.prompt = newPrompt + var button = qs('#umap-ui-container div.thead div.tcell:last-of-type .umap-edit') + expect(button).to.be.ok + happen.click(button) + expect(qsa('#umap-ui-container div.table input').length).to.eql(6) + expect(feature.properties.newprop).to.be.undefined + expect(feature.properties.newname).to.eql('the value') + window.prompt = oldPrompt + }) - }); - describe('#properties()', function () { - var feature; - - before(function () { - var firstIndex = this.datalayer._index[0]; - feature = this.datalayer._layers[firstIndex]; - }); - - it('should create new property column', function () { - var newPrompt = function () { - return 'newprop'; - }; - var oldPrompt = window.prompt; - window.prompt = newPrompt; - var button = qs('#umap-ui-container .add-property'); - expect(button).to.be.ok; - happen.click(button); - expect(qsa('#umap-ui-container div.table input').length).to.eql(6); // One per feature and per property. - window.prompt = oldPrompt; - }); - - it('should populate feature property on fill', function () { - var input = qs('form#umap-feature-properties_' + L.stamp(feature) + ' input[name=newprop]'); - changeInputValue(input, 'the value'); - expect(feature.properties.newprop).to.eql('the value'); - }); - - it('should update property name on update click', function () { - var newPrompt = function () { - return 'newname'; - }; - var oldPrompt = window.prompt; - window.prompt = newPrompt; - var button = qs('#umap-ui-container div.thead div.tcell:last-of-type .umap-edit'); - expect(button).to.be.ok; - happen.click(button); - expect(qsa('#umap-ui-container div.table input').length).to.eql(6); - expect(feature.properties.newprop).to.be.undefined; - expect(feature.properties.newname).to.eql('the value'); - window.prompt = oldPrompt; - }); - - it('should update property on delete click', function () { - var oldConfirm, - newConfirm = function () { - return true; - }; - oldConfirm = window.confirm; - window.confirm = newConfirm; - var button = qs('#umap-ui-container div.thead div.tcell:last-of-type .umap-delete'); - expect(button).to.be.ok; - happen.click(button); - FEATURE = feature; - expect(qsa('#umap-ui-container div.table input').length).to.eql(3); - expect(feature.properties.newname).to.be.undefined; - window.confirm = oldConfirm; - }); - - }); - -}); + it('should update property on delete click', function () { + var oldConfirm, + newConfirm = function () { + return true + } + oldConfirm = window.confirm + window.confirm = newConfirm + var button = qs( + '#umap-ui-container div.thead div.tcell:last-of-type .umap-delete' + ) + expect(button).to.be.ok + happen.click(button) + FEATURE = feature + expect(qsa('#umap-ui-container div.table input').length).to.eql(3) + expect(feature.properties.newname).to.be.undefined + window.confirm = oldConfirm + }) + }) +}) diff --git a/umap/static/umap/test/Util.js b/umap/static/umap/test/Util.js index 04ba27b2..836be108 100644 --- a/umap/static/umap/test/Util.js +++ b/umap/static/umap/test/Util.js @@ -1,285 +1,435 @@ describe('L.Util', function () { - - describe('#toHTML()', function () { - - it('should handle title', function () { - assert.equal(L.Util.toHTML('# A title'), '