From c4006944d6995529909e9d3993236bbc9850dc81 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 21 Sep 2025 13:17:16 +0300 Subject: [PATCH 01/24] added validations for content items --- .../commands/common/schemas/layoutrule.yml | 10 +++- .../commands/common/schemas/trigger.yml | 12 ++++- .../commands/common/schemas/xdrctemplate.yml | 6 ++- .../common/schemas/xsiamdashboard.yml | 6 ++- .../commands/common/schemas/xsiamreport.yml | 10 +++- .../LO101_standardized_fields.py | 46 ++++++++++++++++ .../TR101_standardized_fields.py | 46 ++++++++++++++++ .../XD101_standardized_fields.py | 50 ++++++++++++++++++ .../validators/XD_validators/__init__.py | 0 .../XR101_standardized_fields.py | 52 +++++++++++++++++++ .../validators/XR_validators/__init__.py | 0 .../XT101_standardized_fields.py | 44 ++++++++++++++++ .../validators/XT_validators/__init__.py | 0 13 files changed, 276 insertions(+), 6 deletions(-) create mode 100644 demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py create mode 100644 demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py create mode 100644 demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py create mode 100644 demisto_sdk/commands/validate/validators/XD_validators/__init__.py create mode 100644 demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py create mode 100644 demisto_sdk/commands/validate/validators/XR_validators/__init__.py create mode 100644 demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py create mode 100644 demisto_sdk/commands/validate/validators/XT_validators/__init__.py diff --git a/demisto_sdk/commands/common/schemas/layoutrule.yml b/demisto_sdk/commands/common/schemas/layoutrule.yml index 59a2b24d0ad..6b02025218d 100644 --- a/demisto_sdk/commands/common/schemas/layoutrule.yml +++ b/demisto_sdk/commands/common/schemas/layoutrule.yml @@ -1,11 +1,19 @@ type: map mapping: + id: + type: str + required: true rule_id: + type: str + required: false + # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. + name: type: str required: true rule_name: type: str - required: true + required: false + # DEPRECATED: Use 'name' field instead. This field is kept for backward compatibility with existing content items. layout_id: type: str required: true diff --git a/demisto_sdk/commands/common/schemas/trigger.yml b/demisto_sdk/commands/common/schemas/trigger.yml index 75b60f3685c..310bf34a3e4 100644 --- a/demisto_sdk/commands/common/schemas/trigger.yml +++ b/demisto_sdk/commands/common/schemas/trigger.yml @@ -1,15 +1,23 @@ type: map mapping: - trigger_id: + id: type: str required: true + trigger_id: + type: str + required: false + # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. fromVersion: type: str toVersion: type: str - trigger_name: + name: type: str required: true + trigger_name: + type: str + required: false + # DEPRECATED: Use 'name' field instead. This field is kept for backward compatibility with existing content items. playbook_id: type: str required: true diff --git a/demisto_sdk/commands/common/schemas/xdrctemplate.yml b/demisto_sdk/commands/common/schemas/xdrctemplate.yml index 7b757d5ec37..6a0666a127b 100644 --- a/demisto_sdk/commands/common/schemas/xdrctemplate.yml +++ b/demisto_sdk/commands/common/schemas/xdrctemplate.yml @@ -9,9 +9,13 @@ mapping: name: type: str required: true - content_global_id: + id: type: str required: true + content_global_id: + type: str + required: false + # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. from_xdr_version: type: str required: true diff --git a/demisto_sdk/commands/common/schemas/xsiamdashboard.yml b/demisto_sdk/commands/common/schemas/xsiamdashboard.yml index 99dba0dbf84..0cf6e5e44f9 100644 --- a/demisto_sdk/commands/common/schemas/xsiamdashboard.yml +++ b/demisto_sdk/commands/common/schemas/xsiamdashboard.yml @@ -27,9 +27,13 @@ mapping: schema;dashboards_data_schema: type: map mapping: - global_id: + id: type: str required: true + global_id: + type: str + required: false + # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. status: type: str required: true diff --git a/demisto_sdk/commands/common/schemas/xsiamreport.yml b/demisto_sdk/commands/common/schemas/xsiamreport.yml index d943cd3a1d8..94239c5a9a2 100644 --- a/demisto_sdk/commands/common/schemas/xsiamreport.yml +++ b/demisto_sdk/commands/common/schemas/xsiamreport.yml @@ -19,12 +19,20 @@ schema;templates_data_schema: mapping: metadata: type: str + id: + type: str + required: true global_id: + type: str + required: false + # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. + name: type: str required: true report_name: type: str - required: true + required: false + # DEPRECATED: Use 'name' field instead. This field is kept for backward compatibility with existing content items. report_description: type: str required: false diff --git a/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py b/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py new file mode 100644 index 00000000000..2110c1df086 --- /dev/null +++ b/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.objects import LayoutRule +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[LayoutRule] + + +class LayoutRuleStandardizedFieldsValidator(BaseValidator[ContentTypes]): + error_code = "LO101" + description = "Validate that Layout Rules use standardized 'id' and 'name' fields instead of 'rule_id' and 'rule_name'." + rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." + error_message = "Layout Rules must use 'id' and 'name' fields instead of 'rule_id' and 'rule_name'. Please update your layout rule to use the standardized field names." + related_field = "rule_id, rule_name" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if self.has_non_standard_fields(content_item) + ] + + def has_non_standard_fields(self, content_item: ContentTypes) -> bool: + """Check if the content item uses non-standard field names.""" + data = content_item.data + + # Check for non-standard fields + has_rule_id = "rule_id" in data + has_rule_name = "rule_name" in data + has_standard_id = "id" in data + has_standard_name = "name" in data + + # Invalid if it has old fields but not the corresponding new standard fields + return (has_rule_id and not has_standard_id) or (has_rule_name and not has_standard_name) diff --git a/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py new file mode 100644 index 00000000000..f07a6f072be --- /dev/null +++ b/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py @@ -0,0 +1,46 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.objects.trigger import Trigger +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[Trigger] + + +class TriggerStandardizedFieldsValidator(BaseValidator[ContentTypes]): + error_code = "TR101" + description = "Validate that Triggers use standardized 'id' and 'name' fields instead of 'trigger_id' and 'trigger_name'." + rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." + error_message = "Triggers must use 'id' and 'name' fields instead of 'trigger_id' and 'trigger_name'. Please update your trigger to use the standardized field names." + related_field = "trigger_id, trigger_name" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if self.has_non_standard_fields(content_item) + ] + + def has_non_standard_fields(self, content_item: ContentTypes) -> bool: + """Check if the content item uses non-standard field names.""" + data = content_item.data + + # Check for non-standard fields + has_trigger_id = "trigger_id" in data + has_trigger_name = "trigger_name" in data + has_standard_id = "id" in data + has_standard_name = "name" in data + + # Invalid if it has old fields but not the corresponding new standard fields + return (has_trigger_id and not has_standard_id) or (has_trigger_name and not has_standard_name) diff --git a/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py new file mode 100644 index 00000000000..87eab45fee7 --- /dev/null +++ b/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py @@ -0,0 +1,50 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.objects import XSIAMDashboard +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[XSIAMDashboard] + + +class XSIAMDashboardStandardizedFieldsValidator(BaseValidator[ContentTypes]): + error_code = "XD101" + description = "Validate that XSIAM Dashboards use standardized 'id' field instead of 'global_id' in dashboards_data." + rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." + error_message = "XSIAM Dashboards must use 'id' field instead of 'global_id' in dashboards_data. Please update your dashboard to use the standardized field name." + related_field = "global_id" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if self.has_non_standard_fields(content_item) + ] + + def has_non_standard_fields(self, content_item: ContentTypes) -> bool: + """Check if the content item uses non-standard field names.""" + data = content_item.data + + # Check dashboards_data for non-standard fields + dashboards_data = data.get("dashboards_data", []) + + for dashboard in dashboards_data: + has_global_id = "global_id" in dashboard + has_standard_id = "id" in dashboard + + # Invalid if it has the old field but not the new standard field + if has_global_id and not has_standard_id: + return True + + return False diff --git a/demisto_sdk/commands/validate/validators/XD_validators/__init__.py b/demisto_sdk/commands/validate/validators/XD_validators/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py new file mode 100644 index 00000000000..0781c561228 --- /dev/null +++ b/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.objects import XSIAMReport +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[XSIAMReport] + + +class XSIAMReportStandardizedFieldsValidator(BaseValidator[ContentTypes]): + error_code = "XR101" + description = "Validate that XSIAM Reports use standardized 'id' and 'name' fields instead of 'global_id' and 'report_name' in templates_data." + rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." + error_message = "XSIAM Reports must use 'id' and 'name' fields instead of 'global_id' and 'report_name' in templates_data. Please update your report to use the standardized field names." + related_field = "global_id, report_name" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if self.has_non_standard_fields(content_item) + ] + + def has_non_standard_fields(self, content_item: ContentTypes) -> bool: + """Check if the content item uses non-standard field names.""" + data = content_item.data + + # Check templates_data for non-standard fields + templates_data = data.get("templates_data", []) + + for template in templates_data: + has_global_id = "global_id" in template + has_report_name = "report_name" in template + has_standard_id = "id" in template + has_standard_name = "name" in template + + # Invalid if it has old fields but not the corresponding new standard fields + if (has_global_id and not has_standard_id) or (has_report_name and not has_standard_name): + return True + + return False diff --git a/demisto_sdk/commands/validate/validators/XR_validators/__init__.py b/demisto_sdk/commands/validate/validators/XR_validators/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py new file mode 100644 index 00000000000..e825320cd4a --- /dev/null +++ b/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.objects import XDRCTemplate +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[XDRCTemplate] + + +class XDRCTemplateStandardizedFieldsValidator(BaseValidator[ContentTypes]): + error_code = "XT101" + description = "Validate that XDRCTemplates use standardized 'id' field instead of 'content_global_id'." + rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." + error_message = "XDRCTemplates must use 'id' field instead of 'content_global_id'. Please update your template to use the standardized field name." + related_field = "content_global_id" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if self.has_non_standard_fields(content_item) + ] + + def has_non_standard_fields(self, content_item: ContentTypes) -> bool: + """Check if the content item uses non-standard field names.""" + data = content_item.data + + # Check for non-standard fields + has_content_global_id = "content_global_id" in data + has_standard_id = "id" in data + + # Invalid if it has the old field but not the new standard field + return has_content_global_id and not has_standard_id diff --git a/demisto_sdk/commands/validate/validators/XT_validators/__init__.py b/demisto_sdk/commands/validate/validators/XT_validators/__init__.py new file mode 100644 index 00000000000..e69de29bb2d From a523859398db4afda73a543740cf47f5f83f0600 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 21 Sep 2025 13:17:51 +0300 Subject: [PATCH 02/24] added tests --- .../validate/tests/TR_validators_test.py | 58 ++++++++++++++ .../validate/tests/XT_validators_test.py | 80 +++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100644 demisto_sdk/commands/validate/tests/XT_validators_test.py diff --git a/demisto_sdk/commands/validate/tests/TR_validators_test.py b/demisto_sdk/commands/validate/tests/TR_validators_test.py index 14b447a453d..965872fad9d 100644 --- a/demisto_sdk/commands/validate/tests/TR_validators_test.py +++ b/demisto_sdk/commands/validate/tests/TR_validators_test.py @@ -6,6 +6,9 @@ from demisto_sdk.commands.validate.validators.TR_validators.TR100_is_silent_trigger import ( IsSilentTriggerValidator, ) +from demisto_sdk.commands.validate.validators.TR_validators.TR101_standardized_fields import ( + TriggerStandardizedFieldsValidator, +) @pytest.mark.parametrize( @@ -74,3 +77,58 @@ def test_IsSilentTriggerValidator(name, is_silent, result_len, file_name): [trigger] ) assert result_len == len(invalid_content_items) + + +class TestTriggerStandardizedFieldsValidator: + def test_valid_trigger_with_standard_fields(self): + """Test that trigger with standard 'id' and 'name' fields passes validation.""" + trigger = create_trigger_object() + trigger.data.update({"id": "test-trigger-id", "name": "Test Trigger Name"}) + + validator = TriggerStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([trigger]) + + assert len(results) == 0 + + def test_invalid_trigger_with_old_id_field_only(self): + """Test that trigger with only 'trigger_id' fails validation.""" + trigger = create_trigger_object() + trigger.data.update( + {"trigger_id": "old-trigger-id", "name": "Test Trigger Name"} + ) + + validator = TriggerStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([trigger]) + + assert len(results) == 1 + assert results[0].validator.error_code == "TR101" + + def test_invalid_trigger_with_old_name_field_only(self): + """Test that trigger with only 'trigger_name' fails validation.""" + trigger = create_trigger_object() + trigger.data.update( + {"id": "test-trigger-id", "trigger_name": "Old Trigger Name"} + ) + + validator = TriggerStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([trigger]) + + assert len(results) == 1 + assert results[0].validator.error_code == "TR101" + + def test_valid_trigger_with_both_fields(self): + """Test that trigger with both old and new fields passes validation.""" + trigger = create_trigger_object() + trigger.data.update( + { + "id": "test-trigger-id", + "trigger_id": "old-trigger-id", # Backward compatibility + "name": "Test Trigger Name", + "trigger_name": "Old Trigger Name", # Backward compatibility + } + ) + + validator = TriggerStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([trigger]) + + assert len(results) == 0 diff --git a/demisto_sdk/commands/validate/tests/XT_validators_test.py b/demisto_sdk/commands/validate/tests/XT_validators_test.py new file mode 100644 index 00000000000..1c31083e3e7 --- /dev/null +++ b/demisto_sdk/commands/validate/tests/XT_validators_test.py @@ -0,0 +1,80 @@ +from demisto_sdk.commands.content_graph.objects import XDRCTemplate +from demisto_sdk.commands.validate.validators.XT_validators.XT101_standardized_fields import ( + XDRCTemplateStandardizedFieldsValidator, +) + + +class TestXDRCTemplateStandardizedFieldsValidator: + def test_valid_xdrc_template_with_standard_fields(self): + """Test that XDRC template with standard 'id' field passes validation.""" + content_item = XDRCTemplate.from_dict( + { + "os_type": "windows", + "profile_type": "endpoint", + "name": "Test Template", + "id": "test-template-id", + "from_xdr_version": "1.0.0", + "yaml_template": "template content", + } + ) + + validator = XDRCTemplateStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([content_item]) + + assert len(results) == 0 + + def test_invalid_xdrc_template_with_old_field_only(self): + """Test that XDRC template with only 'content_global_id' fails validation.""" + content_item = XDRCTemplate.from_dict( + { + "os_type": "windows", + "profile_type": "endpoint", + "name": "Test Template", + "content_global_id": "old-global-id", + "from_xdr_version": "1.0.0", + "yaml_template": "template content", + } + ) + + validator = XDRCTemplateStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([content_item]) + + assert len(results) == 1 + assert results[0].validator.error_code == "XT101" + + def test_valid_xdrc_template_with_both_fields(self): + """Test that XDRC template with both old and new fields passes validation.""" + content_item = XDRCTemplate.from_dict( + { + "os_type": "windows", + "profile_type": "endpoint", + "name": "Test Template", + "id": "test-template-id", + "content_global_id": "old-global-id", # Backward compatibility + "from_xdr_version": "1.0.0", + "yaml_template": "template content", + } + ) + + validator = XDRCTemplateStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([content_item]) + + assert len(results) == 0 + + def test_valid_xdrc_template_without_old_field(self): + """Test that XDRC template without old field passes validation.""" + content_item = XDRCTemplate.from_dict( + { + "os_type": "windows", + "profile_type": "endpoint", + "name": "Test Template", + "id": "test-template-id", + "from_xdr_version": "1.0.0", + "yaml_template": "template content", + } + ) + + validator = XDRCTemplateStandardizedFieldsValidator() + results = validator.obtain_invalid_content_items([content_item]) + + assert len(results) == 0 From f99a95786c4e4e9f85649c5900ce71548255d331 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 21 Sep 2025 14:38:46 +0300 Subject: [PATCH 03/24] fixed tests --- .../commands/common/tests/layout_rule_test.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/demisto_sdk/commands/common/tests/layout_rule_test.py b/demisto_sdk/commands/common/tests/layout_rule_test.py index 22a8b0e6160..426a940cbf1 100644 --- a/demisto_sdk/commands/common/tests/layout_rule_test.py +++ b/demisto_sdk/commands/common/tests/layout_rule_test.py @@ -14,10 +14,10 @@ def test_is_valid_file(repo): dummy_layout_rule = pack.create_layout_rule( "MyRule", { - "rule_id": "test_rule", + "id": "test_rule", "layout_id": "test_layout_id", "description": "This trigger is test", - "rule_name": "test rule name", + "name": "test rule name", "alerts_filter": { "filter": { "AND": [ @@ -50,10 +50,10 @@ def test_is_valid_file_complicated_schema(repo): dummy_layout_rule = pack.create_layout_rule( "MyRule", { - "rule_id": "test_rule", + "id": "test_rule", "layout_id": "test_layout_id", "description": "This trigger is test", - "rule_name": "test rule name", + "name": "test rule name", "alerts_filter": { "filter": { "OR": [ @@ -109,10 +109,10 @@ def test_is_not_valid_file_complicated_schema(repo): dummy_layout_rule = pack.create_layout_rule( "MyRule", { - "rule_id": "test_rule", + "id": "test_rule", "layout_id": "test_layout_id", "description": "This trigger is test", - "rule_name": "test rule name", + "name": "test rule name", "alerts_filter": { "filter": { "OR": [ From 061ac529cec74ef13fcdef0270a9f20183e1cd48 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 21 Sep 2025 15:40:03 +0300 Subject: [PATCH 04/24] fixed tests --- .../validate/tests/XT_validators_test.py | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/demisto_sdk/commands/validate/tests/XT_validators_test.py b/demisto_sdk/commands/validate/tests/XT_validators_test.py index 1c31083e3e7..c413ea0d5a3 100644 --- a/demisto_sdk/commands/validate/tests/XT_validators_test.py +++ b/demisto_sdk/commands/validate/tests/XT_validators_test.py @@ -1,4 +1,6 @@ -from demisto_sdk.commands.content_graph.objects import XDRCTemplate +from demisto_sdk.commands.validate.tests.test_tools import ( + create_xdrc_template_object, +) from demisto_sdk.commands.validate.validators.XT_validators.XT101_standardized_fields import ( XDRCTemplateStandardizedFieldsValidator, ) @@ -6,8 +8,19 @@ class TestXDRCTemplateStandardizedFieldsValidator: def test_valid_xdrc_template_with_standard_fields(self): - """Test that XDRC template with standard 'id' field passes validation.""" - content_item = XDRCTemplate.from_dict( + """ + Given + an XDRC template that contains only the standard "id" field (no deprecated field). + When + - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. + Then + - No validation errors are returned (length 0). + """ + content_item = create_xdrc_template_object() + # Ensure only the standard field exists + data = content_item.data + data.pop("content_global_id", None) + data.update( { "os_type": "windows", "profile_type": "endpoint", @@ -24,8 +37,18 @@ def test_valid_xdrc_template_with_standard_fields(self): assert len(results) == 0 def test_invalid_xdrc_template_with_old_field_only(self): - """Test that XDRC template with only 'content_global_id' fails validation.""" - content_item = XDRCTemplate.from_dict( + """ + Given + an XDRC template that contains only the deprecated "content_global_id" (no standard "id"). + When + - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. + Then + - One validation error is returned with error code XT101. + """ + content_item = create_xdrc_template_object() + data = content_item.data + data.pop("id", None) + data.update( { "os_type": "windows", "profile_type": "endpoint", @@ -43,8 +66,17 @@ def test_invalid_xdrc_template_with_old_field_only(self): assert results[0].validator.error_code == "XT101" def test_valid_xdrc_template_with_both_fields(self): - """Test that XDRC template with both old and new fields passes validation.""" - content_item = XDRCTemplate.from_dict( + """ + Given + an XDRC template that contains both the deprecated "content_global_id" and standard "id". + When + - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. + Then + - No validation errors are returned (backward compatibility is allowed). + """ + content_item = create_xdrc_template_object() + data = content_item.data + data.update( { "os_type": "windows", "profile_type": "endpoint", @@ -62,8 +94,18 @@ def test_valid_xdrc_template_with_both_fields(self): assert len(results) == 0 def test_valid_xdrc_template_without_old_field(self): - """Test that XDRC template without old field passes validation.""" - content_item = XDRCTemplate.from_dict( + """ + Given + an XDRC template that contains the standard "id" and does not contain the deprecated field. + When + - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. + Then + - No validation errors are returned. + """ + content_item = create_xdrc_template_object() + data = content_item.data + data.pop("content_global_id", None) + data.update( { "os_type": "windows", "profile_type": "endpoint", From d023ed6f3d43290ef535ffaaa8fe72ee53359e42 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Thu, 25 Sep 2025 15:04:51 +0300 Subject: [PATCH 05/24] added changelog, fixed pre-commit --- .changelog/5079.yml | 4 ++++ .../validators/LO_validators/LO101_standardized_fields.py | 4 +++- .../validators/TR_validators/TR101_standardized_fields.py | 4 +++- .../validators/XR_validators/XR101_standardized_fields.py | 4 +++- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .changelog/5079.yml diff --git a/.changelog/5079.yml b/.changelog/5079.yml new file mode 100644 index 00000000000..c80a3114462 --- /dev/null +++ b/.changelog/5079.yml @@ -0,0 +1,4 @@ +changes: +- description: enter description about this PR + type: internal +pr_number: 5079 diff --git a/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py b/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py index 2110c1df086..7ea2629bed8 100644 --- a/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py +++ b/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py @@ -43,4 +43,6 @@ def has_non_standard_fields(self, content_item: ContentTypes) -> bool: has_standard_name = "name" in data # Invalid if it has old fields but not the corresponding new standard fields - return (has_rule_id and not has_standard_id) or (has_rule_name and not has_standard_name) + return (has_rule_id and not has_standard_id) or ( + has_rule_name and not has_standard_name + ) diff --git a/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py index f07a6f072be..3f4f640433a 100644 --- a/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py +++ b/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py @@ -43,4 +43,6 @@ def has_non_standard_fields(self, content_item: ContentTypes) -> bool: has_standard_name = "name" in data # Invalid if it has old fields but not the corresponding new standard fields - return (has_trigger_id and not has_standard_id) or (has_trigger_name and not has_standard_name) + return (has_trigger_id and not has_standard_id) or ( + has_trigger_name and not has_standard_name + ) diff --git a/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py index 0781c561228..cce02860752 100644 --- a/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py +++ b/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py @@ -46,7 +46,9 @@ def has_non_standard_fields(self, content_item: ContentTypes) -> bool: has_standard_name = "name" in template # Invalid if it has old fields but not the corresponding new standard fields - if (has_global_id and not has_standard_id) or (has_report_name and not has_standard_name): + if (has_global_id and not has_standard_id) or ( + has_report_name and not has_standard_name + ): return True return False From dbe552d01e4391308c78a5e213f526bab2a7e557 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Thu, 25 Sep 2025 15:15:00 +0300 Subject: [PATCH 06/24] fixed changelog --- .changelog/5079.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/5079.yml b/.changelog/5079.yml index c80a3114462..13bcca5c64e 100644 --- a/.changelog/5079.yml +++ b/.changelog/5079.yml @@ -1,4 +1,4 @@ changes: -- description: enter description about this PR +- description: Add validators to enforce standardized id/name fields. type: internal pr_number: 5079 From 058c0872976fda7ae57aa779ac9884e56636c1fb Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 28 Sep 2025 14:51:26 +0300 Subject: [PATCH 07/24] added valid. to sdk valid. congig --- .../commands/validate/sdk_validation_config.toml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index 49ccbf975a1..2260788d109 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -251,7 +251,12 @@ select = [ "TR100", "VC100", "VC101", - "BC115" + "BC115", + "XT101", + "LO101", + "XR101", + "TR101", + "XD101" ] warning = [ "RM108" @@ -538,7 +543,12 @@ select = [ "LO107", "VC100", "VC101", - "BA112" + "BA112", + "XT101", + "LO101", + "XR101", + "TR101", + "XD101" ] warning = [ "GR109" From 0e6733b7a2ab347f7b1158434a66be05110f474c Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 28 Sep 2025 15:14:39 +0300 Subject: [PATCH 08/24] fix tests --- TestSuite/trigger.py | 7 +++++++ TestSuite/xdrc_template.py | 1 + 2 files changed, 8 insertions(+) diff --git a/TestSuite/trigger.py b/TestSuite/trigger.py index 38f23ecdecf..b89bb4f9e7f 100644 --- a/TestSuite/trigger.py +++ b/TestSuite/trigger.py @@ -11,6 +11,11 @@ def __init__(self, name: str, trigger_dir_path: Path, json_content: dict = None) super().__init__(trigger_dir_path, name, "") if json_content: + # Ensure standardized required fields exist per schemas/trigger.yml + if "id" not in json_content: + json_content["id"] = json_content.get("trigger_id", self.id) + if "name" not in json_content: + json_content["name"] = json_content.get("trigger_name", self.id) self.write_json(json_content) else: self.create_default_trigger() @@ -18,7 +23,9 @@ def __init__(self, name: str, trigger_dir_path: Path, json_content: dict = None) def create_default_trigger(self): self.write_json( { + "id": self.id, "trigger_id": self.id, + "name": self.id, "playbook_id": "mock playbook", "suggestion_reason": "mock reason", "description": "desc", diff --git a/TestSuite/xdrc_template.py b/TestSuite/xdrc_template.py index 01e07c0d232..247910d41dd 100644 --- a/TestSuite/xdrc_template.py +++ b/TestSuite/xdrc_template.py @@ -32,6 +32,7 @@ def write_dict(self, yml: dict): def create_default(self): self.write_json( { + "id": self.id, "content_global_id": self.id, "name": self.id, "os_type": "os_type_test", From 6c53cd9f78e89db1e91a8786a98fa4a375dfe04f Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 28 Sep 2025 15:55:49 +0300 Subject: [PATCH 09/24] fix tests --- TestSuite/trigger.py | 6 +----- TestSuite/xsiam_report.py | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/TestSuite/trigger.py b/TestSuite/trigger.py index b89bb4f9e7f..0b2b659c429 100644 --- a/TestSuite/trigger.py +++ b/TestSuite/trigger.py @@ -11,11 +11,7 @@ def __init__(self, name: str, trigger_dir_path: Path, json_content: dict = None) super().__init__(trigger_dir_path, name, "") if json_content: - # Ensure standardized required fields exist per schemas/trigger.yml - if "id" not in json_content: - json_content["id"] = json_content.get("trigger_id", self.id) - if "name" not in json_content: - json_content["name"] = json_content.get("trigger_name", self.id) + # Write exactly what the test provided; do not auto-normalize. self.write_json(json_content) else: self.create_default_trigger() diff --git a/TestSuite/xsiam_report.py b/TestSuite/xsiam_report.py index de5f36480cc..ab4839f34b7 100644 --- a/TestSuite/xsiam_report.py +++ b/TestSuite/xsiam_report.py @@ -17,7 +17,9 @@ def create_default(self): { "templates_data": [ { + "id": self.id, "global_id": self.id, + "name": self.id, "report_name": self.id, "report_description": None, "default_template_id": None, From ded58fa4709a716a86f736f7968fb2ae7b1144f9 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 28 Sep 2025 16:49:01 +0300 Subject: [PATCH 10/24] fix tests --- TestSuite/layout_rule.py | 2 ++ TestSuite/xsiam_dashboard.py | 1 + 2 files changed, 3 insertions(+) diff --git a/TestSuite/layout_rule.py b/TestSuite/layout_rule.py index e81c580ae12..1091e01d67f 100644 --- a/TestSuite/layout_rule.py +++ b/TestSuite/layout_rule.py @@ -21,7 +21,9 @@ def __init__( def create_default_layout_rule(self): self.write_json( { + "id": self.rule_id, "rule_id": self.rule_id, + "name": self.name, "rule_name": self.name, "layout_id": "test_layout", "description": "", diff --git a/TestSuite/xsiam_dashboard.py b/TestSuite/xsiam_dashboard.py index 6d94b0c5e1f..71b476aeceb 100644 --- a/TestSuite/xsiam_dashboard.py +++ b/TestSuite/xsiam_dashboard.py @@ -17,6 +17,7 @@ def create_default(self): { "dashboards_data": [ { + "id": self.id, "name": self.id, "description": "mock dashboard desc", "status": "ENABLED", From 818e513b785ecbc3c16c94df1c8a7371aab1c061 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Mon, 29 Sep 2025 14:04:03 +0300 Subject: [PATCH 11/24] fix tests --- demisto_sdk/commands/common/schemas/trigger.yml | 4 ++-- demisto_sdk/commands/common/schemas/xsiamreport.yml | 2 +- demisto_sdk/commands/validate/sdk_validation_config.toml | 7 +------ 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/demisto_sdk/commands/common/schemas/trigger.yml b/demisto_sdk/commands/common/schemas/trigger.yml index 310bf34a3e4..b914f487945 100644 --- a/demisto_sdk/commands/common/schemas/trigger.yml +++ b/demisto_sdk/commands/common/schemas/trigger.yml @@ -2,7 +2,7 @@ type: map mapping: id: type: str - required: true + required: false trigger_id: type: str required: false @@ -13,7 +13,7 @@ mapping: type: str name: type: str - required: true + required: false trigger_name: type: str required: false diff --git a/demisto_sdk/commands/common/schemas/xsiamreport.yml b/demisto_sdk/commands/common/schemas/xsiamreport.yml index 94239c5a9a2..3377cab5cab 100644 --- a/demisto_sdk/commands/common/schemas/xsiamreport.yml +++ b/demisto_sdk/commands/common/schemas/xsiamreport.yml @@ -24,7 +24,7 @@ schema;templates_data_schema: required: true global_id: type: str - required: false + required: true # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. name: type: str diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index 2260788d109..157a67db550 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -251,12 +251,7 @@ select = [ "TR100", "VC100", "VC101", - "BC115", - "XT101", - "LO101", - "XR101", - "TR101", - "XD101" + "BC115" ] warning = [ "RM108" From 69eaccf9a749a0173ebb80d3ec5bea14cc9ba9ab Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Thu, 20 Nov 2025 15:39:33 +0200 Subject: [PATCH 12/24] add id to dashboarddata --- .../commands/content_graph/strict_objects/xsiam_dashboard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py b/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py index f774a603ce6..fc10053cdc9 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py +++ b/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py @@ -35,6 +35,7 @@ class _Layout(BaseStrictModel): class _DashboardsData(BaseStrictModel): global_id: str + id: str status: str name: str description: Optional[str] = None From 56eec1f22ac6d8dc7f5d467a68933f224b8de504 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Thu, 20 Nov 2025 17:16:56 +0200 Subject: [PATCH 13/24] added id and name to content items --- .../commands/content_graph/strict_objects/layout_rule.py | 6 ++++-- .../commands/content_graph/strict_objects/trigger.py | 6 ++++-- .../commands/content_graph/strict_objects/xdrc_template.py | 5 ++++- .../content_graph/strict_objects/xsiam_dashboard.py | 2 +- .../commands/content_graph/strict_objects/xsiam_report.py | 6 ++++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/demisto_sdk/commands/content_graph/strict_objects/layout_rule.py b/demisto_sdk/commands/content_graph/strict_objects/layout_rule.py index 87c3ca3ba79..dd10bb31f53 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/layout_rule.py +++ b/demisto_sdk/commands/content_graph/strict_objects/layout_rule.py @@ -14,8 +14,10 @@ class _StrictLayoutRule(BaseStrictModel): - rule_id: str - rule_name: str + rule_id: Optional[str] = None + id: str + rule_name: Optional[str] = None + name: str layout_id: str from_version: str = Field( alias="fromVersion" diff --git a/demisto_sdk/commands/content_graph/strict_objects/trigger.py b/demisto_sdk/commands/content_graph/strict_objects/trigger.py index 9d334c0987f..fdf9c887d14 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/trigger.py +++ b/demisto_sdk/commands/content_graph/strict_objects/trigger.py @@ -12,8 +12,10 @@ class _StrictTrigger(BaseStrictModel): - trigger_id: str - trigger_name: str + trigger_id: Optional[str] = None + id: str + trigger_name: Optional[str] = None + name: str playbook_id: str description: str suggestion_reason: str diff --git a/demisto_sdk/commands/content_graph/strict_objects/xdrc_template.py b/demisto_sdk/commands/content_graph/strict_objects/xdrc_template.py index f0733c26668..7cdb119b1b5 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/xdrc_template.py +++ b/demisto_sdk/commands/content_graph/strict_objects/xdrc_template.py @@ -1,3 +1,5 @@ +from typing import Optional + from demisto_sdk.commands.content_graph.strict_objects.base_strict_model import ( BaseOptionalVersionJson, ) @@ -12,7 +14,8 @@ class _StrictXDRCTemplate(BaseStrictModel): os_type: str profile_type: str name: str - content_global_id: str + content_global_id: Optional[str] = None + id: str from_xdr_version: str yaml_template: str diff --git a/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py b/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py index fc10053cdc9..452770ce7cd 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py +++ b/demisto_sdk/commands/content_graph/strict_objects/xsiam_dashboard.py @@ -34,7 +34,7 @@ class _Layout(BaseStrictModel): class _DashboardsData(BaseStrictModel): - global_id: str + global_id: Optional[str] = None id: str status: str name: str diff --git a/demisto_sdk/commands/content_graph/strict_objects/xsiam_report.py b/demisto_sdk/commands/content_graph/strict_objects/xsiam_report.py index a1459c7e222..1f6424fadf2 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/xsiam_report.py +++ b/demisto_sdk/commands/content_graph/strict_objects/xsiam_report.py @@ -38,8 +38,10 @@ class TimeFrame(BaseStrictModel): class TemplatesData(BaseStrictModel): metadata: Optional[str] = None - global_id: str - report_name: str + global_id: Optional[str] = None + id: str + report_name: Optional[str] = None + name: str report_description: Optional[str] = None default_template_id: Optional[int] = None time_frame: Optional[TimeFrame] = None From e4a2eaa25e576aaa170e4052848c0ee9b07a7e35 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Thu, 20 Nov 2025 18:08:35 +0200 Subject: [PATCH 14/24] fix --- demisto_sdk/commands/common/schemas/trigger.yml | 4 ++-- demisto_sdk/commands/common/schemas/xsiamreport.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demisto_sdk/commands/common/schemas/trigger.yml b/demisto_sdk/commands/common/schemas/trigger.yml index 1c995b26a5a..87be3d9ac7d 100644 --- a/demisto_sdk/commands/common/schemas/trigger.yml +++ b/demisto_sdk/commands/common/schemas/trigger.yml @@ -6,7 +6,7 @@ mapping: type: str id: type: str - required: false + required: true trigger_id: type: str required: false @@ -17,7 +17,7 @@ mapping: type: str name: type: str - required: false + required: true trigger_name: type: str required: false diff --git a/demisto_sdk/commands/common/schemas/xsiamreport.yml b/demisto_sdk/commands/common/schemas/xsiamreport.yml index 3377cab5cab..94239c5a9a2 100644 --- a/demisto_sdk/commands/common/schemas/xsiamreport.yml +++ b/demisto_sdk/commands/common/schemas/xsiamreport.yml @@ -24,7 +24,7 @@ schema;templates_data_schema: required: true global_id: type: str - required: true + required: false # DEPRECATED: Use 'id' field instead. This field is kept for backward compatibility with existing content items. name: type: str From 7de453be127488b5853f9689c46c002684c25096 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 11:15:36 +0200 Subject: [PATCH 15/24] fix tests --- demisto_sdk/commands/common/tests/structure_test.py | 6 +++--- demisto_sdk/commands/common/tests/trigger_test.py | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/demisto_sdk/commands/common/tests/structure_test.py b/demisto_sdk/commands/common/tests/structure_test.py index cf8326b4aa7..1e7bd4c121e 100644 --- a/demisto_sdk/commands/common/tests/structure_test.py +++ b/demisto_sdk/commands/common/tests/structure_test.py @@ -945,17 +945,17 @@ def test_valid_xsiam_report(self, pack: Pack): validator = StructureValidator(xsiam_report.path) assert validator.is_valid_scheme() - def test_invalid_xsiam_report_missing_global_id(self, pack: Pack): + def test_invalid_xsiam_report_missing_id(self, pack: Pack): """ Given: - An invalid XSIAM report with a missing global_id field + An invalid XSIAM report with a missing id field When: Running schema validation. Then: Make sure the schema is invalid. """ xsiam_report = pack.create_xsiam_report("xsiam_report") - xsiam_report.remove_field_by_path("templates_data.[0].global_id") + xsiam_report.remove_field_by_path("templates_data.[0].id") validator = StructureValidator(xsiam_report.path) assert not validator.is_valid_scheme() diff --git a/demisto_sdk/commands/common/tests/trigger_test.py b/demisto_sdk/commands/common/tests/trigger_test.py index b3bb09926d6..a86c16c521f 100644 --- a/demisto_sdk/commands/common/tests/trigger_test.py +++ b/demisto_sdk/commands/common/tests/trigger_test.py @@ -13,11 +13,11 @@ def test_is_valid_file(repo): dummy_trigger = pack.create_trigger( "MyTrigger", { - "trigger_id": "trigger_id", + "id": "trigger_id", "playbook_id": "playbook_id", "suggestion_reason": "Reason", "description": "Description", - "trigger_name": "trigger_name", + "name": "trigger_name", "alerts_filter": { "filter": { "AND": [ @@ -48,11 +48,11 @@ def test_is_valid_file_complicated_schema(repo): dummy_trigger = pack.create_trigger( "MyTrigger", { - "trigger_id": "trigger_id", + "id": "trigger_id", "playbook_id": "playbook_id", "suggestion_reason": "Reason", "description": "Description", - "trigger_name": "trigger_name", + "name": "trigger_name", "alerts_filter": { "filter": { "OR": [ @@ -106,10 +106,12 @@ def test_is_not_valid_file_complicated_schema(repo): dummy_trigger = pack.create_trigger( "MyTrigger", { + "id": "trigger_id", "trigger_id": "trigger_id", "playbook_id": "playbook_id", "suggestion_reason": "Reason", "description": "Description", + "name": "trigger_name", "trigger_name": "trigger_name", "alerts_filter": { "filter": { From c56e05ef919d56b6dca786fa954617597f8c5f8f Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 11:45:59 +0200 Subject: [PATCH 16/24] remove all validations --- .../validate/sdk_validation_config.toml | 7 +- .../validate/tests/TR_validators_test.py | 57 -------- .../validate/tests/XT_validators_test.py | 122 ------------------ .../LO101_standardized_fields.py | 48 ------- .../TR101_standardized_fields.py | 48 ------- .../XD101_standardized_fields.py | 50 ------- .../validators/XD_validators/__init__.py | 0 .../XR101_standardized_fields.py | 54 -------- .../validators/XR_validators/__init__.py | 0 .../XT101_standardized_fields.py | 44 ------- .../validators/XT_validators/__init__.py | 0 11 files changed, 1 insertion(+), 429 deletions(-) delete mode 100644 demisto_sdk/commands/validate/tests/XT_validators_test.py delete mode 100644 demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py delete mode 100644 demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py delete mode 100644 demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py delete mode 100644 demisto_sdk/commands/validate/validators/XD_validators/__init__.py delete mode 100644 demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py delete mode 100644 demisto_sdk/commands/validate/validators/XR_validators/__init__.py delete mode 100644 demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py delete mode 100644 demisto_sdk/commands/validate/validators/XT_validators/__init__.py diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index 3b23cf7c616..e2ba8e98cf8 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -543,12 +543,7 @@ select = [ "LO107", "VC100", "VC101", - "BA112", - "XT101", - "LO101", - "XR101", - "TR101", - "XD101" + "BA112" ] warning = [ "GR109", diff --git a/demisto_sdk/commands/validate/tests/TR_validators_test.py b/demisto_sdk/commands/validate/tests/TR_validators_test.py index 965872fad9d..6be429e4d4e 100644 --- a/demisto_sdk/commands/validate/tests/TR_validators_test.py +++ b/demisto_sdk/commands/validate/tests/TR_validators_test.py @@ -6,9 +6,6 @@ from demisto_sdk.commands.validate.validators.TR_validators.TR100_is_silent_trigger import ( IsSilentTriggerValidator, ) -from demisto_sdk.commands.validate.validators.TR_validators.TR101_standardized_fields import ( - TriggerStandardizedFieldsValidator, -) @pytest.mark.parametrize( @@ -78,57 +75,3 @@ def test_IsSilentTriggerValidator(name, is_silent, result_len, file_name): ) assert result_len == len(invalid_content_items) - -class TestTriggerStandardizedFieldsValidator: - def test_valid_trigger_with_standard_fields(self): - """Test that trigger with standard 'id' and 'name' fields passes validation.""" - trigger = create_trigger_object() - trigger.data.update({"id": "test-trigger-id", "name": "Test Trigger Name"}) - - validator = TriggerStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([trigger]) - - assert len(results) == 0 - - def test_invalid_trigger_with_old_id_field_only(self): - """Test that trigger with only 'trigger_id' fails validation.""" - trigger = create_trigger_object() - trigger.data.update( - {"trigger_id": "old-trigger-id", "name": "Test Trigger Name"} - ) - - validator = TriggerStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([trigger]) - - assert len(results) == 1 - assert results[0].validator.error_code == "TR101" - - def test_invalid_trigger_with_old_name_field_only(self): - """Test that trigger with only 'trigger_name' fails validation.""" - trigger = create_trigger_object() - trigger.data.update( - {"id": "test-trigger-id", "trigger_name": "Old Trigger Name"} - ) - - validator = TriggerStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([trigger]) - - assert len(results) == 1 - assert results[0].validator.error_code == "TR101" - - def test_valid_trigger_with_both_fields(self): - """Test that trigger with both old and new fields passes validation.""" - trigger = create_trigger_object() - trigger.data.update( - { - "id": "test-trigger-id", - "trigger_id": "old-trigger-id", # Backward compatibility - "name": "Test Trigger Name", - "trigger_name": "Old Trigger Name", # Backward compatibility - } - ) - - validator = TriggerStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([trigger]) - - assert len(results) == 0 diff --git a/demisto_sdk/commands/validate/tests/XT_validators_test.py b/demisto_sdk/commands/validate/tests/XT_validators_test.py deleted file mode 100644 index c413ea0d5a3..00000000000 --- a/demisto_sdk/commands/validate/tests/XT_validators_test.py +++ /dev/null @@ -1,122 +0,0 @@ -from demisto_sdk.commands.validate.tests.test_tools import ( - create_xdrc_template_object, -) -from demisto_sdk.commands.validate.validators.XT_validators.XT101_standardized_fields import ( - XDRCTemplateStandardizedFieldsValidator, -) - - -class TestXDRCTemplateStandardizedFieldsValidator: - def test_valid_xdrc_template_with_standard_fields(self): - """ - Given - an XDRC template that contains only the standard "id" field (no deprecated field). - When - - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. - Then - - No validation errors are returned (length 0). - """ - content_item = create_xdrc_template_object() - # Ensure only the standard field exists - data = content_item.data - data.pop("content_global_id", None) - data.update( - { - "os_type": "windows", - "profile_type": "endpoint", - "name": "Test Template", - "id": "test-template-id", - "from_xdr_version": "1.0.0", - "yaml_template": "template content", - } - ) - - validator = XDRCTemplateStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([content_item]) - - assert len(results) == 0 - - def test_invalid_xdrc_template_with_old_field_only(self): - """ - Given - an XDRC template that contains only the deprecated "content_global_id" (no standard "id"). - When - - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. - Then - - One validation error is returned with error code XT101. - """ - content_item = create_xdrc_template_object() - data = content_item.data - data.pop("id", None) - data.update( - { - "os_type": "windows", - "profile_type": "endpoint", - "name": "Test Template", - "content_global_id": "old-global-id", - "from_xdr_version": "1.0.0", - "yaml_template": "template content", - } - ) - - validator = XDRCTemplateStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([content_item]) - - assert len(results) == 1 - assert results[0].validator.error_code == "XT101" - - def test_valid_xdrc_template_with_both_fields(self): - """ - Given - an XDRC template that contains both the deprecated "content_global_id" and standard "id". - When - - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. - Then - - No validation errors are returned (backward compatibility is allowed). - """ - content_item = create_xdrc_template_object() - data = content_item.data - data.update( - { - "os_type": "windows", - "profile_type": "endpoint", - "name": "Test Template", - "id": "test-template-id", - "content_global_id": "old-global-id", # Backward compatibility - "from_xdr_version": "1.0.0", - "yaml_template": "template content", - } - ) - - validator = XDRCTemplateStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([content_item]) - - assert len(results) == 0 - - def test_valid_xdrc_template_without_old_field(self): - """ - Given - an XDRC template that contains the standard "id" and does not contain the deprecated field. - When - - Calling XDRCTemplateStandardizedFieldsValidator.obtain_invalid_content_items. - Then - - No validation errors are returned. - """ - content_item = create_xdrc_template_object() - data = content_item.data - data.pop("content_global_id", None) - data.update( - { - "os_type": "windows", - "profile_type": "endpoint", - "name": "Test Template", - "id": "test-template-id", - "from_xdr_version": "1.0.0", - "yaml_template": "template content", - } - ) - - validator = XDRCTemplateStandardizedFieldsValidator() - results = validator.obtain_invalid_content_items([content_item]) - - assert len(results) == 0 diff --git a/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py b/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py deleted file mode 100644 index 7ea2629bed8..00000000000 --- a/demisto_sdk/commands/validate/validators/LO_validators/LO101_standardized_fields.py +++ /dev/null @@ -1,48 +0,0 @@ -from __future__ import annotations - -from typing import Iterable, List, Union - -from demisto_sdk.commands.content_graph.objects import LayoutRule -from demisto_sdk.commands.validate.validators.base_validator import ( - BaseValidator, - ValidationResult, -) - -ContentTypes = Union[LayoutRule] - - -class LayoutRuleStandardizedFieldsValidator(BaseValidator[ContentTypes]): - error_code = "LO101" - description = "Validate that Layout Rules use standardized 'id' and 'name' fields instead of 'rule_id' and 'rule_name'." - rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." - error_message = "Layout Rules must use 'id' and 'name' fields instead of 'rule_id' and 'rule_name'. Please update your layout rule to use the standardized field names." - related_field = "rule_id, rule_name" - is_auto_fixable = False - - def obtain_invalid_content_items( - self, content_items: Iterable[ContentTypes] - ) -> List[ValidationResult]: - return [ - ValidationResult( - validator=self, - message=self.error_message, - content_object=content_item, - ) - for content_item in content_items - if self.has_non_standard_fields(content_item) - ] - - def has_non_standard_fields(self, content_item: ContentTypes) -> bool: - """Check if the content item uses non-standard field names.""" - data = content_item.data - - # Check for non-standard fields - has_rule_id = "rule_id" in data - has_rule_name = "rule_name" in data - has_standard_id = "id" in data - has_standard_name = "name" in data - - # Invalid if it has old fields but not the corresponding new standard fields - return (has_rule_id and not has_standard_id) or ( - has_rule_name and not has_standard_name - ) diff --git a/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py deleted file mode 100644 index 3f4f640433a..00000000000 --- a/demisto_sdk/commands/validate/validators/TR_validators/TR101_standardized_fields.py +++ /dev/null @@ -1,48 +0,0 @@ -from __future__ import annotations - -from typing import Iterable, List, Union - -from demisto_sdk.commands.content_graph.objects.trigger import Trigger -from demisto_sdk.commands.validate.validators.base_validator import ( - BaseValidator, - ValidationResult, -) - -ContentTypes = Union[Trigger] - - -class TriggerStandardizedFieldsValidator(BaseValidator[ContentTypes]): - error_code = "TR101" - description = "Validate that Triggers use standardized 'id' and 'name' fields instead of 'trigger_id' and 'trigger_name'." - rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." - error_message = "Triggers must use 'id' and 'name' fields instead of 'trigger_id' and 'trigger_name'. Please update your trigger to use the standardized field names." - related_field = "trigger_id, trigger_name" - is_auto_fixable = False - - def obtain_invalid_content_items( - self, content_items: Iterable[ContentTypes] - ) -> List[ValidationResult]: - return [ - ValidationResult( - validator=self, - message=self.error_message, - content_object=content_item, - ) - for content_item in content_items - if self.has_non_standard_fields(content_item) - ] - - def has_non_standard_fields(self, content_item: ContentTypes) -> bool: - """Check if the content item uses non-standard field names.""" - data = content_item.data - - # Check for non-standard fields - has_trigger_id = "trigger_id" in data - has_trigger_name = "trigger_name" in data - has_standard_id = "id" in data - has_standard_name = "name" in data - - # Invalid if it has old fields but not the corresponding new standard fields - return (has_trigger_id and not has_standard_id) or ( - has_trigger_name and not has_standard_name - ) diff --git a/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py deleted file mode 100644 index 87eab45fee7..00000000000 --- a/demisto_sdk/commands/validate/validators/XD_validators/XD101_standardized_fields.py +++ /dev/null @@ -1,50 +0,0 @@ -from __future__ import annotations - -from typing import Iterable, List, Union - -from demisto_sdk.commands.content_graph.objects import XSIAMDashboard -from demisto_sdk.commands.validate.validators.base_validator import ( - BaseValidator, - ValidationResult, -) - -ContentTypes = Union[XSIAMDashboard] - - -class XSIAMDashboardStandardizedFieldsValidator(BaseValidator[ContentTypes]): - error_code = "XD101" - description = "Validate that XSIAM Dashboards use standardized 'id' field instead of 'global_id' in dashboards_data." - rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." - error_message = "XSIAM Dashboards must use 'id' field instead of 'global_id' in dashboards_data. Please update your dashboard to use the standardized field name." - related_field = "global_id" - is_auto_fixable = False - - def obtain_invalid_content_items( - self, content_items: Iterable[ContentTypes] - ) -> List[ValidationResult]: - return [ - ValidationResult( - validator=self, - message=self.error_message, - content_object=content_item, - ) - for content_item in content_items - if self.has_non_standard_fields(content_item) - ] - - def has_non_standard_fields(self, content_item: ContentTypes) -> bool: - """Check if the content item uses non-standard field names.""" - data = content_item.data - - # Check dashboards_data for non-standard fields - dashboards_data = data.get("dashboards_data", []) - - for dashboard in dashboards_data: - has_global_id = "global_id" in dashboard - has_standard_id = "id" in dashboard - - # Invalid if it has the old field but not the new standard field - if has_global_id and not has_standard_id: - return True - - return False diff --git a/demisto_sdk/commands/validate/validators/XD_validators/__init__.py b/demisto_sdk/commands/validate/validators/XD_validators/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py deleted file mode 100644 index cce02860752..00000000000 --- a/demisto_sdk/commands/validate/validators/XR_validators/XR101_standardized_fields.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import annotations - -from typing import Iterable, List, Union - -from demisto_sdk.commands.content_graph.objects import XSIAMReport -from demisto_sdk.commands.validate.validators.base_validator import ( - BaseValidator, - ValidationResult, -) - -ContentTypes = Union[XSIAMReport] - - -class XSIAMReportStandardizedFieldsValidator(BaseValidator[ContentTypes]): - error_code = "XR101" - description = "Validate that XSIAM Reports use standardized 'id' and 'name' fields instead of 'global_id' and 'report_name' in templates_data." - rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." - error_message = "XSIAM Reports must use 'id' and 'name' fields instead of 'global_id' and 'report_name' in templates_data. Please update your report to use the standardized field names." - related_field = "global_id, report_name" - is_auto_fixable = False - - def obtain_invalid_content_items( - self, content_items: Iterable[ContentTypes] - ) -> List[ValidationResult]: - return [ - ValidationResult( - validator=self, - message=self.error_message, - content_object=content_item, - ) - for content_item in content_items - if self.has_non_standard_fields(content_item) - ] - - def has_non_standard_fields(self, content_item: ContentTypes) -> bool: - """Check if the content item uses non-standard field names.""" - data = content_item.data - - # Check templates_data for non-standard fields - templates_data = data.get("templates_data", []) - - for template in templates_data: - has_global_id = "global_id" in template - has_report_name = "report_name" in template - has_standard_id = "id" in template - has_standard_name = "name" in template - - # Invalid if it has old fields but not the corresponding new standard fields - if (has_global_id and not has_standard_id) or ( - has_report_name and not has_standard_name - ): - return True - - return False diff --git a/demisto_sdk/commands/validate/validators/XR_validators/__init__.py b/demisto_sdk/commands/validate/validators/XR_validators/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py b/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py deleted file mode 100644 index e825320cd4a..00000000000 --- a/demisto_sdk/commands/validate/validators/XT_validators/XT101_standardized_fields.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import annotations - -from typing import Iterable, List, Union - -from demisto_sdk.commands.content_graph.objects import XDRCTemplate -from demisto_sdk.commands.validate.validators.base_validator import ( - BaseValidator, - ValidationResult, -) - -ContentTypes = Union[XDRCTemplate] - - -class XDRCTemplateStandardizedFieldsValidator(BaseValidator[ContentTypes]): - error_code = "XT101" - description = "Validate that XDRCTemplates use standardized 'id' field instead of 'content_global_id'." - rationale = "New content items should use standardized field names 'id' and 'name' for consistency across all content types." - error_message = "XDRCTemplates must use 'id' field instead of 'content_global_id'. Please update your template to use the standardized field name." - related_field = "content_global_id" - is_auto_fixable = False - - def obtain_invalid_content_items( - self, content_items: Iterable[ContentTypes] - ) -> List[ValidationResult]: - return [ - ValidationResult( - validator=self, - message=self.error_message, - content_object=content_item, - ) - for content_item in content_items - if self.has_non_standard_fields(content_item) - ] - - def has_non_standard_fields(self, content_item: ContentTypes) -> bool: - """Check if the content item uses non-standard field names.""" - data = content_item.data - - # Check for non-standard fields - has_content_global_id = "content_global_id" in data - has_standard_id = "id" in data - - # Invalid if it has the old field but not the new standard field - return has_content_global_id and not has_standard_id diff --git a/demisto_sdk/commands/validate/validators/XT_validators/__init__.py b/demisto_sdk/commands/validate/validators/XT_validators/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 From 1efa309000c054ab672f7c72e58bf45543b18f6e Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 11:46:53 +0200 Subject: [PATCH 17/24] remove all validations --- demisto_sdk/commands/validate/tests/TR_validators_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/demisto_sdk/commands/validate/tests/TR_validators_test.py b/demisto_sdk/commands/validate/tests/TR_validators_test.py index 6be429e4d4e..14b447a453d 100644 --- a/demisto_sdk/commands/validate/tests/TR_validators_test.py +++ b/demisto_sdk/commands/validate/tests/TR_validators_test.py @@ -74,4 +74,3 @@ def test_IsSilentTriggerValidator(name, is_silent, result_len, file_name): [trigger] ) assert result_len == len(invalid_content_items) - From 151134273fabf5a984ce0adcbac7f5cf5567c991 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 11:52:11 +0200 Subject: [PATCH 18/24] fix testsuit --- TestSuite/layout_rule.py | 2 -- TestSuite/trigger.py | 3 --- TestSuite/xdrc_template.py | 1 - TestSuite/xsiam_report.py | 2 -- demisto_sdk/commands/common/tests/trigger_test.py | 1 - 5 files changed, 9 deletions(-) diff --git a/TestSuite/layout_rule.py b/TestSuite/layout_rule.py index 1091e01d67f..5bab3bce254 100644 --- a/TestSuite/layout_rule.py +++ b/TestSuite/layout_rule.py @@ -22,9 +22,7 @@ def create_default_layout_rule(self): self.write_json( { "id": self.rule_id, - "rule_id": self.rule_id, "name": self.name, - "rule_name": self.name, "layout_id": "test_layout", "description": "", "alerts_filter": { diff --git a/TestSuite/trigger.py b/TestSuite/trigger.py index 0b2b659c429..16bef1cb476 100644 --- a/TestSuite/trigger.py +++ b/TestSuite/trigger.py @@ -11,7 +11,6 @@ def __init__(self, name: str, trigger_dir_path: Path, json_content: dict = None) super().__init__(trigger_dir_path, name, "") if json_content: - # Write exactly what the test provided; do not auto-normalize. self.write_json(json_content) else: self.create_default_trigger() @@ -20,12 +19,10 @@ def create_default_trigger(self): self.write_json( { "id": self.id, - "trigger_id": self.id, "name": self.id, "playbook_id": "mock playbook", "suggestion_reason": "mock reason", "description": "desc", - "trigger_name": self.id, "alerts_filter": { "filter": { "AND": [ diff --git a/TestSuite/xdrc_template.py b/TestSuite/xdrc_template.py index 247910d41dd..e5113e1135d 100644 --- a/TestSuite/xdrc_template.py +++ b/TestSuite/xdrc_template.py @@ -33,7 +33,6 @@ def create_default(self): self.write_json( { "id": self.id, - "content_global_id": self.id, "name": self.id, "os_type": "os_type_test", "profile_type": "profile_type_test", diff --git a/TestSuite/xsiam_report.py b/TestSuite/xsiam_report.py index ab4839f34b7..703bb9178f4 100644 --- a/TestSuite/xsiam_report.py +++ b/TestSuite/xsiam_report.py @@ -18,9 +18,7 @@ def create_default(self): "templates_data": [ { "id": self.id, - "global_id": self.id, "name": self.id, - "report_name": self.id, "report_description": None, "default_template_id": None, "time_frame": {"relativeTime": 86400000}, diff --git a/demisto_sdk/commands/common/tests/trigger_test.py b/demisto_sdk/commands/common/tests/trigger_test.py index a86c16c521f..3092c92774a 100644 --- a/demisto_sdk/commands/common/tests/trigger_test.py +++ b/demisto_sdk/commands/common/tests/trigger_test.py @@ -107,7 +107,6 @@ def test_is_not_valid_file_complicated_schema(repo): "MyTrigger", { "id": "trigger_id", - "trigger_id": "trigger_id", "playbook_id": "playbook_id", "suggestion_reason": "Reason", "description": "Description", From 3e9220547b5fc0bc7712a28a9da21c8f88e9d4c5 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 12:05:09 +0200 Subject: [PATCH 19/24] fix testsuit --- TestSuite/layout_rule.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TestSuite/layout_rule.py b/TestSuite/layout_rule.py index 5bab3bce254..1091e01d67f 100644 --- a/TestSuite/layout_rule.py +++ b/TestSuite/layout_rule.py @@ -22,7 +22,9 @@ def create_default_layout_rule(self): self.write_json( { "id": self.rule_id, + "rule_id": self.rule_id, "name": self.name, + "rule_name": self.name, "layout_id": "test_layout", "description": "", "alerts_filter": { From 720dafb62fa092ef86f83f92d4814dbeaf865e11 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 14:34:23 +0200 Subject: [PATCH 20/24] after code review --- .changelog/5079.yml | 2 +- .../commands/common/tests/trigger_test.py | 1 - .../validate/tests/ST_validators_test.py | 40 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/.changelog/5079.yml b/.changelog/5079.yml index 13bcca5c64e..c5c88f38151 100644 --- a/.changelog/5079.yml +++ b/.changelog/5079.yml @@ -1,4 +1,4 @@ changes: -- description: Add validators to enforce standardized id/name fields. +- description: Updated the content item structure to adopt standardized id and name fields. type: internal pr_number: 5079 diff --git a/demisto_sdk/commands/common/tests/trigger_test.py b/demisto_sdk/commands/common/tests/trigger_test.py index 3092c92774a..b033d960e27 100644 --- a/demisto_sdk/commands/common/tests/trigger_test.py +++ b/demisto_sdk/commands/common/tests/trigger_test.py @@ -111,7 +111,6 @@ def test_is_not_valid_file_complicated_schema(repo): "suggestion_reason": "Reason", "description": "Description", "name": "trigger_name", - "trigger_name": "trigger_name", "alerts_filter": { "filter": { "OR": [ diff --git a/demisto_sdk/commands/validate/tests/ST_validators_test.py b/demisto_sdk/commands/validate/tests/ST_validators_test.py index 43eb5b12f72..6966e888b53 100644 --- a/demisto_sdk/commands/validate/tests/ST_validators_test.py +++ b/demisto_sdk/commands/validate/tests/ST_validators_test.py @@ -885,3 +885,43 @@ def test_IsSupportedModulesSubsetOfPack_inherit_pack_when_missing(): [playbook] ) assert len(results) == 0 + + +def test_validate_trigger_with_standardized_id_and_name_valid(): + """ + Given: + - A trigger with standardized 'id' and 'name' fields. + When: + - Instantiating _StrictTrigger. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + trigger = _StrictTrigger( + id="test_trigger", + name="Test Trigger", + description="desc", + suggestion_reason="reason", + playbook_id="Playbook123", + ) + assert trigger.id == "test_trigger" + assert trigger.name == "Test Trigger" + + +def test_validate_trigger_missing_required_id_field(): + """ + Given: + - A trigger missing the required 'id' field (using only old 'trigger_id'). + When: + - Instantiating _StrictTrigger. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + with pytest.raises(ValueError) as exc: + _StrictTrigger( + trigger_id="test_trigger", + name="Test Trigger", + description="desc", + suggestion_reason="reason", + playbook_id="Playbook123", + ) + assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() From c99bea1df2cd671f173885c2f6bd07552dc3774d Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 15:04:18 +0200 Subject: [PATCH 21/24] after code review --- .../validate/tests/ST_validators_test.py | 263 +++++++++++++++--- 1 file changed, 231 insertions(+), 32 deletions(-) diff --git a/demisto_sdk/commands/validate/tests/ST_validators_test.py b/demisto_sdk/commands/validate/tests/ST_validators_test.py index 6966e888b53..097ec83cb68 100644 --- a/demisto_sdk/commands/validate/tests/ST_validators_test.py +++ b/demisto_sdk/commands/validate/tests/ST_validators_test.py @@ -9,7 +9,19 @@ ScriptParser, ) from demisto_sdk.commands.content_graph.parsers.pack import PackParser +from demisto_sdk.commands.content_graph.strict_objects.layout_rule import ( + _StrictLayoutRule, +) from demisto_sdk.commands.content_graph.strict_objects.trigger import _StrictTrigger +from demisto_sdk.commands.content_graph.strict_objects.xdrc_template import ( + _StrictXDRCTemplate, +) +from demisto_sdk.commands.content_graph.strict_objects.xsiam_dashboard import ( + _StrictXSIAMDashboard, +) +from demisto_sdk.commands.content_graph.strict_objects.xsiam_report import ( + _StrictXSIAMReport, +) from demisto_sdk.commands.content_graph.tests.test_tools import load_yaml from demisto_sdk.commands.validate.tests.test_tools import ( REPO, @@ -886,42 +898,229 @@ def test_IsSupportedModulesSubsetOfPack_inherit_pack_when_missing(): ) assert len(results) == 0 - -def test_validate_trigger_with_standardized_id_and_name_valid(): - """ - Given: - - A trigger with standardized 'id' and 'name' fields. - When: - - Instantiating _StrictTrigger. - Then: - - Validation passes (no exception) and fields are set correctly. - """ - trigger = _StrictTrigger( - id="test_trigger", - name="Test Trigger", - description="desc", - suggestion_reason="reason", - playbook_id="Playbook123", - ) - assert trigger.id == "test_trigger" - assert trigger.name == "Test Trigger" - - -def test_validate_trigger_missing_required_id_field(): +class TestStandardizedIdAndNameFields: """ - Given: - - A trigger missing the required 'id' field (using only old 'trigger_id'). - When: - - Instantiating _StrictTrigger. - Then: - - ValidationError is raised indicating 'id' field is required. + Test class to validate the existence of standardized 'id' and 'name' fields + in various content items: triggers, xsiam reports, xsiam dashboards, layout rules, and xdrc templates. """ - with pytest.raises(ValueError) as exc: - _StrictTrigger( - trigger_id="test_trigger", + + def test_validate_trigger_with_standardized_id_and_name_valid(self): + """ + Given: + - A trigger with standardized 'id' and 'name' fields. + When: + - Instantiating _StrictTrigger. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + trigger = _StrictTrigger( # type: ignore[call-arg] + id="test_trigger", name="Test Trigger", description="desc", suggestion_reason="reason", playbook_id="Playbook123", ) - assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() + assert trigger.id == "test_trigger" + assert trigger.name == "Test Trigger" + + def test_validate_trigger_missing_required_id_field(self): + """ + Given: + - A trigger missing the required 'id' field (using only old 'trigger_id'). + When: + - Instantiating _StrictTrigger. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + with pytest.raises(ValueError) as exc: + _StrictTrigger( # type: ignore[call-arg] + trigger_id="test_trigger", + trigger_name="Test Trigger", + name="Test Trigger", + description="desc", + suggestion_reason="reason", + playbook_id="Playbook123", + ) + assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() + + + def test_validate_xsiam_report_with_standardized_id_and_name_in_templates_data( + self, + ): + """ + Given: + - An XSIAM report with templates_data containing standardized 'id' and 'name' fields. + When: + - Instantiating _StrictXSIAMReport with valid TemplatesData. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + from demisto_sdk.commands.content_graph.strict_objects.xsiam_report import ( + TemplatesData, + ) + + template_data = TemplatesData( + id="test_template", + global_id="test_template", + name="Test Template", + report_name="Test Template", + time_offset=0, + layout=[], + ) + xsiam_report = _StrictXSIAMReport(templates_data=[template_data]) + assert xsiam_report.templates_data[0].id == "test_template" + assert xsiam_report.templates_data[0].name == "Test Template" + + def test_validate_xsiam_report_missing_required_id_in_templates_data(self): + """ + Given: + - An XSIAM report with templates_data missing the required 'id' field. + When: + - Instantiating TemplatesData without 'id'. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + from demisto_sdk.commands.content_graph.strict_objects.xsiam_report import ( + TemplatesData, + ) + + with pytest.raises(ValueError) as exc: + TemplatesData( # type: ignore[call-arg] + report_name="Test Template", + global_id="test_template", + time_offset=0, + layout=[], + ) + assert "id" in str(exc.value).lower() and "name" in str(exc.value).lower() and "required" in str(exc.value).lower() + + def test_validate_xsiam_dashboard_with_standardized_id_and_name_in_dashboards_data( + self, + ): + """ + Given: + - An XSIAM dashboard with dashboards_data containing standardized 'id' and 'name' fields. + When: + - Instantiating _StrictXSIAMDashboard with valid DashboardsData. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + from demisto_sdk.commands.content_graph.strict_objects.xsiam_dashboard import ( + _DashboardsData, + ) + + dashboard_data = _DashboardsData( + id="test_dashboard", + global_id="test_dashboard", + name="Test Dashboard", + status="active", + default_dashboard_id=1, + layout=[], + ) + xsiam_dashboard = _StrictXSIAMDashboard( + dashboards_data=[dashboard_data], widgets_data=[] + ) + assert xsiam_dashboard.dashboards_data[0].id == "test_dashboard" + assert xsiam_dashboard.dashboards_data[0].name == "Test Dashboard" + + def test_validate_xsiam_dashboard_missing_required_id_in_dashboards_data(self): + """ + Given: + - An XSIAM dashboard with dashboards_data missing the required 'id' field. + When: + - Instantiating _DashboardsData without 'id'. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + from demisto_sdk.commands.content_graph.strict_objects.xsiam_dashboard import ( + _DashboardsData, + ) + + with pytest.raises(ValueError) as exc: + _DashboardsData( # type: ignore[call-arg] + name="Test Dashboard", + global_id="test_dashboard", + status="active", + default_dashboard_id=1, + layout=[], + ) + assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() + + def test_validate_layout_rule_with_standardized_id_and_name_valid(self): + """ + Given: + - A layout rule with standardized 'id' and 'name' fields. + When: + - Instantiating _StrictLayoutRule. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + layout_rule = _StrictLayoutRule( # type: ignore[call-arg] + id="test_layout_rule", + rule_id="test_layout_rule", + name="Test Layout Rule", + rule_name="Test Layout Rule", + layout_id="layout123", + fromVersion="6.0.0", + ) + assert layout_rule.id == "test_layout_rule" + assert layout_rule.name == "Test Layout Rule" + + def test_validate_layout_rule_missing_required_id_field(self): + """ + Given: + - A layout rule missing the required 'id' field (using only old 'rule_id'). + When: + - Instantiating _StrictLayoutRule. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + with pytest.raises(ValueError) as exc: + _StrictLayoutRule( # type: ignore[call-arg] + rule_id="test_layout_rule", + rule_name="Test Layout Rule", + layout_id="layout123", + fromVersion="6.0.0", + ) + assert "id" in str(exc.value).lower() and "name" in str(exc.value).lower() and "required" in str(exc.value).lower() + + def test_validate_xdrc_template_with_standardized_id_and_name_valid(self): + """ + Given: + - An XDRC template with standardized 'id' and 'name' fields. + When: + - Instantiating _StrictXDRCTemplate. + Then: + - Validation passes (no exception) and fields are set correctly. + """ + xdrc_template = _StrictXDRCTemplate( + id="test_xdrc_template", + content_global_id="test_xdrc_template", + name="Test XDRC Template", + os_type="Linux", + profile_type="profile1", + from_xdr_version="1.0.0", + yaml_template="template_content", + ) + assert xdrc_template.id == "test_xdrc_template" + assert xdrc_template.name == "Test XDRC Template" + + def test_validate_xdrc_template_missing_required_id_field(self): + """ + Given: + - An XDRC template missing the required 'id' field. + When: + - Instantiating _StrictXDRCTemplate. + Then: + - ValidationError is raised indicating 'id' field is required. + """ + with pytest.raises(ValueError) as exc: + _StrictXDRCTemplate( # type: ignore[call-arg] + name="Test XDRC Template", + content_global_id="test_xdrc_template", + os_type="Linux", + profile_type="profile1", + from_xdr_version="1.0.0", + yaml_template="template_content", + ) + assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() + From 93e997724a65a142e3408f58ccff4c17574ef197 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 23 Nov 2025 15:15:25 +0200 Subject: [PATCH 22/24] after code review --- .../validate/tests/ST_validators_test.py | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/demisto_sdk/commands/validate/tests/ST_validators_test.py b/demisto_sdk/commands/validate/tests/ST_validators_test.py index 097ec83cb68..35dd8d68571 100644 --- a/demisto_sdk/commands/validate/tests/ST_validators_test.py +++ b/demisto_sdk/commands/validate/tests/ST_validators_test.py @@ -898,6 +898,7 @@ def test_IsSupportedModulesSubsetOfPack_inherit_pack_when_missing(): ) assert len(results) == 0 + class TestStandardizedIdAndNameFields: """ Test class to validate the existence of standardized 'id' and 'name' fields @@ -913,7 +914,7 @@ def test_validate_trigger_with_standardized_id_and_name_valid(self): Then: - Validation passes (no exception) and fields are set correctly. """ - trigger = _StrictTrigger( # type: ignore[call-arg] + trigger = _StrictTrigger( # type: ignore[call-arg] id="test_trigger", name="Test Trigger", description="desc", @@ -933,7 +934,7 @@ def test_validate_trigger_missing_required_id_field(self): - ValidationError is raised indicating 'id' field is required. """ with pytest.raises(ValueError) as exc: - _StrictTrigger( # type: ignore[call-arg] + _StrictTrigger( # type: ignore[call-arg] trigger_id="test_trigger", trigger_name="Test Trigger", name="Test Trigger", @@ -943,7 +944,6 @@ def test_validate_trigger_missing_required_id_field(self): ) assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() - def test_validate_xsiam_report_with_standardized_id_and_name_in_templates_data( self, ): @@ -991,7 +991,11 @@ def test_validate_xsiam_report_missing_required_id_in_templates_data(self): time_offset=0, layout=[], ) - assert "id" in str(exc.value).lower() and "name" in str(exc.value).lower() and "required" in str(exc.value).lower() + assert ( + "id" in str(exc.value).lower() + and "name" in str(exc.value).lower() + and "required" in str(exc.value).lower() + ) def test_validate_xsiam_dashboard_with_standardized_id_and_name_in_dashboards_data( self, @@ -1054,7 +1058,7 @@ def test_validate_layout_rule_with_standardized_id_and_name_valid(self): Then: - Validation passes (no exception) and fields are set correctly. """ - layout_rule = _StrictLayoutRule( # type: ignore[call-arg] + layout_rule = _StrictLayoutRule( # type: ignore[call-arg] id="test_layout_rule", rule_id="test_layout_rule", name="Test Layout Rule", @@ -1081,7 +1085,11 @@ def test_validate_layout_rule_missing_required_id_field(self): layout_id="layout123", fromVersion="6.0.0", ) - assert "id" in str(exc.value).lower() and "name" in str(exc.value).lower() and "required" in str(exc.value).lower() + assert ( + "id" in str(exc.value).lower() + and "name" in str(exc.value).lower() + and "required" in str(exc.value).lower() + ) def test_validate_xdrc_template_with_standardized_id_and_name_valid(self): """ @@ -1123,4 +1131,3 @@ def test_validate_xdrc_template_missing_required_id_field(self): yaml_template="template_content", ) assert "id" in str(exc.value).lower() and "required" in str(exc.value).lower() - From 4bf0e61a6ac766d669f7254795cd38a44cb728f9 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 14 Dec 2025 13:53:59 +0200 Subject: [PATCH 23/24] changed change log --- .changelog/5079.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/5079.yml b/.changelog/5079.yml index c5c88f38151..027373204d3 100644 --- a/.changelog/5079.yml +++ b/.changelog/5079.yml @@ -1,4 +1,4 @@ changes: - description: Updated the content item structure to adopt standardized id and name fields. type: internal -pr_number: 5079 +pr_number: 5160 From f2b626285db3810e92add94efe950b9712cfc360 Mon Sep 17 00:00:00 2001 From: Shir2611 Date: Sun, 14 Dec 2025 13:54:57 +0200 Subject: [PATCH 24/24] changed change log --- .changelog/{5079.yml => 5160.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{5079.yml => 5160.yml} (100%) diff --git a/.changelog/5079.yml b/.changelog/5160.yml similarity index 100% rename from .changelog/5079.yml rename to .changelog/5160.yml