Index: main/waeup.aaue/trunk/src/waeup/aaue/applicants/tests/test_browser.py
===================================================================
--- main/waeup.aaue/trunk/src/waeup/aaue/applicants/tests/test_browser.py	(revision 15099)
+++ main/waeup.aaue/trunk/src/waeup/aaue/applicants/tests/test_browser.py	(revision 15113)
@@ -20,9 +20,11 @@
 import pytz
 import os
+from StringIO import StringIO
 from zope.event import notify
 from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
 from zope.component import createObject, getUtility
 from waeup.kofa.configuration import SessionConfiguration
-from waeup.kofa.interfaces import IUserAccount
+from waeup.kofa.interfaces import (
+    IUserAccount, IExtFileStore, IFileStoreNameChooser)
 from waeup.kofa.applicants.container import ApplicantsContainer
 from waeup.kofa.browser.tests.test_pdf import samples_dir
@@ -285,2 +287,74 @@
         self.assertFalse('Admitted Course of Study' in self.browser.contents)
         return
+
+    def test_upload_stateresult_by_manager(self):
+        # Add trans applicants container
+        self.transcontainer = ApplicantsContainer()
+        self.transcontainer.mode = 'create'
+        self.transcontainer.code = u'trans%s' % session_1
+        self.transcontainer.prefix = u'trans'
+        self.transcontainer.application_category = u'no'
+        self.transcontainer.year = session_1
+        self.transcontainer.application_fee = 300.0
+        self.transcontainer.title = u'This is the trans%s container' % session_1
+        self.app['applicants'][self.transcontainer.code] = self.transcontainer
+        delta = datetime.timedelta(days=10)
+        self.transcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
+        self.transcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
+        # Add applicant
+        transapplicant = createObject(u'waeup.Applicant')
+        transapplicant.firstname = u'Anna'
+        transapplicant.lastname = u'Post'
+        self.app['applicants'][self.transcontainer.code].addApplicant(transapplicant)
+        self.transapplicant = self.app['applicants'][self.transcontainer.code][
+            transapplicant.application_number]
+        self.transapplicant_view_path = ('http://localhost/app/applicants/trans%s/%s'
+            % (session_1, transapplicant.application_number))
+        self.transapplicant_manage_path = ('http://localhost/app/applicants/trans%s/%s/manage'
+            % (session_1, transapplicant.application_number))
+        # Login
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.transapplicant_manage_path)
+        # Create a pseudo file with acceptable size
+        pdf_content = 'A' * 1024 * 300  # A string of 300 KB size
+        pseudo_pdf = StringIO(pdf_content)
+        ctrl = self.browser.getControl(name='form.stateresult')
+        file_ctrl = ctrl.mech_control
+        file_ctrl.add_file(pseudo_pdf, filename='myform.pdf')
+        self.browser.getControl("Save").click() # submit form
+        # Even though the form could not be saved ...
+        self.assertTrue('Required input is missing' in self.browser.contents)
+        # ... the file has been successfully uploaded
+        pdf_url = self.transapplicant_manage_path.replace('manage', 'stateresult.pdf')
+        self.browser.open(pdf_url)
+        self.assertEqual(
+            self.browser.headers['content-type'], 'application/pdf')
+        self.assertEqual(len(self.browser.contents), 307200)
+        # There is really a file stored for the applicant
+        storage = getUtility(IExtFileStore)
+        file_id = IFileStoreNameChooser(self.transapplicant).chooseName(
+            attr='stateresult.pdf')
+        # The stored file can be fetched
+        fd = storage.getFile(file_id)
+        file_len = len(fd.read())
+        self.assertEqual(file_len, 307200)
+        # A file link is displayed on the edit view ...
+        self.browser.open(self.transapplicant_manage_path)
+        self.assertTrue('<a href="stateresult.pdf">' in self.browser.contents)
+        # ... and on the dislay view
+        self.browser.open(self.transapplicant_view_path)
+        self.assertTrue('<a href="stateresult.pdf">Statement of Result</a>'
+            in self.browser.contents)
+        # Adding file is properly logged
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'applicants.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'zope.mgr - waeup.aaue.applicants.browser.CustomApplicantManageFormPage'
+            ' - %s - saved: stateresult'
+            % (self.transapplicant.applicant_id)
+            in logcontent)
+        # When an applicant is removed, also the pdf files are gone.
+        del self.app['applicants'][self.transcontainer.code][self.transapplicant.application_number]
+        fd = storage.getFile(file_id)
+        self.assertTrue(fd is None)
