Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports.py	(revision 9677)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports.py	(revision 9678)
@@ -124,5 +124,5 @@
         self.mode = mode
         self.author = author
-        self._creation_dt_string = self.creation_dt.astimezone(
+        self.creation_dt_string = self.creation_dt.astimezone(
             getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z")
         self.data = get_students_by(session, mode)
@@ -132,5 +132,5 @@
         table_data = tbl_data_to_table(*self.data)
         col_widths = [None,] + [1.6*cm] * len(self.data[1]) + [None,]
-        pdf_data = [Paragraph('<b>%s</b>' % self._creation_dt_string,
+        pdf_data = [Paragraph('<b>%s</b>' % self.creation_dt_string,
                               STYLE["Normal"]),
                     Spacer(1, 12),]
@@ -218,5 +218,5 @@
         filename = 'StudentsReport_%s_%s_%s.pdf' % (
             self.context.session, self.context.mode,
-            self._creation_dt_string)
+            self.context.creation_dt_string)
         filename = filename.replace(
             '/', '_').replace(' ','_').replace(':', '-')
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_reports.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_reports.py	(revision 9677)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_reports.py	(revision 9678)
@@ -1,8 +1,14 @@
 # Tests for student related reports
+import os
+from zc.async.testing import wait_for_result
 from zope.interface.verify import verifyClass, verifyObject
+from zope.component import getUtility
+from waeup.kofa.interfaces import IJobManager
 from waeup.kofa.students.reports import (
     get_students_by, StudentsReport, IStudentsReport)
 from waeup.kofa.students.tests.test_catalog import CatalogTestSetup
+from waeup.kofa.students.tests.test_browser import StudentsFullSetup
 from waeup.kofa.testing import FunctionalLayer
+from waeup.kofa.tests.test_async import FunctionalAsyncTestCase
 
 class StudentsReportTests(CatalogTestSetup):
@@ -66,2 +72,70 @@
         self.assertTrue(result.startswith('%PDF-'))
         return
+
+class StudentsReportUITests(StudentsFullSetup, FunctionalAsyncTestCase):
+
+    layer = FunctionalLayer
+
+    def wait_for_report_job_completed(self):
+        # helper function waiting until the current export job is completed
+        manager = getUtility(IJobManager)
+        job_id = self.app['reports'].running_report_jobs[0][0]
+        job = manager.get(job_id)
+        wait_for_result(job)
+        return job_id
+
+    def stored_in_reports(self, job_id):
+        # tell whether job_id is stored in reports's running jobs list
+        for entry in list(self.app['reports'].running_report_jobs):
+            if entry[0] == job_id:
+                return True
+        return False
+
+    def trigger_report_creation(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open('http://localhost/app/reports')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.browser.getLink("Create new report").click()
+        self.browser.getControl(name="generator").value = ['students_by']
+        self.browser.getControl("Configure").click()
+        self.browser.getControl(name="mode").value = ['All']
+        self.browser.getControl(name="session").value = ['2004']
+        self.browser.getControl("Create").click()
+        return
+
+    def test_report_download(self):
+        # We can download a generated report
+        self.trigger_report_creation()
+        # When the job is finished and we reload the page...
+        job_id = self.wait_for_report_job_completed()
+        self.browser.open('http://localhost/app/reports')
+        # ... the pdf file can be downloaded ...
+        self.browser.getControl("Download").click()
+        self.assertEqual(self.browser.headers['content-type'],
+                         'application/pdf')
+        self.assertTrue(
+            'filename="StudentsReport_2004_2005_All_' in
+            self.browser.headers['content-disposition'])
+        self.assertEqual(len(self.app['reports'].running_report_jobs), 1)
+        job_id = self.app['reports'].running_report_jobs[0][0]
+        # ... and discarded
+        self.browser.open('http://localhost/app/reports')
+        self.browser.getControl("Discard").click()
+        self.assertEqual(len(self.app['reports'].running_report_jobs), 0)
+        # Creation, downloading and discarding is logged
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'main.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'INFO - zope.mgr - students.reports.StudentsReportGeneratorPage - '
+            'created: Students (session=2004, mode=All)' in logcontent
+            )
+        self.assertTrue(
+            'INFO - zope.mgr - students.reports.StudentsReportPDFView - '
+            'downloaded: StudentsReport_2004_2005_All_' in logcontent
+            )
+        self.assertTrue(
+            'INFO - zope.mgr - browser.reports.ReportsContainerPage - '
+            'discarded: %s' % job_id in logcontent
+            )
+        return
