From dfcd17d78ad496cae232c21a762c8149e76ddf6a Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Fri, 5 Aug 2022 23:29:19 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20objects=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/crm-datafetch/src/config/objects.py | 19 +- ecs/crm-datafetch/src/system_var/constants.py | 2 + ecs/crm-datafetch/src/util/dict_checker.py | 8 + .../tests/config/test_objects.py | 2506 +++++++++++++++++ 4 files changed, 2528 insertions(+), 7 deletions(-) create mode 100644 ecs/crm-datafetch/tests/config/test_objects.py diff --git a/ecs/crm-datafetch/src/config/objects.py b/ecs/crm-datafetch/src/config/objects.py index 41ca753b..2979e0f0 100644 --- a/ecs/crm-datafetch/src/config/objects.py +++ b/ecs/crm-datafetch/src/config/objects.py @@ -9,7 +9,9 @@ from src.system_var.constants import (COLUMNS_KEY, COLUMNS_TYPE, LAST_FETCH_DATETIME_FILE_NAME_KEY, LAST_FETCH_DATETIME_FILE_NAME_TYPE, LAST_FETCH_DATETIME_FROM_KEY, + LAST_FETCH_DATETIME_FROM_TYPE, LAST_FETCH_DATETIME_TO_KEY, + LAST_FETCH_DATETIME_TO_TYPE, OBJECT_NAME_KEY, OBJECT_NAME_TYPE, OBJECTS_KEY, OBJECTS_TYPE, UPLOAD_FILE_NAME_KEY, @@ -22,7 +24,7 @@ class FetchTargetObjects(): def __init__(self, object_info_file_dict) -> None: self.__objects = object_info_file_dict self.__dict_checker = DictChecker(self.__objects) - self.validate() + self.__validate() self.__i = 0 def __iter__(self): @@ -35,7 +37,7 @@ class FetchTargetObjects(): self.__i += 1 return value - def validate(self) -> None: + def __validate(self) -> None: self.__dict_checker.assert_key_exist(OBJECTS_KEY) self.__dict_checker.assert_data_type(OBJECTS_KEY, OBJECTS_TYPE) @@ -58,6 +60,7 @@ class TargetObject(): self.__dict_checker.assert_data_type(OBJECT_NAME_KEY, OBJECT_NAME_TYPE) self.__dict_checker.assert_key_exist(COLUMNS_KEY) self.__dict_checker.assert_data_type(COLUMNS_KEY, COLUMNS_TYPE) + self.__dict_checker.assert_list_empty(COLUMNS_KEY) return @@ -95,7 +98,7 @@ class TargetObject(): def is_update_last_fetch_datetime(self) -> bool: if self.__dict_checker.check_key_exist(IS_UPDATE_LAST_FETCH_DATETIME_KEY): return self.__object_info[IS_UPDATE_LAST_FETCH_DATETIME_KEY] - return False + return True @property def last_fetch_datetime_file_name(self) -> str: @@ -107,7 +110,7 @@ class TargetObject(): def upload_file_name(self) -> str: if self.__dict_checker.check_key_exist(UPLOAD_FILE_NAME_KEY): return self.__object_info[UPLOAD_FILE_NAME_KEY].format(execute_datetime=self.__execute_datetime.format_date()) - return f'{self.__object_info[OBJECT_NAME_KEY]}_{self.__execute_datetime.format_date()}' + return f'CRM_{self.__object_info[OBJECT_NAME_KEY]}_{self.__execute_datetime.format_date()}' @property def datetime_column(self) -> str: @@ -122,9 +125,11 @@ class LastFetchDatetime(): self.__validate() def __validate(self) -> None: - if self.__dict_checker.check_key_exist(LAST_FETCH_DATETIME_FROM_KEY): - self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_FROM_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ) + self.__dict_checker.assert_key_exist(LAST_FETCH_DATETIME_FROM_KEY) + self.__dict_checker.assert_data_type(LAST_FETCH_DATETIME_FROM_KEY, LAST_FETCH_DATETIME_FROM_TYPE) + self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_FROM_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ) if self.__dict_checker.check_key_exist(LAST_FETCH_DATETIME_TO_KEY): + self.__dict_checker.assert_data_type(LAST_FETCH_DATETIME_TO_KEY, LAST_FETCH_DATETIME_TO_TYPE) self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_TO_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ) return @@ -136,4 +141,4 @@ class LastFetchDatetime(): def last_fetch_datetime_to(self) -> str: if self.__dict_checker.check_key_exist(LAST_FETCH_DATETIME_TO_KEY): return self.__last_fetch_datetime_file_dict[LAST_FETCH_DATETIME_TO_KEY] - return self.__execute_datetime + return str(self.__execute_datetime) diff --git a/ecs/crm-datafetch/src/system_var/constants.py b/ecs/crm-datafetch/src/system_var/constants.py index bf65010c..0214e5ac 100644 --- a/ecs/crm-datafetch/src/system_var/constants.py +++ b/ecs/crm-datafetch/src/system_var/constants.py @@ -93,4 +93,6 @@ DATETIME_COLUMN_KEY = 'datetime_column' DATETIME_COLUMN_TYPE = str DATETIME_COLUMN_DEFAULT_VALUE = 'SystemModstamp' LAST_FETCH_DATETIME_TO_KEY = 'last_fetch_datetime_to' +LAST_FETCH_DATETIME_TO_TYPE = str LAST_FETCH_DATETIME_FROM_KEY = 'last_fetch_datetime_from' +LAST_FETCH_DATETIME_FROM_TYPE = str diff --git a/ecs/crm-datafetch/src/util/dict_checker.py b/ecs/crm-datafetch/src/util/dict_checker.py index 39ebf9f0..52c4f1ae 100644 --- a/ecs/crm-datafetch/src/util/dict_checker.py +++ b/ecs/crm-datafetch/src/util/dict_checker.py @@ -9,6 +9,10 @@ class DictChecker: """辞書型バリュー空文字チェック""" return self.__object_dict[check_key] != '' and self.__object_dict[check_key] is not None + def is_list_empty(self, check_key): + """list型データ存在チェック""" + return len(self.__object_dict[check_key]) != 0 + def check_key_exist(self, check_key: str) -> bool: """辞書型キー存在チェック""" return check_key in self.__object_dict and self.is_empty(check_key) @@ -41,3 +45,7 @@ class DictChecker: raise Exception(f'「{check_key}」キーの値の正規表現「{regex_str}」チェックに失敗しました') return + + def assert_list_empty(self, check_key: str): + if not self.is_list_empty(check_key): + raise Exception(f'「{check_key}」キーのリストの値は必須です') diff --git a/ecs/crm-datafetch/tests/config/test_objects.py b/ecs/crm-datafetch/tests/config/test_objects.py new file mode 100644 index 00000000..51c31981 --- /dev/null +++ b/ecs/crm-datafetch/tests/config/test_objects.py @@ -0,0 +1,2506 @@ +import pytest +from src.config.objects import (FetchTargetObjects, LastFetchDatetime, + TargetObject) +from src.parser.json_parse import JsonParser +from src.util.execute_datetime import ExecuteDateTime + + +class TestFetchTargetObjects(): + + def test_constructor(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キーがあるかまた、キーの型が正しいかをチェック + Arranges: + - オブジェクト情報文字列を準備する + - オブジェクト情報を辞書型にパースする + Expects: + - 例外が発生しないこと + """ + + # Arranges + fetch_objects = '''{ + "objects": [ + { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true, + "datetime_column": "LastModifiedDate" + }, + { + "object_name": "Contact", + "columns": [ + "Id", + "IsDeleted", + "MasterRecordId", + "AccountId", + "IsPersonAccount", + "LastName", + "FirstName", + "Salutation", + "Name", + "OtherStreet", + "OtherCity", + "OtherState", + "OtherPostalCode", + "OtherCountry", + "OtherLatitude", + "OtherLongitude", + "OtherGeocodeAccuracy", + "OtherAddress", + "MailingStreet", + "MailingCity", + "MailingState", + "MailingPostalCode", + "MailingCountry", + "MailingLatitude", + "MailingLongitude", + "MailingGeocodeAccuracy", + "MailingAddress", + "Phone", + "Fax", + "MobilePhone", + "HomePhone", + "OtherPhone", + "AssistantPhone", + "ReportsToId", + "Email", + "Title", + "Department", + "AssistantName", + "Birthdate", + "Description", + "OwnerId", + "HasOptedOutOfEmail", + "HasOptedOutOfFax", + "DoNotCall", + "CreatedDate", + "CreatedById", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "LastActivityDate", + "LastCURequestDate", + "LastCUUpdateDate", + "MayEdit", + "IsLocked", + "LastViewedDate", + "LastReferencedDate", + "EmailBouncedReason", + "EmailBouncedDate", + "IsEmailBounced", + "PhotoUrl", + "Jigsaw", + "JigsawContactId", + "IndividualId", + "Mobile_ID_vod__c", + "H1Insights__H1_NPI_Value_for_Testing__c", + "H1Insights__H1_Person_ID__c", + "H1Insights__H1_Request_Status__c", + "H1Insights__H1_URL__c", + "H1Insights__NPI_Number__c", + "H1Insights__NPI_Number_for_H1_Insights__c", + "MSJ_Marketing_Cloud_Integration__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + }, + { + "object_name": "Territory2", + "columns": [ + "Id", + "Name", + "Territory2TypeId", + "Territory2ModelId", + "ParentTerritory2Id", + "Description", + "ForecastUserId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "DeveloperName", + "MSJ_Territory_Type__c", + "MSJ_Level__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + } + ] + }''' + + json_parser = JsonParser(fetch_objects) + fetch_objects_dict = json_parser.parse() + + # Act + FetchTargetObjects(fetch_objects_dict) + + # Expects + None + + def test_constructor_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキーがない場合、例外が発生すること + Arranges: + - オブジェクト情報を辞書型にパースする + Expects: + - 例外が発生し期待値と一致する + """ + + fetch_objects = '''{ + "test_objects": [ + { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true, + "datetime_column": "LastModifiedDate" + }, + { + "object_name": "Contact", + "columns": [ + "Id", + "IsDeleted", + "MasterRecordId", + "AccountId", + "IsPersonAccount", + "LastName", + "FirstName", + "Salutation", + "Name", + "OtherStreet", + "OtherCity", + "OtherState", + "OtherPostalCode", + "OtherCountry", + "OtherLatitude", + "OtherLongitude", + "OtherGeocodeAccuracy", + "OtherAddress", + "MailingStreet", + "MailingCity", + "MailingState", + "MailingPostalCode", + "MailingCountry", + "MailingLatitude", + "MailingLongitude", + "MailingGeocodeAccuracy", + "MailingAddress", + "Phone", + "Fax", + "MobilePhone", + "HomePhone", + "OtherPhone", + "AssistantPhone", + "ReportsToId", + "Email", + "Title", + "Department", + "AssistantName", + "Birthdate", + "Description", + "OwnerId", + "HasOptedOutOfEmail", + "HasOptedOutOfFax", + "DoNotCall", + "CreatedDate", + "CreatedById", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "LastActivityDate", + "LastCURequestDate", + "LastCUUpdateDate", + "MayEdit", + "IsLocked", + "LastViewedDate", + "LastReferencedDate", + "EmailBouncedReason", + "EmailBouncedDate", + "IsEmailBounced", + "PhotoUrl", + "Jigsaw", + "JigsawContactId", + "IndividualId", + "Mobile_ID_vod__c", + "H1Insights__H1_NPI_Value_for_Testing__c", + "H1Insights__H1_Person_ID__c", + "H1Insights__H1_Request_Status__c", + "H1Insights__H1_URL__c", + "H1Insights__NPI_Number__c", + "H1Insights__NPI_Number_for_H1_Insights__c", + "MSJ_Marketing_Cloud_Integration__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + }, + { + "object_name": "Territory2", + "columns": [ + "Id", + "Name", + "Territory2TypeId", + "Territory2ModelId", + "ParentTerritory2Id", + "Description", + "ForecastUserId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "DeveloperName", + "MSJ_Territory_Type__c", + "MSJ_Level__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + } + ] + }''' + + # Arranges + json_parser = JsonParser(fetch_objects) + fetch_objects_dict = json_parser.parse() + + # Act + with pytest.raises(Exception) as e: + FetchTargetObjects(fetch_objects_dict) + + # Expects + assert str(e.value) == '「objects」キーは必須です' + + def test_constructor_no_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキーの値の型が想定と違う場合、例外が発生すること + Arranges: + - オブジェクト情報を辞書型にパースする + Expects: + - 例外が発生し期待値と一致する + """ + + fetch_objects = '''{ + "objects": "test_value" + }''' + + # Arranges + json_parser = JsonParser(fetch_objects) + fetch_objects_dict = json_parser.parse() + + # Act + with pytest.raises(Exception) as e: + FetchTargetObjects(fetch_objects_dict) + + # Expects + assert str(e.value) == '「objects」キーの値は「」でなければなりません' + + +class TestTargetObject(): + + def test_constructor(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、バリデーションチェックを行いチェックが通ることを確認する + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + # object_name + + def test_raise_constructor_object_name_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキー(object_name)がない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「object_name」キーは必須です' + + def test_raise_constructor_object_name_no_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(object_name)の値が空文字の場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「object_name」キーは必須です' + + def test_raise_constructor_object_name_none_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(object_name)の値がNoneの場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": None, + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「object_name」キーは必須です' + + def test_raise_constructor_object_name_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(object_name)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": 1, + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「object_name」キーの値は「」でなければなりません' + + # columns + + def test_raise_constructor_columns_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキー(columns)がない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「columns」キーは必須です' + + def test_raise_constructor_columns_no_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(columns)の値が空文字の場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": "", + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「columns」キーは必須です' + + def test_raise_constructor_columns_none_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(columns)の値がNoneの場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": None, + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「columns」キーは必須です' + + def test_raise_constructor_columns_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(columns)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": False, + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「columns」キーの値は「」でなければなりません' + + def test_raise_constructor_columns_no_value_list(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(columns)の値がリスト型で空の場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「columns」キーのリストの値は必須です' + + # is_skip + + def test_raise_constructor_is_skip_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(is_skip)がない場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_is_skip_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(is_skip)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": "", + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_is_skip_none_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(is_skip)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": None, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_raise_constructor_is_skip_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(is_skip)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": "False", + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「is_skip」キーの値は「」でなければなりません' + + # is_update_last_fetch_datetime + + def test_raise_constructor_is_update_last_fetch_datetime_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(is_update_last_fetch_datetime)がない場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_is_update_last_fetch_datetime_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": "", + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_is_update_last_fetch_datetime_none_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": None, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_raise_constructor_is_update_last_fetch_datetime_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": "False", + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「is_update_last_fetch_datetime」キーの値は「」でなければなりません' + + # last_fetch_datetime_file_name + + def test_raise_constructor_last_fetch_datetime_file_name_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(last_fetch_datetime_file_name)がない場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_last_fetch_datetime_file_name_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_last_fetch_datetime_file_name_none_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": None, + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_raise_constructor_last_fetch_datetime_file_name_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": 1, + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_file_name」キーの値は「」でなければなりません' + + # upload_file_name + + def test_raise_constructor_upload_file_name_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(upload_file_name)がない場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_upload_file_name_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(upload_file_name)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_upload_file_name_none_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(upload_file_name)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": None, + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_raise_constructor_upload_file_name_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(upload_file_name)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": 1, + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「upload_file_name」キーの値は「」でなければなりません' + + # datetime_column + + def test_raise_constructor_datetime_column_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(datetime_column)がない場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_datetime_column_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(datetime_column)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "" + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_constructor_datetime_column_none_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(datetime_column)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": None + } + + execute_datetime = ExecuteDateTime() + + # Act + TargetObject(object_info, execute_datetime) + + # Expects + None + + def test_raise_constructor_datetime_column_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(datetime_column)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": 1 + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + TargetObject(object_info, execute_datetime) + + # Expects + assert str(e.value) == '「datetime_column」キーの値は「」でなければなりません' + + # property + + def test_object_name(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.object_name + + # Expects + assert actual == 'AccountShare' + + def test_columns(self) -> list: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.columns + + # Expects + expected_value = [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ] + assert actual == expected_value + + def test_is_skip(self) -> bool: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.is_skip + + # Expects + assert actual is True + + def test_is_skip_default(self) -> bool: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": "", + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.is_skip + + # Expects + assert actual is False + + def test_is_update_last_fetch_datetime(self) -> bool: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.is_update_last_fetch_datetime + + # Expects + assert actual is False + + def test_is_update_last_fetch_datetime_default(self) -> bool: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": "", + "last_fetch_datetime_file_name": "AccountShare.json", + "upload_file_name": "CRM_AccountShare", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.is_update_last_fetch_datetime + + # Expects + assert actual is True + + def test_last_fetch_datetime_file_name(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare_Test.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_file_name + + # Expects + assert actual == 'AccountShare_Test.json' + + def test_last_fetch_datetime_file_name_default(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "", + "upload_file_name": "CRM_AccountShare", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_file_name + + # Expects + assert actual == 'AccountShare.json' + + def test_upload_file_name(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare_Test.json", + "upload_file_name": "CRM_AccountShare_Test_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.upload_file_name + + # Expects + assert actual == f'CRM_AccountShare_Test_{execute_datetime.format_date()}' + + def test_upload_file_name_default(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare_Test.json", + "upload_file_name": "", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.upload_file_name + + # Expects + assert actual == f'CRM_AccountShare_{execute_datetime.format_date()}' + + def test_datetime_column(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare_Test.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "LastModifiedDate" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.datetime_column + + # Expects + assert actual == 'LastModifiedDate' + + def test_datetime_column_default(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + - オブジェクト情報インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_info = { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": True, + "is_update_last_fetch_datetime": False, + "last_fetch_datetime_file_name": "AccountShare_Test.json", + "upload_file_name": "CRM_AccountShare_{execute_datetime}", + "datetime_column": "" + } + + execute_datetime = ExecuteDateTime() + + sut = TargetObject(object_info, execute_datetime) + + # Act + actual = sut.datetime_column + + # Expects + assert actual == 'SystemModstamp' + + +class TestLastFetchDatetime(): + def test_constructor(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、バリデーションチェックを行いチェックが通ることを確認する + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + None + + def test_raise_constructor_last_fetch_datetime_from_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキー(last_fetch_datetime_from)がない場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_no_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が空文字の場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_none_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値がNoneの場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": None, + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": 1, + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーの値は「」でなければなりません' + + def test_raise_constructor_last_fetch_datetime_from_other_string(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が正規表現と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "aaa", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str( + e.value) == '「last_fetch_datetime_from」キーの値の正規表現「[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z」チェックに失敗しました' + + def test_raise_constructor_last_fetch_datetime_to_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(last_fetch_datetime_to)がない場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + None + + def test_constructor_last_fetch_datetime_to_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + None + + def test_constructor_last_fetch_datetime_to_none__value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": None + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + None + + def test_raise_constructor_last_fetch_datetime_to_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": 1 + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_to」キーの値は「」でなければなりません' + + def test_raise_constructor_last_fetch_datetime_to_other_string(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値が正規表現と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "aaa" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str( + e.value) == '「last_fetch_datetime_to」キーの値の正規表現「[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z」チェックに失敗しました' + + def test_last_fetch_datetime_from(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_from + + # Expects + assert actual == '1900-01-01T00:00:00.000Z' + + def test_last_fetch_datetime_to(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_to + + # Expects + assert actual == '2022-01-01T00:00:00.000Z' + + def test_last_fetch_datetime_to_default(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日次インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_to + + # Expects + assert actual == str(execute_datetime) From 3702a43c9dda36ad446d36881f83756f91116830 Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Fri, 5 Aug 2022 23:58:09 +0900 Subject: [PATCH 2/5] =?UTF-8?q?refactor:=20=E7=99=BB=E9=8C=B2=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=A6=E3=81=97=E3=81=BE=E3=81=A3=E3=81=9F=E4=B8=8D?= =?UTF-8?q?=E8=A6=81=E3=81=AA=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/util/test_counter_object.py | 114 ------------------ 1 file changed, 114 deletions(-) delete mode 100644 ecs/crm-datafetch/tests/util/test_counter_object.py diff --git a/ecs/crm-datafetch/tests/util/test_counter_object.py b/ecs/crm-datafetch/tests/util/test_counter_object.py deleted file mode 100644 index 8bf677a0..00000000 --- a/ecs/crm-datafetch/tests/util/test_counter_object.py +++ /dev/null @@ -1,114 +0,0 @@ -import pytest -from src.util.counter_object import CounterObject - - -class TestCounterObject: - - def test_describe(self) -> int: - """ - Cases: - カウンターオブジェクトにて保持した値を返すこと - Arranges: - なし - Expects: - 問い合わせた値が期待値と一致する - """ - - # Act - sut = CounterObject() - actual = sut.describe() - - # Expects - assert actual == 1 - - def test_raise_describe(self) -> int: - """ - Cases: - カウンターオブジェクトの保持した値を問い合わせる際、引数を渡すと例外が発生すること - Arranges: - なし - Expects: - 問い合わせた値が期待値と一致する - """ - - # Act - with pytest.raises(Exception) as e: - sut = CounterObject() - sut.describe(1) - - # Expects - assert str(e.value) == 'describe() takes 1 positional argument but 2 were given' - - def test_increment(self) -> int: - """ - Cases: - カウンターオブジェクトにて保持した値がインクリメントされていること - Arranges: - なし - Expects: - 戻り値が期待値と一致する - """ - - # Act - sut = CounterObject(5) - sut.increment() - actual = sut.increment() - - # Expects - assert actual == 7 - - def test_raise_increment(self) -> int: - """ - Cases: - 文字列を引数で渡すことで、例外が発生すること - Arranges: - なし - Expects: - 発生した例外が期待値と一致する - """ - - # Act - with pytest.raises(Exception) as e: - sut = CounterObject(5) - sut.increment('aaa') - sut.increment('aaa') - - # Expects - assert str(e.value) == "unsupported operand type(s) for +=: 'int' and 'str'" - - def test_decrement(self) -> int: - """ - Cases: - カウンターオブジェクトにて保持した値がデクリメントされていること - Arranges: - なし - Expects: - 戻り値が期待値と一致する - """ - - # Act - sut = CounterObject(5) - sut.decrement(2) - actual = sut.decrement(2) - - # Expects - assert actual == 1 - - def test_raise_decrement(self) -> int: - """ - Cases: - 文字列を引数で渡すことで、例外が発生すること - Arranges: - なし - Expects: - 発生した例外が期待値と一致する - """ - - # Act - with pytest.raises(Exception) as e: - sut = CounterObject(5) - sut.decrement('aaa') - sut.decrement('aaa') - - # Expects - assert str(e.value) == "unsupported operand type(s) for -=: 'int' and 'str'" From e534090034c971fe2c766c73f92137e6d8621cfb Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Mon, 8 Aug 2022 13:24:03 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E5=8D=98=E4=BD=93=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E6=8C=87=E6=91=98=E3=81=AB?= =?UTF-8?q?=E4=BC=B4=E3=81=86=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ecs/crm-datafetch/src/config/objects.py | 32 +- ecs/crm-datafetch/src/system_var/constants.py | 2 + ecs/crm-datafetch/src/util/dict_checker.py | 12 +- .../test_objects_fetch_target_objects.py | 467 ++++++++++ .../test_objects_last_fetch_datetime.py | 380 ++++++++ ...jects.py => test_objects_target_object.py} | 822 ++---------------- 6 files changed, 926 insertions(+), 789 deletions(-) create mode 100644 ecs/crm-datafetch/tests/config/test_objects_fetch_target_objects.py create mode 100644 ecs/crm-datafetch/tests/config/test_objects_last_fetch_datetime.py rename ecs/crm-datafetch/tests/config/{test_objects.py => test_objects_target_object.py} (66%) diff --git a/ecs/crm-datafetch/src/config/objects.py b/ecs/crm-datafetch/src/config/objects.py index 2979e0f0..70beb2eb 100644 --- a/ecs/crm-datafetch/src/config/objects.py +++ b/ecs/crm-datafetch/src/config/objects.py @@ -1,21 +1,13 @@ -from src.system_var.constants import (COLUMNS_KEY, COLUMNS_TYPE, - DATE_PATTERN_YYYYMMDDTHHMMSSTZ, - DATETIME_COLUMN_DEFAULT_VALUE, - DATETIME_COLUMN_KEY, - DATETIME_COLUMN_TYPE, IS_SKIP_KEY, - IS_SKIP_TYPE, - IS_UPDATE_LAST_FETCH_DATETIME_KEY, - IS_UPDATE_LAST_FETCH_DATETIME_TYPE, - LAST_FETCH_DATETIME_FILE_NAME_KEY, - LAST_FETCH_DATETIME_FILE_NAME_TYPE, - LAST_FETCH_DATETIME_FROM_KEY, - LAST_FETCH_DATETIME_FROM_TYPE, - LAST_FETCH_DATETIME_TO_KEY, - LAST_FETCH_DATETIME_TO_TYPE, - OBJECT_NAME_KEY, OBJECT_NAME_TYPE, - OBJECTS_KEY, OBJECTS_TYPE, - UPLOAD_FILE_NAME_KEY, - UPLOAD_FILE_NAME_TYPE) +from src.system_var.constants import ( + COLUMNS_KEY, COLUMNS_TYPE, DATE_PATTERN_YYYYMMDDTHHMMSSTZ, + DATETIME_COLUMN_DEFAULT_VALUE, DATETIME_COLUMN_KEY, DATETIME_COLUMN_TYPE, + DATE_PATTERN_EXPECTED_YYYYMMDDTHHMMSSTZ, IS_SKIP_KEY, IS_SKIP_TYPE, + IS_UPDATE_LAST_FETCH_DATETIME_KEY, IS_UPDATE_LAST_FETCH_DATETIME_TYPE, + LAST_FETCH_DATETIME_FILE_NAME_KEY, LAST_FETCH_DATETIME_FILE_NAME_TYPE, + LAST_FETCH_DATETIME_FROM_KEY, LAST_FETCH_DATETIME_FROM_TYPE, + LAST_FETCH_DATETIME_TO_KEY, LAST_FETCH_DATETIME_TO_TYPE, OBJECT_NAME_KEY, + OBJECT_NAME_TYPE, OBJECTS_KEY, OBJECTS_TYPE, UPLOAD_FILE_NAME_KEY, + UPLOAD_FILE_NAME_TYPE) from src.util.dict_checker import DictChecker from src.util.execute_datetime import ExecuteDateTime @@ -127,10 +119,10 @@ class LastFetchDatetime(): def __validate(self) -> None: self.__dict_checker.assert_key_exist(LAST_FETCH_DATETIME_FROM_KEY) self.__dict_checker.assert_data_type(LAST_FETCH_DATETIME_FROM_KEY, LAST_FETCH_DATETIME_FROM_TYPE) - self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_FROM_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ) + self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_FROM_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ,DATE_PATTERN_EXPECTED_YYYYMMDDTHHMMSSTZ) if self.__dict_checker.check_key_exist(LAST_FETCH_DATETIME_TO_KEY): self.__dict_checker.assert_data_type(LAST_FETCH_DATETIME_TO_KEY, LAST_FETCH_DATETIME_TO_TYPE) - self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_TO_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ) + self.__dict_checker.assert_match_pattern(LAST_FETCH_DATETIME_TO_KEY, DATE_PATTERN_YYYYMMDDTHHMMSSTZ,DATE_PATTERN_EXPECTED_YYYYMMDDTHHMMSSTZ) return @property diff --git a/ecs/crm-datafetch/src/system_var/constants.py b/ecs/crm-datafetch/src/system_var/constants.py index 0214e5ac..9a8f6cd2 100644 --- a/ecs/crm-datafetch/src/system_var/constants.py +++ b/ecs/crm-datafetch/src/system_var/constants.py @@ -50,8 +50,10 @@ S3_CHAR_CODE = 'utf-8' # 正規表現チェック EXCLUDE_SYMBOL = ['#', '/'] DATE_PATTERN_YYYYMMDDTHHMMSSTZ = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' +DATE_PATTERN_EXPECTED_YYYYMMDDTHHMMSSTZ = 'YYYY-MM-DDTHH:MM:SS.000Z' DATE_PATTERN_YYYYMMDDHHMMSSFFF_UTC = r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.000\+0000' + # logger LOG_FORMAT = '[%(levelname)s]\t%(asctime)s\t%(message)s\n' LOG_DATE_FORMAT = '%Y-%m-%d %H:%M:%S' diff --git a/ecs/crm-datafetch/src/util/dict_checker.py b/ecs/crm-datafetch/src/util/dict_checker.py index 52c4f1ae..87e830e6 100644 --- a/ecs/crm-datafetch/src/util/dict_checker.py +++ b/ecs/crm-datafetch/src/util/dict_checker.py @@ -7,15 +7,15 @@ class DictChecker: def is_empty(self, check_key): """辞書型バリュー空文字チェック""" - return self.__object_dict[check_key] != '' and self.__object_dict[check_key] is not None + return self.__object_dict[check_key] == '' or self.__object_dict[check_key] is None def is_list_empty(self, check_key): """list型データ存在チェック""" - return len(self.__object_dict[check_key]) != 0 + return len(self.__object_dict[check_key]) == 0 def check_key_exist(self, check_key: str) -> bool: """辞書型キー存在チェック""" - return check_key in self.__object_dict and self.is_empty(check_key) + return check_key in self.__object_dict and not self.is_empty(check_key) def check_data_type(self, check_key: str, check_type: type) -> bool: """辞書型バリュー型チェック""" @@ -39,13 +39,13 @@ class DictChecker: return - def assert_match_pattern(self, check_key: str, regex_str: str): + def assert_match_pattern(self, check_key: str, regex_str: str, expected_str: str): """正規表現検査""" if not self.check_match_pattern(regex_str, check_key): - raise Exception(f'「{check_key}」キーの値の正規表現「{regex_str}」チェックに失敗しました') + raise Exception(f'「{check_key}」キーの値の正規表現チェックに失敗しました 「{expected_str}」形式である必要があります') return def assert_list_empty(self, check_key: str): - if not self.is_list_empty(check_key): + if self.is_list_empty(check_key): raise Exception(f'「{check_key}」キーのリストの値は必須です') diff --git a/ecs/crm-datafetch/tests/config/test_objects_fetch_target_objects.py b/ecs/crm-datafetch/tests/config/test_objects_fetch_target_objects.py new file mode 100644 index 00000000..3e7df076 --- /dev/null +++ b/ecs/crm-datafetch/tests/config/test_objects_fetch_target_objects.py @@ -0,0 +1,467 @@ +import pytest +from src.config.objects import FetchTargetObjects +from src.parser.json_parse import JsonParser + + +class TestFetchTargetObjects(): + + def test_constructor(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キーがあるかまた、キーの型が正しいかをチェック + Arranges: + - オブジェクト情報文字列を準備する + - オブジェクト情報を辞書型にパースする + Expects: + - 例外が発生しないこと + """ + + # Arranges + fetch_objects = '''{ + "objects": [ + { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true, + "datetime_column": "LastModifiedDate" + }, + { + "object_name": "Contact", + "columns": [ + "Id", + "IsDeleted", + "MasterRecordId", + "AccountId", + "IsPersonAccount", + "LastName", + "FirstName", + "Salutation", + "Name", + "OtherStreet", + "OtherCity", + "OtherState", + "OtherPostalCode", + "OtherCountry", + "OtherLatitude", + "OtherLongitude", + "OtherGeocodeAccuracy", + "OtherAddress", + "MailingStreet", + "MailingCity", + "MailingState", + "MailingPostalCode", + "MailingCountry", + "MailingLatitude", + "MailingLongitude", + "MailingGeocodeAccuracy", + "MailingAddress", + "Phone", + "Fax", + "MobilePhone", + "HomePhone", + "OtherPhone", + "AssistantPhone", + "ReportsToId", + "Email", + "Title", + "Department", + "AssistantName", + "Birthdate", + "Description", + "OwnerId", + "HasOptedOutOfEmail", + "HasOptedOutOfFax", + "DoNotCall", + "CreatedDate", + "CreatedById", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "LastActivityDate", + "LastCURequestDate", + "LastCUUpdateDate", + "MayEdit", + "IsLocked", + "LastViewedDate", + "LastReferencedDate", + "EmailBouncedReason", + "EmailBouncedDate", + "IsEmailBounced", + "PhotoUrl", + "Jigsaw", + "JigsawContactId", + "IndividualId", + "Mobile_ID_vod__c", + "H1Insights__H1_NPI_Value_for_Testing__c", + "H1Insights__H1_Person_ID__c", + "H1Insights__H1_Request_Status__c", + "H1Insights__H1_URL__c", + "H1Insights__NPI_Number__c", + "H1Insights__NPI_Number_for_H1_Insights__c", + "MSJ_Marketing_Cloud_Integration__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + }, + { + "object_name": "Territory2", + "columns": [ + "Id", + "Name", + "Territory2TypeId", + "Territory2ModelId", + "ParentTerritory2Id", + "Description", + "ForecastUserId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "DeveloperName", + "MSJ_Territory_Type__c", + "MSJ_Level__c" + ], + "is_skip": false, + "is_update_last_fetch_datetime": true + } + ] + }''' + + json_parser = JsonParser(fetch_objects) + fetch_objects_dict = json_parser.parse() + + # Act + FetchTargetObjects(fetch_objects_dict) + + # Expects + pass + + def test_raise_constructor_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキーがない場合、例外が発生すること + Arranges: + - オブジェクト情報文字列を準備する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + fetch_objects_dict = { + "test_objects": [ + { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "datetime_column": "LastModifiedDate" + }, + { + "object_name": "Contact", + "columns": [ + "Id", + "IsDeleted", + "MasterRecordId", + "AccountId", + "IsPersonAccount", + "LastName", + "FirstName", + "Salutation", + "Name", + "OtherStreet", + "OtherCity", + "OtherState", + "OtherPostalCode", + "OtherCountry", + "OtherLatitude", + "OtherLongitude", + "OtherGeocodeAccuracy", + "OtherAddress", + "MailingStreet", + "MailingCity", + "MailingState", + "MailingPostalCode", + "MailingCountry", + "MailingLatitude", + "MailingLongitude", + "MailingGeocodeAccuracy", + "MailingAddress", + "Phone", + "Fax", + "MobilePhone", + "HomePhone", + "OtherPhone", + "AssistantPhone", + "ReportsToId", + "Email", + "Title", + "Department", + "AssistantName", + "Birthdate", + "Description", + "OwnerId", + "HasOptedOutOfEmail", + "HasOptedOutOfFax", + "DoNotCall", + "CreatedDate", + "CreatedById", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "LastActivityDate", + "LastCURequestDate", + "LastCUUpdateDate", + "MayEdit", + "IsLocked", + "LastViewedDate", + "LastReferencedDate", + "EmailBouncedReason", + "EmailBouncedDate", + "IsEmailBounced", + "PhotoUrl", + "Jigsaw", + "JigsawContactId", + "IndividualId", + "Mobile_ID_vod__c", + "H1Insights__H1_NPI_Value_for_Testing__c", + "H1Insights__H1_Person_ID__c", + "H1Insights__H1_Request_Status__c", + "H1Insights__H1_URL__c", + "H1Insights__NPI_Number__c", + "H1Insights__NPI_Number_for_H1_Insights__c", + "MSJ_Marketing_Cloud_Integration__c" + ], + "is_skip": False, + "is_update_last_fetch_datetime": True + }, + { + "object_name": "Territory2", + "columns": [ + "Id", + "Name", + "Territory2TypeId", + "Territory2ModelId", + "ParentTerritory2Id", + "Description", + "ForecastUserId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "DeveloperName", + "MSJ_Territory_Type__c", + "MSJ_Level__c" + ], + "is_skip": False, + "is_update_last_fetch_datetime": True + } + ] + } + + # Act + with pytest.raises(Exception) as e: + FetchTargetObjects(fetch_objects_dict) + + # Expects + assert str(e.value) == '「objects」キーは必須です' + + def test_raise_constructor_no_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキーの値の型が想定と違う場合、例外が発生すること + Arranges: + - オブジェクト情報文字列を準備する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + fetch_objects_dict = { + "objects": "test_value" + } + + # Act + with pytest.raises(Exception) as e: + FetchTargetObjects(fetch_objects_dict) + + # Expects + assert str(e.value) == '「objects」キーの値は「」でなければなりません' + + def test_constructor_iterator(self) -> None: + """ + Cases: + インスタンス生成テスト + 登録されたオブジェクトリストをすべて取り出せること + Arranges: + - オブジェクト情報文字列を準備する + Expects: + - ループが最後まで回ること + """ + + fetch_objects_dict = { + "objects": [ + { + "object_name": "AccountShare", + "columns": [ + "Id", + "AccountId", + "UserOrGroupId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "RowCause", + "LastModifiedDate", + "LastModifiedById", + "IsDeleted" + ], + "is_skip": False, + "is_update_last_fetch_datetime": False, + "datetime_column": "LastModifiedDate" + }, + { + "object_name": "Contact", + "columns": [ + "Id", + "IsDeleted", + "MasterRecordId", + "AccountId", + "IsPersonAccount", + "LastName", + "FirstName", + "Salutation", + "Name", + "OtherStreet", + "OtherCity", + "OtherState", + "OtherPostalCode", + "OtherCountry", + "OtherLatitude", + "OtherLongitude", + "OtherGeocodeAccuracy", + "OtherAddress", + "MailingStreet", + "MailingCity", + "MailingState", + "MailingPostalCode", + "MailingCountry", + "MailingLatitude", + "MailingLongitude", + "MailingGeocodeAccuracy", + "MailingAddress", + "Phone", + "Fax", + "MobilePhone", + "HomePhone", + "OtherPhone", + "AssistantPhone", + "ReportsToId", + "Email", + "Title", + "Department", + "AssistantName", + "Birthdate", + "Description", + "OwnerId", + "HasOptedOutOfEmail", + "HasOptedOutOfFax", + "DoNotCall", + "CreatedDate", + "CreatedById", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "LastActivityDate", + "LastCURequestDate", + "LastCUUpdateDate", + "MayEdit", + "IsLocked", + "LastViewedDate", + "LastReferencedDate", + "EmailBouncedReason", + "EmailBouncedDate", + "IsEmailBounced", + "PhotoUrl", + "Jigsaw", + "JigsawContactId", + "IndividualId", + "Mobile_ID_vod__c", + "H1Insights__H1_NPI_Value_for_Testing__c", + "H1Insights__H1_Person_ID__c", + "H1Insights__H1_Request_Status__c", + "H1Insights__H1_URL__c", + "H1Insights__NPI_Number__c", + "H1Insights__NPI_Number_for_H1_Insights__c", + "MSJ_Marketing_Cloud_Integration__c" + ], + "is_skip": False, + "is_update_last_fetch_datetime": True + }, + { + "object_name": "Territory2", + "columns": [ + "Id", + "Name", + "Territory2TypeId", + "Territory2ModelId", + "ParentTerritory2Id", + "Description", + "ForecastUserId", + "AccountAccessLevel", + "OpportunityAccessLevel", + "CaseAccessLevel", + "ContactAccessLevel", + "LastModifiedDate", + "LastModifiedById", + "SystemModstamp", + "DeveloperName", + "MSJ_Territory_Type__c", + "MSJ_Level__c" + ], + "is_skip": False, + "is_update_last_fetch_datetime": True + } + ] + } + + # Act + sut = FetchTargetObjects(fetch_objects_dict) + for i, item in enumerate(sut, 1): + assert item is not None + + # Expects + assert i == 3 diff --git a/ecs/crm-datafetch/tests/config/test_objects_last_fetch_datetime.py b/ecs/crm-datafetch/tests/config/test_objects_last_fetch_datetime.py new file mode 100644 index 00000000..f3712372 --- /dev/null +++ b/ecs/crm-datafetch/tests/config/test_objects_last_fetch_datetime.py @@ -0,0 +1,380 @@ +import pytest +from src.config.objects import LastFetchDatetime +from src.util.execute_datetime import ExecuteDateTime + + +class TestLastFetchDatetime(): + def test_constructor(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、バリデーションチェックを行いチェックが通ることを確認する + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + pass + + def test_raise_constructor_last_fetch_datetime_from_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、必要なキー(last_fetch_datetime_from)がない場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_no_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が空文字の場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_none_value(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値がNoneの場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": None, + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' + + def test_raise_constructor_last_fetch_datetime_from_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": 1, + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_from」キーの値は「」でなければなりません' + + def test_raise_constructor_last_fetch_datetime_from_other_string(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が正規表現と違う場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "aaa", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str( + e.value) == '「last_fetch_datetime_from」キーの値の正規表現チェックに失敗しました 「YYYY-MM-DDTHH:MM:SS.000Z」形式である必要があります' + + def test_raise_constructor_last_fetch_datetime_to_no_key(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータに対して、キー(last_fetch_datetime_to)がない場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + pass + + def test_constructor_last_fetch_datetime_to_no_value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が空文字の場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "" + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + None + + def test_constructor_last_fetch_datetime_to_none__value(self) -> None: + """ + Cases: + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型がNoneの場合、例外が発生しないこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": None + } + + execute_datetime = ExecuteDateTime() + + # Act + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + pass + + def test_raise_constructor_last_fetch_datetime_to_other_type(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が想定と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": 1 + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str(e.value) == '「last_fetch_datetime_to」キーの値は「」でなければなりません' + + def test_raise_constructor_last_fetch_datetime_to_other_string(self) -> None: + """ + Cases: + インスタンス生成テスト + 辞書型のデータの対象のキー(last_fetch_datetime_to)の値が正規表現と違う場合、例外が発生すること + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + Expects: + - 例外が発生し期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "aaa" + } + + execute_datetime = ExecuteDateTime() + + # Act + with pytest.raises(Exception) as e: + LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Expects + assert str( + e.value) == '「last_fetch_datetime_to」キーの値の正規表現チェックに失敗しました 「YYYY-MM-DDTHH:MM:SS.000Z」形式である必要があります' + + def test_last_fetch_datetime_from(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_from + + # Expects + assert actual == '1900-01-01T00:00:00.000Z' + + def test_last_fetch_datetime_to(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_to + + # Expects + assert actual == '2022-01-01T00:00:00.000Z' + + def test_last_fetch_datetime_to_default(self) -> str: + """ + Cases: + オブジェクト情報から対象の値を返すこと + Arranges: + - 辞書型の前回取得日時データを準備する + - 実行日時インスタンスを生成する + - 前回取得日時インスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + last_fetch_datetime_dict = { + "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", + "last_fetch_datetime_to": "" + } + + execute_datetime = ExecuteDateTime() + + sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) + + # Act + actual = sut.last_fetch_datetime_to + + # Expects + assert actual == str(execute_datetime) diff --git a/ecs/crm-datafetch/tests/config/test_objects.py b/ecs/crm-datafetch/tests/config/test_objects_target_object.py similarity index 66% rename from ecs/crm-datafetch/tests/config/test_objects.py rename to ecs/crm-datafetch/tests/config/test_objects_target_object.py index 51c31981..19b89db7 100644 --- a/ecs/crm-datafetch/tests/config/test_objects.py +++ b/ecs/crm-datafetch/tests/config/test_objects_target_object.py @@ -1,335 +1,8 @@ import pytest -from src.config.objects import (FetchTargetObjects, LastFetchDatetime, - TargetObject) -from src.parser.json_parse import JsonParser +from src.config.objects import TargetObject from src.util.execute_datetime import ExecuteDateTime -class TestFetchTargetObjects(): - - def test_constructor(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータに対して、キーがあるかまた、キーの型が正しいかをチェック - Arranges: - - オブジェクト情報文字列を準備する - - オブジェクト情報を辞書型にパースする - Expects: - - 例外が発生しないこと - """ - - # Arranges - fetch_objects = '''{ - "objects": [ - { - "object_name": "AccountShare", - "columns": [ - "Id", - "AccountId", - "UserOrGroupId", - "AccountAccessLevel", - "OpportunityAccessLevel", - "CaseAccessLevel", - "ContactAccessLevel", - "RowCause", - "LastModifiedDate", - "LastModifiedById", - "IsDeleted" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true, - "datetime_column": "LastModifiedDate" - }, - { - "object_name": "Contact", - "columns": [ - "Id", - "IsDeleted", - "MasterRecordId", - "AccountId", - "IsPersonAccount", - "LastName", - "FirstName", - "Salutation", - "Name", - "OtherStreet", - "OtherCity", - "OtherState", - "OtherPostalCode", - "OtherCountry", - "OtherLatitude", - "OtherLongitude", - "OtherGeocodeAccuracy", - "OtherAddress", - "MailingStreet", - "MailingCity", - "MailingState", - "MailingPostalCode", - "MailingCountry", - "MailingLatitude", - "MailingLongitude", - "MailingGeocodeAccuracy", - "MailingAddress", - "Phone", - "Fax", - "MobilePhone", - "HomePhone", - "OtherPhone", - "AssistantPhone", - "ReportsToId", - "Email", - "Title", - "Department", - "AssistantName", - "Birthdate", - "Description", - "OwnerId", - "HasOptedOutOfEmail", - "HasOptedOutOfFax", - "DoNotCall", - "CreatedDate", - "CreatedById", - "LastModifiedDate", - "LastModifiedById", - "SystemModstamp", - "LastActivityDate", - "LastCURequestDate", - "LastCUUpdateDate", - "MayEdit", - "IsLocked", - "LastViewedDate", - "LastReferencedDate", - "EmailBouncedReason", - "EmailBouncedDate", - "IsEmailBounced", - "PhotoUrl", - "Jigsaw", - "JigsawContactId", - "IndividualId", - "Mobile_ID_vod__c", - "H1Insights__H1_NPI_Value_for_Testing__c", - "H1Insights__H1_Person_ID__c", - "H1Insights__H1_Request_Status__c", - "H1Insights__H1_URL__c", - "H1Insights__NPI_Number__c", - "H1Insights__NPI_Number_for_H1_Insights__c", - "MSJ_Marketing_Cloud_Integration__c" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true - }, - { - "object_name": "Territory2", - "columns": [ - "Id", - "Name", - "Territory2TypeId", - "Territory2ModelId", - "ParentTerritory2Id", - "Description", - "ForecastUserId", - "AccountAccessLevel", - "OpportunityAccessLevel", - "CaseAccessLevel", - "ContactAccessLevel", - "LastModifiedDate", - "LastModifiedById", - "SystemModstamp", - "DeveloperName", - "MSJ_Territory_Type__c", - "MSJ_Level__c" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true - } - ] - }''' - - json_parser = JsonParser(fetch_objects) - fetch_objects_dict = json_parser.parse() - - # Act - FetchTargetObjects(fetch_objects_dict) - - # Expects - None - - def test_constructor_no_key(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータに対して、必要なキーがない場合、例外が発生すること - Arranges: - - オブジェクト情報を辞書型にパースする - Expects: - - 例外が発生し期待値と一致する - """ - - fetch_objects = '''{ - "test_objects": [ - { - "object_name": "AccountShare", - "columns": [ - "Id", - "AccountId", - "UserOrGroupId", - "AccountAccessLevel", - "OpportunityAccessLevel", - "CaseAccessLevel", - "ContactAccessLevel", - "RowCause", - "LastModifiedDate", - "LastModifiedById", - "IsDeleted" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true, - "datetime_column": "LastModifiedDate" - }, - { - "object_name": "Contact", - "columns": [ - "Id", - "IsDeleted", - "MasterRecordId", - "AccountId", - "IsPersonAccount", - "LastName", - "FirstName", - "Salutation", - "Name", - "OtherStreet", - "OtherCity", - "OtherState", - "OtherPostalCode", - "OtherCountry", - "OtherLatitude", - "OtherLongitude", - "OtherGeocodeAccuracy", - "OtherAddress", - "MailingStreet", - "MailingCity", - "MailingState", - "MailingPostalCode", - "MailingCountry", - "MailingLatitude", - "MailingLongitude", - "MailingGeocodeAccuracy", - "MailingAddress", - "Phone", - "Fax", - "MobilePhone", - "HomePhone", - "OtherPhone", - "AssistantPhone", - "ReportsToId", - "Email", - "Title", - "Department", - "AssistantName", - "Birthdate", - "Description", - "OwnerId", - "HasOptedOutOfEmail", - "HasOptedOutOfFax", - "DoNotCall", - "CreatedDate", - "CreatedById", - "LastModifiedDate", - "LastModifiedById", - "SystemModstamp", - "LastActivityDate", - "LastCURequestDate", - "LastCUUpdateDate", - "MayEdit", - "IsLocked", - "LastViewedDate", - "LastReferencedDate", - "EmailBouncedReason", - "EmailBouncedDate", - "IsEmailBounced", - "PhotoUrl", - "Jigsaw", - "JigsawContactId", - "IndividualId", - "Mobile_ID_vod__c", - "H1Insights__H1_NPI_Value_for_Testing__c", - "H1Insights__H1_Person_ID__c", - "H1Insights__H1_Request_Status__c", - "H1Insights__H1_URL__c", - "H1Insights__NPI_Number__c", - "H1Insights__NPI_Number_for_H1_Insights__c", - "MSJ_Marketing_Cloud_Integration__c" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true - }, - { - "object_name": "Territory2", - "columns": [ - "Id", - "Name", - "Territory2TypeId", - "Territory2ModelId", - "ParentTerritory2Id", - "Description", - "ForecastUserId", - "AccountAccessLevel", - "OpportunityAccessLevel", - "CaseAccessLevel", - "ContactAccessLevel", - "LastModifiedDate", - "LastModifiedById", - "SystemModstamp", - "DeveloperName", - "MSJ_Territory_Type__c", - "MSJ_Level__c" - ], - "is_skip": false, - "is_update_last_fetch_datetime": true - } - ] - }''' - - # Arranges - json_parser = JsonParser(fetch_objects) - fetch_objects_dict = json_parser.parse() - - # Act - with pytest.raises(Exception) as e: - FetchTargetObjects(fetch_objects_dict) - - # Expects - assert str(e.value) == '「objects」キーは必須です' - - def test_constructor_no_type(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキーの値の型が想定と違う場合、例外が発生すること - Arranges: - - オブジェクト情報を辞書型にパースする - Expects: - - 例外が発生し期待値と一致する - """ - - fetch_objects = '''{ - "objects": "test_value" - }''' - - # Arranges - json_parser = JsonParser(fetch_objects) - fetch_objects_dict = json_parser.parse() - - # Act - with pytest.raises(Exception) as e: - FetchTargetObjects(fetch_objects_dict) - - # Expects - assert str(e.value) == '「objects」キーの値は「」でなければなりません' - - class TestTargetObject(): def test_constructor(self) -> None: @@ -339,7 +12,7 @@ class TestTargetObject(): 辞書型のデータに対して、バリデーションチェックを行いチェックが通ることを確認する Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -373,7 +46,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass # object_name @@ -384,7 +57,7 @@ class TestTargetObject(): 辞書型のデータに対して、必要なキー(object_name)がない場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -427,7 +100,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(object_name)の値が空文字の場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -471,7 +144,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(object_name)の値がNoneの場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -515,7 +188,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(object_name)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -561,7 +234,7 @@ class TestTargetObject(): 辞書型のデータに対して、必要なキー(columns)がない場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -592,7 +265,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(columns)の値が空文字の場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -624,7 +297,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(columns)の値がNoneの場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -656,7 +329,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(columns)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -688,7 +361,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(columns)の値がリスト型で空の場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -722,7 +395,7 @@ class TestTargetObject(): 辞書型のデータに対して、キー(is_skip)がない場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -755,7 +428,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_is_skip_no_value(self) -> None: """ @@ -763,7 +436,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_skip)の値の型が空文字の場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -797,7 +470,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_is_skip_none_value(self) -> None: """ @@ -805,7 +478,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_skip)の値の型がNoneの場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -839,7 +512,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_raise_constructor_is_skip_other_type(self) -> None: """ @@ -848,7 +521,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_skip)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -894,7 +567,7 @@ class TestTargetObject(): 辞書型のデータに対して、キー(is_update_last_fetch_datetime)がない場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -927,7 +600,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_is_update_last_fetch_datetime_no_value(self) -> None: """ @@ -935,7 +608,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型が空文字の場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -969,7 +642,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_is_update_last_fetch_datetime_none_value(self) -> None: """ @@ -977,7 +650,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型がNoneの場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1011,7 +684,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_raise_constructor_is_update_last_fetch_datetime_other_type(self) -> None: """ @@ -1020,7 +693,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(is_update_last_fetch_datetime)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -1066,7 +739,7 @@ class TestTargetObject(): 辞書型のデータに対して、キー(last_fetch_datetime_file_name)がない場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1099,7 +772,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_last_fetch_datetime_file_name_no_value(self) -> None: """ @@ -1107,7 +780,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型が空文字の場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1141,7 +814,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_last_fetch_datetime_file_name_none_value(self) -> None: """ @@ -1149,7 +822,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型がNoneの場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1183,7 +856,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_raise_constructor_last_fetch_datetime_file_name_other_type(self) -> None: """ @@ -1192,7 +865,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(last_fetch_datetime_file_name)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -1238,7 +911,7 @@ class TestTargetObject(): 辞書型のデータに対して、キー(upload_file_name)がない場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1271,7 +944,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_upload_file_name_no_value(self) -> None: """ @@ -1279,7 +952,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(upload_file_name)の値の型が空文字の場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1313,7 +986,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_upload_file_name_none_value(self) -> None: """ @@ -1321,7 +994,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(upload_file_name)の値の型がNoneの場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1355,7 +1028,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_raise_constructor_upload_file_name_other_type(self) -> None: """ @@ -1364,7 +1037,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(upload_file_name)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -1410,7 +1083,7 @@ class TestTargetObject(): 辞書型のデータに対して、キー(datetime_column)がない場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1443,7 +1116,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_datetime_column_no_value(self) -> None: """ @@ -1451,7 +1124,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(datetime_column)の値の型が空文字の場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1485,7 +1158,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_constructor_datetime_column_none_value(self) -> None: """ @@ -1493,7 +1166,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(datetime_column)の値の型がNoneの場合、例外が発生しないこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生しないこと """ @@ -1527,7 +1200,7 @@ class TestTargetObject(): TargetObject(object_info, execute_datetime) # Expects - None + pass def test_raise_constructor_datetime_column_other_type(self) -> None: """ @@ -1536,7 +1209,7 @@ class TestTargetObject(): 辞書型のデータの対象のキー(datetime_column)の値の型が想定と違う場合、例外が発生すること Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する Expects: - 例外が発生し期待値と一致する """ @@ -1581,7 +1254,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1626,7 +1299,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1684,7 +1357,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1729,7 +1402,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1774,7 +1447,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1819,7 +1492,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1864,7 +1537,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1909,7 +1582,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1954,7 +1627,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -1999,7 +1672,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -2044,7 +1717,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -2089,7 +1762,7 @@ class TestTargetObject(): オブジェクト情報から対象の値を返すこと Arranges: - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する + - 実行日時インスタンスを生成する - オブジェクト情報インスタンスを生成する Expects: - 戻り値が期待値と一致する @@ -2127,380 +1800,3 @@ class TestTargetObject(): # Expects assert actual == 'SystemModstamp' - - -class TestLastFetchDatetime(): - def test_constructor(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータに対して、バリデーションチェックを行いチェックが通ることを確認する - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生しないこと - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - None - - def test_raise_constructor_last_fetch_datetime_from_no_key(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータに対して、必要なキー(last_fetch_datetime_from)がない場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' - - def test_raise_constructor_last_fetch_datetime_from_no_value(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が空文字の場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "", - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' - - def test_raise_constructor_last_fetch_datetime_from_none_value(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_from)の値がNoneの場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": None, - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str(e.value) == '「last_fetch_datetime_from」キーは必須です' - - def test_raise_constructor_last_fetch_datetime_from_other_type(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_from)の値の型が想定と違う場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": 1, - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str(e.value) == '「last_fetch_datetime_from」キーの値は「」でなければなりません' - - def test_raise_constructor_last_fetch_datetime_from_other_string(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_from)の値が正規表現と違う場合、例外が発生すること - Arranges: - - 辞書型のオブジェクト情報を準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "aaa", - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str( - e.value) == '「last_fetch_datetime_from」キーの値の正規表現「[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z」チェックに失敗しました' - - def test_raise_constructor_last_fetch_datetime_to_no_key(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータに対して、キー(last_fetch_datetime_to)がない場合、例外が発生しないこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生しないこと - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - # Act - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - None - - def test_constructor_last_fetch_datetime_to_no_value(self) -> None: - """ - Cases: - 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が空文字の場合、例外が発生しないこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生しないこと - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "" - } - - execute_datetime = ExecuteDateTime() - - # Act - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - None - - def test_constructor_last_fetch_datetime_to_none__value(self) -> None: - """ - Cases: - 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型がNoneの場合、例外が発生しないこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生しないこと - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": None - } - - execute_datetime = ExecuteDateTime() - - # Act - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - None - - def test_raise_constructor_last_fetch_datetime_to_other_type(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_to)の値の型が想定と違う場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": 1 - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str(e.value) == '「last_fetch_datetime_to」キーの値は「」でなければなりません' - - def test_raise_constructor_last_fetch_datetime_to_other_string(self) -> None: - """ - Cases: - インスタンス生成テスト - 辞書型のデータの対象のキー(last_fetch_datetime_to)の値が正規表現と違う場合、例外が発生すること - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - Expects: - - 例外が発生し期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "aaa" - } - - execute_datetime = ExecuteDateTime() - - # Act - with pytest.raises(Exception) as e: - LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Expects - assert str( - e.value) == '「last_fetch_datetime_to」キーの値の正規表現「[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z」チェックに失敗しました' - - def test_last_fetch_datetime_from(self) -> str: - """ - Cases: - オブジェクト情報から対象の値を返すこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - - 前回取得日時インスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Act - actual = sut.last_fetch_datetime_from - - # Expects - assert actual == '1900-01-01T00:00:00.000Z' - - def test_last_fetch_datetime_to(self) -> str: - """ - Cases: - オブジェクト情報から対象の値を返すこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - - 前回取得日時インスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "2022-01-01T00:00:00.000Z" - } - - execute_datetime = ExecuteDateTime() - - sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Act - actual = sut.last_fetch_datetime_to - - # Expects - assert actual == '2022-01-01T00:00:00.000Z' - - def test_last_fetch_datetime_to_default(self) -> str: - """ - Cases: - オブジェクト情報から対象の値を返すこと - Arranges: - - 辞書型の前回取得日時データを準備する - - 実行日次インスタンスを生成する - - 前回取得日時インスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - last_fetch_datetime_dict = { - "last_fetch_datetime_from": "1900-01-01T00:00:00.000Z", - "last_fetch_datetime_to": "" - } - - execute_datetime = ExecuteDateTime() - - sut = LastFetchDatetime(last_fetch_datetime_dict, execute_datetime) - - # Act - actual = sut.last_fetch_datetime_to - - # Expects - assert actual == str(execute_datetime) From e10201c1f29de8b02c13442c126e5ef6acee9685 Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Mon, 8 Aug 2022 17:43:51 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20dict=5Fchecker=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/util/test_dict_checker.py | 580 ++++++++++++++++++ 1 file changed, 580 insertions(+) create mode 100644 ecs/crm-datafetch/tests/util/test_dict_checker.py diff --git a/ecs/crm-datafetch/tests/util/test_dict_checker.py b/ecs/crm-datafetch/tests/util/test_dict_checker.py new file mode 100644 index 00000000..6707b8be --- /dev/null +++ b/ecs/crm-datafetch/tests/util/test_dict_checker.py @@ -0,0 +1,580 @@ +import pytest +from src.util.dict_checker import DictChecker + + +class TestDictChecker: + + def test_is_empty_no_value(self): + """ + Cases: + 辞書型データの対象のキーの値が''(空文字)の場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_empty("test_key") + + # Expects + assert actual is True + + def test_is_empty_none(self): + """ + Cases: + 辞書型データの対象のキーの値がNoneの場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": None + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_empty("test_key") + + # Expects + assert actual is True + + def test_is_empty_exist_value(self): + """ + Cases: + 辞書型データの対象のキーの値が存在する場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_empty("test_key") + + # Expects + assert actual is False + + def test_is_list_empty_no_value(self): + """ + Cases: + 辞書型のデータの対象のキーのリストの値が''(空文字)の場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": [ + "" + ] + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_list_empty("test_key") + + # Expects + assert actual is False + + def test_is_list_empty_none(self): + """ + Cases: + 辞書型データの対象のキーのリストの値がNoneの場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": [ + None + ] + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_list_empty("test_key") + + # Expects + assert actual is False + + def test_is_list_empty_blank(self): + """ + Cases: + 辞書型データの対象のキーのリストの値が[](空)の場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": [] + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_list_empty("test_key") + + # Expects + assert actual is True + + def test_is_list_empty_exist_string(self): + """ + Cases: + 辞書型データの対象のキーの値に文字列が存在する場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_list_empty("test_key") + + # Expects + assert actual is False + + def test_is_list_empty_exist_value(self): + """ + Cases: + 辞書型データの対象のキーのリストの値が存在する場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": [ + "test_value" + ] + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.is_list_empty("test_key") + + # Expects + assert actual is False + + def test_check_key_exist(self) -> bool: + """ + Cases: + 辞書型データの対象のキーが存在する、かつ値が存在する場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.check_key_exist("test_key") + + # Expects + assert actual is True + + def test_check_key_exist_no_key(self) -> bool: + """ + Cases: + 辞書型データの対象のキーが存在しない場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.check_key_exist("test_key") + + # Expects + assert actual is False + + def test_check_key_exist_no_value(self) -> bool: + """ + Cases: + 辞書型データの対象のキーの値が存在しない場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.check_key_exist("test_key") + + # Expects + assert actual is False + + def test_check_data_type(self) -> bool: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した型と一致した場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.check_data_type("test_key", str) + + # Expects + assert actual is True + + def test_check_data_type_other_type(self) -> bool: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した型と一致しない場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": 1 + } + + sut = DictChecker(object_dict) + + # Act + actual = sut.check_data_type("test_key", str) + + # Expects + assert actual is False + + def test_check_match_pattern(self) -> bool: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した正規表現と一致した場合、Trueが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + - 正規表現パターンの生成 + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "2022-08-01T10:00:00.000Z" + } + + sut = DictChecker(object_dict) + + pattern = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' + + # Act + actual = sut.check_match_pattern(pattern, "test_key") + + # Expects + assert actual is True + + def test_check_match_pattern_not_match(self) -> bool: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した正規表現と一致しない場合、Falseが返る + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + - 正規表現パターンの生成 + Expects: + - 戻り値が期待値と一致する + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + pattern = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' + + # Act + actual = sut.check_match_pattern(pattern, "test_key") + + # Expects + assert actual is False + + def test_assert_key_exist(self) -> None: + """ + Cases: + 辞書型データの対象のキーの値が存在する場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + sut.assert_key_exist("test_key") + + # Expects + pass + + def test_raise_assert_key_exist(self) -> None: + """ + Cases: + 辞書型データの対象のキーの値が存在しない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 発生した例外が期待値と一致すること + """ + + # Arranges + object_dict = { + "test_key": "" + } + + sut = DictChecker(object_dict) + + # Act + with pytest.raises(Exception) as e: + sut.assert_key_exist("test_key") + + # Expects + assert str(e.value) == '「test_key」キーは必須です' + + def test_assert_data_type(self) -> None: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した型と一致した場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + # Act + sut.assert_data_type("test_key", str) + + # Expects + pass + + def test_raise_assert_data_type(self) -> None: + """ + Cases: + 辞書型データの対象のキーの値の型が指定した型と一致しない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 発生した例外が期待値と一致すること + """ + + # Arranges + object_dict = { + "test_key": 1 + } + + sut = DictChecker(object_dict) + + # Act + with pytest.raises(Exception) as e: + sut.assert_data_type("test_key", str) + + # Expects + assert str(e.value) == "「test_key」キーの値は「」でなければなりません" + + def test_assert_match_pattern(self): + """ + Cases: + 辞書型データの対象のキーの値の型が指定した正規表現と一致した場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + - 正規表現パターンの生成 + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_dict = { + "test_key": "2022-08-01T10:00:00.000Z" + } + + sut = DictChecker(object_dict) + + pattern = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' + + # Act + sut.assert_match_pattern("test_key", pattern, 'YYYY-MM-DDTHH:MM:SS.000Z') + + # Expects + pass + + def test_raise_assert_match_pattern(self): + """ + Cases: + 辞書型データの対象のキーの値の型が指定した正規表現と一致しない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + - 正規表現パターンの生成 + Expects: + - 発生した例外が期待値と一致すること + """ + + # Arranges + object_dict = { + "test_key": "test_value" + } + + sut = DictChecker(object_dict) + + pattern = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' + + # Act + with pytest.raises(Exception) as e: + sut.assert_match_pattern("test_key", pattern, 'YYYY-MM-DDTHH:MM:SS.000Z') + + assert str(e.value) == '「test_key」キーの値の正規表現チェックに失敗しました 「YYYY-MM-DDTHH:MM:SS.000Z」形式である必要があります' + + def test_assert_list_empty(self): + """ + Cases: + 辞書型データの対象のキーのリストの値が存在する場合、例外が発生しないこと + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 例外が発生しないこと + """ + + # Arranges + object_dict = { + "test_key": [ + "test_value" + ] + } + + sut = DictChecker(object_dict) + + # Act + sut.assert_list_empty("test_key") + + # Expects + pass + + def test_raise_assert_list_empty(self): + """ + Cases: + 辞書型データの対象のキーのリストの値が存在しない場合、例外が発生すること + Arranges: + - 辞書型のオブジェクト情報を準備する + - 辞書型チェックインスタンスを生成する + Expects: + - 発生した例外が期待値と一致すること + """ + + # Arranges + object_dict = { + "test_key": [ + ] + } + + sut = DictChecker(object_dict) + + # Act + with pytest.raises(Exception) as e: + sut.assert_list_empty("test_key") + + # Expects + assert str(e.value) == '「test_key」キーのリストの値は必須です' From 00cb7602f602d9226ae52af4d97bf2c67037178a Mon Sep 17 00:00:00 2001 From: Y_SAKAI Date: Tue, 16 Aug 2022 21:17:41 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20parametrize=E3=82=92=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E3=81=97=E3=81=9F=E3=83=86=E3=82=B9=E3=83=88=E3=83=91?= =?UTF-8?q?=E3=82=BF=E3=83=BC=E3=83=B3=E3=81=AE=E9=9B=86=E7=B4=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/util/test_dict_checker.py | 331 +++--------------- 1 file changed, 56 insertions(+), 275 deletions(-) diff --git a/ecs/crm-datafetch/tests/util/test_dict_checker.py b/ecs/crm-datafetch/tests/util/test_dict_checker.py index 6707b8be..508afa69 100644 --- a/ecs/crm-datafetch/tests/util/test_dict_checker.py +++ b/ecs/crm-datafetch/tests/util/test_dict_checker.py @@ -4,10 +4,17 @@ from src.util.dict_checker import DictChecker class TestDictChecker: - def test_is_empty_no_value(self): + @pytest.mark.parametrize('test_data,expect', [ + ('', True), + (None, True), + ('test_data', False), + ]) + def test_is_empty(self, test_data, expect): """ Cases: - 辞書型データの対象のキーの値が''(空文字)の場合、Trueが返る + 1. 辞書型データの対象のキーの値が''(空文字)の場合、Trueが返る + 2. 辞書型データの対象のキーの値がNoneの場合、Trueが返る + 3. 辞書型データの対象のキーの値が存在する場合、Falseが返る Arranges: - 辞書型のオブジェクト情報を準備する - 辞書型チェックインスタンスを生成する @@ -17,7 +24,7 @@ class TestDictChecker: # Arranges object_dict = { - "test_key": "" + "test_key": test_data } sut = DictChecker(object_dict) @@ -26,12 +33,23 @@ class TestDictChecker: actual = sut.is_empty("test_key") # Expects - assert actual is True + assert actual is expect - def test_is_empty_none(self): + @pytest.mark.parametrize('test_data,expect', [ + ([''], False), + ([None], False), + (['test_value'], False), + ([], True), + ('test_value', False) + ]) + def test_is_list_empty(self, test_data, expect): """ Cases: - 辞書型データの対象のキーの値がNoneの場合、Trueが返る + 1. 辞書型のデータの対象のキーのリストの値が''(空文字)の場合、Falseが返る + 2. 辞書型データの対象のキーのリストの値がNoneの場合、Falseが返る + 3. 辞書型データの対象のキーのリストの値が存在する場合、Falseが返る + 4. 辞書型データの対象のキーのリストの値が[](空)の場合、Trueが返る + 5. 辞書型データの対象のキーの値に文字列が存在する場合、Falseが返る Arranges: - 辞書型のオブジェクト情報を準備する - 辞書型チェックインスタンスを生成する @@ -41,57 +59,7 @@ class TestDictChecker: # Arranges object_dict = { - "test_key": None - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_empty("test_key") - - # Expects - assert actual is True - - def test_is_empty_exist_value(self): - """ - Cases: - 辞書型データの対象のキーの値が存在する場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "test_value" - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_empty("test_key") - - # Expects - assert actual is False - - def test_is_list_empty_no_value(self): - """ - Cases: - 辞書型のデータの対象のキーのリストの値が''(空文字)の場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": [ - "" - ] + "test_key": test_data } sut = DictChecker(object_dict) @@ -100,12 +68,19 @@ class TestDictChecker: actual = sut.is_list_empty("test_key") # Expects - assert actual is False + assert actual is expect - def test_is_list_empty_none(self): + @pytest.mark.parametrize('test_data,expect', [ + ({"test_key": "test_value"}, True), + ({}, False), + ({"test_key": ""}, False), + ]) + def test_check_key_exist(self, test_data, expect) -> bool: """ Cases: - 辞書型データの対象のキーのリストの値がNoneの場合、Falseが返る + 1. 辞書型データの対象のキーが存在する、かつ値が存在する場合、Trueが返る + 2. 辞書型データの対象のキーが存在しない場合、Falseが返る + 3. 辞書型データの対象のキーの値が存在しない場合、Falseが返る Arranges: - 辞書型のオブジェクト情報を準備する - 辞書型チェックインスタンスを生成する @@ -114,109 +89,7 @@ class TestDictChecker: """ # Arranges - object_dict = { - "test_key": [ - None - ] - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_list_empty("test_key") - - # Expects - assert actual is False - - def test_is_list_empty_blank(self): - """ - Cases: - 辞書型データの対象のキーのリストの値が[](空)の場合、Trueが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": [] - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_list_empty("test_key") - - # Expects - assert actual is True - - def test_is_list_empty_exist_string(self): - """ - Cases: - 辞書型データの対象のキーの値に文字列が存在する場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "test_value" - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_list_empty("test_key") - - # Expects - assert actual is False - - def test_is_list_empty_exist_value(self): - """ - Cases: - 辞書型データの対象のキーのリストの値が存在する場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": [ - "test_value" - ] - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.is_list_empty("test_key") - - # Expects - assert actual is False - - def test_check_key_exist(self) -> bool: - """ - Cases: - 辞書型データの対象のキーが存在する、かつ値が存在する場合、Trueが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "test_value" - } + object_dict = test_data sut = DictChecker(object_dict) @@ -224,12 +97,17 @@ class TestDictChecker: actual = sut.check_key_exist("test_key") # Expects - assert actual is True + assert actual is expect - def test_check_key_exist_no_key(self) -> bool: + @pytest.mark.parametrize('test_data,test_type,expect', [ + ({"test_key": "test_value"}, str, True), + ({"test_key": 1}, str, False) + ]) + def test_check_data_type(self, test_data, test_type, expect) -> bool: """ Cases: - 辞書型データの対象のキーが存在しない場合、Falseが返る + 1. 辞書型データの対象のキーの値の型が指定した型と一致した場合、Trueが返る + 2. 辞書型データの対象のキーの値の型が指定した型と一致しない場合、Falseが返る Arranges: - 辞書型のオブジェクト情報を準備する - 辞書型チェックインスタンスを生成する @@ -238,93 +116,25 @@ class TestDictChecker: """ # Arranges - object_dict = { - } + object_dict = test_data sut = DictChecker(object_dict) # Act - actual = sut.check_key_exist("test_key") + actual = sut.check_data_type("test_key", test_type) # Expects - assert actual is False + assert actual is expect - def test_check_key_exist_no_value(self) -> bool: + @pytest.mark.parametrize('test_data,expect', [ + ({"test_key": "2022-08-01T10:00:00.000Z"}, True), + ({"test_key": "test_value"}, False) + ]) + def test_check_match_pattern(self, test_data, expect) -> bool: """ Cases: - 辞書型データの対象のキーの値が存在しない場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "" - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.check_key_exist("test_key") - - # Expects - assert actual is False - - def test_check_data_type(self) -> bool: - """ - Cases: - 辞書型データの対象のキーの値の型が指定した型と一致した場合、Trueが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "test_value" - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.check_data_type("test_key", str) - - # Expects - assert actual is True - - def test_check_data_type_other_type(self) -> bool: - """ - Cases: - 辞書型データの対象のキーの値の型が指定した型と一致しない場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": 1 - } - - sut = DictChecker(object_dict) - - # Act - actual = sut.check_data_type("test_key", str) - - # Expects - assert actual is False - - def test_check_match_pattern(self) -> bool: - """ - Cases: - 辞書型データの対象のキーの値の型が指定した正規表現と一致した場合、Trueが返る + 1. 辞書型データの対象のキーの値の型が指定した正規表現と一致した場合、Trueが返る + 2. 辞書型データの対象のキーの値の型が指定した正規表現と一致しない場合、Falseが返る Arranges: - 辞書型のオブジェクト情報を準備する - 辞書型チェックインスタンスを生成する @@ -334,9 +144,7 @@ class TestDictChecker: """ # Arranges - object_dict = { - "test_key": "2022-08-01T10:00:00.000Z" - } + object_dict = test_data sut = DictChecker(object_dict) @@ -346,34 +154,7 @@ class TestDictChecker: actual = sut.check_match_pattern(pattern, "test_key") # Expects - assert actual is True - - def test_check_match_pattern_not_match(self) -> bool: - """ - Cases: - 辞書型データの対象のキーの値の型が指定した正規表現と一致しない場合、Falseが返る - Arranges: - - 辞書型のオブジェクト情報を準備する - - 辞書型チェックインスタンスを生成する - - 正規表現パターンの生成 - Expects: - - 戻り値が期待値と一致する - """ - - # Arranges - object_dict = { - "test_key": "test_value" - } - - sut = DictChecker(object_dict) - - pattern = r'[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\.000Z' - - # Act - actual = sut.check_match_pattern(pattern, "test_key") - - # Expects - assert actual is False + assert actual is expect def test_assert_key_exist(self) -> None: """