diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0e9306f..8ab3256 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,3 @@ # Contributors -- Lur Ibargutxi [libargutxi@codesyntax.com] +- Plone Community [collective@plone.org] diff --git a/LICENSE.md b/LICENSE.md index a3a620a..d7e00b9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -cs_dynamicpages Copyright 2025, Lur Ibargutxi +cs_dynamicpages Copyright 2025, Plone Community This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 diff --git a/Makefile b/Makefile index fef1930..72b1955 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ requirements-mxdev.txt: pyproject.toml mx.ini ## Generate constraints file $(VENV_FOLDER): requirements-mxdev.txt ## Install dependencies @echo "$(GREEN)==> Install environment$(RESET)" - @uv venv --python=3.10 $(VENV_FOLDER) + @uv venv $(VENV_FOLDER) @uv pip install -r requirements-mxdev.txt .PHONY: sync @@ -131,4 +131,10 @@ test-coverage: $(VENV_FOLDER) ## run tests with coverage ## Add bobtemplates features (check bobtemplates.plone's documentation to get the list of available features) add: $(VENV_FOLDER) - /home/lur/plonecli_azkena/bin/plonecli add $(filter-out $@,$(MAKECMDGOALS)) + @uvx plonecli add -b .mrbob.ini $(filter-out $@,$(MAKECMDGOALS)) + +.PHONY: release +release: $(VENV_FOLDER) ## Create a release + @echo "$(GREEN)==> Create a release$(RESET)" + @uv pip install -e ".[release]" + @uv run fullrelease \ No newline at end of file diff --git a/README.md b/README.md index 99e93b6..ce2ecf7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # cs_dynamicpages -An addon to create dynamic pages for Plone +A new addon for Plone ## Features @@ -22,8 +22,8 @@ make create-site ## Contribute -- [Issue tracker](https://github.com/cs/cs_dynamicpages/issues) -- [Source code](https://github.com/cs/cs_dynamicpages/) +- [Issue tracker](https://github.com/collective/cs_dynamicpages/issues) +- [Source code](https://github.com/collective/cs_dynamicpages/) ### Prerequisites ✅ @@ -38,7 +38,7 @@ make create-site 1. Clone this repository, then change your working directory. ```shell - git clone git@github.com:cs/cs_dynamicpages.git + git clone git@github.com:collective/cs_dynamicpages.git cd cs_dynamicpages ``` @@ -83,4 +83,4 @@ The project is licensed under GPLv2. ## Credits and acknowledgements 🙏 -Generated using [Cookieplone (0.9.7)](https://github.com/plone/cookieplone) and [cookieplone-templates (6782781)](https://github.com/plone/cookieplone-templates/commit/6782781dae4bafb227467828066ab16b84c23750) on 2025-07-07 09:25:15.108762. A special thanks to all contributors and supporters! +Generated using [Cookieplone (0.9.7)](https://github.com/plone/cookieplone) and [cookieplone-templates (4d55553)](https://github.com/plone/cookieplone-templates/commit/4d55553d61416df56b3360914b398d675b3f72a6) on 2025-07-17 11:59:12.982862. A special thanks to all contributors and supporters! diff --git a/pyproject.toml b/pyproject.toml index 601e8cd..811ef4c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,31 +1,30 @@ [project] name = "cs_dynamicpages" dynamic = ["version"] -description = "An addon to create dynamic pages for Plone" +description = "A new addon for Plone" readme = "README.md" license = "GPL-2.0-only" requires-python = ">=3.10" -authors = [ - { name = "Lur Ibargutxi", email = "libargutxi@codesyntax.com" }, -] -keywords = [ - "CMS", - "Plone", - "Python", -] +authors = [{ name = "Plone Community", email = "collective@plone.org" }] +keywords = ["CMS", "Plone", "Python"] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", - "Framework :: Plone","Framework :: Plone :: 6.0","Framework :: Plone :: 6.1", + "Framework :: Plone", + "Framework :: Plone :: 6.0", + "Framework :: Plone :: 6.1", "Framework :: Plone :: Addon", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: OS Independent", - "Programming Language :: Python","Programming Language :: Python :: 3.10","Programming Language :: Python :: 3.11","Programming Language :: Python :: 3.12","Programming Language :: Python :: 3.13", + "Programming Language :: Python", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "Products.CMFPlone", "plone.api", - "z3c.jbot", "collective.z3cform.datagridfield", ] @@ -33,17 +32,24 @@ dependencies = [ test = [ "horse-with-no-namespace", "plone.app.testing", - "plone.classicui","plone.restapi[test]", + "plone.app.contenttypes[test]", + "plone.classicui", + "plone.restapi[test]", "pytest", "pytest-cov", "pytest-plone>=0.5.0", ] +release = [ + "zest.releaser[recommended]", + "zestreleaser.towncrier", + "zest.pocompile", +] [project.urls] -Homepage = "https://github.com/cs/cs_dynamicpages" +Homepage = "https://github.com/collective/cs_dynamicpages" PyPI = "https://pypi.org/project/cs_dynamicpages" -Source = "https://github.com/cs/cs_dynamicpages" -Tracker = "https://github.com/cs/cs_dynamicpages/issues" +Source = "https://github.com/collective/cs_dynamicpages" +Tracker = "https://github.com/collective/cs_dynamicpages/issues" [project.entry-points."plone.autoinclude.plugin"] @@ -63,9 +69,7 @@ build-backend = "hatchling.build" strict-naming = true [tool.hatch.build.targets.sdist] -exclude = [ - "/.github", -] +exclude = ["/.github"] [tool.hatch.build.targets.wheel] packages = ["src/cs_dynamicpages"] @@ -76,7 +80,7 @@ filename = "CHANGELOG.md" start_string = "\n" title_format = "## {version} ({project_date})" template = "news/.changelog_template.jinja" -issue_format = "[#{issue}](https://github.com/cs/cs_dynamicpages/issues/{issue})" +issue_format = "[#{issue}](https://github.com/collective/cs_dynamicpages/issues/{issue})" underlines = ["", "", ""] [[tool.towncrier.type]] @@ -131,7 +135,8 @@ lint.select = [ # mccabe "C90", # pycodestyle - "E", "W", + "E", + "W", # pyflakes "F", # pygrep-hooks @@ -168,6 +173,8 @@ testpaths = ["tests"] source_pkgs = ["cs_dynamicpages", "tests"] branch = true parallel = true -omit = [ - "src/cs_dynamicpages/locales/*.py", -] \ No newline at end of file +omit = ["src/cs_dynamicpages/locales/*.py"] + + +[tool.zest-releaser] +python-file-with-version = "src/cs_dynamicpages/__init__.py" diff --git a/src/cs_dynamicpages/behaviors/configure.zcml b/src/cs_dynamicpages/behaviors/configure.zcml index f1d4aeb..ea2852a 100644 --- a/src/cs_dynamicpages/behaviors/configure.zcml +++ b/src/cs_dynamicpages/behaviors/configure.zcml @@ -13,14 +13,14 @@ - + - - - - + - + diff --git a/src/cs_dynamicpages/content/dynamic_page_row.py b/src/cs_dynamicpages/content/dynamic_page_row.py index aed9969..e7f71da 100644 --- a/src/cs_dynamicpages/content/dynamic_page_row.py +++ b/src/cs_dynamicpages/content/dynamic_page_row.py @@ -11,7 +11,7 @@ # from z3c.form.browser.radio import RadioFieldWidget from zope import schema from zope.interface import implementer -from plone import api + log = getLogger(__name__) @@ -52,10 +52,12 @@ def featured_list(self): def show_featured_add_button(self): row_type = self.row_type - row_type_fields = api.portal.get_registry_record('cs_dynamicpages.dynamica_pages_control_panel.row_type_fields') + row_type_fields = api.portal.get_registry_record( + "cs_dynamicpages.dynamica_pages_control_panel.row_type_fields" + ) for row_type_field in row_type_fields: - if row_type_field['row_type'] == row_type: - return row_type_field['row_type_has_featured_add_button'] + if row_type_field["row_type"] == row_type: + return row_type_field["row_type_has_featured_add_button"] return False def render(self, request): diff --git a/src/cs_dynamicpages/content/dynamic_page_row_featured.py b/src/cs_dynamicpages/content/dynamic_page_row_featured.py index 1a20140..27ad5f5 100644 --- a/src/cs_dynamicpages/content/dynamic_page_row_featured.py +++ b/src/cs_dynamicpages/content/dynamic_page_row_featured.py @@ -1,5 +1,6 @@ # from plone.app.textfield import RichText # from plone.autoform import directives +from plone import api from plone.dexterity.content import Item # from plone.namedfile import field as namedfile @@ -9,7 +10,7 @@ # from z3c.form.browser.radio import RadioFieldWidget # from zope import schema from zope.interface import implementer -from plone import api + # from cs_dynamicpages import _ diff --git a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py b/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py index 49009ca..3769ed6 100644 --- a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py +++ b/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py @@ -1,15 +1,16 @@ +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from collective.z3cform.datagridfield.registry import DictRow from cs_dynamicpages import _ from cs_dynamicpages.interfaces import IBrowserLayer from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper from plone.app.registry.browser.controlpanel import RegistryEditForm +from plone.autoform.directives import widget from plone.restapi.controlpanels import RegistryConfigletPanel from plone.z3cform import layout from zope import schema from zope.component import adapter from zope.interface import Interface -from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory -from collective.z3cform.datagridfield.registry import DictRow -from plone.autoform.directives import widget + class IRowTypeFieldsSchema(Interface): row_type = schema.Choice( @@ -35,18 +36,31 @@ class IRowTypeFieldsSchema(Interface): class IDynamicaPagesControlPanel(Interface): widget(row_type_fields=DataGridFieldFactory) row_type_fields = schema.List( - title=u"Row Type Fields", + title="Row Type Fields", required=True, - value_type=DictRow(title=u"Row Type Fields", schema=IRowTypeFieldsSchema), + value_type=DictRow(title="Row Type Fields", schema=IRowTypeFieldsSchema), default=[ { "row_type": "cs_dynamicpages-featured-view", - "each_row_type_fields": ["IBasic.title", "IBasic.description", "IRelatedImage.related_image", "IRelatedImage.image_position", "ILinkInfo.link_text", "ILinkInfo.link_url"], + "each_row_type_fields": [ + "IBasic.title", + "IBasic.description", + "IRelatedImage.related_image", + "IRelatedImage.image_position", + "ILinkInfo.link_text", + "ILinkInfo.link_url", + ], "row_type_has_featured_add_button": False, }, { "row_type": "cs_dynamicpages-featured-overlay-view", - "each_row_type_fields": ["IBasic.title", "IBasic.description", "IRelatedImage.related_image", "ILinkInfo.link_text", "ILinkInfo.link_url"], + "each_row_type_fields": [ + "IBasic.title", + "IBasic.description", + "IRelatedImage.related_image", + "ILinkInfo.link_text", + "ILinkInfo.link_url", + ], "row_type_has_featured_add_button": False, }, { @@ -76,7 +90,15 @@ class IDynamicaPagesControlPanel(Interface): }, { "row_type": "cs_dynamicpages-query-columns-view", - "each_row_type_fields": ["IBasic.title", "ICollection.query", "ICollection.sort_on", "ICollection.sort_order", "ICollection.betweeen", "ICollection.limit", "IRowColumns.columns"], + "each_row_type_fields": [ + "IBasic.title", + "ICollection.query", + "ICollection.sort_on", + "ICollection.sort_order", + "ICollection.betweeen", + "ICollection.limit", + "IRowColumns.columns", + ], "row_type_has_featured_add_button": False, }, { diff --git a/src/cs_dynamicpages/dependencies.zcml b/src/cs_dynamicpages/dependencies.zcml index 75ca76a..3a4d184 100644 --- a/src/cs_dynamicpages/dependencies.zcml +++ b/src/cs_dynamicpages/dependencies.zcml @@ -1,5 +1,5 @@ - + diff --git a/src/cs_dynamicpages/locales/__main__.py b/src/cs_dynamicpages/locales/__main__.py index a5677b6..cea189c 100644 --- a/src/cs_dynamicpages/locales/__main__.py +++ b/src/cs_dynamicpages/locales/__main__.py @@ -37,7 +37,7 @@ def locale_folder_setup(domain: str): f"--input={locale_path}/{domain}.pot " f"--output={locale_path}/{lang}/LC_MESSAGES/{domain}.po" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def _rebuild(domain: str): @@ -46,7 +46,7 @@ def _rebuild(domain: str): f"--exclude {excludes} " f"--create {domain} {target_path}" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def _sync(domain: str): @@ -54,7 +54,7 @@ def _sync(domain: str): f"{i18ndude} sync --pot {locale_path}/{domain}.pot " f"{locale_path}/*/LC_MESSAGES/{domain}.po" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def main(): diff --git a/src/cs_dynamicpages/locales/cs_dynamicpages.pot b/src/cs_dynamicpages/locales/cs_dynamicpages.pot new file mode 100644 index 0000000..ca28bf5 --- /dev/null +++ b/src/cs_dynamicpages/locales/cs_dynamicpages.pot @@ -0,0 +1,18 @@ +#--- PLEASE EDIT THE LINES BELOW CORRECTLY --- +#SOME DESCRIPTIVE TITLE. +#FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2022-05-25 17:12+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: cs_dynamicpages\n" diff --git a/src/cs_dynamicpages/permissions.zcml b/src/cs_dynamicpages/permissions.zcml index 6773a76..cf82d48 100644 --- a/src/cs_dynamicpages/permissions.zcml +++ b/src/cs_dynamicpages/permissions.zcml @@ -17,7 +17,7 @@ title="cs_dynamicpages: Add DynamicPageRow" /> - diff --git a/src/cs_dynamicpages/profiles/default/metadata.xml b/src/cs_dynamicpages/profiles/default/metadata.xml index ec58cba..999094f 100644 --- a/src/cs_dynamicpages/profiles/default/metadata.xml +++ b/src/cs_dynamicpages/profiles/default/metadata.xml @@ -2,5 +2,8 @@ 1000 - profile-plone.app.dexterity:default + profile-plone.app.dexterity:default + profile-collective.z3cform.datagridfield:default + + diff --git a/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml b/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml index 2419b1c..908eb65 100644 --- a/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml +++ b/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml @@ -1,50 +1,48 @@ - + - - - - True - ++plone++cs_dynamicpages.edit/edit_dynamicpagerow.js - ++plone++cs_dynamicpages.edit/dynamicpageview.css - plone - True - False - + True + ++plone++cs_dynamicpages.edit/edit_dynamicpagerow.js + ++plone++cs_dynamicpages.edit/dynamicpageview.css + plone + True + False + - True - ++plone++cs_dynamicpages.edit/delete-row.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/delete-row.js + plone + True + False + - True - ++plone++cs_dynamicpages.edit/reorder-rows.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/reorder-rows.js + plone + True + False + - True - ++plone++cs_dynamicpages.edit/editmode-toggle.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/editmode-toggle.js + plone + True + False + diff --git a/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml b/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml index 787b2bd..cc8b6d4 100644 --- a/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +++ b/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml @@ -54,7 +54,7 @@ - + diff --git a/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml b/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml index 06e8789..e8d85e9 100644 --- a/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +++ b/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml @@ -47,7 +47,7 @@ - + diff --git a/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml b/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml new file mode 100644 index 0000000..cafe9d2 --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml @@ -0,0 +1,22 @@ + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml b/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml new file mode 100644 index 0000000..dc49d67 --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml b/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml new file mode 100644 index 0000000..24b3120 --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/types.xml b/src/cs_dynamicpages/profiles/uninstall/types.xml new file mode 100644 index 0000000..a325b1b --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/types.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/src/cs_dynamicpages/tests/test_behavior_row_columns.py b/src/cs_dynamicpages/tests/test_behavior_row_columns.py index cfc4c29..4e56339 100644 --- a/src/cs_dynamicpages/tests/test_behavior_row_columns.py +++ b/src/cs_dynamicpages/tests/test_behavior_row_columns.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.behaviors.row_columns import IRowColumnsMarker -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.behavior.interfaces import IBehavior @@ -10,16 +9,15 @@ class RowColumnsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_behavior_row_columns(self): - behavior = getUtility(IBehavior, 'cs_dynamicpages.row_columns') + behavior = getUtility(IBehavior, "cs_dynamicpages.row_columns") self.assertEqual( behavior.marker, IRowColumnsMarker, diff --git a/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py b/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py index c00c836..caf7d16 100644 --- a/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py +++ b/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from cs_dynamicpages.views.dynamic_page_folder_view import IDynamicPageFolderView @@ -12,19 +11,18 @@ class ViewsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) - api.content.create(self.portal, 'Folder', 'other-folder') - api.content.create(self.portal, 'Document', 'front-page') + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + api.content.create(self.portal, "Folder", "other-folder") + api.content.create(self.portal, "Document", "front-page") def test_dynamic_page_folder_view_is_registered(self): view = getMultiAdapter( - (self.portal['other-folder'], self.portal.REQUEST), - name='dynamic-page-folder-view' + (self.portal["other-folder"], self.portal.REQUEST), + name="dynamic-page-folder-view", ) self.assertTrue(IDynamicPageFolderView.providedBy(view)) @@ -32,8 +30,8 @@ def test_dynamic_page_folder_view_not_matching_interface(self): view_found = True try: view = getMultiAdapter( - (self.portal['front-page'], self.portal.REQUEST), - name='dynamic-page-folder-view' + (self.portal["front-page"], self.portal.REQUEST), + name="dynamic-page-folder-view", ) except ComponentLookupError: view_found = False @@ -43,9 +41,8 @@ def test_dynamic_page_folder_view_not_matching_interface(self): class ViewsFunctionalTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) diff --git a/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py b/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py index 29e6a8f..e8d71fa 100644 --- a/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py +++ b/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING -from cs_dynamicpages.views.dynamic_page_row_featured_view import IDynamicPageRowFeaturedView +from cs_dynamicpages.views.dynamic_page_row_featured_view import ( + IDynamicPageRowFeaturedView, +) from plone import api from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID @@ -12,19 +13,18 @@ class ViewsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) - api.content.create(self.portal, 'Folder', 'other-folder') - api.content.create(self.portal, 'Document', 'front-page') + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + api.content.create(self.portal, "Folder", "other-folder") + api.content.create(self.portal, "Document", "front-page") def test_dynamic_page_row_featured_view_is_registered(self): view = getMultiAdapter( - (self.portal['other-folder'], self.portal.REQUEST), - name='dynamic-page-row-featured-view' + (self.portal["other-folder"], self.portal.REQUEST), + name="dynamic-page-row-featured-view", ) self.assertTrue(IDynamicPageRowFeaturedView.providedBy(view)) @@ -32,8 +32,8 @@ def test_dynamic_page_row_featured_view_not_matching_interface(self): view_found = True try: view = getMultiAdapter( - (self.portal['front-page'], self.portal.REQUEST), - name='dynamic-page-row-featured-view' + (self.portal["front-page"], self.portal.REQUEST), + name="dynamic-page-row-featured-view", ) except ComponentLookupError: view_found = False @@ -43,9 +43,8 @@ def test_dynamic_page_row_featured_view_not_matching_interface(self): class ViewsFunctionalTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) diff --git a/src/cs_dynamicpages/tests/test_vocab_image_position.py b/src/cs_dynamicpages/tests/test_vocab_image_position.py index b5ce923..ad21df9 100644 --- a/src/cs_dynamicpages/tests/test_vocab_image_position.py +++ b/src/cs_dynamicpages/tests/test_vocab_image_position.py @@ -1,5 +1,5 @@ from cs_dynamicpages import _ -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from zope.component import getUtility @@ -10,22 +10,21 @@ class ImagePositionIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_vocab_image_position(self): - vocab_name = 'cs_dynamicpages.ImagePosition' + vocab_name = "cs_dynamicpages.ImagePosition" factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( - vocabulary.getTerm('sony-a7r-iii').title, - _(u'Sony Aplha 7R III'), + vocabulary.getTerm("sony-a7r-iii").title, + _("Sony Aplha 7R III"), ) diff --git a/src/cs_dynamicpages/tests/test_vocab_row_columns.py b/src/cs_dynamicpages/tests/test_vocab_row_columns.py index afe4d49..4bc54cd 100644 --- a/src/cs_dynamicpages/tests/test_vocab_row_columns.py +++ b/src/cs_dynamicpages/tests/test_vocab_row_columns.py @@ -1,5 +1,5 @@ from cs_dynamicpages import _ -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from zope.component import getUtility @@ -10,22 +10,21 @@ class RowColumnsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_vocab_row_columns(self): - vocab_name = 'cs_dynamicpages.RowColumns' + vocab_name = "cs_dynamicpages.RowColumns" factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( - vocabulary.getTerm('sony-a7r-iii').title, - _(u'Sony Aplha 7R III'), + vocabulary.getTerm("sony-a7r-iii").title, + _("Sony Aplha 7R III"), ) diff --git a/src/cs_dynamicpages/browser/overrides/.gitkeep b/src/cs_dynamicpages/upgrades/__init__.py similarity index 100% rename from src/cs_dynamicpages/browser/overrides/.gitkeep rename to src/cs_dynamicpages/upgrades/__init__.py diff --git a/src/cs_dynamicpages/upgrades/configure.zcml b/src/cs_dynamicpages/upgrades/configure.zcml new file mode 100644 index 0000000..7a0a5a3 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/configure.zcml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/src/cs_dynamicpages/views/accordion_view.pt b/src/cs_dynamicpages/views/accordion_view.pt index 491f6e8..196e04b 100644 --- a/src/cs_dynamicpages/views/accordion_view.pt +++ b/src/cs_dynamicpages/views/accordion_view.pt @@ -1,22 +1,42 @@ -
-
+ " + tal:condition="elements" +> +
-
-
-
+
- + " + > +
-
\ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/configure.zcml b/src/cs_dynamicpages/views/configure.zcml index 15a3539..931c9f1 100644 --- a/src/cs_dynamicpages/views/configure.zcml +++ b/src/cs_dynamicpages/views/configure.zcml @@ -2,28 +2,29 @@ xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:plone="http://namespaces.plone.org/plone" + xmlns:zcml="http://namespaces.zope.org/zcml" i18n_domain="cs_dynamicpages" > + name="view" + for="cs_dynamicpages.content.dynamic_page_row_featured.IDynamicPageRowFeatured" + class=".dynamic_page_row_featured_view.DynamicPageRowFeaturedView" + template="dynamic_page_row_featured_view.pt" + permission="zope2.View" + layer="cs_dynamicpages.interfaces.IBrowserLayer" + /> + name="view" + for="cs_dynamicpages.content.dynamic_page_folder.IDynamicPageFolder" + class=".dynamic_page_folder_view.DynamicPageFolderView" + template="dynamic_page_folder_view.pt" + permission="zope2.View" + layer="cs_dynamicpages.interfaces.IBrowserLayer" + /> @@ -98,6 +102,7 @@ diff --git a/src/cs_dynamicpages/views/dynamic_page_folder_view.pt b/src/cs_dynamicpages/views/dynamic_page_folder_view.pt index 5a0d62b..ea6bf9d 100644 --- a/src/cs_dynamicpages/views/dynamic_page_folder_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_folder_view.pt @@ -1,34 +1,40 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - - - - - - View dynamic page - - + + + + + + + View dynamic page + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_folder_view.py b/src/cs_dynamicpages/views/dynamic_page_folder_view.py index f8596ad..d58cd86 100644 --- a/src/cs_dynamicpages/views/dynamic_page_folder_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_folder_view.py @@ -1,14 +1,14 @@ -# -*- coding: utf-8 -*- - # from cs_dynamicpages import _ from Products.Five.browser import BrowserView from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile + class IDynamicPageFolderView(Interface): - """ Marker Interface for IDynamicPageFolderView""" + """Marker Interface for IDynamicPageFolderView""" @implementer(IDynamicPageFolderView) diff --git a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt index 980e00f..78af5c0 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt @@ -1,25 +1,29 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py index 0dd9585..84422a9 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py @@ -1,14 +1,14 @@ -# -*- coding: utf-8 -*- - # from cs_dynamicpages import _ from Products.Five.browser import BrowserView from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile + class IDynamicPageRowFeaturedView(Interface): - """ Marker Interface for IDynamicPageRowFeaturedView""" + """Marker Interface for IDynamicPageRowFeaturedView""" @implementer(IDynamicPageRowFeaturedView) diff --git a/src/cs_dynamicpages/views/dynamic_page_row_view.pt b/src/cs_dynamicpages/views/dynamic_page_row_view.pt index 7eb711f..38f6aae 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_row_view.pt @@ -1,26 +1,29 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_row_view.py b/src/cs_dynamicpages/views/dynamic_page_row_view.py index df39bd6..a15d1ea 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_row_view.py @@ -3,6 +3,7 @@ from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile diff --git a/src/cs_dynamicpages/views/dynamic_view.pt b/src/cs_dynamicpages/views/dynamic_view.pt index 983a03e..2c78757 100644 --- a/src/cs_dynamicpages/views/dynamic_view.pt +++ b/src/cs_dynamicpages/views/dynamic_view.pt @@ -1,158 +1,248 @@ - + - - -
-
-
-
- - + + +
+
+
+
+ + +
-
-
- - -
-
- + + +
+
+ Template: ${row/row_template} - - - Edit - Delete row + + + Edit + Delete row - -
- -
- - -
-
-
-
-
- - +
  • + +
  • + + +
  • ${featured_transition/name} +
  • +
    +
    +
  • + +
  • +
  • Move up
  • +
  • Move down
  • +
  • + +
  • Delete
  • + + +
    +
    +
    - - Add new featured - + + Add new featured + +
    +
    +
    + +
    +
    +
    + + + -
    - -
    -
    -
    -
    - - - - -
    -
    - + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_view.py b/src/cs_dynamicpages/views/dynamic_view.py index ed03e33..fb20f67 100644 --- a/src/cs_dynamicpages/views/dynamic_view.py +++ b/src/cs_dynamicpages/views/dynamic_view.py @@ -26,7 +26,10 @@ def rows(self): def dynamic_page_folder_element(self): return api.content.find( - portal_type="DynamicPageFolder", context=self.context, depth=1, sort_on="getObjPositionInParent" + portal_type="DynamicPageFolder", + context=self.context, + depth=1, + sort_on="getObjPositionInParent", ) def dynamic_page_folder_element_url(self): @@ -36,4 +39,4 @@ def dynamic_page_folder_element_url(self): return "" def can_edit(self): - return api.user.has_permission("Modify portal content", obj=self.context) \ No newline at end of file + return api.user.has_permission("Modify portal content", obj=self.context) diff --git a/src/cs_dynamicpages/views/featured_overlay_view.pt b/src/cs_dynamicpages/views/featured_overlay_view.pt index 34fc3da..07742fc 100644 --- a/src/cs_dynamicpages/views/featured_overlay_view.pt +++ b/src/cs_dynamicpages/views/featured_overlay_view.pt @@ -2,18 +2,26 @@ + " + tal:condition="image" + > + title=image.Title())" + />
    ${context/Title}
    -

    ${context/Description}

    - ${context/link_text} +

    ${context/Description}

    + ${context/link_text}
    -

    \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/featured_view.pt b/src/cs_dynamicpages/views/featured_view.pt index 915d80b..839626b 100644 --- a/src/cs_dynamicpages/views/featured_view.pt +++ b/src/cs_dynamicpages/views/featured_view.pt @@ -1,23 +1,35 @@
    + image view/related_image; + " + tal:condition="image" + > + title=image.Title())" + />
    + tal:attributes=" + class python:context.image_position=='right' and 'col-md-6 order-first' or 'col-md-6'; + " + >

    ${context/Title}

    ${context/Description}

    - + - ${context/link_text} + ${context/link_text}
    -
    \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/featured_view.py b/src/cs_dynamicpages/views/featured_view.py index 0f6e7c5..ae977c9 100644 --- a/src/cs_dynamicpages/views/featured_view.py +++ b/src/cs_dynamicpages/views/featured_view.py @@ -1,7 +1,7 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView class IFeaturedView(Interface): diff --git a/src/cs_dynamicpages/views/features_view.pt b/src/cs_dynamicpages/views/features_view.pt index c85ec5d..664903b 100644 --- a/src/cs_dynamicpages/views/features_view.pt +++ b/src/cs_dynamicpages/views/features_view.pt @@ -1,32 +1,50 @@ -
    -
    + " + tal:condition="elements" +> +
    + element brain/getObject; + ">
    + image element/related_image_object; + " + tal:condition="image" + tal:on-error="nothing" + > + title=element.Title())" + />
    - ${element/Title} -

    ${element/Title}

    -

    ${element/Description}

    - + ${element/Title} +

    ${element/Title}

    +

    ${element/Description}

    +
    -
    \ No newline at end of file +
    diff --git a/src/cs_dynamicpages/views/horizontal_rule_view.pt b/src/cs_dynamicpages/views/horizontal_rule_view.pt index 84af8ad..af383ee 100644 --- a/src/cs_dynamicpages/views/horizontal_rule_view.pt +++ b/src/cs_dynamicpages/views/horizontal_rule_view.pt @@ -1 +1 @@ -
    \ No newline at end of file +
    diff --git a/src/cs_dynamicpages/views/query_columns_view.pt b/src/cs_dynamicpages/views/query_columns_view.pt index 5b11405..5c23d4e 100644 --- a/src/cs_dynamicpages/views/query_columns_view.pt +++ b/src/cs_dynamicpages/views/query_columns_view.pt @@ -1,6 +1,8 @@ -
    +

    ${context/Title}

    @@ -11,21 +13,32 @@
    + " + tal:condition="image" + tal:on-error="nothing" + > + title=element.Title())" + />
    - ${element/Title} -

    -

    + ${element/Title} +

    +

    ${element/Description}

    @@ -36,7 +49,9 @@
    -
    \ No newline at end of file +
    diff --git a/src/cs_dynamicpages/views/query_columns_view.py b/src/cs_dynamicpages/views/query_columns_view.py index 5ae8b6d..29a923a 100644 --- a/src/cs_dynamicpages/views/query_columns_view.py +++ b/src/cs_dynamicpages/views/query_columns_view.py @@ -1,8 +1,9 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from plone.app.contenttypes.browser.collection import CollectionView from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile diff --git a/src/cs_dynamicpages/views/slider_view.pt b/src/cs_dynamicpages/views/slider_view.pt index bad68cb..7892d95 100644 --- a/src/cs_dynamicpages/views/slider_view.pt +++ b/src/cs_dynamicpages/views/slider_view.pt @@ -1,44 +1,74 @@ - \ No newline at end of file +
    diff --git a/src/cs_dynamicpages/views/slider_view.py b/src/cs_dynamicpages/views/slider_view.py index ca22b3e..1ce0fd2 100644 --- a/src/cs_dynamicpages/views/slider_view.py +++ b/src/cs_dynamicpages/views/slider_view.py @@ -1,8 +1,8 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from plone import api from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView class ISliderView(Interface): diff --git a/src/cs_dynamicpages/views/spacer_view.pt b/src/cs_dynamicpages/views/spacer_view.pt index ae4bf27..903b036 100644 --- a/src/cs_dynamicpages/views/spacer_view.pt +++ b/src/cs_dynamicpages/views/spacer_view.pt @@ -1,2 +1,2 @@
    -
    \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/text_view.pt b/src/cs_dynamicpages/views/text_view.pt index c739948..fd65f8d 100644 --- a/src/cs_dynamicpages/views/text_view.pt +++ b/src/cs_dynamicpages/views/text_view.pt @@ -1,4 +1,6 @@
    - - -
    \ No newline at end of file + + + diff --git a/src/cs_dynamicpages/vocabularies/configure.zcml b/src/cs_dynamicpages/vocabularies/configure.zcml index 4db2909..74e9b6b 100644 --- a/src/cs_dynamicpages/vocabularies/configure.zcml +++ b/src/cs_dynamicpages/vocabularies/configure.zcml @@ -2,16 +2,16 @@ - + - + list: + """Content to be created.""" + return [ + # EU CONTENT + { + "_container": "", + "_language": "eu", + "_transitions": ["publish"], + "type": "Folder", + "id": "folder", + "title": "Folder", + }, + { + "_container": "folder", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageFolder", + "id": "dpf", + "title": "DPF", + }, + { + "_container": "folder/dpf", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageRow", + "id": "row-1", + "title": "Row 1", + }, + { + "_container": "folder/dpf", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageRow", + "id": "row-2", + "title": "Row 2", + }, + ] + + +@pytest.fixture() +def portal(functional): + return functional["portal"] + + +@pytest.fixture() +def browser(functional): + browser = Browser(functional["app"]) + browser.handleErrors = False + browser.addHeader("Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}") + return browser + + +@pytest.fixture() +def my_request(functional): + req = functional["request"] + alsoProvides(req, IBrowserLayer) + return req + + +@pytest.fixture +def create_contents(contents): + """Helper fixture to create initial content.""" + + def func(portal) -> dict: + ids = defaultdict(list) + for item in contents: + container_path = item["_container"] + container = portal.unrestrictedTraverse(container_path) + payload = {"container": container, "language": item["_language"]} + if "_image" in item: + payload["image"] = NamedBlobImage(b64decode(item["_image"])) + for key, value in item.items(): + if key.startswith("_"): + continue + payload[key] = value + + content = api.content.create(**payload) + content.language = payload["language"] + if "_view" in item: + content.setLayout(item["_view"]) + # Set translation + if "_translation_of" in item: + source = portal.unrestrictedTraverse(item["_translation_of"]) + ITranslationManager(source).register_translation( + content.language, content + ) + # Transition items + if "_transitions" in item: + transitions = item["_transitions"] + for transition in transitions: + api.content.transition(content, transition=transition) + ids[container_path].append(content.getId()) + return ids + + return func + + +@pytest.fixture() +def portal_with_content(app, portal, create_contents): + """Plone portal with initial content.""" + with api.env.adopt_roles(["Manager"]): + create_contents(portal) + # transaction.commit() + yield portal + # with api.env.adopt_roles(["Manager"]): + # containers = sorted(content_ids.keys(), reverse=True) + # for container_path in containers: + # container = portal.unrestrictedTraverse(container_path) + # container.manage_delObjects(content_ids[container_path]) + # transaction.commit() diff --git a/tests/content/test_content_operations.py b/tests/content/test_content_operations.py new file mode 100644 index 0000000..9ed19fb --- /dev/null +++ b/tests/content/test_content_operations.py @@ -0,0 +1,72 @@ +from ..base import TestBase +from plone import api + +import pytest +import transaction + + +class TestContent(TestBase): + @pytest.fixture(autouse=True) + def create_content(self, portal): + with api.env.adopt_roles(["Manager"]): + self.folder = api.content.create( + container=portal, + type="Folder", + id="folder", + ) + + assert self.folder is not None + assert self.folder.id == "folder" + + self.folder.setLayout("dynamic-view") + + self.dpf = api.content.create( + container=self.folder, type="DynamicPageFolder", id="dpf", title="DPF" + ) + + assert self.dpf is not None + assert self.dpf.id == "dpf" + + self.row1 = api.content.create( + container=self.dpf, type="DynamicPageRow", id="row-1", title="Row 1" + ) + assert self.row1 is not None + assert self.row1.id == "row-1" + + self.row2 = api.content.create( + container=self.dpf, type="DynamicPageRow", id="row-2", title="Row 2" + ) + assert self.row2 is not None + assert self.row2.id == "row-2" + + transaction.commit() + + def test_view(self, browser): + """check that the folder is rendered correctly with the basic instructions""" + + browser.open(self.folder.absolute_url()) + # We have 2 rows, so there must be an option to delete a row + assert "Delete row" in browser.contents + + # assert "Row 1" in browser.contents + # assert "Row 2" in browser.contents + + # There must be an option to add a new row + assert "Add new row" in browser.contents + + def test_add_row(self, browser): + """click add row""" + browser.open(self.folder.absolute_url()) + link = browser.getLink("Add new row") + link.click() + assert "++add++DynamicPageRow" in browser.url + + control = browser.getControl(name="form.widgets.IBasic.title") + control.value = "Row 3" + + save = browser.getControl(name="form.buttons.save") + save.click() + + browser.open(self.folder.absolute_url()) + + assert len(self.folder.dpf.keys()) == 3 diff --git a/tests/setup/__init__.py b/tests/setup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/setup/test_setup_install.py b/tests/setup/test_setup_install.py index e2efb57..77abfa1 100644 --- a/tests/setup/test_setup_install.py +++ b/tests/setup/test_setup_install.py @@ -1,7 +1,8 @@ +from ..base import TestBase from cs_dynamicpages import PACKAGE_NAME -class TestSetupInstall: +class TestSetupInstall(TestBase): def test_addon_installed(self, installer): """Test if cs_dynamicpages is installed.""" assert installer.is_product_installed(PACKAGE_NAME) is True