rer.solrpush 1.3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rer/solrpush/__init__.py +7 -0
- rer/solrpush/adapters/__init__.py +1 -0
- rer/solrpush/adapters/configure.zcml +13 -0
- rer/solrpush/adapters/file.py +52 -0
- rer/solrpush/adapters/rss_feed.py +28 -0
- rer/solrpush/behaviors/__init__.py +0 -0
- rer/solrpush/behaviors/configure.zcml +16 -0
- rer/solrpush/behaviors/solr_fields.py +41 -0
- rer/solrpush/browser/__init__.py +0 -0
- rer/solrpush/browser/configure.zcml +111 -0
- rer/solrpush/browser/controlpanel.py +96 -0
- rer/solrpush/browser/elevate_settings.py +35 -0
- rer/solrpush/browser/maintenance.py +476 -0
- rer/solrpush/browser/query_debug.py +12 -0
- rer/solrpush/browser/querybuilder.py +168 -0
- rer/solrpush/browser/scales.py +80 -0
- rer/solrpush/browser/static/.gitkeep +0 -0
- rer/solrpush/browser/static/dist/dev/main.js +58240 -0
- rer/solrpush/browser/static/dist/dev/main.js.map +180 -0
- rer/solrpush/browser/static/dist/prod/main.js +9604 -0
- rer/solrpush/browser/static/dist/prod/main.js.map +1 -0
- rer/solrpush/browser/static/javascripts/FacetsContainer/index.js +46 -0
- rer/solrpush/browser/static/javascripts/ProgressBar/index.js +40 -0
- rer/solrpush/browser/static/javascripts/ProgressBarContainer/index.js +66 -0
- rer/solrpush/browser/static/javascripts/index.js +14 -0
- rer/solrpush/browser/static/package.json +13 -0
- rer/solrpush/browser/static/styles.css +22 -0
- rer/solrpush/browser/static/styles.css.map +1 -0
- rer/solrpush/browser/static/styles.scss +27 -0
- rer/solrpush/browser/static/yarn.lock +1408 -0
- rer/solrpush/browser/templates/controlpanel_layout.pt +49 -0
- rer/solrpush/browser/templates/query_debug.pt +17 -0
- rer/solrpush/browser/templates/reindex_solr.pt +35 -0
- rer/solrpush/configure.zcml +81 -0
- rer/solrpush/indexer.py +120 -0
- rer/solrpush/interfaces/__init__.py +8 -0
- rer/solrpush/interfaces/adapter.py +13 -0
- rer/solrpush/interfaces/elevate.py +98 -0
- rer/solrpush/interfaces/layer.py +6 -0
- rer/solrpush/interfaces/queueprocessor.py +6 -0
- rer/solrpush/interfaces/settings.py +194 -0
- rer/solrpush/locales/README.rst +37 -0
- rer/solrpush/locales/__init__.py +0 -0
- rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.mo +0 -0
- rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.po +399 -0
- rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.mo +0 -0
- rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.po +399 -0
- rer/solrpush/locales/rer.solrpush.pot +402 -0
- rer/solrpush/locales/update.py +71 -0
- rer/solrpush/locales/update.sh +12 -0
- rer/solrpush/parser.py +211 -0
- rer/solrpush/permissions.zcml +18 -0
- rer/solrpush/profiles/default/actions.xml +21 -0
- rer/solrpush/profiles/default/browserlayer.xml +7 -0
- rer/solrpush/profiles/default/catalog.xml +4 -0
- rer/solrpush/profiles/default/controlpanel.xml +31 -0
- rer/solrpush/profiles/default/metadata.xml +8 -0
- rer/solrpush/profiles/default/registry/bundle.xml +25 -0
- rer/solrpush/profiles/default/registry/criteria.xml +55 -0
- rer/solrpush/profiles/default/registry/settings.xml +6 -0
- rer/solrpush/profiles/default/rolemap.xml +13 -0
- rer/solrpush/profiles/default/types/Document.xml +12 -0
- rer/solrpush/profiles/to_1100/componentregistry.xml +9 -0
- rer/solrpush/profiles/to_1100/metadata.xml +5 -0
- rer/solrpush/profiles/to_1300/controlpanel.xml +13 -0
- rer/solrpush/profiles/to_1300/registry.xml +5 -0
- rer/solrpush/profiles/uninstall/browserlayer.xml +7 -0
- rer/solrpush/profiles/uninstall/controlpanel.xml +21 -0
- rer/solrpush/profiles/uninstall/registry.xml +17 -0
- rer/solrpush/restapi/__init__.py +0 -0
- rer/solrpush/restapi/configure.zcml +8 -0
- rer/solrpush/restapi/services/__init__.py +0 -0
- rer/solrpush/restapi/services/configure.zcml +8 -0
- rer/solrpush/restapi/services/elevate_schema/__init__.py +0 -0
- rer/solrpush/restapi/services/elevate_schema/configure.zcml +14 -0
- rer/solrpush/restapi/services/elevate_schema/get.py +12 -0
- rer/solrpush/restapi/services/solr_search/__init__.py +0 -0
- rer/solrpush/restapi/services/solr_search/batch.py +129 -0
- rer/solrpush/restapi/services/solr_search/configure.zcml +14 -0
- rer/solrpush/restapi/services/solr_search/get.py +25 -0
- rer/solrpush/restapi/services/solr_search/solr_search_handler.py +86 -0
- rer/solrpush/setuphandlers.py +20 -0
- rer/solrpush/testing.py +161 -0
- rer/solrpush/tests/__init__.py +0 -0
- rer/solrpush/tests/docs/example.docx +0 -0
- rer/solrpush/tests/docs/example.ods +0 -0
- rer/solrpush/tests/docs/example.pdf +0 -0
- rer/solrpush/tests/docs/plone_logo.png +0 -0
- rer/solrpush/tests/test_behaviors.py +61 -0
- rer/solrpush/tests/test_elevate.py +124 -0
- rer/solrpush/tests/test_events.py +181 -0
- rer/solrpush/tests/test_image_tags.py +85 -0
- rer/solrpush/tests/test_maintenance.py +165 -0
- rer/solrpush/tests/test_querybuilder.py +272 -0
- rer/solrpush/tests/test_restapi_search.py +127 -0
- rer/solrpush/tests/test_search.py +177 -0
- rer/solrpush/tests/test_setup.py +67 -0
- rer/solrpush/tests/test_solr_interface.py +359 -0
- rer/solrpush/tests/test_tika.py +85 -0
- rer/solrpush/tests/test_vocabularies.py +113 -0
- rer/solrpush/upgrades.py +76 -0
- rer/solrpush/upgrades.zcml +86 -0
- rer/solrpush/utils/__init__.py +6 -0
- rer/solrpush/utils/solr_common.py +122 -0
- rer/solrpush/utils/solr_indexer.py +295 -0
- rer/solrpush/utils/solr_search.py +352 -0
- rer/solrpush/vocabularies.py +50 -0
- rer.solrpush-1.3.4-py3.10-nspkg.pth +1 -0
- rer.solrpush-1.3.4.dist-info/LICENSE.GPL +339 -0
- rer.solrpush-1.3.4.dist-info/LICENSE.rst +15 -0
- rer.solrpush-1.3.4.dist-info/METADATA +507 -0
- rer.solrpush-1.3.4.dist-info/RECORD +116 -0
- rer.solrpush-1.3.4.dist-info/WHEEL +5 -0
- rer.solrpush-1.3.4.dist-info/entry_points.txt +5 -0
- rer.solrpush-1.3.4.dist-info/namespace_packages.txt +1 -0
- rer.solrpush-1.3.4.dist-info/top_level.txt +1 -0
rer/solrpush/testing.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from plone.api.portal import set_registry_record
|
|
3
|
+
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
|
|
4
|
+
from plone.app.testing import applyProfile
|
|
5
|
+
from plone.app.testing import FunctionalTesting
|
|
6
|
+
from plone.app.testing import IntegrationTesting
|
|
7
|
+
from plone.app.testing import PloneSandboxLayer
|
|
8
|
+
from plone.restapi.testing import PloneRestApiDXLayer
|
|
9
|
+
from plone.testing import Layer
|
|
10
|
+
from plone.testing import z2
|
|
11
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
12
|
+
from rer.solrpush.utils import init_solr_push
|
|
13
|
+
from six.moves import range
|
|
14
|
+
from time import sleep
|
|
15
|
+
from ZPublisher.HTTPRequest import HTTPRequest
|
|
16
|
+
|
|
17
|
+
import collective.z3cform.jsonwidget
|
|
18
|
+
import os
|
|
19
|
+
import plone.restapi
|
|
20
|
+
import rer.solrpush
|
|
21
|
+
import six
|
|
22
|
+
import subprocess
|
|
23
|
+
import sys
|
|
24
|
+
|
|
25
|
+
BIN_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SolrLayer(Layer):
|
|
29
|
+
"""Solr test layer that fires up and shuts down a Solr instance. This
|
|
30
|
+
layer can be used to unit test a Solr configuration without having to
|
|
31
|
+
fire up Plone.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
proc = None
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self,
|
|
38
|
+
bases=None,
|
|
39
|
+
name="Solr Layer",
|
|
40
|
+
module=None,
|
|
41
|
+
solr_host="localhost",
|
|
42
|
+
solr_port=8983,
|
|
43
|
+
solr_base="/solr/solrpush_test",
|
|
44
|
+
):
|
|
45
|
+
super(SolrLayer, self).__init__(bases, name, module)
|
|
46
|
+
self.solr_host = solr_host
|
|
47
|
+
self.solr_port = solr_port
|
|
48
|
+
self.solr_base = solr_base
|
|
49
|
+
self.solr_url = u"http://{0}:{1}{2}".format(
|
|
50
|
+
solr_host, solr_port, solr_base
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def setUp(self):
|
|
54
|
+
"""Start Solr and poll until it is up and running."""
|
|
55
|
+
self.proc = subprocess.call(
|
|
56
|
+
"./solr-start", shell=True, close_fds=True, cwd=BIN_DIR
|
|
57
|
+
)
|
|
58
|
+
# Poll Solr until it is up and running
|
|
59
|
+
solr_ping_url = "{0}/admin/ping?wt=xml".format(self.solr_url)
|
|
60
|
+
for i in range(1, 10):
|
|
61
|
+
try:
|
|
62
|
+
result = six.moves.urllib.request.urlopen(solr_ping_url)
|
|
63
|
+
if result.code == 200:
|
|
64
|
+
if b'<str name="status">OK</str>' in result.read():
|
|
65
|
+
break
|
|
66
|
+
except six.moves.urllib.error.URLError:
|
|
67
|
+
sleep(3)
|
|
68
|
+
sys.stdout.write(".")
|
|
69
|
+
if i == 9:
|
|
70
|
+
subprocess.call(
|
|
71
|
+
"./solr-stop", shell=True, close_fds=True, cwd=BIN_DIR
|
|
72
|
+
)
|
|
73
|
+
sys.stdout.write("Solr Instance could not be started !!!")
|
|
74
|
+
|
|
75
|
+
def tearDown(self):
|
|
76
|
+
"""Stop Solr."""
|
|
77
|
+
solr_clean_url = "{0}/update?stream.body=<delete><query>*:*</query></delete>&commit=true".format( # noqa
|
|
78
|
+
self.solr_url
|
|
79
|
+
)
|
|
80
|
+
six.moves.urllib.request.urlopen(solr_clean_url)
|
|
81
|
+
subprocess.check_call(
|
|
82
|
+
"./solr-stop", shell=True, close_fds=True, cwd=BIN_DIR
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
SOLR_FIXTURE = SolrLayer()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class RerSolrpushRestApiLayer(PloneRestApiDXLayer):
|
|
90
|
+
""" """
|
|
91
|
+
|
|
92
|
+
defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
bases=None,
|
|
97
|
+
name="SolrPush Layer",
|
|
98
|
+
module=None,
|
|
99
|
+
solr_host=u"localhost",
|
|
100
|
+
solr_port=8983,
|
|
101
|
+
solr_base=u"/solr/solrpush_test",
|
|
102
|
+
):
|
|
103
|
+
super(PloneSandboxLayer, self).__init__(bases, name, module)
|
|
104
|
+
self.solr_host = solr_host
|
|
105
|
+
self.solr_port = solr_port
|
|
106
|
+
self.solr_base = solr_base
|
|
107
|
+
# SolrLayer should use the same settings as CollectiveSolrLayer
|
|
108
|
+
self.solr_layer = SolrLayer(
|
|
109
|
+
bases,
|
|
110
|
+
name,
|
|
111
|
+
module,
|
|
112
|
+
solr_host=solr_host,
|
|
113
|
+
solr_port=solr_port,
|
|
114
|
+
solr_base=solr_base,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
def setUpZope(self, app, configurationContext):
|
|
118
|
+
# Load any other ZCML that is required for your tests.
|
|
119
|
+
# The z3c.autoinclude feature is disabled in the Plone fixture base
|
|
120
|
+
# layer.
|
|
121
|
+
self._orig_retry_max_count = HTTPRequest.retry_max_count
|
|
122
|
+
HTTPRequest.retry_max_count = 3
|
|
123
|
+
|
|
124
|
+
self.loadZCML(package=rer.solrpush)
|
|
125
|
+
self.loadZCML(package=plone.restapi)
|
|
126
|
+
self.loadZCML(package=collective.z3cform.jsonwidget)
|
|
127
|
+
|
|
128
|
+
def tearDownZope(self, app):
|
|
129
|
+
HTTPRequest.retry_max_count = self._orig_retry_max_count
|
|
130
|
+
|
|
131
|
+
def setUpPloneSite(self, portal):
|
|
132
|
+
self.solr_layer.setUp()
|
|
133
|
+
applyProfile(portal, "rer.solrpush:default")
|
|
134
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
135
|
+
set_registry_record(
|
|
136
|
+
"solr_url",
|
|
137
|
+
self.solr_layer.solr_url,
|
|
138
|
+
interface=IRerSolrpushSettings,
|
|
139
|
+
)
|
|
140
|
+
init_solr_push()
|
|
141
|
+
|
|
142
|
+
def tearDownPloneSite(self, portal):
|
|
143
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
144
|
+
set_registry_record(
|
|
145
|
+
"solr_url",
|
|
146
|
+
self.solr_layer.solr_url,
|
|
147
|
+
interface=IRerSolrpushSettings,
|
|
148
|
+
)
|
|
149
|
+
self.solr_layer.tearDown()
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
RER_SOLRPUSH_API_FIXTURE = RerSolrpushRestApiLayer()
|
|
153
|
+
RER_SOLRPUSH_API_INTEGRATION_TESTING = IntegrationTesting(
|
|
154
|
+
bases=(RER_SOLRPUSH_API_FIXTURE,),
|
|
155
|
+
name="RerSolrpushRestApiLayer:Integration",
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
RER_SOLRPUSH_API_FUNCTIONAL_TESTING = FunctionalTesting(
|
|
159
|
+
bases=(RER_SOLRPUSH_API_FIXTURE, z2.ZSERVER_FIXTURE),
|
|
160
|
+
name="RerSolrpushRestApiLayer:Functional",
|
|
161
|
+
)
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Setup tests for this package."""
|
|
3
|
+
from plone import api
|
|
4
|
+
from plone.api.portal import set_registry_record
|
|
5
|
+
from plone.app.testing import setRoles
|
|
6
|
+
from plone.app.testing import TEST_USER_ID
|
|
7
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
8
|
+
from rer.solrpush.utils import init_solr_push
|
|
9
|
+
from rer.solrpush.utils import reset_solr
|
|
10
|
+
from rer.solrpush.utils import search
|
|
11
|
+
from rer.solrpush.testing import (
|
|
12
|
+
RER_SOLRPUSH_API_FUNCTIONAL_TESTING,
|
|
13
|
+
) # noqa: E501
|
|
14
|
+
from transaction import commit
|
|
15
|
+
|
|
16
|
+
import unittest
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestShowInSearch(unittest.TestCase):
|
|
20
|
+
"""Test show in search field behavior."""
|
|
21
|
+
|
|
22
|
+
layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
23
|
+
|
|
24
|
+
def setUp(self):
|
|
25
|
+
"""
|
|
26
|
+
We create objects before initializing solr settings, so solr core is
|
|
27
|
+
always empty on setUp.
|
|
28
|
+
"""
|
|
29
|
+
self.portal = self.layer["portal"]
|
|
30
|
+
self.request = self.layer["request"]
|
|
31
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
32
|
+
set_registry_record(
|
|
33
|
+
"enabled_types",
|
|
34
|
+
[u"Document", u"News Item"],
|
|
35
|
+
interface=IRerSolrpushSettings,
|
|
36
|
+
)
|
|
37
|
+
init_solr_push()
|
|
38
|
+
self.document = api.content.create(
|
|
39
|
+
container=self.portal, type="Document", title="Document foo"
|
|
40
|
+
)
|
|
41
|
+
api.content.transition(obj=self.document, transition="publish")
|
|
42
|
+
self.news = api.content.create(
|
|
43
|
+
container=self.portal, type="News Item", title="News bar"
|
|
44
|
+
)
|
|
45
|
+
api.content.transition(obj=self.news, transition="publish")
|
|
46
|
+
commit()
|
|
47
|
+
|
|
48
|
+
def tearDown(self):
|
|
49
|
+
reset_solr()
|
|
50
|
+
commit()
|
|
51
|
+
|
|
52
|
+
def test_items_are_indexed_by_default(self):
|
|
53
|
+
solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
|
|
54
|
+
self.assertEqual(solr_results.hits, 2)
|
|
55
|
+
|
|
56
|
+
def test_items_are_unindexed_when_set_false(self):
|
|
57
|
+
self.document.showinsearch = False
|
|
58
|
+
self.document.reindexObject()
|
|
59
|
+
commit()
|
|
60
|
+
solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
|
|
61
|
+
self.assertEqual(solr_results.hits, 1)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Setup tests for this package."""
|
|
3
|
+
from plone import api
|
|
4
|
+
from plone.api.portal import set_registry_record
|
|
5
|
+
from plone.app.testing import setRoles
|
|
6
|
+
from plone.app.testing import TEST_USER_ID
|
|
7
|
+
from rer.solrpush.interfaces import IElevateSettings
|
|
8
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
9
|
+
from rer.solrpush.utils import init_solr_push
|
|
10
|
+
from rer.solrpush.utils import reset_solr
|
|
11
|
+
from rer.solrpush.utils import search
|
|
12
|
+
from rer.solrpush.testing import RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
13
|
+
from transaction import commit
|
|
14
|
+
|
|
15
|
+
import unittest
|
|
16
|
+
import json
|
|
17
|
+
import six
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestSolrSearch(unittest.TestCase):
|
|
21
|
+
"""
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
25
|
+
|
|
26
|
+
def setUp(self):
|
|
27
|
+
"""
|
|
28
|
+
"""
|
|
29
|
+
self.portal = self.layer["portal"]
|
|
30
|
+
self.request = self.layer["request"]
|
|
31
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
32
|
+
set_registry_record(
|
|
33
|
+
"enabled_types",
|
|
34
|
+
[u"Document", u"News Item"],
|
|
35
|
+
interface=IRerSolrpushSettings,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
init_solr_push()
|
|
39
|
+
commit()
|
|
40
|
+
self.doc1 = api.content.create(
|
|
41
|
+
container=self.portal,
|
|
42
|
+
type="Document",
|
|
43
|
+
title="First page",
|
|
44
|
+
description="lorem ipsum",
|
|
45
|
+
subject=["foo", "bar"],
|
|
46
|
+
)
|
|
47
|
+
self.doc2 = api.content.create(
|
|
48
|
+
container=self.portal,
|
|
49
|
+
type="Document",
|
|
50
|
+
title="Second page",
|
|
51
|
+
description="lorem ipsum dolor sit amet",
|
|
52
|
+
searchwords="important",
|
|
53
|
+
)
|
|
54
|
+
self.unpublished_doc = api.content.create(
|
|
55
|
+
container=self.portal, type="Document", title="Unpublished page"
|
|
56
|
+
)
|
|
57
|
+
self.published_news = api.content.create(
|
|
58
|
+
container=self.portal,
|
|
59
|
+
type="News Item",
|
|
60
|
+
title="Published News",
|
|
61
|
+
subject=["foo", "news category"],
|
|
62
|
+
)
|
|
63
|
+
self.unpublished_news = api.content.create(
|
|
64
|
+
container=self.portal,
|
|
65
|
+
type="News Item",
|
|
66
|
+
title="Unpublished News",
|
|
67
|
+
subject=["foo"],
|
|
68
|
+
)
|
|
69
|
+
self.event = api.content.create(
|
|
70
|
+
container=self.portal, type="Event", title="Event", subject=["foo"]
|
|
71
|
+
)
|
|
72
|
+
api.content.transition(obj=self.doc1, transition="publish")
|
|
73
|
+
api.content.transition(obj=self.doc2, transition="publish")
|
|
74
|
+
api.content.transition(obj=self.published_news, transition="publish")
|
|
75
|
+
api.content.transition(obj=self.event, transition="publish")
|
|
76
|
+
commit()
|
|
77
|
+
|
|
78
|
+
def tearDown(self):
|
|
79
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
80
|
+
# reset elevate
|
|
81
|
+
set_registry_record("elevate_schema", u"", interface=IElevateSettings)
|
|
82
|
+
reset_solr()
|
|
83
|
+
commit()
|
|
84
|
+
|
|
85
|
+
def test_search_with_elevate(self):
|
|
86
|
+
doc3 = api.content.create(
|
|
87
|
+
container=self.portal, type="Document", title="Third page"
|
|
88
|
+
)
|
|
89
|
+
# page with the shortest title containing keyword has the better score
|
|
90
|
+
doc4 = api.content.create(
|
|
91
|
+
container=self.portal, type="Document", title="page"
|
|
92
|
+
)
|
|
93
|
+
api.content.transition(obj=doc3, transition="publish")
|
|
94
|
+
api.content.transition(obj=doc4, transition="publish")
|
|
95
|
+
commit()
|
|
96
|
+
|
|
97
|
+
solr_results = search(
|
|
98
|
+
query={"SearchableText": "page"}, fl=["UID", "Title", "[elevated]"]
|
|
99
|
+
).docs
|
|
100
|
+
self.assertEqual(len(solr_results), 4)
|
|
101
|
+
self.assertEqual(
|
|
102
|
+
solr_results[0],
|
|
103
|
+
{"UID": doc4.UID(), "Title": doc4.Title(), "[elevated]": False},
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# now let's set an elevate for third document
|
|
107
|
+
value = json.dumps([{"text": [u"page"], "uid": [{"UID": doc3.UID()}]}])
|
|
108
|
+
if six.PY2:
|
|
109
|
+
value = value.decode("utf-8")
|
|
110
|
+
set_registry_record(
|
|
111
|
+
"elevate_schema", value, interface=IElevateSettings,
|
|
112
|
+
)
|
|
113
|
+
solr_results = search(
|
|
114
|
+
query={"SearchableText": "page"}, fl=["UID", "Title", "[elevated]"]
|
|
115
|
+
).docs
|
|
116
|
+
self.assertEqual(len(solr_results), 4)
|
|
117
|
+
self.assertEqual(
|
|
118
|
+
solr_results[0],
|
|
119
|
+
{"UID": doc3.UID(), "Title": doc3.Title(), "[elevated]": True},
|
|
120
|
+
)
|
|
121
|
+
self.assertEqual(
|
|
122
|
+
solr_results[1],
|
|
123
|
+
{"UID": doc4.UID(), "Title": doc4.Title(), "[elevated]": False},
|
|
124
|
+
)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Setup tests for this package."""
|
|
3
|
+
from plone import api
|
|
4
|
+
from plone.api.portal import get_registry_record
|
|
5
|
+
from plone.api.portal import set_registry_record
|
|
6
|
+
from plone.app.testing import setRoles
|
|
7
|
+
from plone.app.testing import TEST_USER_ID
|
|
8
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
9
|
+
from rer.solrpush.utils import init_solr_push
|
|
10
|
+
from rer.solrpush.testing import (
|
|
11
|
+
RER_SOLRPUSH_API_FUNCTIONAL_TESTING,
|
|
12
|
+
) # noqa: E501
|
|
13
|
+
from transaction import commit
|
|
14
|
+
from zope.event import notify
|
|
15
|
+
from zope.lifecycleevent import ObjectModifiedEvent
|
|
16
|
+
from rer.solrpush.utils import reset_solr
|
|
17
|
+
|
|
18
|
+
import requests
|
|
19
|
+
import unittest
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from Products.CMFPlone.utils import get_installer
|
|
23
|
+
except ImportError:
|
|
24
|
+
get_installer = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TestSOLRPush(unittest.TestCase):
|
|
28
|
+
"""Test that rer.solrpush is properly installed."""
|
|
29
|
+
|
|
30
|
+
layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
31
|
+
|
|
32
|
+
def setUp(self):
|
|
33
|
+
"""Custom shared utility setup for tests."""
|
|
34
|
+
self.portal = self.layer["portal"]
|
|
35
|
+
self.request = self.layer["request"]
|
|
36
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
37
|
+
set_registry_record(
|
|
38
|
+
"enabled_types",
|
|
39
|
+
[u"Document", u"File"],
|
|
40
|
+
interface=IRerSolrpushSettings,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
def tearDown(self):
|
|
44
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
45
|
+
reset_solr()
|
|
46
|
+
|
|
47
|
+
def test_item_not_indexed_if_solrpush_is_not_ready(self):
|
|
48
|
+
solr_url = get_registry_record("solr_url", IRerSolrpushSettings)
|
|
49
|
+
api.content.create(container=self.portal, type="Document", title="foo")
|
|
50
|
+
commit()
|
|
51
|
+
res = requests.get("{}/select?q=*%3A*&wt=json".format(solr_url)).json()
|
|
52
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
53
|
+
|
|
54
|
+
init_solr_push()
|
|
55
|
+
|
|
56
|
+
api.content.create(container=self.portal, type="Document", title="bar")
|
|
57
|
+
commit()
|
|
58
|
+
res = requests.get("{}/select?q=*%3A*&wt=json".format(solr_url)).json()
|
|
59
|
+
|
|
60
|
+
# because initial state id private
|
|
61
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
62
|
+
|
|
63
|
+
# File types has no wf, so they are published
|
|
64
|
+
api.content.create(
|
|
65
|
+
container=self.portal, type="File", title="bar file"
|
|
66
|
+
)
|
|
67
|
+
commit()
|
|
68
|
+
res = requests.get("{}/select?q=*%3A*&wt=json".format(solr_url)).json()
|
|
69
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestEvents(unittest.TestCase):
|
|
73
|
+
"""Test that rer.solrpush is properly installed."""
|
|
74
|
+
|
|
75
|
+
layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
76
|
+
|
|
77
|
+
def setUp(self):
|
|
78
|
+
"""Custom shared utility setup for tests."""
|
|
79
|
+
self.portal = self.layer["portal"]
|
|
80
|
+
self.request = self.layer["request"]
|
|
81
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
82
|
+
set_registry_record(
|
|
83
|
+
"enabled_types",
|
|
84
|
+
[u"Document", u"File"],
|
|
85
|
+
interface=IRerSolrpushSettings,
|
|
86
|
+
)
|
|
87
|
+
init_solr_push()
|
|
88
|
+
|
|
89
|
+
def tearDown(self):
|
|
90
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
91
|
+
reset_solr()
|
|
92
|
+
|
|
93
|
+
def clean_solr(self):
|
|
94
|
+
solr_url = get_registry_record("solr_url", IRerSolrpushSettings)
|
|
95
|
+
solr_clean_url = "{0}/update?stream.body=<delete><query>*:*</query></delete>&commit=true".format( # noqa
|
|
96
|
+
solr_url
|
|
97
|
+
)
|
|
98
|
+
requests.get(solr_clean_url)
|
|
99
|
+
|
|
100
|
+
def get_solr_results(self):
|
|
101
|
+
solr_url = get_registry_record("solr_url", IRerSolrpushSettings)
|
|
102
|
+
return requests.get(
|
|
103
|
+
"{}/select?q=*%3A*&wt=json".format(solr_url)
|
|
104
|
+
).json()
|
|
105
|
+
|
|
106
|
+
def create_indexed_doc(self):
|
|
107
|
+
published_doc = api.content.create(
|
|
108
|
+
container=self.portal, type="Document", title="foo"
|
|
109
|
+
)
|
|
110
|
+
api.content.transition(obj=published_doc, transition="publish")
|
|
111
|
+
commit()
|
|
112
|
+
return published_doc
|
|
113
|
+
|
|
114
|
+
def test_create_indexeable_content(self):
|
|
115
|
+
api.content.create(container=self.portal, type="Document", title="foo")
|
|
116
|
+
commit()
|
|
117
|
+
res = self.get_solr_results()
|
|
118
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
119
|
+
|
|
120
|
+
api.content.create(container=self.portal, type="File", title="foo")
|
|
121
|
+
commit()
|
|
122
|
+
res = self.get_solr_results()
|
|
123
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
124
|
+
|
|
125
|
+
def test_create_non_indexeable_content(self):
|
|
126
|
+
# we use images because hte don't have a workflow, like Files.
|
|
127
|
+
api.content.create(container=self.portal, type="Image", title="bara")
|
|
128
|
+
commit()
|
|
129
|
+
res = self.get_solr_results()
|
|
130
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
131
|
+
|
|
132
|
+
def test_edit_content(self):
|
|
133
|
+
doc = self.create_indexed_doc()
|
|
134
|
+
res = self.get_solr_results()
|
|
135
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
136
|
+
res_doc = res["response"]["docs"][0]
|
|
137
|
+
self.assertEqual("foo", res_doc.get("Title", ""))
|
|
138
|
+
self.assertEqual(res_doc.get("Description", ""), "")
|
|
139
|
+
|
|
140
|
+
doc.setDescription("foo description")
|
|
141
|
+
notify(ObjectModifiedEvent(doc))
|
|
142
|
+
commit()
|
|
143
|
+
|
|
144
|
+
res = self.get_solr_results()
|
|
145
|
+
res_doc = res["response"]["docs"][0]
|
|
146
|
+
self.assertEqual("foo description", res_doc.get("Description", ""))
|
|
147
|
+
|
|
148
|
+
def test_change_state(self):
|
|
149
|
+
doc = self.create_indexed_doc()
|
|
150
|
+
res = self.get_solr_results()
|
|
151
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
152
|
+
res_doc = res["response"]["docs"][0]
|
|
153
|
+
self.assertEqual("published", res_doc.get("review_state", ""))
|
|
154
|
+
api.content.transition(obj=doc, transition="retract")
|
|
155
|
+
commit()
|
|
156
|
+
|
|
157
|
+
res = self.get_solr_results()
|
|
158
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
159
|
+
|
|
160
|
+
def test_rename_content(self):
|
|
161
|
+
doc = self.create_indexed_doc()
|
|
162
|
+
res = self.get_solr_results()
|
|
163
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
164
|
+
res_doc = res["response"]["docs"][0]
|
|
165
|
+
self.assertEqual("foo", res_doc.get("id", ""))
|
|
166
|
+
api.content.rename(obj=doc, new_id="bar")
|
|
167
|
+
commit()
|
|
168
|
+
|
|
169
|
+
res = self.get_solr_results()
|
|
170
|
+
res_doc = res["response"]["docs"][0]
|
|
171
|
+
self.assertEqual("bar", res_doc.get("id", ""))
|
|
172
|
+
|
|
173
|
+
def test_delete_content(self):
|
|
174
|
+
doc = self.create_indexed_doc()
|
|
175
|
+
res = self.get_solr_results()
|
|
176
|
+
self.assertEqual(res["response"]["numFound"], 1)
|
|
177
|
+
api.content.delete(obj=doc)
|
|
178
|
+
commit()
|
|
179
|
+
|
|
180
|
+
res = self.get_solr_results()
|
|
181
|
+
self.assertEqual(res["response"]["numFound"], 0)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Setup tests for this package."""
|
|
3
|
+
from plone import api
|
|
4
|
+
from plone.api.portal import set_registry_record
|
|
5
|
+
from plone.app.testing import setRoles
|
|
6
|
+
from plone.app.testing import TEST_USER_ID
|
|
7
|
+
from plone.namedfile.file import NamedFile
|
|
8
|
+
from rer.solrpush.interfaces.settings import IRerSolrpushSettings
|
|
9
|
+
from rer.solrpush.utils import init_solr_push
|
|
10
|
+
from rer.solrpush.utils import reset_solr
|
|
11
|
+
from rer.solrpush.utils import search
|
|
12
|
+
from rer.solrpush.testing import RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
13
|
+
from transaction import commit
|
|
14
|
+
|
|
15
|
+
import unittest
|
|
16
|
+
import os
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class TestTika(unittest.TestCase):
|
|
20
|
+
"""Test solr indexing for files"""
|
|
21
|
+
|
|
22
|
+
layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
|
|
23
|
+
|
|
24
|
+
def setUp(self):
|
|
25
|
+
"""Custom shared utility setup for tests."""
|
|
26
|
+
self.portal = self.layer["portal"]
|
|
27
|
+
self.request = self.layer["request"]
|
|
28
|
+
setRoles(self.portal, TEST_USER_ID, ["Manager"])
|
|
29
|
+
set_registry_record(
|
|
30
|
+
"enabled_types", [u"File"], interface=IRerSolrpushSettings
|
|
31
|
+
)
|
|
32
|
+
init_solr_push()
|
|
33
|
+
commit()
|
|
34
|
+
|
|
35
|
+
def tearDown(self):
|
|
36
|
+
set_registry_record("active", True, interface=IRerSolrpushSettings)
|
|
37
|
+
reset_solr()
|
|
38
|
+
commit()
|
|
39
|
+
|
|
40
|
+
def create_file_item(self, filename):
|
|
41
|
+
item_file = None
|
|
42
|
+
with open(
|
|
43
|
+
os.path.join(os.path.dirname(__file__), "docs", filename), "rb"
|
|
44
|
+
) as f:
|
|
45
|
+
item_file = NamedFile(data=f.read(), filename=filename)
|
|
46
|
+
|
|
47
|
+
file_item = api.content.create(
|
|
48
|
+
container=self.portal, type="File", title=filename, file=item_file
|
|
49
|
+
)
|
|
50
|
+
commit()
|
|
51
|
+
return file_item
|
|
52
|
+
|
|
53
|
+
def test_index_and_extract_pdf(self):
|
|
54
|
+
file_item = self.create_file_item(u"example.pdf")
|
|
55
|
+
|
|
56
|
+
solr_results = search(query={"*": "*"}, fl="UID")
|
|
57
|
+
self.assertEqual(solr_results.hits, 1)
|
|
58
|
+
st_results = search(query={"SearchablesText": "lorem"}, fl="UID")
|
|
59
|
+
self.assertEqual(st_results.hits, 1)
|
|
60
|
+
self.assertEqual(file_item.UID(), st_results.docs[0]["UID"])
|
|
61
|
+
|
|
62
|
+
def test_index_and_extract_docx(self):
|
|
63
|
+
file_item = self.create_file_item(u"example.docx")
|
|
64
|
+
|
|
65
|
+
solr_results = search(query={"*": "*"}, fl="UID SearchableText")
|
|
66
|
+
self.assertEqual(solr_results.hits, 1)
|
|
67
|
+
st_results = search(query={"SearchableText": "ipsum"}, fl="UID")
|
|
68
|
+
self.assertEqual(st_results.hits, 1)
|
|
69
|
+
self.assertEqual(file_item.UID(), st_results.docs[0]["UID"])
|
|
70
|
+
|
|
71
|
+
def test_index_and_extract_ods(self):
|
|
72
|
+
file_item = self.create_file_item(u"example.ods")
|
|
73
|
+
|
|
74
|
+
solr_results = search(query={"*": "*"}, fl="UID SearchableText")
|
|
75
|
+
self.assertEqual(solr_results.hits, 1)
|
|
76
|
+
st_results = search(query={"SearchableText": "yyy"}, fl="UID")
|
|
77
|
+
self.assertEqual(st_results.hits, 1)
|
|
78
|
+
self.assertEqual(file_item.UID(), st_results.docs[0]["UID"])
|
|
79
|
+
|
|
80
|
+
def test_indexed_file_has_right_mimetype(self):
|
|
81
|
+
self.create_file_item(u"example.pdf")
|
|
82
|
+
|
|
83
|
+
solr_results = search(query={"*": "*"}, fl="UID mime_type")
|
|
84
|
+
self.assertEqual(solr_results.hits, 1)
|
|
85
|
+
self.assertEqual(solr_results.docs[0]["mime_type"], "application/pdf")
|