Through-the-web content type editing
====================================

This package, plone.app.dexterity, provides the UI for creating and editing
Dexterity content types through the Plone control panel.

To demonstrate this, we'll need a logged in test browser::

  >>> from Products.Five.testbrowser import Browser
  >>> browser = Browser()
  >>> browser.handleErrors = False
  >>> self.app.acl_users.userFolderAddUser('root', 'secret', ['Manager'], [])
  >>> browser.addHeader('Authorization', 'Basic root:secret')


Dexterity Types Configlet
-------------------------

Once the 'Dexterity Content Configlet' product is installed, site managers
can navigate to the configlet via the control panel::

  >>> browser.open('http://nohost/plone')
  >>> browser.getLink('Site Setup').click()
  >>> browser.getLink('Dexterity Content Types').click()
  >>> browser.url
  'http://nohost/plone/@@dexterity-types'
  >>> 'Dexterity content types' in browser.contents
  True


Adding a content type
---------------------

Let's add a 'Plonista' content type to keep track of members of the Plone
community::

  >>> browser.getControl('Type Name').value = 'Plonista'
  >>> browser.getControl('Add').click()
  >>> browser.url
  'http://nohost/plone/@@dexterity-types'
  >>> 'Item added successfully.' in browser.contents
  True

Now we should also have a 'plonista' FTI in portal_types::

  >>> 'plonista' in self.portal.portal_types
  True

The new type should have the dublin core behavior assigned by default::

  >>> plonista = self.portal.portal_types.plonista
  >>> 'plone.app.dexterity.behaviors.metadata.IDublinCore' in plonista.behaviors
  True
  >>> 'document_icon' in plonista.getIcon()
  True


Editing a content type
----------------------

Editing schemata is handled by the plone.schemaeditor package and is tested
there.  However, let's at least make sure that we can navigate to the
schema for the 'plonista' type we just created::

  >>> browser.getLink('Plonista').click()
  >>> browser.url
  'http://nohost/plone/dexterity-types/plonista'


Enabling a behavior
-------------------

For each content type, a number of behaviors may be enabled.  Let's disable all
the behaviors for 'plonista' and make sure that the change is reflected on the
FTI::

  >>> browser.getLink('Behaviors').click()
  >>> browser.getControl(name='form.widgets.plone.app.dexterity.behaviors.metadata.IDublinCore:list').value = []
  >>> browser.getControl('Save').click()
  >>> self.portal.portal_types.plonista.behaviors
  []


Viewing a non-editable schema
-----------------------------

If a type's schema is not stored as XML in its FTI's schema property, it cannot
currently be edited through the web.  However, the fields of the schema can at
least be listed.

  >>> from zope.interface import Interface
  >>> from zope import schema
  >>> import plone.app.dexterity.tests
  >>> class IFilesystemSchema(Interface):
  ...     irc_nick = schema.TextLine(title=u'IRC Nickname')
  >>> plone.app.dexterity.tests.IFilesystemSchema = IFilesystemSchema
  >>> plonista.schema = 'plone.app.dexterity.tests.IFilesystemSchema'
  >>> browser.open('http://nohost/plone/dexterity-types/plonista')
  >>> 'crud-edit.form.buttons.delete' in browser.contents
  False
  >>> 'IRC Nickname' in browser.contents
  True


Removing a content type
-----------------------

We can also delete a content type via the configlet::

  >>> browser.open('http://nohost/plone/@@dexterity-types')
  >>> browser.getControl(name='crud-edit.plonista.widgets.select:list').value = ['0']
  >>> browser.getControl('Delete').click()

Now the FTI for the type should no longer be present in portal_types::

  >>> 'plonista' in self.portal.portal_types
  False


Adding a container
------------------

We can create a content type that is a container for other content::

  >>> browser.getControl('Type Name').value = 'Plonista Folder'
  >>> browser.getControl(name='crud-add.form.widgets.container:list').value = ['true']
  >>> browser.getControl('Add').click()
  >>> browser.url
  'http://nohost/plone/@@dexterity-types'
  >>> 'Item added successfully.' in browser.contents
  True

Now we should have a 'plonista-folder' FTI in portal_types, and it should be
using the Container base class::

  >>> 'plonista-folder' in self.portal.portal_types
  True
  >>> pf = getattr(self.portal.portal_types, 'plonista-folder')
  >>> pf.klass
  'plone.dexterity.content.Container'
  >>> 'folder_icon' in pf.getIcon()
  True
