diff --git a/ecs/crm-datafetch/.vscode/recommend_settings.json b/ecs/crm-datafetch/.vscode/recommend_settings.json index 66a8f2b5..d4822731 100644 --- a/ecs/crm-datafetch/.vscode/recommend_settings.json +++ b/ecs/crm-datafetch/.vscode/recommend_settings.json @@ -12,5 +12,8 @@ "python.linting.flake8Enabled": true, "python.linting.flake8Args": ["--max-line-length=150", "--ignore=F541"], "python.formatting.provider": "autopep8", - "python.formatting.autopep8Args": ["--max-line-length", "150"] + "python.formatting.autopep8Args": ["--max-line-length", "150"], + "python.testing.pytestArgs": ["tests"], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true } diff --git a/ecs/crm-datafetch/tests/test_convert_crm_csv_data_process.py b/ecs/crm-datafetch/tests/test_convert_crm_csv_data_process.py new file mode 100644 index 00000000..49d960c0 --- /dev/null +++ b/ecs/crm-datafetch/tests/test_convert_crm_csv_data_process.py @@ -0,0 +1,169 @@ +import textwrap +from collections import OrderedDict +from unittest.mock import patch + +import pytest +from src.config.objects import TargetObject +from src.convert_crm_csv_data_process import convert_crm_csv_data_process +from src.error.exceptions import DataConvertException +from src.system_var.constants import CONV_JP_NAME +from src.util.execute_datetime import ExecuteDateTime + +from .test_utils.log_message import generate_log_message_tuple + + +class TestConvertCrmCsvDataProcess: + + def test_run_process_success(self, caplog): + """ + Cases: + CSV変換処理が正常終了し、期待通りの結果が返ること + Arranges: + - チェック対象のdictオブジェクトを宣言する + Expects: + - CSV変換処理の結果文字列が返却されること + - CSV変換処理の仕様に沿った正常系ログが出力されること(デバッグログは除く) + """ + # Arrange + response_json = [ + OrderedDict([ + ('attributes', OrderedDict([('type', 'Account'), + ('url', '/services/data/v1.0/sobjects/Account/TEST001')])), + ('Id', 'TEST001'), + ('AccountNumber', 'test001'), + ('LastModifiedDate', '2022-06-01T00:00:00.000+0000'), + ('LastModifiedById', 1.234567E+6), + ('SystemModstamp', '2022-06-01T00:00:00.000+0000'), + ('IsDeleted', True) + ]), + OrderedDict([ + ('attributes', OrderedDict([('type', 'Account'), + ('url', '/services/data/v1.0/sobjects/Account/TEST002')])), + ('Id', 'TEST002'), + ('AccountNumber', 'test002'), + ('LastModifiedDate', '2022-06-01T00:00:00.000+0000'), + ('LastModifiedById', 1.234567E+6), + ('SystemModstamp', '2022-06-01T00:00:00.000+0000'), + ('IsDeleted', False) + ]), + OrderedDict([ + ('attributes', OrderedDict([('type', 'Account'), + ('url', '/services/data/v1.0/sobjects/Account/TEST003')])), + ('Id', 'TEST003'), + ('AccountNumber', 'test003'), + ('LastModifiedDate', '2022-06-01T00:00:00.000+0000'), + ('LastModifiedById', 1.234567E+6), + ('SystemModstamp', '2022-06-01T00:00:00.000+0000'), + ('IsDeleted', False) + ]), + ] + + target_object_dict = { + 'object_name': 'Account', + 'columns': [ + 'Id', + 'AccountNumber', + 'LastModifiedDate', + 'LastModifiedById', + 'SystemModstamp', + 'IsDeleted' + ] + } + + execute_datetime = ExecuteDateTime() + target_object = TargetObject(target_object_dict, execute_datetime) + + # Act + actual_csv_string = convert_crm_csv_data_process(target_object, response_json) + + # Assert + + expect_csv_string = """\ + "Id","AccountNumber","LastModifiedDate","LastModifiedById","SystemModstamp","IsDeleted"\r\n\ + "TEST001","test001","2022-06-01 09:00:00","1234567","2022-06-01 09:00:00","1"\r\n\ + "TEST002","test002","2022-06-01 09:00:00","1234567","2022-06-01 09:00:00","0"\r\n\ + "TEST003","test003","2022-06-01 09:00:00","1234567","2022-06-01 09:00:00","0"\r\n\ + """ + # 返り値の期待値チェック + assert isinstance(actual_csv_string, str), 'CSV文字列が返却される' + assert actual_csv_string == textwrap.dedent(expect_csv_string) + + # ログの確認 + assert generate_log_message_tuple(log_message='I-CONV-01 [Account] のCSV変換処理を開始します') in caplog.record_tuples + assert generate_log_message_tuple(log_message='I-CONV-03 [Account] のCSV変換処理を終了します') in caplog.record_tuples + + def test_call_depended_modules(self): + """ + Cases: + CSV変換処理内で依存しているモジュールが正しく呼ばれていること + Arranges: + - CSV変換処理の依存モジュールをモック化する + Expects: + - 依存しているモジュールが正しく呼ばれている + """ + + # Arrange + target_object_dict = { + 'object_name': 'Account', + 'columns': [ + 'Id', + 'AccountNumber', + 'LastModifiedDate', + 'LastModifiedById', + 'SystemModstamp', + 'IsDeleted' + ] + } + + execute_datetime = ExecuteDateTime() + target_object = TargetObject(target_object_dict, execute_datetime) + # Act + with patch('src.convert_crm_csv_data_process.CSVStringConverter') as mock_converter: + inst = mock_converter.return_value + inst.convert.return_value = '' + convert_crm_csv_data_process(target_object, {}) + + # Assert + assert mock_converter.called is True + assert inst.convert.called is True + + def test_raise_convert(self): + """ + Cases: + CSV変換処理でエラーが発生した場合、検査例外が発生すること + Arranges: + - CSV変換処理で例外が発生するようにする + Expects: + - 例外が発生する + - 形式チェックが失敗したエラーが返却される + """ + + # Arrange + target_object_dict = { + 'object_name': 'Account', + 'columns': [ + 'Id', + 'AccountNumber', + 'LastModifiedDate', + 'LastModifiedById', + 'SystemModstamp', + 'IsDeleted' + ] + } + + execute_datetime = ExecuteDateTime() + target_object = TargetObject(target_object_dict, execute_datetime) + # Act + with patch('src.convert_crm_csv_data_process.CSVStringConverter') as mock_converter: + inst = mock_converter.return_value + inst.convert.side_effect = Exception('変換エラー') + with pytest.raises(DataConvertException) as e: + convert_crm_csv_data_process(target_object, {}) + + # Assert + assert mock_converter.called is True + assert inst.convert.called is True + + assert e.value.error_id == 'E-CONV-01' + assert e.value.func_name == CONV_JP_NAME + assert e.value.args[0] == f'[Account] CSV変換に失敗しました エラー内容:[変換エラー]'