imio.smartweb.core 1.2.37__py3-none-any.whl → 1.2.79__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 (222) hide show
  1. imio/smartweb/core/behaviors/categorization.py +24 -0
  2. imio/smartweb/core/behaviors/configure.zcml +7 -0
  3. imio/smartweb/core/browser/controlpanel.py +43 -0
  4. imio/smartweb/core/browser/faceted/block_view.pt +4 -4
  5. imio/smartweb/core/browser/faceted/summary_view.pt +4 -4
  6. imio/smartweb/core/browser/sitemap.py +10 -3
  7. imio/smartweb/core/browser/static/icons/action-delete.svg +3 -0
  8. imio/smartweb/core/browser/static/icons/action-engagement-2.svg +4 -0
  9. imio/smartweb/core/browser/static/icons/action-panneaux.svg +3 -0
  10. imio/smartweb/core/browser/static/icons/action-vote.svg +3 -0
  11. imio/smartweb/core/browser/static/icons/categorie-attention.svg +3 -0
  12. imio/smartweb/core/browser/static/icons/categorie-infos-travaux-2.svg +4 -0
  13. imio/smartweb/core/browser/static/icons/categorie-nature.svg +3 -0
  14. imio/smartweb/core/browser/static/icons/categorie-parcs-a-conteneurs.svg +4 -0
  15. imio/smartweb/core/browser/static/icons/categorie-plus.svg +3 -0
  16. imio/smartweb/core/browser/static/icons/categorie-primes-2.svg +5 -0
  17. imio/smartweb/core/browser/static/icons/categorie-sport-natation.svg +4 -0
  18. imio/smartweb/core/browser/static/icons/organisation-ecole-sac.svg +4 -0
  19. imio/smartweb/core/browser/static/icons/organisation-scout.svg +3 -0
  20. imio/smartweb/core/browser/static/icons/reseausocial-behance.svg +3 -0
  21. imio/smartweb/core/browser/static/icons/reseausocial-linkedin.svg +3 -0
  22. imio/smartweb/core/browser/static/smartweb-edit-compiled.css +1 -1
  23. imio/smartweb/core/browser/static/smartweb-view-compiled.css +1 -1
  24. imio/smartweb/core/browser/static/src/edit.less +42 -0
  25. imio/smartweb/core/browser/static/src/view.less +109 -56
  26. imio/smartweb/core/browser/vocabulary.py +8 -3
  27. imio/smartweb/core/contents/__init__.py +2 -0
  28. imio/smartweb/core/contents/configure.zcml +1 -0
  29. imio/smartweb/core/contents/folder/block_view.pt +8 -8
  30. imio/smartweb/core/contents/folder/summary_view.pt +4 -4
  31. imio/smartweb/core/contents/pages/cirkwi/content.py +5 -0
  32. imio/smartweb/core/contents/pages/cirkwi/view.py +2 -1
  33. imio/smartweb/core/contents/pages/configure.zcml +1 -0
  34. imio/smartweb/core/contents/pages/portal_page/view.py +3 -0
  35. imio/smartweb/core/contents/pages/views.py +47 -1
  36. imio/smartweb/core/contents/publication/__init__.py +0 -0
  37. imio/smartweb/core/contents/publication/configure.zcml +5 -0
  38. imio/smartweb/core/contents/publication/content.py +23 -0
  39. imio/smartweb/core/contents/rest/base.py +9 -7
  40. imio/smartweb/core/contents/rest/directory/endpoint.py +2 -2
  41. imio/smartweb/core/contents/rest/directory/view.pt +2 -1
  42. imio/smartweb/core/contents/rest/events/content.py +13 -0
  43. imio/smartweb/core/contents/rest/events/endpoint.py +5 -3
  44. imio/smartweb/core/contents/rest/events/view.pt +5 -1
  45. imio/smartweb/core/contents/rest/events/view.py +12 -0
  46. imio/smartweb/core/contents/rest/news/content.py +6 -0
  47. imio/smartweb/core/contents/rest/news/endpoint.py +4 -2
  48. imio/smartweb/core/contents/rest/news/view.pt +4 -1
  49. imio/smartweb/core/contents/rest/news/view.py +8 -0
  50. imio/smartweb/core/contents/rest/utils.py +0 -1
  51. imio/smartweb/core/contents/rest/view.py +4 -0
  52. imio/smartweb/core/contents/sections/common_templates/carousel.pt +5 -1
  53. imio/smartweb/core/contents/sections/common_templates/table.pt +18 -4
  54. imio/smartweb/core/contents/sections/configure.zcml +18 -0
  55. imio/smartweb/core/contents/sections/contact/content.py +2 -2
  56. imio/smartweb/core/contents/sections/contact/macros.pt +28 -3
  57. imio/smartweb/core/contents/sections/contact/utils.py +2 -0
  58. imio/smartweb/core/contents/sections/contact/view.py +28 -12
  59. imio/smartweb/core/contents/sections/events/content.py +12 -4
  60. imio/smartweb/core/contents/sections/events/view.py +20 -2
  61. imio/smartweb/core/contents/sections/external_content/view.pt +4 -4
  62. imio/smartweb/core/contents/sections/external_content/views.py +6 -4
  63. imio/smartweb/core/contents/sections/files/content.py +7 -1
  64. imio/smartweb/core/contents/sections/files/view.py +43 -12
  65. imio/smartweb/core/contents/sections/links/view.py +5 -0
  66. imio/smartweb/core/contents/sections/macros.pt +26 -0
  67. imio/smartweb/core/contents/sections/news/content.py +11 -3
  68. imio/smartweb/core/contents/sections/news/view.py +20 -2
  69. imio/smartweb/core/contents/sections/text/views.py +2 -0
  70. imio/smartweb/core/contents/sections/views.py +73 -10
  71. imio/smartweb/core/interfaces.py +4 -0
  72. imio/smartweb/core/profiles/default/metadata.xml +1 -1
  73. imio/smartweb/core/profiles/default/taxonomies/page_category.xml +16 -0
  74. imio/smartweb/core/profiles/default/taxonomies/procedure_category.xml +26 -0
  75. imio/smartweb/core/profiles/default/types/imio.smartweb.EventsView.xml +1 -0
  76. imio/smartweb/core/profiles/default/types/imio.smartweb.NewsView.xml +1 -0
  77. imio/smartweb/core/profiles/default/types/imio.smartweb.Publication.xml +38 -0
  78. imio/smartweb/core/profiles/default/types/imio.smartweb.SectionEvents.xml +1 -0
  79. imio/smartweb/core/profiles/default/types/imio.smartweb.SectionFiles.xml +2 -0
  80. imio/smartweb/core/profiles/default/types/imio.smartweb.SectionNews.xml +1 -0
  81. imio/smartweb/core/profiles/default/types.xml +1 -0
  82. imio/smartweb/core/profiles/icons/basic/registry.xml +120 -0
  83. imio/smartweb/core/rest/authentic_sources.py +17 -2
  84. imio/smartweb/core/subscribers.py +48 -0
  85. imio/smartweb/core/subscribers.zcml +12 -0
  86. imio/smartweb/core/tests/resources/json_iadeliberations_institutions.json +60 -0
  87. imio/smartweb/core/tests/resources/json_iadeliberations_publication.json +105 -0
  88. imio/smartweb/core/tests/resources/json_iadeliberations_publications.json +270 -0
  89. imio/smartweb/core/tests/resources/json_rest_events.json +6 -2
  90. imio/smartweb/core/tests/resources/json_rest_news.json +2 -2
  91. imio/smartweb/core/tests/resources/json_rest_specific_events.json +1 -1
  92. imio/smartweb/core/tests/test_htmx_in_sections.py +131 -0
  93. imio/smartweb/core/tests/test_iadeliberations.py +136 -0
  94. imio/smartweb/core/tests/test_icons.py +1 -1
  95. imio/smartweb/core/tests/test_rest.py +58 -17
  96. imio/smartweb/core/tests/test_section_contact.py +42 -10
  97. imio/smartweb/core/tests/test_section_events.py +28 -5
  98. imio/smartweb/core/tests/test_section_external_content.py +28 -2
  99. imio/smartweb/core/tests/test_section_news.py +30 -8
  100. imio/smartweb/core/tests/test_sections.py +17 -0
  101. imio/smartweb/core/tests/test_vocabularies.py +60 -3
  102. imio/smartweb/core/tests/test_vocabulary.py +43 -0
  103. imio/smartweb/core/upgrades/configure.zcml +108 -0
  104. imio/smartweb/core/upgrades/profiles/1055_to_1056/types/imio.smartweb.SectionFiles.xml +12 -0
  105. imio/smartweb/core/upgrades/profiles/1056_to_1057/types/imio.smartweb.EventsView.xml +11 -0
  106. imio/smartweb/core/upgrades/profiles/1056_to_1057/types/imio.smartweb.NewsView.xml +11 -0
  107. imio/smartweb/core/upgrades/profiles/1056_to_1057/types/imio.smartweb.SectionEvents.xml +11 -0
  108. imio/smartweb/core/upgrades/profiles/1056_to_1057/types/imio.smartweb.SectionNews.xml +11 -0
  109. imio/smartweb/core/upgrades/profiles/1057_to_1058/taxonomies/page_category.cfg +9 -0
  110. imio/smartweb/core/upgrades/profiles/1057_to_1058/taxonomies/page_category.xml +73 -0
  111. imio/smartweb/core/upgrades/profiles/1057_to_1058/taxonomies/procedure_category.cfg +9 -0
  112. imio/smartweb/core/upgrades/profiles/1057_to_1058/taxonomies/procedure_category.xml +118 -0
  113. imio/smartweb/core/upgrades/profiles/1058_to_1059/registry/linkedin-icon.xml +126 -0
  114. imio/smartweb/core/upgrades/profiles/1059_to_1060/registry/iadeliberation.xml +9 -0
  115. imio/smartweb/core/upgrades/profiles/1060_to_1061/types/imio.smartweb.Publication.xml +38 -0
  116. imio/smartweb/core/upgrades/profiles/1060_to_1061/types/imio.smartweb.SectionFiles.xml +11 -0
  117. imio/smartweb/core/upgrades/profiles/1060_to_1061/types.xml +4 -0
  118. imio/smartweb/core/upgrades/profiles/1060_to_1061/workflows.xml +6 -0
  119. imio/smartweb/core/utils.py +33 -2
  120. imio/smartweb/core/viewlets/configure.zcml +23 -1
  121. imio/smartweb/core/viewlets/footer.pt +5 -0
  122. imio/smartweb/core/viewlets/footer.py +5 -0
  123. imio/smartweb/core/viewlets/htmx.py +15 -0
  124. imio/smartweb/core/viewlets/htmx_js_header.pt +64 -0
  125. imio/smartweb/core/viewlets/ogptags.py +4 -3
  126. imio/smartweb/core/viewlets/social.py +23 -0
  127. imio/smartweb/core/vocabularies.py +65 -3
  128. imio/smartweb/core/vocabularies.zcml +18 -0
  129. imio/smartweb/core/webcomponents/build/1c1605a5fe9a2b10a88f.png +1 -0
  130. imio/smartweb/core/webcomponents/build/524db40e119aa11f4478.png +1 -0
  131. imio/smartweb/core/webcomponents/build/57d3b7cb1ab874660b39.svg +1 -0
  132. imio/smartweb/core/webcomponents/build/6cf03871df23ed2ee8b3.png +1 -0
  133. imio/smartweb/core/webcomponents/build/css/373.smartweb-webcomponents-compiled.css +1 -1
  134. imio/smartweb/core/webcomponents/build/css/486.smartweb-webcomponents-compiled.css +1 -1
  135. imio/smartweb/core/webcomponents/build/css/884.smartweb-webcomponents-compiled.css +1 -0
  136. imio/smartweb/core/webcomponents/build/css/919.smartweb-webcomponents-compiled.css +1 -1
  137. imio/smartweb/core/webcomponents/build/css/smartweb-webcomponents-compiled.css +1 -1
  138. imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js +1 -1
  139. imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js.LICENSE.txt +10 -8
  140. imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +2 -1
  141. imio/smartweb/core/webcomponents/build/js/{568.smartweb-webcomponents-compiled.js.LICENSE.txt → 373.smartweb-webcomponents-compiled.js.LICENSE.txt} +0 -4
  142. imio/smartweb/core/webcomponents/build/js/486.smartweb-webcomponents-compiled.js +1 -1
  143. imio/smartweb/core/webcomponents/build/js/499.smartweb-webcomponents-compiled.js +2 -0
  144. imio/smartweb/core/webcomponents/build/js/{674.smartweb-webcomponents-compiled.js.LICENSE.txt → 499.smartweb-webcomponents-compiled.js.LICENSE.txt} +1 -8
  145. imio/smartweb/core/webcomponents/build/js/799.smartweb-webcomponents-compiled.js +1 -1
  146. imio/smartweb/core/webcomponents/build/js/824.smartweb-webcomponents-compiled.js +2 -0
  147. imio/smartweb/core/webcomponents/build/js/828.smartweb-webcomponents-compiled.js +2 -0
  148. imio/smartweb/core/webcomponents/build/js/828.smartweb-webcomponents-compiled.js.LICENSE.txt +32 -0
  149. imio/smartweb/core/webcomponents/build/js/884.smartweb-webcomponents-compiled.js +1 -0
  150. imio/smartweb/core/webcomponents/build/js/919.smartweb-webcomponents-compiled.js +1 -1
  151. imio/smartweb/core/webcomponents/build/js/{568.smartweb-webcomponents-compiled.js → 963.smartweb-webcomponents-compiled.js} +2 -2
  152. imio/smartweb/core/webcomponents/build/js/963.smartweb-webcomponents-compiled.js.LICENSE.txt +3 -0
  153. imio/smartweb/core/webcomponents/build/js/smartweb-webcomponents-compiled.js +1 -1
  154. imio/smartweb/core/webcomponents/build/js/smartweb-webcomponents-compiled.js.LICENSE.txt +11 -14
  155. imio/smartweb/core/webcomponents/package.json +42 -40
  156. imio/smartweb/core/webcomponents/src/components/Annuaire/Annuaire.jsx +146 -79
  157. imio/smartweb/core/webcomponents/src/components/Annuaire/Annuaire.scss +415 -351
  158. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactCard/ContactCard.jsx +95 -62
  159. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactContent/ContactContent.jsx +328 -168
  160. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactList/ContactList.jsx +21 -4
  161. imio/smartweb/core/webcomponents/src/components/Annuaire/Filters/Filter.jsx +213 -100
  162. imio/smartweb/core/webcomponents/src/components/Annuaire/index.js +1 -1
  163. imio/smartweb/core/webcomponents/src/components/Events/EventCard/EventCard.jsx +76 -33
  164. imio/smartweb/core/webcomponents/src/components/Events/EventContent/EventContent.jsx +604 -377
  165. imio/smartweb/core/webcomponents/src/components/Events/EventList/EventList.jsx +29 -4
  166. imio/smartweb/core/webcomponents/src/components/Events/Events.jsx +162 -88
  167. imio/smartweb/core/webcomponents/src/components/Events/Events.scss +496 -378
  168. imio/smartweb/core/webcomponents/src/components/Events/Filters/Filter.jsx +259 -91
  169. imio/smartweb/core/webcomponents/src/components/Filters/DateFilter.jsx +62 -55
  170. imio/smartweb/core/webcomponents/src/components/Filters/DateFilter.scss +68 -17
  171. imio/smartweb/core/webcomponents/src/components/Filters/IamData.jsx +42 -0
  172. imio/smartweb/core/webcomponents/src/components/Filters/MainFilter.scss +229 -0
  173. imio/smartweb/core/webcomponents/src/components/Filters/PublicTargetData.jsx +94 -0
  174. imio/smartweb/core/webcomponents/src/components/Filters/SelectStyles.js +58 -0
  175. imio/smartweb/core/webcomponents/src/components/Filters/TaxonomyFilter.jsx +149 -0
  176. imio/smartweb/core/webcomponents/src/components/Filters/TaxonomyFilter.scss +70 -0
  177. imio/smartweb/core/webcomponents/src/components/News/Filters/Filter.jsx +139 -83
  178. imio/smartweb/core/webcomponents/src/components/News/News.jsx +133 -67
  179. imio/smartweb/core/webcomponents/src/components/News/News.scss +170 -127
  180. imio/smartweb/core/webcomponents/src/components/News/NewsCard/NewsCard.jsx +76 -44
  181. imio/smartweb/core/webcomponents/src/components/News/NewsContent/NewsContent.jsx +261 -188
  182. imio/smartweb/core/webcomponents/src/components/News/NewsList/NewsList.jsx +48 -9
  183. imio/smartweb/core/webcomponents/src/components/Search/ContactResult/ContactResult.jsx +21 -10
  184. imio/smartweb/core/webcomponents/src/components/Search/EventsResult/EventsResult.jsx +21 -10
  185. imio/smartweb/core/webcomponents/src/components/Search/Filters/Filter.jsx +8 -9
  186. imio/smartweb/core/webcomponents/src/components/Search/NewsResult/NewsResult.jsx +23 -12
  187. imio/smartweb/core/webcomponents/src/components/Search/Search.jsx +7 -6
  188. imio/smartweb/core/webcomponents/src/components/Search/Search.scss +115 -96
  189. imio/smartweb/core/webcomponents/src/components/Search/WebResult/WebResult.jsx +12 -3
  190. imio/smartweb/core/webcomponents/src/components/Search/index.js +1 -1
  191. imio/smartweb/core/webcomponents/src/hooks/ScrollContext.jsx +3 -0
  192. imio/smartweb/core/webcomponents/src/hooks/useAxios.js +3 -3
  193. imio/smartweb/core/webcomponents/src/hooks/useFilterQuery.js +1 -2
  194. imio/smartweb/core/webcomponents/src/index.scss +255 -211
  195. imio/smartweb/core/webcomponents/src/utils/Map.jsx +26 -19
  196. imio/smartweb/core/webcomponents/src/utils/Map.scss +2 -2
  197. imio/smartweb/core/webcomponents/src/utils/translation.js +129 -9
  198. imio.smartweb.core-1.2.79-py3.8-nspkg.pth +2 -0
  199. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/METADATA +413 -10
  200. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/RECORD +206 -160
  201. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/WHEEL +1 -1
  202. imio/smartweb/core/webcomponents/build/assets/location-bla.1423bcce16ddcb21141430cac1428dc1.svg +0 -1
  203. imio/smartweb/core/webcomponents/build/assets/next-react-white.819cb069ac8eec300a9db6a7707712d6.svg +0 -1
  204. imio/smartweb/core/webcomponents/build/assets/next-react.17bc43ff4a6a86f4520f5782f6a89a72.svg +0 -1
  205. imio/smartweb/core/webcomponents/build/assets/search.57bdbf5b191499cd77514097d1c4972c.svg +0 -1
  206. imio/smartweb/core/webcomponents/build/css/686.smartweb-webcomponents-compiled.css +0 -1
  207. imio/smartweb/core/webcomponents/build/js/209.smartweb-webcomponents-compiled.js +0 -2
  208. imio/smartweb/core/webcomponents/build/js/674.smartweb-webcomponents-compiled.js +0 -2
  209. imio/smartweb/core/webcomponents/build/js/686.smartweb-webcomponents-compiled.js +0 -1
  210. imio/smartweb/core/webcomponents/build/js/804.smartweb-webcomponents-compiled.js +0 -1
  211. imio/smartweb/core/webcomponents/src/assets/facebook-news.svg +0 -1
  212. imio/smartweb/core/webcomponents/src/assets/location-bla.svg +0 -1
  213. imio/smartweb/core/webcomponents/src/assets/next-react.svg +0 -1
  214. imio/smartweb/core/webcomponents/src/assets/search.svg +0 -1
  215. imio/smartweb/core/webcomponents/src/assets/skeleton.svg +0 -1
  216. imio/smartweb/core/webcomponents/src/components/Annuaire/ContactContent/download.svg +0 -1
  217. imio.smartweb.core-1.2.37-py3.10-nspkg.pth +0 -3
  218. /imio/smartweb/core/webcomponents/build/js/{209.smartweb-webcomponents-compiled.js.LICENSE.txt → 824.smartweb-webcomponents-compiled.js.LICENSE.txt} +0 -0
  219. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/LICENSE.GPL +0 -0
  220. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/LICENSE.rst +0 -0
  221. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/namespace_packages.txt +0 -0
  222. {imio.smartweb.core-1.2.37.dist-info → imio.smartweb.core-1.2.79.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,131 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from imio.smartweb.core.interfaces import IImioSmartwebCoreLayer
4
+ from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_FUNCTIONAL_TESTING
5
+ from imio.smartweb.core.testing import ImioSmartwebTestCase
6
+ from plone import api
7
+ from plone.api import portal as portal_api
8
+ from plone.app.testing import logout
9
+ from plone.app.testing import setRoles
10
+ from plone.app.testing import TEST_USER_ID
11
+ from plone.app.testing import TEST_USER_NAME
12
+ from plone.app.testing import TEST_USER_PASSWORD
13
+ from plone.app.textfield.value import RichTextValue
14
+ from plone.protect.authenticator import createToken
15
+ from plone.testing.zope import Browser
16
+ from zope.component import getMultiAdapter
17
+ from zope.component import queryMultiAdapter
18
+ from zope.interface import alsoProvides
19
+
20
+ import json
21
+ import mock
22
+ import re
23
+ import transaction
24
+
25
+
26
+ class TestSections(ImioSmartwebTestCase):
27
+ layer = IMIO_SMARTWEB_CORE_FUNCTIONAL_TESTING
28
+
29
+ def setUp(self):
30
+ self.request = self.layer["request"]
31
+ self.portal = self.layer["portal"]
32
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
33
+ self.page = api.content.create(
34
+ container=self.portal,
35
+ type="imio.smartweb.Page",
36
+ id="page",
37
+ )
38
+ alsoProvides(self.request, IImioSmartwebCoreLayer)
39
+ self.section_text = api.content.create(
40
+ container=self.page,
41
+ type="imio.smartweb.SectionText",
42
+ title="Section Text",
43
+ id="section-text",
44
+ )
45
+ self.section_text.text = RichTextValue(
46
+ "<p>My rich text</p>", "text/html", "text/html"
47
+ )
48
+ api.content.transition(self.page, "publish")
49
+
50
+ def test_htmx_not_loaded_for_anonymous(self):
51
+ logout()
52
+ view = queryMultiAdapter((self.page, self.request), name="full_view")
53
+ self.assertNotIn("https://unpkg.com/htmx.org@1.9.10/dist/htmx.js", view())
54
+
55
+ def test_all_html_elements_are_here(self):
56
+ view = queryMultiAdapter((self.page, self.request), name="full_view")
57
+ # test if htmx well loaded
58
+ self.assertIn("https://unpkg.com/htmx.org@1.9.10/dist/htmx.js", view())
59
+ section_text_uid = self.section_text.UID()
60
+ # test if elements are here and have the right id
61
+ self.assertIn(f"sizesForm_{section_text_uid}", view())
62
+ self.assertIn(f'hx-boost="{section_text_uid}"', view())
63
+ self.assertIn(f'id="selected_size_{section_text_uid}"', view())
64
+ self.assertIn(f'hx-target="#selected_size_{section_text_uid}"', view())
65
+
66
+ def test_options_in_select(self):
67
+ view = queryMultiAdapter((self.page, self.request), name="full_view")
68
+ section_text_view = getMultiAdapter(
69
+ (self.section_text, self.request), name="view"
70
+ )
71
+ available_sizes = section_text_view.get_sizes
72
+ match = re.search(
73
+ r'<form class="form_section_size".*?</form>', view(), re.DOTALL
74
+ )
75
+ form_to_choose_size = match.group(0)
76
+ nb_occurrences = len(re.findall(r"<option", form_to_choose_size))
77
+ self.assertEqual(len(available_sizes), nb_occurrences)
78
+ for size in available_sizes:
79
+ self.assertIn(
80
+ f'<option title="{size["value"]}" value="{size["key"]}" class="icon_{size["key"]}" >',
81
+ form_to_choose_size,
82
+ )
83
+ # self.assertIn(
84
+ # f'<option value="{size["key"]}">{size["value"]}</option>',
85
+ # form_to_choose_size,
86
+ # )
87
+
88
+ def test_change_section_size(self):
89
+ portal_api.get_current_language = mock.Mock(return_value="en")
90
+ transaction.commit()
91
+ section_text_uid = self.section_text.UID()
92
+ browser = Browser(self.layer["app"])
93
+ browser.addHeader(
94
+ "Authorization",
95
+ "Basic %s:%s"
96
+ % (
97
+ TEST_USER_NAME,
98
+ TEST_USER_PASSWORD,
99
+ ),
100
+ )
101
+ browser.open(f"{self.page.absolute_url()}/full_view/?language=fr")
102
+ contents = browser.contents
103
+ div_section_container = (
104
+ '<div class="sortable-section sectiontext" data-id="section-text" style="">'
105
+ )
106
+ self.assertIn(div_section_container, contents)
107
+
108
+ select = browser.getControl(name=f"select_{section_text_uid}")
109
+ select.value = "col-sm-12"
110
+ browser.getForm(name=f"sizesForm_{section_text_uid}").submit()
111
+ section_text_view = getMultiAdapter(
112
+ (self.section_text, self.request), name="view"
113
+ )
114
+ self.assertEqual(section_text_view.save_size, json.dumps({}))
115
+ select_name = f"select_{self.section_text.UID()}"
116
+ self.request.form[select_name] = select.value[0]
117
+ self.request.form["_authenticator"] = createToken()
118
+ section_text_view = getMultiAdapter(
119
+ (self.section_text, self.request), name="view"
120
+ )
121
+ section_text_view.save_size
122
+ self.assertEqual(
123
+ section_text_view.save_size,
124
+ json.dumps({"id": "col-sm-12", "title": "Full width"}),
125
+ )
126
+ transaction.commit()
127
+
128
+ browser.open(f"{self.page.absolute_url()}/full_view/?language=fr")
129
+ contents = browser.contents
130
+ div_section_container = f'<div class="sortable-section sectiontext {select.value[0]}" data-id="section-text" style="">'
131
+ self.assertIn(div_section_container, contents)
@@ -0,0 +1,136 @@
1
+ # -*- coding: utf-8 -*-
2
+ from imio.smartweb.core.contents import IPublication
3
+ from imio.smartweb.core.tests.utils import get_json
4
+ from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_INTEGRATION_TESTING
5
+ from imio.smartweb.core.testing import ImioSmartwebTestCase
6
+ from plone import api
7
+ from plone.app.testing import setRoles
8
+ from plone.app.testing import TEST_USER_ID
9
+ from plone.dexterity.interfaces import IDexterityFTI
10
+ from unittest.mock import patch
11
+ from zope.component import createObject
12
+ from zope.component import queryMultiAdapter
13
+ from zope.component import queryUtility
14
+
15
+
16
+ class TestIADeliberations(ImioSmartwebTestCase):
17
+ layer = IMIO_SMARTWEB_CORE_INTEGRATION_TESTING
18
+
19
+ def setUp(self):
20
+ """Custom shared utility setup for tests."""
21
+ self.portal = self.layer["portal"]
22
+ self.request = self.layer["request"]
23
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
24
+ self.page = api.content.create(
25
+ container=self.portal,
26
+ type="imio.smartweb.Page",
27
+ title="A Page",
28
+ )
29
+ self.files_section = api.content.create(
30
+ container=self.page,
31
+ type="imio.smartweb.SectionFiles",
32
+ title="My files section",
33
+ )
34
+ self.json_publication_raw_mock = get_json(
35
+ "resources/json_iadeliberations_publication.json"
36
+ )
37
+
38
+ def test_ct_publication_schema(self):
39
+ fti = queryUtility(IDexterityFTI, name="imio.smartweb.Publication")
40
+ schema = fti.lookupSchema()
41
+ self.assertEqual(IPublication, schema)
42
+
43
+ def test_ct_publication_fti(self):
44
+ fti = queryUtility(IDexterityFTI, name="imio.smartweb.Publication")
45
+ self.assertTrue(fti)
46
+
47
+ def test_ct_publication_factory(self):
48
+ fti = queryUtility(IDexterityFTI, name="imio.smartweb.Publication")
49
+ factory = fti.factory
50
+ obj = createObject(factory)
51
+ self.assertTrue(
52
+ IPublication.providedBy(obj),
53
+ "IPublication not provided by {0}!".format(
54
+ obj,
55
+ ),
56
+ )
57
+
58
+ @patch("imio.smartweb.core.subscribers.get_iadeliberation_json")
59
+ @patch(
60
+ "imio.smartweb.core.subscribers.get_iadeliberation_institution_from_registry"
61
+ )
62
+ def test_ct_publication_adding(self, m_get_institution, m_get_publication):
63
+ m_get_institution.return_value = "https://conseil.staging.imio.be/liege"
64
+ m_get_publication.return_value = self.json_publication_raw_mock
65
+ obj = api.content.create(
66
+ container=self.files_section,
67
+ type="imio.smartweb.Publication",
68
+ linked_publication="ordonnance-concernant-des-mesures-specifiques-en-cas-de-grand-froid",
69
+ id="ordonnance-concernant-des-mesures-specifiques-en-cas-de-grand-froid",
70
+ )
71
+ self.assertTrue(
72
+ IPublication.providedBy(obj),
73
+ "IPublication not provided by {0}!".format(
74
+ obj.id,
75
+ ),
76
+ )
77
+ parent = obj.__parent__
78
+ self.assertIn(
79
+ "ordonnance-concernant-des-mesures-specifiques-en-cas-de-grand-froid",
80
+ parent.objectIds(),
81
+ )
82
+ title_resp = (
83
+ "Ordonnance concernant des mesures spécifiques en cas de grand froid."
84
+ )
85
+ self.assertEqual(obj.title, title_resp)
86
+ desc_resp = "Adopté par M. le Bourgmestre en date 12 décembre 2022"
87
+ self.assertEqual(obj.description, desc_resp)
88
+ url_resp = "https://conseil.staging.imio.be/liege/publications/ordonnance-concernant-des-mesures-specifiques-en-cas-de-grand-froid"
89
+ self.assertEqual(obj.publication_url, url_resp)
90
+ self.assertEqual(obj.publication_category, "Sécurité & Prévention")
91
+ self.assertEqual(
92
+ obj.publication_attached_file.get("filename"), "013400000123949.PDF"
93
+ )
94
+
95
+ # check that deleting the object works too
96
+ api.content.delete(obj=obj)
97
+ self.assertNotIn("publication", parent.objectIds())
98
+
99
+ @patch("imio.smartweb.core.subscribers.get_iadeliberation_json")
100
+ @patch(
101
+ "imio.smartweb.core.subscribers.get_iadeliberation_institution_from_registry"
102
+ )
103
+ def test_publication_view(self, m_get_institution, m_get_publication):
104
+ m_get_institution.return_value = "https://conseil.staging.imio.be/liege"
105
+ m_get_publication.return_value = self.json_publication_raw_mock
106
+ obj = api.content.create(
107
+ container=self.files_section,
108
+ type="imio.smartweb.Publication",
109
+ id="18820593",
110
+ )
111
+ obj.reindexObject()
112
+ title_to_get = (
113
+ "Ordonnance concernant des mesures spécifiques en cas de grand froid."
114
+ )
115
+
116
+ view = queryMultiAdapter((self.files_section, self.request), name="full_view")
117
+ self.assertIn(title_to_get, view())
118
+ self.assertNotIn("013400000123949.PDF", view())
119
+
120
+ view = queryMultiAdapter((self.files_section, self.request), name="table_view")
121
+ self.assertIn(title_to_get, [item[0]["title"] for item in view.items()])
122
+ self.assertEqual(
123
+ [
124
+ item[0]["publication_attached_file"].get("filename")
125
+ for item in view.items()
126
+ ][0],
127
+ "013400000123949.PDF",
128
+ )
129
+ self.assertEqual(
130
+ [item[0]["publication_document_type"] for item in view.items()][0],
131
+ "Ordonnance de police administrative",
132
+ )
133
+ self.assertEqual(
134
+ [item[0]["publication_datetime"] for item in view.items()][0],
135
+ "2024-08-14T09:14:31",
136
+ )
@@ -54,7 +54,7 @@ class TestIcons(ImioSmartwebTestCase):
54
54
  self.assertIn('<path d="M18 0H2V2H18V0ZM2 24H18V22H2V24ZM18', view)
55
55
 
56
56
  def test_icons_override(self):
57
- self.assertVocabularyLen("imio.smartweb.vocabulary.Icons", 49)
57
+ self.assertVocabularyLen("imio.smartweb.vocabulary.Icons", 64)
58
58
  portal_resources = getUtility(IResourceDirectory, name="persistent")
59
59
  portal_resources.makeDirectory("plone")
60
60
  portal_resources["plone"].makeDirectory("imio.smartweb.core")
@@ -134,34 +134,37 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
134
134
  endpoint.convert_cached_image_scales(item, modified_hash)
135
135
  self.assertEqual(len(item.keys()), 6)
136
136
 
137
- def test_get_extra_params(self):
137
+ def test_construct_query_string(self):
138
+ request = TestRequest()
139
+ endpoint = DirectoryEndpoint(self.portal, request)
140
+ query = endpoint.construct_query_string([])
141
+ self.assertEqual(query, "translated_in_en=1")
142
+
143
+ query = endpoint.construct_query_string(["param=1", "param2=2"])
144
+ self.assertEqual(query, "param=1&param2=2&translated_in_en=1")
145
+
138
146
  request = TestRequest(
139
147
  form={"taxonomy_contact_category": '("token")', "topics": "education"}
140
148
  )
141
149
  endpoint = DirectoryEndpoint(self.portal, request)
142
- params = endpoint.get_extra_params([])
150
+ query = endpoint.construct_query_string([])
143
151
  self.assertEqual(
144
- params,
145
- [
146
- 'taxonomy_contact_category=("token")',
147
- "topics=education",
148
- "translated_in_en=1",
149
- ],
152
+ query,
153
+ "taxonomy_contact_category=%28%22token%22%29&topics=education&translated_in_en=1",
150
154
  )
151
155
 
152
156
  request = TestRequest(
153
- form={"topics": "education", "metadata_fields": ["topics", "category"]}
157
+ form={
158
+ "topics": "education",
159
+ "metadata_fields": ["topics", "category"],
160
+ "local_category": "Local & category",
161
+ }
154
162
  )
155
163
  endpoint = DirectoryEndpoint(self.portal, request)
156
- params = endpoint.get_extra_params([])
164
+ query = endpoint.construct_query_string([])
157
165
  self.assertEqual(
158
- params,
159
- [
160
- "topics=education",
161
- "metadata_fields=topics",
162
- "metadata_fields=category",
163
- "translated_in_en=1",
164
- ],
166
+ query,
167
+ "topics=education&metadata_fields=topics&metadata_fields=category&local_category=Local+%26+category&translated_in_en=1",
165
168
  )
166
169
 
167
170
  @requests_mock.Mocker()
@@ -369,6 +372,8 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
369
372
  "http://localhost:8080/Plone/@events?"
370
373
  "selected_agendas={}&"
371
374
  "metadata_fields=category&"
375
+ "metadata_fields=local_category&"
376
+ "metadata_fields=container_uid&"
372
377
  "metadata_fields=topics&"
373
378
  "metadata_fields=start&"
374
379
  "metadata_fields=end&"
@@ -425,6 +430,8 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
425
430
  "selected_news_folders={}&"
426
431
  "portal_type=imio.news.NewsItem&"
427
432
  "metadata_fields=category&"
433
+ "metadata_fields=local_category&"
434
+ "metadata_fields=container_uid&"
428
435
  "metadata_fields=topics&"
429
436
  "metadata_fields=has_leadimage&"
430
437
  "metadata_fields=UID&"
@@ -487,6 +494,40 @@ class SectionsFunctionalTest(ImioSmartwebTestCase):
487
494
  view = queryMultiAdapter((self.rest_events, self.request), name="view")
488
495
  self.assertIn('display-map="True"', view())
489
496
 
497
+ def test_show_categories_or_topics(self):
498
+ rest_events = api.content.create(
499
+ container=self.portal,
500
+ type="imio.smartweb.EventsView",
501
+ title="events view",
502
+ )
503
+ view = queryMultiAdapter((rest_events, self.request), name="view")
504
+ self.assertIn('show-categories-or-topics="category"', view())
505
+ rest_events.show_categories_or_topics = "category"
506
+ view = queryMultiAdapter((rest_events, self.request), name="view")
507
+ self.assertIn('show-categories-or-topics="category"', view())
508
+ rest_events.show_categories_or_topics = "topic"
509
+ view = queryMultiAdapter((rest_events, self.request), name="view")
510
+ self.assertIn('show-categories-or-topics="topic"', view())
511
+ rest_events.show_categories_or_topics = ""
512
+ view = queryMultiAdapter((rest_events, self.request), name="view")
513
+ self.assertIn('show-categories-or-topics=""', view())
514
+ rest_news = api.content.create(
515
+ container=self.portal,
516
+ type="imio.smartweb.NewsView",
517
+ title="news view",
518
+ )
519
+ view = queryMultiAdapter((rest_news, self.request), name="view")
520
+ self.assertIn('show-categories-or-topics="category"', view())
521
+ rest_news.show_categories_or_topics = "category"
522
+ view = queryMultiAdapter((rest_news, self.request), name="view")
523
+ self.assertIn('show-categories-or-topics="category"', view())
524
+ rest_news.show_categories_or_topics = "topic"
525
+ view = queryMultiAdapter((rest_news, self.request), name="view")
526
+ self.assertIn('show-categories-or-topics="topic"', view())
527
+ rest_news.show_categories_or_topics = ""
528
+ view = queryMultiAdapter((rest_news, self.request), name="view")
529
+ self.assertIn('show-categories-or-topics=""', view())
530
+
490
531
  @patch("imio.smartweb.core.rest.authentic_sources.get_wca_token")
491
532
  @patch("imio.smartweb.core.rest.authentic_sources.requests.request")
492
533
  @patch("imio.smartweb.core.rest.authentic_sources.get_default_view_url")
@@ -8,6 +8,7 @@ from imio.smartweb.common.contact_utils import formatted_schedule
8
8
  from imio.smartweb.common.contact_utils import get_schedule_for_today
9
9
  from imio.smartweb.core.contents.sections.contact.utils import ContactProperties
10
10
  from imio.smartweb.core.contents.sections.views import SECTION_ITEMS_HASH_KEY
11
+ from imio.smartweb.core.tests.utils import clear_cache
11
12
  from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_FUNCTIONAL_TESTING
12
13
  from imio.smartweb.core.testing import ImioSmartwebTestCase
13
14
  from imio.smartweb.core.tests.utils import get_json
@@ -57,7 +58,8 @@ class TestSectionContact(ImioSmartwebTestCase):
57
58
  view = queryMultiAdapter((self.page, self.request), name="full_view")
58
59
  self.assertIn("My contact", view())
59
60
  contact_view = queryMultiAdapter((contact, self.request), name="view")
60
- self.assertIsNone(contact_view.contacts())
61
+ self.assertEqual(contact_view.contacts(), [])
62
+
61
63
  authentic_contact_uid = "2dc381f0fb584381b8e4a19c84f53b35"
62
64
  contact.related_contacts = [authentic_contact_uid]
63
65
  contact_search_url = (
@@ -69,12 +71,13 @@ class TestSectionContact(ImioSmartwebTestCase):
69
71
  authentic_contact_uid
70
72
  )
71
73
  m.get(contact_search_url, exc=requests.exceptions.ConnectTimeout)
72
- self.assertIsNone(contact_view.contacts())
74
+ self.assertEqual(contact_view.contacts(), [])
73
75
  m.get(contact_search_url, status_code=404)
74
- self.assertIsNone(contact_view.contacts())
76
+ self.assertEqual(contact_view.contacts(), [])
75
77
  m.get(contact_search_url, text=json.dumps(self.json_no_contact))
76
- self.assertIsNone(contact_view.contacts())
78
+ self.assertEqual(contact_view.contacts(), [])
77
79
  m.get(contact_search_url, text=json.dumps(self.json_contact))
80
+ clear_cache(self.request)
78
81
  self.assertIsNotNone(contact_view.contacts())
79
82
  json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
80
83
  self.assertEqual(json_contact.contact_type_class, "contact-type-organization")
@@ -113,6 +116,13 @@ class TestSectionContact(ImioSmartwebTestCase):
113
116
  m.get(contact_images_url, text=json.dumps(self.json_contact_images))
114
117
  self.assertIn("contact_gallery", view())
115
118
 
119
+ contact.visible_blocks = ["titles"]
120
+ json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
121
+ images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
122
+ self.assertNotIn("contact_gallery", view())
123
+ self.assertIsNone(images)
124
+
125
+ contact.visible_blocks = ["titles", "gallery"]
116
126
  json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
117
127
  images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
118
128
  self.assertEqual(len(images[0]), 2)
@@ -130,6 +140,18 @@ class TestSectionContact(ImioSmartwebTestCase):
130
140
  images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
131
141
  self.assertIsNone(images)
132
142
 
143
+ @requests_mock.Mocker()
144
+ def test_sorted_contacts_are_empty(self, m):
145
+ # TODO Separate test test_sorted_contacts_is_none /
146
+ # test_sorted_contacts 'cause of Memoize ??!!
147
+ contact = api.content.create(
148
+ container=self.page,
149
+ type="imio.smartweb.SectionContact",
150
+ title="My contact",
151
+ )
152
+ contact_view = queryMultiAdapter((contact, self.request), name="view")
153
+ self.assertEqual(contact_view.contacts(), [])
154
+
133
155
  @requests_mock.Mocker()
134
156
  def test_sorted_contacts(self, m):
135
157
  contact = api.content.create(
@@ -138,7 +160,6 @@ class TestSectionContact(ImioSmartwebTestCase):
138
160
  title="My contact",
139
161
  )
140
162
  contact_view = queryMultiAdapter((contact, self.request), name="view")
141
- self.assertIsNone(contact_view.contacts())
142
163
  authentic_contact_uid = [
143
164
  "2dc381f0fb584381b8e4a19c84f53b35",
144
165
  "af7bd1f547034b24a2e0da16c0ba0358",
@@ -501,7 +522,9 @@ class TestSectionContact(ImioSmartwebTestCase):
501
522
  "afternoonend": "",
502
523
  "comments": "",
503
524
  }
525
+ clear_cache(self.request)
504
526
  m.get(contact_search_url, text=json.dumps(json_contact_empty_schedule))
527
+ view = queryMultiAdapter((self.page, self.request), name="full_view")
505
528
  json_contact = ContactProperties(
506
529
  json_contact_empty_schedule.get("items")[0], contact
507
530
  )
@@ -549,7 +572,6 @@ class TestSectionContact(ImioSmartwebTestCase):
549
572
 
550
573
  annotations = IAnnotations(contact)
551
574
  self.assertIsNone(annotations.get(SECTION_ITEMS_HASH_KEY))
552
-
553
575
  self.assertIsNotNone(contact_view.contacts())
554
576
  hash_1 = annotations.get(SECTION_ITEMS_HASH_KEY)
555
577
  self.assertIsNotNone(hash_1)
@@ -557,15 +579,25 @@ class TestSectionContact(ImioSmartwebTestCase):
557
579
 
558
580
  sleep(1)
559
581
  m.get(contact_search_url, text=json.dumps(self.json_no_contact))
560
- self.assertIsNone(contact_view.contacts())
582
+ clear_cache(self.request)
583
+ contact_view = queryMultiAdapter((contact, self.request), name="view")
584
+ self.assertEqual(contact_view.contacts(), [])
585
+ # refresh_modification_date doesn't calculate when json_data is None
586
+ # For this section, this is the case
587
+ # For other sections, we get json_data with empty "items"
588
+ # Refactoring needed to ensure clarity ?
561
589
  next_modification = self.page.ModificationDate()
562
590
  hash_2 = annotations.get(SECTION_ITEMS_HASH_KEY)
563
- self.assertNotEqual(hash_1, hash_2)
564
- self.assertNotEqual(first_modification, next_modification)
591
+ self.assertEqual(hash_1, hash_2)
592
+ self.assertEqual(first_modification, next_modification)
565
593
 
566
594
  sleep(1)
567
- self.assertIsNone(contact_view.contacts())
595
+ contact_view = queryMultiAdapter((contact, self.request), name="view")
596
+ self.assertEqual(contact_view.contacts(), [])
568
597
  last_modification = self.page.ModificationDate()
569
598
  hash_3 = annotations.get(SECTION_ITEMS_HASH_KEY)
570
599
  self.assertEqual(hash_2, hash_3)
571
600
  self.assertEqual(next_modification, last_modification)
601
+
602
+ # TODO we should test with various contact sections containing
603
+ # contacts
@@ -59,12 +59,12 @@ class TestSectionEvents(ImioSmartwebTestCase):
59
59
  (self.events, self.request), name="carousel_view"
60
60
  )
