"""Unit testcases for adjustment file validation.""" from decimal import Decimal from unittest.mock import MagicMock, patch import numpy as np from adjustment_file_validation.adjustment_file_validation import ( AdjustmentFileValidation, ) @patch( 'adjustment_file_validation.adjustment_file_validation.validate_with_shared_validation' ) @patch('adjustment_file_validation.adjustment_file_validation.openpyxl') @patch('adjustment_file_validation.adjustment_file_validation.pd') def test_read_and_validate_file( mock_pandas, mock_openpyxl, mock_validation, mock_adjustment ): """Test read_and_validate_file method.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.iterrows = MagicMock( return_value=enumerate([mock_adjustment]) ) mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.empty = False mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.shape = [ 1, 4, ] mock_validation.return_value = {} wb = mock_openpyxl.workbook() wb.return_value.active = 1 mock_openpyxl.load_workbook = MagicMock(return_value=wb) wb.save.return_value = MagicMock() wb.close.return_value = MagicMock() adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) ( total_valid_rows, total_invalid_rows, total_file_amount, rounded_amount, error, error_type, ) = adjustment_file.read_and_validate_file() assert total_valid_rows == 1 assert total_file_amount == Decimal('-50.90') assert total_invalid_rows == 0 assert rounded_amount == Decimal('-50.90') assert error is None assert error_type is None wb.save.assert_not_called() wb.close.assert_called_once() @patch( 'adjustment_file_validation.adjustment_file_validation.validate_with_shared_validation' ) @patch('adjustment_file_validation.adjustment_file_validation.openpyxl') @patch('adjustment_file_validation.adjustment_file_validation.pd') def test_read_and_validate_file_special_characters( mock_pandas, mock_openpyxl, mock_validation, mock_adjustment_special_characters, ): """Test read_and_validate_file method with special characters.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.iterrows = MagicMock( return_value=enumerate([mock_adjustment_special_characters]) ) mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.empty = False mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.shape = [ 1, 4, ] mock_validation.return_value = {} wb = mock_openpyxl.workbook() wb.return_value.active = 1 mock_openpyxl.load_workbook = MagicMock(return_value=wb) wb.save.return_value = MagicMock() wb.close.return_value = MagicMock() adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) ( total_valid_rows, total_invalid_rows, total_file_amount, rounded_amount, error, error_type, ) = adjustment_file.read_and_validate_file() assert total_valid_rows == 1 assert total_file_amount == Decimal('-50.90') assert total_invalid_rows == 0 assert rounded_amount == Decimal('-50.90') assert error is None assert error_type is None wb.save.assert_not_called() wb.close.assert_called_once() @patch('adjustment_file_validation.adjustment_file_validation.config') @patch('adjustment_file_validation.adjustment_file_validation.upload_file') @patch( 'adjustment_file_validation.adjustment_file_validation.validate_with_shared_validation' ) @patch('adjustment_file_validation.adjustment_file_validation.openpyxl') @patch('adjustment_file_validation.adjustment_file_validation.pd') def test_read_and_validate_file_validation_errors( mock_pandas, mock_openpyxl, mock_validation, mock_upload_file, mock_config, mock_adjustment, ): """Test read_and_validate_file method when file has validation errors.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_pandas.read_excel.return_value.iterrows = MagicMock( return_value=enumerate([mock_adjustment]) ) mock_config.FILE_BATCH_SIZE = 5 mock_config.S3_BUCKET_NAME = 'test_adjustment_bucket' mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.iterrows = MagicMock( return_value=enumerate([mock_adjustment]) ) mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.empty = False mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.shape = [ 1, 4, ] mock_validation.return_value = {2: ["Account Id doesn't exist in abacus"]} mock_upload_file.return_value = True wb = mock_openpyxl.workbook() wb.return_value.active = 1 mock_openpyxl.load_workbook = MagicMock(return_value=wb) wb.save.return_value = MagicMock() wb.close.return_value = MagicMock() adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) ( total_valid_rows, total_invalid_rows, total_file_amount, rounded_amount, error, error_type, ) = adjustment_file.read_and_validate_file() assert total_valid_rows == 0 assert total_file_amount == Decimal('-50.90') assert total_invalid_rows == 1 assert rounded_amount == Decimal('-50.90') assert error == 'Validation errors has been added to the file.' assert error_type == 'Validation Error' wb.save.assert_called_once() wb.close.assert_called_once() mock_upload_file.assert_called_once() @patch('adjustment_file_validation.adjustment_file_validation.config') @patch('adjustment_file_validation.adjustment_file_validation.openpyxl') @patch('adjustment_file_validation.adjustment_file_validation.pd') def test_read_and_validate_file_empty_file( mock_pandas, mock_openpyxl, mock_config, ): """Test read_and_validate_file method when adjustment file is empty.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_config.FILE_BATCH_SIZE = 5 mock_config.S3_BUCKET_NAME = 'test_adjustment_bucket' mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.empty = True mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.shape = [] wb = mock_openpyxl.workbook() wb.return_value.active = 1 mock_openpyxl.load_workbook = MagicMock(return_value=wb) wb.save.return_value = MagicMock() wb.close.return_value = MagicMock() adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) ( total_valid_rows, total_invalid_rows, total_file_amount, rounded_amount, error, error_type, ) = adjustment_file.read_and_validate_file() assert total_valid_rows is None assert total_file_amount is None assert total_invalid_rows is None assert rounded_amount is None assert error == 'No adjustments records found in excel sheet' assert error_type == 'Empty File' wb.save.assert_not_called() wb.close.assert_not_called() @patch('adjustment_file_validation.adjustment_file_validation.openpyxl') @patch('adjustment_file_validation.adjustment_file_validation.pd') def test_read_and_validate_file_format_error(mock_pandas, mock_openpyxl): """Test read_and_validate_file method when there is a format error.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.empty = False mock_pandas.read_excel.return_value.astype.return_value.replace.return_value.dropna.return_value.astype.return_value.where.return_value.apply.return_value.shape = [ 1, 4, ] wb = mock_openpyxl.workbook() wb.return_value.active = 1 mock_openpyxl.load_workbook = MagicMock(return_value=wb) wb.save.return_value = MagicMock() wb.close.return_value = MagicMock() mock_openpyxl.load_workbook.side_effect = Exception( 'Error while adding error column to excel sheet' ) adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) ( total_valid_rows, total_invalid_rows, total_file_amount, rounded_amount, error, error_type, ) = adjustment_file.read_and_validate_file() assert total_valid_rows is None assert total_file_amount is None assert total_invalid_rows is None assert rounded_amount is None assert error == 'Error while adding error column to excel sheet' assert error_type == 'Format Error' wb.save.assert_not_called() wb.close.assert_not_called() @patch( 'adjustment_file_validation.adjustment_file_validation.validate_with_shared_validation' ) def test_validate_adjustment(mock_validation, mock_adjustment): """Test _validate_adjustment method.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 mock_validation.return_value = {} adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) adjustment_file._AdjustmentFileValidation__excel_data = {0: mock_adjustment} result = adjustment_file._validate_adjustment() assert not result mock_validation.assert_called_once() def test__is_valid_amount(): """Test _is_valid_amount method.""" temp_file = '/tmp/tmpez56kjmd.xlsx' statement_adjustment_file_id = 288 statement_period_id = 320 adjustment_file = AdjustmentFileValidation( temp_file, statement_adjustment_file_id, statement_period_id, ) result = adjustment_file._is_valid_amount('90.12') assert result is True result = adjustment_file._is_valid_amount('Testing') assert result is False result = adjustment_file._is_valid_amount(None) assert result is False result = adjustment_file._is_valid_amount('') assert result is False result = adjustment_file._is_valid_amount('12#3$4@1289') assert result is False result = adjustment_file._is_valid_amount(str(np.nan)) assert result is False result = adjustment_file._is_valid_amount('#N/A') assert result is False