source: main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py @ 9395

Last change on this file since 9395 was 9395, checked in by Henrik Bettermann, 12 years ago

Do not require second sitting scan.

  • Property svn:keywords set to Id
File size: 27.9 KB
Line 
1## $Id: test_browser.py 9395 2012-10-23 14:22:17Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import os
19import shutil
20import tempfile
21from StringIO import StringIO
22from hurry.workflow.interfaces import IWorkflowState, IWorkflowInfo
23from zope.securitypolicy.interfaces import IPrincipalRoleManager
24from zope.component.hooks import setSite, clearSite
25from zope.component import getUtility, createObject
26from zope.interface import verify
27from zope.event import notify
28from waeup.kofa.authentication import LocalRoleSetEvent
29from waeup.kofa.app import University
30from waeup.kofa.students.tests.test_browser import StudentsFullSetup
31from waeup.kofa.testing import FunctionalTestCase
32from waeup.kofa.interfaces import (
33    IExtFileStore, IFileStoreNameChooser)
34from waeup.kofa.students.interfaces import IStudentsUtils
35from waeup.uniben.testing import FunctionalLayer
36
37
38class StudentProcessorTest(FunctionalTestCase):
39    """Perform some batching tests.
40    """
41
42    layer = FunctionalLayer
43
44    def setUp(self):
45        super(StudentProcessorTest, self).setUp()
46        # Setup a sample site for each test
47        app = University()
48        self.dc_root = tempfile.mkdtemp()
49        app['datacenter'].setStoragePath(self.dc_root)
50
51        # Prepopulate the ZODB...
52        self.getRootFolder()['app'] = app
53        # we add the site immediately after creation to the
54        # ZODB. Catalogs and other local utilities are not setup
55        # before that step.
56        self.app = self.getRootFolder()['app']
57        # Set site here. Some of the following setup code might need
58        # to access grok.getSite() and should get our new app then
59        setSite(app)
60
61
62    def tearDown(self):
63        super(StudentProcessorTest, self).tearDown()
64        shutil.rmtree(self.workdir)
65        shutil.rmtree(self.dc_root)
66        clearSite()
67        return
68
69class StudentUITests(StudentsFullSetup):
70    """Tests for customized student class views and pages
71    """
72
73    layer = FunctionalLayer
74
75    def test_next_session_allowed(self):
76        # Let's see if next_session_allowed works as expected
77        # A, ug_ft, 100
78        IWorkflowState(self.student).setState('returning')
79        self.assertTrue(self.student['studycourse'].next_session_allowed)
80        # Uniben special PG programmes have the same workflow
81        # as UG students
82        self.certificate.study_mode = 'special_pg_pt'
83        self.assertTrue(self.student['studycourse'].next_session_allowed)
84        IWorkflowState(self.student).setState('school fee paid')
85        self.assertFalse(self.student['studycourse'].next_session_allowed)
86        # Now we convert the certificate into a 'regular
87        # postgraduate certificate ...
88        self.certificate.study_mode = 'pg_ft'
89        # ... and voila next session registration is allowed
90        self.assertTrue(self.student['studycourse'].next_session_allowed)
91
92    def test_manage_access(self):
93        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
94        # The student created in the base package is a ug student
95        self.browser.open(self.manage_clearance_path)
96        self.assertMatches('...First Sitting Record...',
97                           self.browser.contents)
98        # There is no pg field in the clearance form
99        self.assertFalse('Second Higher Education Record'
100            in self.browser.contents)
101        # Now we change the study mode ...
102        self.certificate.study_mode = 'pg_ft'
103        self.browser.open(self.clearance_path)
104        # ... and additional pg clearance fields appear
105        self.assertMatches('...Second Higher Education Record...',
106                           self.browser.contents)
107        # But also fields from the ug form are displayed
108        self.assertMatches('...First Sitting Record...',
109                           self.browser.contents)
110        # The same holds for Uniben's special pg students
111        self.certificate.study_mode = 'special_pg_ft'
112        self.browser.open(self.clearance_path)
113        self.assertMatches('...Second Higher Education Record...',
114                           self.browser.contents)
115        self.assertMatches('...First Sitting Record...',
116                           self.browser.contents)
117
118    def test_student_access(self):
119        # Students can edit clearance data
120        IWorkflowState(self.student).setState('clearance started')
121        self.student.clearance_locked = False
122        self.student.nationality = u'NG'
123        file_store = getUtility(IExtFileStore)
124        self.browser.open(self.login_path)
125        self.browser.getControl(name="form.login").value = self.student_id
126        self.browser.getControl(name="form.password").value = 'spwd'
127        self.browser.getControl("Login").click()
128        self.browser.open(self.edit_clearance_path)
129
130        # Clearance can only be requested if all required documents
131        # have been uploaded.
132        self.browser.getControl("Save and request clearance").click()
133        self.assertTrue('No birth certificate uploaded'
134            in self.browser.contents)
135        birth_certificate = 'My birth certificate'
136        file_id = IFileStoreNameChooser(self.student).chooseName(
137            attr="birth_certificate.jpg")
138        file_store.createFile(file_id, StringIO(birth_certificate))
139        self.browser.open(self.edit_clearance_path)
140        self.browser.getControl("Save and request clearance").click()
141
142        self.assertTrue('No guarantor/referee letter uploaded'
143            in self.browser.contents)
144        ref_let = 'My ref let'
145        file_id = IFileStoreNameChooser(self.student).chooseName(
146            attr="ref_let.jpg")
147        file_store.createFile(file_id, StringIO(ref_let))
148        self.browser.open(self.edit_clearance_path)
149        self.browser.getControl("Save and request clearance").click()
150
151        self.assertTrue('No acceptance letter uploaded'
152            in self.browser.contents)
153        acc_let = 'My acc let'
154        file_id = IFileStoreNameChooser(self.student).chooseName(
155            attr="acc_let.jpg")
156        file_store.createFile(file_id, StringIO(acc_let))
157        self.browser.open(self.edit_clearance_path)
158        self.browser.getControl("Save and request clearance").click()
159
160        self.assertTrue('No first sitting result uploaded'
161            in self.browser.contents)
162        fst_sit_scan = 'My first sitting result'
163        file_id = IFileStoreNameChooser(self.student).chooseName(
164            attr="fst_sit_scan.jpg")
165        file_store.createFile(file_id, StringIO(fst_sit_scan))
166        self.browser.open(self.edit_clearance_path)
167        self.browser.getControl("Save and request clearance").click()
168
169        #self.assertTrue('No second sitting result uploaded'
170        #    in self.browser.contents)
171        #scd_sit_scan = 'My second sitting result'
172        #file_id = IFileStoreNameChooser(self.student).chooseName(
173        #    attr="scd_sit_scan.jpg")
174        #file_store.createFile(file_id, StringIO(scd_sit_scan))
175        #self.browser.open(self.edit_clearance_path)
176        #self.browser.getControl("Save and request clearance").click()
177
178        self.assertTrue('No affidavit of non-menbership of secret cults uploaded'
179            in self.browser.contents)
180        secr_cults = 'My non-membership scan'
181        file_id = IFileStoreNameChooser(self.student).chooseName(
182            attr="secr_cults.jpg")
183        file_store.createFile(file_id, StringIO(secr_cults))
184        self.browser.open(self.edit_clearance_path)
185        self.browser.getControl("Save and request clearance").click()
186
187        self.assertTrue('Clearance has been requested'
188            in self.browser.contents)
189
190    def test_manage_payments(self):
191        # Add missing configuration data
192        self.app['configuration']['2004'].gown_fee = 150.0
193        self.app['configuration']['2004'].transfer_fee = 90.0
194        #self.app['configuration']['2004'].clearance_fee = 120.0
195        self.app['configuration']['2004'].booking_fee = 150.0
196        self.app['configuration']['2004'].maint_fee = 180.0
197
198        # Managers can add online payment tickets
199        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
200        self.browser.open(self.payments_path)
201        self.browser.getControl("Add online payment ticket").click()
202        self.browser.getControl("Create ticket").click()
203        self.assertMatches('...Amount could not be determined...',
204                           self.browser.contents)
205        IWorkflowState(self.student).setState('cleared')
206        self.student.nationality = u'NG'
207        self.browser.open(self.payments_path + '/addop')
208        self.browser.getControl("Create ticket").click()
209        self.assertMatches('...ticket created...',
210                           self.browser.contents)
211        ctrl = self.browser.getControl(name='val_id')
212        value = ctrl.options[0]
213        self.browser.getLink(value).click()
214        self.assertMatches('...Amount Authorized...',
215                           self.browser.contents)
216        # Managers can open payment slip
217        self.browser.getLink("Download payment slip").click()
218        self.assertEqual(self.browser.headers['Status'], '200 Ok')
219        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
220        # Set ticket paid
221        ticket = self.student['payments'].items()[0][1]
222        ticket.p_state = 'paid'
223        self.browser.open(self.payments_path + '/addop')
224        self.browser.getControl("Create ticket").click()
225        self.assertMatches('...This type of payment has already been made...',
226                           self.browser.contents)
227        # Remove all payments so that we can add a school fee payment again
228        keys = [i for i in self.student['payments'].keys()]
229        for payment in keys:
230            del self.student['payments'][payment]
231        self.browser.open(self.payments_path + '/addop')
232        self.browser.getControl("Create ticket").click()
233        self.assertMatches('...ticket created...',
234                           self.browser.contents)
235        self.browser.open(self.payments_path + '/addop')
236        self.browser.getControl(name="form.p_category").value = ['gown']
237        self.browser.getControl("Create ticket").click()
238        self.assertMatches('...ticket created...',
239                           self.browser.contents)
240        self.browser.open(self.payments_path + '/addop')
241        self.browser.getControl(name="form.p_category").value = ['transfer']
242        self.browser.getControl("Create ticket").click()
243        self.assertMatches('...ticket created...',
244                           self.browser.contents)
245        self.browser.open(self.payments_path + '/addop')
246        self.browser.getControl(
247            name="form.p_category").value = ['bed_allocation']
248        self.browser.getControl("Create ticket").click()
249        self.assertMatches('...ticket created...',
250                           self.browser.contents)
251        self.browser.open(self.payments_path + '/addop')
252        self.browser.getControl(
253            name="form.p_category").value = ['hostel_maintenance']
254        self.browser.getControl("Create ticket").click()
255        self.assertMatches('...ticket created...',
256                           self.browser.contents)
257        self.browser.open(self.payments_path + '/addop')
258        self.browser.getControl(name="form.p_category").value = ['clearance']
259        self.browser.getControl("Create ticket").click()
260        self.assertMatches('...ticket created...',
261                           self.browser.contents)
262        self.browser.open(self.payments_path + '/addop')
263        self.browser.getControl(name="form.p_category").value = ['schoolfee']
264        self.browser.getControl("Create ticket").click()
265        self.assertMatches('...ticket created...',
266                           self.browser.contents)
267        # In state returning we can add a new school fee ticket since
268        # p_session and p_level is different
269        IWorkflowState(self.student).setState('returning')
270        self.browser.open(self.payments_path + '/addop')
271        self.browser.getControl(name="form.p_category").value = ['schoolfee']
272        self.browser.getControl("Create ticket").click()
273        self.assertMatches('...Session configuration object is not...',
274                           self.browser.contents)
275        # Uups, we forgot to add a session configuration for next session
276        configuration = createObject('waeup.SessionConfiguration')
277        configuration.academic_session = 2005
278        self.app['configuration'].addSessionConfiguration(configuration)
279        self.browser.open(self.payments_path + '/addop')
280        self.browser.getControl(name="form.p_category").value = ['schoolfee']
281        self.browser.getControl("Create ticket").click()
282        self.assertMatches('...ticket created...',
283                           self.browser.contents)
284        # In state admitted school fee can't be determined
285        IWorkflowState(self.student).setState('admitted')
286        self.browser.open(self.payments_path + '/addop')
287        self.browser.getControl(name="form.p_category").value = ['schoolfee']
288        self.browser.getControl("Create ticket").click()
289        self.assertMatches('...Amount could not be determined...',
290                           self.browser.contents)
291
292        # If the session configuration doesn't exist an error message will
293        # be shown. No other requirement is being checked.
294        del self.app['configuration']['2004']
295        self.browser.open(self.payments_path)
296        self.browser.getControl("Add online payment ticket").click()
297        self.browser.getControl("Create ticket").click()
298        self.assertMatches('...Session configuration object is not...',
299                           self.browser.contents)
300
301    def test_get_returning_data(self):
302        # Student is in level 100, session 2004 with verdict A
303        utils = getUtility(IStudentsUtils)
304        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
305        self.student['studycourse'].current_verdict = 'C'
306        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
307        self.student['studycourse'].current_verdict = 'D'
308        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
309        return
310
311    def test_set_returning_data(self):
312        # Student is in level 100, session 2004 with verdict A
313        utils = getUtility(IStudentsUtils)
314
315        utils.setReturningData(self.student)
316        self.assertEqual(self.student['studycourse'].current_session, 2005)
317        self.assertEqual(self.student['studycourse'].current_level, 200)
318
319        self.student['studycourse'].current_session = 2004
320        self.student['studycourse'].current_level = 100
321        self.student['studycourse'].current_verdict = 'C'
322        utils.setReturningData(self.student)
323        self.assertEqual(self.student['studycourse'].current_session, 2005)
324        self.assertEqual(self.student['studycourse'].current_level, 110)
325
326        self.student['studycourse'].current_session = 2004
327        self.student['studycourse'].current_level = 100
328        self.student['studycourse'].current_verdict = 'D'
329        utils.setReturningData(self.student)
330        self.assertEqual(self.student['studycourse'].current_session, 2005)
331        self.assertEqual(self.student['studycourse'].current_level, 100)
332        return
333
334    def test_set_payment_details(self):
335        self.app['configuration']['2004'].gown_fee = 150.0
336        self.app['configuration']['2004'].transfer_fee = 90.0
337        self.app['configuration']['2004'].booking_fee = 150.0
338        self.app['configuration']['2004'].maint_fee = 180.0
339
340        configuration = createObject('waeup.SessionConfiguration')
341        configuration.academic_session = 2000
342        self.app['configuration'].addSessionConfiguration(configuration)
343        configuration2 = createObject('waeup.SessionConfiguration')
344        configuration2.academic_session = 2002
345        self.app['configuration'].addSessionConfiguration(configuration2)
346        configuration3 = createObject('waeup.SessionConfiguration')
347        configuration3.academic_session = 2003
348        self.app['configuration'].addSessionConfiguration(configuration3)
349
350        utils = getUtility(IStudentsUtils)
351
352        self.student['studycourse'].entry_session = 2002
353        self.student.nationality = u'NG'
354
355        configuration = createObject('waeup.SessionConfiguration')
356        configuration.academic_session = 2005
357        self.app['configuration'].addSessionConfiguration(configuration)
358
359        error, payment = utils.setPaymentDetails('schoolfee',
360            self.student, None, None)
361        self.assertEqual(payment, None)
362        self.assertTrue(u'Amount could not be determined.' in error)
363
364        # Previous session must be valid.
365        error, payment = utils.setPaymentDetails('schoolfee',
366            self.student, 2000, 300)
367        self.assertEqual(payment, None)
368        self.assertTrue(u'The previous session must not fall below' in error)
369        error, payment = utils.setPaymentDetails('schoolfee',
370            self.student, 2004, 300)
371        self.assertEqual(payment, None)
372        self.assertTrue(u'This is not a previous session' in error)
373
374        # Previous session payment; fresh and returning
375        # are distinguished by their entry_level
376        error, payment = utils.setPaymentDetails('schoolfee',
377            self.student, 2002, 300)
378        self.assertEqual(payment.amount_auth, 40000.0)
379        self.assertEqual(payment.p_session, 2002)
380        self.assertEqual(payment.p_level, 300)
381        self.assertFalse(payment.p_current)
382        error, payment = utils.setPaymentDetails('schoolfee',
383            self.student, 2003, 300)
384        self.assertEqual(payment.amount_auth, 20000.0)
385        self.assertEqual(payment.p_session, 2003)
386        self.assertEqual(payment.p_level, 300)
387        self.assertFalse(payment.p_current)
388
389        # Current payment; fresh and returning
390        # are distinguished by their state
391        IWorkflowState(self.student).setState('cleared')
392        error, payment = utils.setPaymentDetails('schoolfee',
393            self.student, None, None)
394        self.assertEqual(payment.p_level, 100)
395        self.assertEqual(payment.p_session, 2004)
396        self.assertEqual(payment.amount_auth, 40000.0)
397        self.assertEqual(payment.p_item, u'CERT1')
398        self.assertEqual(error, None)
399        self.assertTrue(payment.p_current)
400
401        # Add penalty fee ...
402        # ... for cleared
403        self.app['configuration']['2004'].penalty_ug = 99.0
404        # ... for returning
405        self.app['configuration']['2005'].penalty_ug = 88.0
406        error, payment = utils.setPaymentDetails('schoolfee',
407            self.student, None, None)
408        self.assertEqual(payment.amount_auth, 40099.0)
409
410        IWorkflowState(self.student).setState('returning')
411        error, payment = utils.setPaymentDetails('schoolfee',
412            self.student, None, None)
413        self.assertEqual(payment.p_level, 200)
414        self.assertEqual(payment.p_session, 2005)
415        self.assertEqual(payment.amount_auth, 20088.0)
416        self.assertEqual(payment.p_item, u'CERT1')
417        self.assertEqual(error, None)
418        self.student.is_staff = True
419        error, payment = utils.setPaymentDetails('schoolfee',
420            self.student, None, None)
421        self.assertEqual(payment.p_level, 200)
422        self.assertEqual(payment.p_session, 2005)
423        self.assertEqual(payment.amount_auth, 10088.0)
424        self.assertEqual(payment.p_item, u'CERT1')
425        self.assertEqual(error, None)
426
427        IWorkflowState(self.student).setState('cleared')
428        self.student.is_staff = False
429        self.student.nationality = u'DE'
430        self.certificate.school_fee_3 = 60000.0
431        error, payment = utils.setPaymentDetails(
432            'schoolfee', self.student, None, None)
433        self.assertEqual(payment.p_level, 100)
434        self.assertEqual(payment.p_session, 2004)
435        self.assertEqual(payment.amount_auth, 60099.0)
436        self.assertEqual(payment.p_item, u'CERT1')
437        self.assertEqual(error, None)
438
439        IWorkflowState(self.student).setState('returning')
440        self.student.is_staff = False
441        self.student.nationality = u'DE'
442        self.certificate.school_fee_4 = 20000.0
443        error, payment = utils.setPaymentDetails(
444            'schoolfee', self.student, None, None)
445        self.assertEqual(payment.p_level, 200)
446        self.assertEqual(payment.p_session, 2005)
447        self.assertEqual(payment.amount_auth, 20088.0)
448        self.assertEqual(payment.p_item, u'CERT1')
449        self.assertEqual(error, None)
450
451        # In Uniben we have pg and special pg students.
452        # They pay the same but their workflow is different.
453        IWorkflowState(self.student).setState('school fee paid')
454        self.student.is_staff = False
455        self.student.nationality = u'NG'
456        self.certificate.school_fee_2 = 10000.0
457        error, payment = utils.setPaymentDetails(
458            'schoolfee', self.student, None, None)
459        self.assertEqual(payment, None)
460        self.assertTrue('not be determined' in error)
461        self.certificate.study_mode = 'pg_pt'
462        self.assertTrue(self.student.is_postgrad)
463        self.assertFalse(self.student.is_special_postgrad)
464        error, payment = utils.setPaymentDetails(
465            'schoolfee', self.student, None, None)
466        self.assertEqual(payment.p_level, 100)
467        self.assertEqual(payment.p_session, 2005)
468        self.assertEqual(payment.amount_auth, 10000.0)
469        self.assertEqual(payment.p_item, u'CERT1')
470        self.assertEqual(error, None)
471        self.certificate.study_mode = 'special_pg_pt'
472        self.assertTrue(self.student.is_postgrad)
473        self.assertTrue(self.student.is_special_postgrad)
474        error, payment = utils.setPaymentDetails(
475            'schoolfee', self.student, None, None)
476        self.assertTrue('not be determined' in error)
477        IWorkflowState(self.student).setState('returning')
478        error, payment = utils.setPaymentDetails(
479            'schoolfee', self.student, None, None)
480        self.assertEqual(payment.p_level, 200)
481        self.assertEqual(payment.p_session, 2005)
482        self.assertEqual(payment.amount_auth, 10000.0)
483        self.assertEqual(payment.p_item, u'CERT1')
484        self.assertEqual(error, None)
485
486        error, payment = utils.setPaymentDetails('clearance',
487            self.student, None, None)
488        self.assertEqual(payment.p_level, 100)
489        self.assertEqual(payment.p_session, 2004)
490        self.assertEqual(payment.amount_auth, 45000.0)
491        self.assertEqual(payment.p_item, u'CERT1')
492        self.assertEqual(error, None)
493
494        error, payment = utils.setPaymentDetails('gown',
495            self.student, None, None)
496        self.assertEqual(payment.p_level, 100)
497        self.assertEqual(payment.p_session, 2004)
498        self.assertEqual(payment.amount_auth, 150.0)
499        self.assertEqual(payment.p_item, u'')
500        self.assertEqual(error, None)
501
502        error, payment = utils.setPaymentDetails('hostel_maintenance',
503            self.student, None, None)
504        self.assertEqual(payment.p_level, 100)
505        self.assertEqual(payment.p_session, 2004)
506        self.assertEqual(payment.amount_auth, 180.0)
507        self.assertEqual(payment.p_item, u'')
508        self.assertEqual(error, None)
509
510        error, payment = utils.setPaymentDetails('bed_allocation',
511            self.student, None, None)
512        self.assertEqual(payment.p_level, 100)
513        self.assertEqual(payment.p_session, 2004)
514        self.assertEqual(payment.amount_auth, 150.0)
515        self.assertEqual(payment.p_item, u'')
516        self.assertEqual(error, None)
517
518        error, payment = utils.setPaymentDetails('transfer',
519            self.student, None, None)
520        self.assertEqual(payment.p_level, 100)
521        self.assertEqual(payment.p_session, 2004)
522        self.assertEqual(payment.amount_auth, 90.0)
523        self.assertEqual(payment.p_item, u'')
524        self.assertEqual(error, None)
525        return
526
527    def test_edit_level_by_co(self):
528        # Create clearance officer
529        self.app['users'].addUser('mrclear', 'mrclearsecret')
530        self.app['users']['mrclear'].email = 'mrclear@foo.ng'
531        self.app['users']['mrclear'].title = 'Carlo Pitter'
532        # Assign local ClearanceOfficer role
533        department = self.app['faculties']['fac1']['dep1']
534        prmlocal = IPrincipalRoleManager(department)
535        prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear')
536        notify(LocalRoleSetEvent(
537            department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
538        IWorkflowState(self.student).setState('clearance started')
539        # Login as clearance officer
540        self.browser.open(self.login_path)
541        self.browser.getControl(name="form.login").value = 'mrclear'
542        self.browser.getControl(name="form.password").value = 'mrclearsecret'
543        self.browser.getControl("Login").click()
544        self.assertMatches('...You logged in...', self.browser.contents)
545        # Only in state clearance requested the CO does see the
546        # 'Edit level' button ...
547        self.browser.open(self.studycourse_path)
548        self.assertFalse('Edit level' in self.browser.contents)
549        # ... and can open the edit_level view
550        self.browser.open(self.studycourse_path + '/edit_level')
551        self.assertMatches('...is locked...', self.browser.contents)
552        self.assertEqual(self.browser.url, self.studycourse_path)
553        IWorkflowInfo(self.student).fireTransition('request_clearance')
554        self.browser.open(self.studycourse_path)
555        self.assertTrue('Edit level' in self.browser.contents)
556        self.browser.getLink("Edit level").click()
557        self.browser.getControl(name="form.current_level").value = ['200']
558        self.browser.getControl("Save").click()
559        self.assertMatches('...has been saved...', self.browser.contents)
560        self.assertEqual(self.student.current_level, 200)
561
562    def test_postgraduate_student_access(self):
563        self.certificate.study_mode = 'special_pg_pt'
564        self.certificate.start_level = 700
565        self.certificate.end_level = 800
566        self.student['studycourse'].current_level = 700
567        IWorkflowState(self.student).setState('school fee paid')
568        self.browser.open(self.login_path)
569        self.browser.getControl(name="form.login").value = self.student_id
570        self.browser.getControl(name="form.password").value = 'spwd'
571        self.browser.getControl("Login").click()
572        self.assertTrue(
573            'You logged in.' in self.browser.contents)
574        # Now students can add the current study level
575        self.browser.getLink("Study Course").click()
576        self.browser.getLink("Add course list").click()
577        self.assertMatches('...Add current level 700...',
578                           self.browser.contents)
579        self.browser.getControl("Create course list now").click()
580        # A level with one course ticket was created
581        self.assertEqual(self.student['studycourse']['700'].number_of_tickets, 0)
582        self.browser.getLink("700").click()
583        self.browser.getLink("Edit course list").click()
584        self.browser.getControl("Add course ticket").click()
585        self.browser.getControl(name="form.course").value = ['COURSE1']
586        self.browser.getControl("Add course ticket").click()
587        self.assertMatches('...Successfully added COURSE1...',
588                           self.browser.contents)
589        # Special postgraduate students can register course lists
590        self.browser.getControl("Register course list").click()
591        self.assertMatches('...Course list has been registered...',
592            self.browser.contents)
593        self.assertEqual(self.student.state, 'courses registered')
594        return
Note: See TracBrowser for help on using the repository browser.