Skip to content

Commit c98cf55

Browse files
committed
Add versioning tests for Workspace and Wiki Page content types
Move the Workspace and WikiPage FTI assertions out of the central test_fti.py table into dedicated per-type test modules, following the test_subsite.py pattern, and cover the new edit-time versioning: - tests/content_types/test_workspace.py: new module with FTI, behavior, creation and versioning tests. - tests/content_types/test_wiki_page.py: reuse the shared portal_type / container / payload / content_factory fixtures and add versioning tests. - tests/content_types/test_fti.py: drop the entries now covered by the per-type modules. Refs https://gitlab.kitconcept.io/kitconcept/distribution-kitconcept-intranet/-/issues/550
1 parent 129b9cc commit c98cf55

3 files changed

Lines changed: 167 additions & 88 deletions

File tree

backend/tests/content_types/test_fti.py

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -256,68 +256,6 @@ def _setup(self, portal, get_fti):
256256
"kitconcept.intranet.content_review",
257257
),
258258
),
259-
("Workspace", "title", "Workspace"),
260-
("Workspace", "description", "A folderish workspace container."),
261-
("Workspace", "allow_discussion", False),
262-
("Workspace", "global_allow", True),
263-
("Workspace", "filter_content_types", True),
264-
(
265-
"Workspace",
266-
"allowed_content_types",
267-
(
268-
"WikiPage",
269-
"File",
270-
"Image",
271-
),
272-
),
273-
(
274-
"Workspace",
275-
"behaviors",
276-
(
277-
"plone.basic",
278-
"volto.preview_image_link",
279-
"plone.categorization",
280-
"plone.publication",
281-
"plone.ownership",
282-
"plone.relateditems",
283-
"plone.shortname",
284-
"volto.navtitle",
285-
"plone.excludefromnavigation",
286-
"plone.allowdiscussion",
287-
"volto.blocks",
288-
"plone.constraintypes",
289-
"plone.namefromtitle",
290-
"plone.versioning",
291-
"plone.locking",
292-
"plone.translatable",
293-
"kitconcept.plate.workspace",
294-
"kitconcept.intranet.clm",
295-
),
296-
),
297-
("WikiPage", "title", "Wiki Page"),
298-
(
299-
"WikiPage",
300-
"behaviors",
301-
(
302-
"plone.basic",
303-
"volto.preview_image_link",
304-
"plone.categorization",
305-
"plone.publication",
306-
"plone.ownership",
307-
"plone.relateditems",
308-
"plone.shortname",
309-
"volto.navtitle",
310-
"plone.excludefromnavigation",
311-
"plone.allowdiscussion",
312-
"volto.blocks",
313-
"plone.constraintypes",
314-
"plone.namefromtitle",
315-
"plone.versioning",
316-
"plone.locking",
317-
"plone.translatable",
318-
"kitconcept.intranet.clm",
319-
),
320-
),
321259
("Plone Site", "title", "Plone Site"),
322260
("Plone Site", "klass", "Products.CMFPlone.Portal.PloneSite"),
323261
("Plone Site", "global_allow", False),

backend/tests/content_types/test_wiki_page.py

Lines changed: 65 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from collections.abc import Generator
22
from plone import api
33
from plone.api.exc import InvalidParameterError
4-
from plone.app.testing.interfaces import SITE_OWNER_NAME
54
from plone.dexterity.fti import DexterityFTI
65
from Products.CMFPlone.Portal import PloneSite
76

@@ -14,13 +13,36 @@ def portal(app_class, create_site, answers) -> Generator[PloneSite]:
1413
yield site
1514

1615

17-
class TestWikiPage:
18-
portal_type: str = "WikiPage"
16+
@pytest.fixture(scope="class")
17+
def portal_type() -> str:
18+
return "WikiPage"
19+
20+
21+
@pytest.fixture(scope="class")
22+
def container(portal, content_factory):
23+
"""Return the container used to create the content instance under test."""
24+
payload = {
25+
"type": "Workspace",
26+
"id": "my-workspace",
27+
}
28+
return content_factory(portal, payload)
29+
30+
31+
@pytest.fixture(scope="class")
32+
def payload(portal_type) -> dict:
33+
return {
34+
"type": portal_type,
35+
"id": "my-other-wiki-page",
36+
"title": "My other wiki page",
37+
"description": "Description of my other wiki page",
38+
}
39+
1940

41+
class TestWikiPage:
2042
@pytest.fixture(autouse=True)
21-
def _setup(self, portal, get_fti) -> None:
43+
def _setup(self, portal, get_fti, portal_type) -> None:
2244
self.portal = portal
23-
self.fti: DexterityFTI = get_fti(self.portal_type)
45+
self.fti: DexterityFTI = get_fti(portal_type)
2446

