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

Last change on this file since 8320 was 8320, checked in by Henrik Bettermann, 13 years ago

Add more tests.

  • Property svn:keywords set to Id
File size: 14.2 KB
Line 
1## $Id: test_browser.py 8320 2012-05-02 05:10:36Z 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 hurry.workflow.interfaces import IWorkflowState
22from zope.component.hooks import setSite, clearSite
23from zope.component import getUtility
24from waeup.kofa.app import University
25from waeup.kofa.students.tests.test_browser import StudentsFullSetup
26from waeup.kofa.testing import FunctionalTestCase
27from waeup.kofa.students.batching import StudentProcessor
28from waeup.kofa.students.interfaces import IStudentsUtils
29from waeup.uniben.students.batching import CustomStudentProcessor
30from waeup.uniben.testing import FunctionalLayer
31from waeup.uniben.students.utils import get_school_fee
32
33
34STUDENT_SAMPLE_DATA = open(
35    os.path.join(os.path.dirname(__file__), 'sample_student_data.csv'),
36    'rb').read()
37
38STUDENT_HEADER_FIELDS = STUDENT_SAMPLE_DATA.split(
39    '\n')[0].split(',')
40
41class StudentProcessorTest(FunctionalTestCase):
42    """Perform some batching tests.
43    """
44
45    layer = FunctionalLayer
46
47    def setUp(self):
48        super(StudentProcessorTest, self).setUp()
49        # Setup a sample site for each test
50        app = University()
51        self.dc_root = tempfile.mkdtemp()
52        app['datacenter'].setStoragePath(self.dc_root)
53
54        # Prepopulate the ZODB...
55        self.getRootFolder()['app'] = app
56        # we add the site immediately after creation to the
57        # ZODB. Catalogs and other local utilities are not setup
58        # before that step.
59        self.app = self.getRootFolder()['app']
60        # Set site here. Some of the following setup code might need
61        # to access grok.getSite() and should get our new app then
62        setSite(app)
63
64        self.processor_base = StudentProcessor()
65        self.processor = CustomStudentProcessor()
66        self.workdir = tempfile.mkdtemp()
67        self.csv_file = os.path.join(self.workdir, 'sample_student_data.csv')
68        open(self.csv_file, 'wb').write(STUDENT_SAMPLE_DATA)
69
70    def tearDown(self):
71        super(StudentProcessorTest, self).tearDown()
72        shutil.rmtree(self.workdir)
73        shutil.rmtree(self.dc_root)
74        clearSite()
75        return
76
77    def test_import(self):
78        # We have an empty column 'date_of_birth' in  the import file.
79        # The original processor will fail because 'date_of_birth' is required
80        # in the base package.
81        num, num_warns, fin_file, fail_file = self.processor_base.doImport(
82            self.csv_file, STUDENT_HEADER_FIELDS)
83        self.assertEqual(num_warns,3)
84        assert len(self.app['students'].keys()) == 0
85        # The customized processor does not complain since 'date_of_birth' is
86        # not required in the custom package.
87        num, num_warns, fin_file, fail_file = self.processor.doImport(
88            self.csv_file, STUDENT_HEADER_FIELDS)
89        #print open(fail_file).read()
90        self.assertEqual(num_warns,0)
91        assert len(self.app['students'].keys()) == 3
92        shutil.rmtree(os.path.dirname(fin_file))
93
94
95class StudentUITests(StudentsFullSetup):
96    """Tests for customized student class views and pages
97    """
98
99    layer = FunctionalLayer
100
101    def test_manage_access(self):
102        # Managers can access the pages of students
103        # and can perform actions
104        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
105        # The student created in the base package is an ug student
106        self.browser.open(self.student_path)
107        self.browser.getLink("Clearance Data").click()
108        self.assertEqual(self.browser.headers['Status'], '200 Ok')
109        self.assertEqual(self.browser.url, self.clearance_path)
110        self.browser.getLink("Manage").click()
111        self.assertEqual(self.browser.headers['Status'], '200 Ok')
112        self.assertEqual(self.browser.url, self.manage_clearance_path)
113        self.browser.getControl(name="form.date_of_birth").value = '09/10/1961'
114        self.browser.getControl("Save").click()
115        self.assertMatches('...Form has been saved...',
116                           self.browser.contents)
117        self.assertMatches('...First Sitting Record...',
118                           self.browser.contents)
119        # Managers can open clearance slip of ug students
120        self.browser.open(self.student_path + '/clearance.pdf')
121        self.assertEqual(self.browser.headers['Status'], '200 Ok')
122        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
123        # There is no pg field in the clearance form
124        self.assertFalse('Second Higher Education Record'
125            in self.browser.contents)
126        # Now we change the study mode ...
127        self.certificate.study_mode = 'pg_ft'
128        self.browser.open(self.clearance_path)
129        # ... and additional pg clearance fields appear
130        self.assertMatches('...Second Higher Education Record...',
131                           self.browser.contents)
132        # But also fields from the ug form are displayed
133        self.assertMatches('...First Sitting Record...',
134                           self.browser.contents)
135        # Managers can open clearance slip of pg students
136        self.browser.open(self.student_path + '/clearance.pdf')
137        self.assertEqual(self.browser.headers['Status'], '200 Ok')
138        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
139
140    def test_manage_payments(self):
141        # Add missing configuration data
142        self.app['configuration']['2004'].gown_fee = 150.0
143        self.app['configuration']['2004'].transfer_fee = 90.0
144        #self.app['configuration']['2004'].clearance_fee = 120.0
145        self.app['configuration']['2004'].booking_fee = 150.0
146        self.app['configuration']['2004'].maint_fee = 180.0
147
148        # Managers can add online payment tickets
149        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
150        self.browser.open(self.payments_path)
151        self.browser.getControl("Add online payment ticket").click()
152        self.browser.getControl("Create ticket").click()
153        self.assertMatches('...Amount could not be determined...',
154                           self.browser.contents)
155        IWorkflowState(self.student).setState('cleared')
156        self.browser.open(self.payments_path + '/addop')
157        self.browser.getControl("Create ticket").click()
158        self.assertMatches('...ticket created...',
159                           self.browser.contents)
160        ctrl = self.browser.getControl(name='val_id')
161        value = ctrl.options[0]
162        self.browser.getLink(value).click()
163        self.assertMatches('...Amount Authorized...',
164                           self.browser.contents)
165        # Managers can open payment slip
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        # Set ticket paid
170        ticket = self.student['payments'].items()[0][1]
171        ticket.p_state = 'paid'
172        self.browser.open(self.payments_path + '/addop')
173        self.browser.getControl("Create ticket").click()
174        self.assertMatches('...This type of payment has already been made...',
175                           self.browser.contents)
176        # Remove all payments so that we can add a school fee payment again
177        keys = [i for i in self.student['payments'].keys()]
178        for payment in keys:
179            del self.student['payments'][payment]
180        self.browser.open(self.payments_path + '/addop')
181        self.browser.getControl("Create ticket").click()
182        self.assertMatches('...ticket created...',
183                           self.browser.contents)
184        self.browser.open(self.payments_path + '/addop')
185        self.browser.getControl(name="form.p_category").value = ['gown']
186        self.browser.getControl("Create ticket").click()
187        self.assertMatches('...ticket created...',
188                           self.browser.contents)
189        self.browser.open(self.payments_path + '/addop')
190        self.browser.getControl(name="form.p_category").value = ['transfer']
191        self.browser.getControl("Create ticket").click()
192        self.assertMatches('...ticket created...',
193                           self.browser.contents)
194        self.browser.open(self.payments_path + '/addop')
195        self.browser.getControl(
196            name="form.p_category").value = ['bed_allocation']
197        self.browser.getControl("Create ticket").click()
198        self.assertMatches('...ticket created...',
199                           self.browser.contents)
200        self.browser.open(self.payments_path + '/addop')
201        self.browser.getControl(
202            name="form.p_category").value = ['hostel_maintenance']
203        self.browser.getControl("Create ticket").click()
204        self.assertMatches('...ticket created...',
205                           self.browser.contents)
206        self.browser.open(self.payments_path + '/addop')
207        self.browser.getControl(name="form.p_category").value = ['clearance']
208        self.browser.getControl("Create ticket").click()
209        self.assertMatches('...ticket created...',
210                           self.browser.contents)
211        self.browser.open(self.payments_path + '/addop')
212        self.browser.getControl(name="form.p_category").value = ['schoolfee']
213        self.browser.getControl("Create ticket").click()
214        self.assertMatches('...ticket created...',
215                           self.browser.contents)
216        # In state returning we can add a new school fee ticket since
217        # p_session and p_level is different
218        IWorkflowState(self.student).setState('returning')
219        self.browser.open(self.payments_path + '/addop')
220        self.browser.getControl(name="form.p_category").value = ['schoolfee']
221        self.browser.getControl("Create ticket").click()
222        self.assertMatches('...ticket created...',
223                           self.browser.contents)
224        # In state admitted school fee can't be determined
225        IWorkflowState(self.student).setState('admitted')
226        self.browser.open(self.payments_path + '/addop')
227        self.browser.getControl(name="form.p_category").value = ['schoolfee']
228        self.browser.getControl("Create ticket").click()
229        self.assertMatches('...Amount could not be determined...',
230                           self.browser.contents)
231
232        # If the session configuration doesn't exist an error message will
233        # be shown. No other requirement is being checked.
234        del self.app['configuration']['2004']
235        self.browser.open(self.payments_path)
236        self.browser.getControl("Add online payment ticket").click()
237        self.browser.getControl("Create ticket").click()
238        self.assertMatches('...Session configuration object is not...',
239                           self.browser.contents)
240
241    def test_student_access(self):
242        # Students can edit clearance data
243        IWorkflowState(self.student).setState('cleared')
244        self.student.clearance_locked = False
245        self.browser.open(self.login_path)
246        self.browser.getControl(name="form.login").value = self.student_id
247        self.browser.getControl(name="form.password").value = 'spwd'
248        self.browser.getControl("Login").click()
249        # Student can view and edit clearance data
250        self.browser.getLink("Clearance Data").click()
251        self.browser.getLink("Edit").click()
252        self.assertTrue('Save' in self.browser.contents)
253
254    def test_get_returning_data(self):
255        # Student is in level 100, session 2004 with verdict A
256        utils = getUtility(IStudentsUtils)
257        self.assertEqual(utils.getReturningData(self.student),(2005, 200))
258        self.student['studycourse'].current_verdict = 'C'
259        self.assertEqual(utils.getReturningData(self.student),(2005, 110))
260        self.student['studycourse'].current_verdict = 'D'
261        self.assertEqual(utils.getReturningData(self.student),(2005, 100))
262        return
263
264    def test_get_schoolfee(self):
265        self.assertEqual(get_school_fee(self.student),0.0)
266        IWorkflowState(self.student).setState('cleared')
267        self.assertEqual(get_school_fee(self.student),40000.0)
268        IWorkflowState(self.student).setState('returning')
269        self.assertEqual(get_school_fee(self.student),20000.0)
270        return
271
272    def test_get_payment_details(self):
273        self.app['configuration']['2004'].gown_fee = 150.0
274        self.app['configuration']['2004'].transfer_fee = 90.0
275        self.app['configuration']['2004'].booking_fee = 150.0
276        self.app['configuration']['2004'].maint_fee = 180.0
277        utils = getUtility(IStudentsUtils)
278        self.assertEqual(utils.getPaymentDetails('schoolfee',self.student),
279            {'p_level': 100, 'p_session': 2004, 'amount': 0.0,
280            'p_item': u'CERT1', 'error': u'Amount could not be determined.'}
281            )
282        self.assertEqual(utils.getPaymentDetails('clearance',self.student),
283            {'p_level': 100, 'p_session': 2004, 'amount': 34250.0,
284            'p_item': u'CERT1', 'error': u''}
285            )
286        self.assertEqual(utils.getPaymentDetails('gown',self.student),
287            {'p_level': 100, 'p_session': 2004, 'amount': 150.0,
288            'p_item': u'', 'error': u''}
289            )
290        self.assertEqual(utils.getPaymentDetails('hostel_maintenance',self.student),
291            {'p_level': 100, 'p_session': 2004, 'amount': 180.0,
292            'p_item': u'', 'error': u''}
293            )
294        self.assertEqual(utils.getPaymentDetails('bed_allocation',self.student),
295            {'p_level': 100, 'p_session': 2004, 'amount': 150.0,
296            'p_item': u'', 'error': u''}
297            )
298        self.assertEqual(utils.getPaymentDetails('transfer',self.student),
299            {'p_level': 100, 'p_session': 2004, 'amount': 90.0,
300            'p_item': u'', 'error': u''}
301            )
302        return
Note: See TracBrowser for help on using the repository browser.