I’ve got a content type based on ATFolder:
ConceptSheetFolderSchema = folder.ATFolderSchema.copy()
ConceptSheetFolderSchema['title'].widget.label = _(u"Title")
ConceptSheetFolderSchema['title'].widget.description = _(u"")
ConceptSheetFolderSchema['title'].storage = atapi.AnnotationStorage()
ConceptSheetFolderSchema['description'].widget.label = _(u"Description")
ConceptSheetFolderSchema['description'].widget.description = _("")
ConceptSheetFolderSchema['description'].storage = atapi.AnnotationStorage()
finalizeATCTSchema(ConceptSheetFolderSchema, folderish=True, moveDiscussion=False)
class ConceptSheetFolder(folder.ATFolder):
"""
This is the central container for concept sheets in the site
"""
implements(IConceptSheetFolder)
portal_type = "Concept Sheet Folder"
_at_rename_after_creation = True
schema = ConceptSheetFolderSchema
title = atapi.ATFieldProperty('title')
description = atapi.ATFieldProperty('description')
atapi.registerType(ConceptSheetFolder, PROJECTNAME)
I can add a ConceptSheetFolder no problem through the Plone interface, but I can’t get this basic test to work:
class TestContent(unittest.TestCase):
layer = PROJECT_CONCEPTSHEETS_INTEGRATION_TESTING
def test_hierarchy(self):
portal = self.layer['portal']
# Ensure that we can create the various content types without error
setRoles(portal, TEST_USER_ID, ('Manager',))
portal.invokeFactory('Concept Sheet Folder', 'csf1', title=u"Concept Sheet folder")
portal['csf1'].invokeFactory('project.ConceptSheet', 'cs1', title=u"ConceptSheet")
portal['csf1']['cs1'].invokeFactory('project.ConceptMilestone', 'cs1', title=u"Approved")`
I get a error
Unauthorized: Cannot create Concept Sheet Folder when I try this test. I Googled around a bit and found this Nabble post, leading me to look at isConstructionAllowed() in Plone/CMFCore/TestTools.py. Using pdb, I found that ._queryFactoryMethod(), when run in this context, is returning ‘None’.
So it appears the FactoryTool for this type isn’t working, at least not in the test. I’ve got the test in the normal GenericSetup place (types.xml, Concept_Sheet_Folder.xml, factorytool.xml), and I’m at a lost as to what else could be causing this problem. Any ideas?
Bonus question: why does this work in the Plone interface but not in the test?
Edit (Dec 13, 2011): Here’s my Concept_Sheet_Folder.xml
<?xml version="1.0"?>
<object name="Concept Sheet Folder"
meta_type="Factory-based Type Information with dynamic views"
i18n:domain="iedea.conceptsheets" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
<property name="title" i18n:translate="">Concept Sheet Folder</property>
<property name="description"
i18n:translate="">A folder which can contain concept sheets.</property>
<property name="content_icon">++resource++conceptsheetfolder_icon.gif</property>
<property name="content_meta_type">Concept Sheet Folder</property>
<property name="product">iedea.conceptsheets</property>
<property name="factory">addConceptSheetFolder</property>
<property name="immediate_view">atct_edit</property>
<property name="global_allow">True</property>
<property name="filter_content_types">True</property>
<property name="allowed_content_types">
<element value="Concept Sheet" />
</property>
<property name="allow_discussion">False</property>
<property name="default_view">view</property>
<property name="view_methods">
<element value="view"/>
</property>
<alias from="(Default)" to="(dynamic view)"/>
<alias from="edit" to="atct_edit"/>
<alias from="sharing" to="@@sharing"/>
<alias from="view" to="(selected layout)"/>
<action title="View" action_id="view" category="object" condition_expr=""
url_expr="string:${folder_url}/" visible="True">
<permission value="View"/>
</action>
<action title="Edit" action_id="edit" category="object" condition_expr=""
url_expr="string:${object_url}/edit" visible="True">
<permission value="Modify portal content"/>
</action>
</object>
I’ve run into this problem myself. The problem is that the your Archetype’s factory is not yet properly registered by the time you are trying to create it.
That’s why _queryFactoryMethod() returns None, as you found out.
The solution differs a bit on whether you are using Products.ZopeTestCase or the newer plone.app.testing as your testing framework.
However, in both cases you need to make sure that the add-on product that defines the Archetype (ConceptSheetFolder) that you are trying to create (via invokeFactory), has aready been installed.
When using Products.ZopeTestCase:
In the case that you are using Products.ZopeTestCase (and Products.PloneTestCase), you need to call
You need to make sure that your installProduct call does not get deferred until after your test is called.
In Plone 4 this means that your installProduct call should not be in an @onsetup decorated function (although this will still work in Plone 3).
This mailing list discussion might further clear things up:
http://plone.293351.n2.nabble.com/invokeFactory-failing-on-Plone-4-PTC-but-working-on-Plone-3-td5755482.html
When using plone.app.testing:
If you are using plone.app.testing, you should call:
This should be done in the setUpZope method that you override from the PloneSandboxLayer.
For more info, read the description under setUpZope in plone.app.testing.helpers.py (Line 257)
https://github.com/plone/plone.app.testing/blob/2ef789f8173c695179b043fd4634e0bdb6567511/plone/app/testing/helpers.py