Skip to content

Commit

Permalink
Merge b1f7284 into bb92414
Browse files Browse the repository at this point in the history
  • Loading branch information
thet committed Mar 8, 2021
2 parents bb92414 + b1f7284 commit a1790c7
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 13 deletions.
3 changes: 3 additions & 0 deletions news/452.bugfix
@@ -0,0 +1,3 @@
Fix plone.api.content.find to respect object_provides "not" queries.
Fixes: #451
[thet]
2 changes: 2 additions & 0 deletions news/452.feature
@@ -0,0 +1,2 @@
Adapt flake8 to Plone/black standards.
[thet]
7 changes: 2 additions & 5 deletions setup.cfg
Expand Up @@ -4,11 +4,8 @@ ignore =
.travis.yml

[flake8]
exclude =
bootstrap-buildout.py,

ignore =
W503
max-line-length = 88
extend-ignore = E203, W503

[isort]
force_alphabetical_sort=True
Expand Down
33 changes: 25 additions & 8 deletions src/plone/api/content.py
Expand Up @@ -594,18 +594,35 @@ def _parse_object_provides_query(query):
query for multiple values
(eg. `{'query': [Iface1, Iface2], 'operator': 'or'}`)
"""
operator = 'or'
ifaces = query
operator = 'or'
query_not = []

if isinstance(query, dict):
operator = query.get('operator', operator)
ifaces = query.get('query', [])
elif not isinstance(query, (list, tuple)):
ifaces = [query]
operator = query.get('operator', operator)
query_not = query.get('not', [])
# KeywordIndex also supports "range",
# but that's not useful for querying object_provides

if not isinstance(ifaces, (list, tuple)):
ifaces = [ifaces]
ifaces = [getattr(x, '__identifier__', x) for x in ifaces]

if not isinstance(query_not, (list, tuple)):
query_not = [query_not]
query_not = [getattr(x, '__identifier__', x) for x in query_not]

result = {}

if ifaces:
result['query'] = ifaces
result['operator'] = operator

if query_not:
result['not'] = query_not

return {
'query': [getattr(x, '__identifier__', x) for x in ifaces],
'operator': operator,
}
return result


def find(context=None, depth=None, **kwargs):
Expand Down
69 changes: 69 additions & 0 deletions src/plone/api/tests/test_content.py
Expand Up @@ -6,6 +6,7 @@
from OFS.event import ObjectWillBeMovedEvent
from OFS.interfaces import IObjectWillBeMovedEvent
from plone import api
from plone.api.content import _parse_object_provides_query
from plone.api.content import NEW_LINKINTEGRITY
from plone.api.tests.base import INTEGRATION_TESTING
from plone.app.layout.navigation.interfaces import INavigationRoot
Expand Down Expand Up @@ -1049,6 +1050,74 @@ def test_find_interface_dict(self):
)
self.assertEqual(len(brains), 1)

def test_find_interface_dict__include_not_query(self):
"""Check if not query in object_provides is functional.
"""

brains_all = api.content.find(
object_provides={'query': IContentish.__identifier__},
)

alsoProvides(self.portal.events, INavigationRoot)
self.portal.events.reindexObject(idxs=['object_provides'])

brains = api.content.find(
object_provides={
'query': IContentish.__identifier__,
'not': INavigationRoot.__identifier__,
},
)

self.assertEqual(len(brains_all) - len(brains), 1)

def test_find_interface_dict__all_options(self):
""" Check for all options in a object_provides query are correctly
transformed.
"""
parser = _parse_object_provides_query

self.assertDictEqual(
parser({'query': IContentish}),
{'query': [IContentish.__identifier__], 'operator': 'or'},
)

self.assertDictEqual(
parser(
{
'query': [IContentish, INavigationRoot.__identifier__],
'operator': 'and',
},
),
{
'query': [IContentish.__identifier__, INavigationRoot.__identifier__],
'operator': 'and',
},
)

self.assertDictEqual(
parser({'not': IContentish}),
{'not': [IContentish.__identifier__]},
)

self.assertDictEqual(
parser({'not': [IContentish, INavigationRoot.__identifier__]}),
{'not': [IContentish.__identifier__, INavigationRoot.__identifier__]},
)

self.assertDictEqual(
parser({'not': IContentish}),
{'not': [IContentish.__identifier__]},
)

self.assertDictEqual(
parser({'query': IContentish, 'operator': 'and', 'not': INavigationRoot}),
{
'query': [IContentish.__identifier__],
'operator': 'and',
'not': [INavigationRoot.__identifier__],
},
)

def test_find_dict(self):
# Pass arguments using dict
path = '/'.join(self.portal.about.getPhysicalPath())
Expand Down

0 comments on commit a1790c7

Please sign in to comment.