61
61
  self.assertEqual(events_view.items, [])
62
- url = "http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=category_title&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query=2021-11-15&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
62
+ url = "http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query=2021-11-15&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
63
63
  m.get(url, text=json.dumps(self.json_events))
64
64
  self.assertEqual(events_view.items[0][0].get("title"), "Journée de l'ATL")
65
65
  self.assertEqual(len(events_view.items[0]), 2)
66
66
  self.events.specific_related_events = ["1178188bddde4ced95a6cf8bf04c443c"]
67
- url = "http://localhost:8080/Plone/@events?UID=1178188bddde4ced95a6cf8bf04c443c&metadata_fields=category_title&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query=2021-11-15&event_dates.range=min&b_size=6&translated_in_en=1"
67
+ url = "http://localhost:8080/Plone/@events?UID=1178188bddde4ced95a6cf8bf04c443c&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query=2021-11-15&event_dates.range=min&b_size=6&translated_in_en=1"
68
68
  m.get(url, text=json.dumps(self.json_specific_event))
69
69
  self.assertEqual(len(events_view.items[0]), 1)
70
70
  self.assertEqual(events_view.items[0][0].get("title"), "Bonne cheville")
@@ -84,7 +84,7 @@ class TestSectionEvents(ImioSmartwebTestCase):
84
84
  events_view = queryMultiAdapter(
85
85
  (self.events, self.request), name="carousel_view"
86
86
  )