2547
@pytest.mark.parametrize(
2648
"attr,expected",
@@ -44,8 +66,9 @@ def test_fti(self, attr: str, expected):
4466
assert isinstance(self.fti, DexterityFTI)
4567
assert getattr(self.fti, attr) == expected
4668

47-
def test_behaviors(self):
48-
assert self.fti.behaviors == (
69+
@pytest.mark.parametrize(
70+
"idx,behavior",
71+
enumerate((
4972
"plone.basic",
5073
"volto.preview_image_link",
5174
"plone.categorization",
@@ -63,27 +86,43 @@ def test_behaviors(self):
6386
"plone.locking",
6487
"plone.translatable",
6588
"kitconcept.intranet.clm",
66-
)
89+
)),
90+
)
91+
def test_behaviors(self, idx, behavior):
92+
assert self.fti.behaviors[idx] == behavior
6793

68-
def test_wikipage_requires_workspace_container(self):
69-
with api.env.adopt_user(SITE_OWNER_NAME):
94+
def test_wikipage_requires_workspace_container(
95+
self, site_owner_name, content_factory, portal_type, payload
96+
):
97+
with api.env.adopt_user(site_owner_name):
7098
with pytest.raises(InvalidParameterError):
71-
api.content.create(
72-
container=self.portal,
73-
type=self.portal_type,
74-
title="Root Wiki Page",
75-
)
76-
77-
workspace = api.content.create(
78-
container=self.portal,
79-
type="Workspace",
80-
title="Team Workspace",
81-
)
82-
page = api.content.create(
83-
container=workspace,
84-
type=self.portal_type,
85-
title="Workspace Wiki Page",
99+
content_factory(self.portal, payload)
100+
101+
workspace = content_factory(
102+
self.portal,
103+
{"type": "Workspace", "title": "Team Workspace"},
86104
)
105+
page = content_factory(workspace, payload)
87106

88-
assert page.portal_type == self.portal_type
107+
assert page.portal_type == portal_type
89108
assert page.aq_parent == workspace
109+
110+
def test_versionable(self, portal_type, versionable_content_types):
111+
assert portal_type in versionable_content_types
112+
113+
def test_create_initial_version_after_adding(self, last_version, content_instance):
114+
version = last_version(content_instance)
115+
assert version.comment.default == "Initial version"
116+
assert version.version_id == 0
117+
118+
def test_create_version_on_save(
119+
self, notify_modified, history, last_version, content_instance
120+
):
121+
with api.env.adopt_roles(["Manager"]):
122+
content_instance.title = "Wiki Redux"
123+
notify_modified(content_instance)
124+
history_data = history(content_instance)
125+
assert len(history_data) == 2 # Initial + modified version
126+
version = last_version(content_instance)
127+
assert version.comment is None
128+
assert version.version_id == 1
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from collections.abc import Generator
2+
from plone import api
3+
from plone.dexterity.fti import DexterityFTI
4+
from Products.CMFPlone.Portal import PloneSite
5+
6+
import pytest
7+
8+
9+
@pytest.fixture(scope="class")
10+
def portal(app_class, create_site, answers) -> Generator[PloneSite]:
11+
site = create_site(app=app_class, answers=answers)
12+
yield site
13+
14+
15+
@pytest.fixture(scope="class")
16+
def portal_type() -> str:
17+
return "Workspace"
18+
19+
20+
@pytest.fixture(scope="class")
21+
def payload(portal_type) -> dict:
22+
return {
23+
"type": portal_type,
24+
"id": "my-personal-workspace",
25+
"title": "My personal workspace",
26+
"description": "Description of my personal workspace",
27+
}
28+
29+
30+
class TestWorkspace:
31+
@pytest.fixture(autouse=True)
32+
def _setup(self, portal, get_fti, portal_type) -> None:
33+
self.portal = portal
34+
self.fti: DexterityFTI = get_fti(portal_type)
35+
36+
@pytest.mark.parametrize(
37+
"attr,expected",
38+
[
39+
("title", "Workspace"),
40+
("factory", "Workspace"),
41+
("description", "A folderish workspace container."),
42+
("schema", "kitconcept.plate.content.workspace.IWorkspace"),
43+
("allow_discussion", False),
44+
("global_allow", True),
45+
("filter_content_types", True),
46+
("allowed_content_types", ("WikiPage", "File", "Image")),
47+
],
48+
)
49+
def test_fti(self, attr: str, expected):
50+
assert isinstance(self.fti, DexterityFTI)
51+
assert getattr(self.fti, attr) == expected
52+
53+
@pytest.mark.parametrize(
54+
"idx,behavior",
55+
(
56+
enumerate((
57+
"plone.basic",
58+
"volto.preview_image_link",
59+
"plone.categorization",
60+
"plone.publication",
61+
"plone.ownership",
62+
"plone.relateditems",
63+
"plone.shortname",
64+
"volto.navtitle",
65+
"plone.excludefromnavigation",
66+
"plone.allowdiscussion",
67+
"volto.blocks",
68+
"plone.constraintypes",
69+
"plone.namefromtitle",
70+
"plone.versioning",
71+
"plone.locking",
72+
"plone.translatable",
73+
"kitconcept.plate.workspace",
74+
))
75+
),
76+
)
77+
def test_behaviors(self, idx, behavior):
78+
assert self.fti.behaviors[idx] == behavior
79+
80+
def test_workspace_creation(self, content_instance, portal_type):
81+
assert content_instance.portal_type == portal_type
82+
assert content_instance.aq_parent == self.portal
83+
84+
def test_versionable(self, portal_type, versionable_content_types):
85+
assert portal_type in versionable_content_types
86+
87+
def test_create_initial_version_after_adding(self, last_version, content_instance):
88+
version = last_version(content_instance)
89+
assert version.comment.default == "Initial version"
90+
assert version.version_id == 0
91+
92+
def test_create_version_on_save(
93+
self, notify_modified, history, last_version, content_instance
94+
):
95+
with api.env.adopt_roles(["Manager"]):
96+
content_instance.title = "Workspace Redux"
97+
notify_modified(content_instance)
98+
history_data = history(content_instance)
99+
assert len(history_data) == 2 # Initial + modified version
100+
version = last_version(content_instance)
101+
assert version.comment is None
102+
assert version.version_id == 1

0 commit comments

Comments
 (0)