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

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

Define PAYMENT_CATEGORIES in CustomKofaUtils?.

Fix tests.

  • Property svn:keywords set to Id
File size: 18.3 KB
Line 
1## $Id: test_browser.py 9755 2012-12-01 10:05:53Z 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 StudentUITests(StudentsFullSetup):
68    """Tests for customized student class views and pages
69    """
70
71    layer = FunctionalLayer
72
73    def setUp(self):
74        super(StudentUITests, self).setUp()
75
76        bedticket = BedTicket()
77        bedticket.booking_session = 2004
78        bedticket.bed_type = u'any bed type'
79        bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
80        bedticket.bed_coordinates = u'My bed coordinates'
81        self.student['accommodation'].addBedTicket(bedticket)
82
83    def test_manage_payments(self):
84        # Add missing configuration data
85        self.app['configuration']['2004'].gown_fee = 150.0
86        self.app['configuration']['2004'].transfer_fee = 90.0
87        self.app['configuration']['2004'].booking_fee = 150.0
88        self.app['configuration']['2004'].maint_fee = 180.0
89
90        # Managers can add online payment tickets
91        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
92        self.browser.open(self.payments_path)
93        self.browser.getLink("Add current session payment ticket").click()
94        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
95        self.browser.getControl("Create ticket").click()
96        self.assertMatches('...Wrong state...',
97                           self.browser.contents)
98        IWorkflowState(self.student).setState('cleared')
99        self.browser.open(self.payments_path + '/addop')
100        self.browser.getControl("Create ticket").click()
101        self.assertMatches('...Amount could not be determined...',
102                           self.browser.contents)
103        self.app['configuration']['2004'].school_fee_base = 6666.0
104        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
105        self.browser.getControl("Create ticket").click()
106        self.assertMatches('...ticket created...',
107                           self.browser.contents)
108        ctrl = self.browser.getControl(name='val_id')
109        value = ctrl.options[0]
110        self.browser.getLink(value).click()
111        self.assertMatches('...Amount Authorized...',
112                           self.browser.contents)
113        # Managers can open payment slip
114        self.browser.getLink("Download payment slip").click()
115        self.assertEqual(self.browser.headers['Status'], '200 Ok')
116        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
117        # Set ticket paid
118        ticket = self.student['payments'].items()[0][1]
119        ticket.p_state = 'paid'
120        self.browser.open(self.payments_path + '/addop')
121        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
122        self.browser.getControl("Create ticket").click()
123        self.assertMatches('...This type of payment has already been made...',
124                           self.browser.contents)
125        self.browser.open(self.payments_path + '/addop')
126        # Also the other payments can be made
127        self.browser.getControl(name="form.p_category").value = ['gown']
128        self.browser.getControl("Create ticket").click()
129        self.assertMatches('...ticket created...',
130                           self.browser.contents)
131        self.browser.open(self.payments_path + '/addop')
132        self.browser.getControl(name="form.p_category").value = ['transfer']
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 = ['bed_allocation']
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(
144            name="form.p_category").value = ['hostel_maintenance']
145        self.browser.getControl("Create ticket").click()
146        self.assertMatches('...ticket created...',
147                           self.browser.contents)
148        self.browser.open(self.payments_path + '/addop')
149        self.browser.getControl(name="form.p_category").value = ['clearance']
150        self.browser.getControl("Create ticket").click()
151        self.assertMatches('...ticket created...',
152                           self.browser.contents)
153        # Remove all payments so that we can add a school fee payment again
154        keys = [i for i in self.student['payments'].keys()]
155        for payment in keys:
156            del self.student['payments'][payment]
157        self.browser.open(self.payments_path + '/addop')
158        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
159        self.browser.getControl("Create ticket").click()
160        self.assertMatches('...ticket created...',
161                           self.browser.contents)
162        # We can't add the 2nd instalment ticket because the
163        # first one has not yet been approved.
164        self.browser.open(self.payments_path + '/addop')
165        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
166        self.browser.getControl("Create ticket").click()
167        self.assertMatches('...1st school fee instalment has not yet been paid...',
168                           self.browser.contents)
169        # Ok, then we approve the first instalment ...
170        self.browser.open(self.payments_path)
171        ctrl = self.browser.getControl(name='val_id')
172        p_id = ctrl.options[0]
173        self.browser.open(self.payments_path + '/' + p_id + '/approve')
174        # ... add the second instalment ...
175        self.browser.open(self.payments_path + '/addop')
176        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
177        self.browser.getControl("Create ticket").click()
178        self.assertMatches('...ticket created...',
179                           self.browser.contents)
180        # ... approve the second instalment ...
181        ctrl = self.browser.getControl(name='val_id')
182        p_id = ctrl.options[1]
183        self.browser.open(self.payments_path + '/' + p_id + '/approve')
184        # ... and finally add the 1st instalment for the next session
185        # provided that student is returning.
186        IWorkflowState(self.student).setState('returning')
187        self.browser.open(self.payments_path + '/addop')
188        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
189        self.browser.getControl("Create ticket").click()
190        self.assertMatches('...Session configuration object is not...',
191                           self.browser.contents)
192        # Uups, we forgot to add a session configuration for next session
193        configuration = createObject('waeup.SessionConfiguration')
194        configuration.academic_session = 2005
195        self.app['configuration'].addSessionConfiguration(configuration)
196        self.app['configuration']['2005'].school_fee_base = 7777.0
197        self.browser.open(self.payments_path + '/addop')
198        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
199        self.browser.getControl("Create ticket").click()
200        self.assertMatches('...ticket created...',
201                           self.browser.contents)
202        # If the session configuration doesn't exist an error message will
203        # be shown. No other requirement is being checked.
204        del self.app['configuration']['2004']
205        self.browser.open(self.payments_path)
206        self.browser.getLink("Add current session payment ticket").click()
207        self.browser.getControl("Create ticket").click()
208        self.assertMatches('...Session configuration object is not...',
209                           self.browser.contents)
210
211    def test_student_payments(self):
212        # Login
213        IWorkflowState(self.student).setState('returning')
214        self.browser.open(self.login_path)
215        self.browser.getControl(name="form.login").value = self.student_id
216        self.browser.getControl(name="form.password").value = 'spwd'
217        self.browser.getControl("Login").click()
218        self.browser.open(self.student_path + '/payments')
219        self.assertTrue(
220          'Add current session payment ticket' in self.browser.contents)
221        self.assertFalse(
222          'Add previous session payment ticket' in self.browser.contents)
223        return
224
225    def test_get_returning_data(self):
226        # Student is in level 100, session 2004 with verdict A
227        utils = getUtility(IStudentsUtils)
228        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
229        self.student['studycourse'].current_verdict = 'C'
230        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
231        self.student['studycourse'].current_verdict = 'D'
232        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
233        return
234
235    def test_set_payment_details(self):
236        self.app['configuration']['2004'].gown_fee = 150.0
237        self.app['configuration']['2004'].transfer_fee = 90.0
238        self.app['configuration']['2004'].booking_fee = 150.0
239        self.app['configuration']['2004'].maint_fee = 180.0
240        self.app['configuration']['2004'].clearance_fee = 1234.0
241        self.app['configuration']['2004'].school_fee_base = 6666.0
242        utils = getUtility(IStudentsUtils)
243
244        configuration = createObject('waeup.SessionConfiguration')
245        configuration.academic_session = 2005
246        self.app['configuration'].addSessionConfiguration(configuration)
247        self.app['configuration']['2005'].school_fee_base = 7777.0
248
249        error, payment = utils.setPaymentDetails('schoolfee_1',self.student)
250        self.assertEqual(payment, None)
251        self.assertEqual(error, u'Wrong state.')
252
253        IWorkflowState(self.student).setState('cleared')
254        error, payment = utils.setPaymentDetails('schoolfee_1',self.student)
255        self.assertEqual(payment.p_level, 100)
256        self.assertEqual(payment.p_session, 2004)
257        self.assertEqual(payment.amount_auth, 6666.0)
258        self.assertEqual(payment.p_item, u'CERT1')
259        self.assertEqual(error, None)
260
261        # Add penalty fee ...
262        # ... for cleared
263        self.app['configuration']['2004'].penalty_ug = 99.0
264        # ... for returning
265        self.app['configuration']['2005'].penalty_ug = 88.0
266        error, payment = utils.setPaymentDetails('schoolfee_1',self.student)
267        self.assertEqual(payment.amount_auth, 6765.0)
268        IWorkflowState(self.student).setState('returning')
269        error, payment = utils.setPaymentDetails('schoolfee_1',self.student)
270        self.assertEqual(payment.p_level, 200)
271        self.assertEqual(payment.p_session, 2005)
272        self.assertEqual(payment.amount_auth, 7865.0)
273        self.assertEqual(payment.p_item, u'CERT1')
274        self.assertEqual(error, None)
275
276        error, payment = utils.setPaymentDetails('clearance',self.student)
277        self.assertEqual(payment.p_level, 100)
278        self.assertEqual(payment.p_session, 2004)
279        self.assertEqual(payment.amount_auth, 1234.0)
280        self.assertEqual(payment.p_item, u'CERT1')
281        self.assertEqual(error, None)
282
283        error, payment = utils.setPaymentDetails('gown',self.student)
284        self.assertEqual(payment.p_level, 100)
285        self.assertEqual(payment.p_session, 2004)
286        self.assertEqual(payment.amount_auth, 150.0)
287        self.assertEqual(payment.p_item, u'')
288        self.assertEqual(error, None)
289
290        error, payment = utils.setPaymentDetails('hostel_maintenance',self.student)
291        self.assertEqual(payment.p_level, 100)
292        self.assertEqual(payment.p_session, 2004)
293        self.assertEqual(payment.amount_auth, 180.0)
294        self.assertEqual(payment.p_item, u'')
295        self.assertEqual(error, None)
296
297        error, payment = utils.setPaymentDetails('bed_allocation',self.student)
298        self.assertEqual(payment.p_level, 100)
299        self.assertEqual(payment.p_session, 2004)
300        self.assertEqual(payment.amount_auth, 150.0)
301        self.assertEqual(payment.p_item, u'')
302        self.assertEqual(error, None)
303
304        error, payment = utils.setPaymentDetails('transfer',self.student)
305        self.assertEqual(payment.p_level, 100)
306        self.assertEqual(payment.p_session, 2004)
307        self.assertEqual(payment.amount_auth, 90.0)
308        self.assertEqual(payment.p_item, u'')
309        self.assertEqual(error, None)
310
311        error, payment = utils.setPaymentDetails('schoolfee',self.student, 2004, 100)
312        self.assertEqual(error, u'Previous session payment not yet implemented.')
313        return
314
315    def test_student_course_registration(self):
316
317        # Add more courses
318        self.course2 = createObject('waeup.Course')
319        self.course2.code = 'COURSE2'
320        self.course2.semester = 2
321        self.course2.credits = 10
322        self.course2.passmark = 40
323        self.app['faculties']['fac1']['dep1'].courses.addCourse(
324            self.course2)
325        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
326            self.course2, level=100)
327        self.course3 = createObject('waeup.Course')
328        self.course3.code = 'COURSE3'
329        self.course3.semester = 3
330        self.course3.credits = 10
331        self.course3.passmark = 40
332        self.app['faculties']['fac1']['dep1'].courses.addCourse(
333            self.course3)
334        self.app['faculties']['fac1']['dep1'].certificates['CERT1'].addCertCourse(
335            self.course3, level=100)
336
337        # Login as student
338        self.browser.open(self.login_path)
339        IWorkflowState(self.student).setState('school fee paid')
340        self.browser.open(self.login_path)
341        self.browser.getControl(name="form.login").value = self.student_id
342        self.browser.getControl(name="form.password").value = 'spwd'
343        self.browser.getControl("Login").click()
344        # Students can add the current study level
345        self.browser.getLink("Study Course").click()
346        self.browser.getLink("Add course list").click()
347        self.assertMatches('...Add current level 100 (Year 1)...',
348                           self.browser.contents)
349        self.browser.getControl("Create course list now").click()
350        # Student has not paid second instalment, therefore a level
351        # with two course ticket was created (semester 1 and combined)
352        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
353        self.browser.getLink("100").click()
354        self.browser.getLink("Edit course list").click()
355        self.browser.getControl("Add course ticket").click()
356        # Student can't add second semester course
357        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
358        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
359        self.assertFalse('<option value="COURSE2">' in self.browser.contents)
360
361        # Let's remove level and see what happens after 2nd instalment payment
362        del(self.student['studycourse']['100'])
363        payment2 = createObject('waeup.StudentOnlinePayment')
364        payment2.p_category = u'schoolfee_2'
365        payment2.p_session = self.student.current_session
366        self.student['payments']['anykey'] = payment2
367        self.browser.open(self.studycourse_path)
368        self.browser.getLink("Add course list").click()
369        self.browser.getControl("Create course list now").click()
370        # Still only 2 tickets have been created since payment ticket
371        # was not paid
372        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 2)
373        payment2.p_state = u'paid'
374        del(self.student['studycourse']['100'])
375        self.browser.open(self.studycourse_path)
376        self.browser.getLink("Add course list").click()
377        self.browser.getControl("Create course list now").click()
378        # Now 2nd semester course has been added
379        self.assertEqual(self.student['studycourse']['100'].number_of_tickets, 3)
380        # Student can add second semester course
381        self.browser.getLink("100").click()
382        self.browser.getLink("Edit course list").click()
383        self.browser.getControl("Add course ticket").click()
384        self.assertTrue('<option value="COURSE1">' in self.browser.contents)
385        self.assertTrue('<option value="COURSE2">' in self.browser.contents)
386        self.assertTrue('<option value="COURSE3">' in self.browser.contents)
387        return
Note: See TracBrowser for help on using the repository browser.