From 2acaa3117841c905b84fef9aede31fc9774ba7bd Mon Sep 17 00:00:00 2001 From: Riadh Habbachi <riadh@angrycactus.biz> Date: Tue, 8 Sep 2015 15:55:03 +0100 Subject: [PATCH 1/7] Improve tabs implementation for leaflet widget --- js/draw.js | 448 ++++++++++++++++++++++-------------------- leaflet_widget.module | 1 + 2 files changed, 241 insertions(+), 208 deletions(-) diff --git a/js/draw.js b/js/draw.js index 1a817ad..b95f2c4 100644 --- a/js/draw.js +++ b/js/draw.js @@ -1,244 +1,276 @@ (function ($) { - Drupal.leaflet_widget = Drupal.leaflet_widget || {}; - - Drupal.behaviors.geofield_widget = { - attach: attach - }; - - function attach(context, settings) { - $('.leaflet-widget').once().each(function(i, item) { - var id = $(item).attr('id'), - options = settings.leaflet_widget_widget[id]; - if (options.toggle) { - $('#' + id + '-input').before('<div class="map btn btn-default" style="cursor: pointer;" id="' + id + '-geojson-toggle">GEOJSON</div>'); - $('#' + id + '-input').before('<div class="map btn btn-default" style="cursor: pointer;" id="' + id + '-point-toggle">POINT</div></br><input type="text" id="manual-' + id + '-point-input" name="manual-point">'); - $('#manual-' + id + '-point-input').hide(); - $('#' + id + '-geojson-toggle').click(function () { - $(item).toggle(); - if ($(this).hasClass('map')) { - $(this).text('Use map'); - $(this).removeClass('map'); - $('#' + id + '-input').get(0).type = 'text'; - - //Hide select geographic areas if is enable. - if (options.geographic_areas) { - $('.geographic_areas_desc').hide(); - } - } - else { - $(this).text('GEOJSON'); - $('#' + id + '-input').get(0).type = 'hidden'; - $(this).addClass('map'); - - //Show select geographic areas if is enable. - if (options.geographic_areas) { - $('.geographic_areas_desc').show(); - } - } - }); + Drupal.leaflet_widget = Drupal.leaflet_widget || {}; - $('#' + id + '-point-toggle').click(function () { - $(item).toggle(); - $('#manual-' + id + '-point-input').toggle(); + Drupal.behaviors.geofield_widget = { + attach: attach + }; - if ($(this).hasClass('map')) { - $(this).text('Use map'); - $(this).removeClass('map'); - $('#manual-' + id + '-point-input').get(0).type = 'text'; + function attach(context, settings) { + $('.leaflet-widget').once().each(function(i, item) { + var id = $(item).attr('id'), + options = settings.leaflet_widget_widget[id]; - //Hide select geographic areas if is enable. - if (options.geographic_areas) { - $('.geographic_areas_desc').hide(); - } - } - else { - $(this).text('POINT'); - $('#' + id + '-input').get(0).type = 'hidden'; - $(this).addClass('map'); - var point_string = $('#manual-' + id + '-point-input').val(); - - if (point_string) { - var point_array = point_string.split(','); - var geojsonFeature = { - "type": "Feature", - "properties": {}, - "geometry": { - "type": "Point", - "coordinates": [point_array[0], point_array[1]] - } - }; - L.geoJson(geojsonFeature).addTo(map); - leafletWidgetFormWrite(map._layers, id); - } + var map = L.map(id, options.map); - //Show select geographic areas if is enable. - if (options.geographic_areas) { - $('.geographic_areas_desc').show(); - } - } - }); + L.tileLayer(options.map.base_url).addTo(map); - } - if (options.geographic_areas) { - var json_data = {}; - var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>"; - selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>"; - - for (i = 0; i < options.areas.length; i++) { - json_data = jQuery.parseJSON(options.areas[i]); - $.each(json_data.features, function (index, item) { - selectList += "<option value='" + item.id + "'>" + item.properties.name + "</option>"; - }); - } - selectList += "</select></div></br>"; - $('#' + id + '-input').before(selectList); - - $('#geographic_areas').change(function() { - var area = $(this).val(); - - for (i = 0; i < options.areas.length; i++) { - json_data = jQuery.parseJSON(options.areas[i]); - $.each(json_data.features, function (index, item) { - if (item.id == area) { - L.geoJson(item).addTo(map); - leafletWidgetFormWrite(map._layers, id); - } - }); - } - }); - } - var map = L.map(id, options.map); - - L.tileLayer(options.map.base_url).addTo(map); - - var current = $('#' + id + '-input').val(); - current = JSON.parse(current); - var layers = Array(); - if (current.features.length) { - var geojson = L.geoJson(current) - for (var key in geojson._layers) { - layers.push(geojson._layers[key]); - } - } + // Get initial geojson value + var current = $('#' + id + '-input').val(); + current = JSON.parse(current); + var layers = Array(); + if (current.features.length) { + var geojson = L.geoJson(current) + for (var key in geojson._layers) { + layers.push(geojson._layers[key]); + } + } + + var Items = new L.FeatureGroup(layers).addTo(map); + + // Autocenter if that's cool. + if (options.map.auto_center) { + if (current.features.length) { + map.fitBounds(Items.getBounds()); + } + } + + // Add controles to the map + var drawControl = new L.Control.Draw({ + autocenter: true, + draw: { + position: 'topleft', + polygon: options.draw.tools.polygon, + circle: options.draw.tools.circle, + marker: options.draw.tools.marker, + rectangle: options.draw.tools.rectangle, + polyline: options.draw.tools.polyline + }, + edit: { + featureGroup: Items + } + }); + + map.addControl(drawControl); + + map.on('draw:created', function (e) { + var type = e.layerTypee, + layer = e.layer; + // Remove already created layers. We only want to save one + // per field. + leafletWidgetLayerRemove(map._layers, Items); + // Add new layer. + Items.addLayer(layer); + }); + + $(item).parents('form').submit(function(event){ + if ($('#' + id + '-toggle').hasClass('map')) { + leafletWidgetFormWrite(map._layers, id) + } + }); + + Drupal.leaflet_widget[id] = map; + + if (options.toggle) { + $('#' + id).before('<ul class="ui-tabs-nav leaflet-widget">' + + '<li><a href="#' + id + '">Map</a></li>' + + '<li><a href="#' + id + '-geojson' + '">GeoJSON</a></li>' + + '<li><a href="#' + id + '-points' + '">Points</a></li>' + + '</ul>'); + + $('#' + id).after('<div id="' + id + '-geojson">' + + '<label for="' + id + '-geojson-textarea">' + Drupal.t('Enter GeoJSON:') + '</label>' + + '<textarea class="text-full form-control form-textarea" id="' + id + '-geojson-textarea" cols="60" rows="10"></textarea>' + + '</div>'); + + // Set placeholder + $('#' + id + '-geojson-textarea').attr('placeholder', JSON.stringify({"type":"FeatureCollection","features":[]})); + + // Update field's input when geojson input is updated. + // @TODO validate before sync + $('#' + id + '-geojson-textarea').on('input', function(e) { + if(!$('#' + id + '-geojson-textarea').val()) { + $('#' + id + '-input').val(JSON.stringify({"type":"FeatureCollection","features":[]})); + } else { + $('#' + id + '-input').val($('#' + id + '-geojson-textarea').val()); + } + }); - var Items = new L.FeatureGroup(layers).addTo(map); - // Autocenter if that's cool. - if (options.map.auto_center) { + $('#' + id).after('<div id="' + id + '-points" class="">' + + '<label for="' + id + '-points">' + Drupal.t('Point') + '</label>' + + '<input class="text-full form-control form-text" type="text" id="' + id + '-points-input" " placeholder="longitude,latitude" "size="60" maxlength="255">' + + '</div>'); + + // Update field's input when geojson input is updated. + $('#' + id + '-points-input').on('input', function(e) { + var latlng = L.latLng($('#' + id + '-points-input').val().split(',')); + var coordinates = LatLngToCoords(latlng); + var write = JSON.stringify( + {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":coordinates},"properties":[]}]} + ); + $('#' + id + '-input').val(write); + }); + + // Set parent as JQuery UI element and update on selection + $('#' + id).parent().tabs({ + // Default tab is the map tab. + selected: 0, + select: function(event, ui){ + switch(ui.index) { + case 0: + // Map tab is selected + // Clear previous layers + leafletWidgetLayerRemove(map._layers, Items); + var current = $('#' + id + '-input').val(); + current = JSON.parse(current); if (current.features.length) { + var geojson = L.geoJson(current) + for (var key in geojson._layers) { + // Add new layer. + Items.addLayer(geojson._layers[key]); + } map.fitBounds(Items.getBounds()); } + break; + + case 1: + // GeoJSON tab is selected + // Sync from field's input + $('#' + id + '-geojson-textarea').val($('#' + id + '-input').val()); + break; + + case 2: + // Points tab is selected + // Reset value and error message and classes (if any). + $('#' + id + '-points-input').val(''); + $('#' + id + '-points-input').parent().removeClass('has-error'); + $('#' + id + '-points-input').prop('disabled', false) + .removeClass('error'); + $('#' + id + '-points .help-block').remove(); + + var current = $('#' + id + '-input').val(); + current = JSON.parse(current); + // Make this unavailable if more then single point. + if (current.features.length == 0) { + // Empty. Nothing to do + } else if (current.features.length == 1 + && current.features[0].geometry.type == 'Point') { + $('#' + id + '-points-input').val(current.features[0].geometry.coordinates.toString()); + } else { + $('#' + id + '-points-input').parent().addClass('has-error'); + $('#' + id + '-points-input').prop('disabled', true) + .addClass('error') + .after('<span class="help-block">Current data cannot be converted to a single point!</span>'); + } + break; } + } + }); + } - var drawControl = new L.Control.Draw({ - autocenter: true, - draw: { - position: 'topleft', - polygon: options.draw.tools.polygon, - circle: options.draw.tools.circle, - marker: options.draw.tools.marker, - rectangle: options.draw.tools.rectangle, - polyline: options.draw.tools.polyline - }, - edit: { - featureGroup: Items - } - - }); + if (options.geographic_areas) { + var json_data = {}; + var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>"; + selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>"; - map.addControl(drawControl); + for (i = 0; i < options.areas.length; i++) { + json_data = jQuery.parseJSON(options.areas[i]); + $.each(json_data.features, function (index, item) { + selectList += "<option value='" + item.id + "'>" + item.properties.name + "</option>"; + }); + } - map.on('draw:created', function (e) { - var type = e.layerTypee, - layer = e.layer; - // Remove already created layers. We only want to save one - // per field. - leafletWidgetLayerRemove(map._layers, Items); - // Add new layer. - Items.addLayer(layer); - }); + selectList += "</select></div></br>"; + $('#' + id + '-input').before(selectList); - $(item).parents('form').submit(function(event){ - if ($('#' + id + '-toggle').hasClass('map')) { - leafletWidgetFormWrite(map._layers, id) - } - }); + $('#geographic_areas').change(function() { + var area = $(this).val(); - Drupal.leaflet_widget[id] = map; + for (i = 0; i < options.areas.length; i++) { + json_data = jQuery.parseJSON(options.areas[i]); + $.each(json_data.features, function (index, item) { + if (item.id == area) { + L.geoJson(item).addTo(map); + leafletWidgetFormWrite(map._layers, id); + } + }); + } }); - } - - /** - * Writes layer to input field if there is a layer to write. - */ - function leafletWidgetFormWrite(layers, id) { - var write = Array(); - for (var key in layers) { - if (layers[key]._latlngs || layers[key]._latlng) { - write.push(layerToGeometry(layers[key])); - } } - // If no value then provide empty collection. - if (!write.length) { - write = JSON.stringify({"type":"FeatureCollection","features":[]}); + }); + } + + /** + * Writes layer to input field if there is a layer to write. + */ + function leafletWidgetFormWrite(layers, id) { + var write = Array(); + for (var key in layers) { + if (layers[key]._latlngs || layers[key]._latlng) { + write.push(layerToGeometry(layers[key])); } - $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}'); } - - /** - * Removes layers that are already on the map. - */ - function leafletWidgetLayerRemove(layers, Items) { - for (var key in layers) { - if (layers[key]._latlngs || layers[key]._latlng) { - Items.removeLayer(layers[key]); - } + // If no value then provide empty collection. + if (!write.length) { + write = JSON.stringify({"type":"FeatureCollection","features":[]}); + } + $('#' + id + '-input').val('{"type":"FeatureCollection", "features":[' + write + ']}'); + } + + /** + * Removes layers that are already on the map. + */ + function leafletWidgetLayerRemove(layers, Items) { + for (var key in layers) { + if (layers[key]._latlngs || layers[key]._latlng) { + Items.removeLayer(layers[key]); } } + } - // This will all go away once this gets into leaflet main branch: - // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998 - var layerToGeometry = function(layer) { - var json, type, latlng, latlngs = [], i; + // This will all go away once this gets into leaflet main branch: + // https://github.com/jfirebaugh/Leaflet/commit/4bc36d4c1926d7c68c966264f3cbf179089bd998 + var layerToGeometry = function(layer) { + var json, type, latlng, latlngs = [], i; - if (L.Marker && (layer instanceof L.Marker)) { - type = 'Point'; - latlng = LatLngToCoords(layer._latlng); - return JSON.stringify({"type": type, "coordinates": latlng}); + if (L.Marker && (layer instanceof L.Marker)) { + type = 'Point'; + latlng = LatLngToCoords(layer._latlng); + return JSON.stringify({"type": type, "coordinates": latlng}); - } else if (L.Polygon && (layer instanceof L.Polygon)) { - type = 'Polygon'; - latlngs = LatLngsToCoords(layer._latlngs, 1); - return JSON.stringify({"type": type, "coordinates": [latlngs]}); + } else if (L.Polygon && (layer instanceof L.Polygon)) { + type = 'Polygon'; + latlngs = LatLngsToCoords(layer._latlngs, 1); + return JSON.stringify({"type": type, "coordinates": [latlngs]}); - } else if (L.Polyline && (layer instanceof L.Polyline)) { - type = 'LineString'; - latlngs = LatLngsToCoords(layer._latlngs); - return JSON.stringify({"type": type, "coordinates": latlngs}); + } else if (L.Polyline && (layer instanceof L.Polyline)) { + type = 'LineString'; + latlngs = LatLngsToCoords(layer._latlngs); + return JSON.stringify({"type": type, "coordinates": latlngs}); - } } + } - var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array - var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat), - lng = parseFloat(reverse ? LatLng.lat : LatLng.lng); - - return [lng,lat]; - } + var LatLngToCoords = function (LatLng, reverse) { // (LatLng, Boolean) -> Array + var lat = parseFloat(reverse ? LatLng.lng : LatLng.lat), + lng = parseFloat(reverse ? LatLng.lat : LatLng.lng); - var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array - var coord, - coords = [], - i, len; + return [lng,lat]; + } - for (i = 0, len = LatLngs.length; i < len; i++) { - coord = levelsDeep ? - LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) : - LatLngToCoords(LatLngs[i], reverse); - coords.push(coord); - } + var LatLngsToCoords = function (LatLngs, levelsDeep, reverse) { // (LatLngs, Number, Boolean) -> Array + var coord, + coords = [], + i, len; - return coords; + for (i = 0, len = LatLngs.length; i < len; i++) { + coord = levelsDeep ? + LatLngToCoords(LatLngs[i], levelsDeep - 1, reverse) : + LatLngToCoords(LatLngs[i], reverse); + coords.push(coord); } + return coords; + } + }(jQuery)); diff --git a/leaflet_widget.module b/leaflet_widget.module index 127b148..842f589 100644 --- a/leaflet_widget.module +++ b/leaflet_widget.module @@ -172,6 +172,7 @@ function leaflet_widget_field_widget_form(&$form, &$form_state, $field, $instanc // Include javascript. $widget['#attached']['library'][] = array('leaflet_widget', 'draw'); + $widget['#attached']['library'][] = array('system', 'ui.tabs'); //Check if we need to add geographic areas if (isset($settings['geographic_areas']) && $settings['geographic_areas']) { From 5dd2e4eb4f44280d5db0299b22c75ce17bd11d43 Mon Sep 17 00:00:00 2001 From: Riadh Habbachi <riadh@angrycactus.biz> Date: Tue, 8 Sep 2015 19:23:47 +0100 Subject: [PATCH 2/7] Update the field's input when updating the map. * Fix missing geojson propreties. --- js/draw.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/js/draw.js b/js/draw.js index b95f2c4..8c442e9 100644 --- a/js/draw.js +++ b/js/draw.js @@ -61,12 +61,9 @@ leafletWidgetLayerRemove(map._layers, Items); // Add new layer. Items.addLayer(layer); - }); - $(item).parents('form').submit(function(event){ - if ($('#' + id + '-toggle').hasClass('map')) { - leafletWidgetFormWrite(map._layers, id) - } + // Update the field input. + leafletWidgetFormWrite(Items._layers, id) }); Drupal.leaflet_widget[id] = map; @@ -207,7 +204,8 @@ var write = Array(); for (var key in layers) { if (layers[key]._latlngs || layers[key]._latlng) { - write.push(layerToGeometry(layers[key])); + var feature = '{ "type": "Feature","geometry":' + layerToGeometry(layers[key]) + '}'; + write.push(feature); } } // If no value then provide empty collection. From d02020d1276c55e36e2c995d5d4b4711cb02c55f Mon Sep 17 00:00:00 2001 From: Jacinto capote Robles <jacintocapote@gmail.com> Date: Thu, 10 Sep 2015 22:01:38 +0200 Subject: [PATCH 3/7] Fixed problem deleting items after use the new interface with the select regions --- js/draw.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/js/draw.js b/js/draw.js index 8c442e9..62b33dc 100644 --- a/js/draw.js +++ b/js/draw.js @@ -47,7 +47,7 @@ polyline: options.draw.tools.polyline }, edit: { - featureGroup: Items + featureGroup: Items, } }); @@ -60,7 +60,7 @@ // per field. leafletWidgetLayerRemove(map._layers, Items); // Add new layer. - Items.addLayer(layer); + Items.addLayer(layer); // Update the field input. leafletWidgetFormWrite(Items._layers, id) @@ -187,7 +187,12 @@ json_data = jQuery.parseJSON(options.areas[i]); $.each(json_data.features, function (index, item) { if (item.id == area) { - L.geoJson(item).addTo(map); + var geojson = L.geoJson(item, { + onEachFeature: function (feature, layer) { + Items.addLayer(layer); + + } + }); leafletWidgetFormWrite(map._layers, id); } }); From 535f6b155d10a9154f6fa7ff819f6d05411b7464 Mon Sep 17 00:00:00 2001 From: Jacinto capote Robles <jacintocapote@gmail.com> Date: Thu, 10 Sep 2015 22:05:16 +0200 Subject: [PATCH 4/7] Fixed label to use region instead state --- js/draw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/draw.js b/js/draw.js index 62b33dc..d148ed3 100644 --- a/js/draw.js +++ b/js/draw.js @@ -167,7 +167,7 @@ if (options.geographic_areas) { var json_data = {}; - var selectList = "<div class='geographic_areas_desc'><p></br>Select a state to add into the map:</p><select id='geographic_areas' name='area'>"; + var selectList = "<div class='geographic_areas_desc'><p></br>Select a region to add into the map:</p><select id='geographic_areas' name='area'>"; selectList += "<option value='0'>" + Drupal.t('-none-') + "</option>"; for (i = 0; i < options.areas.length; i++) { From 67c4e01dd6349adae73857edc9ec5f5462edfb23 Mon Sep 17 00:00:00 2001 From: Jacinto capote Robles <jacintocapote@gmail.com> Date: Fri, 11 Sep 2015 22:07:28 +0200 Subject: [PATCH 5/7] Fixed problem deleting and saving a polygon --- js/draw.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/js/draw.js b/js/draw.js index d148ed3..ab29110 100644 --- a/js/draw.js +++ b/js/draw.js @@ -66,6 +66,10 @@ leafletWidgetFormWrite(Items._layers, id) }); + map.on('draw:deleted', function (e) { + $('#' + id + '-input').val(''); + }); + Drupal.leaflet_widget[id] = map; if (options.toggle) { @@ -189,6 +193,9 @@ if (item.id == area) { var geojson = L.geoJson(item, { onEachFeature: function (feature, layer) { + // Remove already created layers. We only want to save one + // per field. + leafletWidgetLayerRemove(map._layers, Items); Items.addLayer(layer); } From 1e785275c816e7f57ed0ff3fc1e60e6be30c980d Mon Sep 17 00:00:00 2001 From: Aaron Couch <acinternets@gmail.com> Date: Mon, 28 Sep 2015 16:42:40 -0500 Subject: [PATCH 6/7] Update leaflet_widget.module Fixes for https --- leaflet_widget.module | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/leaflet_widget.module b/leaflet_widget.module index 842f589..623be6a 100644 --- a/leaflet_widget.module +++ b/leaflet_widget.module @@ -335,7 +335,7 @@ function leaflet_widget_geojson_feature($wkt, $properties = array()) { */ function leaflet_widget_leaflet_widget_base_layers() { return array( - 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik', + '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' => 'OSM Mapnik', ); } From 5ae229a01a9f2ac94c63fedfcd91da88b97a7bc5 Mon Sep 17 00:00:00 2001 From: Riadh Habbachi <riadh@angrycactus.biz> Date: Wed, 4 Nov 2015 12:11:59 +0100 Subject: [PATCH 7/7] Add test based on NuCivic/leaflet_draw_widget#8 * Better travis file copied from other repo. * Use dkanextension. * Fixes for leaflet_widget.feature --- .travis.yml | 73 ++++++++++++++++++++++ test/.gitignore | 4 ++ test/behat.yml | 49 +++++++++++++++ test/composer.json | 8 +++ test/features/bootstrap/FeatureContext.php | 20 ++++++ test/features/leaflet_widget.feature | 21 +++++++ 6 files changed, 175 insertions(+) create mode 100644 .travis.yml create mode 100644 test/.gitignore create mode 100644 test/behat.yml create mode 100644 test/composer.json create mode 100644 test/features/bootstrap/FeatureContext.php create mode 100644 test/features/leaflet_widget.feature diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7756401 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,73 @@ +language: php + +php: + - 5.5 + +mysql: + database: leaflet_draw_widget_test + username: root + encoding: utf8 + +install: + - cd test + - composer install + - mysql -e 'create database leaflet_draw_widget_test;' + - sudo apt-get update > /dev/null + - sudo apt-get --quiet=2 install php5-cgi php5-curl php5-gd php5-mysql > /dev/null + + # Install latest Drush 7. + - export PATH="$HOME/.composer/vendor/bin:$PATH" + - composer global require --no-interaction drush/drush:dev-master + - composer global require --no-interaction youngj/httpserver:* + - drush dl registry_rebuild + # Disable sendmail + - echo sendmail_path=`which true` >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini + +before_script: + # Navigate out of TRAVIS_BUILD_DIR to prevent blown stack by recursive module lookup + - cd ../.. + # Grab dkan + - git clone --branch 7.x-1.x https://github.com/NuCivic/dkan.git + # Prepare install + - mkdir drupal + - cd drupal + - cp ../dkan/drupal-org-core.make ./ + - drush make --prepare-install drupal-org-core.make --yes + - cp -R ../dkan profiles/ + - cd profiles/dkan + - drush -y make --no-core --contrib-destination=./ drupal-org.make --no-recursion + - cd ../.. + # Create Nucivic Directory and Copy working copy to proper dir + - mkdir sites/all/modules/nucivic + - cp -r $TRAVIS_BUILD_DIR sites/all/modules/nucivic/leaflet_draw_widget + - drush -y make --no-core sites/all/modules/nucivic/leaflet_draw_widget/leaflet_widget.make --no-recursion + # Go back to TRAVIS_BUILD_DIR and move drupal build inside the test folder + - cd $TRAVIS_BUILD_DIR/test + - mv ../../drupal ./ + # Install dkan + - cd drupal + - drush si dkan --sites-subdir=default --db-url=mysql://root:@127.0.0.1:3306/leaflet_draw_widget_test --account-name=admin --account-pass=admin --site-name="DKAN" install_configure_form.update_status_module='array(FALSE,FALSE)' --yes + # Enable module + - drush -y en leaflet_widget + - drush rr all + - drush ev 'node_access_rebuild();' + # Clear cache and run webserver + - drush cc all --yes + - drush --quiet --yes --root=$PWD runserver :8888 > /dev/null 2>&1 & + - sleep 4 + # Setup display for selenium + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - sleep 3 + # Download and run selenium + - cd .. + - wget http://selenium-release.storage.googleapis.com/2.42/selenium-server-standalone-2.42.2.jar + - java -jar selenium-server-standalone-2.42.2.jar -quiet -p 4444 -log shut_up_selenium & + - sleep 5 + +script: + - bin/behat features/leaflet_draw_widget.feature + +notifications: + slack: + rooms: diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..ac83d63 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,4 @@ +bin/ +vendor +composer.lock +.idea diff --git a/test/behat.yml b/test/behat.yml new file mode 100644 index 0000000..f785ff6 --- /dev/null +++ b/test/behat.yml @@ -0,0 +1,49 @@ +# behat.yml + +default: + suites: + default: + contexts: + - FeatureContext + # Load the Drupal Context from DrupalExtension + - Drupal\DrupalExtension\Context\DrupalContext + # Load the generic DKAN context + - Drupal\DKANExtension\Context\DKANContext + # Load DKAN Groups functionality + - Drupal\DKANExtension\Context\GroupContext + # Load DKAN Page functionality + - Drupal\DKANExtension\Context\PageContext + # Load DKAN Page functionality + - Drupal\DKANExtension\Context\DatasetContext + gherkin: + filters: + tags: ~@wip + formatters: + pretty: true + extensions: + Behat\MinkExtension: + base_url: http://127.0.0.1 + selenium2: ~ + goutte: ~ + show_cmd: firefox %s + Drupal\DrupalExtension: + blackbox: ~ + drupal: + drupal_root: %paths.base%/drupal + drush: + alias: @self + api_driver: 'drupal' + # @todo fixup these regions for use on hhs + region_map: + navigation: '.region-navigation' + breadcrumb: '.breadcrumb' + left_sidebar: '.panel-col-first' + search_area: '.panel-col-last' + dropdown_links: '.comment-main .links.inline.dropdown-menu' + comment: '.comment-main' + selectors: + message_selector: '.alert' + error_message_selector: '.alert.alert-error' + success_message_selector: '.alert.alert-success' + + diff --git a/test/composer.json b/test/composer.json new file mode 100644 index 0000000..b96d3a9 --- /dev/null +++ b/test/composer.json @@ -0,0 +1,8 @@ +{ + "require": { + "nucivic/dkanextension": "dev-master" + }, + "config": { + "bin-dir": "bin/" + } +} diff --git a/test/features/bootstrap/FeatureContext.php b/test/features/bootstrap/FeatureContext.php new file mode 100644 index 0000000..ac2ecb2 --- /dev/null +++ b/test/features/bootstrap/FeatureContext.php @@ -0,0 +1,20 @@ +<?php + +use Drupal\DKANExtension\Context\RawDKANContext; + +/** + * Defines application features from the specific context. + */ +class FeatureContext extends RawDKANContext { + + /** + * Initializes context. + * + * Every scenario gets its own context instance. + * You can also pass arbitrary arguments to the + * context constructor through behat.yml. + */ + public function __construct() { + } + +} diff --git a/test/features/leaflet_widget.feature b/test/features/leaflet_widget.feature new file mode 100644 index 0000000..8266682 --- /dev/null +++ b/test/features/leaflet_widget.feature @@ -0,0 +1,21 @@ +Feature: Leaflet Widget Tests. + + Scenario: Authenticated users should be able to use the Leaflet Widget to input GeoJson data. + Given datasets: + | title | description | + | test dataset | this is a test dataset | + + Given I am a user with the "authenticated user" role + When I edit "Test Dataset" + Then I should see "Select a state to add into the map" + When I select "Georgia" from "#geographic_areas" + And I click "edit-submit" + Then I should see "POLYGON ((-83.109191 35.00118" or Then I should see the geojson for "Georgia" + + Scenario: Authenticated users should be able to input GeoJson data manually. + Given I am a user with the "authenticated user" role + When I edit "Test Dataset" + And I click "Add Data Manually" + And I enter "invalid json" in ".geofield_wkt" + And I click "Submit" + Then I should see "Invalid Geojson"