Fix BT5 installation of unique catalog keys

While installing a BT5 make sure not to install duplicate keys for the following ZSQLCatalog properties:
 - sql_catalog_search_keys
 - sql_catalog_related_keys
 - sql_catalog_scriptable_keys
 - sql_catalog_role_keys
 - sql_catalog_local_role_keys
parent eb89f6b2
......@@ -4263,7 +4263,26 @@ class CatalogKeyTemplateItemBase(BaseTemplateItem):
xml_data = self.generateXml(path=path)
bta.addObject(xml_data, name=path)
class CatalogSearchKeyTemplateItem(CatalogKeyTemplateItemBase):
class CatalogUniqueKeyTemplateItemBase(CatalogKeyTemplateItemBase):
# like CatalogKeyTemplateItemBase, but for keys which use
# "key | value" syntax to configure dictionaries.
# The keys (part before the pipe) must be unique.
def _getMapFromKeyList(self, key_list):
# in case of duplicates, only the last installed entry will survive
return dict(tuple(part.strip() for part in key.split('|', 1))
for key in key_list)
def _getListFromKeyMap(self, key_map):
return [" | ".join(item) for item in sorted(key_map.items())]
def _getUpdatedCatalogKeyList(self, catalog_key_list, new_key_list):
# treat key lists as dictionaries, parse and update:
catalog_key_map = self._getMapFromKeyList(catalog_key_list)
catalog_key_map.update(self._getMapFromKeyList(new_key_list))
return self._getListFromKeyMap(catalog_key_map)
class CatalogSearchKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_search_keys'
key_list_title = 'search_key_list'
key_title = 'Search key'
......@@ -4273,7 +4292,7 @@ class CatalogResultKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_title = 'result_key_list'
key_title = 'Result key'
class CatalogRelatedKeyTemplateItem(CatalogKeyTemplateItemBase):
class CatalogRelatedKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_related_keys'
key_list_title = 'related_key_list'
key_title = 'Related key'
......@@ -4326,17 +4345,17 @@ class CatalogTopicKeyTemplateItem(CatalogKeyTemplateItemBase):
key_list_title = 'topic_key_list'
key_title = 'Topic key'
class CatalogScriptableKeyTemplateItem(CatalogKeyTemplateItemBase):
class CatalogScriptableKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_scriptable_keys'
key_list_title = 'scriptable_key_list'
key_title = 'Scriptable key'
class CatalogRoleKeyTemplateItem(CatalogKeyTemplateItemBase):
class CatalogRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_role_keys'
key_list_title = 'role_key_list'
key_title = 'Role key'
class CatalogLocalRoleKeyTemplateItem(CatalogKeyTemplateItemBase):
class CatalogLocalRoleKeyTemplateItem(CatalogUniqueKeyTemplateItemBase):
key_list_attr = 'sql_catalog_local_role_keys'
key_list_title = 'local_role_key_list'
key_title = 'LocalRole key'
......
......@@ -1898,6 +1898,66 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor
self.failUnless('catalog.reference'
in catalog.sql_search_result_keys)
def stepModifyRelatedKey(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_list = list(catalog.sql_catalog_related_keys)
related_key_list.remove(related_key)
# related_key_2 <- 'fake_id | category/catalog/z_fake_method_2':
related_key_2 = related_key + '_2'
related_key_list.append(related_key_2)
catalog.sql_catalog_related_keys = tuple(related_key_list)
sequence['related_key_2'] = related_key_2
# check related key column is not present twice:
self.assertTrue(related_key_2.startswith('fake_id |'), related_key_2)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepCheckRelatedKeyNonDuplicated(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
# stepModifyRelatedKey added related_key_2 and removed related_key
# but the reinstallation of the BT replaced related_key_2 with
# related_key:
self.assertTrue(related_key in related_key_list)
self.assertFalse(related_key_2 in related_key_list)
# make sure there's only one entry
self.assertTrue(related_key.startswith('fake_id |'), related_key)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepDuplicateRelatedKeyColumn(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
self.assertTrue(related_key in related_key_list)
self.assertFalse(related_key_2 in related_key_list)
# we manually duplicate the key in the list, creating an invalid situation
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
related_key_list.append(related_key_2)
catalog.sql_catalog_related_keys = tuple(related_key_list)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 2)
def stepCheckOnlyDuplicateRelatedKeyRemains(self, sequence):
catalog = self.getCatalogTool().getSQLCatalog()
related_key = sequence['related_key']
related_key_2 = sequence['related_key_2']
related_key_list = list(catalog.sql_catalog_related_keys)
# after the uninstallation of the BT, only the wrong/duplicated
# entry remains because the original was uninstalled with the BT.
# This also means that an uninstallation of a BT does not
# accidentally removes an overriding key from another BT that
# depends on it.
self.assertFalse(related_key in related_key_list)
self.assertTrue(related_key_2 in related_key_list)
self.assertEqual(len([key for key in related_key_list
if key.startswith('fake_id |')]), 1)
def stepRemoveCatalogLocalConfiguration(self, sequence, **kw):
"""
Remove modification made in stepModifyCatalogConfiguration
......@@ -1919,7 +1979,13 @@ class BusinessTemplateMixin(TestDeveloperMixin, ERP5TypeTestCase, LogInterceptor
sql_search_tables.remove(result_table)
sql_search_tables.sort()
catalog.sql_search_tables = tuple(sql_search_tables)
self.failUnless(result_table not in catalog.sql_search_tables)
self.assertFalse(result_table in catalog.sql_search_tables)
# related key
related_key_2 = sequence['related_key_2']
sql_catalog_related_keys = list(catalog.sql_catalog_related_keys)
sql_catalog_related_keys.remove(related_key_2)
catalog.sql_catalog_related_keys = tuple(sql_catalog_related_keys)
self.assertFalse(related_key_2 in catalog.sql_catalog_related_keys)
def stepAddKeysAndTableToBusinessTemplate(self, sequence=None, **kw):
"""
......@@ -5250,7 +5316,10 @@ class TestBusinessTemplate(BusinessTemplateMixin):
sequence_list.play(self)
def test_30_CheckInstalledCatalogProperties(self):
"""Test if installing some new catalog properties overwrites existing ones"""
"""
Test if installing some new catalog properties do not overwrite existing ones
Also check that it doesn't install two keys for the same column"""
sequence_list = SequenceList()
sequence_string = '\
CreateCatalogMethod \
......@@ -5262,12 +5331,16 @@ class TestBusinessTemplate(BusinessTemplateMixin):
BuildBusinessTemplate \
SaveBusinessTemplate \
ModifyCatalogConfiguration \
ModifyRelatedKey \
ImportBusinessTemplate \
UseImportBusinessTemplate \
InstallBusinessTemplate \
Tic \
CheckCatalogConfigurationKept \
CheckRelatedKeyNonDuplicated \
DuplicateRelatedKeyColumn \
UninstallBusinessTemplate \
CheckOnlyDuplicateRelatedKeyRemains \
CheckCatalogConfigurationKept \
RemoveCatalogLocalConfiguration \
'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment