diff --git a/.changelog/4355.yml b/.changelog/4355.yml new file mode 100644 index 0000000000..b5fd3c1d33 --- /dev/null +++ b/.changelog/4355.yml @@ -0,0 +1,4 @@ +changes: +- description: Modified the RP102 validation to support the new validate format. The validation checks wether the id field equals the details field in an indicator type + type: internal +pr_number: 4355 diff --git a/demisto_sdk/commands/content_graph/tests/parsers_and_models_test.py b/demisto_sdk/commands/content_graph/tests/parsers_and_models_test.py index 0128d93e00..3716a4e441 100644 --- a/demisto_sdk/commands/content_graph/tests/parsers_and_models_test.py +++ b/demisto_sdk/commands/content_graph/tests/parsers_and_models_test.py @@ -696,7 +696,7 @@ def test_indicator_type_parser(self, pack: Pack): ContentItemModelVerifier.run( model, expected_id="urlRep", - expected_name="URL", + expected_name="urlRep", expected_path=indicator_type_path, expected_content_type=ContentType.INDICATOR_TYPE, expected_fromversion="5.5.0", diff --git a/demisto_sdk/commands/content_graph/tests/test_data/indicator_type.json b/demisto_sdk/commands/content_graph/tests/test_data/indicator_type.json index 10f632a2da..ea69f373b6 100644 --- a/demisto_sdk/commands/content_graph/tests/test_data/indicator_type.json +++ b/demisto_sdk/commands/content_graph/tests/test_data/indicator_type.json @@ -8,7 +8,7 @@ "shouldPublish": false, "shouldCommit": false, "regex": "(?i)((?:(?:https?|ftps?|hxxps?|sftp|meows):((\\/\\/)|(\\\\\\\\))(www\\[?\\.\\]?)?|ftp\\[?\\.\\]?))(?:[-_\\d\\p{L}\\p{S}]+\\[?\\.\\]?)+[-_\\d\\p{L}\\[\\]]+(?::\\d+)?(?:(?:((\\/)|(\\*)|(\\#)|(\\?)))+(?:[-\\d\\p{L}+&@'#\\/%=~_$!\\-:.;\\\\*–—―|\\[\\]]*|\\([-\\d\\p{L}\\+&@#\\/%=~_\\$\\?!\\-:,;\\\\\\*–—―\\|\\[\\]]*\\))*)*|((?i)((((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.)+(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(([\\[\\]\\p{L}\\dֿ]+\\[?\\.\\]?){1,3}[\\p{L}]+))(:[\\d]+)?\\/([-\\p{L}\\+&@#\\/%=~_\\$\\?!\\-:,;\\\\\\*–—―\\|\\.]+([\\d]*)?)+)|((?:(?:https?|ftps?|hxxps?|sftp):((\\/\\/)|(\\\\\\\\)))[\\d][\\S]+)|(((https?|ftps?|hxxps?|sftp):((\\/\\/)|(\\\\\\\\)))?(\\[)?(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(\\])?(:[\\d]+)?(((\\/|\\\\)[\\d]+(\\/|\\\\)[-\\d\\p{L}+&@'#\\/%=~_$!\\-:.;\\\\*–—―|\\[\\]]+)|((\\/|\\\\)[^\\d \\n\\t]+)))", - "details": "URL", + "details": "urlRep", "prevDetails": "URL", "reputationScriptName": "", "reputationCommand": "url", diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index bdba0c0726..95113d3542 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -38,7 +38,7 @@ select = [ "GF100", "GF101", "GF102", "IF100", "IF101", "IF102", "IF103", "IF104", "IF105", "IF106", "IF116", "IM100", "IM101", "IM108", "IM109", "IM106", "IM111", - "RP101", + "RP101", "RP102", "DA100", "DA101", "IT100", "IT101", "IT102", "IT103", "MR100", @@ -64,7 +64,7 @@ select = [ "GF100", "GF101", "IF100", "IF101", "IF102", "IF103", "IF104", "IF105", "IF106", "IF116", "IM101", "IM108", "IM111", - "RP101", + "RP101", "RP102", "IT102", "IT103", "MR100", ] diff --git a/demisto_sdk/commands/validate/tests/RP_validatiors_test.py b/demisto_sdk/commands/validate/tests/RP_validatiors_test.py index cb38bb99ac..59be7e2b7b 100644 --- a/demisto_sdk/commands/validate/tests/RP_validatiors_test.py +++ b/demisto_sdk/commands/validate/tests/RP_validatiors_test.py @@ -6,6 +6,9 @@ from demisto_sdk.commands.validate.validators.RP_validators.RP101_expiration_field_is_numeric import ( ExpirationFieldIsNumericValidator, ) +from demisto_sdk.commands.validate.validators.RP_validators.RP102_details_field_equals_id import ( + DetailsFieldEqualsIdValidator, +) @pytest.mark.parametrize( @@ -55,3 +58,31 @@ def test_ExpirationFieldIsNumericValidator_is_valid( for result, expected_msg in zip(results, expected_msgs) ] ) + + +def test_DetailsFieldEqualsIdValidator_is_valid(): + """ + Given + - two indicator_type objects: + - One indicator_type with id equals details. + - One indicator_type with id not equals details. + When + - Calling the DetailsFieldEqualsIdValidator is valid function. + Then + - Make sure the right amount of failures return. Should fail object two. + """ + content_items = [ + create_indicator_type_object(["details", "id"], ["test", "test"]), + create_indicator_type_object(["details", "id"], ["test", "test-not-equal"]), + ] + expected_msgs = [ + "id and details fields are not equal. id=test-not-equal, details=test" + ] + results = DetailsFieldEqualsIdValidator().is_valid(content_items) + assert len(results) == 1 + assert all( + [ + result.message == expected_msg + for result, expected_msg in zip(results, expected_msgs) + ] + ) diff --git a/demisto_sdk/commands/validate/validators/RP_validators/RP102_details_field_equals_id.py b/demisto_sdk/commands/validate/validators/RP_validators/RP102_details_field_equals_id.py new file mode 100644 index 0000000000..0d306c724c --- /dev/null +++ b/demisto_sdk/commands/validate/validators/RP_validators/RP102_details_field_equals_id.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from typing import Iterable, List + +from demisto_sdk.commands.common.constants import GitStatuses +from demisto_sdk.commands.content_graph.objects.indicator_type import IndicatorType +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = IndicatorType + + +class DetailsFieldEqualsIdValidator(BaseValidator[ContentTypes]): + error_code = "RP102" + description = "Validate that the id and the details fields are equal." + error_message = "id and details fields are not equal. id={0}, details={1}" + rationale = "To align with the platform requirements." + related_field = "id" + expected_git_statuses = [GitStatuses.ADDED] + + def is_valid(self, content_items: Iterable[ContentTypes]) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message.format( + content_item.object_id, content_item.description + ), + content_object=content_item, + ) + for content_item in content_items + if content_item.description != content_item.object_id + ]