source: main/waeup.aaue/trunk/src/waeup/aaue/students/tests/test_browser.py @ 13853

Last change on this file since 13853 was 13834, checked in by Henrik Bettermann, 9 years ago

Further customizations for taking the ca into consideration and displaying the ca on all forms and slips.

  • Property svn:keywords set to Id
File size: 36.5 KB
Line 
1## $Id: test_browser.py 13834 2016-04-19 06:42:26Z 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
21import pytz
22import grok
23from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
24from zope.securitypolicy.interfaces import IPrincipalRoleManager
25from datetime import datetime, timedelta, date
26from mechanize import LinkNotFoundError
27from hurry.workflow.interfaces import IWorkflowState
28from zope.event import notify
29from zope.component.hooks import setSite, clearSite
30from zope.component import getUtility, createObject, queryUtility
31from zope.catalog.interfaces import ICatalog
32from waeup.kofa.app import University
33from waeup.kofa.students.tests.test_browser import StudentsFullSetup
34from waeup.kofa.students.accommodation import BedTicket
35from waeup.kofa.testing import FunctionalTestCase
36from waeup.kofa.authentication import LocalRoleSetEvent
37from waeup.kofa.browser.tests.test_pdf import samples_dir
38from waeup.aaue.testing import FunctionalLayer
39
40SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
41
42
43class StudentProcessorTest(FunctionalTestCase):
44    """Perform some batching tests.
45    """
46
47    layer = FunctionalLayer
48
49    def setUp(self):
50        super(StudentProcessorTest, self).setUp()
51        # Setup a sample site for each test
52        app = University()
53        self.dc_root = tempfile.mkdtemp()
54        app['datacenter'].setStoragePath(self.dc_root)
55
56        # Prepopulate the ZODB...
57        self.getRootFolder()['app'] = app
58        # we add the site immediately after creation to the
59        # ZODB. Catalogs and other local utilities are not setup
60        # before that step.
61        self.app = self.getRootFolder()['app']
62        # Set site here. Some of the following setup code might need
63        # to access grok.getSite() and should get our new app then
64        setSite(app)
65
66
67    def tearDown(self):
68        super(StudentProcessorTest, self).tearDown()
69        shutil.rmtree(self.workdir)
70        shutil.rmtree(self.dc_root)
71        clearSite()
72        return
73
74class OfficerUITests(StudentsFullSetup):
75    # Tests for Student class views and pages
76
77    layer = FunctionalLayer
78
79    def test_gpa_calculation(self):
80        studylevel = createObject(u'waeup.StudentStudyLevel')
81        studylevel.level = 100
82        studylevel.level_session = 2005
83        self.student['studycourse'].entry_mode = 'ug_ft'
84        self.student['studycourse'].addStudentStudyLevel(
85            self.certificate, studylevel)
86        # First course has been added automatically.
87        # Set score.
88        studylevel['COURSE1'].score = 35
89        studylevel['COURSE1'].ca = 20
90        # GPA is 3.0.
91        self.assertEqual(studylevel.gpa_params[0], 3.0)
92        courseticket = createObject('waeup.CourseTicket')
93        courseticket.code = 'ANYCODE'
94        courseticket.title = u'Any TITLE'
95        courseticket.credits = 13
96        courseticket.score = 44
97        courseticket.ca = 22
98        courseticket.semester = 1
99        courseticket.dcode = u'ANYDCODE'
100        courseticket.fcode = u'ANYFCODE'
101        studylevel['COURSE2'] = courseticket
102        # total credits
103        self.assertEqual(self.student['studycourse']['100'].gpa_params[1], 23)
104        # weigheted credits = 3 * 10 + 4 * 13
105        self.assertEqual(self.student['studycourse']['100'].gpa_params[2], 82.0)
106        # sgpa = 82 / 23
107        self.assertEqual(self.student['studycourse']['100'].gpa_params[0], 3.565)
108        return
109
110    def test_manage_payments(self):
111        # Add missing configuration data
112        self.app['configuration']['2004'].gown_fee = 150.0
113        self.app['configuration']['2004'].transfer_fee = 90.0
114        self.app['configuration']['2004'].booking_fee = 150.0
115        self.app['configuration']['2004'].maint_fee = 180.0
116        self.app['configuration']['2004'].late_fee = 80.0
117
118        # Managers can add online payment tickets
119        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
120        self.browser.open(self.payments_path)
121        self.browser.getLink("Add current session payment ticket").click()
122        self.browser.getControl(name="form.p_category").value = ['schoolfee_incl']
123        self.browser.getControl("Create ticket").click()
124        self.assertMatches('...Wrong state...',
125                           self.browser.contents)
126        IWorkflowState(self.student).setState('cleared')
127        self.browser.open(self.payments_path + '/addop')
128        self.browser.getControl("Create ticket").click()
129        self.assertMatches('...Amount could not be determined...',
130                           self.browser.contents)
131        #self.browser.getControl(name="form.p_category").value = ['schoolfee']
132        # Accepotance fee must be paid first
133        #self.browser.getControl("Create ticket").click()
134        #self.assertMatches('...Please pay acceptance fee first...',
135        #                   self.browser.contents)
136        self.app['configuration']['2004'].clearance_fee = 666.0
137        self.browser.getControl(name="form.p_category").value = ['clearance_incl']
138        self.browser.getControl("Create ticket").click()
139        ctrl = self.browser.getControl(name='val_id')
140        cpt_value = ctrl.options[0]
141        # School fee payment ticket can be added ...
142        self.student['studycourse'].certificate.school_fee_1 = 6666.0
143        self.student.nationality = u'NG'
144        self.browser.open(self.payments_path + '/addop')
145        self.browser.getControl(name="form.p_category").value = ['schoolfee_incl']
146        self.browser.getControl("Create ticket").click()
147        self.assertMatches('...ticket created...',
148                           self.browser.contents)
149        # ... but not paid through the query_history page.
150        ctrl = self.browser.getControl(name='val_id')
151        sfpt_value = ctrl.options[1]
152        self.student['studycourse'].entry_session = 2013
153        self.browser.open(self.payments_path + '/' + sfpt_value)
154        self.browser.getLink("Query eTranzact History").click()
155        self.assertMatches('...alert-danger">Please pay acceptance fee first...',
156                           self.browser.contents)
157        # If clearance/acceptance fee is paid ...
158        self.student['payments'][cpt_value].approveStudentPayment()
159        self.browser.getLink("Query eTranzact History").click()
160        # ... query_history page is accessible.
161        self.assertMatches(
162            '...<h1 class="kofa-content-label">Requery eTranzact History</h1>...',
163            self.browser.contents)
164        # Managers can open school fee payment slip
165        self.browser.open(self.payments_path + '/' + sfpt_value)
166        self.browser.getLink("Download payment slip").click()
167        self.assertEqual(self.browser.headers['Status'], '200 Ok')
168        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
169        # If school fee ticket is paid, the student is automatically set to
170        # school fee paid...
171        ticket = self.student['payments'][sfpt_value].approveStudentPayment()
172        self.assertEqual(self.student.state, 'school fee paid')
173        # ... no further school fee ticket can be added.
174        self.browser.open(self.payments_path + '/addop')
175        self.browser.getControl(name="form.p_category").value = ['schoolfee_incl']
176        self.browser.getControl("Create ticket").click()
177        self.assertMatches('...Wrong state...',
178                           self.browser.contents)
179        self.browser.open(self.payments_path + '/addop')
180        self.browser.getControl(name="form.p_category").value = ['late_registration']
181        self.browser.getControl("Create ticket").click()
182        self.assertMatches('...ticket created...',
183                           self.browser.contents)
184        return
185
186    def test_for_instalment_payments(self):
187        self.student['studycourse'].certificate.study_mode = 'ug_pt'
188        self.student['studycourse'].certificate.school_fee_1 = 6666.0
189        self.app['configuration']['2004'].union_fee = 1250.0
190        self.app['configuration']['2004'].welfare_fee = 750.0
191        self.student.nationality = u'NG'
192        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
193        self.browser.open(self.payments_path + '/addop')
194        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
195        self.browser.getControl("Create ticket").click()
196        self.assertTrue(
197            'Part-time students are not allowed' in self.browser.contents)
198        self.student['studycourse'].certificate.study_mode = 'ug_ft'
199        self.browser.open(self.payments_path + '/addop')
200        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
201        self.browser.getControl("Create ticket").click()
202        self.assertTrue(
203            'Wrong state. Only students in state \'cleared\' are allowed to pay by instalments'
204            in self.browser.contents)
205        IWorkflowState(self.student).setState('cleared')
206        self.browser.open(self.payments_path + '/addop')
207        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
208        self.browser.getControl("Create ticket").click()
209        self.assertTrue('ticket created' in self.browser.contents)
210        # We can't add the 2nd instalment ticket because the
211        # first one has not yet been approved.
212        #self.browser.open(self.payments_path + '/addop')
213        #self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
214        #self.browser.getControl("Create ticket").click()
215        #self.assertMatches('...1st school fee instalment has not yet been paid...',
216        #                   self.browser.contents)
217        # Ok, then we approve the first instalment ...
218        self.browser.open(self.payments_path)
219        ctrl = self.browser.getControl(name='val_id')
220        p_id = ctrl.options[0]
221        self.browser.open(self.payments_path + '/' + p_id + '/approve')
222        # ... add the second instalment ...
223        self.browser.open(self.payments_path + '/addop')
224        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
225        self.browser.getControl("Create ticket").click()
226        self.assertTrue('ticket created' in self.browser.contents)
227        # ... approve the second instalment ...
228        ctrl = self.browser.getControl(name='val_id')
229        p_id = ctrl.options[1]
230        self.browser.open(self.payments_path + '/' + p_id + '/approve')
231        self.assertEqual(self.student['payments'].values()[0].p_category, 'schoolfee_1')
232        self.assertEqual(self.student['payments'].values()[1].p_category, 'schoolfee_2')
233        # (6666-250)/2 + 1250 + 750 - 500 + 250
234        self.assertEqual(self.student['payments'].values()[0].amount_auth, 4958.0)
235        # (6666-250)/2 + 250
236        self.assertEqual(self.student['payments'].values()[1].amount_auth, 3458.0)
237        return
238
239    def test_manage_payments_bypass_ac_creation(self):
240        self.student['studycourse'].certificate.school_fee_1 = 6666.0
241        self.student.nationality = u'NG'
242        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
243        self.browser.open(self.payments_path)
244        IWorkflowState(self.student).setState('cleared')
245        self.browser.getLink("Add current session payment ticket").click()
246        self.browser.getControl(name="form.p_category").value = ['schoolfee_incl']
247        self.browser.getControl("Create ticket").click()
248        ctrl = self.browser.getControl(name='val_id')
249        value = ctrl.options[0]
250        self.browser.getLink(value).click()
251        payment_url = self.browser.url
252        logfile = os.path.join(
253            self.app['datacenter'].storage, 'logs', 'students.log')
254        # The ticket can be found in the payments_catalog
255        cat = queryUtility(ICatalog, name='payments_catalog')
256        results = list(cat.searchResults(p_state=('unpaid', 'unpaid')))
257        self.assertTrue(len(results), 1)
258        self.assertTrue(results[0] is self.student['payments'][value])
259        # Managers can approve the payment
260        self.browser.open(payment_url)
261        self.browser.getLink("Approve payment").click()
262        self.assertMatches('...Payment approved...',
263                          self.browser.contents)
264        # Approval is logged in students.log ...
265        logcontent = open(logfile).read()
266        self.assertTrue(
267            'zope.mgr - students.browser.OnlinePaymentApproveView '
268            '- E1000000 - schoolfee_incl payment approved'
269            in logcontent)
270        # ... and in payments.log
271        logfile = os.path.join(
272            self.app['datacenter'].storage, 'logs', 'payments.log')
273        logcontent = open(logfile).read()
274        self.assertTrue(
275            '"zope.mgr",E1000000,%s,schoolfee_incl,6666.0,AP,,,,,,\n' % value
276            in logcontent)
277        # Student is in state school fee paid, no activation
278        # code was necessary.
279        self.assertEqual(self.student.state, 'school fee paid')
280        self.assertEqual(len(self.app['accesscodes']['SFE-0']),0)
281        return
282
283class StudentUITests(StudentsFullSetup):
284    """Tests for customized student class views and pages
285    """
286
287    layer = FunctionalLayer
288
289    def setUp(self):
290        super(StudentUITests, self).setUp()
291
292        bedticket = BedTicket()
293        bedticket.booking_session = 2004
294        bedticket.bed_type = u'any bed type'
295        bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
296        bedticket.bed_coordinates = u'My bed coordinates'
297        self.student['accommodation'].addBedTicket(bedticket)
298
299    def test_student_payments(self):
300        self.certificate.study_mode = 'ug_ft'
301        self.student['studycourse'].entry_session = 2013
302        self.student['studycourse'].certificate.school_fee_1 = 50250.0
303        self.app['configuration']['2004'].union_fee = 1250.0
304        self.app['configuration']['2004'].welfare_fee = 750.0
305        self.student.nationality = u'NG'
306        # Login
307        IWorkflowState(self.student).setState('cleared')
308        self.browser.open(self.login_path)
309        self.browser.getControl(name="form.login").value = self.student_id
310        self.browser.getControl(name="form.password").value = 'spwd'
311        self.browser.getControl("Login").click()
312        # Test school fee payments
313        self.browser.open(self.student_path + '/payments')
314        self.browser.getLink("Add current session payment ticket").click()
315        self.browser.getControl(name="form.p_category").value = ['schoolfee_incl']
316        self.browser.getControl("Create ticket").click()
317        self.assertTrue('ticket created' in self.browser.contents)
318        value = self.student['payments'].keys()[0]
319        self.browser.getLink(value).click()
320        self.assertTrue('Amount Authorized' in self.browser.contents)
321        self.assertEqual(self.student['payments'][value].amount_auth, 51750.0)
322        self.browser.open(self.browser.url + '/payment_slip.pdf')
323        self.assertEqual(self.browser.headers['Status'], '200 Ok')
324        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
325        path = os.path.join(samples_dir(), 'payment_slip.pdf')
326        open(path, 'wb').write(self.browser.contents)
327        print "Sample PDF payment_slip.pdf written to %s" % path
328        # Another school fee payment cannot be added
329        self.student['payments'][value].approve()
330        self.browser.open(self.student_path + '/payments')
331        self.browser.getLink("Add current session payment ticket").click()
332        self.browser.getControl(name="form.p_category").value = ['schoolfee']
333        self.browser.getControl("Create ticket").click()
334        self.assertTrue(
335            'Another school fee payment for this session has already been made'
336            in self.browser.contents)
337        # Test hostel maintenance payments
338        self.browser.open(self.student_path + '/payments')
339        self.browser.getLink("Add current session payment ticket").click()
340        self.browser.getControl(name="form.p_category").value = ['hostel_maintenance']
341        self.browser.getControl("Create ticket").click()
342        self.assertTrue('ticket created' in self.browser.contents)
343        value = self.student['payments'].keys()[1]
344        self.browser.getLink(value).click()
345        self.assertTrue('<span>My bed coordinates</span>' in self.browser.contents)
346        self.assertEqual(self.student['payments'][value].amount_auth, 876.0)
347        return
348
349    def test_late_registration(self):
350        # Login
351        delta = timedelta(days=10)
352        self.app['configuration'][
353            '2004'].coursereg_deadline = datetime.now(pytz.utc) - delta
354        IWorkflowState(self.student).setState('school fee paid')
355        # Current session is 2004. Here we test course registration for
356        # returning students.
357        self.student['studycourse'].entry_session = 2003
358        self.browser.open(self.login_path)
359        self.browser.getControl(name="form.login").value = self.student_id
360        self.browser.getControl(name="form.password").value = 'spwd'
361        self.browser.getControl("Login").click()
362        self.browser.open(self.payments_path)
363        self.browser.open(self.payments_path + '/addop')
364        self.browser.getControl(name="form.p_category").value = ['late_registration']
365        self.browser.getControl("Create ticket").click()
366        self.assertMatches('...ticket created...',
367                           self.browser.contents)
368        self.browser.getLink("Study Course").click()
369        self.browser.getLink("Add course list").click()
370        self.assertMatches('...Add current level 100 (Year 1)...',
371                           self.browser.contents)
372        self.browser.getControl("Create course list now").click()
373        self.browser.getLink("100").click()
374        self.browser.getLink("Edit course list").click()
375        self.browser.getControl("Register course list").click()
376        self.assertTrue('Course registration has ended. Please pay' in self.browser.contents)
377        self.student['payments'].values()[0].approve()
378        self.browser.getControl("Register course list").click()
379        self.assertTrue('Course list has been registered' in self.browser.contents)
380        self.assertEqual(self.student.state, 'courses registered')
381        # Reset student and check if fresh students are always allowed to
382        # register courses.
383        self.student['studycourse'].entry_session = 2004
384        del self.student['payments'][self.student['payments'].keys()[0]]
385        IWorkflowState(self.student).setState('school fee paid')
386        self.browser.open(self.studycourse_path + '/100/edit')
387        self.browser.getControl("Register course list").click()
388        self.assertTrue('Course list has been registered' in self.browser.contents)
389        return
390
391
392    def deactivated_test_student_course_registration(self):
393        # Add more courses
394        self.course2 = createObject('waeup.Course')
395        self.course2.code = 'COURSE2'
396        self.course2.semester = 2
397        self.course2.credits = 10
398        self.course2.passmark = 40
399        self.app['faculties']['fac1']['dep1'].courses.addCourse(
400            self.course2)
401        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
402            self.course2, level=100)
403        self.course3 = createObject('waeup.Course')
404        self.course3.code = 'COURSE3'
405        self.course3.semester = 3
406        self.course3.credits = 10
407        self.course3.passmark = 40
408        self.app['faculties']['fac1']['dep1'].courses.addCourse(
409            self.course3)
410        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
411            self.course3, level=100)
412
413        # Login as student
414        self.browser.open(self.login_path)
415        IWorkflowState(self.student).setState('school fee paid')
416        self.browser.open(self.login_path)
417        self.browser.getControl(name="form.login").value = self.student_id
418        self.browser.getControl(name="form.password").value = 'spwd'
419        self.browser.getControl("Login").click()
420        # Students can add the current study level
421        self.browser.getLink("Study Course").click()
422        self.browser.getLink("Add course list").click()
423        self.assertMatches('...Add current level 100 (Year 1)...',
424                           self.browser.contents)
425        self.browser.getControl("Create course list now").click()
426        # Student has not paid second instalment, therefore a level
427        # with two course ticket was created (semester 1 and combined)
428        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
429        self.browser.getLink("100").click()
430        self.browser.getLink("Edit course list").click()
431        self.browser.getControl("Add course ticket").click()
432        # Student can't add second semester course
433        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
434        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
435        self.assertFalse('<option value="COURSE2">' in self.browser.contents)
436
437        # Let's remove level and see what happens after 2nd instalment payment
438        del(self.student['studycourse']['100'])
439        payment2 = createObject('waeup.StudentOnlinePayment')
440        payment2.p_category = u'schoolfee_2'
441        payment2.p_session = self.student.current_session
442        self.student['payments']['anykey'] = payment2
443        self.browser.open(self.studycourse_path)
444        self.browser.getLink("Add course list").click()
445        self.browser.getControl("Create course list now").click()
446        # Still only 2 tickets have been created since payment ticket
447        # was not paid
448        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
449        payment2.p_state = u'paid'
450        del(self.student['studycourse']['100'])
451        self.browser.open(self.studycourse_path)
452        self.browser.getLink("Add course list").click()
453        self.browser.getControl("Create course list now").click()
454        # Now 2nd semester course has been added
455        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 3)
456        # Student can add second semester course
457        self.browser.getLink("100").click()
458        self.browser.getLink("Edit course list").click()
459        self.browser.getControl("Add course ticket").click()
460        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
461        self.assertTrue('<option value="COURSE2">' in self.browser.contents)
462        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
463        return
464
465    def test_set_matric_number(self):
466        #payment = createObject('waeup.StudentOnlinePayment')
467        #payment.p_category = u'concessional'
468        #payment.p_id = u'anyid'
469        #payment.p_state = u'paid'
470        #self.student['payments']['anykey'] = payment
471        # Login as student
472        self.browser.open(self.login_path)
473        IWorkflowState(self.student).setState('school fee paid')
474        self.browser.open(self.login_path)
475        self.browser.getControl(name="form.login").value = self.student_id
476        self.browser.getControl(name="form.password").value = 'spwd'
477        self.browser.getControl("Login").click()
478        self.assertRaises(
479            LinkNotFoundError,
480            self.browser.getLink, 'Get Matriculation Number')
481        self.student.matric_number = None
482        site = grok.getSite()
483        site['configuration'].next_matric_integer = 1
484        self.student['studycourse'].certificate.study_mode = 'ug_pt'
485        self.browser.open(self.student_path)
486        self.assertRaises(
487            LinkNotFoundError,
488            self.browser.getLink, 'Download matriculation number slip')
489        self.browser.getLink("Get Matriculation Number").click()
490        self.assertTrue('Matriculation number PTP/fac1/dep1/04/00001 assigned.'
491            in self.browser.contents)
492        self.assertEqual(self.student.matric_number, 'PTP/fac1/dep1/04/00001')
493        self.assertRaises(
494            LinkNotFoundError,
495            self.browser.getLink, 'Get Matriculation Number')
496        # Setting matric number is logged.
497        logfile = os.path.join(
498            self.app['datacenter'].storage, 'logs', 'students.log')
499        logcontent = open(logfile).read()
500        self.assertTrue('E1000000 - waeup.aaue.students.browser.StudentGetMatricNumberPage - '
501                        'E1000000 - PTP/fac1/dep1/04/00001 assigned' in logcontent)
502        # Matric Number Slip can be downloaded
503        self.browser.getLink("Download matriculation number slip").click()
504        self.assertEqual(self.browser.headers['Status'], '200 Ok')
505        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
506        path = os.path.join(samples_dir(), 'matric_number_slip.pdf')
507        open(path, 'wb').write(self.browser.contents)
508        print "Sample PDF matric_number_slip.pdf written to %s" % path
509        return
510
511    def test_personal_data_slip(self):
512        # Login as student
513        self.browser.open(self.login_path)
514        IWorkflowState(self.student).setState('school fee paid')
515        self.browser.open(self.login_path)
516        self.browser.getControl(name="form.login").value = self.student_id
517        self.browser.getControl(name="form.password").value = 'spwd'
518        self.browser.getControl("Login").click()
519        self.browser.getLink("Personal Data").click()
520        self.assertRaises(
521            LinkNotFoundError,
522            self.browser.getLink, 'Download personal data slip')
523        self.student.father_name = u'Rudolf'
524        self.browser.open(self.personal_path)
525        self.browser.getLink("Download personal data slip").click()
526        self.assertEqual(self.browser.headers['Status'], '200 Ok')
527        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
528        path = os.path.join(samples_dir(), 'personal_data_slip.pdf')
529        open(path, 'wb').write(self.browser.contents)
530        print "Sample PDF personal_data_slip.pdf written to %s" % path
531        return
532
533    def test_student_course_registration(self):
534        IWorkflowState(self.student).setState('school fee paid')
535        self.browser.open(self.login_path)
536        self.browser.getControl(name="form.login").value = self.student_id
537        self.browser.getControl(name="form.password").value = 'spwd'
538        self.browser.getControl("Login").click()
539        # Now students can add the current study level
540        self.browser.getLink("Study Course").click()
541        self.browser.getLink("Add course list").click()
542        self.assertMatches('...Add current level 100 (Year 1)...',
543                           self.browser.contents)
544        self.browser.getControl("Create course list now").click()
545        # Students can't open the customized pdf course registration slip
546        self.browser.open(
547            self.student_path + '/studycourse/100/course_registration_slip.pdf')
548        self.assertTrue('Forbidden' in self.browser.contents)
549        # They can open slips from the previous session ...
550        self.student['studycourse'].current_level = 200
551        self.browser.open(self.student_path + '/studycourse/100')
552        self.browser.getLink("Download course registration slip").click()
553        self.assertEqual(self.browser.headers['Status'], '200 Ok')
554        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
555        # or if they have registered their course list
556        self.student['studycourse'].current_level = 200
557        IWorkflowState(self.student).setState('courses registered')
558        self.browser.open(self.student_path + '/studycourse/100')
559        self.browser.getLink("Download course registration slip").click()
560        self.assertEqual(self.browser.headers['Status'], '200 Ok')
561        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
562        path = os.path.join(samples_dir(), 'ft_course_registration_slip.pdf')
563        open(path, 'wb').write(self.browser.contents)
564        print "Sample PDF ft_course_registration_slip.pdf written to %s" % path
565
566        self.certificate.study_mode = 'ug_pt'
567        self.browser.open(self.student_path + '/studycourse/100')
568        self.browser.getLink("Download course registration slip").click()
569        self.assertEqual(self.browser.headers['Status'], '200 Ok')
570        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
571        path = os.path.join(samples_dir(), 'pt_course_registration_slip.pdf')
572        open(path, 'wb').write(self.browser.contents)
573        print "Sample PDF pt_course_registration_slip.pdf written to %s" % path
574
575        self.certificate.study_mode = 'special_pg_ft'
576        self.student.matric_number = u'AAU/SPS/FLW/LAW/15/PHD/09504'
577        self.browser.open(self.student_path + '/studycourse/100')
578        self.browser.getLink("Download course registration slip").click()
579        self.assertEqual(self.browser.headers['Status'], '200 Ok')
580        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
581        path = os.path.join(samples_dir(), 'pg_course_registration_slip.pdf')
582        open(path, 'wb').write(self.browser.contents)
583        print "Sample PDF pg_course_registration_slip.pdf written to %s" % path
584
585    def test_student_clearance(self):
586        # Student cant login if their password is not set
587        IWorkflowInfo(self.student).fireTransition('admit')
588        self.browser.open(self.login_path)
589        self.browser.getControl(name="form.login").value = self.student_id
590        self.browser.getControl(name="form.password").value = 'spwd'
591        self.browser.getControl("Login").click()
592        self.assertMatches(
593            '...You logged in...', self.browser.contents)
594        # Admitted student can upload a passport picture
595        self.browser.open(self.student_path + '/change_portrait')
596        ctrl = self.browser.getControl(name='passportuploadedit')
597        file_obj = open(SAMPLE_IMAGE, 'rb')
598        file_ctrl = ctrl.mech_control
599        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
600        self.browser.getControl(
601            name='upload_passportuploadedit').click()
602        self.assertTrue(
603            'src="http://localhost/app/students/E1000000/passport.jpg"'
604            in self.browser.contents)
605        # Student is redirected to the personal data form because
606        # personal data form is not properly filled.
607        self.browser.open(self.student_path + '/start_clearance')
608        self.assertMatches('...Personal data form is not properly filled...',
609                           self.browser.contents)
610        self.assertEqual(self.browser.url, self.student_path + '/edit_personal')
611        self.student.father_name = u'Rudolf'
612        self.browser.open(self.student_path + '/start_clearance')
613        self.assertMatches(
614            '...<h1 class="kofa-content-label">Start clearance</h1>...',
615            self.browser.contents)
616
617    def test_student_accommodation(self):
618        del self.student['accommodation']['2004']
619        self.student['studycourse'].certificate.study_mode = 'dp_ft'
620        # All beds can be assigned
621        bed1 = self.app['hostels']['hall-1']['hall-1_A_101_A']
622        bed1.bed_type = u'regular_male_all'
623        bed2 = self.app['hostels']['hall-1']['hall-1_A_101_B']
624        bed2.bed_type = u'regular_female_all'
625        notify(grok.ObjectModifiedEvent(bed1))
626        notify(grok.ObjectModifiedEvent(bed2))
627        # Login
628        self.browser.open(self.login_path)
629        self.browser.getControl(name="form.login").value = self.student_id
630        self.browser.getControl(name="form.password").value = 'spwd'
631        self.browser.getControl("Login").click()
632        # Students can book accommodation without AC ...
633        self.browser.open(self.acco_path)
634        IWorkflowInfo(self.student).fireTransition('admit')
635        self.browser.getControl("Book accommodation").click()
636        self.assertTrue(
637            'You are not eligible to book accommodation.'
638            in self.browser.contents)
639        self.student['studycourse'].certificate.study_mode = 'ug_ft'
640        self.browser.getControl("Book accommodation").click()
641        self.assertFalse('Activation Code:' in self.browser.contents)
642        self.browser.getControl("Create bed ticket").click()
643        # Bed is randomly selected but, since there is only
644        # one bed for this student, we know that
645        self.assertEqual(self.student['accommodation']['2004'].bed_coordinates,
646            'Hall 1, Block A, Room 101, Bed A (regular_male_all)')
647        # Only the hall name is displayed
648        self.assertEqual(self.student[
649            'accommodation']['2004'].display_coordinates,
650            'Hall 1')
651        self.assertFalse('Hall 1, Block A, Room 101, Bed A'
652            in self.browser.contents)
653        self.assertTrue('<td>Hall 1</td>'
654            in self.browser.contents)
655        return
656
657    def test_handle_courses_by_lecturer(self):
658        self.app['users'].addUser('mrslecturer', 'mrslecturersecret')
659        self.app['users']['mrslecturer'].email = 'mrslecturer@foo.ng'
660        self.app['users']['mrslecturer'].title = u'Mercedes Benz'
661        # Add course ticket
662        studylevel = createObject(u'waeup.StudentStudyLevel')
663        studylevel.level = 100
664        studylevel.level_session = 2004
665        self.student['studycourse'].addStudentStudyLevel(
666            self.certificate, studylevel)
667        # Assign local Lecturer role for a certificate.
668        course = self.app['faculties']['fac1']['dep1'].courses['COURSE1']
669        prmlocal = IPrincipalRoleManager(course)
670        prmlocal.assignRoleToPrincipal('waeup.local.Lecturer', 'mrslecturer')
671        notify(LocalRoleSetEvent(
672            course, 'waeup.local.Lecturer', 'mrslecturer', granted=True))
673        # Login as lecturer.
674        self.browser.open(self.login_path)
675        self.browser.getControl(name="form.login").value = 'mrslecturer'
676        self.browser.getControl(name="form.password").value = 'mrslecturersecret'
677        self.browser.getControl("Login").click()
678        self.browser.getLink("My Roles").click()
679        self.browser.getLink(
680            "http://localhost/app/faculties/fac1/dep1/courses/COURSE1").click()
681        # Course results can be batch edited via the edit_courses view.
682        self.app['faculties']['fac1']['dep1'].score_editing_disabled = False
683        self.app['configuration'].current_academic_session = 2004
684        IWorkflowState(self.student).setState('courses validated')
685        self.browser.open(
686            "http://localhost/app/faculties/fac1/dep1/courses/COURSE1/edit_scores")
687        self.assertTrue(
688            'input type="text" name="scores"'
689            in self.browser.contents)
690        self.browser.getControl(name="scores", index=0).value = '55'
691        self.browser.getControl(name="cas", index=0).value = '66'
692        self.browser.getControl("Update scores").click()
693        # New score and ca has been set.
694        self.assertEqual(
695            self.student['studycourse']['100']['COURSE1'].score, 55)
696        self.assertEqual(
697            self.student['studycourse']['100']['COURSE1'].ca, 66)
698        # Score editing has been logged.
699        logfile = os.path.join(
700            self.app['datacenter'].storage, 'logs', 'students.log')
701        logcontent = open(logfile).read()
702        self.assertTrue('mrslecturer - waeup.aaue.students.browser.CustomEditScoresPage - '
703                        'E1000000 100/COURSE1 score updated (55)' in logcontent)
704        self.assertTrue('mrslecturer - waeup.aaue.students.browser.CustomEditScoresPage - '
705                        'E1000000 100/COURSE1 ca updated (66)' in logcontent)
706        # Non-integer scores won't be accepted.
707        self.browser.open(
708            "http://localhost/app/faculties/fac1/dep1/courses/COURSE1/edit_scores")
709        self.assertTrue('value="55" />' in self.browser.contents)
710        self.browser.getControl(name="scores", index=0).value = 'abc'
711        self.browser.getControl("Update scores").click()
712        self.assertTrue('Error: Score(s) and CA(s) of Anna Tester have not be updated.'
713            in self.browser.contents)
714        # Scores can be removed.
715        self.browser.open(
716            "http://localhost/app/faculties/fac1/dep1/courses/COURSE1/edit_scores")
717        self.browser.getControl(name="scores", index=0).value = ''
718        self.browser.getControl("Update scores").click()
719        self.assertEqual(
720            self.student['studycourse']['100']['COURSE1'].score, None)
721        logcontent = open(logfile).read()
722        self.assertTrue('mrslecturer - waeup.aaue.students.browser.CustomEditScoresPage - '
723                        'E1000000 100/COURSE1 score updated (None)' in logcontent)
Note: See TracBrowser for help on using the repository browser.