87
- url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=category_title&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
87
+ url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
88
88
  m.get(url, text=json.dumps(self.json_events))
89
89
  self.assertEqual(len(events_view.items[0]), 2)
90
90
  hash_1 = annotations.get(SECTION_ITEMS_HASH_KEY)
@@ -92,7 +92,7 @@ class TestSectionEvents(ImioSmartwebTestCase):
92
92
  first_modification = self.portalpage.ModificationDate()
93
93
 
94
94
  sleep(1)
95
- url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=category_title&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
95
+ url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
96
96
  m.get(url, text="{}")
97
97
  self.assertEqual(len(events_view.items), 0)
98
98
  next_modification = self.portalpage.ModificationDate()
@@ -119,9 +119,32 @@ class TestSectionEvents(ImioSmartwebTestCase):
119
119
  events_view = queryMultiAdapter(
120
120
  (self.events, self.request), name="carousel_view"
121
121
  )
122
- url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=category_title&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
122
+ url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
123
123
  m.get(url, text=json.dumps(self.json_events))
124
124
 
125
125
  self.assertIn("paysage_vignette", events_view.items[0][0]["image"])
126
126
  self.events.orientation = "portrait"
127
127
  self.assertIn("portrait_vignette", events_view.items[0][0]["image"])
128
+
129
+ @requests_mock.Mocker()
130
+ def test_show_categories_or_topics(self, m):
131
+ today = datetime.now()
132
+ today_str = today.strftime("%Y-%m-%d")
133
+ intids = getUtility(IIntIds)
134
+ self.events.related_events = "e73e6a81afea4a579cd0da2773af8d29"
135
+ self.events.linking_rest_view = RelationValue(
136
+ intids.getId(self.rest_events_view)
137
+ )
138
+ events_view = queryMultiAdapter(
139
+ (self.events, self.request), name="carousel_view"
140
+ )
141
+ url = f"http://localhost:8080/Plone/@events?selected_agendas=e73e6a81afea4a579cd0da2773af8d29&metadata_fields=container_uid&metadata_fields=category_title&metadata_fields=local_category&metadata_fields=topics&metadata_fields=start&metadata_fields=end&metadata_fields=has_leadimage&metadata_fields=modified&metadata_fields=UID&event_dates.query={today_str}&event_dates.range=min&b_size=6&translated_in_en=1&sort_on=event_dates"
142
+ m.get(url, text=json.dumps(self.json_events))
143
+ self.assertEqual(events_view.items[0][0]["category"], "Local Category title")
144
+ self.assertEqual(events_view.items[0][1]["category"], "Presse")
145
+ self.events.show_categories_or_topics = "category"
146
+ self.assertEqual(events_view.items[0][0]["category"], "Local Category title")
147
+ self.events.show_categories_or_topics = "topic"
148
+ self.assertEqual(events_view.items[0][0]["category"], "Education")
149
+ self.events.show_categories_or_topics = ""
150
+ self.assertEqual(events_view.items[0][0]["category"], "")
@@ -1,11 +1,14 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
+ from imio.smartweb.core.interfaces import IOdwbViewUtils
3
4
  from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_FUNCTIONAL_TESTING
