diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 151394ed..bad5bbe2 100755 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -1996,7 +1996,7 @@ def schema_field_create(self, entity_type, data_type, display_name, properties=N return self._call_rpc("schema_field_create", params) - def schema_field_update(self, entity_type, field_name, properties): + def schema_field_update(self, entity_type, field_name, properties, project_entity=None): """ Update the properties for the specified field on an entity. @@ -2014,7 +2014,16 @@ def schema_field_update(self, entity_type, field_name, properties): :param field_name: Internal Shotgun name of the field to update. :param properties: Dictionary with key/value pairs where the key is the property to be updated and the value is the new value. + :param dict project_entity: Optional Project entity specifying which project to modify the + ``visible`` property for. If the ``visible`` is present in ``properties`` and + ``project_entity`` is not set, an exception will be raised. Example: + ``{'type': 'Project', 'id': 3}`` :returns: ``True`` if the field was updated. + + .. note:: + The ``project_entity`` parameter can only affect the state of the ``visible`` property + and has no impact on other properties. + :rtype: bool """ @@ -2026,7 +2035,7 @@ def schema_field_update(self, entity_type, field_name, properties): for k, v in six.iteritems((properties or {})) ] } - + params = self._add_project_param(params, project_entity) return self._call_rpc("schema_field_update", params) def schema_field_delete(self, entity_type, field_name): diff --git a/tests/test_api.py b/tests/test_api.py index 71870259..41a910e3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -2678,6 +2678,72 @@ def test_multiple_latest_filters(self): self.sg.find, "Version", filters, fields=fields, additional_filter_presets=additional_filters) + def test_modify_visibility(self): + """ + Ensure the visibility of a field can be edited via the API. + """ + # If the version of Shotgun is too old, do not run this test. + # TODO: Update this with the real version number once the feature is released. + if self.sg_version < (8, 5, 0): + warnings.warn("Test bypassed because SG server used does not support this feature.", FutureWarning) + return + + field_display_name = "Project Visibility Test" + field_name = "sg_{0}".format(field_display_name.lower().replace(" ", "_")) + + schema = self.sg.schema_field_read("Asset") + # Ensure the custom field exists. + if field_name not in schema: + self.sg.schema_field_create("Asset", "text", "Project Visibility Test") + + # Grab any two projects that we can use for toggling the visible property with. + projects = self.sg.find("Project", [], order=[{"field_name": "id", "direction": "asc"}]) + project_1 = projects[0] + project_2 = projects[1] + + # First, reset the field visibility in a known state, i.e. visible for both projects, + # in case the last test run failed midway through. + self.sg.schema_field_update("Asset", field_name, {"visible": True}, project_1) + self.assertEqual( + {"value": True, "editable": True}, + self.sg.schema_field_read("Asset", field_name, project_1)[field_name]["visible"] + ) + self.sg.schema_field_update("Asset", field_name, {"visible": True}, project_2) + self.assertEqual( + {"value": True, "editable": True}, + self.sg.schema_field_read("Asset", field_name, project_2)[field_name]["visible"] + ) + + # Built-in fields should remain not editable. + self.assertFalse(self.sg.schema_field_read("Asset", "code")["code"]["visible"]["editable"]) + + # Custom fields should be editable + self.assertEqual( + {"value": True, "editable": True}, + self.sg.schema_field_read("Asset", field_name)[field_name]["visible"] + ) + + # Hide the field on project 1 + self.sg.schema_field_update("Asset", field_name, {"visible": False}, project_1) + # It should not be visible anymore. + self.assertEqual( + {"value": False, "editable": True}, + self.sg.schema_field_read("Asset", field_name, project_1)[field_name]["visible"] + ) + + # The field should be visible on the second project. + self.assertEqual( + {"value": True, "editable": True}, + self.sg.schema_field_read("Asset", field_name, project_2)[field_name]["visible"] + ) + + # Restore the visibility on the field. + self.sg.schema_field_update("Asset", field_name, {"visible": True}, project_1) + self.assertEqual( + {"value": True, "editable": True}, + self.sg.schema_field_read("Asset", field_name, project_1)[field_name]["visible"] + ) + def _has_unicode(data): for k, v in data.items():