mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	This work amends the code from f2f6046c0f
where multiple geometry widgets rendered `<script>` elements in the
admin with the same HTML `id`, resulting in invalid HTML and fragile
JavaScript selectors. Refs #25706.
This change uses the widget's textarea ID to generate a unique `id` for
each JSON options `<script>`, ensuring valid and robust markup.
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
		
	
		
			
				
	
	
		
			175 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* global QUnit, MapWidget, ol */
 | |
| 'use strict';
 | |
| 
 | |
| QUnit.module('gis.OLMapWidget');
 | |
| 
 | |
| QUnit.test('MapWidget.featureAdded', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     const widget = new MapWidget(options);
 | |
|     assert.equal(widget.featureCollection.getLength(), 1);
 | |
|     widget.serializeFeatures();
 | |
|     assert.equal(
 | |
|         document.getElementById('id_point').value,
 | |
|         '{"type":"Point","coordinates":[7.8177,47.397]}',
 | |
|         'Point added to vector layer'
 | |
|     );
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.map_srid', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     const widget = new MapWidget(options);
 | |
|     assert.equal(widget.map.getView().getProjection().getCode(), 'EPSG:3857', 'SRID 3857');
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.defaultCenter', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     let widget = new MapWidget(options);
 | |
|     assert.equal(widget.defaultCenter().toString(), '0,0', 'Default center at 0, 0');
 | |
|     options.default_lat = 47.08;
 | |
|     options.default_lon = 6.81;
 | |
|     widget = new MapWidget(options);
 | |
|     assert.equal(
 | |
|         widget.defaultCenter().toString(),
 | |
|         '6.81,47.08',
 | |
|         'Default center at 6.81, 47.08'
 | |
|     );
 | |
|     assert.equal(Math.round(widget.map.getView().getZoom()), 17);
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.interactions', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     const widget = new MapWidget(options);
 | |
|     assert.equal(Object.keys(widget.interactions).length, 2);
 | |
|     assert.equal(widget.interactions.draw.getActive(), false, "Draw is inactive with an existing point");
 | |
|     assert.equal(widget.interactions.modify.getActive(), true, "Modify is active with an existing point");
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.clearFeatures', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     const widget = new MapWidget(options);
 | |
|     const initial_value = document.getElementById('id_point').value;
 | |
|     widget.clearFeatures();
 | |
|     assert.equal(document.getElementById('id_point').value, "");
 | |
|     document.getElementById('id_point').value = initial_value;
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.multipolygon', function(assert) {
 | |
|     const options = {id: 'id_multipolygon', map_id: 'id_multipolygon_map', geom_name: 'MultiPolygon'};
 | |
|     const widget = new MapWidget(options);
 | |
|     assert.ok(widget.options.is_collection);
 | |
|     assert.equal(widget.interactions.draw.getActive(), true, "Draw is active with no existing content");
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.IsCollection', function(assert) {
 | |
|     const options = {id: 'id_point', map_id: 'id_point_map', geom_name: 'Point'};
 | |
|     let widget = new MapWidget(options);
 | |
|     assert.notOk(widget.options.is_collection);
 | |
|     // Empty the default initial Point
 | |
|     document.getElementById('id_point').value = "";
 | |
| 
 | |
|     options.geom_name = 'Polygon';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.notOk(widget.options.is_collection);
 | |
| 
 | |
|     options.geom_name = 'LineString';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.notOk(widget.options.is_collection);
 | |
| 
 | |
|     options.geom_name = 'MultiPoint';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.ok(widget.options.is_collection);
 | |
| 
 | |
|     options.geom_name = 'MultiPolygon';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.ok(widget.options.is_collection);
 | |
| 
 | |
|     options.geom_name = 'MultiLineString';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.ok(widget.options.is_collection);
 | |
| 
 | |
|     options.geom_name = 'GeometryCollection';
 | |
|     widget = new MapWidget(options);
 | |
|     assert.ok(widget.options.is_collection);
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.layerBuilder.osm returns OSM layer', function(assert) {
 | |
|     const layer = MapWidget.layerBuilder.osm();
 | |
|     assert.ok(layer instanceof ol.layer.Tile, 'Layer is Tile');
 | |
|     assert.ok(layer.getSource() instanceof ol.source.OSM, 'Source is OSM');
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget.layerBuilder.nasaWorldview returns XYZ layer', function(assert) {
 | |
|     const layer = MapWidget.layerBuilder.nasaWorldview();
 | |
|     assert.ok(layer instanceof ol.layer.Tile, 'Layer is Tile');
 | |
|     assert.ok(layer.getSource() instanceof ol.source.XYZ, 'Source is XYZ');
 | |
|     assert.ok(layer.getSource().getUrls()[0].includes('earthdata.nasa.gov'), 'URL is NASA-hosted');
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget uses default OSM base layer when none specified', function(assert) {
 | |
|     const widget = new MapWidget({
 | |
|         id: 'id_point',
 | |
|         map_id: 'id_point_map',
 | |
|         geom_name: 'Point'
 | |
|     });
 | |
|     assert.ok(widget.baseLayer.getSource() instanceof ol.source.OSM, 'Default base layer is OSM');
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget uses named base layer from layerBuilder', function(assert) {
 | |
|     const widget = new MapWidget({
 | |
|         id: 'id_point',
 | |
|         map_id: 'id_point_map',
 | |
|         geom_name: 'Point',
 | |
|         base_layer: 'nasaWorldview'
 | |
|     });
 | |
|     assert.ok(widget.baseLayer.getSource() instanceof ol.source.XYZ, 'Uses named base layer from builder');
 | |
| });
 | |
