From 3f2fcf54592f228f4979b545748372c46fd2b4f3 Mon Sep 17 00:00:00 2001 From: sujata-m Date: Mon, 7 Oct 2024 15:47:05 +0530 Subject: [PATCH 1/3] Updated package version as part of Ticket 1281 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 48d9270..b5ef454 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ pydantic==1.10.4 html_testRunner==1.2.1 uvicorn==0.20.0 python-ms-core==0.0.22 -tcat-gtfs-csv-validator~=0.0.38 \ No newline at end of file +tcat-gtfs-csv-validator~=0.0.39 \ No newline at end of file From c9f23ccfc5dd9814211005f574fd9b0379e4e23c Mon Sep 17 00:00:00 2001 From: sujata-m Date: Tue, 8 Oct 2024 22:45:11 +0530 Subject: [PATCH 2/3] - Updated package version - Updated unit test cases - Fixed pipeline --- .github/workflows/unit_tests.yaml | 8 +- requirements.txt | 2 +- tests/unit_tests/test_file_upload_msg.py | 13 +- tests/unit_tests/test_gtfx_flex_validator.py | 175 +++++++++++-------- 4 files changed, 119 insertions(+), 79 deletions(-) diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index d315fc2..ccee1df 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -16,10 +16,10 @@ jobs: with: fetch-depth: 0 - - name: Setup Virtual Environment - run: | - python3.10 -m venv .venv - source .venv/bin/activate + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10' - name: Install Dependencies run: | diff --git a/requirements.txt b/requirements.txt index b5ef454..62c8074 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ pydantic==1.10.4 html_testRunner==1.2.1 uvicorn==0.20.0 python-ms-core==0.0.22 -tcat-gtfs-csv-validator~=0.0.39 \ No newline at end of file +tcat-gtfs-csv-validator~=0.0.40 \ No newline at end of file diff --git a/tests/unit_tests/test_file_upload_msg.py b/tests/unit_tests/test_file_upload_msg.py index 562702d..4b66082 100644 --- a/tests/unit_tests/test_file_upload_msg.py +++ b/tests/unit_tests/test_file_upload_msg.py @@ -2,6 +2,7 @@ import json import unittest from src.models.file_upload_msg import FileUploadMsg + # from src.gtfx_flex_validator import GTFSFlexValidator current_dir = os.path.dirname(os.path.abspath(os.path.join(__file__, '../'))) @@ -11,18 +12,22 @@ TEST_FILE = open(TEST_JSON_FILE) TEST_DATA = json.loads(TEST_FILE.read()) + class TestFileUploadMsg(unittest.TestCase): def setUp(self): data = TEST_DATA self.upload = FileUploadMsg.from_dict(data=data) - + def test_message_type(self): - self.assertEqual(self.upload.messageType,"workflow_identifier") + self.assertEqual(self.upload.messageType, "workflow_identifier") + def test_message_id(self): self.upload.messageId = "abc" - self.assertEqual(self.upload.messageId,"abc") + self.assertEqual(self.upload.messageId, "abc") + def test_file_upload_path(self): - self.assertEqual(self.upload.data.file_upload_path,'https://tdeisamplestorage.blob.core.windows.net/gtfsflex/tests/success_1_all_attrs.zip') + self.assertEqual(self.upload.data.file_upload_path, + 'https://tdeisamplestorage.blob.core.windows.net/gtfsflex/tests/success_1_all_attrs.zip') if __name__ == '__main__': diff --git a/tests/unit_tests/test_gtfx_flex_validator.py b/tests/unit_tests/test_gtfx_flex_validator.py index ce29948..0ab1231 100644 --- a/tests/unit_tests/test_gtfx_flex_validator.py +++ b/tests/unit_tests/test_gtfx_flex_validator.py @@ -5,96 +5,131 @@ class TestGTFSFlexValidator(unittest.TestCase): - def setUp(self): - with patch.object(GTFSFlexValidator, '__init__', return_value=None): - self.validator = GTFSFlexValidator() - self.validator._subscription_name = MagicMock() - self.validator.request_topic = MagicMock() - self.validator.response_topic = MagicMock() - self.validator.logger = MagicMock() - self.validator.storage_client = MagicMock() - - @patch.object(GTFSFlexValidator, 'subscribe') - def test_subscribe(self, mock_subscribe): + @patch('src.gtfx_flex_validator.Settings') + @patch('src.gtfx_flex_validator.Core') + def setUp(self, mock_core, mock_settings): + mock_settings.return_value.request_subscription = 'test_subscription' + mock_settings.return_value.request_topic_name = 'test_request_topic' + mock_settings.return_value.response_topic_name = 'test_response_topic' + mock_settings.return_value.max_concurrent_messages = 10 + mock_settings.return_value.get_unique_id.return_value = '123' + mock_settings.return_value.container_name = 'test_container' + + # Mock Core + mock_core.return_value.get_topic.return_value = MagicMock() + mock_core.return_value.get_storage_client.return_value = MagicMock() + + # Initialize GTFSFlexValidator with mocked dependencies + self.validator = GTFSFlexValidator() + self.validator.storage_client = MagicMock() + self.validator.container_name = 'test_container' + self.sample_message = { + 'messageId': '1234', + 'data': { + 'file_upload_path': 'https://tdeisamplestorage.blob.core.windows.net/gtfsflex/tests/success_1_all_attrs.zip', + 'user_id': 'c59d29b6-a063-4249-943f-d320d15ac9ab', + 'tdei_project_group_id': '0b41ebc5-350c-42d3-90af-3af4ad3628fb' + } + } + + @patch('src.gtfx_flex_validator.QueueMessage') + @patch('src.gtfx_flex_validator.FileUploadMsg') + def test_subscribe_with_valid_message(self, mock_request_message, mock_queue_message): + # Arrange + mock_message = MagicMock() + mock_queue_message.to_dict.return_value = self.sample_message + mock_request_message.from_dict.return_value = mock_request_message + self.validator.process_message = MagicMock() + # Act self.validator.subscribe() + callback = self.validator.request_topic.subscribe.call_args[1]['callback'] + callback(mock_message) # Assert - mock_subscribe.assert_called_once() - - @patch.object(GTFSFlexValidator, 'send_status') # Mock the send_status method - def test_valid_send_status(self, mock_send_status): - upload_message_data = MagicMock() - upload_message_data.stage = 'flex-validation' # Set the stage attribute - - # Create a mock meta object - mock_meta = MagicMock() - mock_meta.isValid = True - mock_meta.validationMessage = 'Validation successful' + self.validator.process_message.assert_called_once_with(mock_request_message) - upload_message_data.meta = mock_meta - # Create a mock response object - mock_response = MagicMock() - mock_response.success = True - mock_response.message = 'Validation successful' + @patch('src.gtfx_flex_validator.GTFSFlexValidation') + def test_process_message_with_valid_file_path(self, mock_gtfs_flex_validation): + # Arrange + mock_request_message = MagicMock() + mock_request_message.data.file_upload_path = 'test_dataset_url' + mock_request_message.data.user_id = 'user_id' + mock_request_message.data.tdei_project_group_id = 'tdei_project_group_id' + mock_gtfs_flex_validation_instance = mock_gtfs_flex_validation.return_value + mock_gtfs_flex_validation_instance.validate.return_value = True, 'Validation successful' - upload_message_data.response = mock_response + self.validator.send_status = MagicMock() - # Create a mock upload_message object - upload_message = MagicMock() - upload_message.message = 'Test message' - upload_message.data = upload_message_data + # Act + self.validator.process_message(mock_request_message) - # Call the send_status method - self.validator.send_status(valid=True, upload_message=upload_message) + # Assert - # Add assertions for the expected behavior - self.assertEqual(upload_message_data.stage, 'flex-validation') - self.assertTrue(upload_message_data.meta.isValid) - self.assertEqual(upload_message_data.meta.validationMessage, 'Validation successful') - self.assertTrue(upload_message_data.response.success) - self.assertEqual(upload_message_data.response.message, 'Validation successful') + self.validator.send_status.assert_called_once_with(valid=True, upload_message=mock_request_message, + validation_message='Validation successful') - # Assert that the send_status method was called once with the expected arguments - mock_send_status.assert_called_once_with(valid=True, upload_message=upload_message) + @patch('src.gtfx_flex_validator.GTFSFlexValidation') + def test_process_message_when_file_path_is_none_and_valid_is_false(self, mock_gtfs_flex_validation): + # Arrange + mock_request_message = MagicMock() + mock_request_message.data.file_upload_path = 'test_dataset_url' + mock_request_message.data.user_id = 'user_id' + mock_request_message.data.tdei_project_group_id = 'tdei_project_group_id' + mock_gtfs_flex_validation.return_value.validate.return_value = False, 'Validation error' + self.validator.send_status = MagicMock() - @patch.object(GTFSFlexValidator, 'send_status') # Mock the send_status method - def test_invalid_send_status(self, mock_send_status): - upload_message_data = MagicMock() - upload_message_data.stage = 'flex-validation' # Set the stage attribute + # Act + self.validator.process_message(mock_request_message) - # Create a mock meta object - mock_meta = MagicMock() - mock_meta.isValid = False - mock_meta.validationMessage = 'Validation failed' + self.validator.send_status.assert_called_once_with( + valid=False, + upload_message=mock_request_message, + validation_message='Validation error' + ) - upload_message_data.meta = mock_meta - # Create a mock response object - mock_response = MagicMock() - mock_response.success = False - mock_response.message = 'Validation failed' + @patch('src.gtfx_flex_validator.GTFSFlexValidation') + def test_process_message_when_exception_is_raised(self, mock_gtfs_flex_validation): + # Arrange + mock_request_message = MagicMock() + mock_request_message.data.file_upload_path = 'test_dataset_url' + mock_request_message.data.user_id = 'user_id' + mock_request_message.data.tdei_project_group_id = 'tdei_project_group_id' + self.validator.send_status = MagicMock() - upload_message_data.response = mock_response + # Mock Inclination to raise an exception + mock_gtfs_flex_validation.side_effect = Exception('Some error occurred') - # Create a mock upload_message object - upload_message = MagicMock() - upload_message.message = 'Test message' - upload_message.data = upload_message_data + # Act + self.validator.process_message(mock_request_message) - # Call the send_status method - self.validator.send_status(valid=False, upload_message=upload_message) + # Assert + self.validator.send_status.assert_called_once_with( + valid=False, + upload_message=mock_request_message, + validation_message='Some error occurred' + ) + + @patch('src.gtfx_flex_validator.QueueMessage') + def test_send_status_success(self, mock_queue_message): + # Arrange + mock_request_message = MagicMock() + mock_response_topic = self.validator.core.get_topic.return_value + mock_data = {'messageId': '1234', 'messageType': 'test', 'data': {'success': True}} + mock_queue_message.data_from.return_value = mock_data - # Add assertions for the expected behavior - self.assertEqual(upload_message_data.stage, 'flex-validation') - self.assertFalse(upload_message_data.meta.isValid) - self.assertEqual(upload_message_data.meta.validationMessage, 'Validation failed') - self.assertFalse(upload_message_data.response.success) - self.assertEqual(upload_message_data.response.message, 'Validation failed') + # Act + self.validator.send_status( + valid=True, + upload_message=mock_request_message, + validation_message='Validation successful' + ) - # Assert that the send_status method was called once with the expected arguments - mock_send_status.assert_called_once_with(valid=False, upload_message=upload_message) + # Assert + mock_queue_message.data_from.assert_called_once() + mock_response_topic.publish.assert_called_once_with(data=mock_data) if __name__ == '__main__': From 0f114aea67fbf2efbcf6089c9c19196964ced680 Mon Sep 17 00:00:00 2001 From: sujata-m Date: Tue, 8 Oct 2024 22:46:59 +0530 Subject: [PATCH 3/3] Added test coverage --- .github/workflows/unit_tests.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit_tests.yaml b/.github/workflows/unit_tests.yaml index ccee1df..7ddc324 100644 --- a/.github/workflows/unit_tests.yaml +++ b/.github/workflows/unit_tests.yaml @@ -27,8 +27,14 @@ jobs: pip install -r requirements.txt pip install numpy==1.26.4 - - name: Run Unit Test Cases - run: python test_report.py + - name: Run tests with coverage + run: | + coverage run --source=src -m unittest discover -s tests/unit_tests/ + coverage xml + + - name: Check coverage + run: | + coverage report --fail-under=85 #- name: Run Coverage Report # run: coverage run --source=src -m unittest discover -s tests/unit_tests