4
5
  from imio.smartweb.core.testing import ImioSmartwebTestCase
5
6
  from plone import api
6
7
  from plone.app.testing import setRoles
7
8
  from plone.app.testing import TEST_USER_ID
8
9
  from zope.component import queryMultiAdapter
10
+ from zope.interface import alsoProvides
11
+ from zope.interface import noLongerProvides
9
12
 
10
13
 
11
14
  class TestSectionExternalContent(ImioSmartwebTestCase):
@@ -21,6 +24,28 @@ class TestSectionExternalContent(ImioSmartwebTestCase):
21
24
  id="page",
22
25
  )
23
26
 
27
+ def test_parent_marker_interface(self):
28
+ sec1 = api.content.create(
29
+ container=self.page, type="imio.smartweb.SectionExternalContent", id="sec1"
30
+ )
31
+ self.assertTrue(IOdwbViewUtils.providedBy(self.page))
32
+
33
+ sec2 = api.content.create(
34
+ container=self.page, type="imio.smartweb.SectionExternalContent", id="sec2"
35
+ )
36
+ api.content.delete(obj=sec1)
37
+ self.assertTrue(IOdwbViewUtils.providedBy(self.page))
38
+
39
+ api.content.delete(obj=sec2)
40
+ self.assertFalse(IOdwbViewUtils.providedBy(self.page))
41
+
42
+ api.content.create(
43
+ container=self.page,
44
+ type="imio.smartweb.SectionText",
45
+ id="not_external_content_section",
46
+ )
47
+ self.assertFalse(IOdwbViewUtils.providedBy(self.page))
48
+
24
49
  def test_unknow_service(self):
