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

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

Customize CustomApplicantRegistrationPage?.

Uniben applicants do see the login credentials on registration landing page.

  • Property svn:keywords set to Id
File size: 17.3 KB
Line 
1## $Id: tests.py 8630 2012-06-05 15:07:26Z 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 waeup.kofa.app import University
32from waeup.kofa.university.faculty import Faculty
33from waeup.kofa.university.department import Department
34from waeup.kofa.testing import FunctionalTestCase
35from waeup.kofa.configuration import SessionConfiguration
36from waeup.kofa.applicants.container import ApplicantsContainer
37from waeup.kofa.applicants.tests.test_batching import ApplicantImportExportSetup
38from waeup.kofa.interfaces import IBatchProcessor
39from waeup.uniben.testing import FunctionalLayer
40from waeup.uniben.applicants.export import CustomApplicantsExporter
41from waeup.uniben.applicants.batching import CustomApplicantProcessor
42
43
44class ApplicantUITest(FunctionalTestCase):
45    """Perform some browser tests.
46    """
47    layer = FunctionalLayer
48
49    def setUp(self):
50        super(ApplicantUITest, self).setUp()
51        # Setup a sample site for each test
52        app = University()
53        self.dc_root = tempfile.mkdtemp()
54        app['datacenter'].setStoragePath(self.dc_root)
55
56        # Prepopulate the ZODB...
57        self.getRootFolder()['app'] = app
58        # we add the site immediately after creation to the
59        # ZODB. Catalogs and other local utilities are not setup
60        # before that step.
61        self.app = self.getRootFolder()['app']
62        # Set site here. Some of the following setup code might need
63        # to access grok.getSite() and should get our new app then
64        setSite(app)
65
66        # Add an two different applicants containers
67        self.pgcontainer = ApplicantsContainer()
68        self.pgcontainer.code = u'pgft2011'
69        self.pgcontainer.prefix = u'pgft'
70        self.pgcontainer.application_category = u'pg_ft'
71        self.pgcontainer.year = 2011
72        self.pgcontainer.application_fee = 300.0
73        self.pgcontainer.title = u'This is the pgft2011 container'
74        self.app['applicants']['pgft2011'] = self.pgcontainer
75        self.ugcontainer = ApplicantsContainer()
76        self.ugcontainer.code = u'putme2011'
77        self.ugcontainer.prefix = u'putme'
78        self.ugcontainer.application_category = u'basic'
79        self.ugcontainer.year = 2011
80        self.ugcontainer.application_fee = 200.0
81        self.ugcontainer.title = u'This is the app2011 container'
82        self.app['applicants']['app2011'] = self.ugcontainer
83
84        self.ugcontainer.mode = 'update'
85        delta = datetime.timedelta(days=10)
86        self.ugcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
87        self.ugcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
88
89        # Populate university
90        self.certificate = createObject('waeup.Certificate')
91        self.certificate.code = 'CERT1'
92        self.certificate.application_category = 'basic'
93        self.certificate.start_level = 100
94        self.certificate.end_level = 500
95        self.app['faculties']['fac1'] = Faculty()
96        self.app['faculties']['fac1']['dep1'] = Department()
97        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
98            self.certificate)
99        self.certificate2 = createObject('waeup.Certificate')
100        self.certificate2.code = 'CERT2'
101        self.certificate2.application_category = 'pg_ft'
102        self.certificate2.start_level = 100
103        self.certificate2.end_level = 500
104        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
105            self.certificate2)
106
107        # Add (customized) applicants
108        pgapplicant = createObject(u'waeup.Applicant')
109        pgapplicant.firstname = u'Anna'
110        pgapplicant.lastname = u'Post'
111        self.app['applicants']['pgft2011'].addApplicant(pgapplicant)
112        self.pgapplication_number = pgapplicant.application_number
113        self.pgapplicant = self.app['applicants']['pgft2011'][
114            self.pgapplication_number]
115
116        ugapplicant = createObject(u'waeup.Applicant')
117        ugapplicant.firstname = u'Klaus'
118        ugapplicant.lastname = u'Under'
119        self.app['applicants']['app2011'].addApplicant(ugapplicant)
120        self.ugapplication_number = ugapplicant.application_number
121        self.ugapplicant = self.app['applicants']['app2011'][
122            self.ugapplication_number]
123        self.pgapplicant_path = ('http://localhost/app/applicants/pgft2011/%s'
124            % self.pgapplication_number)
125        self.ugapplicant_path = ('http://localhost/app/applicants/app2011/%s'
126            % self.ugapplication_number)
127
128        self.browser = Browser()
129        self.browser.handleErrors = False
130
131    def tearDown(self):
132        super(ApplicantUITest, self).tearDown()
133        shutil.rmtree(self.dc_root)
134        clearSite()
135        return
136
137    def fill_correct_values(self):
138        self.browser.getControl(name="form.reg_number").value = '1234'
139        self.browser.getControl(name="form.firstname").value = 'John'
140        self.browser.getControl(name="form.lastname").value = 'Tester'
141        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
142        self.browser.getControl(name="form.lga").value = ['foreigner']
143        self.browser.getControl(name="form.sex").value = ['m']
144        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
145
146    def test_manage_and_view_applicant(self):
147        # Managers can manage pg applicants
148        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
149        # The IPGApplicant interface is really used in all pages
150        self.browser.open(self.pgapplicant_path)
151        self.assertEqual(self.browser.headers['Status'], '200 Ok')
152        self.assertTrue('Employer' in self.browser.contents)
153        self.browser.open(self.pgapplicant_path + '/manage')
154        self.assertEqual(self.browser.headers['Status'], '200 Ok')
155        self.assertTrue('Employer' in self.browser.contents)
156        self.browser.open(self.pgapplicant_path + '/edit')
157        self.assertEqual(self.browser.headers['Status'], '200 Ok')
158        self.assertTrue('Employer' in self.browser.contents)
159        self.browser.open(self.pgapplicant_path + '/application_slip.pdf')
160        self.assertEqual(self.browser.headers['Status'], '200 Ok')
161        # If we view the applicant in the ug container,
162        # the employer field doesn't appear
163        self.browser.open(self.ugapplicant_path)
164        self.assertEqual(self.browser.headers['Status'], '200 Ok')
165        self.assertFalse('Employer' in self.browser.contents)
166        self.browser.open(self.ugapplicant_path + '/manage')
167        self.assertEqual(self.browser.headers['Status'], '200 Ok')
168        # We can save the applicant
169        self.fill_correct_values()
170        self.browser.getControl(name="form.course1").value = ['CERT1']
171        self.browser.getControl("Save").click()
172        self.assertMatches('...Form has been saved...', self.browser.contents)
173        self.assertFalse('Employer' in self.browser.contents)
174        self.browser.open(self.ugapplicant_path + '/edit')
175        self.assertEqual(self.browser.headers['Status'], '200 Ok')
176        self.assertFalse('Employer' in self.browser.contents)
177        self.browser.open(self.ugapplicant_path + '/application_slip.pdf')
178        self.assertEqual(self.browser.headers['Status'], '200 Ok')
179        return
180
181    def test_application_payment(self):
182        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
183
184        # UG (UTME) applicant
185        self.browser.open(self.ugapplicant_path)
186        self.browser.open(self.ugapplicant_path + '/manage')
187        self.assertEqual(self.browser.headers['Status'], '200 Ok')
188        self.fill_correct_values()
189        self.browser.getControl(name="form.course1").value = ['CERT1']
190        self.browser.getControl("Save").click()
191        self.assertMatches('...Form has been saved...', self.browser.contents)
192        self.browser.getControl("Save").click()
193        self.browser.getControl("Add online payment ticket").click()
194        self.assertMatches('...Payment ticket created...',
195                           self.browser.contents)
196        self.assertMatches('...Amount Authorized...',
197                           self.browser.contents)
198        payment_id = self.ugapplicant.keys()[0]
199        payment = self.ugapplicant[payment_id]
200        self.assertEqual(payment.p_item,'This is the app2011 container')
201        self.assertEqual(payment.p_session,2011)
202        self.assertEqual(payment.p_category,'application')
203        self.assertEqual(payment.amount_auth, 200.0)
204
205        # PG applicants pay more
206        self.browser.open(self.pgapplicant_path)
207        self.browser.open(self.pgapplicant_path + '/manage')
208        self.assertEqual(self.browser.headers['Status'], '200 Ok')
209        self.fill_correct_values()
210        self.browser.getControl(name="form.course1").value = ['CERT2']
211        self.browser.getControl(name="form.reg_number").value = '2345'
212        self.browser.getControl(name="form.firstname").value = 'Anna'
213        self.browser.getControl("Save").click()
214        self.assertMatches('...Form has been saved...', self.browser.contents)
215        self.browser.getControl("Add online payment ticket").click()
216        self.assertMatches('...Payment ticket created...',
217                           self.browser.contents)
218        self.assertMatches('...Amount Authorized...',
219                           self.browser.contents)
220        payment_id = self.pgapplicant.keys()[0]
221        payment = self.pgapplicant[payment_id]
222        self.assertEqual(payment.p_item,'This is the pgft2011 container')
223        self.assertEqual(payment.p_session,2011)
224        self.assertEqual(payment.p_category,'application')
225        self.assertEqual(payment.amount_auth, 300.0)
226        return
227
228    def test_register_applicant_update(self):
229        # An applicant can register himself.
230        self.ugapplicant.reg_number = u'1234'
231        notify(grok.ObjectModifiedEvent(self.ugapplicant))
232        self.browser.open('http://localhost/app/applicants/app2011/')
233        self.browser.getLink("Register for application").click()
234        # Fill the edit form with suitable values
235        self.browser.getControl(name="form.firstname").value = 'Klaus'
236        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
237        self.browser.getControl(name="form.reg_number").value = '1234'
238        self.browser.getControl("Get login credentials").click()
239        self.assertMatches('...Your registration was successful...',
240            self.browser.contents)
241        self.assertMatches('...<td>Password:</td>...',
242            self.browser.contents)
243        # The new applicant can be found in the catalog via the email address
244        cat = getUtility(ICatalog, name='applicants_catalog')
245        results = list(
246            cat.searchResults(email=('xx@yy.zz', 'xx@yy.zz')))
247        applicant = results[0]
248        self.assertEqual(applicant.lastname,'Under')
249        # The applicant can be found in the catalog via the reg_number
250        results = list(
251            cat.searchResults(
252            reg_number=(applicant.reg_number, applicant.reg_number)))
253        self.assertEqual(applicant,results[0])
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.