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

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

Add test for previous revision.

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