Skip to content

Commit

Permalink
Merge 6a80fcd into 0539bcc
Browse files Browse the repository at this point in the history
  • Loading branch information
israelpoli committed Mar 21, 2024
2 parents 0539bcc + 6a80fcd commit a5848ad
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class GenericField(ContentItem, content_type=ContentType.GENERIC_FIELD): # type
definition_id: Optional[str] = Field(alias="definitionId")
field_type: Optional[str] = Field(alias="type")
version: Optional[int] = 0
group: int = Field(None, exclude=True)

def metadata_fields(self) -> Set[str]:
return super().metadata_fields().union({"field_type"})
Expand Down
11 changes: 10 additions & 1 deletion demisto_sdk/commands/content_graph/parsers/generic_field.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import cached_property
from pathlib import Path
from typing import List, Optional, Set

Expand All @@ -18,9 +19,13 @@ def __init__(
super().__init__(path, pack_marketplaces, git_sha=git_sha)
self.definition_id = self.json_data.get("definitionId")
self.field_type = self.json_data.get("type") or ""

self.connect_to_dependencies()

@cached_property
def field_mapping(self):
super().field_mapping.update({"group": "group"})
return super().field_mapping

@property
def supported_marketplaces(self) -> Set[MarketplaceVersions]:
return {
Expand All @@ -29,6 +34,10 @@ def supported_marketplaces(self) -> Set[MarketplaceVersions]:
MarketplaceVersions.XSOAR_ON_PREM,
}

@property
def group(self) -> Optional[int]:
return self.json_data.get("group")

def connect_to_dependencies(self) -> None:
"""Collects the generic types associated to the generic field as optional dependencies."""
for associated_type in set(self.json_data.get("associatedTypes") or []):
Expand Down
69 changes: 69 additions & 0 deletions demisto_sdk/commands/validate/tests/GF_validators_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import pytest

from demisto_sdk.commands.validate.tests.test_tools import create_generic_field_object
from demisto_sdk.commands.validate.validators.GF_validators.GF100_generic_field_group import (
REQUIRED_GROUP_VALUE,
GenericFieldGroupValidator,
)
from demisto_sdk.commands.validate.validators.GF_validators.GF101_generic_field_id_prefix_validate import (
GenericFieldIdPrefixValidateValidator,
)


def test_GenericFieldIdPrefixValidateValidator_is_valid():
"""
Given:
- GenericField content items
When:
- run is_valid method
Then:
- Ensure that the ValidationResult returned
for the GenericField whose 'id' without `generic_` prefix
- Ensure that no ValidationResult returned
when `id` field with `generic_` prefix
"""
generic_field = create_generic_field_object(paths=["id"], values=["foo"])

# not valid
results = GenericFieldIdPrefixValidateValidator().is_valid([generic_field])
assert results[0].message == "foo is not a valid id, it should start with generic_."

# valid
generic_field.object_id = "generic_foo"
assert not GenericFieldIdPrefixValidateValidator().is_valid([generic_field])


def test_GenericFieldGroupValidator_is_valid():
"""
Given:
- GenericField content items
When:
- run is_valid method
Then:
- Ensure that the ValidationResult returned
for the GenericField whose 'group' field is not valid
- Ensure that no ValidationResult returned when group field set to 4
"""
# not valid
generic_field = create_generic_field_object(paths=["group"], values=[0])
assert GenericFieldGroupValidator().is_valid([generic_field])

# valid
generic_field.group = REQUIRED_GROUP_VALUE
assert not GenericFieldGroupValidator().is_valid([generic_field])


def test_GenericFieldGroupValidator_fix():
"""
Given:
- invalid GenericField that 'group' field is not 4
When:
- run fix method
Then:
- Ensure the fix message as expected
- Ensure the field `group` is set to 4
"""
generic_field = create_generic_field_object(paths=["group"], values=["0"])
result = GenericFieldGroupValidator().fix(generic_field)
assert result.message == f"set the `group` field to {REQUIRED_GROUP_VALUE}."
assert generic_field.group == REQUIRED_GROUP_VALUE
5 changes: 3 additions & 2 deletions demisto_sdk/commands/validate/tests/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from demisto_sdk.commands.common.handlers import DEFAULT_JSON_HANDLER as json
from demisto_sdk.commands.common.tools import set_value
from demisto_sdk.commands.content_graph.objects.base_content import BaseContent
from demisto_sdk.commands.content_graph.objects.generic_field import GenericField
from demisto_sdk.commands.content_graph.objects.incident_field import IncidentField
from demisto_sdk.commands.content_graph.objects.integration import Integration
from demisto_sdk.commands.content_graph.objects.pack import Pack
Expand Down Expand Up @@ -590,7 +591,7 @@ def create_generic_definition_object(

def create_generic_field_object(
paths: Optional[List[str]] = None, values: Optional[List[Any]] = None
):
) -> GenericField:
"""Creating an generic_field object with altered fields from a default generic_field json structure.
Args:
Expand All @@ -604,7 +605,7 @@ def create_generic_field_object(
update_keys(json_content, paths, values)
pack = REPO.create_pack()
pack.create_generic_field(name="generic_field", content=json_content)
return BaseContent.from_path(Path(pack.generic_fields[0].path))
return cast(GenericField, BaseContent.from_path(Path(pack.generic_fields[0].path)))


def create_generic_type_object(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from __future__ import annotations

from typing import Iterable, List

from demisto_sdk.commands.content_graph.objects.generic_field import GenericField
from demisto_sdk.commands.validate.validators.base_validator import (
BaseValidator,
FixResult,
ValidationResult,
)

REQUIRED_GROUP_VALUE = 4
ContentTypes = GenericField


class GenericFieldGroupValidator(BaseValidator[ContentTypes]):
error_code = "GF100"
rationale = "Required by the platform."
description = f"Checks if group field is set to {REQUIRED_GROUP_VALUE}."
error_message = f"The `group` key must be set to {REQUIRED_GROUP_VALUE}"
fix_message = f"set the `group` field to {REQUIRED_GROUP_VALUE}."
related_field = "group"
is_auto_fixable = True

def is_valid(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 (content_item.group != REQUIRED_GROUP_VALUE)
]

def fix(self, content_item: ContentTypes) -> FixResult:
content_item.group = REQUIRED_GROUP_VALUE
return FixResult(
validator=self,
message=self.fix_message,
content_object=content_item,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from __future__ import annotations

from typing import Iterable, List

from demisto_sdk.commands.content_graph.objects.generic_field import GenericField
from demisto_sdk.commands.validate.validators.base_validator import (
BaseValidator,
FixResult,
ValidationResult,
)

GENERIC_FIELD_ID_PREFIX = "generic_"
ContentTypes = GenericField


class GenericFieldIdPrefixValidateValidator(BaseValidator[ContentTypes]):
error_code = "GF101"
rationale = "Required by the platform."
description = "Checks if the id starts with `generic_`."
error_message = (
"{generic_id} is not a valid id, it should start with {generic_id_prefix}."
)
related_field = "id"

def is_valid(self, content_items: Iterable[ContentTypes]) -> List[ValidationResult]:
return [
ValidationResult(
validator=self,
message=self.error_message.format(
generic_id=content_item.object_id,
generic_id_prefix=GENERIC_FIELD_ID_PREFIX,
),
content_object=content_item,
)
for content_item in content_items
if (not content_item.object_id.startswith(GENERIC_FIELD_ID_PREFIX))
]

0 comments on commit a5848ad

Please sign in to comment.