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

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

Log payment category.

Adjust to previous revisions.

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