def test_data_check_xml_file_is_valid_raises_xml_error_if_failed_during_validation(self): # Arrange template = _get_template() data = _create_data(template, user_id='3', title='title', content='<new_tag></new_tag>') # Act # Assert with self.assertRaises(exceptions.XMLError): data_api.check_xml_file_is_valid(data)
def test_data_check_xml_file_is_valid_raises_xml_error_if_failed_during_xml_validation( self): # Arrange data = _create_data(None, user_id='3', title='title', content='') # Act # Assert with self.assertRaises(exceptions.XMLError): data_api.check_xml_file_is_valid(data)
def test_data_check_xml_file_is_valid_raises_xml_error_if_failed_during_xml_validation( self, ): # Arrange user = create_mock_user("3") mock_request = create_mock_request(user=user) data = _create_data(None, user_id="3", title="title", content="") # Act # Assert with self.assertRaises(exceptions.XMLError): data_api.check_xml_file_is_valid(data, request=mock_request)
def test_data_check_xml_file_is_valid_raises_xsd_error_if_failed_during_xsd_validation( self, ): # Arrange user = create_mock_user("3") mock_request = create_mock_request(user=user) template = _get_template() template.content += "<" data = _create_data( template, user_id="3", title="title", content="<new_tag></new_tag>" ) # Act # Assert with self.assertRaises(exceptions.XSDError): data_api.check_xml_file_is_valid(data, request=mock_request)
def upsert_data(data): """Upsert data Args: data: Returns: """ from core_main_app.components.data.api import check_xml_file_is_valid if data.xml_content is None: raise exceptions.ApiError( "Unable to save data: xml_content field is not set.") check_xml_file_is_valid(data) return data.convert_and_save()
def test_data_check_xml_data_valid_return_true_if_validation_success(self): # Arrange template = _get_template() data = _create_data(template, user_id='3', title='title', content='<tag>toto</tag>') # Act result = data_api.check_xml_file_is_valid(data) # Assert self.assertEqual(result, True)
def test_data_check_xml_data_valid_return_true_if_validation_success(self): # Arrange mock_user = create_mock_user("3") mock_request = create_mock_request(user=mock_user) template = _get_template() data = _create_data( template, user_id="3", title="title", content="<tag>toto</tag>" ) # Act result = data_api.check_xml_file_is_valid(data, request=mock_request) # Assert self.assertEqual(result, True)
def async_template_migration_task(templates, xslt_id, target_template_id, user_id, migrate): """Async task which perform a migration / validation of all the data which belong to the given template id list Args: templates: xslt_id: target_template_id: user_id migrate: (boolean) Perform the migration Return: {"valid": <number>, "wrong": <number>} """ # get the data list to check current_data_progress = 0 current_template_progress = -1 total_data = 0 total_template = len(templates) success = [] error = [] try: if target_template_id and total_template > 0: # get the user user = user_api.get_user_by_id(user_id) # get the target template target_template = system_api.get_template_by_id(target_template_id) # get xsl transformation if selected if xslt_id is not None: xslt = xsl_transformation_api.get_by_id(str(xslt_id)) for template_id in templates: # increase the number of processed template current_template_progress += 1 # rest de number of data current_data_progress = 0 # get a QuerySet of all the data with the given template data_list = data_api.execute_query( {"template": ObjectId(template_id)}, user=user) total_data = data_list.count() # extract the data id from the list data_list_id = data_list.values_list("id") for data_id in data_list_id: # get the data data = data_api.get_by_id(data_id, user) # modify the data temporarily with the new targeted template data.template = target_template if xslt_id is not None: # modify the xml content temporarily with the transformed data content data.xml_content = xsl_transformation_api.xsl_transform( data.xml_content, xslt.name) # check if the data is valid try: # save the new template for the data if the migration is True if migrate: system_api.upsert_data(data) else: data_api.check_xml_file_is_valid(data) success.append(str(data.id)) except Exception as e: error.append(str(data.id)) finally: # increase the current progress and update the task state current_data_progress += 1 async_template_migration_task.update_state( state="PROGRESS", meta={ "template_current": current_template_progress, "template_total": total_template, "data_current": current_data_progress, "data_total": total_data, }, ) return {"valid": success, "wrong": error} else: async_template_migration_task.update_state( state="ABORT", meta={ "template_current": current_template_progress, "template_total": total_template, "data_current": current_data_progress, "data_total": total_data, }, ) raise Exception("Wrong template id." if not target_template_id else "Please provide template id.") except Exception as e: async_template_migration_task.update_state( state="ABORT", meta={ "template_current": current_template_progress, "template_total": total_data, "data_current": current_data_progress, "data_total": total_data, }, ) raise Exception(f"Something went wrong: {str(e)}")
def async_migration_task(data_list, xslt_id, template_id, user_id, migrate): """Async task which perform a migration / validation of the data list for the given target template id Args: data_list: xslt_id: template_id: user_id: migrate: (boolean) Perform the migration Return: {"valid": ["id"...], "wrong": ["id"...]} """ success = [] errors = [] current_progress = 0 total_data = len(data_list) try: user = user_api.get_user_by_id(user_id) target_template = system_api.get_template_by_id(template_id) # get xsl transformation if selected if xslt_id is not None: xslt = xsl_transformation_api.get_by_id(str(xslt_id)) for data_id in data_list: data = data_api.get_by_id(data_id, user=user) # modify the data temporarily with the new targeted template data.template = target_template if xslt_id is not None: # modify the xml content temporarily with the transformed data content data.xml_content = xsl_transformation_api.xsl_transform( data.xml_content, xslt.name) try: # save the new template for the data if the migration is True if migrate: system_api.upsert_data(data) else: # check if the data is valid data_api.check_xml_file_is_valid(data) success.append(str(data.id)) except Exception as e: errors.append(str(data.id)) finally: # increase the current progress and update the task state current_progress += 1 async_migration_task.update_state( state="PROGRESS", meta={ "current": current_progress, "total": total_data }, ) except Exception as e: async_migration_task.update_state(state="ABORT", meta={ "current": current_progress, "total": total_data }) raise Exception(f"Something went wrong: {str(e)}") return {"valid": success, "wrong": errors}
def set_data_pid(sender, document, **kwargs): """Set the PID in the XML field specified in the settings. If the PID already exists and is valid, it is not reset. Params: sender: document: kwargs: Returns: """ if not pid_settings_api.get().auto_set_pid: return pid_xpath = get_xpath_from_dot_notation(PID_XPATH) # Retrieve namespaces xml_tree = XSDTree.build_tree(document.xml_content) pid_xpath, namespaces = get_xpath_with_target_namespace( pid_xpath, document.template.content ) try: # Get the PID from the `pid_xpath` value document_pid = get_value_at_xpath(xml_tree, pid_xpath, namespaces) if type(document_pid) == str and document_pid.endswith( "/" ): # Cleanup PID if it ends with a '/' document_pid = document_pid[:-1] except AssertionError: # PID XPath not found in document try: # Try to create the element at the given PID # Import libs that need to wait for apps to be ready from core_main_app.components.data import api as data_api modified_xml_tree = create_tree_from_xpath(pid_xpath, xml_tree, namespaces) set_value_at_xpath( modified_xml_tree, pid_xpath, "http://sample_pid.org", namespaces ) document.xml_content = XSDTree.tostring(modified_xml_tree) data_api.check_xml_file_is_valid(document) # Replace the current by the modified tree (containing mock PID) and # force document PID to be regenerated. xml_tree = modified_xml_tree document_pid = None except Exception as exc: # Cannot create PID at given XPath LOGGER.warning("Cannot create PID at %s: %s" % (pid_xpath, str(exc))) return # Identify provider name for registration and ensure the PID has not been # already defined in another document. provider_manager = ProviderManager() # Retrieve previous PID and remove it from DB. if document.pk is not None: previous_pid = system_api.get_pid_for_data(document.pk) previous_provider_name = provider_manager.find_provider_from_pid(previous_pid) previous_provider = provider_manager.get(previous_provider_name) previous_pid_url = previous_pid.replace( previous_provider.provider_url, previous_provider.local_url ) previous_pid_delete_response = send_delete_request( "%s?format=json" % previous_pid_url ) # Log any error that happen during PID deletion if previous_pid_delete_response.status_code != HTTP_200_OK: LOGGER.warning( "Deletion of PID %s returned %s" % (previous_pid, previous_pid_delete_response.status_code) ) if document_pid is None or document_pid == "": # PID field left blank # Select the default provider if no PID has been chosen. provider_name = list(settings.ID_PROVIDER_SYSTEMS.keys())[0] document_pid = join( provider_manager.get(provider_name).provider_url, settings.ID_PROVIDER_PREFIX_DEFAULT, ) else: # PID specified in document. # Check that the PID is not defined for a document other than the current # document. if system_api.is_pid_defined(document_pid) and ( document.pk is None or not system_api.is_pid_defined_for_document(document_pid, document.pk) ): raise exceptions.ModelError("PID already defined for another document") provider_name = provider_manager.find_provider_from_pid(document_pid) # PID specified but not matching any possible provider URLs for the # generation. if provider_name is None: raise exceptions.ModelError("Invalid PID provided") provider = provider_manager.get(provider_name) registration_url = document_pid.replace(provider.provider_url, provider.local_url) document_pid_response = send_post_request("%s?format=json" % registration_url) if document_pid_response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR: default_error_message = "An error occurred while creating the PID" try: raise exceptions.ModelError( document_pid_response.json().get("message", default_error_message) ) except ValueError: # If the response is not JSON parsable raise exceptions.ModelError(default_error_message) if ( document_pid_response.status_code != status.HTTP_201_CREATED and document_pid_response.status_code != status.HTTP_200_OK and system_api.get_data_by_pid(document_pid).pk != document.pk ): raise exceptions.ModelError("Invalid PID provided") # FIXME assert the value is not changed when saving document_pid = document_pid_response.json()["url"] # Set the document PID into XML data and update `xml_content` set_value_at_xpath(xml_tree, pid_xpath, document_pid, namespaces) document.xml_content = XSDTree.tostring(xml_tree) # Update the whole document with the updated XML content document.convert_to_file() document.convert_to_dict()