Index: main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9335)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9336)
@@ -400,8 +400,6 @@
         return
 
-class StudentUITests(StudentsFullSetup):
+class OfficerUITests(StudentsFullSetup):
     # Tests for Student class views and pages
-
-    layer = FunctionalLayer
 
     def test_student_properties(self):
@@ -743,4 +741,239 @@
         self.assertTrue(
             self.student['studycourse']['200']['COURSE1'].carry_over)
+        return
+
+    def test_manage_payments(self):
+        # Managers can add online school fee payment tickets
+        # if certain requirements are met
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.payments_path)
+        IWorkflowState(self.student).setState('cleared')
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['schoolfee']
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches('...ticket created...',
+                           self.browser.contents)
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[0]
+        self.browser.getLink(value).click()
+        self.assertMatches('...Amount Authorized...',
+                           self.browser.contents)
+        self.assertEqual(self.student['payments'][value].amount_auth, 40000.0)
+        payment_url = self.browser.url
+
+        # The pdf payment slip can't yet be opened
+        #self.browser.open(payment_url + '/payment_slip.pdf')
+        #self.assertMatches('...Ticket not yet paid...',
+        #                   self.browser.contents)
+
+        # The same payment (with same p_item, p_session and p_category)
+        # can be initialized a second time if the former ticket is not yet paid.
+        self.browser.open(self.payments_path)
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['schoolfee']
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches('...Payment ticket created...',
+                           self.browser.contents)
+
+        # Managers can approve the payment
+        self.assertEqual(len(self.app['accesscodes']['SFE-0']),0)
+        self.browser.open(payment_url)
+        self.browser.getLink("Approve payment").click()
+        self.assertMatches('...Payment approved...',
+                          self.browser.contents)
+
+        # The authorized amount has been stored in the access code
+        self.assertEqual(
+            self.app['accesscodes']['SFE-0'].values()[0].cost,40000.0)
+
+        # Payments can't be approved twice
+        self.browser.open(payment_url + '/approve')
+        self.assertMatches('...This ticket has already been paid...',
+                          self.browser.contents)
+
+        # Now the first ticket is paid and no more ticket of same type
+        # (with same p_item, p_session and p_category) can be added
+        self.browser.open(self.payments_path)
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['schoolfee']
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches(
+            '...This type of payment has already been made...',
+            self.browser.contents)
+
+        # Managers can open the pdf payment slip
+        self.browser.open(payment_url)
+        self.browser.getLink("Download payment slip").click()
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
+
+        # Managers can remove online school fee payment tickets
+        self.browser.open(self.payments_path)
+        self.browser.getControl("Remove selected").click()
+        self.assertMatches('...No payment selected...', self.browser.contents)
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[0]
+        ctrl.getControl(value=value).selected = True
+        self.browser.getControl("Remove selected", index=0).click()
+        self.assertTrue('Successfully removed' in self.browser.contents)
+
+        # Managers can add online clearance payment tickets
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['clearance']
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches('...ticket created...',
+                           self.browser.contents)
+
+        # Managers can approve the payment
+        self.assertEqual(len(self.app['accesscodes']['CLR-0']),0)
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[1] # The clearance payment is the second in the table
+        self.browser.getLink(value).click()
+        self.browser.open(self.browser.url + '/approve')
+        self.assertMatches('...Payment approved...',
+                          self.browser.contents)
+        expected = '''...
+        <td>
+          <span>Paid</span>
+        </td>...'''
+        self.assertMatches(expected,self.browser.contents)
+        # The new CLR-0 pin has been created
+        self.assertEqual(len(self.app['accesscodes']['CLR-0']),1)
+        pin = self.app['accesscodes']['CLR-0'].keys()[0]
+        ac = self.app['accesscodes']['CLR-0'][pin]
+        self.assertEqual(ac.owner, self.student_id)
+        self.assertEqual(ac.cost, 3456.0)
+        return
+
+    def test_manage_accommodation(self):
+        # Managers can add online booking fee payment tickets and open the
+        # callback view (see test_manage_payments)
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.payments_path)
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['bed_allocation']
+        # If student is not in accommodation session, payment cannot be processed
+        self.app['hostels'].accommodation_session = 2011
+        self.browser.getControl("Create ticket").click()
+        self.assertMatches('...Your current session does not match...',
+                           self.browser.contents)
+        self.app['hostels'].accommodation_session = 2004
+        self.browser.getControl("Add online payment ticket").click()
+        self.browser.getControl(name="form.p_category").value = ['bed_allocation']
+        self.browser.getControl("Create ticket").click()
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[0]
+        self.browser.getLink(value).click()
+        self.browser.open(self.browser.url + '/approve')
+        # The new HOS-0 pin has been created
+        self.assertEqual(len(self.app['accesscodes']['HOS-0']),1)
+        pin = self.app['accesscodes']['HOS-0'].keys()[0]
+        ac = self.app['accesscodes']['HOS-0'][pin]
+        self.assertEqual(ac.owner, self.student_id)
+        parts = pin.split('-')[1:]
+        sfeseries, sfenumber = parts
+        # Managers can use HOS code and book a bed space with it
+        self.browser.open(self.acco_path)
+        self.browser.getLink("Book accommodation").click()
+        self.assertMatches('...You are in the wrong...',
+                           self.browser.contents)
+        IWorkflowInfo(self.student).fireTransition('admit')
+        # An existing HOS code can only be used if students
+        # are in accommodation session
+        self.student['studycourse'].current_session = 2003
+        self.browser.getLink("Book accommodation").click()
+        self.assertMatches('...Your current session does not match...',
+                           self.browser.contents)
+        self.student['studycourse'].current_session = 2004
+        # All requirements are met and ticket can be created
+        self.browser.getLink("Book accommodation").click()
+        self.assertMatches('...Activation Code:...',
+                           self.browser.contents)
+        self.browser.getControl(name="ac_series").value = sfeseries
+        self.browser.getControl(name="ac_number").value = sfenumber
+        self.browser.getControl("Create bed ticket").click()
+        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
+                           self.browser.contents)
+        # Bed has been allocated
+        bed1 = self.app['hostels']['hall-1']['hall-1_A_101_A']
+        self.assertTrue(bed1.owner == self.student_id)
+        # BedTicketAddPage is now blocked
+        self.browser.getLink("Book accommodation").click()
+        self.assertMatches('...You already booked a bed space...',
+            self.browser.contents)
+        # The bed ticket displays the data correctly
+        self.browser.open(self.acco_path + '/2004')
+        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
+                           self.browser.contents)
+        self.assertMatches('...2004/2005...', self.browser.contents)
+        self.assertMatches('...regular_male_fr...', self.browser.contents)
+        self.assertMatches('...%s...' % pin, self.browser.contents)
+        # Managers can relocate students if the student's bed_type has changed
+        self.browser.getLink("Relocate student").click()
+        self.assertMatches(
+            "...Student can't be relocated...", self.browser.contents)
+        self.student.sex = u'f'
+        self.browser.getLink("Relocate student").click()
+        self.assertMatches(
+            "...Hall 1, Block A, Room 101, Bed B...", self.browser.contents)
+        self.assertTrue(bed1.owner == NOT_OCCUPIED)
+        bed2 = self.app['hostels']['hall-1']['hall-1_A_101_B']
+        self.assertTrue(bed2.owner == self.student_id)
+        self.assertTrue(self.student['accommodation'][
+            '2004'].bed_type == u'regular_female_fr')
+        # The payment object still shows the original payment item
+        payment_id = self.student['payments'].keys()[0]
+        payment = self.student['payments'][payment_id]
+        self.assertTrue(payment.p_item == u'regular_male_fr')
+        # Managers can relocate students if the bed's bed_type has changed
+        bed1.bed_type = u'regular_female_fr'
+        bed2.bed_type = u'regular_male_fr'
+        notify(grok.ObjectModifiedEvent(bed1))
+        notify(grok.ObjectModifiedEvent(bed2))
+        self.browser.getLink("Relocate student").click()
+        self.assertMatches(
+            "...Student relocated...", self.browser.contents)
+        self.assertMatches(
+            "... Hall 1, Block A, Room 101, Bed A...", self.browser.contents)
+        self.assertMatches(bed1.owner, self.student_id)
+        self.assertMatches(bed2.owner, NOT_OCCUPIED)
+        # Managers can't relocate students if bed is reserved
+        self.student.sex = u'm'
+        bed1.bed_type = u'regular_female_reserved'
+        notify(grok.ObjectModifiedEvent(bed1))
+        self.browser.getLink("Relocate student").click()
+        self.assertMatches(
+            "...Students in reserved beds can't be relocated...",
+            self.browser.contents)
+        # Managers can relocate students if booking has been cancelled but
+        # other bed space has been manually allocated after cancellation
+        old_owner = bed1.releaseBed()
+        self.assertMatches(old_owner, self.student_id)
+        bed2.owner = self.student_id
+        self.browser.open(self.acco_path + '/2004')
+        self.assertMatches(
+            "...booking cancelled...", self.browser.contents)
+        self.browser.getLink("Relocate student").click()
+        # We didn't informed the catalog therefore the new owner is not found
+        self.assertMatches(
+            "...There is no free bed in your category regular_male_fr...",
+            self.browser.contents)
+        # Now we fire the event properly
+        notify(grok.ObjectModifiedEvent(bed2))
+        self.browser.getLink("Relocate student").click()
+        self.assertMatches(
+            "...Student relocated...", self.browser.contents)
+        self.assertMatches(
+            "... Hall 1, Block A, Room 101, Bed B...", self.browser.contents)
+          # Managers can delete bed tickets
+        self.browser.open(self.acco_path)
+        ctrl = self.browser.getControl(name='val_id')
+        value = ctrl.options[0]
+        ctrl.getControl(value=value).selected = True
+        self.browser.getControl("Remove selected", index=0).click()
+        self.assertMatches('...Successfully removed...', self.browser.contents)
+        # The bed has been properly released by the event handler
+        self.assertMatches(bed1.owner, NOT_OCCUPIED)
+        self.assertMatches(bed2.owner, NOT_OCCUPIED)
         return
 
