def test_metadata_validator_valid(self, mocker, metadata): mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) validator = PackUniqueFilesValidator('fake') assert validator.validate_pack_meta_file()
def test_validate_pack_readme_valid_images(self, mocker): """ Given - A pack README file with valid absolute image paths in it. When - Run validate on pack README file Then - Ensure: - Validation succeed - Valid absolute image paths were not caught """ from demisto_sdk.commands.common.hook_validations.readme import \ ReadMeValidator self.validator = PackUniqueFilesValidator(os.path.join(self.FILES_PATH, 'DummyPack2')) mocker.patch.object(ReadMeValidator, 'check_readme_relative_image_paths', return_value=[]) # Test only absolute paths with requests_mock.Mocker() as m: # Mock get requests m.get('https://github.com/demisto/content/raw/test1.png', status_code=200, text="Test1") m.get('https://raw.githubusercontent.com/demisto/content/raw/test1.png', status_code=200, text="Test1") m.get('https://raw.githubusercontent.com/demisto/content/raw/test1.jpg', status_code=200, text="Test1") result = self.validator.validate_pack_readme_images() errors = self.validator.get_errors() assert result assert 'please repair it:\n![Identity with High Risk Score](https://github.com/demisto/content/raw/test1.png)' not in errors assert 'please repair it:\n![Identity with High Risk Score](https://raw.githubusercontent.com/demisto/content/raw/test1.png)' not in errors assert 'please repair it:\n(https://raw.githubusercontent.com/demisto/content/raw/test1.jpg)' not in errors
def validate_pack_unique_files(self, packs): for pack in packs: pack_unique_files_validator = PackUniqueFilesValidator(pack) pack_errors = pack_unique_files_validator.validate_pack_unique_files() if pack_errors: print_error(pack_errors) self._is_valid = False
def validate_pack_unique_files(self, pack_path: str, pack_error_ignore_list: dict, should_version_raise=False) -> bool: """ Runs validations on the following pack files: * .secret-ignore: Validates that the file exist and that the file's secrets can be parsed as a list delimited by '\n' * .pack-ignore: Validates that the file exists and that all regexes in it can be compiled * README.md file: Validates that the file exists * pack_metadata.json: Validates that the file exists and that it has a valid structure Args: should_version_raise: Whether we should check if the version of the metadata was raised pack_error_ignore_list: A dictionary of all pack ignored errors pack_path: A path to a pack """ print(f'\nValidating {pack_path} unique pack files') pack_unique_files_validator = PackUniqueFilesValidator(pack=os.path.basename(pack_path), pack_path=pack_path, ignored_errors=pack_error_ignore_list, print_as_warnings=self.print_ignored_errors, should_version_raise=should_version_raise) pack_errors = pack_unique_files_validator.validate_pack_unique_files() if pack_errors: click.secho(pack_errors, fg="bright_red") return False return True
def test_metadata_validator_valid(self, mocker, metadata): mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) validator = PackUniqueFilesValidator('fake') assert validator.validate_pack_meta_file()
def test_validate_pack_unique_files(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_and_pack_description', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_images', return_value=True) mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) assert not self.validator.are_valid_files(id_set_validations=False) fake_validator = PackUniqueFilesValidator('fake') mocker.patch.object(fake_validator, '_read_metadata_content', return_value=dict()) assert fake_validator.are_valid_files(id_set_validations=False)
def test_metadata_validator_invalid__non_breaking(self, mocker, metadata): mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') mocker.patch.object(PackUniqueFilesValidator, '_is_integration_pack', return_value=True) validator = PackUniqueFilesValidator('fake') assert not validator.validate_pack_meta_file()
def test_metadata_validator_empty_categories(self, mocker): metadata = os.path.join(self.__class__.FILES_PATH, 'pack_metadata_empty_categories.json') mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') mocker.patch.object(PackUniqueFilesValidator, '_is_integration_pack', return_value=True) validator = PackUniqueFilesValidator('fake') assert not validator.validate_pack_meta_file() assert "[PA129] - pack_metadata.json - Missing categories" in validator.get_errors()
def test_is_version_format(self, version, expected): """ Given: - A version to be checked by the _is_version_format function When: - Validating meta data structure. Then: - return True if the version is in the correct format and False otherwise """ validator = PackUniqueFilesValidator('fake') assert validator._is_version_format_valid(version) == expected
def test_metadata_validator_valid(self, mocker): mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file( os.path.join( TestPackMetadataValidator.FILES_PATH, 'valid_pack_metadata.json'))) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) validator = PackUniqueFilesValidator('fake') assert validator.validate_pack_meta_file()
def test_validate_pack_name(self, metadata_content: Dict, expected: bool, mocker): """ Given: - Metadata JSON pack file content. When: - Validating if pack name is valid. Then: - Ensure expected result is returned. """ validator = PackUniqueFilesValidator('fake') mocker.patch.object(validator, '_add_error', return_value=True) assert validator.validate_pack_name(metadata_content) == expected
def test_is_integration_pack(self, pack): """ Given: - A pack with an integration to validate. When: - Calling _is_integration_pack() method. Then: - Ensure true is returned, indicates the pack contains integration. """ pack.create_integration('test') validator = PackUniqueFilesValidator(pack.name, pack_path=pack.path) assert validator._is_integration_pack()
def test_validate_pack_readme_file_is_not_empty_playbook(self, mocker, text, result): """ Given: - pack with playbooks When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure result is False for empty README.md file and True otherwise. """ self.validator = PackUniqueFilesValidator(os.path.join(self.FILES_PATH, 'CortexXDR')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=text) assert self.validator.validate_pack_readme_file_is_not_empty() == result
def test_validate_pack_readme_file_is_not_empty_partner(self, mocker, text, result): """ Given: - partner pack When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure result is False for empty README.md file and True otherwise. """ self.validator = PackUniqueFilesValidator(self.FAKE_PACK_PATH) self.validator.support = 'partner' mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=text) assert self.validator.validate_pack_readme_file_is_not_empty() == result
def test_metadata_not_dict(self, mocker): """ Given: - Metadata file whom structure is not a dict When: - Validating metadata structure. Then: - Ensure false is returned, and a BlockingValidationFailureException is raised. """ mocker.patch.object(PackUniqueFilesValidator, '_read_metadata_content', return_value={'a', 'b'}) validator = PackUniqueFilesValidator('fake') mocker.patch.object(validator, '_add_error') with pytest.raises(BlockingValidationFailureException): assert not validator._is_pack_meta_file_structure_valid()
class TestPackUniqueFilesValidator: FILES_PATH = os.path.normpath(os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files')) FAKE_PACK_PATH = os.path.join(FILES_PATH, 'fake_pack') FAKE_PATH_NAME = 'fake_pack' validator = PackUniqueFilesValidator(FAKE_PATH_NAME) validator.pack_path = FAKE_PACK_PATH def test_is_error_added(self): self.validator._add_error('boop') assert 'boop' in self.validator.get_errors(True) assert 'boop' in self.validator.get_errors() self.validator._errors = [] def test_is_file_exist(self): assert self.validator._is_pack_file_exists(PACKS_README_FILE_NAME) assert not self.validator._is_pack_file_exists('boop') self.validator._errors = [] def test_parse_file_into_list(self): assert ['boop', 'sade', ''] == self.validator._parse_file_into_list(PACKS_README_FILE_NAME) assert not self.validator._parse_file_into_list('boop') self.validator._errors = [] def test_validate_pack_unique_files(self): assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files()
def test_no_readme_alert_on_scripts_layouts(self, repo, mocker): """ Given: - pack with scripts or layouts When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure no error on an empty pack README file. """ dummy_pack = repo.create_pack('TEST_PACK') dummy_pack.create_layout('test_layout') dummy_pack.create_script('test_script') self.validator = PackUniqueFilesValidator(dummy_pack.path) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value="text") assert self.validator.validate_pack_readme_file_is_not_empty()
def test_name_does_not_contain_excluded_word(self): """ Given: - Pack name. When: - Validating pack name does not contain excluded word. Then: - Ensure expected result is returned. """ pack_name: str = 'Bitcoin Abuse' validator = PackUniqueFilesValidator('fake') assert validator.name_does_not_contain_excluded_word(pack_name) for excluded_word in EXCLUDED_DISPLAY_NAME_WORDS: invalid_pack_name: str = f'{pack_name} ({excluded_word})' assert not validator.name_does_not_contain_excluded_word(invalid_pack_name)
def validate_pack_unique_files(self, packs: set) -> None: """ Runs validations on the following pack files: * .secret-ignore: Validates that the file exist and that the file's secrets can be parsed as a list delimited by '\n' * .pack-ignore: Validates that the file exists and that all regexes in it can be compiled * README.md file: Validates that the file exists * pack_metadata.json: Validates that the file exists and that it has a valid structure Args: packs: A set of pack paths i.e {Packs/<pack-name1>, Packs/<pack-name2>} """ for pack in packs: print(f'Validating {pack} unique pack files') pack_unique_files_validator = PackUniqueFilesValidator(pack) pack_errors = pack_unique_files_validator.validate_pack_unique_files( ) if pack_errors: print_error(pack_errors) self._is_valid = False
def test_metadata_validator_invalid__breaking(self, mocker, metadata): """ Given A pack metadata file with invalid contents that should halt validations When Calling validate_pack_meta_file Then Ensure BlockingValidationFailureException is raised """ mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') validator = PackUniqueFilesValidator('fake') with pytest.raises(BlockingValidationFailureException): assert not validator.validate_pack_meta_file()
def test_validate_pack_readme_invalid_images(self): """ Given - A pack README file with invalid absolute and relative image paths in it. When - Run validate on pack README file Then - Ensure: - Validation fails - Invalid relative image paths were caught correctly - Invalid absolute image paths were caught correctly """ self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'DummyPack2')) with requests_mock.Mocker() as m: # Mock get requests m.get('https://github.com/demisto/content/raw/test1.png', status_code=404, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.png', status_code=404, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.jpg', status_code=404, text="Test1") result = self.validator.validate_pack_readme_images() errors = self.validator.get_errors() assert not result assert 'Detected the following image relative path: ![Identity with High Risk Score](doc_files/High_Risk_User.png)' in errors assert 'Detected the following image relative path: ![Identity with High Risk Score](home/test1/test2/doc_files/High_Risk_User.png)' in errors assert 'Detected the following image relative path: (../../doc_files/Access_investigation_-_Generic_4_5.png)' in errors assert 'Image link was not found, either insert it or remove it:\n![Account Enrichment](Insert the link to your image here)' in errors assert 'please repair it:\n![Identity with High Risk Score](https://github.com/demisto/content/raw/test1.png)' in errors assert 'please repair it:\n![Identity with High Risk Score](https://raw.githubusercontent.com/demisto/content/raw/test1.png)' in errors assert 'please repair it:\n(https://raw.githubusercontent.com/demisto/content/raw/test1.jpg)' in errors # this path is not an image path and should not be shown. assert 'https://github.com/demisto/content/raw/test3.png' not in errors
def test_metadata_validator_invalid_version_add_error(self, mocker): """ Given: - pack metadata.json file with wrong version type When: - validating meta data structure Then: - Ensure false is returned and the correct error is added to the validation object error list """ metadata = os.path.join(self.FILES_PATH, 'pack_metadata_invalid_format_version.json') mocker.patch.object(tools, 'get_dict_from_file', return_value=({'approved_list': []}, 'json')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=TestPackMetadataValidator.read_file(metadata)) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') validator = PackUniqueFilesValidator('fake') assert not validator.validate_pack_meta_file() assert "[PA130] - Pack metadata version format is not valid. Please fill in a valid format (example: 0.0.0)" in validator.get_errors()
def test_check_timestamp_format(self): """ Given - timestamps in various formats. When - Running check_timestamp_format on them. Then - Ensure True for iso format and False for any other format. """ fake_validator = PackUniqueFilesValidator('fake') good_format_timestamp = '2020-04-14T00:00:00Z' missing_z = '2020-04-14T00:00:00' missing_t = '2020-04-14 00:00:00Z' only_date = '2020-04-14' with_hyphen = '2020-04-14T00-00-00Z' assert fake_validator.check_timestamp_format(good_format_timestamp) assert not fake_validator.check_timestamp_format(missing_t) assert not fake_validator.check_timestamp_format(missing_z) assert not fake_validator.check_timestamp_format(only_date) assert not fake_validator.check_timestamp_format(with_hyphen)
def test_validate_pack_metadata(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files()
class TestPackUniqueFilesValidator: FILES_PATH = os.path.normpath( os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files')) FAKE_PACK_PATH = os.path.join(FILES_PATH, 'fake_pack') FAKE_PATH_NAME = 'fake_pack' validator = PackUniqueFilesValidator(FAKE_PATH_NAME) validator.pack_path = FAKE_PACK_PATH def test_is_error_added_name_only(self): self.validator._add_error(('boop', '101'), 'file_name') assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_error_added_full_path(self): self.validator._add_error(('boop', '101'), f'{self.validator.pack_path}/file/name') assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_file_exist(self): assert self.validator._is_pack_file_exists(PACKS_README_FILE_NAME) assert not self.validator._is_pack_file_exists('boop') self.validator._errors = [] def test_parse_file_into_list(self): assert [ 'boop', 'sade', '' ] == self.validator._parse_file_into_list(PACKS_README_FILE_NAME) assert not self.validator._parse_file_into_list('boop') self.validator._errors = [] def test_validate_pack_unique_files(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files() def test_validate_pack_metadata(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files() def test_validate_partner_contribute_pack_metadata(self, mocker, repo): """ Given - Partner contributed pack without email and url. When - Running validate on it. Then - Ensure validate found errors. """ mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object( PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(PACK_METADATA_PARTNER_NO_EMAIL_NO_URL)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(PACK_METADATA_PARTNER_NO_EMAIL_NO_URL) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) assert 'Contributed packs must include email or url' in result.stdout def test_check_timestamp_format(self): """ Given - timestamps in various formats. When - Running check_timestamp_format on them. Then - Ensure True for iso format and False for any other format. """ fake_validator = PackUniqueFilesValidator('fake') good_format_timestamp = '2020-04-14T00:00:00Z' missing_z = '2020-04-14T00:00:00' missing_t = '2020-04-14 00:00:00Z' only_date = '2020-04-14' with_hyphen = '2020-04-14T00-00-00Z' assert fake_validator.check_timestamp_format(good_format_timestamp) assert not fake_validator.check_timestamp_format(missing_t) assert not fake_validator.check_timestamp_format(missing_z) assert not fake_validator.check_timestamp_format(only_date) assert not fake_validator.check_timestamp_format(with_hyphen)
class TestPackUniqueFilesValidator: FILES_PATH = os.path.normpath( os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files')) FAKE_PACK_PATH = os.path.join(FILES_PATH, 'fake_pack') FAKE_PATH_NAME = 'fake_pack' validator = PackUniqueFilesValidator(FAKE_PATH_NAME) validator.pack_path = FAKE_PACK_PATH def test_is_error_added_name_only(self): self.validator._add_error(('boop', '101'), 'file_name') assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_error_added_full_path(self): self.validator._add_error(('boop', '101'), f'{self.validator.pack_path}/file/name') assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_file_exist(self): assert self.validator._is_pack_file_exists(PACKS_README_FILE_NAME) assert not self.validator._is_pack_file_exists('boop') self.validator._errors = [] def test_parse_file_into_list(self): assert [ 'boop', 'sade', '' ] == self.validator._parse_file_into_list(PACKS_README_FILE_NAME) assert not self.validator._parse_file_into_list('boop') self.validator._errors = [] def test_validate_pack_unique_files(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files() def test_validate_pack_metadata(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files() def test_validate_partner_contribute_pack_metadata_no_mail_and_url( self, mocker, repo): """ Given - Partner contributed pack without email and url. When - Running validate on it. Then - Ensure validate found errors. """ pack_metadata_no_email_and_url = PACK_METADATA_PARTNER.copy() pack_metadata_no_email_and_url['email'] = '' pack_metadata_no_email_and_url['url'] = '' mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'get_master_private_repo_meta_file', return_value=None) mocker.patch.object( PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(pack_metadata_no_email_and_url)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(pack_metadata_no_email_and_url) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) assert 'Contributed packs must include email or url' in result.stdout def test_validate_partner_contribute_pack_metadata_price_change( self, mocker, repo): """ Given - Partner contributed pack where price has changed. When - Running validate on it. Then - Ensure validate found errors. """ pack_metadata_price_changed = PACK_METADATA_PARTNER.copy() pack_metadata_price_changed['price'] = 3 mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'get_master_private_repo_meta_file', return_value=PACK_METADATA_PARTNER) mocker.patch.object( PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(pack_metadata_price_changed)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(pack_metadata_price_changed) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) assert 'The pack price was changed from 2 to 3 - revert the change' in result.stdout def test_check_timestamp_format(self): """ Given - timestamps in various formats. When - Running check_timestamp_format on them. Then - Ensure True for iso format and False for any other format. """ fake_validator = PackUniqueFilesValidator('fake') good_format_timestamp = '2020-04-14T00:00:00Z' missing_z = '2020-04-14T00:00:00' missing_t = '2020-04-14 00:00:00Z' only_date = '2020-04-14' with_hyphen = '2020-04-14T00-00-00Z' assert fake_validator.check_timestamp_format(good_format_timestamp) assert not fake_validator.check_timestamp_format(missing_t) assert not fake_validator.check_timestamp_format(missing_z) assert not fake_validator.check_timestamp_format(only_date) assert not fake_validator.check_timestamp_format(with_hyphen) def test_validate_pack_dependencies_invalid_id_set(self, mocker, repo): """ Given - An invalid id set error being raised When - Running validate_pack_dependencies. Then - Ensure that the validation fails and that the invalid id set error is printed. """ def error_raising_function(argument): raise ValueError( "Couldn't find any items for pack 'PackID'. make sure your spelling is correct." ) mocker.patch.object(tools, 'get_remote_file', side_effect=error_raising_function) assert not self.validator.validate_pack_dependencies( "fake_id_set_file_path") assert Errors.invalid_id_set()[0] in self.validator.get_errors() def test_validate_pack_dependencies_skip_id_set_creation(self, capsys): """ Given - skip_id_set_creation flag set to true. - No id_set file exists When - Running validate_pack_dependencies. Then - Ensure that the validation passes and that the skipping message is printed. """ self.validator.skip_id_set_creation = True res = self.validator.validate_pack_dependencies( "fake_id_set_file_path") self.validator.skip_id_set_creation = False # reverting to default for next tests assert res assert "Unable to find id_set.json file - skipping dependencies check" in capsys.readouterr( ).out @pytest.mark.parametrize( 'usecases, is_valid', [([], True), (['Phishing', 'Malware'], True), (['NonApprovedUsecase', 'Case Management'], False)]) def test_is_approved_usecases(self, repo, usecases, is_valid): """ Given: - Case A: Pack without usecases - Case B: Pack with approved usecases (Phishing and Malware) - Case C: Pack with non-approved usecase (NonApprovedUsecase) and approved usecase (Case Management) When: - Validating approved usecases Then: - Case A: Ensure validation passes as there are no usecases to verify - Case B: Ensure validation passes as both usecases are approved - Case C: Ensure validation fails as it contains a non-approved usecase (NonApprovedUsecase) Verify expected error is printed """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: usecases, PACK_METADATA_SUPPORT: XSOAR_SUPPORT, PACK_METADATA_TAGS: [] }) self.validator.pack_path = pack.path assert self.validator._is_approved_usecases() == is_valid if not is_valid: assert 'The pack metadata contains non approved usecases: NonApprovedUsecase' in self.validator.get_errors( ) @pytest.mark.parametrize('tags, is_valid', [([], True), (['Machine Learning', 'Spam'], True), (['NonApprovedTag', 'GDPR'], False)]) def test_is_approved_tags(self, repo, tags, is_valid): """ Given: - Case A: Pack without tags - Case B: Pack with approved tags (Machine Learning and Spam) - Case C: Pack with non-approved usecase (NonApprovedTag) and approved usecase (GDPR) When: - Validating approved usecases Then: - Case A: Ensure validation passes as there are no usecases to verify - Case B: Ensure validation passes as both usecases are approved - Case C: Ensure validation fails as it contains a non-approved usecase (NonApprovedTag) Verify expected error is printed """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: [], PACK_METADATA_SUPPORT: XSOAR_SUPPORT, PACK_METADATA_TAGS: tags }) self.validator.pack_path = pack.path assert self.validator._is_approved_tags() == is_valid if not is_valid: assert 'The pack metadata contains non approved tags: NonApprovedTag' in self.validator.get_errors( ) @pytest.mark.parametrize('type, is_valid', [('community', True), ('partner', True), ('xsoar', True), ('someName', False), ('test', False), ('developer', True)]) def test_is_valid_support_type(self, repo, type, is_valid): """ Given: - Pack with support type in the metadata file. When: - Running _is_valid_support_type. Then: - Ensure True when the support types are valid, else False with the right error message. """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: [], PACK_METADATA_SUPPORT: type }) self.validator.pack_path = pack.path assert self.validator._is_valid_support_type() == is_valid if not is_valid: assert 'Support field should be one of the following: xsoar, partner, developer or community.' in \ self.validator.get_errors() def test_get_master_private_repo_meta_file_running_on_master( self, mocker, repo, capsys): """ Given: - A repo which runs on master branch When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'master' mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Running on master branch - skipping price change validation" in capsys.readouterr( ).out def test_get_master_private_repo_meta_file_getting_git_error( self, repo, capsys, mocker): """ Given: - A repo which runs on non-master branch. - git.show command raises GitCommandError. When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'not-master' class gitClass: def show(self, var): raise GitCommandError("A", "B") git = gitClass() mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Got an error while trying to connect to git" in capsys.readouterr( ).out def test_get_master_private_repo_meta_file_file_not_found( self, mocker, repo, capsys): """ Given: - A repo which runs on non-master branch. - git.show command returns None. When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'not-master' class gitClass: def show(self, var): return None git = gitClass() mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Unable to find previous pack_metadata.json file - skipping price change validation" in \ capsys.readouterr().out
def test_validate_pack_metadata(self): assert not self.validator.validate_pack_unique_files() fake_validator = PackUniqueFilesValidator('fake') assert fake_validator.validate_pack_unique_files()
class TestPackUniqueFilesValidator: FILES_PATH = os.path.normpath( os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files', 'Packs')) FAKE_PACK_PATH = os.path.normpath( os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files', 'fake_pack')) FAKE_PACK_NO_PLAYBOOK = os.path.normpath( os.path.join(__file__, f'{git_path()}/demisto_sdk/tests', 'test_files', 'DummyPackOnlyPlaybook')) FAKE_PATH_NAME = 'fake_pack' validator = PackUniqueFilesValidator(FAKE_PATH_NAME) validator.pack_path = FAKE_PACK_PATH def restart_validator(self): self.validator.pack_path = '' self.validator = PackUniqueFilesValidator(self.FAKE_PATH_NAME) self.validator.pack_path = self.FAKE_PACK_PATH def test_is_error_added_name_only(self): self.validator._add_error(('boop', '101'), 'file_name') assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file_name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_error_added_full_path(self): self.validator._add_error(('boop', '101'), f'{self.validator.pack_path}/file/name') assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( True) assert f'{self.validator.pack_path}/file/name: [101] - boop\n' in self.validator.get_errors( ) self.validator._errors = [] def test_is_file_exist(self): assert self.validator._is_pack_file_exists(PACKS_README_FILE_NAME) assert not self.validator._is_pack_file_exists('boop') self.validator._errors = [] def test_parse_file_into_list(self): assert [ 'boop', 'sade', '' ] == self.validator._parse_file_into_list(PACKS_README_FILE_NAME) assert not self.validator._parse_file_into_list('boop') self.validator._errors = [] def test_validate_pack_unique_files(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_and_pack_description', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_images', return_value=True) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': [] }, 'json')) assert not self.validator.are_valid_files(id_set_validations=False) fake_validator = PackUniqueFilesValidator('fake') mocker.patch.object(fake_validator, '_read_metadata_content', return_value=dict()) assert fake_validator.are_valid_files(id_set_validations=False) def test_validate_pack_metadata(self, mocker): mocker.patch.object(BaseValidator, 'check_file_flags', return_value='') mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_and_pack_description', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_readme_images', return_value=True) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': [] }, 'json')) assert not self.validator.are_valid_files(id_set_validations=False) fake_validator = PackUniqueFilesValidator('fake') mocker.patch.object(fake_validator, '_read_metadata_content', return_value=dict()) assert fake_validator.are_valid_files(id_set_validations=False) def test_validate_partner_contribute_pack_metadata_no_mail_and_url( self, mocker, repo): """ Given - Partner contributed pack without email and url. When - Running validate on it. Then - Ensure validate found errors. """ pack_metadata_no_email_and_url = PACK_METADATA_PARTNER.copy() pack_metadata_no_email_and_url['email'] = '' pack_metadata_no_email_and_url['url'] = '' mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_name', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'get_master_private_repo_meta_file', return_value=None) mocker.patch.object( PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(pack_metadata_no_email_and_url)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': [] }, 'json')) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(pack_metadata_no_email_and_url) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) assert 'Contributed packs must include email or url' in result.stdout @pytest.mark.parametrize('url, is_valid', [ ('https://github.com/pont_to_repo', False), ('some_support_url', True), ('https://github.com/pont_to_repo/issues', True), ]) def test_validate_partner_pack_metadata_url(self, mocker, repo, url, is_valid): """ Given - Partner contributed pack with an is_valid url. When - Running validate on it. Then - Ensure validate finds errors accordingly. """ pack_metadata_changed_url = PACK_METADATA_PARTNER.copy() pack_metadata_changed_url['url'] = url mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_name', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'get_master_private_repo_meta_file', return_value=None) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(pack_metadata_changed_url)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': [] }, 'json')) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(pack_metadata_changed_url) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) error_text = 'The metadata URL leads to a GitHub repo instead of a support page.' if is_valid: assert error_text not in result.stdout else: assert error_text in result.stdout def test_validate_partner_contribute_pack_metadata_price_change( self, mocker, repo): """ Given - Partner contributed pack where price has changed. When - Running validate on it. Then - Ensure validate found errors. """ pack_metadata_price_changed = PACK_METADATA_PARTNER.copy() pack_metadata_price_changed['price'] = 3 mocker.patch.object(tools, 'is_external_repository', return_value=True) mocker.patch.object(PackUniqueFilesValidator, '_is_pack_file_exists', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'validate_pack_name', return_value=True) mocker.patch.object(PackUniqueFilesValidator, 'get_master_private_repo_meta_file', return_value=PACK_METADATA_PARTNER) mocker.patch.object( PackUniqueFilesValidator, '_read_file_content', return_value=json.dumps(pack_metadata_price_changed)) mocker.patch.object(BaseValidator, 'check_file_flags', return_value=None) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': [] }, 'json')) pack = repo.create_pack('PackName') pack.pack_metadata.write_json(pack_metadata_price_changed) with ChangeCWD(repo.path): runner = CliRunner(mix_stderr=False) result = runner.invoke(main, [VALIDATE_CMD, '-i', pack.path], catch_exceptions=False) assert 'The pack price was changed from 2 to 3 - revert the change' in result.stdout def test_check_timestamp_format(self): """ Given - timestamps in various formats. When - Running check_timestamp_format on them. Then - Ensure True for iso format and False for any other format. """ fake_validator = PackUniqueFilesValidator('fake') good_format_timestamp = '2020-04-14T00:00:00Z' missing_z = '2020-04-14T00:00:00' missing_t = '2020-04-14 00:00:00Z' only_date = '2020-04-14' with_hyphen = '2020-04-14T00-00-00Z' assert fake_validator.check_timestamp_format(good_format_timestamp) assert not fake_validator.check_timestamp_format(missing_t) assert not fake_validator.check_timestamp_format(missing_z) assert not fake_validator.check_timestamp_format(only_date) assert not fake_validator.check_timestamp_format(with_hyphen) def test_validate_pack_dependencies_invalid_id_set(self, mocker, repo): """ Given - An invalid id set error being raised When - Running validate_pack_dependencies. Then - Ensure that the validation fails and that the invalid id set error is printed. """ self.restart_validator() def error_raising_function(*args, **kwargs): raise ValueError( "Couldn't find any items for pack 'PackID'. make sure your spelling is correct." ) mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.get_core_pack_list', side_effect=error_raising_function) assert not self.validator.validate_pack_dependencies() assert Errors.invalid_id_set()[0] in self.validator.get_errors() def test_validate_core_pack_dependencies(self): """ Given - A list of non-core packs When - Running validate_core_pack_dependencies. Then - Ensure that the validation fails and that the invalid core pack dependencies error is printed. """ self.restart_validator() dependencies_packs = { 'dependency_pack_1': { 'mandatory': True, 'display_name': 'dependency pack 1' }, 'dependency_pack_2': { 'mandatory': False, 'display_name': 'dependency pack 2' }, 'dependency_pack_3': { 'mandatory': True, 'display_name': 'dependency pack 3' } } assert not self.validator.validate_core_pack_dependencies( dependencies_packs) assert Errors.invalid_core_pack_dependencies('fake_pack', ['dependency_pack_1', 'dependency_pack_3'])[0] \ in self.validator.get_errors() def test_validate_pack_dependencies_skip_id_set_creation(self, capsys): """ Given - skip_id_set_creation flag set to true. - No id_set file exists When - Running validate_pack_dependencies. Then - Ensure that the validation passes and that the skipping message is printed. """ self.restart_validator() self.validator.skip_id_set_creation = True res = self.validator.validate_pack_dependencies() self.validator.skip_id_set_creation = False # reverting to default for next tests assert res assert "No first level dependencies found" in capsys.readouterr().out @pytest.mark.parametrize( 'usecases, is_valid, branch_usecases', [([], True, []), (['Phishing', 'Malware'], True, []), (['NonApprovedUsecase', 'Case Management'], False, []), (['NewUseCase'], True, ['NewUseCase']), (['NewUseCase1, NewUseCase2'], False, ['NewUseCase1'])]) def test_is_approved_usecases(self, repo, usecases, is_valid, branch_usecases, mocker): """ Given: - Case A: Pack without usecases - Case B: Pack with approved usecases (Phishing and Malware) - Case C: Pack with non-approved usecase (NonApprovedUsecase) and approved usecase (Case Management) - Case D: Pack with approved usecase (NewUseCase) located in my branch only - Case E: Pack with non-approved usecase (NewUseCase2) and approved usecase (NewUseCase1) located in my branch only When: - Validating approved usecases Then: - Case A: Ensure validation passes as there are no usecases to verify - Case B: Ensure validation passes as both usecases are approved - Case C: Ensure validation fails as it contains a non-approved usecase (NonApprovedUsecase) Verify expected error is printed - Case D: Ensure validation passes as usecase is approved on the same branch - Case E: Ensure validation fails as it contains a non-approved usecase (NewUseCase2) Verify expected error is printed """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: usecases, PACK_METADATA_SUPPORT: XSOAR_SUPPORT, PACK_METADATA_TAGS: [] }) mocker.patch.object(tools, 'is_external_repository', return_value=False) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': branch_usecases }, 'json')) self.validator.pack_path = pack.path with ChangeCWD(repo.path): assert self.validator._is_approved_usecases() == is_valid if not is_valid: assert 'The pack metadata contains non approved usecases:' in self.validator.get_errors( ) @pytest.mark.parametrize('tags, is_valid, branch_tags', [([], True, []), (['Machine Learning', 'Spam'], True, []), (['NonApprovedTag', 'GDPR'], False, []), (['NewTag'], True, ['NewTag']), (['NewTag1, NewTag2'], False, ['NewTag1'])]) def test_is_approved_tags(self, repo, tags, is_valid, branch_tags, mocker): """ Given: - Case A: Pack without tags - Case B: Pack with approved tags (Machine Learning and Spam) - Case C: Pack with non-approved tags (NonApprovedTag) and approved tags (GDPR) - Case D: Pack with approved tags (NewTag) located in my branch only - Case E: Pack with non-approved tags (NewTag) and approved tags (NewTag) located in my branch only When: - Validating approved tags Then: - Case A: Ensure validation passes as there are no tags to verify - Case B: Ensure validation passes as both tags are approved - Case C: Ensure validation fails as it contains a non-approved tags (NonApprovedTag) Verify expected error is printed - Case D: Ensure validation passes as tags is approved on the same branch - Case E: Ensure validation fails as it contains a non-approved tag (NewTag2) Verify expected error is printed """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: [], PACK_METADATA_SUPPORT: XSOAR_SUPPORT, PACK_METADATA_TAGS: tags }) mocker.patch.object(tools, 'is_external_repository', return_value=False) mocker.patch.object(tools, 'get_dict_from_file', return_value=({ 'approved_list': branch_tags }, 'json')) self.validator.pack_path = pack.path with ChangeCWD(repo.path): assert self.validator._is_approved_tags() == is_valid if not is_valid: assert 'The pack metadata contains non approved tags:' in self.validator.get_errors( ) @pytest.mark.parametrize('pack_content, tags, is_valid', [ ("none", [], True), ("none", ["Use Case"], False), ("playbook", ["Use Case"], True), ("incident", ["Use Case"], True), ("layout", ["Use Case"], True), ("playbook", [], True), ]) def test_is_right_usage_of_usecase_tag(self, repo, pack_content, tags, is_valid): self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: [], PACK_METADATA_SUPPORT: XSOAR_SUPPORT, PACK_METADATA_TAGS: tags, }) if pack_content == "playbook": pack.create_playbook(name="PlaybookName") elif pack_content == "incident": pack.create_incident_type(name="IncidentTypeName") elif pack_content == "layout": pack.create_layout(name="Layout") self.validator.pack_path = pack.path with ChangeCWD(repo.path): assert self.validator.is_right_usage_of_usecase_tag() == is_valid @pytest.mark.parametrize('type, is_valid', [('community', True), ('partner', True), ('xsoar', True), ('someName', False), ('test', False), ('developer', True)]) def test_is_valid_support_type(self, repo, type, is_valid): """ Given: - Pack with support type in the metadata file. When: - Running _is_valid_support_type. Then: - Ensure True when the support types are valid, else False with the right error message. """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json({ PACK_METADATA_USE_CASES: [], PACK_METADATA_SUPPORT: type }) self.validator.pack_path = pack.path with ChangeCWD(repo.path): assert self.validator._is_valid_support_type() == is_valid if not is_valid: assert 'Support field should be one of the following: xsoar, partner, developer or community.' in \ self.validator.get_errors() def test_get_master_private_repo_meta_file_running_on_master( self, mocker, repo, capsys): """ Given: - A repo which runs on master branch When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'master' mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Running on master branch - skipping price change validation" in capsys.readouterr( ).out def test_get_master_private_repo_meta_file_getting_git_error( self, repo, capsys, mocker): """ Given: - A repo which runs on non-master branch. - git.show command raises GitCommandError. When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'not-master' class gitClass: def show(self, var): raise GitCommandError("A", "B") git = gitClass() mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Got an error while trying to connect to git" in capsys.readouterr( ).out def test_get_master_private_repo_meta_file_file_not_found( self, mocker, repo, capsys): """ Given: - A repo which runs on non-master branch. - git.show command returns None. When: - Running get_master_private_repo_meta_file. Then: - Ensure result is None and the appropriate skipping message is printed. """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.pack_metadata.write_json(PACK_METADATA_PARTNER) class MyRepo: active_branch = 'not-master' class gitClass: def show(self, var): return None git = gitClass() mocker.patch( 'demisto_sdk.commands.common.hook_validations.pack_unique_files.Repo', return_value=MyRepo) res = self.validator.get_master_private_repo_meta_file( str(pack.pack_metadata.path)) assert not res assert "Unable to find previous pack_metadata.json file - skipping price change validation" in \ capsys.readouterr().out @pytest.mark.parametrize('text, result', README_INPUT_RESULTS_LIST) def test_validate_pack_readme_file_is_not_empty_partner( self, mocker, text, result): """ Given: - partner pack When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure result is False for empty README.md file and True otherwise. """ self.validator = PackUniqueFilesValidator(self.FAKE_PACK_PATH) self.validator.support = 'partner' mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=text) assert self.validator.validate_pack_readme_file_is_not_empty( ) == result @pytest.mark.parametrize('text, result', README_INPUT_RESULTS_LIST) def test_validate_pack_readme_file_is_not_empty_playbook( self, mocker, text, result): """ Given: - pack with playbooks When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure result is False for empty README.md file and True otherwise. """ self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'CortexXDR')) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value=text) assert self.validator.validate_pack_readme_file_is_not_empty( ) == result def test_no_readme_alert_on_scripts_layouts(self, repo, mocker): """ Given: - pack with scripts or layouts When: - Running test_validate_pack_readme_file_is_not_empty_partner. Then: - Ensure no error on an empty pack README file. """ dummy_pack = repo.create_pack('TEST_PACK') dummy_pack.create_layout('test_layout') dummy_pack.create_script('test_script') self.validator = PackUniqueFilesValidator(dummy_pack.path) mocker.patch.object(PackUniqueFilesValidator, '_read_file_content', return_value="text") assert self.validator.validate_pack_readme_file_is_not_empty() def test_validate_pack_readme_file_is_not_empty_missing_file(self): self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'DummyPack')) assert self.validator._is_pack_file_exists( self.validator.readme_file) is False def test_validate_pack_readme_valid_images(self, mocker): """ Given - A pack README file with valid absolute image paths in it. When - Run validate on pack README file Then - Ensure: - Validation succeed - Valid absolute image paths were not caught """ from demisto_sdk.commands.common.hook_validations.readme import \ ReadMeValidator self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'DummyPack2')) mocker.patch.object(ReadMeValidator, 'check_readme_relative_image_paths', return_value=[]) # Test only absolute paths with requests_mock.Mocker() as m: # Mock get requests m.get('https://github.com/demisto/content/raw/test1.png', status_code=200, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.png', status_code=200, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.jpg', status_code=200, text="Test1") result = self.validator.validate_pack_readme_images() errors = self.validator.get_errors() assert result assert 'please repair it:\n![Identity with High Risk Score](https://github.com/demisto/content/raw/test1.png)' not in errors assert 'please repair it:\n![Identity with High Risk Score](https://raw.githubusercontent.com/demisto/content/raw/test1.png)' not in errors assert 'please repair it:\n(https://raw.githubusercontent.com/demisto/content/raw/test1.jpg)' not in errors def test_validate_pack_readme_invalid_images(self): """ Given - A pack README file with invalid absolute and relative image paths in it. When - Run validate on pack README file Then - Ensure: - Validation fails - Invalid relative image paths were caught correctly - Invalid absolute image paths were caught correctly """ self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'DummyPack2')) with requests_mock.Mocker() as m: # Mock get requests m.get('https://github.com/demisto/content/raw/test1.png', status_code=404, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.png', status_code=404, text="Test1") m.get( 'https://raw.githubusercontent.com/demisto/content/raw/test1.jpg', status_code=404, text="Test1") result = self.validator.validate_pack_readme_images() errors = self.validator.get_errors() assert not result assert 'Detected the following image relative path: ![Identity with High Risk Score](doc_files/High_Risk_User.png)' in errors assert 'Detected the following image relative path: ![Identity with High Risk Score](home/test1/test2/doc_files/High_Risk_User.png)' in errors assert 'Detected the following image relative path: (../../doc_files/Access_investigation_-_Generic_4_5.png)' in errors assert 'Image link was not found, either insert it or remove it:\n![Account Enrichment](Insert the link to your image here)' in errors assert 'please repair it:\n![Identity with High Risk Score](https://github.com/demisto/content/raw/test1.png)' in errors assert 'please repair it:\n![Identity with High Risk Score](https://raw.githubusercontent.com/demisto/content/raw/test1.png)' in errors assert 'please repair it:\n(https://raw.githubusercontent.com/demisto/content/raw/test1.jpg)' in errors # this path is not an image path and should not be shown. assert 'https://github.com/demisto/content/raw/test3.png' not in errors @pytest.mark.parametrize('readme_content, is_valid', [ ('Hey there, just testing', True), ('This is a test. All good!', False), ]) def test_pack_readme_is_different_then_pack_description( self, repo, readme_content, is_valid): """ Given: - Case A: A unique pack readme. - Case B: Pack readme that is equal to pack description When: - Validating pack readme vs pack description Then: - Case A: Ensure validation passes as the pack readme and pack description are different. - Case B: Ensure validation fails as the pack readme is the same as the pack description. Verify expected error is printed """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) pack.readme.write_text(readme_content) pack.pack_metadata.write_json({ PACK_METADATA_DESC: 'This is a test. All good!', }) self.validator.pack_path = pack.path with ChangeCWD(repo.path): assert self.validator.validate_pack_readme_and_pack_description( ) == is_valid if not is_valid: assert 'README.md content is equal to pack description. ' \ 'Please remove the duplicate description from README.md file' in self.validator.get_errors() def test_validate_pack_readme_and_pack_description_no_readme_file( self, repo): """ Given: - A pack with no readme. When: - Validating pack readme vs pack description Then: - Fail on no README file and not on descrption error. """ self.restart_validator() pack_name = 'PackName' pack = repo.create_pack(pack_name) self.validator.pack_path = pack.path with ChangeCWD(repo.path): os.remove(pack.readme.path) assert self.validator.validate_pack_readme_and_pack_description() assert '"README.md" file does not exist, create one in the root of the pack' in self.validator.get_errors( ) assert 'README.md content is equal to pack description. ' \ 'Please remove the duplicate description from README.md file' not in self.validator.get_errors() def test_valid_is_pack_metadata_desc_too_long(self, repo): """ Given: - Valid description length When: - Validating pack description length Then: - Ensure validation passes as the description field length is valid. """ pack_description = 'Hey there, just testing' assert self.validator.is_pack_metadata_desc_too_long( pack_description) is True def test_invalid_is_pack_metadata_desc_too_long(self, mocker, repo): """ Given: - Invalid description length - higher than 130 When: - Validating pack description length Then: - Ensure validation passes although description field length is higher than 130 - Ensure warning will be printed. """ pack_description = 'This is will fail cause the description here is too long.' \ 'test test test test test test test test test test test test test test test test test' \ ' test test test test test' error_desc = 'The description field of the pack_metadata.json file is longer than 130 characters.' mocker.patch("click.secho") assert self.validator.is_pack_metadata_desc_too_long( pack_description) is True assert error_desc in click.secho.call_args_list[0][0][0] def test_validate_author_image_exists_valid(self, repo): """ Given: - Pack with partner support and author image When: - Validating if author image exists Then: - Ensure validation passes. """ pack = repo.create_pack('MyPack') self.validator.metadata_content = {'support': 'partner'} self.validator.pack_path = pack.path author_image_path = pack.author_image.path with ChangeCWD(repo.path): res = self.validator.validate_author_image_exists() assert res assert f'Partners must provide a non-empty author image under the path {author_image_path}.' not in \ self.validator.get_errors() def test_validate_author_image_exists_invalid(self, repo): """ Given: - Pack with partner support and no author image When: - Validating if author image exists Then: - Ensure validation fails. """ pack = repo.create_pack('MyPack') self.validator.metadata_content = {'support': 'partner'} self.validator.pack_path = pack.path author_image_path = pack.author_image.path with ChangeCWD(repo.path): os.remove(author_image_path) res = self.validator.validate_author_image_exists() assert not res assert f'Partners must provide a non-empty author image under the path {author_image_path}.' in \ self.validator.get_errors() @pytest.mark.parametrize( 'pack_metadata, rn_version, create_rn, expected_results', [ ({ "currentVersion": "1.0.1" }, "1.0.1", True, True), ({ "currentVersion": "1.0.2" }, "1.0.1", True, False), ({ "currentVersion": "1.0.1" }, "1.0.2", True, False), ({ "currentVersion": "1.0.1" }, "1.0.2", False, False), ({ "currentVersion": "1.0.0" }, "1.0.0", False, True), ]) def test_is_right_version(self, repo, pack_metadata, rn_version, create_rn, expected_results): """ Given - Case 1: Pack containing rn and pack_metadata with equal versions. - Case 2: Pack containing rn and pack_metadata with rn versions lower than pack_metadata. - Case 3: Pack containing rn and pack_metadata with rn versions higher than pack_metadata. - Case 4: Pack with pack_metadata version higher than 1.0.0 but no rn. - Case 5: Pack with pack_metadata version 1.0.0 and no rn. When - Running test_is_right_version command on pack. Then - Ensure validation correctly. - Case 1: Should return True. - Case 2: Should return False. - Case 3: Should return False. - Case 4: Should return False. - Case 5: Should return True. """ pack = repo.create_pack('MyPack') self.validator.metadata_content = pack_metadata self.validator.pack_path = pack.path self.validator.pack_meta_file = PACKS_PACK_META_FILE_NAME if create_rn: pack.create_release_notes(version=rn_version) res = self.validator._is_right_version() assert res == expected_results
def test_validate_pack_readme_file_is_not_empty_missing_file(self): self.validator = PackUniqueFilesValidator( os.path.join(self.FILES_PATH, 'DummyPack')) assert self.validator._is_pack_file_exists( self.validator.readme_file) is False
def restart_validator(self): self.validator.pack_path = '' self.validator = PackUniqueFilesValidator(self.FAKE_PATH_NAME) self.validator.pack_path = self.FAKE_PACK_PATH