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.
Files changed (116) hide show
  1. rer/solrpush/__init__.py +7 -0
  2. rer/solrpush/adapters/__init__.py +1 -0
  3. rer/solrpush/adapters/configure.zcml +13 -0
  4. rer/solrpush/adapters/file.py +52 -0
  5. rer/solrpush/adapters/rss_feed.py +28 -0
  6. rer/solrpush/behaviors/__init__.py +0 -0
  7. rer/solrpush/behaviors/configure.zcml +16 -0
  8. rer/solrpush/behaviors/solr_fields.py +41 -0
  9. rer/solrpush/browser/__init__.py +0 -0
  10. rer/solrpush/browser/configure.zcml +111 -0
  11. rer/solrpush/browser/controlpanel.py +96 -0
  12. rer/solrpush/browser/elevate_settings.py +35 -0
  13. rer/solrpush/browser/maintenance.py +476 -0
  14. rer/solrpush/browser/query_debug.py +12 -0
  15. rer/solrpush/browser/querybuilder.py +168 -0
  16. rer/solrpush/browser/scales.py +80 -0
  17. rer/solrpush/browser/static/.gitkeep +0 -0
  18. rer/solrpush/browser/static/dist/dev/main.js +58240 -0
  19. rer/solrpush/browser/static/dist/dev/main.js.map +180 -0
  20. rer/solrpush/browser/static/dist/prod/main.js +9604 -0
  21. rer/solrpush/browser/static/dist/prod/main.js.map +1 -0
  22. rer/solrpush/browser/static/javascripts/FacetsContainer/index.js +46 -0
  23. rer/solrpush/browser/static/javascripts/ProgressBar/index.js +40 -0
  24. rer/solrpush/browser/static/javascripts/ProgressBarContainer/index.js +66 -0
  25. rer/solrpush/browser/static/javascripts/index.js +14 -0
  26. rer/solrpush/browser/static/package.json +13 -0
  27. rer/solrpush/browser/static/styles.css +22 -0
  28. rer/solrpush/browser/static/styles.css.map +1 -0
  29. rer/solrpush/browser/static/styles.scss +27 -0
  30. rer/solrpush/browser/static/yarn.lock +1408 -0
  31. rer/solrpush/browser/templates/controlpanel_layout.pt +49 -0
  32. rer/solrpush/browser/templates/query_debug.pt +17 -0
  33. rer/solrpush/browser/templates/reindex_solr.pt +35 -0
  34. rer/solrpush/configure.zcml +81 -0
  35. rer/solrpush/indexer.py +120 -0
  36. rer/solrpush/interfaces/__init__.py +8 -0
  37. rer/solrpush/interfaces/adapter.py +13 -0
  38. rer/solrpush/interfaces/elevate.py +98 -0
  39. rer/solrpush/interfaces/layer.py +6 -0
  40. rer/solrpush/interfaces/queueprocessor.py +6 -0
  41. rer/solrpush/interfaces/settings.py +194 -0
  42. rer/solrpush/locales/README.rst +37 -0
  43. rer/solrpush/locales/__init__.py +0 -0
  44. rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.mo +0 -0
  45. rer/solrpush/locales/en/LC_MESSAGES/rer.solrpush.po +399 -0
  46. rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.mo +0 -0
  47. rer/solrpush/locales/it/LC_MESSAGES/rer.solrpush.po +399 -0
  48. rer/solrpush/locales/rer.solrpush.pot +402 -0
  49. rer/solrpush/locales/update.py +71 -0
  50. rer/solrpush/locales/update.sh +12 -0
  51. rer/solrpush/parser.py +211 -0
  52. rer/solrpush/permissions.zcml +18 -0
  53. rer/solrpush/profiles/default/actions.xml +21 -0
  54. rer/solrpush/profiles/default/browserlayer.xml +7 -0
  55. rer/solrpush/profiles/default/catalog.xml +4 -0
  56. rer/solrpush/profiles/default/controlpanel.xml +31 -0
  57. rer/solrpush/profiles/default/metadata.xml +8 -0
  58. rer/solrpush/profiles/default/registry/bundle.xml +25 -0
  59. rer/solrpush/profiles/default/registry/criteria.xml +55 -0
  60. rer/solrpush/profiles/default/registry/settings.xml +6 -0
  61. rer/solrpush/profiles/default/rolemap.xml +13 -0
  62. rer/solrpush/profiles/default/types/Document.xml +12 -0
  63. rer/solrpush/profiles/to_1100/componentregistry.xml +9 -0
  64. rer/solrpush/profiles/to_1100/metadata.xml +5 -0
  65. rer/solrpush/profiles/to_1300/controlpanel.xml +13 -0
  66. rer/solrpush/profiles/to_1300/registry.xml +5 -0
  67. rer/solrpush/profiles/uninstall/browserlayer.xml +7 -0
  68. rer/solrpush/profiles/uninstall/controlpanel.xml +21 -0
  69. rer/solrpush/profiles/uninstall/registry.xml +17 -0
  70. rer/solrpush/restapi/__init__.py +0 -0
  71. rer/solrpush/restapi/configure.zcml +8 -0
  72. rer/solrpush/restapi/services/__init__.py +0 -0
  73. rer/solrpush/restapi/services/configure.zcml +8 -0
  74. rer/solrpush/restapi/services/elevate_schema/__init__.py +0 -0
  75. rer/solrpush/restapi/services/elevate_schema/configure.zcml +14 -0
  76. rer/solrpush/restapi/services/elevate_schema/get.py +12 -0
  77. rer/solrpush/restapi/services/solr_search/__init__.py +0 -0
  78. rer/solrpush/restapi/services/solr_search/batch.py +129 -0
  79. rer/solrpush/restapi/services/solr_search/configure.zcml +14 -0
  80. rer/solrpush/restapi/services/solr_search/get.py +25 -0
  81. rer/solrpush/restapi/services/solr_search/solr_search_handler.py +86 -0
  82. rer/solrpush/setuphandlers.py +20 -0
  83. rer/solrpush/testing.py +161 -0
  84. rer/solrpush/tests/__init__.py +0 -0
  85. rer/solrpush/tests/docs/example.docx +0 -0
  86. rer/solrpush/tests/docs/example.ods +0 -0
  87. rer/solrpush/tests/docs/example.pdf +0 -0
  88. rer/solrpush/tests/docs/plone_logo.png +0 -0
  89. rer/solrpush/tests/test_behaviors.py +61 -0
  90. rer/solrpush/tests/test_elevate.py +124 -0
  91. rer/solrpush/tests/test_events.py +181 -0
  92. rer/solrpush/tests/test_image_tags.py +85 -0
  93. rer/solrpush/tests/test_maintenance.py +165 -0
  94. rer/solrpush/tests/test_querybuilder.py +272 -0
  95. rer/solrpush/tests/test_restapi_search.py +127 -0
  96. rer/solrpush/tests/test_search.py +177 -0
  97. rer/solrpush/tests/test_setup.py +67 -0
  98. rer/solrpush/tests/test_solr_interface.py +359 -0
  99. rer/solrpush/tests/test_tika.py +85 -0
  100. rer/solrpush/tests/test_vocabularies.py +113 -0
  101. rer/solrpush/upgrades.py +76 -0
  102. rer/solrpush/upgrades.zcml +86 -0
  103. rer/solrpush/utils/__init__.py +6 -0
  104. rer/solrpush/utils/solr_common.py +122 -0
  105. rer/solrpush/utils/solr_indexer.py +295 -0
  106. rer/solrpush/utils/solr_search.py +352 -0
  107. rer/solrpush/vocabularies.py +50 -0
  108. rer.solrpush-1.3.4-py3.10-nspkg.pth +1 -0
  109. rer.solrpush-1.3.4.dist-info/LICENSE.GPL +339 -0
  110. rer.solrpush-1.3.4.dist-info/LICENSE.rst +15 -0
  111. rer.solrpush-1.3.4.dist-info/METADATA +507 -0
  112. rer.solrpush-1.3.4.dist-info/RECORD +116 -0
  113. rer.solrpush-1.3.4.dist-info/WHEEL +5 -0
  114. rer.solrpush-1.3.4.dist-info/entry_points.txt +5 -0
  115. rer.solrpush-1.3.4.dist-info/namespace_packages.txt +1 -0
  116. rer.solrpush-1.3.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,177 @@
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.utils.solr_search import escape_special_characters
12
+ from rer.solrpush.testing import (
13
+ RER_SOLRPUSH_API_FUNCTIONAL_TESTING,
14
+ ) # noqa: E501
15
+ from transaction import commit
16
+
17
+ import unittest
18
+
19
+
20
+ class TestSearch(unittest.TestCase):
21
+ """Test show in search field behavior."""
22
+
23
+ layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
24
+
25
+ def setUp(self):
26
+ """
27
+ We create objects before initializing solr settings, so solr core is
28
+ always empty on setUp.
29
+ """
30
+ self.portal = self.layer["portal"]
31
+ self.request = self.layer["request"]
32
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
33
+ set_registry_record(
34
+ "enabled_types",
35
+ [u"Document", u"News Item"],
36
+ interface=IRerSolrpushSettings,
37
+ )
38
+ init_solr_push()
39
+ # set_registry_record("active", True, interface=IRerSolrpushSettings)
40
+ self.docs = {}
41
+ for i in range(20):
42
+ searchwords = []
43
+ id = "doc-%03d" % i
44
+ if i == 5:
45
+ id = "odd"
46
+ title = "Document %s" % i
47
+ searchwords = ["odd"]
48
+ elif i % 2 == 0:
49
+ title = "Document %s even even" % i
50
+ else:
51
+ title = "Document %s odd odd" % i
52
+ obj = self.docs[i] = api.content.create(
53
+ container=self.portal,
54
+ type="Document",
55
+ id=id,
56
+ title=title,
57
+ searchwords=searchwords,
58
+ )
59
+ # obj.reindexObject(idxs=['Title'])
60
+ api.content.transition(obj=obj, transition="publish")
61
+ commit()
62
+
63
+ def tearDown(self):
64
+ reset_solr()
65
+ set_registry_record("qf", u"", interface=IRerSolrpushSettings)
66
+ set_registry_record("bq", u"", interface=IRerSolrpushSettings)
67
+ set_registry_record("bf", u"", interface=IRerSolrpushSettings)
68
+ commit()
69
+
70
+ def test_all_items(self):
71
+ solr_results = search(query={}, fl="UID")
72
+ self.assertEqual(solr_results.hits, len(self.docs))
73
+
74
+ def test_search_odd(self):
75
+ solr_results = search(query={"SearchableText": "odd"}, fl="UID")
76
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
77
+
78
+ def test_search_qf(self):
79
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
80
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
81
+ self.assertNotEqual(solr_results.docs[0]["id"], "odd")
82
+
83
+ set_registry_record(
84
+ "qf",
85
+ u"id^1000.0 SearchableText^1.0",
86
+ interface=IRerSolrpushSettings,
87
+ )
88
+ commit()
89
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
90
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
91
+ self.assertEqual(solr_results.docs[0]["id"], "odd")
92
+
93
+ def test_search_qf_for_searchwords(self):
94
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
95
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
96
+ self.assertNotEqual(solr_results.docs[0]["id"], "odd")
97
+
98
+ set_registry_record(
99
+ "qf",
100
+ u"searchwords^1000.0 SearchableText^1.0",
101
+ interface=IRerSolrpushSettings,
102
+ )
103
+ commit()
104
+
105
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
106
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
107
+ self.assertEqual(solr_results.docs[0]["id"], "odd")
108
+
109
+ def test_search_bq(self):
110
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
111
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
112
+ self.assertNotEqual(solr_results.docs[0]["id"], "odd")
113
+
114
+ set_registry_record("bq", u"id:odd", interface=IRerSolrpushSettings)
115
+ commit()
116
+
117
+ solr_results = search(query={"": "odd"}, fl=["UID", "id", "Title"])
118
+ self.assertEqual(solr_results.hits, len(self.docs) / 2)
119
+ self.assertEqual(solr_results.docs[0]["id"], "odd")
120
+
121
+ def test_escape_chars(self):
122
+ self.assertEqual(escape_special_characters("*:*", False), "\\*\\:\\*")
123
+ self.assertEqual(
124
+ escape_special_characters("* : *", True), '"\\* \\: \\*"'
125
+ )
126
+
127
+ def test_search_words_case_insensitive(self):
128
+ """because it's indexed as lowercase"""
129
+ obj = api.content.create(
130
+ container=self.portal,
131
+ type="Document",
132
+ id="insensitive",
133
+ title="Insensitive",
134
+ searchwords=["FOO", "bar", "bAz"],
135
+ )
136
+ api.content.transition(obj=obj, transition="publish")
137
+
138
+ commit()
139
+
140
+ self.assertEqual(
141
+ search(
142
+ query={"searchwords": "FOO"}, fl=["UID", "id", "Title"]
143
+ ).hits,
144
+ 1,
145
+ )
146
+ self.assertEqual(
147
+ search(
148
+ query={"searchwords": "foo"}, fl=["UID", "id", "Title"]
149
+ ).hits,
150
+ 1,
151
+ )
152
+
153
+ self.assertEqual(
154
+ search(
155
+ query={"searchwords": "bar"}, fl=["UID", "id", "Title"]
156
+ ).hits,
157
+ 1,
158
+ )
159
+ self.assertEqual(
160
+ search(
161
+ query={"searchwords": "Bar"}, fl=["UID", "id", "Title"]
162
+ ).hits,
163
+ 1,
164
+ )
165
+
166
+ self.assertEqual(
167
+ search(
168
+ query={"searchwords": "baz"}, fl=["UID", "id", "Title"]
169
+ ).hits,
170
+ 1,
171
+ )
172
+ self.assertEqual(
173
+ search(
174
+ query={"searchwords": "BAZ"}, fl=["UID", "id", "Title"]
175
+ ).hits,
176
+ 1,
177
+ )
@@ -0,0 +1,67 @@
1
+ # -*- coding: utf-8 -*-
2
+ """Setup tests for this package."""
3
+ from rer.solrpush.testing import (
4
+ RER_SOLRPUSH_API_INTEGRATION_TESTING,
5
+ ) # noqa: E501
6
+ from plone import api
7
+ from plone.app.testing import setRoles
8
+ from plone.app.testing import TEST_USER_ID
9
+
10
+ import unittest
11
+
12
+ try:
13
+ from Products.CMFPlone.utils import get_installer
14
+ except ImportError:
15
+ get_installer = None
16
+
17
+
18
+ class TestSetup(unittest.TestCase):
19
+ """Test that rer.solrpush is properly installed."""
20
+
21
+ layer = RER_SOLRPUSH_API_INTEGRATION_TESTING
22
+
23
+ def setUp(self):
24
+ """Custom shared utility setup for tests."""
25
+ self.portal = self.layer["portal"]
26
+ if get_installer:
27
+ self.installer = get_installer(self.portal, self.layer["request"])
28
+ else:
29
+ self.installer = api.portal.get_tool("portal_quickinstaller")
30
+
31
+ def test_product_installed(self):
32
+ """Test if rer.solrpush is installed."""
33
+ self.assertTrue(self.installer.isProductInstalled("rer.solrpush"))
34
+
35
+ def test_browserlayer(self):
36
+ """Test that IRerSolrpushLayer is registered."""
37
+ from rer.solrpush.interfaces import IRerSolrpushLayer
38
+ from plone.browserlayer import utils
39
+
40
+ self.assertIn(IRerSolrpushLayer, utils.registered_layers())
41
+
42
+
43
+ class TestUninstall(unittest.TestCase):
44
+
45
+ layer = RER_SOLRPUSH_API_INTEGRATION_TESTING
46
+
47
+ def setUp(self):
48
+ self.portal = self.layer["portal"]
49
+ if get_installer:
50
+ self.installer = get_installer(self.portal, self.layer["request"])
51
+ else:
52
+ self.installer = api.portal.get_tool("portal_quickinstaller")
53
+ roles_before = api.user.get_roles(TEST_USER_ID)
54
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
55
+ self.installer.uninstallProducts(["rer.solrpush"])
56
+ setRoles(self.portal, TEST_USER_ID, roles_before)
57
+
58
+ def test_product_uninstalled(self):
59
+ """Test if rer.solrpush is cleanly uninstalled."""
60
+ self.assertFalse(self.installer.isProductInstalled("rer.solrpush"))
61
+
62
+ def test_browserlayer_removed(self):
63
+ """Test that IRerSolrpushLayer is removed."""
64
+ from rer.solrpush.interfaces import IRerSolrpushLayer
65
+ from plone.browserlayer import utils
66
+
67
+ self.assertNotIn(IRerSolrpushLayer, utils.registered_layers())
@@ -0,0 +1,359 @@
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.utils import push_to_solr
12
+ from rer.solrpush.utils import remove_from_solr
13
+ from rer.solrpush.testing import RER_SOLRPUSH_API_FUNCTIONAL_TESTING
14
+ import time
15
+ from transaction import commit
16
+
17
+ import unittest
18
+
19
+
20
+ class TestSolrIndexActions(unittest.TestCase):
21
+ """Test that rer.solrpush is properly installed."""
22
+
23
+ layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
24
+
25
+ def setUp(self):
26
+ """"""
27
+ self.portal = self.layer["portal"]
28
+ self.request = self.layer["request"]
29
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
30
+ set_registry_record(
31
+ "enabled_types", [u"Document"], interface=IRerSolrpushSettings
32
+ )
33
+ self.published_doc = api.content.create(
34
+ container=self.portal, type="Document", title="Published Document"
35
+ )
36
+ api.content.transition(obj=self.published_doc, transition="publish")
37
+ self.unpublished_doc = api.content.create(
38
+ container=self.portal,
39
+ type="Document",
40
+ title="Unpublished Document",
41
+ )
42
+ self.published_news = api.content.create(
43
+ container=self.portal, type="News Item", title="Published News"
44
+ )
45
+ self.unpublished_news = api.content.create(
46
+ container=self.portal, type="News Item", title="Unpublished News"
47
+ )
48
+ api.content.transition(obj=self.published_news, transition="publish")
49
+ init_solr_push()
50
+
51
+ def tearDown(self):
52
+ set_registry_record("active", True, interface=IRerSolrpushSettings)
53
+ reset_solr()
54
+
55
+ def test_push_to_solr(self):
56
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
57
+ self.assertEqual(solr_results.hits, 0)
58
+
59
+ # try to push an indexable and published content
60
+ push_to_solr(self.published_doc)
61
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
62
+ self.assertEqual(solr_results.hits, 1)
63
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
64
+
65
+ # try to push an indexable and private content
66
+ push_to_solr(self.unpublished_doc)
67
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
68
+ self.assertEqual(solr_results.hits, 1)
69
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
70
+
71
+ # try to push a non indexable published content
72
+ push_to_solr(self.published_news)
73
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
74
+ self.assertEqual(solr_results.hits, 1)
75
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
76
+
77
+ # try to push a non indexable private content
78
+ push_to_solr(self.unpublished_news)
79
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
80
+ self.assertEqual(solr_results.hits, 1)
81
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
82
+
83
+ def test_update_content(self):
84
+ push_to_solr(self.published_doc)
85
+ solr_results = search(
86
+ query={"*": "*", "b_size": 100000}, fl="UID Description"
87
+ )
88
+ self.assertEqual(solr_results.hits, 1)
89
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
90
+ self.assertEqual(solr_results.docs[0].get("Description", ""), "")
91
+
92
+ self.published_doc.setDescription("foo description")
93
+ push_to_solr(self.published_doc)
94
+ solr_results = search(
95
+ query={"*": "*", "b_size": 100000}, fl="UID Description"
96
+ )
97
+ self.assertEqual(solr_results.hits, 1)
98
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
99
+ self.assertIn("Description", solr_results.docs[0])
100
+ self.assertEqual(
101
+ solr_results.docs[0]["Description"], "foo description"
102
+ )
103
+
104
+ def test_remove_from_solr(self):
105
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
106
+ self.assertEqual(solr_results.hits, 0)
107
+
108
+ api.content.transition(obj=self.unpublished_doc, transition="publish")
109
+ # commit()
110
+ # try to push an indexable and published content
111
+ push_to_solr(self.published_doc)
112
+ push_to_solr(self.unpublished_doc)
113
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
114
+ self.assertEqual(solr_results.hits, 2)
115
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
116
+
117
+ # try to remove content from solr
118
+ remove_from_solr(uid=self.published_doc.UID())
119
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
120
+ self.assertEqual(solr_results.hits, 1)
121
+ self.assertEqual(
122
+ solr_results.docs[0]["UID"], self.unpublished_doc.UID()
123
+ )
124
+
125
+ def test_reset_solr(self):
126
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
127
+ self.assertEqual(solr_results.hits, 0)
128
+
129
+ api.content.transition(obj=self.unpublished_doc, transition="publish")
130
+ # commit()
131
+ # try to push an indexable and published content
132
+ push_to_solr(self.published_doc)
133
+ push_to_solr(self.unpublished_doc)
134
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
135
+ self.assertEqual(solr_results.hits, 2)
136
+ self.assertEqual(solr_results.docs[0]["UID"], self.published_doc.UID())
137
+
138
+ # cleanup catalog
139
+ reset_solr()
140
+ solr_results = search(query={"*": "*", "b_size": 100000}, fl="UID")
141
+ self.assertEqual(solr_results.hits, 0)
142
+
143
+
144
+ class TestSolrSearch(unittest.TestCase):
145
+ """"""
146
+
147
+ layer = RER_SOLRPUSH_API_FUNCTIONAL_TESTING
148
+
149
+ def setUp(self):
150
+ """"""
151
+ self.portal = self.layer["portal"]
152
+ self.request = self.layer["request"]
153
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
154
+ set_registry_record(
155
+ "enabled_types",
156
+ [u"Document", u"News Item"],
157
+ interface=IRerSolrpushSettings,
158
+ )
159
+ #  initialize solr push, so solr will be populated automatically
160
+ # on commits
161
+ init_solr_push()
162
+ commit()
163
+ self.doc1 = api.content.create(
164
+ container=self.portal,
165
+ type="Document",
166
+ title="First Document",
167
+ description="lorem ipsum",
168
+ subject=["foo", "bar"],
169
+ )
170
+ self.doc2 = api.content.create(
171
+ container=self.portal,
172
+ type="Document",
173
+ title="Second Document",
174
+ description="lorem ipsum dolor sit amet",
175
+ )
176
+ self.unpublished_doc = api.content.create(
177
+ container=self.portal,
178
+ type="Document",
179
+ title="Unpublished Document",
180
+ )
181
+ self.published_news = api.content.create(
182
+ container=self.portal,
183
+ type="News Item",
184
+ title="Published News",
185
+ subject=["foo", "news category"],
186
+ )
187
+ self.unpublished_news = api.content.create(
188
+ container=self.portal,
189
+ type="News Item",
190
+ title="Unpublished News",
191
+ subject=["foo"],
192
+ )
193
+ self.event = api.content.create(
194
+ container=self.portal, type="Event", title="Event", subject=["foo"]
195
+ )
196
+ api.content.transition(obj=self.doc1, transition="publish")
197
+ # commit()
198
+ api.content.transition(obj=self.doc2, transition="publish")
199
+ # commit()
200
+ api.content.transition(obj=self.published_news, transition="publish")
201
+ # commit()
202
+ api.content.transition(obj=self.event, transition="publish")
203
+ commit()
204
+
205
+ def tearDown(self):
206
+ set_registry_record("active", True, interface=IRerSolrpushSettings)
207
+ reset_solr()
208
+
209
+ def test_search_all(self):
210
+ solr_results = search(query={"*": "*"})
211
+ # only published and indexable contents are on solr
212
+ self.assertEqual(solr_results.hits, 3)
213
+ uids = [x["UID"] for x in solr_results.docs]
214
+ self.assertIn(self.doc1.UID(), uids)
215
+ self.assertIn(self.doc2.UID(), uids)
216
+ self.assertIn(self.published_news.UID(), uids)
217
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
218
+ self.assertNotIn(self.unpublished_news.UID(), uids)
219
+ self.assertNotIn(self.event.UID(), uids)
220
+
221
+ def test_search_q(self):
222
+ solr_results = search(query={"SearchableText": "Document"})
223
+ self.assertEqual(solr_results.hits, 2)
224
+ uids = [x["UID"] for x in solr_results.docs]
225
+ self.assertIn(self.doc1.UID(), uids)
226
+ self.assertIn(self.doc2.UID(), uids)
227
+ self.assertNotIn(self.published_news.UID(), uids)
228
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
229
+ self.assertNotIn(self.unpublished_news.UID(), uids)
230
+ self.assertNotIn(self.event.UID(), uids)
231
+
232
+ solr_results = search(query={"SearchableText": "lorem ipsum"})
233
+ self.assertEqual(solr_results.hits, 2)
234
+ uids = [x["UID"] for x in solr_results.docs]
235
+ self.assertIn(self.doc1.UID(), uids)
236
+ self.assertIn(self.doc2.UID(), uids)
237
+
238
+ solr_results = search(query={"SearchableText": "lorem amet"})
239
+ self.assertEqual(solr_results.hits, 1)
240
+ uids = [x["UID"] for x in solr_results.docs]
241
+ self.assertNotIn(self.doc1.UID(), uids)
242
+ self.assertIn(self.doc2.UID(), uids)
243
+
244
+ solr_results = search(query={"SearchableText": "lorem OR amet"})
245
+ self.assertEqual(solr_results.hits, 2)
246
+ uids = [x["UID"] for x in solr_results.docs]
247
+ self.assertIn(self.doc1.UID(), uids)
248
+ self.assertIn(self.doc2.UID(), uids)
249
+
250
+ def test_search_fq(self):
251
+ #  same result if we search by portal_type
252
+ solr_results = search(query={"portal_type": "Document"})
253
+ self.assertEqual(solr_results.hits, 2)
254
+ uids = [x["UID"] for x in solr_results.docs]
255
+ self.assertIn(self.doc1.UID(), uids)
256
+ self.assertIn(self.doc2.UID(), uids)
257
+ self.assertNotIn(self.published_news.UID(), uids)
258
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
259
+ self.assertNotIn(self.unpublished_news.UID(), uids)
260
+ self.assertNotIn(self.event.UID(), uids)
261
+
262
+ solr_results = search(query={"portal_type": "News Item"})
263
+ self.assertEqual(solr_results.hits, 1)
264
+ uids = [x["UID"] for x in solr_results.docs]
265
+ self.assertNotIn(self.doc1.UID(), uids)
266
+ self.assertNotIn(self.doc2.UID(), uids)
267
+ self.assertIn(self.published_news.UID(), uids)
268
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
269
+ self.assertNotIn(self.unpublished_news.UID(), uids)
270
+ self.assertNotIn(self.event.UID(), uids)
271
+
272
+ solr_results = search(query={"Subject": "foo"})
273
+ self.assertEqual(solr_results.hits, 2)
274
+ uids = [x["UID"] for x in solr_results.docs]
275
+ self.assertIn(self.doc1.UID(), uids)
276
+ self.assertNotIn(self.doc2.UID(), uids)
277
+ self.assertIn(self.published_news.UID(), uids)
278
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
279
+ self.assertNotIn(self.unpublished_news.UID(), uids)
280
+ self.assertNotIn(self.event.UID(), uids)
281
+
282
+ solr_results = search(query={"Subject": "bar"})
283
+ self.assertEqual(solr_results.hits, 1)
284
+ uids = [x["UID"] for x in solr_results.docs]
285
+ self.assertIn(self.doc1.UID(), uids)
286
+ self.assertNotIn(self.doc2.UID(), uids)
287
+ self.assertNotIn(self.published_news.UID(), uids)
288
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
289
+ self.assertNotIn(self.unpublished_news.UID(), uids)
290
+ self.assertNotIn(self.event.UID(), uids)
291
+
292
+ solr_results = search(query={"Subject": ["foo", "bar"]})
293
+ self.assertEqual(solr_results.hits, 2)
294
+ uids = [x["UID"] for x in solr_results.docs]
295
+ self.assertIn(self.doc1.UID(), uids)
296
+ self.assertNotIn(self.doc2.UID(), uids)
297
+ self.assertIn(self.published_news.UID(), uids)
298
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
299
+ self.assertNotIn(self.unpublished_news.UID(), uids)
300
+ self.assertNotIn(self.event.UID(), uids)
301
+
302
+ solr_results = search(query={"Subject": ["news category"]})
303
+ self.assertEqual(solr_results.hits, 1)
304
+ uids = [x["UID"] for x in solr_results.docs]
305
+ self.assertNotIn(self.doc1.UID(), uids)
306
+ self.assertNotIn(self.doc2.UID(), uids)
307
+ self.assertIn(self.published_news.UID(), uids)
308
+ self.assertNotIn(self.unpublished_doc.UID(), uids)
309
+ self.assertNotIn(self.unpublished_news.UID(), uids)
310
+ self.assertNotIn(self.event.UID(), uids)
311
+
312
+ def test_search_fl(self):
313
+ """
314
+ with fl we can select which fields solr returns for results
315
+ """
316
+ solr_results = search(query={"*": "*"})
317
+ self.assertEqual(solr_results.hits, 3)
318
+ for doc in solr_results.docs:
319
+ self.assertIn("UID", list(doc.keys()))
320
+ self.assertIn("Title", list(doc.keys()))
321
+
322
+ solr_results = search(query={"*": "*"}, fl="UID")
323
+ self.assertEqual(solr_results.hits, 3)
324
+ for doc in solr_results.docs:
325
+ self.assertIn("UID", list(doc.keys()))
326
+ self.assertNotIn("Title", list(doc.keys()))
327
+
328
+ solr_results = search(query={"*": "*"}, fl="UID Subject")
329
+ self.assertEqual(solr_results.hits, 3)
330
+ for doc in solr_results.docs:
331
+ self.assertIn("UID", list(doc.keys()))
332
+ self.assertNotIn("Title", list(doc.keys()))
333
+ if not api.content.get(UID=doc["UID"]).Subject():
334
+ self.assertNotIn("Subject", list(doc.keys()))
335
+ else:
336
+ self.assertIn("Subject", list(doc.keys()))
337
+
338
+ def test_search_sort_on(self):
339
+ """"""
340
+ # update modification date
341
+ time.sleep(1)
342
+ self.doc2.reindexObject()
343
+ commit()
344
+ solr_results = search(
345
+ query={"portal_type": "Document", "sort_on": "modified"}
346
+ )
347
+ self.assertEqual(solr_results.hits, 2)
348
+ self.assertEqual(solr_results.docs[0]["UID"], self.doc1.UID())
349
+ self.assertEqual(solr_results.docs[1]["UID"], self.doc2.UID())
350
+ solr_results = search(
351
+ query={
352
+ "portal_type": "Document",
353
+ "sort_on": "modified",
354
+ "sort_order": "reverse",
355
+ }
356
+ )
357
+ self.assertEqual(solr_results.hits, 2)
358
+ self.assertEqual(solr_results.docs[0]["UID"], self.doc2.UID())
359
+ self.assertEqual(solr_results.docs[1]["UID"], self.doc1.UID())
@@ -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")