@@ -1092,4 +1325,149 @@
         self.assertTrue(self.student_id in self.browser.contents)
 
+    def test_change_current_mode(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.clearance_path)
+        self.assertFalse('Employer' in self.browser.contents)
+        self.browser.open(self.manage_clearance_path)
+        self.assertFalse('Employer' in self.browser.contents)
+        self.student.clearance_locked = False
+        self.browser.open(self.edit_clearance_path)
+        self.assertFalse('Employer' in self.browser.contents)
+        # Now we change the study mode of the certificate and a different
+        # interface is used by clearance views.
+        self.certificate.study_mode = 'pg_ft'
+        # Invariants are not being checked here?!
+        self.certificate.end_level = 100
+        self.browser.open(self.clearance_path)
+        self.assertTrue('Employer' in self.browser.contents)
+        self.browser.open(self.manage_clearance_path)
+        self.assertTrue('Employer' in self.browser.contents)
+        self.browser.open(self.edit_clearance_path)
+        self.assertTrue('Employer' in self.browser.contents)
+
+    def test_activate_deactivate_buttons(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.student_path)
+        self.browser.getLink("Deactivate").click()
+        self.assertTrue(
+            'Student account has been deactivated.' in self.browser.contents)
+        self.assertTrue(
+            'Base Data (account deactivated)' in self.browser.contents)
+        self.assertTrue(self.student.suspended)
+        self.browser.getLink("Activate").click()
+        self.assertTrue(
+            'Student account has been activated.' in self.browser.contents)
+        self.assertFalse(
+            'Base Data (account deactivated)' in self.browser.contents)
+        self.assertFalse(self.student.suspended)
+        # History messages have been added ...
+        self.browser.getLink("History").click()
+        self.assertTrue(
+            'Student account deactivated by Manager<br />' in self.browser.contents)
+        self.assertTrue(
+            'Student account activated by Manager<br />' in self.browser.contents)
+        # ... and actions have been logged.
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'students.log')
+        logcontent = open(logfile).read()
+        self.assertTrue('zope.mgr - students.browser.StudentDeactivatePage - '
+                        'K1000000 - account deactivated' in logcontent)
+        self.assertTrue('zope.mgr - students.browser.StudentActivatePage - '
+                        'K1000000 - account activated' in logcontent)
+
+    def test_manage_student_transfer(self):
+        # Add second certificate
+        self.certificate2 = createObject('waeup.Certificate')
+        self.certificate2.code = u'CERT2'
+        self.certificate2.study_mode = 'ug_ft'
+        self.certificate2.start_level = 999
+        self.certificate2.end_level = 999
+        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
+            self.certificate2)
+
+        # Add study level to old study course
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 200
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 999
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.student_path)
+        self.browser.getLink("Transfer").click()
+        self.browser.getControl(name="form.certificate").value = ['CERT2']
+        self.browser.getControl(name="form.current_session").value = ['2011']
+        self.browser.getControl(name="form.current_level").value = ['200']
+        self.browser.getControl("Transfer").click()
+        self.assertTrue(
+            'Current level does not match certificate levels'
+            in self.browser.contents)
+        self.browser.getControl(name="form.current_level").value = ['999']
+        self.browser.getControl("Transfer").click()
+        self.assertTrue('Successfully transferred' in self.browser.contents)
+        # The catalog has been updated
+        cat = queryUtility(ICatalog, name='students_catalog')
+        results = list(
+            cat.searchResults(
+            certcode=('CERT2', 'CERT2')))
+        self.assertTrue(results[0] is self.student)
+        results = list(
+            cat.searchResults(
+            current_session=(2011, 2011)))
+        self.assertTrue(results[0] is self.student)
+        # Add study level to new study course
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 999
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+
+        # Edit and add pages are locked for old study courses
+        self.browser.open(self.student_path + '/studycourse/manage')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/manage')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/start_session')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/start_session')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        IWorkflowState(self.student).setState('school fee paid')
+        self.browser.open(self.student_path + '/studycourse/add')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/add')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/999/manage')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/999/manage')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/999/validate_courses')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/999/validate_courses')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/999/reject_courses')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/999/reject_courses')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/999/add')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/999/add')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/999/edit')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse_1/999/edit')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+class StudentUITests(StudentsFullSetup):
+    # Tests for Student class views and pages
+
     def test_student_change_password(self):
         # Students can change the password
