Merge pull request #61 feature-NEWDWH2021-644-prepare_data_fetch_process into develop-6crm

This commit is contained in:
下田雅人 2022-08-16 15:29:47 +09:00
commit 028e96202d
2 changed files with 393 additions and 2 deletions

View File

@ -35,6 +35,22 @@ class TestS3Resource:
# Assert
assert actual == 'aaaaaaaaaaaaaaa'
def test_raise_get_object(self, s3_test, s3_client, bucket_name):
"""
Cases:
- オブジェクトのキーが存在しない場合エラーになること
Arranges:
- S3をモック化する
Expects:
- オブジェクト取得時にエラーになること
"""
# Arrange
# Act
sut = S3Resource(bucket_name)
with pytest.raises(Exception):
# Assert
sut.get_object('hogehoge/test.txt')
def test_put_object(self, s3_test, s3_client, bucket_name):
"""
Cases:
@ -52,6 +68,23 @@ class TestS3Resource:
assert actual['Body'].read().decode('utf-8') == 'aaaaaaaaaaaaaaa'
def test_raise_put_object(self, s3_client, bucket_name):
"""
Cases:
- バケットが存在しない場合エラーになること
Arranges:
- S3をモック化する
- バケットを作成しない
Expects:
- オブジェクト登録時にエラーになること
"""
# Arrange
# Act
sut = S3Resource(bucket_name)
with pytest.raises(Exception):
# Assert
sut.put_object('hogehoge/test.txt', 'aaaaaaaaaaaaaaa')
def test_copy(self, s3_test, s3_client, bucket_name):
"""
Cases:
@ -74,7 +107,23 @@ class TestS3Resource:
actual = s3_client.get_object(Bucket=for_copy_bucket, Key='test.txt')
assert actual['Body'].read() == b'aaaaaaaaaaaaaaa'
def test_init_raise_no_provide_bucket_name(self):
def test_raise_copy(self, s3_client, s3_test, bucket_name):
"""
Cases:
- コピー対象のキーが存在しない場合エラーになること
Arranges:
- S3をモック化する
Expects:
- オブジェクト登録時にエラーになること
"""
# Arrange
# Act
sut = S3Resource(bucket_name)
with pytest.raises(Exception):
# Assert
sut.copy(bucket_name, 'hogehoge/test.txt', 'for_copy_bucket', 'test.txt')
def test_raise_init_no_provide_bucket_name(self):
"""
Cases:
- バケット名を指定しない場合例外となること
@ -95,6 +144,7 @@ class TestConfigBucket:
Cases:
- オブジェクト情報ファイルが取得できること
Arranges:
- 環境変数を置き換える
- オブジェクト情報ファイルを配置する
Expects:
- オブジェクト情報ファイルが文字列として取得でき期待値と一致する
@ -109,6 +159,24 @@ class TestConfigBucket:
assert actual == 'aaaaaaaaaaaaaaa'
def test_raise_get_object_info_file(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
- オブジェクト情報ファイルが存在しない場合エラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- オブジェクト情報ファイルが取得できず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.CRM_CONFIG_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.OBJECT_INFO_FOLDER', 'crm')
monkeypatch.setattr('src.aws.s3.OBJECT_INFO_FILENAME', 'objects.json')
sut = ConfigBucket()
with pytest.raises(Exception):
sut.get_object_info_file()
def test_get_last_fetch_datetime_file(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -128,6 +196,23 @@ class TestConfigBucket:
assert actual == 'aaaaaaaaaaaaaaa'
def test_raise_get_last_fetch_datetime_file(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
- オブジェクト最終更新日時ファイルが存在しない場合エラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- オブジェクト最終更新日時ファイルが取得できず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.CRM_CONFIG_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.LAST_FETCH_DATE_FOLDER', 'crm')
sut = ConfigBucket()
with pytest.raises(Exception):
sut.get_last_fetch_datetime_file('Object.json')
def test_put_last_fetch_datetime_file(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -147,6 +232,23 @@ class TestConfigBucket:
actual = s3_client.get_object(Bucket=bucket_name, Key=f'crm/Object.json')
assert actual['Body'].read().decode('utf-8') == 'aaaaaaaaaaaaaaa'
def test_raise_put_last_fetch_datetime_file(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- オブジェクト最終更新日時ファイルをPUTできない場合エラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- オブジェクト最終更新日時ファイルをPUTできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.CRM_CONFIG_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.LAST_FETCH_DATE_FOLDER', 'crm')
sut = ConfigBucket()
with pytest.raises(Exception):
sut.put_last_fetch_datetime_file('Object.json', 'aaaaaaaaaaaaaaa')
def test_config_bucket_str(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -184,6 +286,23 @@ class TestDataBucket:
actual = s3_client.get_object(Bucket=bucket_name, Key=f'crm/target/test.csv')
assert actual['Body'].read().decode('utf-8') == 'test,test,test'
def test_raise_put_csv(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- CSVファイルをPUTできずエラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- CSVファイルをPUTできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.IMPORT_DATA_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.CRM_IMPORT_DATA_FOLDER', 'crm/target')
sut = DataBucket()
with pytest.raises(Exception):
sut.put_csv('test.csv', 'test,test,test')
def test_put_csv_from(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -209,6 +328,23 @@ class TestDataBucket:
assert actual['Body'].read().decode('utf-8') == 'test,test,test'
def test_raise_put_csv_from(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- 他のバケットからCSVファイルをコピーできずエラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- コピーできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.IMPORT_DATA_BUCKET', 'for_copy_bucket')
monkeypatch.setattr('src.aws.s3.CRM_IMPORT_DATA_FOLDER', 'crm/target')
sut = DataBucket()
with pytest.raises(Exception):
sut.put_csv_from(bucket_name, 'hogehoge/test.csv')
def test_data_bucket_str(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -246,6 +382,23 @@ class TestBackupBucket:
actual = s3_client.get_object(Bucket=bucket_name, Key=f'data_import/test.csv')
assert actual['Body'].read().decode('utf-8') == 'test,test,test'
def test_raise_put_csv_from(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- CSVファイルをPUTできずエラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- CSVファイルがPUTできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.IMPORT_DATA_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.CRM_IMPORT_DATA_FOLDER', 'crm/target')
sut = BackupBucket()
with pytest.raises(Exception):
sut.put_csv('test.csv', 'test,test,test')
def test_put_response_json(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
@ -265,10 +418,27 @@ class TestBackupBucket:
actual = s3_client.get_object(Bucket=bucket_name, Key=f'response_json/test.json')
assert actual['Body'].read().decode('utf-8') == '{"test": "test"}'
def test_raise_response_json(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- JSONファイルをPUTできずエラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- JSONファイルをPUTできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.CRM_BACKUP_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.RESPONSE_JSON_BACKUP_FOLDER', 'response_json')
sut = BackupBucket()
with pytest.raises(Exception):
sut.put_response_json('test.json', {"test": "test"})
def test_put_result_json(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:
- JSONファイルをPUTできること
- 結果のJSONファイルをPUTできること
Arranges:
- S3をモック化する
- 環境変数をテスト用の値に置き換える
@ -284,6 +454,23 @@ class TestBackupBucket:
actual = s3_client.get_object(Bucket=bucket_name, Key=f'data_import/result.json')
assert actual['Body'].read().decode('utf-8') == '{"test": "test"}'
def test_raise_result_json(self, s3_client, bucket_name, monkeypatch):
"""
Cases:
- 結果のJSONファイルをPUTできずエラーになること
Arranges:
- s3_testフィクスチャを引数に指定しない
- 環境変数を置き換える
Expects:
- 結果のJSONファイルをPUTできず例外が発生する
"""
monkeypatch.setattr('src.aws.s3.CRM_BACKUP_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.PROCESS_RESULT_FOLDER', 'data_import')
sut = BackupBucket()
with pytest.raises(Exception):
sut.put_result_json('result.json', {"test": "test"})
def test_backup_bucket_str(self, s3_test, s3_client, bucket_name, monkeypatch):
"""
Cases:

View File

@ -0,0 +1,204 @@
import json
from datetime import datetime
from unittest.mock import MagicMock, patch
import pytest
from src.config.objects import FetchTargetObjects
from src.error.exceptions import FileNotFoundException, InvalidConfigException
from src.prepare_data_fetch_process import prepare_data_fetch_process
from src.system_var.constants import PRE_JP_NAME, YYYYMMDDTHHMMSSTZ
from .test_utils.log_message import generate_log_message_tuple
class TestPrepareDataFetchProcess:
@pytest.fixture
def bucket_name(self):
return 'test-config-bucket'
@pytest.fixture
def prepare_bucket(self, s3_client, bucket_name):
s3_client.create_bucket(Bucket=bucket_name)
yield
def test_run_process_success(self, s3_client, prepare_bucket, bucket_name, monkeypatch, caplog):
"""
Cases:
データ取得準備処理が正常終了し期待通りの結果が返ること
Arranges:
- prepare_bucketフィクスチャでCRM_取得オブジェクト情報ファイルを置くためのモックバケットを作る
- 作成したモックバケットを指すように環境変数を設定する
- CRM_取得オブジェクト情報ファイルを置く
Expects:
- CRM取得オブジェクトクラスのインスタンスが返却される
- CRM取得オブジェクトクラスのインスタンスが期待値と一致
- 実行日時クラスのインスタンスが返却される
- 実行日時クラスがテスト実行後の日時よりも小さい
- 処理結果出力用の空のdictが返却される
- データ取得準備処理の仕様に沿った正常系ログが出力されること(デバッグログは除く)
"""
# Arrange
target_objects_dict = {
'objects': [
{
'object_name': 'Account',
'columns': [
'Id',
'Name'
]
},
{
'object_name': 'Contact',
'columns': [
'Id',
'Name'
]
}
]
}
s3_client.put_object(Bucket=bucket_name, Key='crm/object_info/crm_object_list_diff.json', Body=json.dumps(target_objects_dict))
# 環境変数を編集
monkeypatch.setattr('src.aws.s3.CRM_CONFIG_BUCKET', bucket_name)
monkeypatch.setattr('src.aws.s3.OBJECT_INFO_FOLDER', 'crm/object_info')
monkeypatch.setattr('src.aws.s3.OBJECT_INFO_FILENAME', 'crm_object_list_diff.json')
# Act
actual_fetch_target_objects, actual_execute_datetime, actual_process_result = \
prepare_data_fetch_process()
# Assert
# 返り値の期待値チェック
expect_fetch_target_objects = FetchTargetObjects(target_objects_dict)
assert isinstance(actual_fetch_target_objects, FetchTargetObjects), 'CRM取得オブジェクトクラスのインスタンスが返却される'
assert all([a == e for a, e in zip(actual_fetch_target_objects, expect_fetch_target_objects)]), 'CRM取得オブジェクトクラスのインスタンスが期待値と一致'
assert datetime.strptime(str(actual_execute_datetime), YYYYMMDDTHHMMSSTZ) < datetime.now(), '実行日時がアサーション時点の日時よりも小さいこと'
assert actual_process_result == {}, '処理結果出力用の空のdictが返却される'
# ログの確認
assert generate_log_message_tuple(log_message='I-PRE-01 データ取得準備処理を開始します') in caplog.record_tuples
assert generate_log_message_tuple(log_message=f'I-PRE-02 データ取得処理開始日時:{str(actual_execute_datetime)}') in caplog.record_tuples
assert generate_log_message_tuple(log_message='I-PRE-09 データ取得準備処理を終了します') in caplog.record_tuples
def test_call_depended_modules(self):
"""
Cases:
データ取得準備処理内で依存しているモジュールが正しく呼ばれていること
Arranges:
- データ取得準備処理の依存モジュールをモック化する
Expects:
- 依存しているモジュールが正しく呼ばれている
"""
# Arrange
mock_config_bucket = MagicMock(return_value='')
mock_json_parser = MagicMock(return_value={})
mock_fetch_target_objects = MagicMock(return_value=None)
# Act
with patch('src.aws.s3.ConfigBucket.get_object_info_file', mock_config_bucket), \
patch('src.parser.json_parser.JsonParser.parse', mock_json_parser), \
patch('src.config.objects.FetchTargetObjects.__init__', mock_fetch_target_objects):
prepare_data_fetch_process()
# Assert
assert mock_config_bucket.called is True
assert mock_json_parser.called is True
assert mock_fetch_target_objects.called is True
def test_raise_get_object_info(self, bucket_name, monkeypatch, caplog):
"""
Cases:
CRM_取得オブジェクト情報ファイルを取得できない場合エラーが発生すること
Arranges:
- オブジェクト情報ファイル取得処理で例外が発生するようにする
Expects:
- 例外が発生する
- ファイルが読み込めないエラーが返却される
"""
# Arrange
monkeypatch.setattr('src.prepare_data_fetch_process.OBJECT_INFO_FILENAME', 'crm_object_list_diff.json')
mock_config_bucket = MagicMock(side_effect=Exception('ファイル取得エラー'))
mock_json_parser = MagicMock(return_value={})
mock_fetch_target_objects = MagicMock(return_value=None)
# Act
with patch('src.aws.s3.ConfigBucket.get_object_info_file', mock_config_bucket), \
patch('src.parser.json_parser.JsonParser.parse', mock_json_parser), \
patch('src.config.objects.FetchTargetObjects.__init__', mock_fetch_target_objects):
with pytest.raises(FileNotFoundException) as e:
prepare_data_fetch_process()
# Assert
assert mock_config_bucket.called is True
assert mock_json_parser.called is False
assert mock_fetch_target_objects.called is False
assert e.value.error_id == 'E-PRE-01'
assert e.value.func_name == PRE_JP_NAME
assert e.value.args[0] == f'CRM_取得オブジェクト情報ファイルが存在しません ファイル名:[crm_object_list_diff.json] エラー内容:[ファイル取得エラー]'
def test_raise_parse_json_str(self, bucket_name, monkeypatch, caplog):
"""
Cases:
CRM_取得オブジェクト情報ファイルをパースできない場合エラーが発生すること
Arranges:
- オブジェクト情報ファイルパース処理で例外が発生するようにする
Expects:
- 例外が発生する
- パースが失敗した旨エラーメッセージが表示される
"""
# Arrange
mock_config_bucket = MagicMock(return_value='')
mock_json_parser = MagicMock(side_effect=Exception('JSONパースエラー'))
mock_fetch_target_objects = MagicMock(return_value=None)
# Act
with patch('src.aws.s3.ConfigBucket.get_object_info_file', mock_config_bucket), \
patch('src.parser.json_parser.JsonParser.parse', mock_json_parser), \
patch('src.config.objects.FetchTargetObjects.__init__', mock_fetch_target_objects):
with pytest.raises(InvalidConfigException) as e:
prepare_data_fetch_process()
# Assert
assert mock_config_bucket.called is True
assert mock_json_parser.called is True
assert mock_fetch_target_objects.called is False
assert e.value.error_id == 'E-PRE-02'
assert e.value.func_name == PRE_JP_NAME
assert e.value.args[0] == f'CRM_取得オブジェクト情報ファイルのパースに失敗しました エラー内容:[JSONパースエラー]'
def test_raise_check_objects_format(self, bucket_name, monkeypatch, caplog):
"""
Cases:
CRM_取得オブジェクト情報のキーobjectsの形式チェックが不正の場合エラーが発生すること
Arranges:
- CRM_取得オブジェクト情報のキーobjectsの形式チェックで例外が発生するようにする
Expects:
- 例外が発生する
- 形式チェックが失敗した旨エラーメッセージが表示される
"""
# Arrange
monkeypatch.setattr('src.prepare_data_fetch_process.OBJECT_INFO_FILENAME', 'crm_object_list_diff.json')
mock_config_bucket = MagicMock(return_value='')
mock_json_parser = MagicMock(return_value={})
mock_fetch_target_objects = MagicMock(side_effect=Exception('形式チェックエラー'))
# Act
with patch('src.aws.s3.ConfigBucket.get_object_info_file', mock_config_bucket), \
patch('src.parser.json_parser.JsonParser.parse', mock_json_parser), \
patch('src.config.objects.FetchTargetObjects.__init__', mock_fetch_target_objects):
with pytest.raises(InvalidConfigException) as e:
prepare_data_fetch_process()
# Assert
assert mock_config_bucket.called is True
assert mock_json_parser.called is True
assert mock_fetch_target_objects.called is True
assert e.value.error_id == 'E-PRE-03'
assert e.value.func_name == PRE_JP_NAME
assert e.value.args[0] == 'CRM_取得オブジェクト情報ファイルの形式チェックに失敗しました ファイル名:[crm_object_list_diff.json] エラー内容:[形式チェックエラー]'