Commit c139fb83 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

Predicate: support NULL membership criteria.

parent e79e888a
...@@ -65,6 +65,12 @@ class TestPredicateMixIn(ERP5TypeTestCase): ...@@ -65,6 +65,12 @@ class TestPredicateMixIn(ERP5TypeTestCase):
self.createCategories() self.createCategories()
self.login() self.login()
def beforeTearDown(self):
self.portal.organisation_module.manage_delObjects(
ids=list(self.portal.organisation_module.objectIds())
)
self.tic()
def playSequence(self, sequence_string, quiet=QUIET) : def playSequence(self, sequence_string, quiet=QUIET) :
# don't commit between steps # don't commit between steps
sequence = Sequence() sequence = Sequence()
...@@ -323,6 +329,21 @@ class TestPredicates(TestPredicateMixIn): ...@@ -323,6 +329,21 @@ class TestPredicates(TestPredicateMixIn):
['region/europe/western_europe/germany']) ['region/europe/western_europe/germany'])
self.assertFalse(pred.test(doc)) self.assertFalse(pred.test(doc))
def test_BasicCategoryNullMembership(self):
# if the document is any member of the base category, the predicate returns
# false
doc1 = self.createDocument()
doc2 = self.createDocument(region='europe/western_europe/france',)
self.tic()
pred = self.createPredicate(
membership_criterion_base_category_list=['region'],
membership_criterion_category_list=['region/NULL'])
self.assertTrue(pred.test(doc1))
self.assertFalse(pred.test(doc2))
self.assertItemsEqual(
[doc1],
[x.getObject() for x in pred.searchResults(portal_type='Organisation')]
)
def test_NonExistantCategoryMembership(self): def test_NonExistantCategoryMembership(self):
# the predicate also return false for non existant category and no error is # the predicate also return false for non existant category and no error is
......
...@@ -1170,7 +1170,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject): ...@@ -1170,7 +1170,7 @@ class CatalogTool (UniqueObject, ZCatalog, CMFCoreCatalogTool, ActiveObject):
for base_category_id, document_set in base_category_dict.iteritems(): for base_category_id, document_set in base_category_dict.iteritems():
column = prefix + base_category_id + suffix column = prefix + base_category_id + suffix
category_query = SimpleQuery(**{ category_query = SimpleQuery(**{
column: {document.getUid() for document in document_set}, column: {None if document is None else document.getUid() for document in document_set},
}) })
extra_query = onJoin(column) extra_query = onJoin(column)
if extra_query is not None: if extra_query is not None:
......
...@@ -159,14 +159,17 @@ class Predicate(XMLObject): ...@@ -159,14 +159,17 @@ class Predicate(XMLObject):
isMemberOf = context._getCategoryTool().isMemberOf isMemberOf = context._getCategoryTool().isMemberOf
with readOnlyTransactionCache(): with readOnlyTransactionCache():
for c in membership_criterion_category_list: for c in membership_criterion_category_list:
bc = c.split('/', 1)[0] bc, c_path = c.split('/', 1)
is_null = c_path == 'NULL'
if tested_base_category_list is None or bc in tested_base_category_list: if tested_base_category_list is None or bc in tested_base_category_list:
if bc in multimembership_criterion_base_category_list: if bc in multimembership_criterion_base_category_list:
if not isMemberOf(context, c, strict_membership=strict_membership): if (is_null and isMemberOf(context, bc, strict_membership=False)) or \
not isMemberOf(context, c, strict_membership=strict_membership):
return 0 return 0
elif bc in membership_criterion_base_category_list and \ elif bc in membership_criterion_base_category_list and \
not tested_base_category.get(bc): not tested_base_category.get(bc):
tested_base_category[bc] = \ tested_base_category[bc] = \
(is_null and not isMemberOf(context, bc, strict_membership=False)) or \
isMemberOf(context, c, strict_membership=strict_membership) isMemberOf(context, c, strict_membership=strict_membership)
if 0 in tested_base_category.itervalues(): if 0 in tested_base_category.itervalues():
return 0 return 0
...@@ -248,7 +251,7 @@ class Predicate(XMLObject): ...@@ -248,7 +251,7 @@ class Predicate(XMLObject):
getCategoryParameterDict( getCategoryParameterDict(
filterCategoryList(getBaseCategorySet(), getCategoryList()), filterCategoryList(getBaseCategorySet(), getCategoryList()),
strict_membership=strict_membership, strict_membership=strict_membership,
onMissing=lambda category: False, onMissing=lambda category: category.split('/', 1)[1] == 'NULL',
), ),
) )
......
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