@@ -1451,107 +1829,4 @@
         self.assertMatches('...Clearance has been requested...',
                            self.browser.contents)
-
-    def test_manage_payments(self):
-        # Managers can add online school fee payment tickets
-        # if certain requirements are met
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.payments_path)
-        IWorkflowState(self.student).setState('cleared')
-        self.browser.getControl("Add online payment ticket").click()
-        self.browser.getControl(name="form.p_category").value = ['schoolfee']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...ticket created...',
-                           self.browser.contents)
-        ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[0]
-        self.browser.getLink(value).click()
-        self.assertMatches('...Amount Authorized...',
-                           self.browser.contents)
-        self.assertEqual(self.student['payments'][value].amount_auth, 40000.0)
-        payment_url = self.browser.url
-
-        # The pdf payment slip can't yet be opened
-        #self.browser.open(payment_url + '/payment_slip.pdf')
-        #self.assertMatches('...Ticket not yet paid...',
-        #                   self.browser.contents)
-
-        # The same payment (with same p_item, p_session and p_category)
-        # can be initialized a second time if the former ticket is not yet paid.
-        self.browser.open(self.payments_path)
-        self.browser.getControl("Add online payment ticket").click()
-        self.browser.getControl(name="form.p_category").value = ['schoolfee']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...Payment ticket created...',
-                           self.browser.contents)
-
-        # Managers can approve the payment
-        self.assertEqual(len(self.app['accesscodes']['SFE-0']),0)
-        self.browser.open(payment_url)
-        self.browser.getLink("Approve payment").click()
-        self.assertMatches('...Payment approved...',
-                          self.browser.contents)
-
-        # The authorized amount has been stored in the access code
-        self.assertEqual(
-            self.app['accesscodes']['SFE-0'].values()[0].cost,40000.0)
-
-        # Payments can't be approved twice
-        self.browser.open(payment_url + '/approve')
-        self.assertMatches('...This ticket has already been paid...',
-                          self.browser.contents)
-
-        # Now the first ticket is paid and no more ticket of same type
-        # (with same p_item, p_session and p_category) can be added
-        self.browser.open(self.payments_path)
-        self.browser.getControl("Add online payment ticket").click()
-        self.browser.getControl(name="form.p_category").value = ['schoolfee']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches(
-            '...This type of payment has already been made...',
-            self.browser.contents)
-
-        # Managers can open the pdf payment slip
-        self.browser.open(payment_url)
-        self.browser.getLink("Download payment slip").click()
-        self.assertEqual(self.browser.headers['Status'], '200 Ok')
-        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
-
-        # Managers can remove online school fee payment tickets
-        self.browser.open(self.payments_path)
-        self.browser.getControl("Remove selected").click()
-        self.assertMatches('...No payment selected...', self.browser.contents)
-        ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[0]
-        ctrl.getControl(value=value).selected = True
-        self.browser.getControl("Remove selected", index=0).click()
-        self.assertTrue('Successfully removed' in self.browser.contents)
-
-        # Managers can add online clearance payment tickets
-        self.browser.open(self.payments_path + '/addop')
-        self.browser.getControl(name="form.p_category").value = ['clearance']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...ticket created...',
-                           self.browser.contents)
-
-        # Managers can approve the payment
-        self.assertEqual(len(self.app['accesscodes']['CLR-0']),0)
-        ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[1] # The clearance payment is the second in the table
-        self.browser.getLink(value).click()
-        self.browser.open(self.browser.url + '/approve')
-        self.assertMatches('...Payment approved...',
-                          self.browser.contents)
-        expected = '''...
-        <td>
-          <span>Paid</span>
-        </td>...'''
-        self.assertMatches(expected,self.browser.contents)
-        # The new CLR-0 pin has been created
-        self.assertEqual(len(self.app['accesscodes']['CLR-0']),1)
-        pin = self.app['accesscodes']['CLR-0'].keys()[0]
-        ac = self.app['accesscodes']['CLR-0'][pin]
-        self.assertEqual(ac.owner, self.student_id)
-        self.assertEqual(ac.cost, 3456.0)
-        return
 
     def test_student_payments(self):
