Functional Tests
================

Upload and Download
-------------------

Let's make sure a user can upload a file and then download it. This is
the minimal required to make sure we fulfill the basic expectations.

1. Give the manager role to our test user so he can do anything

  >>> from Testing.ZopeTestCase import user_name, user_password, folder_name
  >>> from Products.Sessions.SessionDataManager import constructSessionDataManager
  >>> from Products.Sessions.BrowserIdManager import constructBrowserIdManager
  >>> from Products.Transience.Transience import constructTransientObjectContainer
  >>> self.setRoles(['Manager'])
  >>> self.login(user_name)
  >>> constructTransientObjectContainer(self.app, 'test_session_data')
  >>> constructSessionDataManager(self.app, 'sdm', path='/test_session_data',
  ...                             requestName='SESSION')
  >>> constructBrowserIdManager(self.app)
  >>> self.portal.manage_delObjects(ids=['cookie_authentication'])

2. Create a file for our tests:

  >>> self.portal.invokeFactory('AT Managed File', 'file3')
  >>> 'file3' in self.portal.objectIds()
  True

3. Post a very simple file:

  >>> print http(r"""
  ... POST /portal/file3/base_edit HTTP/1.1
  ... Authorization: Basic %s:%s
  ... Content-Length: 1632
  ... Content-Type: multipart/form-data; boundary=---------------------------16997119618530731951446521160
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="id"
  ...
  ... file3
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="title"
  ...
  ... File3
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="file_file"; filename="test.txt"
  ... Content-Type: text/plain
  ...
  ... This is a Test
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="repository"
  ...
  ... default
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="deletePolicy"
  ...
  ... Immediate
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="fieldset"
  ...
  ... default
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="form.submitted"
  ...
  ... 1
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.field:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.type:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.destination:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="last_referer"
  ...
  ... http://localhost:8180/portal/file3/base_edit
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="form_submit"
  ...
  ... Save
  ... -----------------------------16997119618530731951446521160--
  ... """ % (user_name, user_password), handle_errors=False)
  HTTP/1.1 302 Moved Temporarily
  ...

4. Try to download the file:

  >>> print http(r"""
  ... GET /portal/file3/at_download HTTP/1.1
  ... Authorization: Basic %s:%s
  ... """ % (user_name, user_password))
  HTTP/1.1 200 OK
  Accept-Ranges: none
  Content-Disposition: attachment; filename=test.txt
  Content-Length: ...
  Content-Type: text/plain
  ...
  <BLANKLINE>
  <open file...

  >>> print self.portal.file3.getFile()
  This is a Test
  <BLANKLINE>

  >>> orig_filename = self.portal.file3.getFilepath()
  >>> print open(orig_filename, 'rb').read()
  This is a Test
  <BLANKLINE>

Editing
-------

Changing the repository while uploading the file:

1. Setup a second repository, pointing to a temporary directory:


  >>> import os
  >>> import tempfile
  >>> from Products.CMFManagedFile.config import *
  >>> tmp_dir = tempfile.mkdtemp()
  >>> repo = self.tool.addRepository('test',
  ...   path=tmp_dir,
  ...   path_policy=FS_BASE,
  ...   filename_policy=ORIGINAL_POLICY)

2. Edit the previously created file changing the repository and
   uploading a new file:

  >>> print http(r"""
  ... POST /portal/file3/base_edit HTTP/1.1
  ... Authorization: Basic %s:%s
  ... Content-Length: 1632
  ... Content-Type: multipart/form-data; boundary=---------------------------16997119618530731951446521160
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="id"
  ...
  ... file3
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="title"
  ...
  ... Test File
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="file_file"; filename="test.txt"
  ... Content-Type: text/plain
  ...
  ... This is another test
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="repository"
  ...
  ... test
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="deletePolicy"
  ...
  ... Immediate
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="fieldset"
  ...
  ... default
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="form.submitted"
  ...
  ... 1
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.field:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.type:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="add_reference.destination:record"
  ...
  ...
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="last_referer"
  ...
  ... http://localhost:8180/portal/file3/base_edit
  ... -----------------------------16997119618530731951446521160
  ... Content-Disposition: form-data; name="form_submit"
  ...
  ... Save
  ... -----------------------------16997119618530731951446521160--
  ... """ % (user_name, user_password), handle_errors=False)
  HTTP/1.1 302 Moved Temporarily
  ...

  >>> print self.portal.file3.Title()
  Test File

  >>> self.portal.file3.getFilepath() == orig_filename
  False

  >>> os.path.exists(orig_filename)
  False

  >>> print self.portal.file3.getProperty('repository')
  test

  >>> print self.portal.file3.getFile()
  This is another test
  <BLANKLINE>

  >>> orig_filename = self.portal.file3.getFilepath()
  >>> print open(orig_filename, 'rb').read()
  This is another test
  <BLANKLINE>

External Editor
---------------

Need to ensure two things here:

1. That manage_FTPget returns just the file content (use list and join
   so it works both with string and filestream_iterator)

  >>> print ''.join(list(self.portal.file3.manage_FTPget()))
  This is another test
  <BLANKLINE>

2. That ExternalEditor can handle everything just fine

  >>> from Products.ExternalEditor.ExternalEditor import ExternalEditor
  >>> ext_edit = ExternalEditor()
  >>> request = self.app.REQUEST
  >>> response = request.RESPONSE
  >>> request.set('target', 'file3')
  >>> print ext_edit.__of__(self.portal).index_html(request, response)
  url:http://.../portal/file3
  meta_type:AT Managed File
  content_type:text/plain
  cookie:
  <BLANKLINE>
  This is another test
  <BLANKLINE>


Creation and manipulation through WebDAV
----------------------------------------

First of all, we have to change the Content Type Registry to tell it
to create ATManagedFile for file uploads:

  >>> from Products.CMFCore.utils import getToolByName
  >>> ctr = getToolByName(self.portal, 'content_type_registry')
  >>> p_id = 'at_managed_file'
  >>> p_type = 'name_regex'
  >>> ctr.addPredicate(p_id, p_type)
  >>> class foo: pass
  >>> p_dict = foo()
  >>> p_dict.pattern = '.*'
  >>> ctr.updatePredicate(p_id, p_dict, 'AT Managed File')
  >>> ctr.reorderPredicate(p_id, 0)

  >>> body = open(orig_filename, 'rb').read()

  >>> print http(r"""
  ... PUT portal/file4 HTTP/1.1
  ... Authorization: Basic %s:%s
  ... Content-Type: text/plain
  ... %s""" % (user_name, user_password, body),
  ...        handle_errors=False)
  HTTP/1.1 201 Created...

  >>> print http(r"""
  ... GET /portal/file4/at_download HTTP/1.1
  ... Authorization: Basic %s:%s
  ... """ % (user_name, user_password))
  HTTP/1.1 200 OK
  Accept-Ranges: none
  Content-Disposition: attachment; filename=file4
  Content-Length: ...
  Content-Type: application/octet-stream
  ...
  <BLANKLINE>
  <open file...

  >>> print self.portal.file4.getFile()
  This is another test
  <BLANKLINE>

  >>> orig_filename = self.portal.file4.getFilepath()
  >>> print open(orig_filename, 'rb').read()
  This is another test
  <BLANKLINE>
