Note that for the sake of the test, the test setup has installed a dummy schema
context that will allow us to demonstrate editing a dummy IDummySchema schema, via the
/schemaeditor URL. It also registers an event handler for various schema events that
will print out the event, so that we can make sure events are getting raised properly.
Let's set up the test browser::
>>> from Testing.testbrowser import Browser
>>> browser = Browser()
>>> portal_url = 'http://nohost'
>>> browser.handleErrors = False
Navigating to a schema
----------------------
If we try to access the schema editor without logging in, we should get an Unauthorized
error::
>>> browser.open(portal_url + '/@@schemaeditor')
Traceback (most recent call last):
...
Unauthorized: ...You are not authorized to access this resource...
We need to log in as a manager, because by default only managers get the 'Manage Schemata' permission::
>>> user = self.app.acl_users.userFolderAddUser('root', 'secret', ['Manager'], [])
>>> browser.addHeader('Authorization', 'Basic root:secret')
Now we should be able to navigate to the IDummySchema schema in the browser::
>>> browser.open(portal_url + '/@@schemaeditor')
>>> 'Edit @@schemaeditor' in browser.contents
True
Adding a field
--------------
Let's add a 'favorite-color' field to the IDummySchema schema::
>>> browser.getControl('Add new field').click()
>>> browser.getControl('Title').value = 'Favorite Color'
>>> browser.getControl('Short Name').value = 'favorite_color'
>>> browser.getControl(name='form.widgets.description').value = 'Select your favorite color'
>>> browser.getControl('Field type').value = ['Text line (String)']
>>> browser.getControl(name='form.widgets.required').value = ['true']
>>> browser.getControl('Add').click()
[event: ObjectAddedEvent on TextLine]
[event: FieldAddedEvent on DummySchemaContext]
>>> browser.url
'http://nohost/@@schemaeditor'
Now the actual IDummySchema schema should have the new field (the field id is a
normalized form of the title)::
>>> from plone.schemaeditor.tests.fixtures import IDummySchema
>>> 'favorite_color' in IDummySchema
True
>>> from zope.schema import TextLine
>>> isinstance(IDummySchema['favorite_color'], TextLine)
True
>>> IDummySchema['favorite_color'].title
u'Favorite Color'
>>> IDummySchema['favorite_color'].required
True
>>> IDummySchema['favorite_color'].description
u'Select your favorite color'
Editing a schema field attribute
--------------------------------
Let's navigate to the 'favorite-color' field we just created::
>>> browser.getLink(url='favorite_color').click()
>>> browser.url
'http://nohost/@@schemaeditor/favorite_color'
>>> "Edit Field 'favorite_color'" in browser.contents
True
Now we can change various attributes. For instance, let's change the help text
for the 'color' field::
>>> browser.getControl('Description').value = 'Enter your favorite color.'
And now click the button to save the change. This should take us back to the list
of schema fields, which should reflect the change::
>>> browser.getControl('Save').click()
[event: ObjectModifiedEvent on TextLine]
[event: SchemaModifiedEvent on DummySchemaContext]
>>> browser.url
'http://nohost/@@schemaeditor'
Let's confirm that the new default value was correctly saved to the actual schema::
>>> IDummySchema['favorite_color'].description
u'Enter your favorite color.'
Let's go back and try to make an invalid change. The form won't let us::
>>> browser.getLink(url='favorite_color').click()
>>> browser.url
'http://nohost/@@schemaeditor/favorite_color'
>>> browser.getControl('Minimum length').value = 'asdf'
>>> browser.getControl('Save').click()
>>> browser.url
'http://nohost/@@schemaeditor/favorite_color/@@edit'
>>> 'The entered value is not a valid integer literal.' in browser.contents
True
We also cannot set the field title to an empty string, even though the field is
not required in zope.schema.interfaces.IField::
>>> browser.open('http://nohost/@@schemaeditor/favorite_color')
>>> browser.getControl('Title').value = ''
>>> browser.getControl('Save').click()
>>> browser.url
'http://nohost/@@schemaeditor/favorite_color/@@edit'
>>> 'Required input is missing.' in browser.contents
True
We can give up and hit the Cancel button, which should take us back to the schema listing,
without trying to save changes::
>>> browser.getControl('Cancel').click()
>>> browser.url
'http://nohost/@@schemaeditor'
Re-ordering a field
-------------------
The field we added was created in a position following the 5 existing fields on the
interface::
>>> from zope.schema import getFieldsInOrder
>>> getFieldsInOrder(IDummySchema)[5][0]
'favorite_color'
Fields can be reordered via drag-and-drop. Let's simulate the AJAX request that would
result from dragging the 'favorite_color' field to the 3rd position (since the
testbrowser doesn't support Javascript)::
>>> browser.open('http://nohost/@@schemaeditor/favorite_color/@@order?pos=2&fieldset_index=0')
[event: ContainerModifiedEvent on InterfaceClass]
[event: SchemaModifiedEvent on DummySchemaContext]
>>> browser.contents
''
Now the field should be the third field of the schema::
>>> getFieldsInOrder(IDummySchema)[2][0]
'favorite_color'
Now let's move it to be the first field (as there is an edge case in the ordering
algorithm that we need to test)::
>>> browser.open('http://nohost/@@schemaeditor/favorite_color/@@order?pos=0&fieldset_index=0')
[event: ContainerModifiedEvent on InterfaceClass]
[event: SchemaModifiedEvent on DummySchemaContext]
>>> getFieldsInOrder(IDummySchema)[0][0]
'favorite_color'
Moving a field to an other fieldset
-----------------------------------
Fields can be moved from a fieldset to an other one.
They are moved to the end of the new fieldset::
>>> browser.open('http://nohost/@@schemaeditor/favorite_color/@@changefieldset?fieldset_index=1')
[event: ContainerModifiedEvent on InterfaceClass]
[event: SchemaModifiedEvent on DummySchemaContext]
>>> browser.contents
''
Now the field should be the seventh field of the schema::
>>> getFieldsInOrder(IDummySchema)[6][0]
'favorite_color'
>>> from plone.schemaeditor.utils import get_field_fieldset
>>> get_field_fieldset(IDummySchema, 'favorite_color')