@@ -1859,136 +2134,4 @@
         return
 
-    def test_manage_accommodation(self):
-        # Managers can add online booking fee payment tickets and open the
-        # callback view (see test_manage_payments)
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.payments_path)
-        self.browser.getControl("Add online payment ticket").click()
-        self.browser.getControl(name="form.p_category").value = ['bed_allocation']
-        # If student is not in accommodation session, payment cannot be processed
-        self.app['hostels'].accommodation_session = 2011
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...Your current session does not match...',
-                           self.browser.contents)
-        self.app['hostels'].accommodation_session = 2004
-        self.browser.getControl("Add online payment ticket").click()
-        self.browser.getControl(name="form.p_category").value = ['bed_allocation']
-        self.browser.getControl("Create ticket").click()
-        ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[0]
-        self.browser.getLink(value).click()
-        self.browser.open(self.browser.url + '/approve')
-        # The new HOS-0 pin has been created
-        self.assertEqual(len(self.app['accesscodes']['HOS-0']),1)
-        pin = self.app['accesscodes']['HOS-0'].keys()[0]
-        ac = self.app['accesscodes']['HOS-0'][pin]
-        self.assertEqual(ac.owner, self.student_id)
-        parts = pin.split('-')[1:]
-        sfeseries, sfenumber = parts
-        # Managers can use HOS code and book a bed space with it
-        self.browser.open(self.acco_path)
-        self.browser.getLink("Book accommodation").click()
-        self.assertMatches('...You are in the wrong...',
-                           self.browser.contents)
-        IWorkflowInfo(self.student).fireTransition('admit')
-        # An existing HOS code can only be used if students
-        # are in accommodation session
-        self.student['studycourse'].current_session = 2003
-        self.browser.getLink("Book accommodation").click()
-        self.assertMatches('...Your current session does not match...',
-                           self.browser.contents)
-        self.student['studycourse'].current_session = 2004
-        # All requirements are met and ticket can be created
-        self.browser.getLink("Book accommodation").click()
-        self.assertMatches('...Activation Code:...',
-                           self.browser.contents)
-        self.browser.getControl(name="ac_series").value = sfeseries
-        self.browser.getControl(name="ac_number").value = sfenumber
-        self.browser.getControl("Create bed ticket").click()
-        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
-                           self.browser.contents)
-        # Bed has been allocated
-        bed1 = self.app['hostels']['hall-1']['hall-1_A_101_A']
-        self.assertTrue(bed1.owner == self.student_id)
-        # BedTicketAddPage is now blocked
-        self.browser.getLink("Book accommodation").click()
-        self.assertMatches('...You already booked a bed space...',
-            self.browser.contents)
-        # The bed ticket displays the data correctly
-        self.browser.open(self.acco_path + '/2004')
-        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
-                           self.browser.contents)
-        self.assertMatches('...2004/2005...', self.browser.contents)
-        self.assertMatches('...regular_male_fr...', self.browser.contents)
-        self.assertMatches('...%s...' % pin, self.browser.contents)
-        # Managers can relocate students if the student's bed_type has changed
-        self.browser.getLink("Relocate student").click()
-        self.assertMatches(
-            "...Student can't be relocated...", self.browser.contents)
-        self.student.sex = u'f'
-        self.browser.getLink("Relocate student").click()
-        self.assertMatches(
-            "...Hall 1, Block A, Room 101, Bed B...", self.browser.contents)
-        self.assertTrue(bed1.owner == NOT_OCCUPIED)
-        bed2 = self.app['hostels']['hall-1']['hall-1_A_101_B']
-        self.assertTrue(bed2.owner == self.student_id)
-        self.assertTrue(self.student['accommodation'][
-            '2004'].bed_type == u'regular_female_fr')
-        # The payment object still shows the original payment item
-        payment_id = self.student['payments'].keys()[0]
-        payment = self.student['payments'][payment_id]
-        self.assertTrue(payment.p_item == u'regular_male_fr')
-        # Managers can relocate students if the bed's bed_type has changed
-        bed1.bed_type = u'regular_female_fr'
-        bed2.bed_type = u'regular_male_fr'
-        notify(grok.ObjectModifiedEvent(bed1))
-        notify(grok.ObjectModifiedEvent(bed2))
-        self.browser.getLink("Relocate student").click()
-        self.assertMatches(
-            "...Student relocated...", self.browser.contents)
-        self.assertMatches(
-            "... Hall 1, Block A, Room 101, Bed A...", self.browser.contents)
-        self.assertMatches(bed1.owner, self.student_id)
-        self.assertMatches(bed2.owner, NOT_OCCUPIED)
-        # Managers can't relocate students if bed is reserved
-        self.student.sex = u'm'
-        bed1.bed_type = u'regular_female_reserved'
-        notify(grok.ObjectModifiedEvent(bed1))
-        self.browser.getLink("Relocate student").click()
-        self.assertMatches(
-            "...Students in reserved beds can't be relocated...",
-            self.browser.contents)
-        # Managers can relocate students if booking has been cancelled but
-        # other bed space has been manually allocated after cancellation
-        old_owner = bed1.releaseBed()
-        self.assertMatches(old_owner, self.student_id)
-        bed2.owner = self.student_id
-        self.browser.open(self.acco_path + '/2004')
-        self.assertMatches(
-            "...booking cancelled...", self.browser.contents)
-        self.browser.getLink("Relocate student").click()
-        # We didn't informed the catalog therefore the new owner is not found
-        self.assertMatches(
-            "...There is no free bed in your category regular_male_fr...",
-            self.browser.contents)
-        # Now we fire the event properly
-        notify(grok.ObjectModifiedEvent(bed2))
-        self.browser.getLink("Relocate student").click()
-        self.assertMatches(
-            "...Student relocated...", self.browser.contents)
-        self.assertMatches(
-            "... Hall 1, Block A, Room 101, Bed B...", self.browser.contents)
-          # Managers can delete bed tickets
-        self.browser.open(self.acco_path)
-        ctrl = self.browser.getControl(name='val_id')
-        value = ctrl.options[0]
-        ctrl.getControl(value=value).selected = True
-        self.browser.getControl("Remove selected", index=0).click()
-        self.assertMatches('...Successfully removed...', self.browser.contents)
-        # The bed has been properly released by the event handler
-        self.assertMatches(bed1.owner, NOT_OCCUPIED)
-        self.assertMatches(bed2.owner, NOT_OCCUPIED)
-        return
-
     def test_student_accommodation(self):
         # Login
