diff --git a/.github/workflows/plone-package-test-gha.yml b/.github/workflows/plone-package-test-gha.yml index 6ae9b88..f92f155 100644 --- a/.github/workflows/plone-package-test-gha.yml +++ b/.github/workflows/plone-package-test-gha.yml @@ -24,8 +24,10 @@ jobs: test: runs-on: gha-runners-smartweb strategy: + fail-fast: false matrix: - python-version: ['3.10', '3.12'] + plone-version: ['6.0', '6.1'] + python-version: ['3.10', '3.11', '3.12', '3.13'] steps: - name: Checkout codebase uses: actions/checkout@v4 @@ -34,6 +36,8 @@ jobs: with: CACHE_KEY: eggs-test-${{ hashFiles('base.cfg') }}-python-${{ matrix.python-version }} TEST_COMMAND: TZ=UTC bin/test + BUILDOUT_CONFIG_FILE: 'test_plone-${{ matrix.plone-version }}.cfg' + REQUIREMENTS_FILE: 'requirements-${{ matrix.plone-version }}.txt' MATTERMOST_WEBHOOK_URL: ${{ secrets.SMARTWEB_MATTERMOST_WEBHOOK_URL }} PYTHON_VERSION: ${{ matrix.python-version }} @@ -53,4 +57,3 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: coveralls --service=github - diff --git a/CHANGES.rst b/CHANGES.rst index e670062..42a1187 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,11 @@ Changelog 1.2.28 (unreleased) ------------------- -- Nothing changed yet. +- Upgrade dev environment to Plone 6.1-latest + [remdub] + +- Add tests for Plone 6.1-latest and add Python 3.13 + [remdub] 1.2.27 (2025-03-19) diff --git a/base.cfg b/base-6.0.cfg similarity index 100% rename from base.cfg rename to base-6.0.cfg diff --git a/base-6.1.cfg b/base-6.1.cfg new file mode 100644 index 0000000..eecdd20 --- /dev/null +++ b/base-6.1.cfg @@ -0,0 +1,65 @@ +[buildout] +show-picked-versions = true +extensions = + mr.developer + +sources-dir = devel + +extends = + https://dist.plone.org/release/6.1-latest/versions.cfg + https://dist.plone.org/release/6.1-latest/versions-ecosystem.cfg + https://dist.plone.org/release/6.1-latest/versions-extra.cfg + https://raw.githubusercontent.com/IMIO/buildout.smartweb/main/versions.cfg + https://raw.githubusercontent.com/IMIO/buildout.smartweb/main/sources.cfg + +parts = + instance +# releaser + omelette + plone-helper-scripts + vscode + +develop = . + +auto-checkout += + imio.smartweb.locales + +[instance] +recipe = plone.recipe.zope2instance +zodb-temporary-storage = off +user = admin:admin +http-address = 8080 +environment-vars = + zope_i18n_compile_mo_files true +eggs = + Plone + Pillow + imio.smartweb.common +zcml = + imio.smartweb.common + +[vscode] +recipe = collective.recipe.vscode +eggs = ${instance:eggs} +autocomplete-use-omelette = True + +[omelette] +recipe = collective.recipe.omelette +eggs = ${instance:eggs} + +[releaser] +recipe = zc.recipe.egg +eggs = zest.releaser + +[plone-helper-scripts] +recipe = zc.recipe.egg +eggs = + Products.CMFPlone + ${instance:eggs} +interpreter = zopepy +scripts = + zopepy + +[versions] +# Don't use a released version of imio.smartweb.common +imio.smartweb.common = diff --git a/buildout.cfg b/buildout.cfg index 0d5e93b..f1efe62 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -3,4 +3,4 @@ # use this extend one of the buildout configuration: extends = # -*- mrbob: extra extends -*- - test_plone6.cfg + test_plone-6.0.cfg diff --git a/requirements.txt b/requirements-6.0.txt similarity index 100% rename from requirements.txt rename to requirements-6.0.txt diff --git a/requirements-6.1.txt b/requirements-6.1.txt new file mode 100644 index 0000000..b48e71e --- /dev/null +++ b/requirements-6.1.txt @@ -0,0 +1 @@ +-r https://dist.plone.org/release/6.1-latest/requirements.txt diff --git a/requirements-coverage.txt b/requirements-coverage.txt index 0be2ef0..9f2b53f 100644 --- a/requirements-coverage.txt +++ b/requirements-coverage.txt @@ -1,2 +1,2 @@ --r requirements.txt +-r requirements-6.0.txt coveralls==3.2.0 \ No newline at end of file diff --git a/setup.py b/setup.py index 2974fab..6299bd7 100644 --- a/setup.py +++ b/setup.py @@ -26,10 +26,13 @@ "Framework :: Plone", "Framework :: Plone :: Addon", "Framework :: Plone :: 6.0", + "Framework :: Plone :: 6.1", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Operating System :: OS Independent", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", ], diff --git a/src/imio/smartweb/common/adapters.py b/src/imio/smartweb/common/adapters.py index 529448d..22fda4c 100644 --- a/src/imio/smartweb/common/adapters.py +++ b/src/imio/smartweb/common/adapters.py @@ -4,7 +4,6 @@ from plone.namedfile.interfaces import IAvailableSizes from plone.namedfile.interfaces import INamedImageField from plone.namedfile.field import InvalidImageFile -from plone.namedfile.utils import get_contenttype from zope.component import adapter from zope.component import getUtility from zope.interface import Interface diff --git a/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py b/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py index 56f8dcb..f45ac0c 100644 --- a/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py +++ b/src/imio/smartweb/common/browser/collective_taxonomy_controlpanel.py @@ -2,11 +2,8 @@ from collective.taxonomy.interfaces import ITaxonomy from collective.taxonomy.jsonimpl import EditTaxonomyData as baseEditTaxonomyData -from imio.smartweb.locales import SmartwebMessageFactory as _ from plone import api from zope.component import queryUtility -from zope.component import queryUtility -from plone import api from Products.Five import BrowserView diff --git a/src/imio/smartweb/common/tests/test_widgets.py b/src/imio/smartweb/common/tests/test_widgets.py index 7f571b5..91aa0c7 100644 --- a/src/imio/smartweb/common/tests/test_widgets.py +++ b/src/imio/smartweb/common/tests/test_widgets.py @@ -2,9 +2,11 @@ from imio.smartweb.common.testing import IMIO_SMARTWEB_COMMON_INTEGRATION_TESTING from imio.smartweb.common.widgets.select import TranslatedAjaxSelectWidget +from importlib.metadata import version from plone.api import portal as portal_api from zope.publisher.browser import TestRequest + import mock import unittest @@ -20,42 +22,99 @@ def test_translated_ajax_select(self): portal_api.get_current_language = mock.Mock(return_value="fr") widget = TranslatedAjaxSelectWidget(self.request) widget.update() - self.assertEqual( - { - "name": None, - "value": "", - "pattern": "select2", - "pattern_options": {"separator": ";"}, - }, - widget._base_args(), - ) - - widget.vocabulary = "imio.smartweb.vocabulary.Topics" - self.assertEqual( - widget._base_args(), - { - "name": None, - "value": "", - "pattern": "select2", - "pattern_options": { - "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", - "separator": ";", - }, - }, - ) - widget.value = "entertainment" - self.assertEqual( - widget._base_args(), - { - "name": None, - "value": "entertainment", - "pattern": "select2", - "pattern_options": { - "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", - "initialValues": { - "entertainment": "Activités et divertissement", + # __import__("pdb").set_trace() + if version("plone.app.z3cform") < "4.4.0": + self.assertEqual( + { + "name": None, + "value": "", + "pattern": "select2", + "pattern_options": {"separator": ";"}, + }, + widget._base_args(), + ) + widget.vocabulary = "imio.smartweb.vocabulary.Topics" + self.assertEqual( + widget._base_args(), + { + "name": None, + "value": "", + "pattern": "select2", + "pattern_options": { + "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", + "separator": ";", }, - "separator": ";", }, - }, - ) + ) + widget.value = "entertainment" + self.assertEqual( + widget._base_args(), + { + "name": None, + "value": "entertainment", + "pattern": "select2", + "pattern_options": { + "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", + "initialValues": { + "entertainment": "Activités et divertissement", + }, + "separator": ";", + }, + }, + ) + else: + # _base.args has been removed + # see https://github.com/plone/plone.app.z3cform/commit/5de30e9b117885859680dfe3861f134a667cea9c + self.assertEqual( + { + "name": None, + "value": None, + "pattern": "select2", + "pattern_options": {"separator": ";"}, + }, + { + "name": widget.name, + "value": widget.value, + "pattern": widget.pattern, + "pattern_options": widget.get_pattern_options(), + }, + ) + widget.vocabulary = "imio.smartweb.vocabulary.Topics" + self.assertEqual( + { + "name": None, + "value": None, + "pattern": "select2", + "pattern_options": { + "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", + "separator": ";", + }, + }, + { + "name": widget.name, + "value": widget.value, + "pattern": widget.pattern, + "pattern_options": widget.get_pattern_options(), + }, + ) + widget.value = "entertainment" + self.assertEqual( + { + "name": None, + "value": "entertainment", + "pattern": "select2", + "pattern_options": { + "vocabularyUrl": "http://nohost/plone/@@getVocabulary?name=imio.smartweb.vocabulary.Topics", + "initialValues": { + "entertainment": "Activités et divertissement", + }, + "separator": ";", + }, + }, + { + "name": widget.name, + "value": widget.value, + "pattern": widget.pattern, + "pattern_options": widget.get_pattern_options(), + }, + ) diff --git a/test_plone6.cfg b/test_plone-6.0.cfg similarity index 98% rename from test_plone6.cfg rename to test_plone-6.0.cfg index 068607c..b286e94 100644 --- a/test_plone6.cfg +++ b/test_plone-6.0.cfg @@ -1,7 +1,7 @@ [buildout] extends = https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg - base.cfg + base-6.0.cfg parts += code-analysis diff --git a/test_plone-6.1.cfg b/test_plone-6.1.cfg new file mode 100644 index 0000000..f6b6211 --- /dev/null +++ b/test_plone-6.1.cfg @@ -0,0 +1,51 @@ +[buildout] +extends = + https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg + base-6.1.cfg + +parts += + code-analysis + test + coverage + test-coverage + createcoverage + robot + +[code-analysis] +flake8-ignore = E501,W503,E203 + +[test] +recipe = zc.recipe.testrunner +eggs = + ${instance:eggs} + imio.smartweb.common [test] +initialization = + os.environ['TZ'] = 'UTC' +defaults = ['-s', 'imio.smartweb.common', '--auto-color', '--auto-progress'] +environment = testenv + +[testenv] +zope_i18n_compile_mo_files = true + +[coverage] +recipe = zc.recipe.egg +eggs = coverage + +[test-coverage] +recipe = collective.recipe.template +input = inline: + #!/bin/bash + export TZ=UTC + ${buildout:directory}/bin/coverage run bin/test $* + ${buildout:directory}/bin/coverage html + ${buildout:directory}/bin/coverage report -m --fail-under=90 + # Fail (exit status 1) if coverage returns exit status 2 (this happens + # when test coverage is below 100%. +output = ${buildout:directory}/bin/test-coverage +mode = 755 + +[robot] +recipe = zc.recipe.egg +eggs = + ${test:eggs} + plone.app.robotframework[debug,reload]