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

Last change on this file since 10888 was 10836, checked in by Henrik Bettermann, 11 years ago

Adjust tests.

  • Property svn:keywords set to Id
File size: 34.5 KB
Line 
1## $Id: test_browser.py 10836 2013-12-10 08:40:03Z 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 StudentUITests(StudentsFullSetup):
40    """Tests for customized student class views and pages
41    """
42
43    layer = FunctionalLayer
44
45    def setUp(self):
46        super(StudentUITests, self).setUp()
47
48        bedticket = BedTicket()
49        bedticket.booking_session = 2004
50        bedticket.bed_type = u'any bed type'
51        bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
52        bedticket.bed_coordinates = u'My bed coordinates'
53        self.student['accommodation'].addBedTicket(bedticket)
54
55    def test_next_session_allowed(self):
56        # Let's see if next_session_allowed works as expected
57        # A, ug_ft, 100
58        IWorkflowState(self.student).setState('returning')
59        self.assertTrue(self.student['studycourse'].next_session_allowed)
60        # Uniben special PG programmes have the same workflow
61        # as UG students
62        self.certificate.study_mode = 'special_pg_pt'
63        self.assertTrue(self.student['studycourse'].next_session_allowed)
64        IWorkflowState(self.student).setState('school fee paid')
65        self.assertFalse(self.student['studycourse'].next_session_allowed)
66        # Now we convert the certificate into a 'regular
67        # postgraduate certificate ...
68        self.certificate.study_mode = 'pg_ft'
69        # ... and voila next session registration is allowed
70        self.assertTrue(self.student['studycourse'].next_session_allowed)
71
72    def test_manage_access(self):
73        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
74        # The student created in the base package is a ug student
75        self.browser.open(self.manage_clearance_path)
76        self.assertMatches('...First Sitting Record...',
77                           self.browser.contents)
78        # There is no pg field in the clearance form
79        self.assertFalse('Second Higher Education Record'
80            in self.browser.contents)
81        # Now we change the study mode ...
82        self.certificate.study_mode = 'pg_ft'
83        self.browser.open(self.clearance_path)
84        # ... and additional pg clearance fields appear
85        self.assertMatches('...Second Higher Education Record...',
86                           self.browser.contents)
87        # But also fields from the ug form are displayed
88        self.assertMatches('...First Sitting Record...',
89                           self.browser.contents)
90        # The same holds for Uniben's special pg students
91        self.certificate.study_mode = 'special_pg_pt'
92        self.browser.open(self.clearance_path)
93        self.assertMatches('...Second Higher Education Record...',
94                           self.browser.contents)
95        self.assertMatches('...First Sitting Record...',
96                           self.browser.contents)
97        self.browser.open(self.student_path + '/clearance_slip.pdf')
98        self.assertEqual(self.browser.headers['Status'], '200 Ok')
99        self.assertEqual(self.browser.headers['Content-Type'],
100                         'application/pdf')
101
102    def test_student_access(self):
103        # Students can edit clearance data
104        IWorkflowState(self.student).setState('clearance started')
105        self.student.clearance_locked = False
106        self.student.nationality = u'NG'
107        file_store = getUtility(IExtFileStore)
108        self.browser.open(self.login_path)
109        self.browser.getControl(name="form.login").value = self.student_id
110        self.browser.getControl(name="form.password").value = 'spwd'
111        self.browser.getControl("Login").click()
112        self.browser.open(self.edit_clearance_path)
113
114        # Clearance can only be requested if all required documents
115        # have been uploaded.
116        self.browser.getControl("Save and request clearance").click()
117        self.assertTrue('No birth certificate uploaded'
118            in self.browser.contents)
119        birth_certificate = 'My birth certificate'
120        file_id = IFileStoreNameChooser(self.student).chooseName(
121            attr="birth_certificate.jpg")
122        file_store.createFile(file_id, StringIO(birth_certificate))
123        self.browser.open(self.edit_clearance_path)
124        self.browser.getControl("Save and request clearance").click()
125
126        self.assertTrue('No guarantor/referee letter uploaded'
127            in self.browser.contents)
128        ref_let = 'My ref let'
129        file_id = IFileStoreNameChooser(self.student).chooseName(
130            attr="ref_let.jpg")
131        file_store.createFile(file_id, StringIO(ref_let))
132        self.browser.open(self.edit_clearance_path)
133        self.browser.getControl("Save and request clearance").click()
134
135        self.assertTrue('No acceptance letter uploaded'
136            in self.browser.contents)
137        acc_let = 'My acc let'
138        file_id = IFileStoreNameChooser(self.student).chooseName(
139            attr="acc_let.jpg")
140        file_store.createFile(file_id, StringIO(acc_let))
141        self.browser.open(self.edit_clearance_path)
142        self.browser.getControl("Save and request clearance").click()
143
144        self.assertTrue('No first sitting result uploaded'
145            in self.browser.contents)
146        fst_sit_scan = 'My first sitting result'
147        file_id = IFileStoreNameChooser(self.student).chooseName(
148            attr="fst_sit_scan.jpg")
149        file_store.createFile(file_id, StringIO(fst_sit_scan))
150        self.browser.open(self.edit_clearance_path)
151        self.browser.getControl("Save and request clearance").click()
152
153        #self.assertTrue('No second sitting result uploaded'
154        #    in self.browser.contents)
155        #scd_sit_scan = 'My second sitting result'
156        #file_id = IFileStoreNameChooser(self.student).chooseName(
157        #    attr="scd_sit_scan.jpg")
158        #file_store.createFile(file_id, StringIO(scd_sit_scan))
159        #self.browser.open(self.edit_clearance_path)
160        #self.browser.getControl("Save and request clearance").click()
161
162        self.assertTrue('No affidavit of non-membership of secret cults uploaded'
163            in self.browser.contents)
164        secr_cults = 'My non-membership scan'
165        file_id = IFileStoreNameChooser(self.student).chooseName(
166            attr="secr_cults.jpg")
167        file_store.createFile(file_id, StringIO(secr_cults))
168        self.browser.open(self.edit_clearance_path)
169        self.browser.getControl("Save and request clearance").click()
170
171        self.assertTrue('Clearance has been requested'
172            in self.browser.contents)
173
174    def test_manage_payments(self):
175        # Add missing configuration data
176        self.app['configuration']['2004'].gown_fee = 150.0
177        self.app['configuration']['2004'].transfer_fee = 90.0
178        #self.app['configuration']['2004'].clearance_fee = 120.0
179        self.app['configuration']['2004'].booking_fee = 150.0
180        self.app['configuration']['2004'].maint_fee = 180.0
181
182        # Managers can add online payment tickets
183        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
184        self.browser.open(self.payments_path)
185        self.browser.getLink("Add current session payment ticket").click()
186        self.browser.getControl("Create ticket").click()
187        self.assertMatches('...Amount could not be determined...',
188                           self.browser.contents)
189        IWorkflowState(self.student).setState('cleared')
190        self.student.nationality = u'NG'
191        self.browser.open(self.payments_path + '/addop')
192        self.browser.getControl(name="form.p_category").value = ['schoolfee']
193        self.browser.getControl("Create ticket").click()
194        self.assertMatches('...ticket created...',
195                           self.browser.contents)
196        ctrl = self.browser.getControl(name='val_id')
197        value = ctrl.options[0]
198        self.browser.getLink(value).click()
199        self.assertMatches('...Amount Authorized...',
200                           self.browser.contents)
201        # Managers can open payment slip
202        self.browser.getLink("Download payment slip").click()
203        self.assertEqual(self.browser.headers['Status'], '200 Ok')
204        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
205        # Set ticket paid
206        ticket = self.student['payments'].items()[0][1]
207        ticket.p_state = 'paid'
208        self.browser.open(self.payments_path + '/addop')
209        self.browser.getControl(name="form.p_category").value = ['schoolfee']
210        self.browser.getControl("Create ticket").click()
211        self.assertMatches('...This type of payment has already been made...',
212                           self.browser.contents)
213        # Remove all payments so that we can add a school fee payment again
214        keys = [i for i in self.student['payments'].keys()]
215        for payment in keys:
216            del self.student['payments'][payment]
217        self.browser.open(self.payments_path + '/addop')
218        self.browser.getControl(name="form.p_category").value = ['schoolfee']
219        self.browser.getControl("Create ticket").click()
220        self.assertMatches('...ticket created...',
221                           self.browser.contents)
222        schoolfee_ticket = self.student['payments'].values()[0]
223        self.browser.open(self.payments_path + '/addop')
224        self.browser.getControl(name="form.p_category").value = ['gown']
225        self.browser.getControl("Create ticket").click()
226        self.assertMatches('...ticket created...',
227                           self.browser.contents)
228        self.browser.open(self.payments_path + '/addop')
229        self.browser.getControl(
230            name="form.p_category").value = ['tempmaint_1']
231        self.browser.getControl("Create ticket").click()
232        self.assertMatches('...ticket created...',
233                           self.browser.contents)
234        self.browser.open(self.payments_path + '/addop')
235        self.browser.getControl(
236            name="form.p_category").value = ['tempmaint_2']
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(
242            name="form.p_category").value = ['tempmaint_3']
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 = ['clearance']
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 = ['schoolfee']
253        self.browser.getControl("Create ticket").click()
254        self.assertMatches('...ticket created...',
255                           self.browser.contents)
256        # In state returning we can add a new school fee ticket since
257        # p_session and p_level is different
258        IWorkflowState(self.student).setState('returning')
259        self.browser.open(self.payments_path + '/addop')
260        self.browser.getControl(name="form.p_category").value = ['schoolfee']
261        self.browser.getControl("Create ticket").click()
262        # Uups, we forgot to add a session configuration for next session
263        self.assertMatches('...Session configuration object is not...',
264                           self.browser.contents)
265        configuration = createObject('waeup.SessionConfiguration')
266        configuration.academic_session = 2005
267        self.app['configuration'].addSessionConfiguration(configuration)
268        self.browser.open(self.payments_path + '/addop')
269        self.browser.getControl(name="form.p_category").value = ['schoolfee']
270        self.browser.getControl("Create ticket").click()
271
272
273        #self.assertMatches('...You have not yet paid your current/active session...',
274        #                   self.browser.contents)
275        ## Ok, let's pay the first schoolfee ticket.
276        #schoolfee_ticket.approve()
277        #self.browser.open(self.payments_path + '/addop')
278        #self.browser.getControl(name="form.p_category").value = ['schoolfee']
279        #self.browser.getControl("Create ticket").click()
280
281
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.getLink("Add current session 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_student_course_registration(self):
302        # Uniben students see grade instead of score on all level pages
303        # and on course ticket page.
304        IWorkflowState(self.student).setState('school fee paid')
305        self.browser.open(self.login_path)
306        self.browser.getControl(name="form.login").value = self.student_id
307        self.browser.getControl(name="form.password").value = 'spwd'
308        self.browser.getControl("Login").click()
309        # Now students can add the current study level
310        self.browser.getLink("Study Course").click()
311        self.browser.getLink("Add course list").click()
312        self.assertMatches('...Add current level 100 (Year 1)...',
313                           self.browser.contents)
314        self.browser.getControl("Create course list now").click()
315        # A level with one course ticket was created
316        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 1)
317        self.student['studycourse']['100']['COURSE1'].score = 55
318        self.browser.getLink("100").click()
319        # GPA has been properly calculated
320        self.assertEqual(self.student['studycourse']['100'].gpa_params[0], 3.0)
321        # Score is not shown but grade
322        self.assertTrue('<th>Grade</th>' in self.browser.contents)
323        self.assertFalse('<th>Score</th>' in self.browser.contents)
324        self.browser.getLink("Edit course list").click()
325        self.assertTrue('<th>Grade</th>' in self.browser.contents)
326        self.assertFalse('<th>Score</th>' in self.browser.contents)
327        self.browser.getLink("COURSE1").click()
328        self.assertFalse('Score' in self.browser.contents)
329        # Students can open the customized pdf course registration slip
330        self.browser.open(self.student_path + '/studycourse/100')
331        self.browser.getLink("Download course registration slip").click()
332        self.assertEqual(self.browser.headers['Status'], '200 Ok')
333        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
334        # Students can open the special Uniben pdf course result slip
335        self.browser.open(self.student_path + '/studycourse/100')
336        self.browser.getLink("Download course result slip").click()
337        self.assertEqual(self.browser.headers['Status'], '200 Ok')
338        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
339        # Even if course is mandatory, students can remove the course
340        self.student['studycourse']['100']['COURSE1'].mandatory = True
341        self.browser.open(self.student_path + '/studycourse/100')
342        self.browser.getLink("Edit course list").click()
343        ctrl = self.browser.getControl(name='val_id')
344        ctrl.getControl(value='COURSE1').selected = True
345        self.browser.getControl("Remove selected", index=0).click()
346        self.assertTrue('Successfully removed' in self.browser.contents)
347
348    def test_get_returning_data(self):
349        # Student is in level 100, session 2004 with verdict A
350        utils = getUtility(IStudentsUtils)
351        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
352        self.student['studycourse'].current_verdict = 'C'
353        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
354        self.student['studycourse'].current_verdict = 'D'
355        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
356        return
357
358    def test_set_returning_data(self):
359        # Student is in level 100, session 2004 with verdict A
360        utils = getUtility(IStudentsUtils)
361
362        utils.setReturningData(self.student)
363        self.assertEqual(self.student['studycourse'].current_session, 2005)
364        self.assertEqual(self.student['studycourse'].current_level, 200)
365
366        self.student['studycourse'].current_session = 2004
367        self.student['studycourse'].current_level = 100
368        self.student['studycourse'].current_verdict = 'C'
369        utils.setReturningData(self.student)
370        self.assertEqual(self.student['studycourse'].current_session, 2005)
371        self.assertEqual(self.student['studycourse'].current_level, 110)
372
373        self.student['studycourse'].current_session = 2004
374        self.student['studycourse'].current_level = 100
375        self.student['studycourse'].current_verdict = 'D'
376        utils.setReturningData(self.student)
377        self.assertEqual(self.student['studycourse'].current_session, 2005)
378        self.assertEqual(self.student['studycourse'].current_level, 100)
379        return
380
381    def test_set_payment_details(self):
382        self.app['configuration']['2004'].gown_fee = 150.0
383        self.app['configuration']['2004'].transfer_fee = 90.0
384        self.app['configuration']['2004'].booking_fee = 150.0
385        self.app['configuration']['2004'].maint_fee = 180.0
386
387        configuration = createObject('waeup.SessionConfiguration')
388        configuration.academic_session = 2000
389        self.app['configuration'].addSessionConfiguration(configuration)
390        configuration2 = createObject('waeup.SessionConfiguration')
391        configuration2.academic_session = 2002
392        self.app['configuration'].addSessionConfiguration(configuration2)
393        configuration3 = createObject('waeup.SessionConfiguration')
394        configuration3.academic_session = 2003
395        self.app['configuration'].addSessionConfiguration(configuration3)
396        configuration4 = createObject('waeup.SessionConfiguration')
397        configuration4.academic_session = 2005
398        self.app['configuration'].addSessionConfiguration(configuration4)
399        utils = getUtility(IStudentsUtils)
400        self.student['studycourse'].entry_session = 2002
401        self.student.nationality = u'NG'
402
403        error, payment = utils.setPaymentDetails('schoolfee',
404            self.student, None, None)
405        self.assertEqual(payment, None)
406        # Student is in state 'created' and can thus not pay.
407        self.assertTrue(u'Amount could not be determined.' in error)
408
409        # Previous session must be valid.
410        error, payment = utils.setPaymentDetails('schoolfee',
411            self.student, 2000, 300)
412        self.assertEqual(payment, None)
413        self.assertTrue(u'The previous session must not fall below' in error)
414        error, payment = utils.setPaymentDetails('schoolfee',
415            self.student, 2005, 300)
416        self.assertEqual(payment, None)
417        self.assertTrue(u'This is not a previous session' in error)
418
419        # Previous session schoolfee payment; fresh and returning
420        # are distinguished by their entry_level
421        error, payment = utils.setPaymentDetails('schoolfee',
422            self.student, 2002, 300)
423        self.assertEqual(payment.amount_auth, 40000.0)
424        self.assertEqual(payment.p_session, 2002)
425        self.assertEqual(payment.p_level, 300)
426        self.assertFalse(payment.p_current)
427        error, payment = utils.setPaymentDetails('schoolfee',
428            self.student, 2003, 300)
429        self.assertEqual(payment.amount_auth, 20000.0)
430        self.assertEqual(payment.p_session, 2003)
431        self.assertEqual(payment.p_level, 300)
432        self.assertFalse(payment.p_current)
433
434        # Current schoolfee payment; fresh and returning
435        # are distinguished by their state
436        IWorkflowState(self.student).setState('cleared')
437        error, payment = utils.setPaymentDetails('schoolfee',
438            self.student, None, None)
439        self.assertEqual(payment.p_level, 100)
440        self.assertEqual(payment.p_session, 2004)
441        self.assertEqual(payment.amount_auth, 40000.0)
442        self.assertEqual(payment.p_item, u'CERT1')
443        self.assertEqual(error, None)
444        self.assertTrue(payment.p_current)
445
446        # Add penalty fee ...
447        # ... for cleared
448        self.app['configuration']['2004'].penalty_ug = 99.0
449        # ... for returning
450        self.app['configuration']['2005'].penalty_ug = 88.0
451        error, payment = utils.setPaymentDetails('schoolfee',
452            self.student, None, None)
453        self.assertEqual(payment.amount_auth, 40099.0)
454
455        IWorkflowState(self.student).setState('returning')
456
457
458        #error, payment = utils.setPaymentDetails('schoolfee',
459        #    self.student, None, None)
460        #self.assertTrue(
461        #    u'You have not yet paid your current/active session.' in error)
462        ## Ok, that means we have to add paid payment ticket first.
463        #payment = createObject('waeup.StudentOnlinePayment')
464        #payment.p_category = u'schoolfee'
465        #payment.p_session = self.student.current_session
466        #payment.p_item = u'My Certificate'
467        #payment.p_id = u'anyid'
468        #payment.p_state = u'paid'
469        #self.student['payments']['anykey'] = payment
470
471
472        error, payment = utils.setPaymentDetails('schoolfee',
473            self.student, None, None)
474        self.assertEqual(payment.p_level, 200)
475        self.assertEqual(payment.p_session, 2005)
476        self.assertEqual(payment.amount_auth, 20088.0)
477        self.assertEqual(payment.p_item, u'CERT1')
478        self.assertEqual(error, None)
479
480        # Staff members pay less.
481        self.student.is_staff = True
482        error, payment = utils.setPaymentDetails('schoolfee',
483            self.student, None, None)
484        self.assertEqual(payment.p_level, 200)
485        self.assertEqual(payment.p_session, 2005)
486        self.assertEqual(payment.amount_auth, 10088.0)
487        self.assertEqual(payment.p_item, u'CERT1')
488        self.assertEqual(error, None)
489
490        # Foreigners pay more.
491        IWorkflowState(self.student).setState('cleared')
492        self.student.is_staff = False
493        self.student.nationality = u'DE'
494        self.certificate.school_fee_3 = 60000.0
495        error, payment = utils.setPaymentDetails(
496            'schoolfee', self.student, None, None)
497        self.assertEqual(payment.p_level, 100)
498        self.assertEqual(payment.p_session, 2004)
499        self.assertEqual(payment.amount_auth, 60099.0)
500        self.assertEqual(payment.p_item, u'CERT1')
501        self.assertEqual(error, None)
502        IWorkflowState(self.student).setState('returning')
503        self.student.is_staff = False
504        self.certificate.school_fee_4 = 20000.0
505        error, payment = utils.setPaymentDetails(
506            'schoolfee', self.student, None, None)
507        self.assertEqual(payment.p_level, 200)
508        self.assertEqual(payment.p_session, 2005)
509        self.assertEqual(payment.amount_auth, 20088.0)
510        self.assertEqual(payment.p_item, u'CERT1')
511        self.assertEqual(error, None)
512
513        # In Uniben students can pay school fee in all states no matter
514        # if they are ug or pg students.
515        IWorkflowState(self.student).setState('school fee paid')
516        self.student.is_staff = False
517        self.student.nationality = u'NG'
518        self.certificate.school_fee_2 = 10000.0
519        error, payment = utils.setPaymentDetails(
520            'schoolfee', self.student, None, None)
521        self.assertEqual(payment.p_level, None)
522        self.assertEqual(payment.p_session, 2005)
523        self.assertEqual(payment.amount_auth, 10088.0)
524        self.assertEqual(payment.p_item, u'CERT1')
525        self.assertEqual(error, None)
526        IWorkflowState(self.student).setState('courses registered')
527        self.certificate.study_mode = 'special_pg_pt'
528        error, payment = utils.setPaymentDetails(
529            'schoolfee', self.student, None, None)
530        self.assertEqual(payment.p_level, None)
531        self.assertEqual(payment.p_session, 2005)
532        self.assertEqual(payment.amount_auth, 10000.0)
533        self.assertEqual(payment.p_item, u'CERT1')
534        self.assertEqual(error, None)
535        IWorkflowState(self.student).setState('courses validated')
536        error, payment = utils.setPaymentDetails(
537            'schoolfee', self.student, None, None)
538        self.assertEqual(payment.p_level, None)
539        self.assertEqual(payment.p_session, 2005)
540        self.assertEqual(payment.amount_auth, 10000.0)
541        self.assertEqual(payment.p_item, u'CERT1')
542        self.assertEqual(error, None)
543
544        error, payment = utils.setPaymentDetails('clearance',
545            self.student, None, None)
546        self.assertEqual(payment.p_level, 100)
547        self.assertEqual(payment.p_session, 2004)
548        self.assertEqual(payment.amount_auth, 45000.0)
549        self.assertEqual(payment.p_item, u'CERT1')
550        self.assertEqual(error, None)
551
552        error, payment = utils.setPaymentDetails('gown',
553            self.student, None, None)
554        self.assertEqual(payment.p_level, 100)
555        self.assertEqual(payment.p_session, 2004)
556        self.assertEqual(payment.amount_auth, 150.0)
557        self.assertEqual(payment.p_item, u'')
558        self.assertEqual(error, None)
559
560        error, payment = utils.setPaymentDetails('hostel_maintenance',
561            self.student, None, None)
562        self.assertEqual(payment.p_level, 100)
563        self.assertEqual(payment.p_session, 2004)
564        self.assertEqual(payment.amount_auth, 180.0)
565        self.assertEqual(payment.p_item, u'')
566        self.assertEqual(error, None)
567
568        error, payment = utils.setPaymentDetails('bed_allocation',
569            self.student, None, None)
570        self.assertEqual(payment.p_level, 100)
571        self.assertEqual(payment.p_session, 2004)
572        self.assertEqual(payment.amount_auth, 150.0)
573        self.assertEqual(payment.p_item, u'')
574        self.assertEqual(error, None)
575
576        error, payment = utils.setPaymentDetails('tempmaint_1',
577            self.student, None, None)
578        self.assertEqual(payment.p_level, 100)
579        self.assertEqual(payment.p_session, 2004)
580        self.assertEqual(payment.amount_auth, 8150.0)
581        self.assertEqual(payment.p_item, u'Hall 1-4 M/F Ekehuan')
582        self.assertEqual(error, None)
583
584        error, payment = utils.setPaymentDetails('tempmaint_2',
585            self.student, None, None)
586        self.assertEqual(payment.p_level, 100)
587        self.assertEqual(payment.p_session, 2004)
588        self.assertEqual(payment.amount_auth, 12650.0)
589        self.assertEqual(payment.p_item, u'Hall 5 M/F')
590        self.assertEqual(error, None)
591
592        error, payment = utils.setPaymentDetails('tempmaint_3',
593            self.student, None, None)
594        self.assertEqual(payment.p_level, 100)
595        self.assertEqual(payment.p_session, 2004)
596        self.assertEqual(payment.amount_auth, 9650.0)
597        self.assertEqual(payment.p_item, u'Clinical Hostel')
598        self.assertEqual(error, None)
599
600        error, payment = utils.setPaymentDetails('transfer',
601            self.student, None, None)
602        self.assertEqual(payment.p_level, 100)
603        self.assertEqual(payment.p_session, 2004)
604        self.assertEqual(payment.amount_auth, 90.0)
605        self.assertEqual(payment.p_item, u'')
606        self.assertEqual(error, None)
607        return
608
609    def test_edit_level_by_co(self):
610        # Create clearance officer
611        self.app['users'].addUser('mrclear', 'mrclearsecret')
612        self.app['users']['mrclear'].email = 'mrclear@foo.ng'
613        self.app['users']['mrclear'].title = 'Carlo Pitter'
614        # Assign local ClearanceOfficer role
615        department = self.app['faculties']['fac1']['dep1']
616        prmlocal = IPrincipalRoleManager(department)
617        prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear')
618        notify(LocalRoleSetEvent(
619            department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
620        IWorkflowState(self.student).setState('clearance started')
621        # Login as clearance officer
622        self.browser.open(self.login_path)
623        self.browser.getControl(name="form.login").value = 'mrclear'
624        self.browser.getControl(name="form.password").value = 'mrclearsecret'
625        self.browser.getControl("Login").click()
626        self.assertMatches('...You logged in...', self.browser.contents)
627        # Only in state clearance requested the CO does see the
628        # 'Edit level' button ...
629        self.browser.open(self.studycourse_path)
630        self.assertFalse('Edit level' in self.browser.contents)
631        # ... and can open the edit_level view
632        self.browser.open(self.studycourse_path + '/edit_level')
633        self.assertMatches('...is locked...', self.browser.contents)
634        self.assertEqual(self.browser.url, self.studycourse_path)
635        IWorkflowInfo(self.student).fireTransition('request_clearance')
636        self.browser.open(self.studycourse_path)
637        self.assertTrue('Edit level' in self.browser.contents)
638        self.browser.getLink("Edit level").click()
639        self.browser.getControl(name="form.current_level").value = ['200']
640        self.browser.getControl("Save").click()
641        self.assertMatches('...has been saved...', self.browser.contents)
642        self.assertEqual(self.student.current_level, 200)
643
644    def test_postgraduate_student_access(self):
645        self.certificate.study_mode = 'special_pg_pt'
646        self.certificate.start_level = 700
647        self.certificate.end_level = 800
648        self.student['studycourse'].current_level = 700
649        IWorkflowState(self.student).setState('school fee paid')
650        self.browser.open(self.login_path)
651        self.browser.getControl(name="form.login").value = self.student_id
652        self.browser.getControl(name="form.password").value = 'spwd'
653        self.browser.getControl("Login").click()
654        self.assertTrue(
655            'You logged in.' in self.browser.contents)
656        # Now students can add the current study level
657        self.browser.getLink("Study Course").click()
658        self.browser.getLink("Add course list").click()
659        self.assertMatches('...Add current level 700...',
660                           self.browser.contents)
661        self.browser.getControl("Create course list now").click()
662        # A level with no course ticket was created
663        self.assertEqual(self.student['studycourse']['700'].number_of_tickets, 0)
664        self.browser.getLink("700").click()
665        self.browser.getLink("Edit course list").click()
666        self.browser.getLink("here").click()
667        self.browser.getControl(name="form.course").value = ['COURSE1']
668        # Non-final year students can't add ticket with 51 credits
669        self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 51
670        self.browser.getControl("Add course ticket").click()
671        self.assertMatches('...Total credits exceed 50...',
672                           self.browser.contents)
673        # Final year students can't add ticket with 52 credits ...
674        self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 52
675        self.student['studycourse'].certificate.end_level = 700
676        self.browser.getControl("Add course ticket").click()
677        self.assertMatches('...Total credits exceed 51...',
678                           self.browser.contents)
679        # ... but with 51 credits
680        self.app['faculties']['fac1']['dep1'].courses['COURSE1'].credits = 51
681        self.browser.getControl("Add course ticket").click()
682        self.assertMatches('...Successfully added COURSE1...',
683                           self.browser.contents)
684        # Non-final year special postgraduate students can't register
685        # course lists if their total credits are 51 and thus exceed 50 ...
686        self.student['studycourse'].certificate.end_level = 800
687        self.browser.getControl("Register course list").click()
688        self.assertMatches('...Maximum credits of 50 exceeded...',
689            self.browser.contents)
690        # ... but final year students can
691        self.student['studycourse'].certificate.end_level = 700
692        self.browser.getControl("Register course list").click()
693        self.assertMatches('...Course list has been registered...',
694            self.browser.contents)
695        self.assertEqual(self.student.state, 'courses registered')
696        return
697
698    def test_login(self):
699        # If suspended_comment is set this message will be flashed instead
700        self.student.suspended_comment = u'Aetsch baetsch!'
701        self.student.suspended = True
702        self.browser.open(self.login_path)
703        self.browser.getControl(name="form.login").value = self.student_id
704        self.browser.getControl(name="form.password").value = 'spwd'
705        self.browser.getControl("Login").click()
706        # Uniben does not display suspended_comment
707        self.assertMatches(
708            '...<div class="alert-message warning">Your account has been deactivated.</div>...',
709            self.browser.contents)
710        self.student.suspended = False
Note: See TracBrowser for help on using the repository browser.