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

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

Customize verdicts.

  • Property svn:keywords set to Id
File size: 19.8 KB
Line 
1## $Id: test_browser.py 10656 2013-09-27 09:52:51Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import os
19import shutil
20import tempfile
21from StringIO import StringIO
22from hurry.workflow.interfaces import IWorkflowState
23from zope.component.hooks import setSite, clearSite
24from zope.component import getUtility, createObject
25from zope.interface import verify
26from waeup.kofa.app import University
27from waeup.kofa.students.tests.test_browser import StudentsFullSetup
28from waeup.kofa.students.accommodation import BedTicket
29from waeup.kofa.testing import FunctionalTestCase
30from waeup.kofa.interfaces import (
31    IExtFileStore, IFileStoreNameChooser)
32from waeup.kofa.students.interfaces import IStudentsUtils
33from waeup.aaue.testing import FunctionalLayer
34
35
36class StudentProcessorTest(FunctionalTestCase):
37    """Perform some batching tests.
38    """
39
40    layer = FunctionalLayer
41
42    def setUp(self):
43        super(StudentProcessorTest, self).setUp()
44        # Setup a sample site for each test
45        app = University()
46        self.dc_root = tempfile.mkdtemp()
47        app['datacenter'].setStoragePath(self.dc_root)
48
49        # Prepopulate the ZODB...
50        self.getRootFolder()['app'] = app
51        # we add the site immediately after creation to the
52        # ZODB. Catalogs and other local utilities are not setup
53        # before that step.
54        self.app = self.getRootFolder()['app']
55        # Set site here. Some of the following setup code might need
56        # to access grok.getSite() and should get our new app then
57        setSite(app)
58
59
60    def tearDown(self):
61        super(StudentProcessorTest, self).tearDown()
62        shutil.rmtree(self.workdir)
63        shutil.rmtree(self.dc_root)
64        clearSite()
65        return
66
67class OfficerUITests(StudentsFullSetup):
68    # Tests for Student class views and pages
69
70    layer = FunctionalLayer
71
72    def test_gpa_calculation(self):
73        studylevel = createObject(u'waeup.StudentStudyLevel')
74        studylevel.level = 100
75        studylevel.level_session = 2005
76        self.student['studycourse'].entry_mode = 'ug_ft'
77        self.student['studycourse'].addStudentStudyLevel(
78            self.certificate, studylevel)
79        # First course has been added automatically.
80        # Set score.
81        studylevel['COURSE1'].score = 55
82        # GPA is 3.0.
83        self.assertEqual(studylevel.gpa_params[0], 3.0)
84        courseticket = createObject('waeup.CourseTicket')
85        courseticket.code = 'ANYCODE'
86        courseticket.title = u'Any TITLE'
87        courseticket.credits = 13
88        courseticket.score = 66
89        courseticket.semester = 1
90        courseticket.dcode = u'ANYDCODE'
91        courseticket.fcode = u'ANYFCODE'
92        studylevel['COURSE2'] = courseticket
93        # total credits
94        self.assertEqual(self.student['studycourse']['100'].gpa_params[1], 23)
95        # weigheted credits = 3 * 10 + 4 * 13
96        self.assertEqual(self.student['studycourse']['100'].gpa_params[2], 82.0)
97        # sgpa = 82 / 23
98        self.assertEqual(self.student['studycourse']['100'].gpa_params[0], 3.565)
99        return
100
101class StudentUITests(StudentsFullSetup):
102    """Tests for customized student class views and pages
103    """
104
105    layer = FunctionalLayer
106
107    def setUp(self):
108        super(StudentUITests, self).setUp()
109
110        bedticket = BedTicket()
111        bedticket.booking_session = 2004
112        bedticket.bed_type = u'any bed type'
113        bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
114        bedticket.bed_coordinates = u'My bed coordinates'
115        self.student['accommodation'].addBedTicket(bedticket)
116
117    def test_manage_payments(self):
118        # Add missing configuration data
119        self.app['configuration']['2004'].gown_fee = 150.0
120        self.app['configuration']['2004'].transfer_fee = 90.0
121        self.app['configuration']['2004'].booking_fee = 150.0
122        self.app['configuration']['2004'].maint_fee = 180.0
123
124        # Managers can add online payment tickets
125        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
126        self.browser.open(self.payments_path)
127        self.browser.getLink("Add current session payment ticket").click()
128        self.browser.getControl(name="form.p_category").value = ['schoolfee']
129        self.browser.getControl("Create ticket").click()
130        self.assertMatches('...Wrong state...',
131                           self.browser.contents)
132        IWorkflowState(self.student).setState('cleared')
133        self.browser.open(self.payments_path + '/addop')
134        self.browser.getControl("Create ticket").click()
135        self.assertMatches('...Amount could not be determined...',
136                           self.browser.contents)
137        self.app['configuration']['2004'].school_fee = 6666.0
138        self.browser.getControl(name="form.p_category").value = ['schoolfee']
139        self.browser.getControl("Create ticket").click()
140        self.assertMatches('...ticket created...',
141                           self.browser.contents)
142        ctrl = self.browser.getControl(name='val_id')
143        value = ctrl.options[0]
144        self.browser.getLink(value).click()
145        self.assertMatches('...Amount Authorized...',
146                           self.browser.contents)
147        # Managers can open payment slip
148        self.browser.getLink("Download payment slip").click()
149        self.assertEqual(self.browser.headers['Status'], '200 Ok')
150        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
151        # Set ticket paid
152        ticket = self.student['payments'].items()[0][1]
153        ticket.p_state = 'paid'
154        self.browser.open(self.payments_path + '/addop')
155        self.browser.getControl(name="form.p_category").value = ['schoolfee']
156        self.browser.getControl("Create ticket").click()
157        self.assertMatches('...This type of payment has already been made...',
158                           self.browser.contents)
159        self.browser.open(self.payments_path + '/addop')
160        # Also the other payments can be made
161        self.browser.getControl(name="form.p_category").value = ['gown']
162        self.browser.getControl("Create ticket").click()
163        self.assertMatches('...ticket created...',
164                           self.browser.contents)
165        self.browser.open(self.payments_path + '/addop')
166        self.browser.getControl(name="form.p_category").value = ['transfer']
167        self.browser.getControl("Create ticket").click()
168        self.assertMatches('...ticket created...',
169                           self.browser.contents)
170        self.browser.open(self.payments_path + '/addop')
171        self.browser.getControl(
172            name="form.p_category").value = ['bed_allocation']
173        self.browser.getControl("Create ticket").click()
174        self.assertMatches('...ticket created...',
175                           self.browser.contents)
176        self.browser.open(self.payments_path + '/addop')
177        self.browser.getControl(
178            name="form.p_category").value = ['hostel_maintenance']
179        self.browser.getControl("Create ticket").click()
180        self.assertMatches('...ticket created...',
181                           self.browser.contents)
182        self.browser.open(self.payments_path + '/addop')
183        self.browser.getControl(name="form.p_category").value = ['clearance']
184        self.browser.getControl("Create ticket").click()
185        self.assertMatches('...ticket created...',
186                           self.browser.contents)
187
188
189    def deactivated_test_for_instalment_payments(self):
190        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
191        self.browser.open(self.payments_path)
192        self.browser.open(self.payments_path + '/addop')
193        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
194        self.browser.getControl("Create ticket").click()
195        self.assertMatches('...ticket created...',
196                           self.browser.contents)
197        # We can't add the 2nd instalment ticket because the
198        # first one has not yet been approved.
199        self.browser.open(self.payments_path + '/addop')
200        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
201        self.browser.getControl("Create ticket").click()
202        self.assertMatches('...1st school fee instalment has not yet been paid...',
203                           self.browser.contents)
204        # Ok, then we approve the first instalment ...
205        self.browser.open(self.payments_path)
206        ctrl = self.browser.getControl(name='val_id')
207        p_id = ctrl.options[0]
208        self.browser.open(self.payments_path + '/' + p_id + '/approve')
209        # ... add the second instalment ...
210        self.browser.open(self.payments_path + '/addop')
211        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
212        self.browser.getControl("Create ticket").click()
213        self.assertMatches('...ticket created...',
214                           self.browser.contents)
215        # ... approve the second instalment ...
216        ctrl = self.browser.getControl(name='val_id')
217        p_id = ctrl.options[1]
218        self.browser.open(self.payments_path + '/' + p_id + '/approve')
219        # ... and finally add the 1st instalment for the next session
220        # provided that student is returning.
221        IWorkflowState(self.student).setState('returning')
222        self.browser.open(self.payments_path + '/addop')
223        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
224        self.browser.getControl("Create ticket").click()
225        self.assertMatches('...Session configuration object is not...',
226                           self.browser.contents)
227        # Uups, we forgot to add a session configuration for next session
228        configuration = createObject('waeup.SessionConfiguration')
229        configuration.academic_session = 2005
230        self.app['configuration'].addSessionConfiguration(configuration)
231        self.app['configuration']['2005'].school_base = 7777.0
232        self.browser.open(self.payments_path + '/addop')
233        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
234        self.browser.getControl("Create ticket").click()
235        self.assertMatches('...ticket created...',
236                           self.browser.contents)
237        # If the session configuration doesn't exist an error message will
238        # be shown. No other requirement is being checked.
239        del self.app['configuration']['2004']
240        self.browser.open(self.payments_path)
241        self.browser.getLink("Add current session payment ticket").click()
242        self.browser.getControl("Create ticket").click()
243        self.assertMatches('...Session configuration object is not...',
244                           self.browser.contents)
245
246    def test_student_payments(self):
247        # Login
248        IWorkflowState(self.student).setState('returning')
249        self.browser.open(self.login_path)
250        self.browser.getControl(name="form.login").value = self.student_id
251        self.browser.getControl(name="form.password").value = 'spwd'
252        self.browser.getControl("Login").click()
253        self.browser.open(self.student_path + '/payments')
254        self.assertTrue(
255          'Add current session payment ticket' in self.browser.contents)
256        self.assertFalse(
257          'Add previous session payment ticket' in self.browser.contents)
258        return
259
260    def test_get_returning_data(self):
261        # Student is in level 100, session 2004 with verdict A
262        utils = getUtility(IStudentsUtils)
263        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
264        self.student['studycourse'].current_verdict = 'C'
265        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
266        self.student['studycourse'].current_verdict = 'NEOR'
267        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
268        return
269
270    def test_set_payment_details(self):
271        self.app['configuration']['2004'].gown_fee = 150.0
272        self.app['configuration']['2004'].transfer_fee = 90.0
273        self.app['configuration']['2004'].booking_fee = 150.0
274        self.app['configuration']['2004'].maint_fee = 180.0
275        self.app['configuration']['2004'].clearance_fee = 1234.0
276        self.app['configuration']['2004'].school_fee = 6666.0
277        utils = getUtility(IStudentsUtils)
278
279        configuration = createObject('waeup.SessionConfiguration')
280        configuration.academic_session = 2005
281        self.app['configuration'].addSessionConfiguration(configuration)
282        self.app['configuration']['2005'].school_fee = 7777.0
283
284        error, payment = utils.setPaymentDetails('schoolfee',self.student)
285        self.assertEqual(payment, None)
286        self.assertEqual(error, u'Wrong state.')
287
288        IWorkflowState(self.student).setState('cleared')
289        error, payment = utils.setPaymentDetails('schoolfee',self.student)
290        self.assertEqual(payment.p_level, 100)
291        self.assertEqual(payment.p_session, 2004)
292        self.assertEqual(payment.amount_auth, 6666.0)
293        self.assertEqual(payment.p_item, u'CERT1')
294        self.assertEqual(error, None)
295
296        # Add penalty fee ...
297        # ... for cleared
298        self.app['configuration']['2004'].penalty_ug = 99.0
299        # ... for returning
300        self.app['configuration']['2005'].penalty_ug = 88.0
301        error, payment = utils.setPaymentDetails('schoolfee',self.student)
302        self.assertEqual(payment.amount_auth, 6765.0)
303        IWorkflowState(self.student).setState('returning')
304        error, payment = utils.setPaymentDetails('schoolfee',self.student)
305        self.assertEqual(payment.p_level, 200)
306        self.assertEqual(payment.p_session, 2005)
307        self.assertEqual(payment.amount_auth, 7865.0)
308        self.assertEqual(payment.p_item, u'CERT1')
309        self.assertEqual(error, None)
310
311        error, payment = utils.setPaymentDetails('clearance',self.student)
312        self.assertEqual(payment.p_level, 100)
313        self.assertEqual(payment.p_session, 2004)
314        self.assertEqual(payment.amount_auth, 1234.0)
315        self.assertEqual(payment.p_item, u'CERT1')
316        self.assertEqual(error, None)
317
318        error, payment = utils.setPaymentDetails('gown',self.student)
319        self.assertEqual(payment.p_level, 100)
320        self.assertEqual(payment.p_session, 2004)
321        self.assertEqual(payment.amount_auth, 150.0)
322        self.assertEqual(payment.p_item, u'')
323        self.assertEqual(error, None)
324
325        error, payment = utils.setPaymentDetails('hostel_maintenance',self.student)
326        self.assertEqual(payment.p_level, 100)
327        self.assertEqual(payment.p_session, 2004)
328        self.assertEqual(payment.amount_auth, 180.0)
329        self.assertEqual(payment.p_item, u'')
330        self.assertEqual(error, None)
331
332        error, payment = utils.setPaymentDetails('bed_allocation',self.student)
333        self.assertEqual(payment.p_level, 100)
334        self.assertEqual(payment.p_session, 2004)
335        self.assertEqual(payment.amount_auth, 150.0)
336        self.assertEqual(payment.p_item, u'')
337        self.assertEqual(error, None)
338
339        error, payment = utils.setPaymentDetails('transfer',self.student)
340        self.assertEqual(payment.p_level, 100)
341        self.assertEqual(payment.p_session, 2004)
342        self.assertEqual(payment.amount_auth, 90.0)
343        self.assertEqual(payment.p_item, u'')
344        self.assertEqual(error, None)
345
346        error, payment = utils.setPaymentDetails('schoolfee',self.student, 2004, 100)
347        self.assertEqual(error, u'Previous session payment not yet implemented.')
348        return
349
350    def deactivated_test_student_course_registration(self):
351
352        # Add more courses
353        self.course2 = createObject('waeup.Course')
354        self.course2.code = 'COURSE2'
355        self.course2.semester = 2
356        self.course2.credits = 10
357        self.course2.passmark = 40
358        self.app['faculties']['fac1']['dep1'].courses.addCourse(
359            self.course2)
360        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
361            self.course2, level=100)
362        self.course3 = createObject('waeup.Course')
363        self.course3.code = 'COURSE3'
364        self.course3.semester = 3
365        self.course3.credits = 10
366        self.course3.passmark = 40
367        self.app['faculties']['fac1']['dep1'].courses.addCourse(
368            self.course3)
369        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
370            self.course3, level=100)
371
372        # Login as student
373        self.browser.open(self.login_path)
374        IWorkflowState(self.student).setState('school fee paid')
375        self.browser.open(self.login_path)
376        self.browser.getControl(name="form.login").value = self.student_id
377        self.browser.getControl(name="form.password").value = 'spwd'
378        self.browser.getControl("Login").click()
379        # Students can add the current study level
380        self.browser.getLink("Study Course").click()
381        self.browser.getLink("Add course list").click()
382        self.assertMatches('...Add current level 100 (Year 1)...',
383                           self.browser.contents)
384        self.browser.getControl("Create course list now").click()
385        # Student has not paid second instalment, therefore a level
386        # with two course ticket was created (semester 1 and combined)
387        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
388        self.browser.getLink("100").click()
389        self.browser.getLink("Edit course list").click()
390        self.browser.getControl("Add course ticket").click()
391        # Student can't add second semester course
392        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
393        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
394        self.assertFalse('<option value="COURSE2">' in self.browser.contents)
395
396        # Let's remove level and see what happens after 2nd instalment payment
397        del(self.student['studycourse']['100'])
398        payment2 = createObject('waeup.StudentOnlinePayment')
399        payment2.p_category = u'schoolfee_2'
400        payment2.p_session = self.student.current_session
401        self.student['payments']['anykey'] = payment2
402        self.browser.open(self.studycourse_path)
403        self.browser.getLink("Add course list").click()
404        self.browser.getControl("Create course list now").click()
405        # Still only 2 tickets have been created since payment ticket
406        # was not paid
407        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
408        payment2.p_state = u'paid'
409        del(self.student['studycourse']['100'])
410        self.browser.open(self.studycourse_path)
411        self.browser.getLink("Add course list").click()
412        self.browser.getControl("Create course list now").click()
413        # Now 2nd semester course has been added
414        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 3)
415        # Student can add second semester course
416        self.browser.getLink("100").click()
417        self.browser.getLink("Edit course list").click()
418        self.browser.getControl("Add course ticket").click()
419        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
420        self.assertTrue('<option value="COURSE2">' in self.browser.contents)
421        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
422        return
423
424    def test_maxCredits(self):
425        dummy = object()
426        utils = getUtility(IStudentsUtils)
427        self.assertEqual(utils.maxCredits(dummy), 48)
428        return
Note: See TracBrowser for help on using the repository browser.