Index: main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_browser.py
===================================================================
--- main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_browser.py	(revision 7326)
+++ main/waeup.sirp/trunk/src/waeup/sirp/students/tests/test_browser.py	(revision 7337)
@@ -36,4 +36,5 @@
 from waeup.sirp.configuration import SessionConfiguration
 from waeup.sirp.students.student import Student
+from waeup.sirp.students.studylevel import StudentStudyLevel
 from waeup.sirp.university.faculty import Faculty
 from waeup.sirp.university.department import Department
@@ -772,4 +773,107 @@
         self.assertTrue(self.student_id in self.browser.contents)
 
+    def test_handle_courses_by_ca(self):
+        # Create course adviser
+        self.app['users'].addUser('mrsadvise', 'mrsadvisesecret')
+        # Assign local CourseAdviser100 role for a certificate
+        cert = self.app['faculties']['fac1']['dep1'].certificates['CERT1']
+        prmlocal = IPrincipalRoleManager(cert)
+        prmlocal.assignRoleToPrincipal('waeup.local.CourseAdviser100', 'mrsadvise')
+        IWorkflowInfo(self.student).fireTransition('admit')
+        IWorkflowInfo(self.student).fireTransition('start_clearance')
+        IWorkflowInfo(self.student).fireTransition('request_clearance')
+        IWorkflowInfo(self.student).fireTransition('clear')
+        IWorkflowInfo(self.student).fireTransition('pay_first_school_fee')
+        # Login as course adviser
+        self.browser.open(self.login_path)
+        self.browser.getControl(name="form.login").value = 'mrsadvise'
+        self.browser.getControl(name="form.password").value = 'mrsadvisesecret'
+        self.browser.getControl("Login").click()
+        self.assertMatches('...You logged in...', self.browser.contents)
+        # CO can see his roles
+        self.browser.getLink("My Roles").click()
+        self.assertMatches(
+            '...<div>Academics Officer (view only)</div>...',
+            self.browser.contents)
+        # But not his local role ...
+        self.assertFalse('Course Adviser' in self.browser.contents)
+        # ... because we forgot to notify the certificate that the local role
+        # has changed
+        notify(LocalRoleSetEvent(
+            cert, 'waeup.local.CourseAdviser100', 'mrsadvise', granted=True))
+        self.browser.open('http://localhost/app/users/mrsadvise/my_roles')
+        self.assertTrue('Course Adviser 100L' in self.browser.contents)
+        self.assertMatches(
+            '...<a href="http://localhost/app/faculties/fac1/dep1/certificates/CERT1">...',
+            self.browser.contents)
+        # CA can view the student ...
+        self.browser.open(self.student_path)
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.url, self.student_path)
+        # ... but not other students
+        other_student = Student()
+        other_student.fullname = u'Dep2 Student'
+        self.app['students'].addStudent(other_student)
+        other_student_path = (
+            'http://localhost/app/students/%s' % other_student.student_id)
+        self.assertRaises(
+            Unauthorized, self.browser.open, other_student_path)
+        # We add study level 110 to the student's studycourse
+        studylevel = StudentStudyLevel()
+        studylevel.level = 110
+        self.student['studycourse'].addStudentStudyLevel(
+            cert,studylevel)
+        L110_student_path = self.studycourse_student_path + '/110'
+        # Only in state courses registered and only if the current level
+        # corresponds with the name of the study level object
+        # the 100L CA does see the 'Validate' button
+        self.browser.open(L110_student_path)
+        self.assertFalse('Validate' in self.browser.contents)
+        IWorkflowInfo(self.student).fireTransition('register_courses')
+        self.browser.open(L110_student_path)
+        self.assertFalse('Validate' in self.browser.contents)
+        self.student['studycourse'].current_level = 110
+        self.browser.open(L110_student_path)
+        self.assertTrue('Validate' in self.browser.contents)
+        # ... but a 100L CA does not see the button on other levels
+        studylevel2 = StudentStudyLevel()
+        studylevel2.level = 200
+        self.student['studycourse'].addStudentStudyLevel(
+            cert,studylevel2)
+        L200_student_path = self.studycourse_student_path + '/200'
+        self.browser.open(L200_student_path)
+        self.assertFalse('Validate' in self.browser.contents)
+        self.browser.open(L110_student_path)
+        self.browser.getLink("Validate courses").click()
+        self.assertTrue('Course list has been validated' in self.browser.contents)
+        self.assertTrue('State: <span>courses validated</span>' in self.browser.contents)
+        self.browser.getLink("Reject courses").click()
+        self.assertTrue('Course list request has been annulled'
+            in self.browser.contents)
+        urlmessage = 'Course+list+request+has+been+annulled'
+        self.assertEqual(self.browser.url, self.student_path +
+            '/contactstudent?subject=%s' % urlmessage)
+        self.assertTrue('State: <span>school fee paid</span>'
+            in self.browser.contents)
+        IWorkflowInfo(self.student).fireTransition('register_courses')
+        self.browser.open(L110_student_path)
+        self.browser.getLink("Reject courses").click()
+        self.assertTrue('Course list request has been rejected'
+            in self.browser.contents)
+        self.assertTrue('State: <span>school fee paid</span>'
+            in self.browser.contents)
+        # The CA can't validate courses if not in state
+        # courses registered
+        self.browser.open(L110_student_path + '/validate_courses')
+        self.assertTrue('Student is in the wrong state'
+            in self.browser.contents)
+        # The CA can go to his certificate throug the my_roles page
+        self.browser.open('http://localhost/app/users/mrsadvise/my_roles')
+        self.browser.getLink(
+            "http://localhost/app/faculties/fac1/dep1/certificates/CERT1").click()
+        # and view the list of students
+        self.browser.getLink("Show students").click()
+        self.assertTrue(self.student_id in self.browser.contents)
+
     def test_student_change_password(self):
         # Students can change the password
