source: main/waeup.aaue/trunk/src/waeup/aaue/applicants/tests.py @ 8669

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

See waeup.uniben.

  • Property svn:keywords set to Id
File size: 17.3 KB
Line 
1## $Id: tests.py 8669 2012-06-11 07:06:40Z 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
21import datetime
22import grok
23import pytz
24from zope.event import notify
25from zope.intid.interfaces import IIntIds
26from zope.interface.verify import verifyClass, verifyObject
27from zope.component.hooks import setSite, clearSite
28from zope.component import createObject, getUtility
29from zope.catalog.interfaces import ICatalog
30from zope.testbrowser.testing import Browser
31from hurry.workflow.interfaces import IWorkflowState
32from waeup.kofa.app import University
33from waeup.kofa.university.faculty import Faculty
34from waeup.kofa.university.department import Department
35from waeup.kofa.testing import FunctionalTestCase
36from waeup.kofa.configuration import SessionConfiguration
37from waeup.kofa.applicants.container import ApplicantsContainer
38from waeup.kofa.applicants.tests.test_batching import ApplicantImportExportSetup
39from waeup.kofa.interfaces import IBatchProcessor
40from waeup.aaue.testing import FunctionalLayer
41from waeup.aaue.applicants.export import CustomApplicantsExporter
42from waeup.aaue.applicants.batching import CustomApplicantProcessor
43
44
45class ApplicantUITest(FunctionalTestCase):
46    """Perform some browser tests.
47    """
48    layer = FunctionalLayer
49
50    def setUp(self):
51        super(ApplicantUITest, self).setUp()
52        # Setup a sample site for each test
53        app = University()
54        self.dc_root = tempfile.mkdtemp()
55        app['datacenter'].setStoragePath(self.dc_root)
56
57        # Prepopulate the ZODB...
58        self.getRootFolder()['app'] = app
59        # we add the site immediately after creation to the
60        # ZODB. Catalogs and other local utilities are not setup
61        # before that step.
62        self.app = self.getRootFolder()['app']
63        # Set site here. Some of the following setup code might need
64        # to access grok.getSite() and should get our new app then
65        setSite(app)
66
67        # Add an two different applicants containers
68        self.pgcontainer = ApplicantsContainer()
69        self.pgcontainer.code = u'pgft2011'
70        self.pgcontainer.prefix = u'pgft'
71        self.pgcontainer.application_category = u'pg_ft'
72        self.pgcontainer.year = 2011
73        self.pgcontainer.application_fee = 300.0
74        self.pgcontainer.title = u'This is the pgft2011 container'
75        self.app['applicants']['pgft2011'] = self.pgcontainer
76        self.ugcontainer = ApplicantsContainer()
77        self.ugcontainer.code = u'putme2011'
78        self.ugcontainer.prefix = u'putme'
79        self.ugcontainer.application_category = u'basic'
80        self.ugcontainer.year = 2011
81        self.ugcontainer.application_fee = 200.0
82        self.ugcontainer.title = u'This is the app2011 container'
83        self.app['applicants']['app2011'] = self.ugcontainer
84
85        self.ugcontainer.mode = 'update'
86        delta = datetime.timedelta(days=10)
87        self.ugcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
88        self.ugcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
89
90        # Populate university
91        self.certificate = createObject('waeup.Certificate')
92        self.certificate.code = 'CERT1'
93        self.certificate.application_category = 'basic'
94        self.certificate.start_level = 100
95        self.certificate.end_level = 500
96        self.certificate.study_mode = u'ug_ft'
97        self.app['faculties']['fac1'] = Faculty()
98        self.app['faculties']['fac1']['dep1'] = Department()
99        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
100            self.certificate)
101        self.certificate2 = createObject('waeup.Certificate')
102        self.certificate2.code = 'CERT2'
103        self.certificate2.application_category = 'pg_ft'
104        self.certificate2.start_level = 100
105        self.certificate2.end_level = 500
106        self.certificate.study_mode = u'pg_ft'
107        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
108            self.certificate2)
109
110        # Add (customized) applicants
111        pgapplicant = createObject(u'waeup.Applicant')
112        pgapplicant.firstname = u'Anna'
113        pgapplicant.lastname = u'Post'
114        self.app['applicants']['pgft2011'].addApplicant(pgapplicant)
115        self.pgapplication_number = pgapplicant.application_number
116        self.pgapplicant = self.app['applicants']['pgft2011'][
117            self.pgapplication_number]
118
119        ugapplicant = createObject(u'waeup.Applicant')
120        ugapplicant.firstname = u'Klaus'
121        ugapplicant.lastname = u'Under'
122        self.app['applicants']['app2011'].addApplicant(ugapplicant)
123        self.ugapplication_number = ugapplicant.application_number
124        self.ugapplicant = self.app['applicants']['app2011'][
125            self.ugapplication_number]
126        self.pgapplicant_path = ('http://localhost/app/applicants/pgft2011/%s'
127            % self.pgapplication_number)
128        self.ugapplicant_path = ('http://localhost/app/applicants/app2011/%s'
129            % self.ugapplication_number)
130
131        self.browser = Browser()
132        self.browser.handleErrors = False
133
134    def tearDown(self):
135        super(ApplicantUITest, self).tearDown()
136        shutil.rmtree(self.dc_root)
137        clearSite()
138        return
139
140    def fill_correct_values(self):
141        self.browser.getControl(name="form.reg_number").value = '1234'
142        self.browser.getControl(name="form.firstname").value = 'John'
143        self.browser.getControl(name="form.lastname").value = 'Tester'
144        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
145        self.browser.getControl(name="form.lga").value = ['foreigner']
146        self.browser.getControl(name="form.nationality").value = ['NG']
147        self.browser.getControl(name="form.sex").value = ['m']
148        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
149
150    def test_manage_and_view_applicant(self):
151        # Managers can manage pg applicants
152        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
153        # The IPGApplicant interface is really used in all pages
154        self.browser.open(self.pgapplicant_path)
155        self.assertEqual(self.browser.headers['Status'], '200 Ok')
156        self.assertTrue('Employer' in self.browser.contents)
157        self.browser.open(self.pgapplicant_path + '/manage')
158        self.assertEqual(self.browser.headers['Status'], '200 Ok')
159        self.assertTrue('Employer' in self.browser.contents)
160        self.browser.open(self.pgapplicant_path + '/edit')
161        self.assertEqual(self.browser.headers['Status'], '200 Ok')
162        self.assertTrue('Employer' in self.browser.contents)
163        self.browser.open(self.pgapplicant_path + '/application_slip.pdf')
164        self.assertEqual(self.browser.headers['Status'], '200 Ok')
165        # If we view the applicant in the ug container,
166        # the employer field doesn't appear
167        self.browser.open(self.ugapplicant_path)
168        self.assertEqual(self.browser.headers['Status'], '200 Ok')
169        self.assertFalse('Employer' in self.browser.contents)
170        self.browser.open(self.ugapplicant_path + '/manage')
171        self.assertEqual(self.browser.headers['Status'], '200 Ok')
172        # We can save the applicant
173        self.fill_correct_values()
174        self.browser.getControl(name="form.course1").value = ['CERT1']
175        self.browser.getControl("Save").click()
176        self.assertMatches('...Form has been saved...', self.browser.contents)
177        self.assertFalse('Employer' in self.browser.contents)
178        self.browser.open(self.ugapplicant_path + '/edit')
179        self.assertEqual(self.browser.headers['Status'], '200 Ok')
180        self.assertFalse('Employer' in self.browser.contents)
181        self.browser.open(self.ugapplicant_path + '/application_slip.pdf')
182        self.assertEqual(self.browser.headers['Status'], '200 Ok')
183        return
184
185    def test_application_payment(self):
186        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
187
188        # UG (UTME) applicant
189        self.browser.open(self.ugapplicant_path)
190        self.browser.open(self.ugapplicant_path + '/manage')
191        self.assertEqual(self.browser.headers['Status'], '200 Ok')
192        self.fill_correct_values()
193        self.browser.getControl(name="form.course1").value = ['CERT1']
194        self.browser.getControl("Save").click()
195        self.assertMatches('...Form has been saved...', self.browser.contents)
196        self.browser.getControl("Save").click()
197        self.browser.getControl("Add online payment ticket").click()
198        self.assertMatches('...Payment ticket created...',
199                           self.browser.contents)
200        self.assertMatches('...Amount Authorized...',
201                           self.browser.contents)
202        payment_id = self.ugapplicant.keys()[0]
203        payment = self.ugapplicant[payment_id]
204        self.assertEqual(payment.p_item,'This is the app2011 container')
205        self.assertEqual(payment.p_session,2011)
206        self.assertEqual(payment.p_category,'application')
207        self.assertEqual(payment.amount_auth, 200.0)
208
209        # PG applicants pay more
210        self.browser.open(self.pgapplicant_path)
211        self.browser.open(self.pgapplicant_path + '/manage')
212        self.assertEqual(self.browser.headers['Status'], '200 Ok')
213        self.fill_correct_values()
214        self.browser.getControl(name="form.course1").value = ['CERT2']
215        self.browser.getControl(name="form.reg_number").value = '2345'
216        self.browser.getControl(name="form.firstname").value = 'Anna'
217        self.browser.getControl("Save").click()
218        self.assertMatches('...Form has been saved...', self.browser.contents)
219        self.browser.getControl("Add online payment ticket").click()
220        self.assertMatches('...Payment ticket created...',
221                           self.browser.contents)
222        self.assertMatches('...Amount Authorized...',
223                           self.browser.contents)
224        payment_id = self.pgapplicant.keys()[0]
225        payment = self.pgapplicant[payment_id]
226        self.assertEqual(payment.p_item,'This is the pgft2011 container')
227        self.assertEqual(payment.p_session,2011)
228        self.assertEqual(payment.p_category,'application')
229        self.assertEqual(payment.amount_auth, 300.0)
230        return
231
232    def test_create_ugstudent(self):
233        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
234        manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
235            'app2011', self.ugapplicant.application_number, 'manage')
236        self.browser.open(manage_path)
237        self.fill_correct_values()
238        self.browser.getControl("Save").click()
239        IWorkflowState(self.ugapplicant).setState('admitted')
240        self.browser.getControl(name="form.course1").value = ['CERT1']
241        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
242        self.browser.getControl("Save").click()
243        self.browser.getLink("Create student").click()
244        student_id =  self.app['students'].keys()[0]
245        self.assertTrue(('Student %s created' % student_id)
246            in self.browser.contents)
247        student = self.app['students'][student_id]
248        self.assertEqual(student.email, 'xx@yy.zz')
249        self.assertEqual(student.firstname, 'John')
250        self.assertEqual(student.lastname, 'Tester')
251        # Also additional attributes have been copied.
252        self.assertEqual(student.lga, 'foreigner')
253        self.assertEqual(student.nationality, 'NG')
254        return
255
256class ApplicantsExporterTest(ApplicantImportExportSetup):
257
258    layer = FunctionalLayer
259
260    def setUp(self):
261        super(ApplicantsExporterTest, self).setUp()
262        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
263        self.cat = getUtility(ICatalog, name='applicants_catalog')
264        self.intids = getUtility(IIntIds)
265        return
266
267    def setup_applicant(self, applicant):
268        # set predictable values for `applicant`
269        applicant.reg_number = u'123456'
270        applicant.applicant_id = u'dp2011_654321'
271        applicant.firstname = u'Anna'
272        applicant.lastname = u'Tester'
273        applicant.middlename = u'M.'
274        applicant.date_of_birth = datetime.date(1981, 2, 4)
275        applicant.sex = 'f'
276        applicant.email = 'anna@sample.com'
277        applicant.phone = u'+234-123-12345'
278        applicant.course1 = self.certificate
279        applicant.course2 = self.certificate
280        applicant.course_admitted = self.certificate
281        applicant.notice = u'Some notice\nin lines.'
282        applicant.screening_score = 98
283        applicant.screening_venue = u'Exam Room'
284        applicant.screening_date = u'Saturday, 16th June 2012 2:00:00 PM'
285        applicant.password = 'any password'
286        return applicant
287
288    def test_export_reimport_all(self):
289        # we can export all applicants in a portal
290        # set values we can expect in export file
291        self.applicant = self.setup_applicant(self.applicant)
292        exporter = CustomApplicantsExporter()
293        exporter.export_all(self.app, self.outfile)
294        result = open(self.outfile, 'rb').read()
295        # The exported records do contain a real date in their
296        # history dict. We skip the date and split the comparison
297        # into two parts.
298        self.assertTrue(
299            'applicant_id,application_date,application_number,course1,course2,'
300            'course_admitted,date_of_birth,display_fullname,email,emp2_end,'
301            'emp2_position,emp2_reason,emp2_start,emp_end,emp_position,'
302            'emp_reason,emp_start,employer,employer2,firstname,history,'
303            'hq_degree,hq_disc,hq_matric_no,hq_school,hq_session,hq_type,'
304            'jamb_score,jamb_subjects,lastname,lga,locked,middlename,'
305            'nationality,notice,nysc_lga,'
306            'nysc_year,password,perm_address,phone,pp_school,presently_inst,'
307            'reg_number,screening_date,screening_score,screening_venue,sex,'
308            'state,student_id,'
309            'container_code'
310            in result)
311        self.assertTrue(
312            'Application initialized by system\'],,,,,,,,,Tester,,0,M.,,'
313            '"Some notice\nin lines.",,,any password,,+234-123-12345,,,'
314            '123456,"Saturday, 16th June 2012 2:00:00 PM",98,Exam Room,f,'
315            'initialized,,dp2011' in result)
316        # We can import the same file with if we ignore some columns.
317        # Since the applicants_catalog hasn't been notified, the same
318        # record with same reg_number can be imported twice.
319        processor = CustomApplicantProcessor()
320        result = processor.doImport(
321            self.outfile,
322            ['ignore_applicant_id','application_date','ignore_application_number',
323            'course1','course2',
324            'course_admitted','date_of_birth','ignore3','email','emp2_end',
325            'emp2_position','emp2_reason','emp2_start','emp_end','emp_position',
326            'emp_reason','emp_start','employer','employer2','firstname','ignore4',
327            'hq_degree','hq_disc','hq_matric_no','hq_school','hq_session','hq_type',
328            'jamb_score','jamb_subjects','lastname','lga','locked','middlename',
329            'nationality','notice','nysc_lga',
330            'nysc_year','password','perm_address','phone','pp_school','presently_inst',
331            'reg_number','screening_date','screening_score','screening_venue','sex',
332            'state','student_id','container_code'],
333            mode='create')
334        num_succ, num_fail, finished_path, failed_path = result
335        self.assertEqual(num_succ,1)
336        self.assertEqual(num_fail,0)
337        # Now we ignore also the container_code and import the same file
338        # in update mode which means that ICustomApplicantUpdateByRegNo
339        # is used for field conversion. applicant_id must be ignored
340        # too since the previous import has notified the applicants_catalog
341        # so that the portal 'knows' that reg_number is in use.
342        processor = CustomApplicantProcessor()
343        result = processor.doImport(
344            self.outfile,
345            ['ignore_applicant_id','application_date','ignore_application_number',
346            'course1','course2',
347            'course_admitted','date_of_birth','ignore3','email','emp2_end',
348            'emp2_position','emp2_reason','emp2_start','emp_end','emp_position',
349            'emp_reason','emp_start','employer','employer2','firstname','ignore4',
350            'hq_degree','hq_disc','hq_matric_no','hq_school','hq_session','hq_type',
351            'jamb_score','jamb_subjects','lastname','lga','locked','middlename',
352            'nationality','notice','nysc_lga',
353            'nysc_year','password','perm_address','phone','pp_school','presently_inst',
354            'reg_number','screening_date','screening_score','screening_venue','sex',
355            'state','student_id','ignore_container_code'],
356            mode='update')
357        num_succ, num_fail, finished_path, failed_path = result
358        self.assertEqual(num_succ,1)
359        self.assertEqual(num_fail,0)
360        return
Note: See TracBrowser for help on using the repository browser.