source: main/waeup.kwarapoly/trunk/src/waeup/kwarapoly/students/tests/test_browser.py @ 10009

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

Use carryover categories only for calculation of fee, then change to schoolfee.

Configure SELECTABLE_PAYMENT_CATEGORIES.

Add and adjust tests.

  • Property svn:keywords set to Id
File size: 15.4 KB
Line 
1## $Id: test_browser.py 9737 2012-11-28 17:00:43Z 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.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 (
28    StudentsFullSetup, SAMPLE_IMAGE)
29from waeup.kofa.students.accommodation import BedTicket
30from waeup.kofa.testing import FunctionalTestCase
31from waeup.kofa.interfaces import (
32    IExtFileStore, IFileStoreNameChooser)
33from waeup.kofa.students.interfaces import IStudentsUtils
34from waeup.kwarapoly.testing import FunctionalLayer
35from waeup.kwarapoly.students.utils import (
36    local_nonlocal, arts_science, pt_ft)
37
38
39class StudentProcessorTest(FunctionalTestCase):
40    """Perform some batching tests.
41    """
42
43    layer = FunctionalLayer
44
45    def setUp(self):
46        super(StudentProcessorTest, self).setUp()
47        # Setup a sample site for each test
48        app = University()
49        self.dc_root = tempfile.mkdtemp()
50        app['datacenter'].setStoragePath(self.dc_root)
51
52        # Prepopulate the ZODB...
53        self.getRootFolder()['app'] = app
54        # we add the site immediately after creation to the
55        # ZODB. Catalogs and other local utilities are not setup
56        # before that step.
57        self.app = self.getRootFolder()['app']
58        # Set site here. Some of the following setup code might need
59        # to access grok.getSite() and should get our new app then
60        setSite(app)
61
62
63    def tearDown(self):
64        super(StudentProcessorTest, self).tearDown()
65        shutil.rmtree(self.workdir)
66        shutil.rmtree(self.dc_root)
67        clearSite()
68        return
69
70class StudentUITests(StudentsFullSetup):
71    """Tests for customized student class views and pages
72    """
73
74    layer = FunctionalLayer
75
76    def setUp(self):
77        super(StudentUITests, self).setUp()
78
79        bedticket = BedTicket()
80        bedticket.booking_session = 2004
81        bedticket.bed_type = u'any bed type'
82        bedticket.bed = self.app['hostels']['hall-1']['hall-1_A_101_A']
83        bedticket.bed_coordinates = u'My bed coordinates'
84        self.student['accommodation'].addBedTicket(bedticket)
85
86    def test_manage_payments(self):
87        # Add missing configuration data
88        self.app['configuration']['2004'].gown_fee = 150.0
89        self.app['configuration']['2004'].transfer_fee = 90.0
90        self.app['configuration']['2004'].clearance_fee = 120.0
91        self.app['configuration']['2004'].booking_fee = 150.0
92        self.app['configuration']['2004'].maint_fee = 180.0
93
94        # Managers can add online payment tickets
95        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
96        self.browser.open(self.payments_path)
97        self.browser.getLink("Add current session payment ticket").click()
98        self.browser.getControl(name="form.p_category").value = ['schoolfee']
99        self.browser.getControl("Create ticket").click()
100        self.assertMatches('...Amount could not be determined...',
101                           self.browser.contents)
102        IWorkflowState(self.student).setState('cleared')
103        self.browser.open(self.payments_path + '/addop')
104        self.browser.getControl(name="form.p_category").value = ['schoolfee']
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']
122        self.browser.getControl("Create ticket").click()
123        self.assertMatches('...This type of payment has already been made...',
124                           self.browser.contents)
125        # Remove all payments so that we can add a school fee payment again
126        keys = [i for i in self.student['payments'].keys()]
127        for payment in keys:
128            del self.student['payments'][payment]
129        self.browser.open(self.payments_path + '/addop')
130        self.browser.getControl(name="form.p_category").value = ['schoolfee']
131        self.browser.getControl("Create ticket").click()
132        self.assertMatches('...ticket created...',
133                           self.browser.contents)
134        self.browser.open(self.payments_path + '/addop')
135        self.browser.getControl(name="form.p_category").value = ['carryover1']
136        self.browser.getControl("Create ticket").click()
137        self.assertMatches('...ticket created...',
138                           self.browser.contents)
139        self.browser.open(self.payments_path + '/addop')
140        self.browser.getControl(name="form.p_category").value = ['carryover2']
141        self.browser.getControl("Create ticket").click()
142        self.assertMatches('...ticket created...',
143                           self.browser.contents)
144        self.browser.open(self.payments_path + '/addop')
145        self.browser.getControl(name="form.p_category").value = ['carryover3']
146        self.browser.getControl("Create ticket").click()
147        self.assertMatches('...ticket created...',
148                           self.browser.contents)
149        self.browser.open(self.payments_path + '/addop')
150        self.browser.getControl(
151            name="form.p_category").value = ['hostel_maintenance']
152        self.browser.getControl("Create ticket").click()
153        self.assertMatches('...ticket created...',
154                           self.browser.contents)
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('...ticket created...',
159                           self.browser.contents)
160        # In state returning we can add a new school fee ticket since
161        # p_session and p_level is different
162        IWorkflowState(self.student).setState('returning')
163        self.browser.open(self.payments_path + '/addop')
164        self.browser.getControl(name="form.p_category").value = ['schoolfee']
165        self.browser.getControl("Create ticket").click()
166        # Uups, we forgot to add a session configuration for next session
167        self.assertTrue('Session configuration object is not available.'
168            in self.browser.contents)
169        configuration = createObject('waeup.SessionConfiguration')
170        configuration.academic_session = 2005
171        self.app['configuration'].addSessionConfiguration(configuration)
172        self.browser.getControl("Create ticket").click()
173        self.assertMatches('...ticket created...',
174                           self.browser.contents)
175        # In state admitted school fee can't be determined
176        IWorkflowState(self.student).setState('admitted')
177        self.browser.open(self.payments_path + '/addop')
178        self.browser.getControl(name="form.p_category").value = ['schoolfee']
179        self.browser.getControl("Create ticket").click()
180        self.assertMatches('...Amount could not be determined...',
181                           self.browser.contents)
182
183    def test_student_payments(self):
184        # Login
185        IWorkflowState(self.student).setState('returning')
186        self.browser.open(self.login_path)
187        self.browser.getControl(name="form.login").value = self.student_id
188        self.browser.getControl(name="form.password").value = 'spwd'
189        self.browser.getControl("Login").click()
190        self.browser.open(self.student_path + '/payments')
191        self.assertTrue(
192          'Add current session payment ticket' in self.browser.contents)
193        self.assertFalse(
194          'Add previous session payment ticket' in self.browser.contents)
195        return
196
197    def test_get_returning_data(self):
198        # Student is in level 100, session 2004 with verdict A
199        utils = getUtility(IStudentsUtils)
200        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
201        self.student['studycourse'].current_verdict = 'C'
202        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
203        self.student['studycourse'].current_verdict = 'D'
204        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
205        return
206
207    def test_set_payment_details(self):
208        self.app['configuration']['2004'].gown_fee = 150.0
209        self.app['configuration']['2004'].transfer_fee = 90.0
210        self.app['configuration']['2004'].booking_fee = 150.0
211        self.app['configuration']['2004'].maint_fee = 180.0
212        self.app['configuration']['2004'].clearance_fee = 120.0
213        utils = getUtility(IStudentsUtils)
214
215        error, payment = utils.setPaymentDetails('schoolfee',self.student)
216        self.assertEqual(payment, None)
217        self.assertEqual(error, u'Amount could not be determined.')
218
219        IWorkflowState(self.student).setState('cleared')
220        self.assertEqual(local_nonlocal(self.student), 'non-local')
221        self.assertEqual(arts_science(self.student), 'science')
222        self.assertEqual(pt_ft(self.student), 'ft')
223
224        error, payment = utils.setPaymentDetails('schoolfee',self.student)
225        self.assertEqual(payment.p_level, 100)
226        self.assertEqual(payment.p_session, 2004)
227        self.assertEqual(payment.amount_auth, 52100.0)
228        self.assertEqual(payment.p_item, u'CERT1')
229        self.assertEqual(error, None)
230
231        IWorkflowState(self.student).setState('returning')
232        error, payment = utils.setPaymentDetails('schoolfee',self.student)
233        self.assertEqual('Session configuration object is not available.', error)
234        configuration = createObject('waeup.SessionConfiguration')
235        configuration.academic_session = 2005
236        self.app['configuration'].addSessionConfiguration(configuration)
237        error, payment = utils.setPaymentDetails('schoolfee',self.student)
238        self.assertEqual(payment.p_level, 200)
239        self.assertEqual(payment.p_session, 2005)
240        self.assertEqual(payment.amount_auth, 38850.0)
241        self.assertEqual(payment.p_item, u'CERT1')
242        self.assertEqual(error, None)
243
244        error, payment = utils.setPaymentDetails('clearance',self.student)
245        self.assertEqual(payment.p_level, 100)
246        self.assertEqual(payment.p_session, 2004)
247        self.assertEqual(payment.amount_auth, 120.0)
248        self.assertEqual(payment.p_item, u'CERT1')
249        self.assertEqual(error, None)
250
251        error, payment = utils.setPaymentDetails('carryover1',self.student)
252        self.assertEqual(payment.p_level, 100)
253        self.assertEqual(payment.p_session, 2004)
254        self.assertEqual(payment.amount_auth, 6000.0)
255        self.assertEqual(payment.p_item, u'1 CarryOver')
256        self.assertEqual(payment.p_category, 'schoolfee')
257        self.assertEqual(error, None)
258
259        error, payment = utils.setPaymentDetails('carryover2',self.student)
260        self.assertEqual(payment.p_level, 100)
261        self.assertEqual(payment.p_session, 2004)
262        self.assertEqual(payment.amount_auth, 7000.0)
263        self.assertEqual(payment.p_item, u'2 CarryOvers')
264        self.assertEqual(payment.p_category, 'schoolfee')
265        self.assertEqual(error, None)
266
267        error, payment = utils.setPaymentDetails('carryover3',self.student)
268        self.assertEqual(payment.p_level, 100)
269        self.assertEqual(payment.p_session, 2004)
270        self.assertEqual(payment.amount_auth, 8000.0)
271        self.assertEqual(payment.p_item, u'3 CarryOvers')
272        self.assertEqual(payment.p_category, 'schoolfee')
273        self.assertEqual(error, None)
274
275        error, payment = utils.setPaymentDetails('hostel_maintenance',self.student)
276        self.assertEqual(payment.p_level, 100)
277        self.assertEqual(payment.p_session, 2004)
278        self.assertEqual(payment.amount_auth, 180.0)
279        self.assertEqual(payment.p_item, u'')
280        self.assertEqual(error, None)
281
282        error, payment = utils.setPaymentDetails('bed_allocation',self.student)
283        self.assertEqual(payment.p_level, 100)
284        self.assertEqual(payment.p_session, 2004)
285        self.assertEqual(payment.amount_auth, 150.0)
286        self.assertEqual(payment.p_item, u'')
287        self.assertEqual(error, None)
288
289        error, payment = utils.setPaymentDetails('schoolfee',self.student, 2004, 100)
290        self.assertEqual(error, u'Previous session payment not yet implemented.')
291        return
292
293    def test_student_start_clearance(self):
294        self.browser.open(self.login_path)
295        self.browser.getControl(name="form.login").value = self.student_id
296        self.browser.getControl(name="form.password").value = 'spwd'
297        self.browser.getControl("Login").click()
298
299        IWorkflowInfo(self.student).fireTransition('admit')
300        self.browser.open(self.student_path + '/change_portrait')
301        image = open(SAMPLE_IMAGE, 'rb')
302        ctrl = self.browser.getControl(name='passportuploadedit')
303        file_ctrl = ctrl.mech_control
304        file_ctrl.add_file(image, filename='my_photo.jpg')
305        self.browser.getControl(
306            name='upload_passportuploadedit').click()
307        self.browser.open(self.student_path + '/start_clearance')
308        # In Okene the students can just start clearance without entering
309        # an activation code.
310        self.browser.getControl("Start clearance now").click()
311        self.assertMatches('...Clearance process has been started...',
312                           self.browser.contents)
313
314    def test_student_accommodation(self):
315        del self.student['accommodation']['2004']
316        # Login
317        self.browser.open(self.login_path)
318        self.browser.getControl(name="form.login").value = self.student_id
319        self.browser.getControl(name="form.password").value = 'spwd'
320        self.browser.getControl("Login").click()
321
322        # Students can book accommodation without AC ...
323        self.browser.open(self.acco_path)
324        IWorkflowInfo(self.student).fireTransition('admit')
325        self.browser.getLink("Book accommodation").click()
326        self.assertFalse('Activation Code:' in self.browser.contents)
327        self.browser.getControl("Create bed ticket").click()
328        # Bed is randomly selected but, since there is only
329        # one bed for this student, we know that
330        self.assertMatches('...Hall 1, Block A, Room 101, Bed A...',
331                           self.browser.contents)
332        return
Note: See TracBrowser for help on using the repository browser.