diff --git a/README.md b/README.md index 0425214..b1b1724 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,8 @@ Follow the steps to install the python packages required for both building and r "source_url": "file_upload_path", "formatted_url": "uploaded_url", "success": true/false, - "message": "message" + "message": "message", + "warnings": "" }, "publishedDate": "published date" } @@ -163,7 +164,8 @@ Follow the steps to install the python packages required for both building and r "target": "osm", "formattedUrl": "https://tdeisamplestorage.blob.core.windows.net/osw/2023/11/c552d5d1-0719-4647-b86d-6ae9b25327b7/aff14a0d29ab4acbaef639063462e85b/naresh-som-2.zip", "success": true, - "message": "" + "message": "", + "warnings": "" } } ``` diff --git a/requirements.txt b/requirements.txt index 4c240f2..74e5e24 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ pydantic==1.10.4 python-ms-core==0.0.26 uvicorn==0.20.0 html_testRunner==1.2.1 -osm-osw-reformatter==0.3.6 +osm-osw-reformatter==0.3.7 numpy==1.26.4 -pyproj~=3.6.1 \ No newline at end of file +pyproj~=3.6.1 diff --git a/src/assets/osw-validation-output.json b/src/assets/osw-validation-output.json index 028d498..d4dbcdc 100644 --- a/src/assets/osw-validation-output.json +++ b/src/assets/osw-validation-output.json @@ -7,6 +7,7 @@ "source_url": "https://tdeisamplestorage.blob.core.windows.net/osw/test_upload/osw.zip", "formatted_url": "https://tdeisamplestorage.blob.core.windows.net/osw/test_upload/osw.zip", "success": true, - "message": "" + "message": "", + "warnings": "" } -} \ No newline at end of file +} diff --git a/src/models/osw_ondemand_response.py b/src/models/osw_ondemand_response.py index a28626a..c3743e2 100644 --- a/src/models/osw_ondemand_response.py +++ b/src/models/osw_ondemand_response.py @@ -14,6 +14,7 @@ class ResponseData: formattedUrl: Optional[str] = '' success: bool = False message: str = '' + warnings: str = '' @dataclass diff --git a/src/models/osw_validation_data.py b/src/models/osw_validation_data.py index 94f2e53..036012d 100644 --- a/src/models/osw_validation_data.py +++ b/src/models/osw_validation_data.py @@ -10,6 +10,7 @@ def __init__(self, data: dict): self._formatted_url = data.get('formatted_url', None) self._success = data.get('success', False) self._message = data.get('message', '') + self._warnings = data.get('warnings', '') @property def tdei_project_group_id(self): return self._tdei_project_group_id @@ -41,6 +42,12 @@ def message(self): return self._message @message.setter def message(self, value): self._message = value + @property + def warnings(self): return self._warnings + + @warnings.setter + def warnings(self, value): self._warnings = value or '' + def to_json(self): return to_json(self.__dict__) diff --git a/src/models/queue_message_content.py b/src/models/queue_message_content.py index e6939b1..cce1816 100644 --- a/src/models/queue_message_content.py +++ b/src/models/queue_message_content.py @@ -4,6 +4,12 @@ class ValidationResult: is_valid: bool validation_message: str = '' + warnings: str = '' + + def __init__(self, is_valid: bool = False, validation_message: str = '', warnings: str = ''): + self.is_valid = is_valid + self.validation_message = validation_message + self.warnings = warnings class Request: diff --git a/src/service/osw_formatter_service.py b/src/service/osw_formatter_service.py index b3d555d..8fabf82 100644 --- a/src/service/osw_formatter_service.py +++ b/src/service/osw_formatter_service.py @@ -120,6 +120,7 @@ def format(self, received_message: OSWValidationMessage): ) result = formatter.format() formatter_result = ValidationResult() + formatter_result.warnings = result.warnings if result and result.status and result.error is None and result.generated_files is not None: # Generated files can be .xml or a bunch of geojson converted_file = self._prepare_upload_file( @@ -154,6 +155,7 @@ def format(self, received_message: OSWValidationMessage): result = ValidationResult() result.is_valid = False result.validation_message = f'Error occurred while formatting OSW request {e}' + result.warnings = '' self.send_status(result=result, upload_message=received_message) traceback.print_exc() finally: @@ -183,6 +185,7 @@ def upload_to_azure(self, file_path=None, project_group_id=None, record_id=None) def send_status(self, result: ValidationResult, upload_message: OSWValidationMessage, upload_url=None): upload_message.data.success = result.is_valid upload_message.data.message = result.validation_message + upload_message.data.warnings = result.warnings if upload_url: upload_message.data.formatted_url = upload_url @@ -219,6 +222,7 @@ def process_on_demand_format(self, request: OSWOnDemandRequest): ) result = formatter.format() osw_response = asdict(request.data) + osw_response['warnings'] = result.warnings # Create remote path if result and result.status and result.error is None and result.generated_files is not None: logger.info('Formatting complete') @@ -261,7 +265,8 @@ def process_on_demand_format(self, request: OSWOnDemandRequest): 'status': 'failed', 'message': str(e), 'success': False, - 'jobId': request.data.jobId + 'jobId': request.data.jobId, + 'warnings': '' } ) ) diff --git a/tests/unit_tests/models/test_osw_ondemand_response.py b/tests/unit_tests/models/test_osw_ondemand_response.py index e1fc99b..6ad85ca 100644 --- a/tests/unit_tests/models/test_osw_ondemand_response.py +++ b/tests/unit_tests/models/test_osw_ondemand_response.py @@ -16,7 +16,8 @@ def test_init(self): 'status': 'completed', 'formattedUrl': 'https://example.com/formatted.zip', 'success': True, - 'message': 'Formatting successful' + 'message': 'Formatting successful', + 'warnings': 'warning one' } osw_response = OSWOnDemandResponse(messageType=message_type, messageId=message_id, data=data) @@ -32,6 +33,7 @@ def test_init(self): self.assertEqual(osw_response.data.formattedUrl, data['formattedUrl']) self.assertEqual(osw_response.data.success, data['success']) self.assertEqual(osw_response.data.message, data['message']) + self.assertEqual(osw_response.data.warnings, data['warnings']) def test_post_init(self): # Test post-init behavior @@ -52,6 +54,7 @@ def test_post_init(self): # Ensure data is an instance of ResponseData after __post_init__ self.assertIsInstance(osw_response.data, ResponseData) + self.assertEqual(osw_response.data.warnings, '') def test_invalid_data_type(self): # Test when data is not a dictionary diff --git a/tests/unit_tests/models/test_osw_validation_data.py b/tests/unit_tests/models/test_osw_validation_data.py index 975a610..b4bf1a8 100644 --- a/tests/unit_tests/models/test_osw_validation_data.py +++ b/tests/unit_tests/models/test_osw_validation_data.py @@ -21,12 +21,14 @@ def setUp(self): def test_init(self): data = { 'tdei_project_group_id': 'group_id', - 'file_upload_path': 'some_url' + 'file_upload_path': 'some_url', + 'warnings': 'warning one' } validation_data = OSWValidationData(data) self.assertEqual(validation_data.tdei_project_group_id, 'group_id') self.assertEqual(validation_data.file_upload_path, 'some_url') + self.assertEqual(validation_data.warnings, 'warning one') def test_tdei_project_group_id(self): validation_data = OSWValidationData(self.data) @@ -37,7 +39,8 @@ def test_tdei_project_group_id(self): def test_to_json(self): data = { 'tdei_project_group_id': 'group_id', - 'file_upload_path': 'some_url' + 'file_upload_path': 'some_url', + 'warnings': 'warning one' } validation_data = OSWValidationData(data) @@ -45,9 +48,11 @@ def test_to_json(self): self.assertIn('tdei_project_group_id', json_data) self.assertIn('file_upload_path', json_data) + self.assertIn('warnings', json_data) self.assertEqual(json_data['tdei_project_group_id'], 'group_id') self.assertEqual(json_data['file_upload_path'], 'some_url') + self.assertEqual(json_data['warnings'], 'warning one') def test_remove_underscore(self): underscored_string = '_test_string' diff --git a/tests/unit_tests/models/test_queue_message_content.py b/tests/unit_tests/models/test_queue_message_content.py index c1c57c1..ccadd84 100644 --- a/tests/unit_tests/models/test_queue_message_content.py +++ b/tests/unit_tests/models/test_queue_message_content.py @@ -29,6 +29,18 @@ def test_validation_result_init(self): result.validation_message = 'Validated' self.assertTrue(result.is_valid) self.assertEqual(result.validation_message, 'Validated') + self.assertEqual(result.warnings, '') + + def test_validation_result_keyword_init(self): + result = ValidationResult( + is_valid=True, + validation_message='Validated', + warnings='warning one' + ) + + self.assertTrue(result.is_valid) + self.assertEqual(result.validation_message, 'Validated') + self.assertEqual(result.warnings, 'warning one') class TestRequest(unittest.TestCase): def test_request_init(self): diff --git a/tests/unit_tests/service/test_osw_formatter_service.py b/tests/unit_tests/service/test_osw_formatter_service.py index fa45331..4344c80 100644 --- a/tests/unit_tests/service/test_osw_formatter_service.py +++ b/tests/unit_tests/service/test_osw_formatter_service.py @@ -33,6 +33,7 @@ class FormatFixture: status: bool error: Optional[str] generated_files: str + warnings: str = '' class TestOSWFomatterService(unittest.TestCase): @@ -97,7 +98,12 @@ def test_format_success(self, mock_send_status, mock_download_single_file, mock_ file_path = f'{SAVED_FILE_PATH}/osw.zip' # Mock OSWFormat instance mock_osw_instance = MagicMock() - mock_osw_instance.format.return_value = Mock(status=True, error=None, generated_files='file1.xml') + mock_osw_instance.format.return_value = Mock( + status=True, + error=None, + generated_files='file1.xml', + warnings='warning one', + ) mock_osw_instance.create_zip.return_value = 'file1.zip' mock_osw_format.return_value = mock_osw_instance mock_download_single_file.return_value = f'{DOWNLOAD_PATH}/osw.zip' @@ -116,6 +122,8 @@ def test_format_success(self, mock_send_status, mock_download_single_file, mock_ # Assert mock_send_status.assert_called_once() mock_osw_instance.create_zip.assert_called_once_with(['file1.xml']) + result = mock_send_status.call_args[1]['result'] + self.assertEqual(result.warnings, 'warning one') @patch.object(OSWFomatterService, 'send_status') def test_format_failure(self, mock_send_status): @@ -190,6 +198,7 @@ def test_valid_send_status(self): result = ValidationResult() result.is_valid = True result.validation_message = 'Formatting Successful' + result.warnings = 'warning one' upload_message = OSWValidationMessage(TEST_DATA) # Call the send_status method @@ -198,6 +207,7 @@ def test_valid_send_status(self): # Add assertions for the expected behavior self.assertEqual(upload_message.data.success, True) self.assertEqual(upload_message.data.message, 'Formatting Successful') + self.assertEqual(upload_message.data.warnings, 'warning one') def test_valid_send_status_with_upload_url(self): self.formatter.publishing_topic = MagicMock() @@ -239,7 +249,12 @@ def test_process_on_demand_format_success(self, mock_format): mock_init = OSWFormat(file_path=file_path, storage_client=MagicMock()) mock_init.file_path = file_path mock_init.file_relative_path = file_path.split('/')[-1] - mock_format.return_value = Mock(status=True, error=None, generated_files='file1.xml') + mock_format.return_value = Mock( + status=True, + error=None, + generated_files='file1.xml', + warnings='warning one', + ) self.formatter.upload_to_azure_on_demand = MagicMock() self.formatter.upload_to_azure_on_demand.return_value = 'some_url' @@ -256,6 +271,8 @@ def test_process_on_demand_format_success(self, mock_format): mock_format.assert_called_once() mock_create_zip.assert_called_once_with(['file1.xml']) + response = self.formatter.send_on_demand_response.call_args[1]['response'] + self.assertEqual(response.data.warnings, 'warning one') @patch.object(OSWFormat, 'format') def test_process_on_demand_format_failure(self, mock_format):