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

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

Add StudyCourseCOEditFormPage (see Uniben ticket 626).

  • Property svn:keywords set to Id
File size: 18.9 KB
Line 
1## $Id: test_browser.py 9210 2012-09-21 06:10:00Z 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.testing import FunctionalTestCase
32from waeup.kofa.interfaces import (
33    IExtFileStore, IFileStoreNameChooser)
34from waeup.kofa.students.interfaces import IStudentsUtils
35from waeup.uniben.testing import FunctionalLayer
36
37
38class StudentProcessorTest(FunctionalTestCase):
39    """Perform some batching tests.
40    """
41
42    layer = FunctionalLayer
43
44    def setUp(self):
45        super(StudentProcessorTest, self).setUp()
46        # Setup a sample site for each test
47        app = University()
48        self.dc_root = tempfile.mkdtemp()
49        app['datacenter'].setStoragePath(self.dc_root)
50
51        # Prepopulate the ZODB...
52        self.getRootFolder()['app'] = app
53        # we add the site immediately after creation to the
54        # ZODB. Catalogs and other local utilities are not setup
55        # before that step.
56        self.app = self.getRootFolder()['app']
57        # Set site here. Some of the following setup code might need
58        # to access grok.getSite() and should get our new app then
59        setSite(app)
60
61
62    def tearDown(self):
63        super(StudentProcessorTest, self).tearDown()
64        shutil.rmtree(self.workdir)
65        shutil.rmtree(self.dc_root)
66        clearSite()
67        return
68
69class StudentUITests(StudentsFullSetup):
70    """Tests for customized student class views and pages
71    """
72
73    layer = FunctionalLayer
74
75    def test_manage_payments(self):
76        # Add missing configuration data
77        self.app['configuration']['2004'].gown_fee = 150.0
78        self.app['configuration']['2004'].transfer_fee = 90.0
79        #self.app['configuration']['2004'].clearance_fee = 120.0
80        self.app['configuration']['2004'].booking_fee = 150.0
81        self.app['configuration']['2004'].maint_fee = 180.0
82
83        # Managers can add online payment tickets
84        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
85        self.browser.open(self.payments_path)
86        self.browser.getControl("Add online payment ticket").click()
87        self.browser.getControl("Create ticket").click()
88        self.assertMatches('...Amount could not be determined...',
89                           self.browser.contents)
90        IWorkflowState(self.student).setState('cleared')
91        self.student.nationality = u'NG'
92        self.browser.open(self.payments_path + '/addop')
93        self.browser.getControl("Create ticket").click()
94        self.assertMatches('...ticket created...',
95                           self.browser.contents)
96        ctrl = self.browser.getControl(name='val_id')
97        value = ctrl.options[0]
98        self.browser.getLink(value).click()
99        self.assertMatches('...Amount Authorized...',
100                           self.browser.contents)
101        # Managers can open payment slip
102        self.browser.getLink("Download payment slip").click()
103        self.assertEqual(self.browser.headers['Status'], '200 Ok')
104        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
105        # Set ticket paid
106        ticket = self.student['payments'].items()[0][1]
107        ticket.p_state = 'paid'
108        self.browser.open(self.payments_path + '/addop')
109        self.browser.getControl("Create ticket").click()
110        self.assertMatches('...This type of payment has already been made...',
111                           self.browser.contents)
112        # Remove all payments so that we can add a school fee payment again
113        keys = [i for i in self.student['payments'].keys()]
114        for payment in keys:
115            del self.student['payments'][payment]
116        self.browser.open(self.payments_path + '/addop')
117        self.browser.getControl("Create ticket").click()
118        self.assertMatches('...ticket created...',
119                           self.browser.contents)
120        self.browser.open(self.payments_path + '/addop')
121        self.browser.getControl(name="form.p_category").value = ['gown']
122        self.browser.getControl("Create ticket").click()
123        self.assertMatches('...ticket created...',
124                           self.browser.contents)
125        self.browser.open(self.payments_path + '/addop')
126        self.browser.getControl(name="form.p_category").value = ['transfer']
127        self.browser.getControl("Create ticket").click()
128        self.assertMatches('...ticket created...',
129                           self.browser.contents)
130        self.browser.open(self.payments_path + '/addop')
131        self.browser.getControl(
132            name="form.p_category").value = ['bed_allocation']
133        self.browser.getControl("Create ticket").click()
134        self.assertMatches('...ticket created...',
135                           self.browser.contents)
136        self.browser.open(self.payments_path + '/addop')
137        self.browser.getControl(
138            name="form.p_category").value = ['hostel_maintenance']
139        self.browser.getControl("Create ticket").click()
140        self.assertMatches('...ticket created...',
141                           self.browser.contents)
142        self.browser.open(self.payments_path + '/addop')
143        self.browser.getControl(name="form.p_category").value = ['clearance']
144        self.browser.getControl("Create ticket").click()
145        self.assertMatches('...ticket created...',
146                           self.browser.contents)
147        self.browser.open(self.payments_path + '/addop')
148        self.browser.getControl(name="form.p_category").value = ['schoolfee']
149        self.browser.getControl("Create ticket").click()
150        self.assertMatches('...ticket created...',
151                           self.browser.contents)
152        # In state returning we can add a new school fee ticket since
153        # p_session and p_level is different
154        IWorkflowState(self.student).setState('returning')
155        self.browser.open(self.payments_path + '/addop')
156        self.browser.getControl(name="form.p_category").value = ['schoolfee']
157        self.browser.getControl("Create ticket").click()
158        self.assertMatches('...Session configuration object is not...',
159                           self.browser.contents)
160        # Uups, we forgot to add a session configuration for next session
161        configuration = createObject('waeup.SessionConfiguration')
162        configuration.academic_session = 2005
163        self.app['configuration'].addSessionConfiguration(configuration)
164        self.browser.open(self.payments_path + '/addop')
165        self.browser.getControl(name="form.p_category").value = ['schoolfee']
166        self.browser.getControl("Create ticket").click()
167        self.assertMatches('...ticket created...',
168                           self.browser.contents)
169        # In state admitted school fee can't be determined
170        IWorkflowState(self.student).setState('admitted')
171        self.browser.open(self.payments_path + '/addop')
172        self.browser.getControl(name="form.p_category").value = ['schoolfee']
173        self.browser.getControl("Create ticket").click()
174        self.assertMatches('...Amount could not be determined...',
175                           self.browser.contents)
176
177        # If the session configuration doesn't exist an error message will
178        # be shown. No other requirement is being checked.
179        del self.app['configuration']['2004']
180        self.browser.open(self.payments_path)
181        self.browser.getControl("Add online payment ticket").click()
182        self.browser.getControl("Create ticket").click()
183        self.assertMatches('...Session configuration object is not...',
184                           self.browser.contents)
185
186    def test_get_returning_data(self):
187        # Student is in level 100, session 2004 with verdict A
188        utils = getUtility(IStudentsUtils)
189        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
190        self.student['studycourse'].current_verdict = 'C'
191        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
192        self.student['studycourse'].current_verdict = 'D'
193        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
194        return
195
196    def test_set_returning_data(self):
197        # Student is in level 100, session 2004 with verdict A
198        utils = getUtility(IStudentsUtils)
199
200        utils.setReturningData(self.student)
201        self.assertEqual(self.student['studycourse'].current_session, 2005)
202        self.assertEqual(self.student['studycourse'].current_level, 200)
203
204        self.student['studycourse'].current_session = 2004
205        self.student['studycourse'].current_level = 100
206        self.student['studycourse'].current_verdict = 'C'
207        utils.setReturningData(self.student)
208        self.assertEqual(self.student['studycourse'].current_session, 2005)
209        self.assertEqual(self.student['studycourse'].current_level, 110)
210
211        self.student['studycourse'].current_session = 2004
212        self.student['studycourse'].current_level = 100
213        self.student['studycourse'].current_verdict = 'D'
214        utils.setReturningData(self.student)
215        self.assertEqual(self.student['studycourse'].current_session, 2005)
216        self.assertEqual(self.student['studycourse'].current_level, 100)
217        return
218
219    def test_set_payment_details(self):
220        self.app['configuration']['2004'].gown_fee = 150.0
221        self.app['configuration']['2004'].transfer_fee = 90.0
222        self.app['configuration']['2004'].booking_fee = 150.0
223        self.app['configuration']['2004'].maint_fee = 180.0
224
225        configuration = createObject('waeup.SessionConfiguration')
226        configuration.academic_session = 2000
227        self.app['configuration'].addSessionConfiguration(configuration)
228        configuration2 = createObject('waeup.SessionConfiguration')
229        configuration2.academic_session = 2002
230        self.app['configuration'].addSessionConfiguration(configuration2)
231        configuration3 = createObject('waeup.SessionConfiguration')
232        configuration3.academic_session = 2003
233        self.app['configuration'].addSessionConfiguration(configuration3)
234
235        utils = getUtility(IStudentsUtils)
236
237        self.student['studycourse'].entry_session = 2002
238        self.student.nationality = u'NG'
239
240        configuration = createObject('waeup.SessionConfiguration')
241        configuration.academic_session = 2005
242        self.app['configuration'].addSessionConfiguration(configuration)
243
244        error, payment = utils.setPaymentDetails('schoolfee',
245            self.student, None, None)
246        self.assertEqual(payment, None)
247        self.assertTrue(u'Amount could not be determined.' in error)
248
249        # Previous session must be valid.
250        error, payment = utils.setPaymentDetails('schoolfee',
251            self.student, 2000, 300)
252        self.assertEqual(payment, None)
253        self.assertTrue(u'The previous session must not fall below' in error)
254        error, payment = utils.setPaymentDetails('schoolfee',
255            self.student, 2004, 300)
256        self.assertEqual(payment, None)
257        self.assertTrue(u'This is not a previous session' in error)
258
259        # Previous session payment; fresh and returning
260        # are distinguished by their entry_level
261        error, payment = utils.setPaymentDetails('schoolfee',
262            self.student, 2002, 300)
263        self.assertEqual(payment.amount_auth, 40000.0)
264        self.assertEqual(payment.p_session, 2002)
265        self.assertEqual(payment.p_level, 300)
266        self.assertFalse(payment.p_current)
267        error, payment = utils.setPaymentDetails('schoolfee',
268            self.student, 2003, 300)
269        self.assertEqual(payment.amount_auth, 20000.0)
270        self.assertEqual(payment.p_session, 2003)
271        self.assertEqual(payment.p_level, 300)
272        self.assertFalse(payment.p_current)
273
274        # Current payment; fresh and returning
275        # are distinguished by their state
276        IWorkflowState(self.student).setState('cleared')
277        error, payment = utils.setPaymentDetails('schoolfee',
278            self.student, None, None)
279        self.assertEqual(payment.p_level, 100)
280        self.assertEqual(payment.p_session, 2004)
281        self.assertEqual(payment.amount_auth, 40000.0)
282        self.assertEqual(payment.p_item, u'CERT1')
283        self.assertEqual(error, None)
284        self.assertTrue(payment.p_current)
285
286        # Add penalty fee ...
287        # ... for cleared
288        self.app['configuration']['2004'].penalty_ug = 99.0
289        # ... for returning
290        self.app['configuration']['2005'].penalty_ug = 88.0
291        error, payment = utils.setPaymentDetails('schoolfee',
292            self.student, None, None)
293        self.assertEqual(payment.amount_auth, 40099.0)
294
295        IWorkflowState(self.student).setState('returning')
296        error, payment = utils.setPaymentDetails('schoolfee',
297            self.student, None, None)
298        self.assertEqual(payment.p_level, 200)
299        self.assertEqual(payment.p_session, 2005)
300        self.assertEqual(payment.amount_auth, 20088.0)
301        self.assertEqual(payment.p_item, u'CERT1')
302        self.assertEqual(error, None)
303
304        self.student.is_staff = True
305        error, payment = utils.setPaymentDetails('schoolfee',
306            self.student, None, None)
307        self.assertEqual(payment.p_level, 200)
308        self.assertEqual(payment.p_session, 2005)
309        self.assertEqual(payment.amount_auth, 10088.0)
310        self.assertEqual(payment.p_item, u'CERT1')
311        self.assertEqual(error, None)
312
313        IWorkflowState(self.student).setState('cleared')
314        self.student.is_staff = False
315        self.student.nationality = u'DE'
316        self.certificate.school_fee_3 = 60000.0
317        error, payment = utils.setPaymentDetails(
318            'schoolfee', self.student, None, None)
319        self.assertEqual(payment.p_level, 100)
320        self.assertEqual(payment.p_session, 2004)
321        self.assertEqual(payment.amount_auth, 60099.0)
322        self.assertEqual(payment.p_item, u'CERT1')
323        self.assertEqual(error, None)
324
325        IWorkflowState(self.student).setState('returning')
326        self.student.is_staff = False
327        self.student.nationality = u'DE'
328        self.certificate.school_fee_4 = 20000.0
329        error, payment = utils.setPaymentDetails(
330            'schoolfee', self.student, None, None)
331        self.assertEqual(payment.p_level, 200)
332        self.assertEqual(payment.p_session, 2005)
333        self.assertEqual(payment.amount_auth, 20088.0)
334        self.assertEqual(payment.p_item, u'CERT1')
335        self.assertEqual(error, None)
336
337        error, payment = utils.setPaymentDetails('clearance',
338            self.student, None, None)
339        self.assertEqual(payment.p_level, 100)
340        self.assertEqual(payment.p_session, 2004)
341        self.assertEqual(payment.amount_auth, 34250.0)
342        self.assertEqual(payment.p_item, u'CERT1')
343        self.assertEqual(error, None)
344
345        error, payment = utils.setPaymentDetails('gown',
346            self.student, None, None)
347        self.assertEqual(payment.p_level, 100)
348        self.assertEqual(payment.p_session, 2004)
349        self.assertEqual(payment.amount_auth, 150.0)
350        self.assertEqual(payment.p_item, u'')
351        self.assertEqual(error, None)
352
353        error, payment = utils.setPaymentDetails('hostel_maintenance',
354            self.student, None, None)
355        self.assertEqual(payment.p_level, 100)
356        self.assertEqual(payment.p_session, 2004)
357        self.assertEqual(payment.amount_auth, 180.0)
358        self.assertEqual(payment.p_item, u'')
359        self.assertEqual(error, None)
360
361        error, payment = utils.setPaymentDetails('bed_allocation',
362            self.student, None, None)
363        self.assertEqual(payment.p_level, 100)
364        self.assertEqual(payment.p_session, 2004)
365        self.assertEqual(payment.amount_auth, 150.0)
366        self.assertEqual(payment.p_item, u'')
367        self.assertEqual(error, None)
368
369        error, payment = utils.setPaymentDetails('transfer',
370            self.student, None, None)
371        self.assertEqual(payment.p_level, 100)
372        self.assertEqual(payment.p_session, 2004)
373        self.assertEqual(payment.amount_auth, 90.0)
374        self.assertEqual(payment.p_item, u'')
375        self.assertEqual(error, None)
376        return
377
378    def test_edit_level_by_co(self):
379        # Create clearance officer
380        self.app['users'].addUser('mrclear', 'mrclearsecret')
381        self.app['users']['mrclear'].email = 'mrclear@foo.ng'
382        self.app['users']['mrclear'].title = 'Carlo Pitter'
383        # Assign local ClearanceOfficer role
384        department = self.app['faculties']['fac1']['dep1']
385        prmlocal = IPrincipalRoleManager(department)
386        prmlocal.assignRoleToPrincipal('waeup.local.ClearanceOfficer', 'mrclear')
387        notify(LocalRoleSetEvent(
388            department, 'waeup.local.ClearanceOfficer', 'mrclear', granted=True))
389        IWorkflowState(self.student).setState('clearance started')
390        # Login as clearance officer
391        self.browser.open(self.login_path)
392        self.browser.getControl(name="form.login").value = 'mrclear'
393        self.browser.getControl(name="form.password").value = 'mrclearsecret'
394        self.browser.getControl("Login").click()
395        self.assertMatches('...You logged in...', self.browser.contents)
396        # Only in state clearance requested the CO does see the
397        # 'Edit level' button ...
398        self.browser.open(self.studycourse_path)
399        self.assertFalse('Edit level' in self.browser.contents)
400        # ... and can open the edit_level view
401        self.browser.open(self.studycourse_path + '/edit_level')
402        self.assertMatches('...is locked...', self.browser.contents)
403        self.assertEqual(self.browser.url, self.studycourse_path)
404        IWorkflowInfo(self.student).fireTransition('request_clearance')
405        self.browser.open(self.studycourse_path)
406        self.assertTrue('Edit level' in self.browser.contents)
407        self.browser.getLink("Edit level").click()
408        self.browser.getControl(name="form.current_level").value = ['200']
409        self.browser.getControl("Save").click()
410        self.assertMatches('...has been saved...', self.browser.contents)
411        self.assertEqual(self.student.current_level, 200)
Note: See TracBrowser for help on using the repository browser.