diff --git a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py index 6719afaef..1d4380d51 100644 --- a/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py +++ b/packages/gooddata-sdk/src/gooddata_sdk/catalog/workspace/service.py @@ -190,27 +190,33 @@ def list_workspace_settings(self, workspace_id: str) -> list[CatalogWorkspaceSet workspace_settings = load_all_entities(get_workspace_settings).data return [CatalogWorkspaceSetting.from_api(ws) for ws in workspace_settings] - def resolve_all_workspace_settings(self, workspace_id: str) -> dict: + def resolve_all_workspace_settings(self, workspace_id: str, exclude_user_settings: Optional[bool] = None) -> dict: """ Resolves values for all settings in a workspace by current user, workspace, organization, or default settings and return them as a dictionary. Proper parsing is up to the caller. TODO: long-term we should return a proper entity object. :param workspace_id: Workspace ID + :param exclude_user_settings: When True, user-level settings are excluded from resolution :return: Dict of settings """ # note: in case some settings were recently added and the API client was not regenerated it can fail on # invalid value when validating allowed types on the client side before request is sent to the server + kwargs: dict = {"_check_return_type": False} + if exclude_user_settings is not None: + kwargs["exclude_user_settings"] = exclude_user_settings resolved_workspace_settings = [ setting.to_dict() for setting in self._client.actions_api.workspace_resolve_all_settings( workspace_id, - _check_return_type=False, + **kwargs, ) ] return {setting["type"]: setting for setting in resolved_workspace_settings} - def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: + def resolve_workspace_settings( + self, workspace_id: str, settings: list, exclude_user_settings: Optional[bool] = None + ) -> dict: """ Resolves values for given settings in a workspace by current user, workspace, organization, or default settings and return them as a dictionary. Proper parsing is up to the caller. @@ -218,14 +224,18 @@ def resolve_workspace_settings(self, workspace_id: str, settings: list) -> dict: :param workspace_id: Workspace ID :param settings: List of settings to resolve + :param exclude_user_settings: When True, user-level settings are excluded from resolution :return: Dict of settings """ + kwargs: dict = {"_check_return_type": False} + if exclude_user_settings is not None: + kwargs["exclude_user_settings"] = exclude_user_settings resolved_workspace_settings = [ setting.to_dict() for setting in self._client.actions_api.workspace_resolve_settings( workspace_id, ResolveSettingsRequest(settings=settings), - _check_return_type=False, + **kwargs, ) ] return {setting["type"]: setting for setting in resolved_workspace_settings} diff --git a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py index d0eff5401..e873c5311 100644 --- a/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py +++ b/packages/gooddata-sdk/tests/catalog/test_catalog_workspace.py @@ -3,6 +3,7 @@ import json from pathlib import Path +from unittest.mock import MagicMock, patch from xml.etree import ElementTree as ET import yaml @@ -1039,3 +1040,97 @@ def test_layout_filter_views(test_config): sdk.catalog_workspace.put_declarative_filter_views(workspace_id, []) filter_views = sdk.catalog_workspace.get_declarative_filter_views(workspace_id) assert len(filter_views) == 0 + + +def test_resolve_all_workspace_settings_forwards_exclude_user_settings(): + mock_setting = MagicMock() + mock_setting.to_dict.return_value = {"type": "LOCALE", "value": "en-US"} + + mock_actions_api = MagicMock() + mock_actions_api.workspace_resolve_all_settings.return_value = [mock_setting] + + mock_client = MagicMock() + mock_client.actions_api = mock_actions_api + + sdk = GoodDataSdk.__new__(GoodDataSdk) + sdk._client = mock_client + from gooddata_sdk.catalog.workspace.service import CatalogWorkspaceService + + service = CatalogWorkspaceService.__new__(CatalogWorkspaceService) + service._client = mock_client + + result = service.resolve_all_workspace_settings("demo", exclude_user_settings=True) + + mock_actions_api.workspace_resolve_all_settings.assert_called_once_with( + "demo", _check_return_type=False, exclude_user_settings=True + ) + assert result == {"LOCALE": {"type": "LOCALE", "value": "en-US"}} + + +def test_resolve_all_workspace_settings_omits_exclude_user_settings_by_default(): + mock_setting = MagicMock() + mock_setting.to_dict.return_value = {"type": "LOCALE", "value": "en-US"} + + mock_actions_api = MagicMock() + mock_actions_api.workspace_resolve_all_settings.return_value = [mock_setting] + + mock_client = MagicMock() + mock_client.actions_api = mock_actions_api + + from gooddata_sdk.catalog.workspace.service import CatalogWorkspaceService + + service = CatalogWorkspaceService.__new__(CatalogWorkspaceService) + service._client = mock_client + + service.resolve_all_workspace_settings("demo") + + mock_actions_api.workspace_resolve_all_settings.assert_called_once_with("demo", _check_return_type=False) + + +def test_resolve_workspace_settings_forwards_exclude_user_settings(): + mock_setting = MagicMock() + mock_setting.to_dict.return_value = {"type": "LOCALE", "value": "en-US"} + + mock_actions_api = MagicMock() + mock_actions_api.workspace_resolve_settings.return_value = [mock_setting] + + mock_client = MagicMock() + mock_client.actions_api = mock_actions_api + + from gooddata_sdk.catalog.workspace.service import CatalogWorkspaceService + + service = CatalogWorkspaceService.__new__(CatalogWorkspaceService) + service._client = mock_client + + settings_input = ["LOCALE"] + result = service.resolve_workspace_settings("demo", settings_input, exclude_user_settings=True) + + call_args = mock_actions_api.workspace_resolve_settings.call_args + assert call_args[0][0] == "demo" + assert call_args[1]["_check_return_type"] is False + assert call_args[1]["exclude_user_settings"] is True + assert result == {"LOCALE": {"type": "LOCALE", "value": "en-US"}} + + +def test_resolve_workspace_settings_omits_exclude_user_settings_by_default(): + mock_setting = MagicMock() + mock_setting.to_dict.return_value = {"type": "LOCALE", "value": "en-US"} + + mock_actions_api = MagicMock() + mock_actions_api.workspace_resolve_settings.return_value = [mock_setting] + + mock_client = MagicMock() + mock_client.actions_api = mock_actions_api + + from gooddata_sdk.catalog.workspace.service import CatalogWorkspaceService + + service = CatalogWorkspaceService.__new__(CatalogWorkspaceService) + service._client = mock_client + + settings_input = ["LOCALE"] + service.resolve_workspace_settings("demo", settings_input) + + call_args = mock_actions_api.workspace_resolve_settings.call_args + assert call_args[0][0] == "demo" + assert call_args[1]["_check_return_type"] is False + assert "exclude_user_settings" not in call_args[1]