=============================================
 Editing sort order of address book entities
=============================================

The sort order of the entities can be changed globally. The places where
entities are displayed in order are changed accordingly.

Set up
======

Create an address book and a browser to access it. Log in as
`Administrator`:

>>> from icemac.addressbook.testing import create_addressbook
>>> from z3c.etestbrowser.wsgi import ExtendedTestBrowser as Browser
>>> ab = create_addressbook()
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
>>> browser.open('http://localhost/++skin++AddressBook/ab')

The sort order of the entities can be changed in the master data area:

>>> browser.getLink('Master data').click()
>>> browser.getLink('Entities').click()
>>> edit_entities_url = browser.url
>>> edit_entities_url
'http://localhost/++skin++AddressBook/ab/++attribute++entities'

Changing sort order
===================

To change the sort order of the entities the user has to select the ``up``
resp. ``down`` links.

>>> import zope.site.hooks
>>> import zope.component
>>> import icemac.addressbook.interfaces
>>> old_site = zope.site.hooks.getSite()
>>> def get_entity_titles():
...     zope.site.hooks.setSite(ab)
...     entities = zope.component.getUtility(
...        icemac.addressbook.interfaces.IEntities)
...     return [x.title for x in entities.getEntities()]

The initial sort order is:

>>> get_entity_titles()
[u'address book', u'person', u'main adresses and numbers', u'postal address', ...

Move entity up
--------------

Seleting the `up` link moves the entity one position up in the list and
shows an info message. Let's move the postal address one up:

>>> from icemac.addressbook.testing import get_messages
>>> up_link_url = browser.getLink('up', index=2).url
>>> browser.open(up_link_url)
>>> get_messages(browser)
['Moved postal address up.']
>>> get_entity_titles()
[u'address book', u'person', u'postal address', u'main adresses and numbers', ...

There is no `up` link for the first entity in the table:

>>> print browser.contents
<!DOCTYPE...
  <tbody>
    <tr class="table-even-row">
      <td>address book</td>
      <td></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.addressbook.AddressBook/@@down.html">down</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.addressbook.AddressBook">Edit fields</a></td>
    </tr>
 ...

Move entity down
----------------

Seleting the `down` link moves the entity one position down in the
list. Let's move the address book one down:

>>> down_link_url = browser.getLink('down', index=0).url
>>> browser.open(down_link_url)
>>> get_messages(browser)
['Moved address book down.']
>>> get_entity_titles()
[u'person', u'address book', u'postal address', u'main adresses and numbers', ...

There is no `down` link for the last entity in the table:

>>> print browser.contents
<!DOCTYPE...
    <tr class="table-...-row">
      <td>keyword</td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.keyword.Keyword/@@up.html">up</a></td>
      <td></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.keyword.Keyword">Edit fields</a></td>
   </tr>
  </tbody>
  ...

Visibility of entity sort order
===============================

The entity sort order is reflected in the entity table:

>>> print browser.contents
<!DOCTYPE...
  <tbody>
    <tr class="table-even-row">
      <td>person</td>
      <td></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.person.Person/@@down.html">down</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.person.Person">Edit fields</a></td>
    </tr>
    <tr class="table-odd-row">
      <td>address book</td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.addressbook.AddressBook/@@up.html">up</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.addressbook.AddressBook/@@down.html">down</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.addressbook.AddressBook">Edit fields</a></td>
    </tr>
    <tr class="table-even-row">
      <td>postal address</td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.address.PostalAddress/@@up.html">up</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.address.PostalAddress/@@down.html">down</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.address.PostalAddress">Edit fields</a></td>
    </tr>
    <tr class="table-odd-row">
      <td>main adresses and numbers</td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.person.PersonDefaults/@@up.html">up</a></td>
      <td><a href="http://localhost/++skin++AddressBook/ab/++attribute++entities/icemac.addressbook.person.PersonDefaults/@@down.html">down</a></td>
      <td></td>
    </tr>
    <tr class="table-even-row">
      <td>phone number</td>
  ...

The sort order of the entries in the add menu also depends on the entity
order: the phone number is shown before the postal address:

>>> from icemac.addressbook.testing import create_full_person
>>> create_full_person(ab, ab, u'Tester', return_obj=False)
>>> browser.getLink('Person list').click()
>>> browser.getLink('Tester').click()
>>> print browser.contents
<!DOCTYPE...
          <ul id="add-menu-content"><li>
  <a href="http://localhost/++skin++AddressBook/ab/Person/@@addPostalAddress.html"><span>postal address</span></a>
</li>
<li>
  <a href="http://localhost/++skin++AddressBook/ab/Person/@@addPhoneNumber.html"><span>phone number</span></a>
  ...


Security
========

Editors and visitors are not able to change the entity sort order even
though, they know the url.

Editor
------

>>> editor = Browser()
>>> editor.addHeader('Authorization', 'Basic editor:editor')
>>> editor.open(up_link_url)
Traceback (most recent call last):
HTTPError: HTTP Error 403: Forbidden
>>> editor.open(down_link_url)
Traceback (most recent call last):
HTTPError: HTTP Error 403: Forbidden


Visitor
-------

>>> visitor = Browser()
>>> visitor.addHeader('Authorization', 'Basic visitor:visitor')
>>> visitor.open(up_link_url)
Traceback (most recent call last):
HTTPError: HTTP Error 403: Forbidden
>>> visitor.open(down_link_url)
Traceback (most recent call last):
HTTPError: HTTP Error 403: Forbidden


Tear down
=========

>>> zope.site.hooks.setSite(old_site)
