diff --git a/cognite/client/data_classes/capabilities.py b/cognite/client/data_classes/capabilities.py index 02c075127f..9a15d17dc0 100644 --- a/cognite/client/data_classes/capabilities.py +++ b/cognite/client/data_classes/capabilities.py @@ -867,3 +867,8 @@ class Scope: _CAPABILITY_CLASS_BY_NAME: dict[str, type[Capability]] = { c._capability_name: c for c in Capability.__subclasses__() if not issubclass(c, UnknownAcl) } +# Give all Actions a better error message (instead of implementing __missing__ for all): +for acl in _CAPABILITY_CLASS_BY_NAME.values(): + if acl.Action.__members__: + _cls = type(next(iter(acl.Action.__members__.values()))) + _cls.__name__ = f"{acl.__name__} {_cls.__name__}" diff --git a/tests/tests_unit/test_data_classes/test_capabilities.py b/tests/tests_unit/test_data_classes/test_capabilities.py index 4bf67ec89c..a9bea08fcc 100644 --- a/tests/tests_unit/test_data_classes/test_capabilities.py +++ b/tests/tests_unit/test_data_classes/test_capabilities.py @@ -183,3 +183,28 @@ def test_load_dump_unknown(self, raw: dict[str, Any]) -> None: assert all(action is UnknownAcl.Action.Unknown for action in capability.actions) assert capability.raw_data == raw assert capability.dump(camel_case=True) == raw + + @pytest.mark.parametrize( + "acl_cls_name, bad_action, dumped", + [ + ("AssetsAcl", "SONG-WRITER", {"assetsAcl": {"actions": ["READ", "SONG-WRITER"], "scope": {"all": {}}}}), + ( + "DocumentFeedbackAcl", + "CTRL-ALT-DELETE", + {"documentFeedbackAcl": {"actions": ["CREATE", "CTRL-ALT-DELETE"], "scope": {"all": {}}}}, + ), + ( + "FilesAcl", + "COMPRESS", + {"filesAcl": {"actions": ["COMPRESS"], "scope": {"datasetScope": {"ids": ["2332579", "372"]}}}}, + ), + ( + "NotificationsAcl", + "SEND-PIGEON", + {"notificationsAcl": {"actions": ["READ", "SEND-PIGEON"], "scope": {"all": {}}}}, + ), + ], + ) + def test_load__action_does_not_exist(self, acl_cls_name: str, bad_action: str, dumped: dict[str, Any]) -> None: + with pytest.raises(ValueError, match=rf"^'{bad_action}' is not a valid {acl_cls_name} Action$"): + Capability.load(dumped)