25
50
  sec = api.content.create(
26
51
  container=self.page, type="imio.smartweb.SectionExternalContent", id="sec"
@@ -71,8 +96,9 @@ class TestSectionExternalContent(ImioSmartwebTestCase):
71
96
  "ConstellationWidgetContainer" : "11111111-1111-1111-1111-111111111111",
72
97
  "Idoi" : "22222222-2222-2222-2222-222222222222"
73
98
  }"""
99
+ self.maxDiff = None
74
100
  section_view = queryMultiAdapter((sec, self.request), name="view")
75
- result = '<div class="elloha"><div id="ConstellationWidgetContainer11111111-1111-1111-1111-111111111111" style="width:100%" data-id-projet="11111111111111111111111111111111">...</div></div><script type="text/javascript" src="https://reservation.elloha.com/Scripts/widget-loader.min.js?v=42/Scripts/widget-loader.min.js?v=42"></script><script type="text/javascript">var constellationWidgetUrl11111111111111111111111111111111, constellationTypeModule11111111111111111111111111111111;constellationWidgetUrl11111111111111111111111111111111 = "https://reservation.elloha.com/Widget/BookingEngine/11111111-1111-1111-1111-111111111111?idoi=22222222-2222-2222-2222-222222222222&culture=fr-FR";constellationTypeModule11111111111111111111111111111111=1; constellationWidgetLoad("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");constellationWidgetAddEvent(window, "resize", function () {constellationWidgetSetAppearance("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");});</script>'
101
+ result = '<div class="elloha" style="position:relative;"><div id="ConstellationWidgetContainer11111111-1111-1111-1111-111111111111" style="width:100%" data-id-projet="11111111111111111111111111111111">...</div></div><script type="text/javascript" src="https://reservation.elloha.com/Scripts/widget-loader.min.js?v=42"></script><script type="text/javascript">var constellationWidgetUrl11111111111111111111111111111111, constellationTypeModule11111111111111111111111111111111;constellationWidgetUrl11111111111111111111111111111111 = "https://reservation.elloha.com/Widget/BookingEngine/11111111-1111-1111-1111-111111111111?idoi=22222222-2222-2222-2222-222222222222&culture=fr-FR";constellationTypeModule11111111111111111111111111111111=1; constellationWidgetLoad("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");constellationWidgetAddEvent(window, "resize", function () {constellationWidgetSetAppearance("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");});</script>'
76
102
  self.assertEqual(section_view.contents, result)
77
103
 
78
104
  # good extra params / dict keys are case insensitive
@@ -81,7 +107,7 @@ class TestSectionExternalContent(ImioSmartwebTestCase):
81
107
  "IDOI" : "22222222-2222-2222-2222-222222222222"
82
108
  }"""
