imio.smartweb.common 1.2.37__tar.gz → 1.2.39__tar.gz

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 (179) hide show
  1. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/CHANGES.rst +17 -0
  2. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/PKG-INFO +18 -1
  3. imio_smartweb_common-1.2.39/requirements-6.1.txt +1 -0
  4. imio_smartweb_common-1.2.39/requirements.txt +1 -0
  5. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/setup.py +1 -1
  6. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/caching_overrides.zcml +1 -0
  7. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/metadata.xml +1 -1
  8. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/registry/tinymce.xml +3 -12
  9. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/endpoint.py +25 -11
  10. imio_smartweb_common-1.2.39/src/imio/smartweb/common/tests/test_rest_endpoint.py +238 -0
  11. imio_smartweb_common-1.2.39/src/imio/smartweb/common/tests/test_rest_utils.py +116 -0
  12. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/configure.zcml +19 -0
  13. imio_smartweb_common-1.2.39/src/imio/smartweb/common/upgrades/profiles/1033_to_1034/registry/tinymce.xml +70 -0
  14. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/PKG-INFO +18 -1
  15. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/SOURCES.txt +3 -0
  16. imio_smartweb_common-1.2.37/requirements-6.1.txt +0 -1
  17. imio_smartweb_common-1.2.37/requirements.txt +0 -1
  18. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/CONTRIBUTORS.rst +0 -0
  19. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/DEVELOP.rst +0 -0
  20. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/LICENSE.GPL +0 -0
  21. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/LICENSE.rst +0 -0
  22. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/MANIFEST.in +0 -0
  23. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/README.rst +0 -0
  24. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/docs/conf.py +0 -0
  25. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/docs/index.rst +0 -0
  26. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/requirements-6.0.txt +0 -0
  27. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/requirements-coverage.txt +0 -0
  28. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/setup.cfg +0 -0
  29. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/__init__.py +0 -0
  30. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/__init__.py +0 -0
  31. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/__init__.py +0 -0
  32. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/adapters.py +0 -0
  33. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/adapters.zcml +0 -0
  34. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/behaviors/__init__.py +0 -0
  35. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/behaviors/configure.zcml +0 -0
  36. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/behaviors/iam.py +0 -0
  37. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/behaviors/topics.py +0 -0
  38. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/__init__.py +0 -0
  39. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py +0 -0
  40. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/configure.zcml +0 -0
  41. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/cropping.py +0 -0
  42. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/description.pt +0 -0
  43. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/description.py +0 -0
  44. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/edit_taxonomy_data.pt +0 -0
  45. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/forms.py +0 -0
  46. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/overrides/plone.app.z3cform.templates.widget.pt +0 -0
  47. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/privacy/__init__.py +0 -0
  48. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/privacy/configure.zcml +0 -0
  49. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/privacy/form.py +0 -0
  50. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/privacy/utils.py +0 -0
  51. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/privacy/views.py +0 -0
  52. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/scaling.py +0 -0
  53. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/Makefile +0 -0
  54. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/package.json +0 -0
  55. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/smartweb-common-edit-compiled.css +0 -0
  56. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/smartweb-common-edit-compiled.js +0 -0
  57. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/smartweb-common-view-compiled.css +0 -0
  58. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/smartweb-common-view-compiled.js +0 -0
  59. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/src/edit.js +0 -0
  60. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/src/edit.less +0 -0
  61. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/src/view.js +0 -0
  62. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/src/view.less +0 -0
  63. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/static/webpack.config.js +0 -0
  64. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/browser/vocabulary.py +0 -0
  65. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/caching.py +0 -0
  66. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/config.py +0 -0
  67. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/configure.zcml +0 -0
  68. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/contact_utils.py +0 -0
  69. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/faceted/__init__.py +0 -0
  70. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/faceted/configure.zcml +0 -0
  71. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/faceted/utils.py +0 -0
  72. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/faceted/widget.pt +0 -0
  73. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/faceted/widget.py +0 -0
  74. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/indexers.py +0 -0
  75. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/indexers.zcml +0 -0
  76. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/interfaces.py +0 -0
  77. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/permissions.zcml +0 -0
  78. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/privacy.py +0 -0
  79. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/privacy.zcml +0 -0
  80. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/actions.xml +0 -0
  81. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/browserlayer.xml +0 -0
  82. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/catalog.xml +0 -0
  83. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/registry/registry.xml +0 -0
  84. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/default/rolemap.xml +0 -0
  85. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/catalog.xml +0 -0
  86. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/metadata.xml +0 -0
  87. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/registry.xml +0 -0
  88. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/types/Collection.xml +0 -0
  89. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/types/Document.xml +0 -0
  90. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/testing/types/Folder.xml +0 -0
  91. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles/uninstall/browserlayer.xml +0 -0
  92. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/profiles.zcml +0 -0
  93. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/__init__.py +0 -0
  94. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/configure.zcml +0 -0
  95. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/odwb.py +0 -0
  96. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/search_filters.py +0 -0
  97. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/rest/utils.py +0 -0
  98. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/serializers/__init__.py +0 -0
  99. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/serializers/configure.zcml +0 -0
  100. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/serializers/summary.py +0 -0
  101. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/setuphandlers.py +0 -0
  102. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/sharing/__init__.py +0 -0
  103. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/sharing/configure.zcml +0 -0
  104. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/sharing/localroles.py +0 -0
  105. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/sharing/permissions.py +0 -0
  106. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/sharing/permissions.zcml +0 -0
  107. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/subscribers.py +0 -0
  108. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/subscribers.zcml +0 -0
  109. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/testing.py +0 -0
  110. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/testing.zcml +0 -0
  111. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/__init__.py +0 -0
  112. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/resources/image.png +0 -0
  113. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/resources/image_1400x800.png +0 -0
  114. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/resources/image_1800x700.png +0 -0
  115. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/robot/test_example.robot +0 -0
  116. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_cropping.py +0 -0
  117. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_description.py +0 -0
  118. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_forms.py +0 -0
  119. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_indexes.py +0 -0
  120. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_local_roles.py +0 -0
  121. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_permissions.py +0 -0
  122. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_privacy.py +0 -0
  123. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_rest.py +0 -0
  124. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_robot.py +0 -0
  125. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_setup.py +0 -0
  126. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_subscribers.py +0 -0
  127. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_taxonomy.py +0 -0
  128. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_text.py +0 -0
  129. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_utils.py +0 -0
  130. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_viewlets.py +0 -0
  131. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_vocabularies.py +0 -0
  132. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_vocabulary.py +0 -0
  133. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/tests/test_widgets.py +0 -0
  134. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/__init__.py +0 -0
  135. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1007_to_1008/rolemap.xml +0 -0
  136. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1008_to_1009/actions.xml +0 -0
  137. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1009_to_1010/registry/tiny_nonbreakingspace.xml +0 -0
  138. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/resources.xml +0 -0
  139. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/scales.xml +0 -0
  140. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1010_to_1011/registry/tinymce.xml +0 -0
  141. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1011_to_1012/registry/bundles.xml +0 -0
  142. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1013_to_1014/registry/tinymce.xml +0 -0
  143. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1014_to_1015/registry/syndication.xml +0 -0
  144. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1015_to_1016/registry/patched-faceted-jquery.xml +0 -0
  145. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1016_to_1017/registry/scales.xml +0 -0
  146. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1017_to_1018/registry.xml +0 -0
  147. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1018_to_1019/registry/scales.xml +0 -0
  148. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1022_to_1023/registry/scales.xml +0 -0
  149. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1023_to_1024/registry/scales.xml +0 -0
  150. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1025_to_1026/registry/scales.xml +0 -0
  151. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1027_to_1028/restored-faceted-jquery.xml +0 -0
  152. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1028_to_1029/registry.xml +0 -0
  153. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1029_to_1030/registry.xml +0 -0
  154. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1030_to_1031/registry/tinymce.xml +0 -0
  155. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1031_to_1032/registry/tinymce.xml +0 -0
  156. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/profiles/1032_to_1033/registry/tinymce.xml +0 -0
  157. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/upgrades/upgrades.py +0 -0
  158. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/utility_overrides.zcml +0 -0
  159. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/utils.py +0 -0
  160. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/__init__.py +0 -0
  161. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/analytics.pt +0 -0
  162. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/colophon.pt +0 -0
  163. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/colophon.py +0 -0
  164. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/configure.zcml +0 -0
  165. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/privacy.pt +0 -0
  166. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/privacy.py +0 -0
  167. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/skip_to_content.pt +0 -0
  168. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/viewlets/skip_to_content.py +0 -0
  169. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/vocabularies.py +0 -0
  170. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/vocabularies.zcml +0 -0
  171. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/widgets/__init__.py +0 -0
  172. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/widgets/select.py +0 -0
  173. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/widgets/templates/ajaxselect_display.pt +0 -0
  174. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio/smartweb/common/widgets.zcml +0 -0
  175. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/dependency_links.txt +0 -0
  176. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/namespace_packages.txt +0 -0
  177. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/not-zip-safe +0 -0
  178. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/requires.txt +0 -0
  179. {imio_smartweb_common-1.2.37 → imio_smartweb_common-1.2.39}/src/imio.smartweb.common.egg-info/top_level.txt +0 -0
