diff --git a/core/docs/changelog/WCM-462.change b/core/docs/changelog/WCM-462.change new file mode 100644 index 0000000000..917fe160c8 --- /dev/null +++ b/core/docs/changelog/WCM-462.change @@ -0,0 +1 @@ +WCM-462: toggle single columns on and off \ No newline at end of file diff --git a/core/src/zeit/connector/models.py b/core/src/zeit/connector/models.py index 7cf58635e9..2b8dc3b310 100644 --- a/core/src/zeit/connector/models.py +++ b/core/src/zeit/connector/models.py @@ -103,7 +103,7 @@ class PublishInfo: Boolean, server_default='false', nullable=False, - info={'namespace': 'workflow', 'name': 'published'}, + info={'namespace': 'workflow', 'name': 'published', 'toggled': True}, ) @@ -188,8 +188,18 @@ def column_by_name(cls, name, namespace): return column @classmethod - def _columns_with_name(cls): - return [x for x in sqlalchemy.orm.class_mapper(cls).columns if x.info.get('namespace')] + def is_column_enabled(cls, column, mode): + namespace = column.info.get('namespace') + name = column.info.get('name') + if column.info.get('toggled'): + return FEATURE_TOGGLES.find(f'{namespace}_{name}_{mode}') + return namespace is not None + + @classmethod + def _columns_with_name(cls, mode='read'): + return [ + c for c in sqlalchemy.orm.class_mapper(cls).columns if cls.is_column_enabled(c, mode) + ] @property def binary_body(self): @@ -253,7 +263,7 @@ def from_webdav(self, props): if FEATURE_TOGGLES.find('write_metadata_columns') or FEATURE_TOGGLES.find( 'write_metadata_columns_strict' ): - for column in self._columns_with_name(): + for column in self._columns_with_name(mode='write'): namespace, name = column.info['namespace'], column.info['name'] value = props.get((name, self.NS + namespace), self) diff --git a/core/src/zeit/connector/tests/test_mock.py b/core/src/zeit/connector/tests/test_mock.py index 427fa0f053..230bacc83e 100644 --- a/core/src/zeit/connector/tests/test_mock.py +++ b/core/src/zeit/connector/tests/test_mock.py @@ -74,9 +74,9 @@ class MockTypeConversionTest(zeit.connector.testing.MockTest): def test_converts_sql_properties_on_read(self): params = [ [ - ('workflow', 'published'), - True, - 'yes', + ('document', 'year'), + 2024, + '2024', ], [ ('document', 'date_created'), diff --git a/core/src/zeit/connector/tests/test_postgresql.py b/core/src/zeit/connector/tests/test_postgresql.py index f54d718d76..9cd084ea54 100644 --- a/core/src/zeit/connector/tests/test_postgresql.py +++ b/core/src/zeit/connector/tests/test_postgresql.py @@ -390,3 +390,26 @@ def test_search_looks_in_columns_or_unsorted_depending_on_toggle(self): result = self.connector.search([var], var == 'Wissen') unique_id, uuid = next(result) self.assertEqual(res.id, unique_id) + + def test_single_properties_can_be_toggled(self): + FEATURE_TOGGLES.set('write_metadata_columns') + FEATURE_TOGGLES.set('read_metadata_columns') + res = self.add_resource('foo', properties={('published', f'{NS}workflow'): 'yes'}) + content = self.connector._get_content(res.id) + self.assertEqual({'workflow': {'published': 'yes'}}, content.unsorted) + # we have not written into the column yet + self.assertFalse(content.published) + # now you are allowed to write + FEATURE_TOGGLES.set('workflow_published_write') + content = self.connector._get_content(res.id) + self.connector[res.id] = res + self.assertTrue(content.published) + # check if we can read our value back + content.published = False + props = content.to_webdav() + # now still read from unsorted + self.assertEqual(props[('published', f'{NS}workflow')], 'yes') + # and now read from column + FEATURE_TOGGLES.set('workflow_published_read') + props = content.to_webdav() + self.assertEqual(props[('published', f'{NS}workflow')], False)