diff --git a/gis_metadata/metadata_parser.py b/gis_metadata/metadata_parser.py index 9f32e68..27543a3 100644 --- a/gis_metadata/metadata_parser.py +++ b/gis_metadata/metadata_parser.py @@ -11,9 +11,8 @@ from gis_metadata.utils import DATES, DATE_TYPE, DATE_VALUES from gis_metadata.utils import DATE_TYPE_RANGE, DATE_TYPE_RANGE_BEGIN, DATE_TYPE_RANGE_END from gis_metadata.utils import parse_complex, parse_complex_list, parse_dates, parse_property -from gis_metadata.utils import update_complex, update_complex_list, update_property -from gis_metadata.utils import validate_any, validate_complex_list, validate_properties -from gis_metadata.utils import _complex_definitions, _supported_props, ParserError +from gis_metadata.utils import update_complex, update_complex_list, update_property, validate_any, validate_properties +from gis_metadata.utils import _supported_props, ParserError # Place holders for lazy, one-time FGDC & ISO imports @@ -395,15 +394,6 @@ def validate(self): validate_properties(self._data_map, self._metadata_props) for prop in self._data_map: - try: - validate_any(prop, getattr(self, prop)) - except ParserError: - if prop in _complex_definitions: - raise # Enforce basic validation for established structures - if prop not in self._data_structures: - raise # Enforce validation for simple properties - - # Validate custom data structures according to configured structure - validate_complex_list(prop, getattr(self, prop), self._data_structures[prop]) + validate_any(prop, getattr(self, prop), self._data_structures.get(prop)) return self diff --git a/gis_metadata/tests/tests.py b/gis_metadata/tests/tests.py index 71d594c..80ae18e 100644 --- a/gis_metadata/tests/tests.py +++ b/gis_metadata/tests/tests.py @@ -513,7 +513,6 @@ class MetadataParserTests(MetadataParserTestCase): def test_custom_parser(self): """ Covers support for custom parsers """ - custom_parser = CustomIsoParser(self.iso_metadata) target_values = { 'metadata_contacts': [{ 'name': 'Custom Contact Name', 'email': 'Custom Contact Email', 'phone': 'Custom Contact Phone', @@ -522,6 +521,7 @@ def test_custom_parser(self): 'metadata_language': 'eng' } + custom_parser = CustomIsoParser(self.iso_metadata) for prop in target_values: self.assertEqual(getattr(custom_parser, prop), target_values[prop], 'Custom parser values were not parsed') @@ -537,6 +537,26 @@ def test_custom_parser(self): self.assert_parsers_are_equal(custom_parser, converted_parser) + # Test invalid custom complex structure value + + metadata_contacts = custom_parser.metadata_contacts + custom_parser.metadata_contacts = u'None' + + with self.assertRaises(ParserError): + custom_parser.validate() + + custom_parser.metadata_contacts = metadata_contacts + + # Test invalid custom simple value + + metadata_language = custom_parser.metadata_language + custom_parser.metadata_language = {} + + with self.assertRaises(ParserError): + custom_parser.validate() + + custom_parser.metadata_language = metadata_language + def test_generic_parser(self): """ Covers code that enforces certain behaviors for custom parsers """ diff --git a/gis_metadata/utils.py b/gis_metadata/utils.py index 586cfdf..b30490a 100644 --- a/gis_metadata/utils.py +++ b/gis_metadata/utils.py @@ -513,9 +513,13 @@ def validate_any(prop, value, xpath_map=None): elif prop == PROCESS_STEPS: validate_process_steps(prop, value) + elif prop not in _supported_props and xpath_map is not None: + # Validate custom data structures as complex lists by default + validate_complex_list(prop, value, xpath_map) + else: - for val in wrap_value(value): - validate_type(prop, val, string_types) + for val in wrap_value(value, include_empty=True): + validate_type(prop, val, (string_types, list)) def validate_complex(prop, value, xpath_map=None):