@@ -2,6 +2,23 @@ Changelog
2
2
  =========
3
3
 
4
4
 
5
+ 1.2.39 (2025-11-03)
6
+ -------------------
7
+
8
+ - Migration to Plone 6.1.3
9
+ [boulch]
10
+
11
+
12
+ 1.2.38 (2025-09-10)
13
+ -------------------
14
+
15
+ - @find : Process None value in a field or ["None", "other value"] for agatha stats
16
+ [boulch
17
+
18
+ - Add plone.app.caching include for futur proofing override
19
+ [jchandelle]
20
+
21
+
5
22
  1.2.37 (2025-09-03)
6
23
  -------------------
7
24
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imio.smartweb.common
3
- Version: 1.2.37
3
+ Version: 1.2.39
4
4
  Summary: Common utilities, vocabularies, taxonomies for imio.smartweb & co products
5
5
  Home-page: https://github.com/imio/imio.smartweb.common
6
6
  Author: iMio
@@ -178,6 +178,23 @@ Changelog
178
178
  =========
179
179
 
180
180
 
181
+ 1.2.39 (2025-11-03)
182
+ -------------------
183
+
184
+ - Migration to Plone 6.1.3
185
+ [boulch]
186
+
187
+
188
+ 1.2.38 (2025-09-10)
189
+ -------------------
190
+
191
+ - @find : Process None value in a field or ["None", "other value"] for agatha stats
192
+ [boulch
193
+
194
+ - Add plone.app.caching include for futur proofing override
195
+ [jchandelle]
196
+
197
+
181
198
  1.2.37 (2025-09-03)
182
199
  -------------------
183
200
 
@@ -0,0 +1 @@
1
+ -r https://dist.plone.org/release/6.1.3/requirements.txt
@@ -0,0 +1 @@
1
+ -r https://dist.plone.org/release/6.1.3/requirements.txt
@@ -16,7 +16,7 @@ long_description = "\n\n".join(
16
16
 
17
17
  setup(
18
18
  name="imio.smartweb.common",
19
- version="1.2.37",
19
+ version="1.2.39",
20
20
  description="Common utilities, vocabularies, taxonomies for imio.smartweb & co products",
21
21
  long_description=long_description,
22
22
  # Get more from https://pypi.org/classifiers/
@@ -3,6 +3,7 @@
3
3
  xmlns:cache="http://namespaces.zope.org/cache"
4
4
  xmlns:zcml="http://namespaces.zope.org/zcml">
5
5
 
6
+ <include package="plone.app.caching" />
6
7
  <include package="z3c.unconfigure" file="meta.zcml" />
7
8
 
8
9
  <unconfigure>
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <metadata>
3
- <version>1033</version>
3
+ <version>1034</version>
4
4
  <dependencies>
5
5
  <dependency>profile-plone.restapi:default</dependency>
6
6
  <dependency>profile-eea.facetednavigation:default</dependency>
@@ -53,11 +53,8 @@
53
53
  <element>code</element>
54
54
  <element>charmap</element>
55
55
  <element>fullscreen</element>
56
- <element>hr</element>
57
56
  <element>lists</element>
58
57
  <element>nonbreaking</element>
59
- <element>noneditable</element>
60
- <element>paste</element>
61
58
  <element>searchreplace</element>
62
59
  <element>table</element>
63
60
  <element>visualblocks</element>
@@ -70,13 +67,7 @@
70
67
  <record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
71
68
  name="plone.menubar"
72
69
  >
73
- <value purge="true">
74
- <element>edit</element>
75
- <element>format</element>
76
- <element>insert</element>
77
- <element>table</element>
78
- <element>view</element>
79
- </value>
70
+ <value purge="true">edit format insert table view</value>
80
71
  </record>
81
72
 
82
73
  <!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/available-menu-items/ -->
@@ -106,8 +97,8 @@
106
97
  "items": ""
107
98
  },
108
99
  "insert": {
109
- "title": "Insert",
110
- "items": "hr"
100
+ "title": "Insert",
101
+ "items": "hr"
111
102
  },
112
103
  "table": {
113
104
  "title": "Table",
@@ -25,8 +25,6 @@ class FindEndpointHandler(SearchHandler):
25
25
  if not types:
26
26
  raise Unauthorized("No types found, you are not allowed to search")
27
27
  self._constrain_query_by_path(query)
28
- if not query.get("path"):
29
- query["path"] = {"query": "/Plone"}
30
28
  # query = self._parse_query(query)
31
29
  if query.get("type_of_request") == "count_contents_types":
32
30
  results = self.count_contents_types(query)
@@ -130,24 +128,40 @@ class FindEndpointHandler(SearchHandler):
130
128
  if total == 0:
131
129
  return {}
132
130
 
133
- # Récupération des valeurs réelles dans les objets
131
+ # Récupération et normalisation des valeurs
134
132
  values = []
135
133
  for brain in brains:
136
134
  obj = brain.getObject()
137
135
  value = getattr(obj, field_name, None)
138
- if isinstance(value, (list, tuple)): # cas champ multi-valué
139
- values.extend(value)
136
+ if isinstance(value, (list, tuple)):
137
+ if not value:
138
+ # liste/tuple vide => on compte 1 None
139
+ values.append(None)
140
+ else:
141
+ mapped = [
142
+ None if (v in ("", "None") or v is None) else v for v in value
143
+ ]
144
+ # si TOUT est None, on compte 1 None (au lieu d'en ajouter 0)
145
+ if all(v is None for v in mapped):
146
+ values.append(None)
147
+ else:
148
+ values.extend(mapped)
140
149
  else:
141
- values.append(value)
150
+ v = None if (value in ("", "None") or value is None) else value
151
+ values.append(v)
142
152
  counter = Counter(values)
143
153
 
144
- # Calcul stats seulement pour expected_values
145
- result = {}
154
+ # Normalisation des valeurs attendues
146
155
  expected_values = normalize_query_param(expected_values)
147
- for val in expected_values:
148
- count = counter.get(val, 0)
156
+ # On garde les labels originaux pour l'affichage, mais on mappe "None" vers None réel pour le compteur
157
+ expected_mapping = {v: (None if v == "None" else v) for v in expected_values}
158
+
159
+ # Calcul stats
160
+ result = {}
161
+ for label, key in expected_mapping.items():
162
+ count = counter.get(key, 0)
149
163
  percent = (count / total) * 100 if total > 0 else 0
150
- result[val] = {"count": count, "percent": round(percent, 2)}
164
+ result[label] = {"count": count, "percent": round(percent, 2)}
151
165
  return result
152
166
 
153
167
 
@@ -0,0 +1,238 @@
1
+ # -*- coding: utf-8 -*-
2
+ from imio.smartweb.common.rest.endpoint import FindEndpointHandler
3
+ from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING
4
+ from plone import api
5
+ from plone.app.testing import setRoles
6
+ from plone.app.testing import TEST_USER_ID
7
+ from plone.namedfile.file import NamedBlobFile, NamedBlobImage
8
+ from unittest.mock import patch
9
+ from zExceptions import Unauthorized
10
+
11
+ import unittest
12
+
13
+
14
+ class TestRestEndpoint(unittest.TestCase):
15
+ layer = IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING
16
+
17
+ def setUp(self):
18
+ self.request = self.layer["request"]
19
+ self.portal = self.layer["portal"]
20
+
21
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
22
+ # Simule un header d'auth présent dans la requête
23
+ self.request._orig_env = {"HTTP_AUTHORIZATION": "Bearer TEST"}
24
+ self.folder = api.content.create(
25
+ container=self.portal,
26
+ type="Folder",
27
+ title="Folder",
28
+ )
29
+ self.doc1 = api.content.create(
30
+ container=self.folder, type="Document", title="Doc 1"
31
+ )
32
+ self.doc2 = api.content.create(
33
+ container=self.folder, type="Document", title="Doc 2"
34
+ )
35
+ self.page = api.content.create(
36
+ container=self.folder, type="Document", title="Doc 3"
37
+ )
38
+
39
+ def test_no_types(self):
40
+ query = {
41
+ "type_of_request": "count_contents_types",
42
+ "portal_type": "Document",
43
+ "path": {"query": self.portal.absolute_url_path()},
44
+ "operator": "and",
45
+ }
46
+ handler = FindEndpointHandler(self.portal, self.request)
47
+ self.assertRaises(Unauthorized, handler.search, query)
48
+
49
+ # ------------------------------
50
+ # count_contents_types
51
+ # ------------------------------
52
+ @patch("imio.smartweb.common.rest.endpoint.get_json")
53
+ def test_count_contents_types_operator_and(self, mjson):
54
+ mjson.return_value = [
55
+ {
56
+ "@id": f"https://{self.portal.absolute_url()}/@types/Document",
57
+ "addable": "false",
58
+ "id": "Document",
59
+ "immediately_addable": "false",
60
+ "title": "Document",
61
+ }
62
+ ]
63
+ handler = FindEndpointHandler(self.portal, self.request)
64
+ query = {
65
+ "type_of_request": "count_contents_types",
66
+ "portal_type": "Document",
67
+ "path": {"query": self.portal.absolute_url_path()},
68
+ "operator": "and",
69
+ }
70
+ res = handler.search(query)
71
+ self.assertEqual(res, {"items": [{"portal_type": "Document", "nb_items": 3}]})
72
+
73
+ # Test without path in query.
74
+ # Path is automaticaly set.
75
+ query = {
76
+ "type_of_request": "count_contents_types",
77
+ "portal_type": "Document",
78
+ "operator": "and",
79
+ }
80
+ res = handler.search(query)
81
+ self.assertEqual(res, {"items": [{"portal_type": "Document", "nb_items": 3}]})
82
+
83
+ @patch("imio.smartweb.common.rest.endpoint.get_json")
84
+ def test_count_contents_types_operator_or_multiple_types(self, mjson):
85
+ mjson.return_value = [
86
+ {
87
+ "@id": f"https://{self.portal.absolute_url()}/@types/Document",
88
+ "addable": "false",
89
+ "id": "Document",
90
+ "immediately_addable": "false",
91
+ "title": "Document",
92
+ },
93
+ {
94
+ "@id": f"https://{self.portal.absolute_url()}/@types/Folder",
95
+ "addable": "false",
96
+ "id": "Folder",
97
+ "immediately_addable": "false",
98
+ "title": "Folder",
99
+ },
100
+ ]
101
+ handler = FindEndpointHandler(self.portal, self.request)
102
+ query = {
103
+ "type_of_request": "count_contents_types",
104
+ "portal_type": ["Document", "Folder"],
105
+ "path": {"query": self.portal.absolute_url_path()},
106
+ "operator": "and",
107
+ }
108
+ res = handler.search(query)
109
+ self.assertEqual(
110
+ res, {"items": [{"portal_type": ["Document", "Folder"], "nb_items": 4}]}
111
+ )
112
+
113
+ @patch("imio.smartweb.common.rest.endpoint.get_json")
114
+ def test_get_max_depth(self, mjson):
115
+ mjson.return_value = [
116
+ {
117
+ "@id": f"https://{self.portal.absolute_url()}/@types/Document",
118
+ "addable": "false",
119
+ "id": "Document",
120
+ "immediately_addable": "false",
121
+ "title": "Document",
122
+ }
123
+ ]
124
+ handler = FindEndpointHandler(self.portal, self.request)
125
+ res = handler.search({"type_of_request": "get_max_depth"})
126
+ self.assertEqual(res["max_depth"], 3)
127
+
128
+ paths = {i["path"] for i in res["items"]}
129
+ self.assertEqual(
130
+ paths, {"/plone/folder/doc-2", "/plone/folder/doc-3", "/plone/folder/doc-1"}
131
+ )
132
+
133
+ folder2 = api.content.create(
134
+ container=self.folder,
135
+ type="Folder",
136
+ title="Folder 2",
137
+ )
138
+
139
+ api.content.create(
140
+ container=folder2,
141
+ type="Document",
142
+ title="Kamoulox",
143
+ )
144
+ handler = FindEndpointHandler(self.portal, self.request)
145
+ res = handler.search({"type_of_request": "get_max_depth"})
146
+ self.assertEqual(res["max_depth"], 4)
147
+
148
+ paths = {i["path"] for i in res["items"]}
149
+ self.assertEqual(paths, {"/plone/folder/folder-2/kamoulox"})
150
+
151
+ @patch("imio.smartweb.common.rest.endpoint.get_json")
152
+ def test_check_value_of_field_counts_and_percents(self, mjson):
153
+ mjson.return_value = [
154
+ {
155
+ "@id": f"https://{self.portal.absolute_url()}/@types/Document",
156
+ "addable": "false",
157
+ "id": "Document",
158
+ "immediately_addable": "false",
159
+ "title": "Document",
160
+ }
161
+ ]
162
+ api.content.create(
163
+ container=self.folder,
164
+ type="Document",
165
+ title="Doc 2",
166
+ )
167
+ handler = FindEndpointHandler(self.portal, self.request)
168
+ q = {
169
+ "type_of_request": "check_value_of_field",
170
+ "portal_type": "Document",
171
+ "field_name": "title",
172
+ "expected_values": ["Doc 1", "Doc 2", "Doc 3"],
173
+ }
174
+ res = handler.search(q)
175
+ # Number
176
+ self.assertEqual(res["Doc 1"]["count"], 1)
177
+ self.assertEqual(res["Doc 2"]["count"], 2)
178
+ self.assertEqual(res["Doc 3"]["count"], 1)
179
+
180
+ # Pourcentages
181
+ self.assertEqual(res["Doc 1"]["percent"], round(1 / 4 * 100, 2)) # 25%
182
+ self.assertEqual(res["Doc 2"]["percent"], round(2 / 4 * 100, 2)) # 50%
183
+ self.assertEqual(res["Doc 3"]["percent"], round(1 / 4 * 100, 2)) # 25%
184
+
185
+ @patch("imio.smartweb.common.rest.endpoint.get_json")
186
+ def test_find_big_files_or_images(self, mjson):
187
+ mjson.return_value = [
188
+ {
189
+ "@id": f"https://{self.portal.absolute_url()}/@types/Image",
190
+ "addable": "false",
191
+ "id": "Image",
192
+ "immediately_addable": "false",
193
+ "title": "Image",
194
+ },
195
+ {
196
+ "@id": f"https://{self.portal.absolute_url()}/@types/File",
197
+ "addable": "false",
198
+ "id": "File",
199
+ "immediately_addable": "false",
200
+ "title": "File",
201
+ },
202
+ ]
203
+ api.content.create(
204
+ container=self.folder,
205
+ type="File",
206
+ id="bigfile",
207
+ title="Big file",
208
+ file=NamedBlobFile(data=b"x" * 2500000, filename="big.pdf"), # 2,5 Mo
209
+ )
210
+
211
+ api.content.create(
212
+ container=self.folder,
213
+ type="Image",
214
+ id="smallimage",
215
+ title="Small image",
216
+ image=NamedBlobImage(data=b"x" * 100000, filename="small.jpg"), # 0,1 Mo
217
+ )
218
+
219
+ api.content.create(
220
+ container=self.folder,
221
+ type="Image",
222
+ id="bigimage",
223
+ title="Big image",
224
+ image=NamedBlobImage(data=b"x" * 3100000, filename="big.jpg"), # 3,1 Mo
225
+ )
226
+ handler = FindEndpointHandler(self.portal, self.request)
227
+ q = {
228
+ "type_of_request": "find_big_files_or_images",
229
+ "portal_type": ["Image", "File"],
230
+ "size": 1000000,
231
+ }
232
+ res = handler.search(q)
233
+ # On attend seulement les gros
234
+ titles = [it["title"] for it in res["items"]]
235
+ self.assertEqual(set(titles), {"Big file", "Big image"})
236
+ # Vérifie calcul Mo arrondi (2_500_000 bytes ≈ 2.38 Mo)
237
+ big_entry = next(i for i in res["items"] if i["title"] == "Big file")
238
+ self.assertAlmostEqual(big_entry["size"], round(2_500_000 / (1024 * 1024), 2))
@@ -0,0 +1,116 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_ACCEPTANCE_TESTING
4
+ from imio.smartweb.common.rest.utils import batch_results
5
+ from imio.smartweb.common.rest.utils import get_json
6
+ from imio.smartweb.common.rest.utils import hash_md5
7
+ from unittest.mock import patch
8
+ from unittest.mock import Mock
9
+
10
+ import json
11
+ import requests
12
+ import unittest
13
+
14
+
15
+ class TestRestUtils(unittest.TestCase):
16
+ layer = IMIO_SMARTWEB_COMMON_ACCEPTANCE_TESTING
17
+
18
+ def setUp(self):
19
+ self.request = self.layer["request"]
20
+ self.portal = self.layer["portal"]
21
+ self.portal_url = self.portal.absolute_url()
22
+ self.url = "https://api.kamoulox.test/endpoint"
23
+
24
+ @patch("imio.smartweb.common.rest.utils.requests.get")
25
+ def test_get_json_success(self, mock_get):
26
+ payload = {"ok": True, "items": [1, 2]}
27
+ mock_get.return_value = Mock(status_code=200, text=json.dumps(payload))
28
+ result = get_json(self.url)
29
+ self.assertEqual(result, payload)
30
+ mock_get.assert_called_once()
31
+ (called_url,) = mock_get.call_args[0]
32
+ self.assertEqual(called_url, self.url)
33
+ kwargs = mock_get.call_args.kwargs
34
+ self.assertEqual(kwargs["timeout"], 5)
35
+ self.assertEqual(kwargs["headers"]["Accept"], "application/json")
36
+ self.assertNotIn("Authorization", kwargs["headers"])
37
+
38
+ @patch("imio.smartweb.common.rest.utils.requests.get")
39
+ def test_get_json_non_200_returns_none(self, mock_get):
40
+ mock_get.return_value = Mock(status_code=404, text="Not found")
41
+ result = get_json(self.url)
42
+ self.assertIsNone(result)
43
+
44
+ @patch("imio.smartweb.common.rest.utils.logger")
45
+ @patch("imio.smartweb.common.rest.utils.requests.get")
46
+ def test_get_json_timeout_returns_none_and_logs(self, mock_get, mock_logger):
47
+ mock_get.side_effect = requests.exceptions.Timeout()
48
+ result = get_json(self.url)
49
+ self.assertIsNone(result)
50
+ mock_logger.warning.assert_called_once()
51
+ # check if url is in log
52
+ self.assertIn(self.url, mock_logger.warning.call_args[0][0])
53
+
54
+ @patch("imio.smartweb.common.rest.utils.requests.get")
55
+ def test_get_json_other_exception_returns_none(self, mock_get):
56
+ mock_get.side_effect = RuntimeError("kamoulox")
57
+ result = get_json(self.url)
58
+ self.assertIsNone(result)
59
+
60
+ @patch("imio.smartweb.common.rest.utils.requests.get")
61
+ def test_get_json_sets_auth_header_when_provided(self, mock_get):
62
+ mock_get.return_value = Mock(status_code=200, text="{}")
63
+ auth = "Bearer TOKEN123"
64
+ _ = get_json(self.url, auth=auth, timeout=10)
65
+ mock_get.assert_called_once()
66
+ kwargs = mock_get.call_args.kwargs
67
+ self.assertEqual(kwargs["timeout"], 10)
68
+ self.assertEqual(kwargs["headers"]["Authorization"], auth)
69
+ self.assertEqual(kwargs["headers"]["Accept"], "application/json")
70
+
71
+ @patch("imio.smartweb.common.rest.utils.requests.get")
72
+ def test_get_json_custom_timeout_is_used(self, mock_get):
73
+ mock_get.return_value = Mock(status_code=200, text="{}")
74
+ _ = get_json(self.url, timeout=2.5)
75
+ self.assertEqual(mock_get.call_args.kwargs["timeout"], 2.5)
76
+
77
+ def test_batch_results_exact_division(self):
78
+ data = [1, 2, 3, 4]
79
+ result = batch_results(data, 2)
80
+ self.assertEqual(result, [[1, 2], [3, 4]])
81
+
82
+ def test_batch_results_not_exact(self):
83
+ data = [1, 2, 3, 4, 5]
84
+ result = batch_results(data, 2)
85
+ self.assertEqual(result, [[1, 2], [3, 4], [5]])
86
+
87
+ def test_batch_results_batch_size_larger_than_list(self):
88
+ data = [1, 2, 3]
89
+ result = batch_results(data, 10)
90
+ self.assertEqual(result, [[1, 2, 3]])
91
+
92
+ def test_batch_results_empty_iterable(self):
93
+ data = []
94
+ result = batch_results(data, 3)
95
+ self.assertEqual(result, [])
96
+
97
+ def test_batch_results_with_generator(self):
98
+ gen = (i for i in range(5))
99
+ result = batch_results(gen, 2)
100
+ self.assertEqual(result, [[0, 1], [2, 3], [4]])
101
+
102
+ def test_hash_md5_basic_string(self):
103
+ result = hash_md5("hello")
104
+ self.assertEqual(result, "5d41402abc4b2a76b9719d911017c592")
105
+
106
+ def test_hash_md5_empty_string(self):
107
+ result = hash_md5("")
108
+ self.assertEqual(result, "d41d8cd98f00b204e9800998ecf8427e")
109
+
110
+ def test_hash_md5_unicode_string(self):
111
+ result = hash_md5("éèà")
112
+ # tu peux vérifier avec hashlib directement
113
+ import hashlib
114
+
115
+ expected = hashlib.md5("éèà".encode()).hexdigest()
116
+ self.assertEqual(result, expected)
@@ -165,6 +165,14 @@
165
165
  directory="profiles/1032_to_1033"
166
166
  />
167
167
 
168
+ <genericsetup:registerProfile
169
+ name="upgrade_1033_to_1034"
170
+ title="Upgrade common from 1033 to 1034"
171
+ description="Update configuration from TinyMCE 7.7.0 to be TinyMCE 7.9.1"
172
+ provides="Products.GenericSetup.interfaces.EXTENSION"
173
+ directory="profiles/1033_to_1034"
174
+ />
175
+
168
176
  <genericsetup:upgradeStep
169
177
  title="Configure first official release"
170
178
  description="Run needed registry step"
@@ -515,4 +523,15 @@
515
523
  />
516
524
  </genericsetup:upgradeSteps>
517
525
 
526
+ <genericsetup:upgradeSteps
527
+ profile="imio.smartweb.common:default"
528
+ source="1033"
529
+ destination="1034"
530
+ >
531
+ <genericsetup:upgradeDepends
532
+ title="Update configuration from TinyMCE 7.7.0 to be TinyMCE 7.9.1"
533
+ import_profile="imio.smartweb.common.upgrades:upgrade_1033_to_1034"
534
+ />
535
+ </genericsetup:upgradeSteps>
536
+
518
537
  </configure>
@@ -0,0 +1,70 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <registry>
3
+
4
+ <record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
5
+ name="plone.plugins"
6
+ >
7
+ <value purge="true">
8
+ <element>code</element>
9
+ <element>charmap</element>
10
+ <element>fullscreen</element>
11
+ <element>lists</element>
12
+ <element>nonbreaking</element>
13
+ <element>searchreplace</element>
14
+ <element>table</element>
15
+ <element>visualblocks</element>
16
+ <element>visualchars</element>
17
+ <element>wordcount</element>
18
+ </value>
19
+ </record>
20
+
21
+ <!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/menus-configuration-options/#menubar -->
22
+ <record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
23
+ name="plone.menubar">
24
+ <value purge="true">edit format insert table view</value>
25
+ </record>
26
+
27
+ <record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
28
+ name="plone.menu">
29
+ <value purge="true">
30
+ {
31
+ "file": {
32
+ "title": "File",
33
+ "items": ""
34
+ },
35
+ "tools": {
36
+ "title": "Tools",
37
+ "items": ""
38
+ },
39
+ "edit": {
40
+ "title": "Edit",
41
+ "items": "undo redo | cut copy paste | searchreplace selectall"
42
+ },
43
+ "format": {
44
+ "title": "Format",
45
+ "items": ""
46
+ },
47
+ "insert": {
48
+ "title": "Insert",
49
+ "items": "hr"
50
+ },
51
+ "table": {
52
+ "title": "Table",
53
+ "items": "inserttable deletetable | cell row column"
54
+ },
55
+ "view": {
56
+ "title": "View",
57
+ "items": "visualblocks preview fullscreen"
58
+ }
59
+ }
60
+ </value>
61
+ </record>
62
+
63
+ <!-- See possible values in https://www.tiny.cloud/docs/tinymce/latest/available-toolbar-buttons/ -->
64
+ <record interface="plone.base.interfaces.controlpanel.ITinyMCESchema"
65
+ name="plone.toolbar"
66
+ >
67
+ <value>undo redo | styleselect | bold italic superscript | bullist numlist | nonbreaking | plonelink unlink | fullscreen</value>
68
+ </record>
69
+
70
+ </registry>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: imio.smartweb.common
3
- Version: 1.2.37
3
+ Version: 1.2.39
4
4
  Summary: Common utilities, vocabularies, taxonomies for imio.smartweb & co products
5
5
  Home-page: https://github.com/imio/imio.smartweb.common
6
6
  Author: iMio
@@ -178,6 +178,23 @@ Changelog
178
178
  =========
179
179
 
180
180
 
181
+ 1.2.39 (2025-11-03)
182
+ -------------------
183
+
184
+ - Migration to Plone 6.1.3
185
+ [boulch]
186
+
187
+
188
+ 1.2.38 (2025-09-10)
189
+ -------------------
190
+
191
+ - @find : Process None value in a field or ["None", "other value"] for agatha stats
192
+ [boulch
193
+
194
+ - Add plone.app.caching include for futur proofing override
195
+ [jchandelle]
196
+
197
+
181
198
  1.2.37 (2025-09-03)
182
199
  -------------------
183
200