>>> from plone.app.testing import TEST_USER_ID >>> from plone.app.testing import TEST_USER_NAME >>> from plone.app.testing import TEST_USER_PASSWORD >>> from plone.app.testing import setRoles >>> from plone.testing.z2 import Browser >>> import transaction >>> portal = layer['portal'] >>> app = layer['app'] >>> setRoles(portal, TEST_USER_ID, ['Manager']) Some Tests ---------- Just use the behavior ``plone.app.versioningbehavior.behaviors.IVersionable`` in your dexterity content type:: >>> from plone.dexterity.fti import DexterityFTI >>> fti = DexterityFTI('TestingType', ... factory='TestingType') >>> fti.behaviors = ( ... 'plone.app.dexterity.behaviors.metadata.IBasic', ... 'plone.app.versioningbehavior.behaviors.IVersionable', ... ) >>> portal.portal_types._setObject('TestingType', fti) 'TestingType' >>> schema = fti.lookupSchema() We have to setup versioning for this content type by visiting the plone configuration panel for content types (/@@types-controlpanel) and enable automatic versioning for our content type. For this test we set this configuration manually:: >>> from Products.CMFCore.utils import getToolByName >>> pr = getToolByName(portal, 'portal_repository') >>> versionable_types = pr.getVersionableContentTypes() >>> versionable_types.append('TestingType') >>> pr.setVersionableContentTypes(versionable_types) >>> for policy_id in ('at_edit_autoversion', 'version_on_revert'): ... pr.addPolicyForContentType('TestingType', policy_id) >>> transaction.commit() Create a new Browser and connect it:: >>> browser = Browser(app) >>> browser.handleErrors = False >>> browser.addHeader('Authorization', 'Basic %s:%s' % (TEST_USER_NAME, TEST_USER_PASSWORD)) Now we should be able to create a new TestingType-object:: >>> browser.open('http://nohost/plone/folder_factories') >>> 'TestingType' in browser.contents True >>> browser.getControl("TestingType").click() >>> browser.getControl("Add").click() >>> browser.url 'http://nohost/plone/++add++TestingType' >>> browser.getControl('Title').value = 'Blubb' >>> browser.getControl('Save').click() >>> browser.url 'http://nohost/plone/testingtype/view' The 'changeNote' field should not be visible in the view:: >>> 'changeNote' in browser.contents False >>> 'Change Note' in browser.contents False We should be able to access the object, it should provide the marker interface ``plone.app.versioningbehavior.behaviors.IVersioningSupport``:: >>> obj = portal.get('testingtype') >>> from plone.app.versioningbehavior.behaviors import IVersioningSupport >>> IVersioningSupport.providedBy(obj) True After creating the object we wan't to create a new version by simply editing it:: >>> browser.open('http://nohost/plone/testingtype/edit') >>> browser.getControl('Title').value = 'Blubb2' >>> field = browser.getControl(name='form.widgets.IVersionable.changeNote') >>> field.value = 'just a test' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/testingtype' Now we should have at least one version:: >>> obj = portal.get('testingtype') >>> pa = portal.portal_archivist >>> history = pa.getHistoryMetadata(obj) >>> history.getLength(countPurged=False) > 0 True And we should be able to list the versions:: >>> browser.open('http://nohost/plone/testingtype/versions_history_form') >>> 'just a test' in browser.contents True A freshly created object should have a initial version:: >>> browser.open('http://nohost/plone/++add++TestingType') >>> browser.getControl('Title').value = 'Init test' >>> browser.getControl(name='form.widgets.IVersionable.changeNote') \ ... .value = 'initial change note' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/testingtype-1/view' Now we should have one - and only one - version:: >>> obj = portal.get('testingtype-1') >>> pa = portal.portal_archivist >>> history = pa.getHistoryMetadata(obj) >>> history.getLength(countPurged=False) 1 And we should see our comment on the versions listing later... >>> browser.open('http://nohost/plone/testingtype-1/versions_history_form') >>> 'initial change note' in browser.contents True It should also be possible to copy/paste an existing content:: >>> browser.open('http://nohost/plone/testingtype') >>> browser.getLink('Copy').click() >>> browser.open('http://nohost/plone/') >>> browser.getLink('Paste').click() >>> 'copy_of_testingtype' in portal.objectIds() True After pasting, we can create a new version by simply editing it:: >>> browser.open('http://nohost/plone/copy_of_testingtype/edit') >>> browser.getControl('Title').value = 'Dup' >>> field = browser.getControl(name='form.widgets.IVersionable.changeNote') >>> field.value = 'Edited the duplicate' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/copy_of_testingtype' Dexterity Containers ==================== We should also be able to use versionig for dexterity contents in dexterity containers. Create a container FTI:: >>> container_fti = DexterityFTI( ... 'DemoContainer', ... klass='plone.dexterity.content.Container', ... filter_content_types=False, ... factory='DemoContainerMyFolder', ... behaviors = ('plone.app.dexterity.behaviors.metadata.IBasic',), ... ) >>> portal.portal_types._setObject('DemoContainer', container_fti) 'DemoContainer' >>> container_schema = fti.lookupSchema() >>> transaction.commit() Create a container object:: >>> browser.open('http://nohost/plone/++add++DemoContainer') >>> browser.getControl('Title').value = 'MyFolder' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/democontainer/view' Now we add a versioned object to the container:: >>> browser.open('http://nohost/plone/democontainer/++add++TestingType') >>> browser.getControl('Title').value = 'My versioned object' >>> browser.getControl(name='form.widgets.IVersionable.changeNote').value = 'created a object' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/democontainer/testingtype/view' So let's see the version history. There should be one version with the comment "created a object":: >>> obj = portal.get('democontainer').get('testingtype') >>> obj >>> pa = portal.portal_archivist >>> history = pa.getHistoryMetadata(obj) >>> history.getLength(countPurged=False) 1 >>> browser.open('http://nohost/plone/democontainer/testingtype/versions_history_form') >>> 'created a object' in browser.contents True Dexterity containers should also be versionable. Let's create a new versioned container FTI:: >>> versioned_container_fti = DexterityFTI( ... 'VersionedContainer', ... klass='plone.dexterity.content.Container', ... filter_content_types=False, ... glboal_allow=True, ... factory='VersionedContainer', ... ) >>> versioned_container_fti.behaviors = ( ... 'plone.app.dexterity.behaviors.metadata.IBasic', ... 'plone.app.versioningbehavior.behaviors.IVersionable', ... ) >>> portal.portal_types._setObject('VersionedContainer', versioned_container_fti) 'VersionedContainer' >>> versioned_container_schema = versioned_container_fti.lookupSchema() Enable versioning for the new content type:: >>> pr = getToolByName(portal, 'portal_repository') >>> versionable_types = pr.getVersionableContentTypes() >>> versionable_types.append('VersionedContainer') >>> pr.setVersionableContentTypes(versionable_types) >>> for policy_id in ('at_edit_autoversion', 'version_on_revert'): ... pr.addPolicyForContentType('VersionedContainer', policy_id) >>> transaction.commit() Let's Create a versioned container object on the portal:: >>> browser.open('http://nohost/plone/++add++VersionedContainer') >>> browser.getControl('Title').value = 'Versioned container one' >>> browser.getControl(name='form.widgets.IVersionable.changeNote').value = 'my change note' >>> browser.getControl(name='form.buttons.save').click() >>> browser.url 'http://nohost/plone/versionedcontainer/view' Do we have a initial version? >>> obj = portal.get('versionedcontainer') >>> obj >>> pa = portal.portal_archivist >>> history = pa.getHistoryMetadata(obj) >>> history.getLength(countPurged=False) 1 >>> browser.open('http://nohost/plone/versionedcontainer/versions_history_form') >>> 'my change note' in browser.contents True Another versioned container should be addable:: >>> browser.open('http://nohost/plone/versionedcontainer/folder_factories') >>> 'VersionedContainer' in browser.contents True Now we try to add another versioned container in the previously created versioned container:: >>> browser.open('http://nohost/plone/versionedcontainer/++add++VersionedContainer') >>> browser.getControl('Title').value = 'Versioned container two' >>> browser.getControl(name='form.widgets.IVersionable.changeNote').value = 'another change note' >>> browser.getControl(name='form.buttons.save').click() So, we should have the initial version:: >>> parent = portal['versionedcontainer'] >>> obj = parent['versionedcontainer'] >>> obj >>> pa = portal.portal_archivist >>> history = pa.getHistoryMetadata(obj) >>> history.getLength(countPurged=False) 1 >>> browser.open('http://nohost/plone/versionedcontainer/versionedcontainer/versions_history_form') >>> 'another change note' in browser.contents True Check that the parent does not get versioned inappropriately. >>> history = pa.getHistoryMetadata(parent) >>> history.getLength(countPurged=False) 1