1+ import json
2+ import os
3+ import tempfile
4+ import unittest
5+ import zipfile
6+
7+ from src .python_osw_validation import OSWValidation
8+
9+ ASSETS_DIR = os .path .join (os .path .dirname (os .path .dirname (os .path .abspath (__file__ ))), "assets" )
10+ MINIMAL_ZIP = os .path .join (ASSETS_DIR , "minimal.zip" )
11+ UW_ZONES_VALID_ZIP = os .path .join (ASSETS_DIR , "UW.zones.valid.zip" )
12+
13+
14+ class TestSchemaRequirementDuringValidation (unittest .TestCase ):
15+ """Ensure that GeoJSON files without $schema fail validation."""
16+
17+ def _validate_missing_schema (self , source_zip : str , relative_paths ):
18+ with tempfile .TemporaryDirectory () as tmpdir :
19+ extracted_dir = os .path .join (tmpdir , "extracted" )
20+ os .makedirs (extracted_dir , exist_ok = True )
21+
22+ with zipfile .ZipFile (source_zip ) as src_zip :
23+ src_zip .extractall (extracted_dir )
24+
25+ for rel_path in relative_paths :
26+ geojson_path = os .path .join (extracted_dir , rel_path )
27+ with open (geojson_path , encoding = "utf-8" ) as geojson_file :
28+ data = json .load (geojson_file )
29+ data .pop ("$schema" , None )
30+ with open (geojson_path , "w" , encoding = "utf-8" ) as geojson_file :
31+ json .dump (data , geojson_file )
32+
33+ modified_zip = os .path .join (tmpdir , "modified.zip" )
34+ with zipfile .ZipFile (modified_zip , "w" , zipfile .ZIP_DEFLATED ) as dst_zip :
35+ for root , _ , files in os .walk (extracted_dir ):
36+ for filename in files :
37+ file_path = os .path .join (root , filename )
38+ arcname = os .path .relpath (file_path , extracted_dir )
39+ dst_zip .write (file_path , arcname )
40+
41+ validation = OSWValidation (zipfile_path = modified_zip )
42+ return validation .validate (max_errors = 5 )
43+
44+ def _assert_missing_schema_failure (self , result ):
45+ self .assertFalse (result .is_valid )
46+ self .assertIsNotNone (result .errors )
47+ self .assertTrue (
48+ any ("\" $schema\" is a required property" in error for error in result .errors ),
49+ f"Expected missing $schema error, got: { result .errors } " ,
50+ )
51+ self .assertIsNotNone (result .issues )
52+ self .assertTrue (
53+ any (
54+ "\" $schema\" is a required property" in message
55+ for issue in result .issues
56+ for message in (
57+ issue .get ("error_message" )
58+ if isinstance (issue .get ("error_message" ), list )
59+ else [issue .get ("error_message" )]
60+ )
61+ if message
62+ ),
63+ f"Expected missing $schema issue, got: { result .issues } " ,
64+ )
65+
66+ def test_point_geojson_requires_schema (self ):
67+ result = self ._validate_missing_schema (
68+ MINIMAL_ZIP ,
69+ ["minimal/wa.microsoft.graph.nodes.OSW.geojson" ],
70+ )
71+ self ._assert_missing_schema_failure (result )
72+
73+ def test_linestring_geojson_requires_schema (self ):
74+ result = self ._validate_missing_schema (
75+ MINIMAL_ZIP ,
76+ ["minimal/wa.microsoft.graph.edges.OSW.geojson" ],
77+ )
78+ self ._assert_missing_schema_failure (result )
79+
80+ def test_polygon_geojson_requires_schema (self ):
81+ result = self ._validate_missing_schema (
82+ UW_ZONES_VALID_ZIP ,
83+ ["UW.zones.valid/UW.zones.geojson" ],
84+ )
85+ self ._assert_missing_schema_failure (result )
0 commit comments