source: main/waeup.uniben/trunk/src/waeup/uniben/applicants/tests.py @ 8803

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

Adjust test.

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