def _validate_additional_property(self, property_name, property_value, resource_path, unused_properties): if self.allow_additional_properties: print "DEBUG::Additional property {resource_path}->{property_name}".format( resource_path=resource_path, property_name=property_name) try_suggest_other_property_names(name=property_name, candidates=unused_properties) odata_type = match_dynamic_property(property_name, self) if odata_type is None: try: odata_type = get_odata_type(property_value) except KeyError: if isinstance(property_value, dict): cts_error("Property {path}->{property_name} is of complex type without @odata_type", path=resource_path, property_name=property_name) return ValidationStatus.FAILED else: return ValidationStatus.PASSED mapped_odata_type = self.metadata_container.map_type(odata_type) # assuming all aditional properties are nullable if property_value is None: return ValidationStatus.PASSED if not self.metadata_container.to_be_ignored(odata_type, mapped_odata_type): return self.metadata_container.types[odata_type].validate( property_value, resource_path + '->' + property_name) else: return ValidationStatus.PASSED else: cts_error("Property {resource_path}->{property_name} is present, but not defined in metadata. " \ "Type {type_name} does not allow additional properties", resource_path=resource_path, property_name=property_name, type_name=self.name) try_suggest_other_property_names(name=property_name, candidates=unused_properties) return ValidationStatus.FAILED
def _validate_additional_property(self, property_name, property_value, resource_path, unused_properties): if self.allow_additional_properties: print "DEBUG::Additional property {odata_id}->{property_name}" \ .format(odata_id=resource_path, property_name=property_name) try_suggest_other_property_names(name=property_name, candidates=unused_properties) odata_type = match_dynamic_property(property_name, self) if odata_type is None: try: odata_type = get_odata_type(property_value) except KeyError: if isinstance(property_value, dict): cts_error("Property {odata_id:id}->{key} is of complex type without @odata_type", odata_id=resource_path, key=property_name) return ValidationStatus.FAILED else: return ValidationStatus.PASSED mapped_odata_type = self.metadata_container.map_type(odata_type) if not self.metadata_container.to_be_ignored(odata_type, mapped_odata_type): return self.metadata_container.types[mapped_odata_type].validate( property_value, resource_path + '->' + property_name) else: cts_error("Property {odata_id:id}->{property_name} is present, but not defined in metadata. " "Entity {entity_name} does not allow additional properties", odata_id=resource_path, property_name=property_name, entity_name=self.name) try_suggest_other_property_names(name=property_name, candidates=unused_properties) status = ValidationStatus.FAILED
def _append_additional_properties(self, property_list, body, type_definition, url, path): additionals = set(body.keys()) - set( [property.name for property in property_list]) # filter out special properties (properties that contain @ and #) additionals = filter( lambda property: not is_special_property(property), additionals) if len(additionals) > 0: if type_definition.allow_additional_properties: for property_name in additionals: # process only objects try: property_value = body[property_name] if isinstance(property_value, dict): odata_type = match_dynamic_property( property_name, type_definition) if odata_type is None: try: odata_type = get_odata_type(property_value) except KeyError as key: cts_error( "{url:id}#{path}: @odata.type not found in complex " "additional property", url=url, path=path.append(property_name)) continue adhoc_description = self.ad_hoc_type_definition( property_name, odata_type) property_list.append(adhoc_description) except KeyError: pass else: cts_error( "{url:id}#{path}: Object of type {type}; unexpected properties: [{" "properties}]", type=type_definition.name, properties=", ".join(additionals), url=url, path=path) self._status = ValidationStatus.FAILED