@@ -2091,182 +2234,4 @@
         self.browser.getControl("Send login credentials").click()
         self.assertTrue('An email with' in self.browser.contents)
-
-    def test_change_current_mode(self):
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.clearance_path)
-        self.assertFalse('Employer' in self.browser.contents)
-        self.browser.open(self.manage_clearance_path)
-        self.assertFalse('Employer' in self.browser.contents)
-        self.student.clearance_locked = False
-        self.browser.open(self.edit_clearance_path)
-        self.assertFalse('Employer' in self.browser.contents)
-        # Now we change the study mode of the certificate and a different
-        # interface is used by clearance views.
-        self.certificate.study_mode = 'pg_ft'
-        # Invariants are not being checked here?!
-        self.certificate.end_level = 100
-        self.browser.open(self.clearance_path)
-        self.assertTrue('Employer' in self.browser.contents)
-        self.browser.open(self.manage_clearance_path)
-        self.assertTrue('Employer' in self.browser.contents)
-        self.browser.open(self.edit_clearance_path)
-        self.assertTrue('Employer' in self.browser.contents)
-
-    def test_activate_deactivate_buttons(self):
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.student_path)
-        self.browser.getLink("Deactivate").click()
-        self.assertTrue(
-            'Student account has been deactivated.' in self.browser.contents)
-        self.assertTrue(
-            'Base Data (account deactivated)' in self.browser.contents)
-        self.assertTrue(self.student.suspended)
-        self.browser.getLink("Activate").click()
-        self.assertTrue(
-            'Student account has been activated.' in self.browser.contents)
-        self.assertFalse(
-            'Base Data (account deactivated)' in self.browser.contents)
-        self.assertFalse(self.student.suspended)
-        # History messages have been added ...
-        self.browser.getLink("History").click()
-        self.assertTrue(
-            'Student account deactivated by Manager<br />' in self.browser.contents)
-        self.assertTrue(
-            'Student account activated by Manager<br />' in self.browser.contents)
-        # ... and actions have been logged.
-        logfile = os.path.join(
-            self.app['datacenter'].storage, 'logs', 'students.log')
-        logcontent = open(logfile).read()
-        self.assertTrue('zope.mgr - students.browser.StudentDeactivatePage - '
-                        'K1000000 - account deactivated' in logcontent)
-        self.assertTrue('zope.mgr - students.browser.StudentActivatePage - '
-                        'K1000000 - account activated' in logcontent)
-
-    def test_student_locked_level_forms(self):
-
-        # Add two study levels, one current and one previous
-        studylevel = createObject(u'waeup.StudentStudyLevel')
-        studylevel.level = 100
-        self.student['studycourse'].addStudentStudyLevel(
-            self.certificate, studylevel)
-        studylevel = createObject(u'waeup.StudentStudyLevel')
-        studylevel.level = 200
-        self.student['studycourse'].addStudentStudyLevel(
-            self.certificate, studylevel)
-        IWorkflowState(self.student).setState('school fee paid')
-        self.student['studycourse'].current_level = 200
-
-        self.browser.open(self.login_path)
-        self.browser.getControl(name="form.login").value = self.student_id
-        self.browser.getControl(name="form.password").value = 'spwd'
-        self.browser.getControl("Login").click()
-
-        self.browser.open(self.student_path + '/studycourse/200/edit')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse/100/edit')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/200/ctadd')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse/100/ctadd')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        IWorkflowState(self.student).setState('courses registered')
-        self.browser.open(self.student_path + '/studycourse/200/edit')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse/200/ctadd')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-
-    def test_manage_student_transfer(self):
-        # Add second certificate
-        self.certificate2 = createObject('waeup.Certificate')
-        self.certificate2.code = u'CERT2'
-        self.certificate2.study_mode = 'ug_ft'
-        self.certificate2.start_level = 999
-        self.certificate2.end_level = 999
-        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
-            self.certificate2)
-
-        # Add study level to old study course
-        studylevel = createObject(u'waeup.StudentStudyLevel')
-        studylevel.level = 200
-        self.student['studycourse'].addStudentStudyLevel(
-            self.certificate, studylevel)
-        studylevel = createObject(u'waeup.StudentStudyLevel')
-        studylevel.level = 999
-        self.student['studycourse'].addStudentStudyLevel(
-            self.certificate, studylevel)
-
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.student_path)
-        self.browser.getLink("Transfer").click()
-        self.browser.getControl(name="form.certificate").value = ['CERT2']
-        self.browser.getControl(name="form.current_session").value = ['2011']
-        self.browser.getControl(name="form.current_level").value = ['200']
-        self.browser.getControl("Transfer").click()
-        self.assertTrue(
-            'Current level does not match certificate levels'
-            in self.browser.contents)
-        self.browser.getControl(name="form.current_level").value = ['999']
-        self.browser.getControl("Transfer").click()
-        self.assertTrue('Successfully transferred' in self.browser.contents)
-        # The catalog has been updated
-        cat = queryUtility(ICatalog, name='students_catalog')
-        results = list(
-            cat.searchResults(
-            certcode=('CERT2', 'CERT2')))
-        self.assertTrue(results[0] is self.student)
-        results = list(
-            cat.searchResults(
-            current_session=(2011, 2011)))
-        self.assertTrue(results[0] is self.student)
-        # Add study level to new study course
-        studylevel = createObject(u'waeup.StudentStudyLevel')
-        studylevel.level = 999
-        self.student['studycourse'].addStudentStudyLevel(
-            self.certificate, studylevel)
-
-        # Edit and add pages are locked for old study courses
-        self.browser.open(self.student_path + '/studycourse/manage')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/manage')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/start_session')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/start_session')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        IWorkflowState(self.student).setState('school fee paid')
-        self.browser.open(self.student_path + '/studycourse/add')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/add')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/999/manage')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/999/manage')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/999/validate_courses')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/999/validate_courses')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/999/reject_courses')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/999/reject_courses')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/999/add')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/999/add')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
-
-        self.browser.open(self.student_path + '/studycourse/999/edit')
-        self.assertFalse('The requested form is locked' in self.browser.contents)
-        self.browser.open(self.student_path + '/studycourse_1/999/edit')
-        self.assertTrue('The requested form is locked' in self.browser.contents)
 
 class StudentRequestPWTests(StudentsFullSetup):
@@ -2330,2 +2295,37 @@
                         '234 (K1000000) - new@yy.zz' in logcontent)
         return
+
+    def test_student_locked_level_forms(self):
+
+        # Add two study levels, one current and one previous
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 100
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 200
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+        IWorkflowState(self.student).setState('school fee paid')
+        self.student['studycourse'].current_level = 200
+
+        self.browser.open(self.login_path)
+        self.browser.getControl(name="form.login").value = self.student_id
+        self.browser.getControl(name="form.password").value = 'spwd'
+        self.browser.getControl("Login").click()
+
+        self.browser.open(self.student_path + '/studycourse/200/edit')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse/100/edit')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        self.browser.open(self.student_path + '/studycourse/200/ctadd')
+        self.assertFalse('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse/100/ctadd')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+
+        IWorkflowState(self.student).setState('courses registered')
+        self.browser.open(self.student_path + '/studycourse/200/edit')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
+        self.browser.open(self.student_path + '/studycourse/200/ctadd')
+        self.assertTrue('The requested form is locked' in self.browser.contents)
