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

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

Customize LoginPage?. Yesterday Uniben requested a feature to display suspended_comment when a deactivated student logs in. Today they want to remove this feature again. I leave the feature in the base package but customize it here.

  • Property svn:keywords set to Id
File size: 32.2 KB
Line 
1## $Id: test_browser.py 9709 2012-11-22 20:47:52Z 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        self.browser.open(self.student_path + '/clearance_slip.pdf')
129        self.assertEqual(self.browser.headers['Status'], '200 Ok')
130        self.assertEqual(self.browser.headers['Content-Type'],
131                         'application/pdf')
132
133    def test_student_access(self):
134        # Students can edit clearance data
135        IWorkflowState(self.student).setState('clearance started')
136        self.student.clearance_locked = False
137        self.student.nationality = u'NG'
138        file_store = getUtility(IExtFileStore)
139        self.browser.open(self.login_path)
140        self.browser.getControl(name="form.login").value = self.student_id
141        self.browser.getControl(name="form.password").value = 'spwd'
142        self.browser.getControl("Login").click()
143        self.browser.open(self.edit_clearance_path)
144
145        # Clearance can only be requested if all required documents
146        # have been uploaded.
147        self.browser.getControl("Save and request clearance").click()
148        self.assertTrue('No birth certificate uploaded'
149            in self.browser.contents)
150        birth_certificate = 'My birth certificate'
151        file_id = IFileStoreNameChooser(self.student).chooseName(
152            attr="birth_certificate.jpg")
153        file_store.createFile(file_id, StringIO(birth_certificate))
154        self.browser.open(self.edit_clearance_path)
155        self.browser.getControl("Save and request clearance").click()
156
157        self.assertTrue('No guarantor/referee letter uploaded'
158            in self.browser.contents)
159        ref_let = 'My ref let'
160        file_id = IFileStoreNameChooser(self.student).chooseName(
161            attr="ref_let.jpg")
162        file_store.createFile(file_id, StringIO(ref_let))
163        self.browser.open(self.edit_clearance_path)
164        self.browser.getControl("Save and request clearance").click()
165
166        self.assertTrue('No acceptance letter uploaded'
167            in self.browser.contents)
168        acc_let = 'My acc let'
169        file_id = IFileStoreNameChooser(self.student).chooseName(
170            attr="acc_let.jpg")
171        file_store.createFile(file_id, StringIO(acc_let))
172        self.browser.open(self.edit_clearance_path)
173        self.browser.getControl("Save and request clearance").click()
174
175        self.assertTrue('No first sitting result uploaded'
176            in self.browser.contents)
177        fst_sit_scan = 'My first sitting result'
178        file_id = IFileStoreNameChooser(self.student).chooseName(
179            attr="fst_sit_scan.jpg")
180        file_store.createFile(file_id, StringIO(fst_sit_scan))
181        self.browser.open(self.edit_clearance_path)
182        self.browser.getControl("Save and request clearance").click()
183
184        #self.assertTrue('No second sitting result uploaded'
185        #    in self.browser.contents)
186        #scd_sit_scan = 'My second sitting result'
187        #file_id = IFileStoreNameChooser(self.student).chooseName(
188        #    attr="scd_sit_scan.jpg")
189        #file_store.createFile(file_id, StringIO(scd_sit_scan))
190        #self.browser.open(self.edit_clearance_path)
191        #self.browser.getControl("Save and request clearance").click()
192
193        self.assertTrue('No affidavit of non-menbership of secret cults uploaded'
194            in self.browser.contents)
195        secr_cults = 'My non-membership scan'
196        file_id = IFileStoreNameChooser(self.student).chooseName(
197            attr="secr_cults.jpg")
198        file_store.createFile(file_id, StringIO(secr_cults))
199        self.browser.open(self.edit_clearance_path)
200        self.browser.getControl("Save and request clearance").click()
201
202        self.assertTrue('Clearance has been requested'
203            in self.browser.contents)
204
205    def test_manage_payments(self):
206        # Add missing configuration data
207        self.app['configuration']['2004'].gown_fee = 150.0
208        self.app['configuration']['2004'].transfer_fee = 90.0
209        #self.app['configuration']['2004'].clearance_fee = 120.0
210        self.app['configuration']['2004'].booking_fee = 150.0
211        self.app['configuration']['2004'].maint_fee = 180.0
212
213        # Managers can add online payment tickets
214        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
215        self.browser.open(self.payments_path)
216        self.browser.getLink("Add current session payment ticket").click()
217        self.browser.getControl("Create ticket").click()
218        self.assertMatches('...Amount could not be determined...',
219                           self.browser.contents)
220        IWorkflowState(self.student).setState('cleared')
221        self.student.nationality = u'NG'
222        self.browser.open(self.payments_path + '/addop')
223        self.browser.getControl("Create ticket").click()
224        self.assertMatches('...ticket created...',
225                           self.browser.contents)
226        ctrl = self.browser.getControl(name='val_id')
227        value = ctrl.options[0]
228        self.browser.getLink(value).click()
229        self.assertMatches('...Amount Authorized...',
230                           self.browser.contents)
231        # Managers can open payment slip
232        self.browser.getLink("Download payment slip").click()
233        self.assertEqual(self.browser.headers['Status'], '200 Ok')
234        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
235        # Set ticket paid
236        ticket = self.student['payments'].items()[0][1]
237        ticket.p_state = 'paid'
238        self.browser.open(self.payments_path + '/addop')
239        self.browser.getControl("Create ticket").click()
240        self.assertMatches('...This type of payment has already been made...',
241                           self.browser.contents)
242        # Remove all payments so that we can add a school fee payment again
243        keys = [i for i in self.student['payments'].keys()]
244        for payment in keys:
245            del self.student['payments'][payment]
246        self.browser.open(self.payments_path + '/addop')
247        self.browser.getControl("Create ticket").click()
248        self.assertMatches('...ticket created...',
249                           self.browser.contents)
250        schoolfee_ticket = self.student['payments'].values()[0]
251        self.browser.open(self.payments_path + '/addop')
252        self.browser.getControl(name="form.p_category").value = ['gown']
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(name="form.p_category").value = ['transfer']
258        self.browser.getControl("Create ticket").click()
259        self.assertMatches('...ticket created...',
260                           self.browser.contents)
261        self.browser.open(self.payments_path + '/addop')
262        self.browser.getControl(
263            name="form.p_category").value = ['bed_allocation']
264        self.browser.getControl("Create ticket").click()
265        self.assertMatches('...ticket created...',
266                           self.browser.contents)
267        self.browser.open(self.payments_path + '/addop')
268        self.browser.getControl(
269            name="form.p_category").value = ['hostel_maintenance']
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 = ['clearance']
275        self.browser.getControl("Create ticket").click()
276        self.assertMatches('...ticket created...',
277                           self.browser.contents)
278        self.browser.open(self.payments_path + '/addop')
279        self.browser.getControl(name="form.p_category").value = ['schoolfee']
280        self.browser.getControl("Create ticket").click()
281        self.assertMatches('...ticket created...',
282                           self.browser.contents)
283        # In state returning we can add a new school fee ticket since
284        # p_session and p_level is different
285        IWorkflowState(self.student).setState('returning')
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        # Uups, we forgot to add a session configuration for next session
290        self.assertMatches('...Session configuration object is not...',
291                           self.browser.contents)
292        configuration = createObject('waeup.SessionConfiguration')
293        configuration.academic_session = 2005
294        self.app['configuration'].addSessionConfiguration(configuration)
295        self.browser.open(self.payments_path + '/addop')
296        self.browser.getControl(name="form.p_category").value = ['schoolfee']
297        self.browser.getControl("Create ticket").click()
298
299
300        #self.assertMatches('...You have not yet paid your current/active session...',
301        #                   self.browser.contents)
302        ## Ok, let's pay the first schoolfee ticket.
303        #schoolfee_ticket.approve()
304        #self.browser.open(self.payments_path + '/addop')
305        #self.browser.getControl(name="form.p_category").value = ['schoolfee']
306        #self.browser.getControl("Create ticket").click()
307
308
309        self.assertMatches('...ticket created...',
310                           self.browser.contents)
311        # In state admitted school fee can't be determined
312        IWorkflowState(self.student).setState('admitted')
313        self.browser.open(self.payments_path + '/addop')
314        self.browser.getControl(name="form.p_category").value = ['schoolfee']
315        self.browser.getControl("Create ticket").click()
316        self.assertMatches('...Amount could not be determined...',
317                           self.browser.contents)
318
319        # If the session configuration doesn't exist an error message will
320        # be shown. No other requirement is being checked.
321        del self.app['configuration']['2004']
322        self.browser.open(self.payments_path)
323        self.browser.getLink("Add current session payment ticket").click()
324        self.browser.getControl("Create ticket").click()
325        self.assertMatches('...Session configuration object is not...',
326                           self.browser.contents)
327
328    def test_student_course_registration(self):
329        # Uniben students see grade instead of score on all level pages
330        # and on course ticket page.
331        IWorkflowState(self.student).setState('school fee paid')
332        self.browser.open(self.login_path)
333        self.browser.getControl(name="form.login").value = self.student_id
334        self.browser.getControl(name="form.password").value = 'spwd'
335        self.browser.getControl("Login").click()
336        # Now students can add the current study level
337        self.browser.getLink("Study Course").click()
338        self.browser.getLink("Add course list").click()
339        self.assertMatches('...Add current level 100 (Year 1)...',
340                           self.browser.contents)
341        self.browser.getControl("Create course list now").click()
342        # A level with one course ticket was created
343        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 1)
344        self.student['studycourse']['100']['COURSE1'].score = 55
345        self.browser.getLink("100").click()
346        # GPA has been properly calculated and is shown on the page
347        self.assertTrue('3.0' in self.browser.contents)
348        self.assertEqual(self.student['studycourse']['100'].gpa, 3.0)
349        # Score is not shown but grade
350        self.assertTrue('<th>Grade</th>' in self.browser.contents)
351        self.assertFalse('<th>Score</th>' in self.browser.contents)
352        self.browser.getLink("Edit course list").click()
353        self.assertTrue('<th>Grade</th>' in self.browser.contents)
354        self.assertFalse('<th>Score</th>' in self.browser.contents)
355        self.browser.getLink("COURSE1").click()
356        self.assertFalse('Score' in self.browser.contents)
357        # Students can open the customized pdf course registration slip
358        self.browser.open(self.student_path + '/studycourse/100')
359        self.browser.getLink("Download course registration slip").click()
360        self.assertEqual(self.browser.headers['Status'], '200 Ok')
361        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
362
363    def test_get_returning_data(self):
364        # Student is in level 100, session 2004 with verdict A
365        utils = getUtility(IStudentsUtils)
366        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
367        self.student['studycourse'].current_verdict = 'C'
368        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
369        self.student['studycourse'].current_verdict = 'D'
370        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
371        return
372
373    def test_set_returning_data(self):
374        # Student is in level 100, session 2004 with verdict A
375        utils = getUtility(IStudentsUtils)
376
377        utils.setReturningData(self.student)
378        self.assertEqual(self.student['studycourse'].current_session, 2005)
379        self.assertEqual(self.student['studycourse'].current_level, 200)
380
381        self.student['studycourse'].current_session = 2004
382        self.student['studycourse'].current_level = 100
383        self.student['studycourse'].current_verdict = 'C'
384        utils.setReturningData(self.student)
385        self.assertEqual(self.student['studycourse'].current_session, 2005)
386        self.assertEqual(self.student['studycourse'].current_level, 110)
387
388        self.student['studycourse'].current_session = 2004
389        self.student['studycourse'].current_level = 100
390        self.student['studycourse'].current_verdict = 'D'
391        utils.setReturningData(self.student)
392        self.assertEqual(self.student['studycourse'].current_session, 2005)
393        self.assertEqual(self.student['studycourse'].current_level, 100)
394        return
395
396    def test_set_payment_details(self):
397        self.app['configuration']['2004'].gown_fee = 150.0
398        self.app['configuration']['2004'].transfer_fee = 90.0
399        self.app['configuration']['2004'].booking_fee = 150.0
400        self.app['configuration']['2004'].maint_fee = 180.0
401
402        configuration = createObject('waeup.SessionConfiguration')
403        configuration.academic_session = 2000
404        self.app['configuration'].addSessionConfiguration(configuration)
405        configuration2 = createObject('waeup.SessionConfiguration')
406        configuration2.academic_session = 2002
407        self.app['configuration'].addSessionConfiguration(configuration2)
408        configuration3 = createObject('waeup.SessionConfiguration')
409        configuration3.academic_session = 2003
410        self.app['configuration'].addSessionConfiguration(configuration3)
411        configuration4 = createObject('waeup.SessionConfiguration')
412        configuration4.academic_session = 2005
413        self.app['configuration'].addSessionConfiguration(configuration4)
414        utils = getUtility(IStudentsUtils)
415        self.student['studycourse'].entry_session = 2002
416        self.student.nationality = u'NG'
417
418        error, payment = utils.setPaymentDetails('schoolfee',
419            self.student, None, None)
420        self.assertEqual(payment, None)
421        # Student is in state 'created' and can thus not pay.
422        self.assertTrue(u'Amount could not be determined.' in error)
423
424        # Previous session must be valid.
425        error, payment = utils.setPaymentDetails('schoolfee',
426            self.student, 2000, 300)
427        self.assertEqual(payment, None)
428        self.assertTrue(u'The previous session must not fall below' in error)
429        error, payment = utils.setPaymentDetails('schoolfee',
430            self.student, 2005, 300)
431        self.assertEqual(payment, None)
432        self.assertTrue(u'This is not a previous session' in error)
433
434        # Previous session schoolfee payment; fresh and returning
435        # are distinguished by their entry_level
436        error, payment = utils.setPaymentDetails('schoolfee',
437            self.student, 2002, 300)
438        self.assertEqual(payment.amount_auth, 40000.0)
439        self.assertEqual(payment.p_session, 2002)
440        self.assertEqual(payment.p_level, 300)
441        self.assertFalse(payment.p_current)
442        error, payment = utils.setPaymentDetails('schoolfee',
443            self.student, 2003, 300)
444        self.assertEqual(payment.amount_auth, 20000.0)
445        self.assertEqual(payment.p_session, 2003)
446        self.assertEqual(payment.p_level, 300)
447        self.assertFalse(payment.p_current)
448
449        # Current schoolfee payment; fresh and returning
450        # are distinguished by their state
451        IWorkflowState(self.student).setState('cleared')
452        error, payment = utils.setPaymentDetails('schoolfee',
453            self.student, None, None)
454        self.assertEqual(payment.p_level, 100)
455        self.assertEqual(payment.p_session, 2004)
456        self.assertEqual(payment.amount_auth, 40000.0)
457        self.assertEqual(payment.p_item, u'CERT1')
458        self.assertEqual(error, None)
459        self.assertTrue(payment.p_current)
460
461        # Add penalty fee ...
462        # ... for cleared
463        self.app['configuration']['2004'].penalty_ug = 99.0
464        # ... for returning
465        self.app['configuration']['2005'].penalty_ug = 88.0
466        error, payment = utils.setPaymentDetails('schoolfee',
467            self.student, None, None)
468        self.assertEqual(payment.amount_auth, 40099.0)
469
470        IWorkflowState(self.student).setState('returning')
471
472
473        #error, payment = utils.setPaymentDetails('schoolfee',
474        #    self.student, None, None)
475        #self.assertTrue(
476        #    u'You have not yet paid your current/active session.' in error)
477        ## Ok, that means we have to add paid payment ticket first.
478        #payment = createObject('waeup.StudentOnlinePayment')
479        #payment.p_category = u'schoolfee'
480        #payment.p_session = self.student.current_session
481        #payment.p_item = u'My Certificate'
482        #payment.p_id = u'anyid'
483        #payment.p_state = u'paid'
484        #self.student['payments']['anykey'] = payment
485
486
487        error, payment = utils.setPaymentDetails('schoolfee',
488            self.student, None, None)
489        self.assertEqual(payment.p_level, 200)
490        self.assertEqual(payment.p_session, 2005)
491        self.assertEqual(payment.amount_auth, 20088.0)
492        self.assertEqual(payment.p_item, u'CERT1')
493        self.assertEqual(error, None)
494
495        # Staff members pay less.
496        self.student.is_staff = True
497        error, payment = utils.setPaymentDetails('schoolfee',
498            self.student, None, None)
499        self.assertEqual(payment.p_level, 200)
500        self.assertEqual(payment.p_session, 2005)
501        self.assertEqual(payment.amount_auth, 10088.0)
502        self.assertEqual(payment.p_item, u'CERT1')
503        self.assertEqual(error, None)
504
505        # Foreigners pay more.
506        IWorkflowState(self.student).setState('cleared')
507        self.student.is_staff = False
508        self.student.nationality = u'DE'
509        self.certificate.school_fee_3 = 60000.0
510        error, payment = utils.setPaymentDetails(
511            'schoolfee', self.student, None, None)
512        self.assertEqual(payment.p_level, 100)
513        self.assertEqual(payment.p_session, 2004)
514        self.assertEqual(payment.amount_auth, 60099.0)
515        self.assertEqual(payment.p_item, u'CERT1')
516        self.assertEqual(error, None)
517        IWorkflowState(self.student).setState('returning')
518        self.student.is_staff = False
519        self.certificate.school_fee_4 = 20000.0
520        error, payment = utils.setPaymentDetails(
521            'schoolfee', self.student, None, None)
522        self.assertEqual(payment.p_level, 200)
523        self.assertEqual(payment.p_session, 2005)
524        self.assertEqual(payment.amount_auth, 20088.0)
525        self.assertEqual(payment.p_item, u'CERT1')
526        self.assertEqual(error, None)
527
528        # In Uniben students can pay school fee in all states no matter
529        # if they are ug or pg students.
530        IWorkflowState(self.student).setState('school fee paid')
531        self.student.is_staff = False
532        self.student.nationality = u'NG'
533        self.certificate.school_fee_2 = 10000.0
534        error, payment = utils.setPaymentDetails(
535            'schoolfee', self.student, None, None)
536        self.assertEqual(payment.p_level, None)
537        self.assertEqual(payment.p_session, 2005)
538        self.assertEqual(payment.amount_auth, 10088.0)
539        self.assertEqual(payment.p_item, u'CERT1')
540        self.assertEqual(error, None)
541        IWorkflowState(self.student).setState('courses registered')
542        self.certificate.study_mode = 'special_pg_pt'
543        error, payment = utils.setPaymentDetails(
544            'schoolfee', self.student, None, None)
545        self.assertEqual(payment.p_level, None)
546        self.assertEqual(payment.p_session, 2005)
547        self.assertEqual(payment.amount_auth, 10000.0)
548        self.assertEqual(payment.p_item, u'CERT1')
549        self.assertEqual(error, None)
550        IWorkflowState(self.student).setState('courses validated')
551        error, payment = utils.setPaymentDetails(
552            'schoolfee', self.student, None, None)
553        self.assertEqual(payment.p_level, None)
554        self.assertEqual(payment.p_session, 2005)
555        self.assertEqual(payment.amount_auth, 10000.0)
556        self.assertEqual(payment.p_item, u'CERT1')
557        self.assertEqual(error, None)
558
559        error, payment = utils.setPaymentDetails('clearance',
560            self.student, None, None)
561        self.assertEqual(payment.p_level, 100)
562        self.assertEqual(payment.p_session, 2004)
563        self.assertEqual(payment.amount_auth, 45000.0)
564        self.assertEqual(payment.p_item, u'CERT1')
565        self.assertEqual(error, None)
566
567        error, payment = utils.setPaymentDetails('gown',
568            self.student, None, None)
569        self.assertEqual(payment.p_level, 100)
570        self.assertEqual(payment.p_session, 2004)
571        self.assertEqual(payment.amount_auth, 150.0)
572        self.assertEqual(payment.p_item, u'')
573        self.assertEqual(error, None)
574
575        error, payment = utils.setPaymentDetails('hostel_maintenance',
576            self.student, None, None)
577        self.assertEqual(payment.p_level, 100)
578        self.assertEqual(payment.p_session, 2004)
579        self.assertEqual(payment.amount_auth, 180.0)
580        self.assertEqual(payment.p_item, u'')
581        self.assertEqual(error, None)
582
583        error, payment = utils.setPaymentDetails('bed_allocation',
584            self.student, None, None)
585        self.assertEqual(payment.p_level, 100)
586        self.assertEqual(payment.p_session, 2004)
587        self.assertEqual(payment.amount_auth, 150.0)
588        self.assertEqual(payment.p_item, u'')
589        self.assertEqual(error, None)
590
591        error, payment = utils.setPaymentDetails('transfer',
592            self.student, None, None)
593        self.assertEqual(payment.p_level, 100)
594        self.assertEqual(payment.p_session, 2004)
595        self.assertEqual(payment.amount_auth, 90.0)
596        self.assertEqual(payment.p_item, u'')
597        self.assertEqual(error, None)
598        return
599
600    def test_edit_level_by_co(self):
601        # Create clearance officer
602        self.app['users'].addUser('mrclear', 'mrclearsecret')
603        self.app['users']['mrclear'].email = 'mrclear@foo.ng'
604        self.app['users']['mrclear'].title = 'Carlo Pitter'
605        # Assign local ClearanceOfficer role
606        department = self.app['faculties']['fac1']['dep1']
607        prmlocal = IPrincipalRoleManager(department)
608        prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear')
609        notify(LocalRoleSetEvent(
610            department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
611        IWorkflowState(self.student).setState('clearance started')
612        # Login as clearance officer
613        self.browser.open(self.login_path)
614        self.browser.getControl(name="form.login").value = 'mrclear'
615        self.browser.getControl(name="form.password").value = 'mrclearsecret'
616        self.browser.getControl("Login").click()
617        self.assertMatches('...You logged in...', self.browser.contents)
618        # Only in state clearance requested the CO does see the
619        # 'Edit level' button ...
620        self.browser.open(self.studycourse_path)
621        self.assertFalse('Edit level' in self.browser.contents)
622        # ... and can open the edit_level view
623        self.browser.open(self.studycourse_path + '/edit_level')
624        self.assertMatches('...is locked...', self.browser.contents)
625        self.assertEqual(self.browser.url, self.studycourse_path)
626        IWorkflowInfo(self.student).fireTransition('request_clearance')
627        self.browser.open(self.studycourse_path)
628        self.assertTrue('Edit level' in self.browser.contents)
629        self.browser.getLink("Edit level").click()
630        self.browser.getControl(name="form.current_level").value = ['200']
631        self.browser.getControl("Save").click()
632        self.assertMatches('...has been saved...', self.browser.contents)
633        self.assertEqual(self.student.current_level, 200)
634
635    def test_postgraduate_student_access(self):
636        self.certificate.study_mode = 'special_pg_pt'
637        self.certificate.start_level = 700
638        self.certificate.end_level = 800
639        self.student['studycourse'].current_level = 700
640        IWorkflowState(self.student).setState('school fee paid')
641        self.browser.open(self.login_path)
642        self.browser.getControl(name="form.login").value = self.student_id
643        self.browser.getControl(name="form.password").value = 'spwd'
644        self.browser.getControl("Login").click()
645        self.assertTrue(
646            'You logged in.' in self.browser.contents)
647        # Now students can add the current study level
648        self.browser.getLink("Study Course").click()
649        self.browser.getLink("Add course list").click()
650        self.assertMatches('...Add current level 700...',
651                           self.browser.contents)
652        self.browser.getControl("Create course list now").click()
653        # A level with one course ticket was created
654        self.assertEqual(self.student['studycourse']['700'].number_of_tickets, 0)
655        self.browser.getLink("700").click()
656        self.browser.getLink("Edit course list").click()
657        self.browser.getControl("Add course ticket").click()
658        self.browser.getControl(name="form.course").value = ['COURSE1']
659        self.browser.getControl("Add course ticket").click()
660        self.assertMatches('...Successfully added COURSE1...',
661                           self.browser.contents)
662        # Special postgraduate students can register course lists
663        self.browser.getControl("Register course list").click()
664        self.assertMatches('...Course list has been registered...',
665            self.browser.contents)
666        self.assertEqual(self.student.state, 'courses registered')
667        return
668
669    def test_login(self):
670        # If suspended_comment is set this message will be flashed instead
671        self.student.suspended_comment = u'Aetsch baetsch!'
672        self.student.suspended = True
673        self.browser.open(self.login_path)
674        self.browser.getControl(name="form.login").value = self.student_id
675        self.browser.getControl(name="form.password").value = 'spwd'
676        self.browser.getControl("Login").click()
677        # Uniben does not display suspended_comment
678        self.assertMatches(
679            '...<div class="alert-message warning">Your account has been deactivated.</div>...',
680            self.browser.contents)
681        self.student.suspended = False
Note: See TracBrowser for help on using the repository browser.