def test_with_duplicate_params(self, print_error): """ Given - integration configuratiton contains duplicate parameter (called test) When - running the validation is_there_duplicate_params() Then - it should set is_valid to False - it should return True (there are duplicate params) - it should print an error message that contains the duplicated param name """ # from demisto_sdk.commands.common.tools import print_error # mocker.patch(tools, 'print_error') current = {'configuration': [{'name': 'test'}, {'name': 'test'}]} structure = mock_structure("", current) validator = IntegrationValidator(structure) assert validator.is_there_duplicate_params() is True assert validator.is_valid is False error_message = print_error.call_args[0][0] assert error_message == ': The parameter \'test\' of the file is duplicated, please remove one of its ' \ 'appearances.'
def test_is_valid_display_configuration(self, configuration_setting, answer): current = {"configuration": configuration_setting} structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_not_valid_display_configuration() is not answer
def test_is_valid_image_positive(monkeypatch): """ Given - An integration is with a valid non default image When - Validating this integration Then - Ensure integration is considered valid """ integration_path = os.path.normpath( os.path.join(f'{git_path()}/demisto_sdk/tests', 'test_files', 'not_default_image_integration-Zoom.yml')) structure = mock_structure(file_path=integration_path) monkeypatch.setattr( 'demisto_sdk.commands.common.hook_validations.image.INTEGRATION_REGXES', [integration_path]) # Adding monkey patching this will make image validator behave like this is an integration outside of # pack context and ignore the image that's in the same folder as the file monkeypatch.setattr( 'demisto_sdk.commands.common.hook_validations.image.INTEGRATION_REGEX', integration_path) validator = IntegrationValidator(structure) assert validator.is_valid_image() is True
def test_is_valid_description_positive(self): integration_path = os.path.normpath( os.path.join(f'{git_path()}/demisto_sdk/tests', 'test_files', 'integration-Zoom.yml') ) structure = mock_structure(file_path=integration_path) validator = IntegrationValidator(structure) assert validator.is_valid_description() is True
def setup(self): config = { 'configuration': deepcopy([FIRST_FETCH_PARAM, MAX_FETCH_PARAM]), 'script': { 'isfetch': True } } self.validator = IntegrationValidator(mock_structure("", config))
def test_valid_pwsh(self, script_type, fromversion, res): current = { "script": {"type": script_type}, "fromversion": fromversion, } structure = mock_structure("", current) validator = IntegrationValidator(structure) assert validator.is_valid_pwsh() == res
def setup(self): config = { 'configuration': deepcopy(FEED_REQUIRED_PARAMS), 'script': { 'feed': True } } self.validator = IntegrationValidator(mock_structure("", config))
class TestIsFetchParamsExist: def setup(self): config = { 'configuration': deepcopy(FETCH_REQUIRED_PARAMS), 'script': { 'isfetch': True } } self.validator = IntegrationValidator(mock_structure("", config)) def test_valid(self): assert self.validator.is_valid_fetch( ), 'is_valid_fetch() returns False instead True' def test_sanity(self): # missing param in configuration self.validator.current_file['configuration'] = [ t for t in self.validator.current_file['configuration'] if t['name'] != 'incidentType' ] assert self.validator.is_valid_fetch( ) is False, 'is_valid_fetch() returns True instead False' def test_missing_field(self): # missing param for i, t in enumerate(self.validator.current_file['configuration']): if t['name'] == 'incidentType': del self.validator.current_file['configuration'][i]['name'] print(self.validator.current_file['configuration']) assert self.validator.is_valid_fetch( ) is False, 'is_valid_fetch() returns True instead False' def test_malformed_field(self, capsys): # incorrect param config = self.validator.current_file['configuration'] self.validator.current_file['configuration'] = [] for t in config: if t['name'] == 'incidentType': t['type'] = 123 self.validator.current_file['configuration'].append(t) assert self.validator.is_valid_fetch( ) is False, 'is_valid_fetch() returns True instead False' captured = capsys.readouterr() out = captured.out print(out) assert "display: Incident type" in out assert "name: incidentType" in out assert "required: false" in out assert "type: 13" in out def test_not_fetch(self, capsys): self.test_malformed_field(capsys) self.validator.is_valid = True self.validator.current_file['script']['isfetch'] = False assert self.validator.is_valid_fetch( ), 'is_valid_fetch() returns False instead True'
def test_valid_feed(self, feed, fromversion): current = { "script": {"feed": feed}, "fromversion": fromversion, 'configuration': deepcopy(FEED_REQUIRED_PARAMS) } structure = mock_structure("", current) validator = IntegrationValidator(structure) assert validator.is_valid_feed()
def validate_integration(self, structure_validator, pack_error_ignore_list, is_modified): integration_validator = IntegrationValidator(structure_validator, ignored_errors=pack_error_ignore_list, print_as_warnings=self.print_ignored_errors, skip_docker_check=self.skip_docker_checks) if is_modified and self.is_backward_check: return all([integration_validator.is_valid_file(validate_rn=False, skip_test_conf=self.skip_conf_json), integration_validator.is_backward_compatible()]) else: return integration_validator.is_valid_file(validate_rn=False, skip_test_conf=self.skip_conf_json)
class TestIsValidMaxFetchAndFirstFetch: """ Given - yml file of integration as config When - run validate checks Then - if the isfetch identifier is true make sure the first_fetch and max_fetch params exists - make sure max_fetch param has a default value """ def setup(self): config = { 'configuration': deepcopy([FIRST_FETCH_PARAM, MAX_FETCH_PARAM]), 'script': { 'isfetch': True } } self.validator = IntegrationValidator(mock_structure("", config)) def test_valid(self): assert self.validator.is_valid_max_fetch_and_first_fetch( ), 'is_valid_fetch() returns False instead True' def test_missing_max_fetch(self): # missing param in configuration self.validator.current_file['configuration'] = [ t for t in self.validator.current_file['configuration'] if t['name'] != 'max_fetch' ] assert self.validator.is_valid_max_fetch_and_first_fetch() is False, \ 'is_valid_fetch() returns True instead False' def test_missing_default_value_in_max_fetch(self): # missing param in configuration for param in self.validator.current_file['configuration']: if param.get('name') == 'max_fetch': param.pop('defaultvalue') assert self.validator.is_valid_max_fetch_and_first_fetch() is False, \ 'is_valid_fetch() returns True instead False' def test_missing_fetch_time(self): # missing param in configuration self.validator.current_file['configuration'] = [ t for t in self.validator.current_file['configuration'] if t['name'] != 'first_fetch' ] assert self.validator.is_valid_max_fetch_and_first_fetch() is False, \ 'is_valid_fetch() returns True instead False' def test_not_fetch(self): self.validator.is_valid = True self.validator.current_file['script']['isfetch'] = False assert self.validator.is_valid_max_fetch_and_first_fetch(), \ 'is_valid_fetch() returns False instead True'
def test_empty_commands(self): """ Given: an integration with no commands When: running validate on integration with no command. Then: Validate it's valid. """ current = {"script": {"commands": None}} structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_valid_default_arguments() is True
def test_is_there_a_runnable(self, param): """ Given: one of any runnable integration When: running validate on integration with at least one of commands, fetch, feed or long-running Then: Validate it's valid. """ current = {"script": param} structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_there_a_runnable() is True
def test_is_valid_default_argument(self, current, answer): """ Given: Integration command with arguments. When: running is_valid_default_argument command. Then: Validate that up to 1 default arg name yields True, else yields False. """ current = {"script": {"commands": current}} structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_valid_default_argument() is answer
def test_is_there_a_runnable_negative(self): """ Given: an integration with no runnable param When: running validate on integration with no one of commands, fetch, feed or long-running Then: Validate it's invalid. """ current = {"script": {}} structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_there_a_runnable() is False
def test_are_tests_configured(self, file_path: str, file_type: str, expected: bool): """ Given - A content item When - Checking if the item has tests configured Then - validator return the correct answer accordingly """ structure_validator = StructureValidator(file_path, predefined_scheme=file_type) validator = IntegrationValidator(structure_validator) assert validator.are_tests_configured() == expected
def test_invalid_integration_path(self, integration, mocker): """ Given - An integration with invalid file path. When - running is_valid_integration_file_path. Then - an integration with an invalid file path is invalid. """ structure_validator = StructureValidator( integration.yml.path, predefined_scheme='integration') validator = IntegrationValidator(structure_validator) validator.file_path = 'Packs/VirusTotal/Integrations/VirusTotal/integration-VirusTotal_5.5.yml' mocker.patch.object(validator, "handle_error", return_value=True) assert not validator.is_valid_integration_file_path() structure_validator = StructureValidator( integration.path, predefined_scheme='integration') validator = IntegrationValidator(structure_validator) validator.file_path = 'Packs/VirusTotal/Integrations/Virus_Total_5.yml' mocker.patch.object(validator, "handle_error", return_value=True) assert not validator.is_valid_integration_file_path()
def test_is_outputs_for_reputations_commands_valid(self, current, name, answer): current = { "script": { "commands": [{ "name": name, "outputs": current }] } } structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_outputs_for_reputations_commands_valid() is answer
def test_is_valid_deprecated_integration(self, current, answer): """ Given - A deprecated integration with a display and description. When - running is_valid_as_deprecated. Then - an integration with an invalid display name or invalid description will be errored. """ structure = mock_structure("", current) validator = IntegrationValidator(structure) validator.current_file = current assert validator.is_valid_as_deprecated() is answer
def test_is_removed_integration_parameters(self, current_file, old_file, answer): """ Given - integration configuration with different parameters When - running the validation is_removed_integration_parameters() Then - upon removal of parameters: it should set is_valid to False and return True - upon non removal or addition of parameters: it should set is_valid to True and return False """ structure = mock_structure("", current_file, old_file) validator = IntegrationValidator(structure) assert validator.is_removed_integration_parameters() is answer assert validator.is_valid is not answer
def test_image_when_invalid_type(monkeypatch): """ Given - An integration that has an invalid image When - Validating this integration Then - Ensure integration is considered non-valid. """ integration_path = os.path.normpath( os.path.join(f'{git_path()}/demisto_sdk/tests', 'test_files', 'not_default_image_integration-Zoom.yml')) structure = mock_structure(file_path=integration_path) validator = IntegrationValidator(structure) assert validator.is_valid_image() is False
def test_image_in_both_yml_and_directory(monkeypatch): """ Given - An integration that has image in both yml file and in the yml directory When - Validating this integration Then - Ensure integration is considered non-valid """ integration_path = os.path.normpath( os.path.join(f'{git_path()}/demisto_sdk/tests', 'test_files', 'not_default_image_integration-Zoom.yml')) structure = mock_structure(file_path=integration_path) validator = IntegrationValidator(structure) assert validator.is_valid_image() is False
def test_no_image_integration(monkeypatch): """ Given - A new integration yml that does not have an image in its pack When - Validating this integration Then - Ensure integration is considered non-valid. """ integration_path = os.path.normpath( os.path.join(f'{git_path()}/demisto_sdk/tests', 'test_files', 'DummyPack', 'Integrations', 'integration-DummyIntegration.yml')) structure = mock_structure(file_path=integration_path) validator = IntegrationValidator(structure) assert validator.is_valid_image() is False
def test_is_context_change_in_readme(self, readme, current_yml, expected): """ Given: a changed YML file When: running validate on integration with at least one command Then: Validate it's synced with the README. """ patcher = patch('os.path.exists') mock_thing = patcher.start() mock_thing.side_effect = lambda x: True with patch("builtins.open", mock_open(read_data=readme)) as _: current = {"script": {}} structure = mock_structure("Pack/Test", current) validator = IntegrationValidator(structure) validator.current_file = current_yml res = validator.is_context_change_in_readme() assert res == expected patcher.stop()
def test_valid_integration_parameters_display_name(self, integration): """ Given - An integration with valid parameters display names. When - running is_valid_parameters_display_name. Then - an integration with a valid parameters display name is valid. """ integration.yml.write_dict( {'configuration': [{ 'display': 'Token' }, { 'display': 'Username' }]}) structure_validator = StructureValidator( integration.yml.path, predefined_scheme='integration') validator = IntegrationValidator(structure_validator) assert validator.is_valid_parameters_display_name()
def test_valid_integration_path(self, integration): """ Given - An integration with valid file path. When - running is_valid_integration_file_path. Then - an integration with a valid file path is valid. """ structure_validator = StructureValidator( integration.yml.path, predefined_scheme='integration') validator = IntegrationValidator(structure_validator) validator.file_path = 'Packs/VirusTotal/Integrations/integration-VirusTotal_5.5.yml' assert validator.is_valid_integration_file_path() structure_validator = StructureValidator( integration.path, predefined_scheme='integration') validator = IntegrationValidator(structure_validator) validator.file_path = 'Packs/VirusTotal/Integrations/VirusTotal/Virus_Total.yml' assert validator.is_valid_integration_file_path()
def test_is_valid_hidden_params(self, source, answer): # type: (str, str) -> None structure = StructureValidator(source) validator = IntegrationValidator(structure) assert validator.is_valid_hidden_params() is answer
def test_is_all_params_not_hidden(self, current, answer): structure = mock_structure(current_file=current) validator = IntegrationValidator(structure) assert validator.is_all_params_not_hidden() is answer
def test_get_field_to_required_dict(self, input_json, expected): assert IntegrationValidator._get_field_to_required_dict( input_json) == expected
class TestIsFeedParamsExist: def setup(self): config = { 'configuration': deepcopy(FEED_REQUIRED_PARAMS), 'script': { 'feed': True } } self.validator = IntegrationValidator(mock_structure("", config)) def test_valid(self): assert self.validator.all_feed_params_exist( ), 'all_feed_params_exist() returns False instead True' def test_sanity(self): # missing param in configuration self.validator.current_file['configuration'] = [ t for t in self.validator.current_file['configuration'] if not t.get('display') ] assert self.validator.all_feed_params_exist( ) is False, 'all_feed_params_exist() returns True instead False' def test_missing_field(self): # missing param configuration = self.validator.current_file['configuration'] for i in range(len(configuration)): if not configuration[i].get('display'): del configuration[i]['name'] self.validator.current_file['configuration'] = configuration assert self.validator.all_feed_params_exist( ) is False, 'all_feed_params_exist() returns True instead False' def test_malformed_field(self): # incorrect param self.validator.current_file['configuration'] = [] for t in self.validator.current_file['configuration']: if not t.get('display'): t['type'] = 123 self.validator.current_file['configuration'].append(t) assert self.validator.all_feed_params_exist( ) is False, 'all_feed_params_exist() returns True instead False' NO_HIDDEN = { "configuration": [{ "id": "new", "name": "new", "display": "test" }, { "d": "123", "n": "s", "r": True }] } HIDDEN_FALSE = { "configuration": [{ "id": "n", "hidden": False }, { "display": "123", "name": "serer" }] } HIDDEN_TRUE = { "configuration": [{ "id": "n", "n": "n" }, { "display": "123", "required": "false", "hidden": True }] } HIDDEN_TRUE_AND_FALSE = { "configuration": [{ "id": "n", "hidden": False }, { "ty": "0", "r": "true", "hidden": True }] } IS_ALL_PARAMS_NOT_HIDDEN_INPUTS = [ (NO_HIDDEN, True), (HIDDEN_FALSE, True), (HIDDEN_TRUE, False), (HIDDEN_TRUE_AND_FALSE, False), ] @pytest.mark.parametrize("current, answer", IS_ALL_PARAMS_NOT_HIDDEN_INPUTS) def test_is_all_params_not_hidden(self, current, answer): structure = mock_structure(current_file=current) validator = IntegrationValidator(structure) assert validator.is_all_params_not_hidden() is answer