| 
 | |
| QUnit.test('MapWidget uses passed-in base layer object directly', function(assert) {
 | |
|     const customLayer = new ol.layer.Tile({source: new ol.source.OSM()});
 | |
|     const widget = new MapWidget({
 | |
|         id: 'id_point',
 | |
|         map_id: 'id_point_map',
 | |
|         geom_name: 'Point',
 | |
|         base_layer: customLayer
 | |
|     });
 | |
|     assert.strictEqual(widget.baseLayer, customLayer, 'Uses provided layer object');
 | |
| });
 | |
| 
 | |
| QUnit.test('initMapWidgetInSection initializes widgets and skips __prefix__', function(assert) {
 | |
|     const wrapper1 = document.createElement('div');
 | |
|     wrapper1.className = 'dj_map_wrapper';
 | |
|     wrapper1.id = 'id_point_map_wrapper';
 | |
|     wrapper1.innerHTML = `
 | |
|         <textarea id="id_point"></textarea>
 | |
|         <div class="dj_map" id="id_point_map"></div>
 | |
|         <script type="application/json" id="id_point_mapwidget_options">
 | |
|             { "geom_name": "Point" }
 | |
|         </script>
 | |
|     `;
 | |
|     document.body.appendChild(wrapper1);
 | |
| 
 | |
|     const wrapper2 = document.createElement('div');
 | |
|     wrapper2.className = 'dj_map_wrapper';
 | |
|     wrapper2.id = 'form-__prefix__-map_wrapper';
 | |
|     wrapper2.innerHTML = `
 | |
|         <textarea id="id_fake"></textarea>
 | |
|         <div class="dj_map" id="id_fake_map"></div>
 | |
|         <script type="application/json" id="id_fake_mapwidget_options">
 | |
|             { "geom_name": "MultiPoint" }
 | |
|         </script>
 | |
|     `;
 | |
| 
 | |
|     document.body.appendChild(wrapper2);
 | |
| 
 | |
|     const maps = window.initMapWidgetInSection(document);
 | |
| 
 | |
|     assert.equal(maps.length, 1, 'Only one map widget is initialized');
 | |
|     assert.ok(maps[0] instanceof MapWidget, 'Map is instance of MapWidget');
 | |
|     assert.equal(maps[0].options.id, 'id_point', 'Correct widget was initialized');
 | |
|     assert.equal(maps[0].options.map_id, 'id_point_map', 'Map ID is correct');
 | |
| 
 | |
|     // Clean up
 | |
|     wrapper1.remove();
 | |
|     wrapper2.remove();
 | |
| });
 |