Give the Manager role to the current user:

  >>> from Testing.ZopeTestCase import user_name, user_password, folder_name
  >>> self.setRoles(['Manager'])

Create an empty file:

  >>> print http(r"""
  ... PUT /%s/file.zip HTTP/1.1
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 201 Created...

  >>> print self.folder._getOb('file.zip').meta_type
  File

Do a PROPFIND to check that the title is empty:

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...<n:title></n:title>...

Do a PROPATCH to set the title to a UTF-8 encoded string:

  >>> value = u'Copyright \xa9'.encode('utf-8')
  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:ns="http://www.zope.org/propsets/default">
  ...   <dav:set><dav:prop>
  ...    <ns:title>%s</ns:title>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password, value), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to check that the title is set to the correctly encoded
string, which should be utf-8 encoded:

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...<n:title>Copyright ©</n:title>...

Do a PROPATCH to set the title to a quoted string:

  >>> value = '&amp; is written &amp;amp;'
  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:ns="http://www.zope.org/propsets/default">
  ...   <dav:set><dav:prop>
  ...    <ns:title>%s</ns:title>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password, value), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to check that the title is set to the correctly quoted
string. If the patch didn't got applied we would get a double quoted
string here:

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...<n:title>&amp; is written &amp;amp;</n:title>...

Do a PROPATCH to set the title to a quoted string using CDATA:

  >>> value = '& is written &amp;'
  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:ns="http://www.zope.org/propsets/default">
  ...   <dav:set><dav:prop>
  ...    <ns:title><![CDATA[%s]]></ns:title>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password, value), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to check that the title is set to the correctly quoted
string. If the patch didn't got applied we would get a double quoted
string here:

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...<n:title>&amp; is written &amp;amp;</n:title>...

Do a PROPATCH to set the title to a quoted string using nested CDATA:

  >>> value = '& is written &amp;'
  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:ns="http://www.zope.org/propsets/default">
  ...   <dav:set><dav:prop>
  ...    <ns:title><title><![CDATA[%s]]></title></ns:title>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password, value), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to check that the title is set to the correctly quoted
string. If the patch didn't got applied we would get a double quoted
string here:

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...<n:title><title><![CDATA[& is written &amp;]]></title></n:title>...

Do a PROPATCH with a xml value and a missing namespace to exercise the
__xml_attrs__ hack:

  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:NS="http://awkly.org/shellex/203">
  ...   <dav:set><dav:prop>
  ...    <bug><number>203</number></bug>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to fetch the new value. Due to the missing namespace, it
will end up mapping the attribute to xmlns:n="None". Ugh. I wonder if
it should complain about it on the PROPPATCH.

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...
  <d:propstat xmlns:n="None">
  ...
  <n:bug><number>203</number></n:bug>
  ...

Delete the file:

  >>> print http(r"""
  ... DELETE /%s/file.zip HTTP/1.1
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 204 No Content
  ...
  <BLANKLINE>

Create an empty file:

  >>> print http(r"""
  ... PUT /%s/file.zip HTTP/1.1
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 201 Created...

  >>> print self.folder._getOb('file.zip').meta_type
  File


Do a PROPATCH with a xml value and a namespace prefix to exercise the
__xml_attrs__ hack:

  >>> print http(r"""
  ... PROPPATCH /%s/file.zip HTTP/1.1
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... <?xml version="1.0" encoding="utf-8"?>
  ... <dav:propertyupdate xmlns:dav="DAV:"
  ...   xmlns:NS="http://awkly.org/shellex/203">
  ...   <dav:set><dav:prop>
  ...    <NS:bug xmlns:NS="http://awkly.org/shellex/203">
  ...      <number>203</number>
  ...    </NS:bug>
  ...   </dav:prop></dav:set>
  ... </dav:propertyupdate>
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...

Do a PROPFIND to fetch the new value. Due to the missing namespace, it
will end up mapping the attribute to xmlns:n="None". Ugh. I wonder if
it should complain about it on the PROPPATCH.

  >>> print http(r"""
  ... PROPFIND /%s/file.zip HTTP/1.1
  ... Depth: 0
  ... Content-Type: text/xml; charset="utf-8"
  ... Authorization: Basic %s:%s
  ... """ % (folder_name, user_name, user_password), handle_errors=False)
  HTTP/1.1 207 Multi-Status
  Accept-Ranges: bytes
  ...
  Content-Type: text/xml; charset="utf-8"
  ...
  <BLANKLINE>
  ...
  <d:propstat xmlns:n="http://awkly.org/shellex/203">
  ...
  <n:bug>
  <number>203</number>
  </n:bug>
  ...
