Utils package
=============

This test suite will test some functions from utils that need a Plone
site set-up::

    >>> self.setup_data()
    >>> from collective.sendaspdf import utils

We need a bit more advanced architecture here::

    >>> _ = self.create_folder(self.portal, 'folder1')
    >>> _ = self.create_folder(self.portal, 'folder2')
    >>> folder1 = self.portal['folder1']
    >>> folder2 = self.portal['folder2']
    >>> _ = self.create_folder(folder1, 'folder1.1')
    >>> _ = self.create_folder(folder1, 'folder1.2')
    >>> folder11 = self.portal['folder1']['folder1.1']
    >>> folder12 = self.portal['folder1']['folder1.2']

And some pages/images::

    >>> for folder in [folder1, folder2, folder11, folder12]:
    ...     _ = self.create_page(None, 'A new page', folder)
    ...     _ = self.create_page(None, 'Another page', folder)
    ...     _ = self.create_image('blink.png', 'image/png', folder)


utils.extract_from_url:
-----------------------

More tests from the function's doctests.

The system can recognise parameters with special characters::

    >>> utils.extract_from_url(
    ...     'http://127.0.0.1:8080/hostedhrm/acl_users/credentials_cookie_auth/require_login?came_from=http%3A//127.0.0.1%3A8080/hostedhrm/nerull-ii/nerull-ii/test-floating-contract%3Fwidget_id%3DplonehrmAbsenceWidget%26mode%3Dpercentage%26UID%3Dea267a725dc3ea79b4e67902d221e04e',
    ...     'http://127.0.0.1:8080/hostedhrm/acl_users/credentials_cookie_auth/')
    ('require_login',
     {'came_from': 'http://127.0.0.1:8080/hostedhrm/nerull-ii/nerull-ii/test-floating-contract?widget_id=plonehrmAbsenceWidget&mode=percentage&UID=ea267a725dc3ea79b4e67902d221e04e'})


utils.get_object_from_url
-------------------------

This function retrieves a Plone object that is linked with a relative path.
It returns a tuple containing:
 - the object
 - the view that was called on the object (if existing)
 - the image size if the image was scaled
 - the path that the function was not able to parse.


First, an example with simple links::

    >>> utils.get_object_from_url(folder11['a-new-page'], ('another-page', ))
    (<ATDocument at /plone/folder1/folder1.1/another-page used for /plone/folder1/folder1.1/a-new-page>, None, None, None)

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'folder1.1', 'a-new-page'))
    (<ATDocument at /plone/folder1/folder1.1/a-new-page>, None, None, None)

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'folder1.2', 'a-new-page'))
    (<ATDocument at /plone/folder1/folder1.2/a-new-page>, None, None, None)


If the link is broken, we get a tuple of Nones::

    >>> utils.get_object_from_url(folder11['a-new-page'], ('this-page-does-not-exist', ))
    (None, None, None, None)

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'this-page-does-not-exist', ))
    (None, None, None, None)


As usual with Zope, there's some dark Acquisition magic taking effect::

    >>> _ = self.create_page(None, 'My page', folder1)
    >>> utils.get_object_from_url(folder11['a-new-page'], ('my-page', ))
    (<ATDocument at /plone/folder1/my-page used for /plone/folder1/folder1.1/a-new-page>, None, None, None)


This system can also handle data existing in skin folder (depending on the
Plone version, the name displayed may change so we use ellipsis to
keep the tests running, the important thing is that it's getting the
FS image object) ::

    >>> utils.get_object_from_url(folder11['a-new-page'], ('pinkie.gif', ))
    (<FSImage at /plone/...pinkie.gif...>, None, None, None)

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'pinkie.gif', ))
    (<FSImage at /plone/...pinkie.gif...>, None, None, None)


If we link to a particular view of a link document, it will appear in
the second position of the tuple::

    >>> self.setRoles(['Manager'])
    >>> utils.get_object_from_url(folder11['a-new-page'], ('@@send_as_pdf', ))
    (<ATDocument at /plone/folder1/folder1.1/a-new-page>, '@@send_as_pdf', None, ())

    >>> utils.get_object_from_url(folder11['a-new-page'], ('another-page', '@@send_as_pdf', ))
    (<ATDocument at /plone/folder1/folder1.1/another-page>, '@@send_as_pdf', None, ())

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'folder1.2', 'a-new-page', '@@send_as_pdf', ))
    (<ATDocument at /plone/folder1/folder1.2/a-new-page>, '@@send_as_pdf', None, ())


If there's some extra things after the view name, they'll be left in
the last part of the tuple::

    >>> utils.get_object_from_url(folder11['a-new-page'], ('..', 'folder1.2', 'a-new-page', '@@send_as_pdf', 'more', 'things', 'after', ))
    (<ATDocument at /plone/folder1/folder1.2/a-new-page>, '@@send_as_pdf', None, ('more', 'things', 'after'))


This is mainly used for images inserted in Plone 4 with TinyMCE, the
URL is ``<path_to_my_image>@@images/image/thumb``.
The ``@@images`` view does not exist in Plone 3, that explains the ugly
hack :/ ::

    >>> if self.is_plone_3:
    ...     print "(<ATImage at /plone/folder1/folder1.1/blink.png>, '@@images', None, ('image', 'thumb'))"
    ... else:
    ...     utils.get_object_from_url(folder11['a-new-page'], ('blink.png', '@@images', 'image', 'thumb', ))
    (<ATImage at /plone/folder1/folder1.1/blink.png>, '@@images', None, ('image', 'thumb'))


With Plone 3, the path was ``<path_to_my_image>image_thumb``. In that
case, the size appears in the third argument of the tuple::

    >>> utils.get_object_from_url(folder11['a-new-page'], ('blink.png', 'image_thumb', ))
    (<ATImage at /plone/folder1/folder1.1/blink.png used for /plone/folder1/folder1.1/a-new-page>, None, 'image_thumb', ())