83
109
  section_view = queryMultiAdapter((sec, self.request), name="view")
84
- result = '<div class="elloha"><div id="ConstellationWidgetContainer11111111-1111-1111-1111-111111111111" style="width:100%" data-id-projet="11111111111111111111111111111111">...</div></div><script type="text/javascript" src="https://reservation.elloha.com/Scripts/widget-loader.min.js?v=42/Scripts/widget-loader.min.js?v=42"></script><script type="text/javascript">var constellationWidgetUrl11111111111111111111111111111111, constellationTypeModule11111111111111111111111111111111;constellationWidgetUrl11111111111111111111111111111111 = "https://reservation.elloha.com/Widget/BookingEngine/11111111-1111-1111-1111-111111111111?idoi=22222222-2222-2222-2222-222222222222&culture=fr-FR";constellationTypeModule11111111111111111111111111111111=1; constellationWidgetLoad("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");constellationWidgetAddEvent(window, "resize", function () {constellationWidgetSetAppearance("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");});</script>'
110
+ result = '<div class="elloha" style="position:relative;"><div id="ConstellationWidgetContainer11111111-1111-1111-1111-111111111111" style="width:100%" data-id-projet="11111111111111111111111111111111">...</div></div><script type="text/javascript" src="https://reservation.elloha.com/Scripts/widget-loader.min.js?v=42"></script><script type="text/javascript">var constellationWidgetUrl11111111111111111111111111111111, constellationTypeModule11111111111111111111111111111111;constellationWidgetUrl11111111111111111111111111111111 = "https://reservation.elloha.com/Widget/BookingEngine/11111111-1111-1111-1111-111111111111?idoi=22222222-2222-2222-2222-222222222222&culture=fr-FR";constellationTypeModule11111111111111111111111111111111=1; constellationWidgetLoad("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");constellationWidgetAddEvent(window, "resize", function () {constellationWidgetSetAppearance("ConstellationWidgetContainer11111111-1111-1111-1111-111111111111");});</script>'
85
111
  self.assertEqual(section_view.contents, result)
86
112
 
87
113
  # with bad params