# SPDX-License-Identifier: 0BSD import io import json import zipfile import pytest from meshchatx.src.backend.map_geo_validator import ( GeoValidationError, validate_geo_bytes, ) def _kmz_with_kml(kml: bytes) -> bytes: buf = io.BytesIO() with zipfile.ZipFile(buf, "w") as zf: zf.writestr("doc.kml", kml) return buf.getvalue() def test_validate_geojson_ok(): data = json.dumps( { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [1.0, 2.0]}, }, ], }, ).encode() result = validate_geo_bytes( data, max_bytes=1024 * 1024, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert result.format == "geojson" assert result.feature_count == 1 def test_validate_geojson_rejects_html(): with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( b"", max_bytes=1024, max_features=10, max_kmz_uncompressed_bytes=1024, ) assert exc.value.code in ("not_geo_content", "unknown_format", "invalid_geojson") def test_validate_geojson_too_large(): data = b'{"type":"Point","coordinates":[0,0]}' with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( data, hinted_format="geojson", max_bytes=5, max_features=10, max_kmz_uncompressed_bytes=1024, ) assert exc.value.code == "file_too_large" def test_validate_geojson_coords_out_of_range(): data = json.dumps( {"type": "Point", "coordinates": [200.0, 2.0]}, ).encode() with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( data, max_bytes=1024, max_features=10, max_kmz_uncompressed_bytes=1024, ) assert exc.value.code == "coordinates_out_of_range" def test_validate_kml_ok(): kml = b""" x 1,2,0 """ result = validate_geo_bytes( kml, max_bytes=1024 * 1024, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert result.format == "kml" assert result.feature_count == 1 def test_validate_kmz_ok(): kml = b""" 1,2,0 """ data = _kmz_with_kml(kml) result = validate_geo_bytes( data, max_bytes=1024 * 1024, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert result.format == "kmz" def test_validate_kmz_too_large(): kml = b""" 1,2,0 """ data = _kmz_with_kml(kml) with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( data, max_bytes=8, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert exc.value.code == "file_too_large" def test_validate_kmz_missing_kml(): buf = io.BytesIO() with zipfile.ZipFile(buf, "w") as zf: zf.writestr("readme.txt", b"nope") with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( buf.getvalue(), max_bytes=1024 * 1024, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert exc.value.code == "kmz_missing_kml" def test_validate_kmz_path_traversal_entry(): buf = io.BytesIO() with zipfile.ZipFile(buf, "w") as zf: zf.writestr("../evil.kml", b"") with pytest.raises(GeoValidationError) as exc: validate_geo_bytes( buf.getvalue(), max_bytes=1024 * 1024, max_features=100, max_kmz_uncompressed_bytes=1024 * 1024, ) assert exc.value.code == "path_traversal"