Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_student.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_student.py	(revision 9124)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_student.py	(revision 9131)
@@ -21,9 +21,13 @@
 import re
 import unittest
+import grok
 from cStringIO import StringIO
 from datetime import tzinfo
-from zope.component import getUtility
+from zope.component import getUtility, queryUtility, createObject
+from zope.catalog.interfaces import ICatalog
 from zope.component.interfaces import IFactory
+from zope.event import notify
 from zope.interface import verify
+from zope.schema.interfaces import RequiredMissing
 from waeup.kofa.interfaces import IExtFileStore, IFileStoreNameChooser
 from waeup.kofa.students.export import EXPORTER_NAMES
@@ -236,4 +240,73 @@
         return
 
+class StudentTransferTests(StudentImportExportSetup):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(StudentTransferTests, self).setUp()
+
+        # Add additional certificate
+        self.certificate2 = createObject('waeup.Certificate')
+        self.certificate2.code = 'CERT2'
+        self.certificate2.application_category = 'basic'
+        self.certificate2.start_level = 200
+        self.certificate2.end_level = 500
+        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
+            self.certificate2)
+
+        # Add student with subobjects
+        student = Student()
+        self.app['students'].addStudent(student)
+        student = self.setup_student(student)
+        notify(grok.ObjectModifiedEvent(student))
+        self.student = self.app['students'][student.student_id]
+        return
+
+    def test_transfer_student(self):
+        self.assertRaises(
+            RequiredMissing, self.student.transfer, self.certificate2)
+        success = self.student.transfer(self.certificate2, current_session=2013)
+        self.assertEqual(self.student['studycourse_1'].certificate.code, 'CERT1')
+        self.assertEqual(self.student['studycourse'].certificate.code, 'CERT2')
+        self.assertEqual(self.student['studycourse_1'].current_session, 2012)
+        self.assertEqual(self.student['studycourse'].current_session, 2013)
+        self.assertEqual(self.student['studycourse_1'].__name__, 'studycourse_1')
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'students.log')
+        logcontent = open(logfile).read()
+        self.assertTrue('system - K1000000 - transferred from CERT1 to CERT2'
+            in logcontent)
+
+        # The students_catalog has been updated.
+        cat = queryUtility(ICatalog, name='students_catalog')
+        results = cat.searchResults(certcode=('CERT1', 'CERT1'))
+        results = [x for x in results]
+        self.assertEqual(len(results), 0)
+        results = cat.searchResults(certcode=('CERT2', 'CERT2'))
+        results = [x for x in results]
+        self.assertEqual(len(results), 1)
+        assert results[0] is self.app['students'][self.student.student_id]
+        results = cat.searchResults(current_session=(2013,2013))
+        results = [x for x in results]
+        self.assertEqual(len(results), 1)
+        assert results[0] is self.app['students'][self.student.student_id]
+
+        # Students can be transferred (only) two times.
+        success = self.student.transfer(self.certificate, current_session=2013)
+        self.assertTrue(success)
+        success = self.student.transfer(self.certificate2, current_session=2013)
+        self.assertFalse(success)
+        self.assertEqual([i for i in self.student.keys()],
+            [u'accommodation', u'payments', u'studycourse',
+             u'studycourse_1', u'studycourse_2'])
+
+        # The students_catalog has been updated again.
+        cat = queryUtility(ICatalog, name='students_catalog')
+        results = cat.searchResults(certcode=('CERT1', 'CERT1'))
+        results = [x for x in results]
+        self.assertEqual(len(results), 1)
+        assert results[0] is self.app['students'][self.student.student_id]
+        return
 
 class StudentFactoryTest(FunctionalTestCase):
