Index: main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py	(revision 16228)
+++ main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py	(revision 16231)
@@ -37,4 +37,6 @@
 from zope.security.interfaces import Unauthorized
 from zope.testbrowser.testing import Browser
+from zope.interface import implementedBy
+from zope.schema.fieldproperty import FieldProperty
 from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
 from waeup.kofa.browser.tests.test_pdf import samples_dir
@@ -583,4 +585,37 @@
     layer = FunctionalLayer
 
+    def setUp(self):
+        super(ApplicantUITests, self).setUp()
+        self.setup_logging()
+        return
+
+    def tearDown(self):
+        super(ApplicantUITests, self).tearDown()
+        self.teardown_logging()
+        return
+
+    def setup_logging(self):
+        # setup a log-handler that catches all fake mailer output
+        self.stream = StringIO()
+        handler = logging.StreamHandler(self.stream)
+        logger = logging.getLogger('test.smtp')
+        logger.addHandler(handler)
+        logger.setLevel(logging.INFO)
+        return
+
+    def get_fake_smtp_output(self):
+        # get output generated by fake mailer
+        self.stream.flush()
+        self.stream.seek(0)
+        return self.stream.read()
+
+    def teardown_logging(self):
+        # remove the log handler for fake mailer output
+        logger = logging.getLogger('test.smtp')
+        handlers = [x for x in logger.handlers]
+        for handler in handlers:
+            logger.removeHandler(handler)
+        return
+
     def test_manage_and_view_applicant(self):
         # Managers can manage applicants
@@ -623,5 +658,5 @@
         # If applicant is in correct state the pdf slip can be opened.
         IWorkflowState(self.applicant).setState('submitted')
-        self.browser.open(self.manage_path)
+        self.browser.open(self.view_path)
         self.browser.getLink("Download application slip").click()
         self.assertEqual(self.browser.headers['Status'], '200 Ok')
@@ -924,5 +959,5 @@
         file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
         self.browser.getControl("Save").click() # submit form
-        self.browser.open(self.manage_path)
+        self.browser.open(self.view_path)
         self.browser.getLink("Download application slip").click()
         self.assertEqual(self.browser.headers['Status'], '200 Ok')
@@ -1331,4 +1366,48 @@
         return
 
+    def test_manage_contact_applicant(self):
+        # Managers can contact student
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        # Remove required FieldProperty attribute first ...
+        delattr(Applicant, 'email')
+        # ... and replace by None
+        self.applicant.email = None
+        # Now we have to add  the FieldProperty attribute again. Otherwise
+        # many other tests below will fail.
+        iface = list(implementedBy(Applicant))[0]
+        field_property = FieldProperty(iface['email'])
+        setattr(Applicant, 'email', field_property)
+        self.browser.open(self.view_path)
+        self.browser.getLink("Send email").click()
+        self.browser.getControl(
+            name="form.subject").value = 'Important subject'
+        self.browser.getControl(name="form.body").value = 'Hello!'
+        self.browser.getControl("Send message now").click()
+        self.assertTrue(
+            'An smtp server error occurred' in self.browser.contents)
+        self.applicant.email = 'xx@yy.zz'
+        self.browser.getControl("Send message now").click()
+        self.assertTrue('Your message has been sent' in self.browser.contents)
+        self.assertMatches(
+            'Sending email from no-reply@waeup.org to xx@yy.zz:'
+            '\nMessage:'
+            '\nmsg: MIME-Version: 1.0'
+            '\nmsg: Content-Type: text/plain; charset="us-ascii"'
+            '\nmsg: Content-Transfer-Encoding: 7bit'
+            '\nmsg: From: Manager <no-reply@waeup.org>'
+            '\nmsg: To: Joan None <xx@yy.zz>'
+            '\nmsg: Reply-To: Manager <contact@waeup.org>'
+            '\nmsg: Subject: Important subject'
+            '\nmsg:'
+            '\nmsg: Hello!'
+            '\nmsg:'
+            '\nmsg: ---'
+            '\nmsg: Manager (id: zope.mgr)'
+            '\nmsg: Sample University'
+            '\nmsg:',
+            self.get_fake_smtp_output()
+            )
+        return
+
 
 class ApplicantRegisterTests(ApplicantsFullSetup):
@@ -1956,5 +2035,5 @@
         # Managers can remind referees
         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.manage_path)
+        self.browser.open(self.view_path)
         self.browser.getLink("Remind referees").click()
         self.assertTrue('2 referee(s) have been reminded by email.'
@@ -2035,5 +2114,5 @@
         report.email = 'linda@forest.de'
         self.applicant[report.r_id] = report
-        self.browser.open(self.manage_path)
+        self.browser.open(self.view_path)
         self.browser.getLink("Remind referees").click()
         self.assertTrue('1 referee(s) have been reminded by email.'
