diff --git a/.coveragerc b/.coveragerc index e6d50447c3..a6e9f5abf5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -6,4 +6,4 @@ omit = splunk_add_on_ucc_framework/templates/input.module-template [report] -fail_under = 81.5 +fail_under = 84.64 diff --git a/splunk_add_on_ucc_framework/global_config.py b/splunk_add_on_ucc_framework/global_config.py index ba119597a8..1f54d8d17d 100644 --- a/splunk_add_on_ucc_framework/global_config.py +++ b/splunk_add_on_ucc_framework/global_config.py @@ -21,6 +21,7 @@ import yaml from splunk_add_on_ucc_framework import utils +from splunk_add_on_ucc_framework import app_manifest as app_manifest_lib from splunk_add_on_ucc_framework.commands.rest_builder.user_defined_rest_handlers import ( UserDefinedRestHandlers, ) @@ -79,13 +80,41 @@ def from_file(cls, global_config_path: str) -> "GlobalConfig": ) return GlobalConfig(content, is_global_config_yaml) + @classmethod + def from_app_manifest( + cls, app_manifest: app_manifest_lib.AppManifest + ) -> "GlobalConfig": + content = { + "meta": { + "name": app_manifest.get_addon_name(), + # TODO(ADDON-79208): once `restRoot` is optional, this line can be removed + "restRoot": app_manifest.get_addon_name(), + "displayName": app_manifest.get_title(), + "version": app_manifest.get_addon_version(), + } + } + return GlobalConfig( + content, + False, + ) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, GlobalConfig): + raise NotImplementedError() + return all( + [ + self.content == other.content, + self.is_yaml == other.is_yaml, + ] + ) + def parse_user_defined_handlers(self) -> None: """Parse user-defined REST handlers from globalConfig["options"]["restHandlers"]""" rest_handlers = self._content.get("options", {}).get("restHandlers", []) self.user_defined_handlers.add_definitions(rest_handlers) def dump(self, path: str) -> None: - if self._is_global_config_yaml: + if self.is_yaml: utils.dump_yaml_config(self.content, path) else: utils.dump_json_config(self.content, path) @@ -121,6 +150,10 @@ def _expand_entities(items: Optional[List[Dict[Any, Any]]]) -> None: def content(self) -> Any: return self._content + @property + def is_yaml(self) -> bool: + return self._is_global_config_yaml + @property def inputs(self) -> List[Any]: if self.has_pages() and "inputs" in self._content["pages"]: diff --git a/splunk_add_on_ucc_framework/global_config_update.py b/splunk_add_on_ucc_framework/global_config_update.py index 00adc05242..ecbb1cff29 100644 --- a/splunk_add_on_ucc_framework/global_config_update.py +++ b/splunk_add_on_ucc_framework/global_config_update.py @@ -270,7 +270,7 @@ def _dump_with_migrated_tabs(global_config: GlobalConfig, path: str) -> None: continue global_config.content["pages"]["configuration"]["tabs"][i] = _collapse_tab(tab) - _dump(global_config.content, path, global_config._is_global_config_yaml) + _dump(global_config.content, path, global_config.is_yaml) def _dump_with_migrated_entities( @@ -288,7 +288,7 @@ def _dump_with_migrated_entities( ) _collapse_entities(global_config.content.get("alerts"), entity_type) - _dump(global_config.content, path, global_config._is_global_config_yaml) + _dump(global_config.content, path, global_config.is_yaml) def _collapse_entities( diff --git a/tests/unit/test_global_config.py b/tests/unit/test_global_config.py index 5d3ba6493d..6b18784f5b 100644 --- a/tests/unit/test_global_config.py +++ b/tests/unit/test_global_config.py @@ -35,6 +35,57 @@ def test_global_config_parse(filename): assert global_config.has_dashboard() is True +def test_global_config_from_app_manifest(app_manifest_correct): + expected_global_config = global_config_lib.GlobalConfig( + { + "meta": { + "name": "Splunk_TA_UCCExample", + "restRoot": "Splunk_TA_UCCExample", + "displayName": "Splunk Add-on for UCC Example", + "version": "7.0.1", + } + }, + False, + ) + + global_config = global_config_lib.GlobalConfig.from_app_manifest( + app_manifest_correct + ) + + assert expected_global_config == global_config + + +def test_global_config_equal(): + global_config_1 = global_config_lib.GlobalConfig.from_file( + helpers.get_testdata_file_path("valid_config.json") + ) + global_config_2 = global_config_lib.GlobalConfig.from_file( + helpers.get_testdata_file_path("valid_config.json") + ) + + assert global_config_1 == global_config_2 + + +def test_global_config_when_no_equal(): + global_config_1 = global_config_lib.GlobalConfig.from_file( + helpers.get_testdata_file_path("valid_config.json") + ) + global_config_2 = global_config_lib.GlobalConfig.from_file( + helpers.get_testdata_file_path("valid_config_only_logging.json") + ) + + assert global_config_1 != global_config_2 + + +def test_global_config_equal_when_wrong_object_type(): + global_config = global_config_lib.GlobalConfig.from_file( + helpers.get_testdata_file_path("valid_config.json") + ) + + with pytest.raises(NotImplementedError): + _ = global_config == "" + + @mock.patch("splunk_add_on_ucc_framework.utils.dump_json_config") def test_global_config_dump_when_json( mock_utils_dump_json_config, global_config_all_json, tmp_path diff --git a/tests/unit/test_global_config_validator.py b/tests/unit/test_global_config_validator.py index 4a9758e92b..a69a6c0106 100644 --- a/tests/unit/test_global_config_validator.py +++ b/tests/unit/test_global_config_validator.py @@ -35,6 +35,17 @@ def test_config_validation_when_valid(filename): validator.validate() +def test_validation_when_created_from_app_manifest(app_manifest_correct): + global_config = global_config_lib.GlobalConfig.from_app_manifest( + app_manifest_correct + ) + + validator = GlobalConfigValidator(helpers.get_path_to_source_dir(), global_config) + + with does_not_raise(): + validator.validate() + + def test_autocompletefields_support_integer_values(): # Regression unit test: https://github.com/splunk/addonfactory-ucc-generator/issues/794 global_config_path = helpers.get_testdata_file_path(