source: main/waeup.futminna/trunk/src/waeup/futminna/applicants/tests.py @ 8730

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

Merged with waeup.uniben 8726:8727.

  • Property svn:keywords set to Id
File size: 17.8 KB
Line 
1## $Id: tests.py 8730 2012-06-15 06:48:10Z 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.schema.interfaces import ConstraintNotSatisfied
28from zope.component.hooks import setSite, clearSite
29from zope.component import createObject, getUtility
30from zope.catalog.interfaces import ICatalog
31from zope.testbrowser.testing import Browser
32from hurry.workflow.interfaces import IWorkflowState
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
37from waeup.kofa.configuration import SessionConfiguration
38from waeup.kofa.applicants.container import ApplicantsContainer
39from waeup.kofa.applicants.tests.test_batching import ApplicantImportExportSetup
40from waeup.kofa.interfaces import IBatchProcessor
41from waeup.futminna.testing import FunctionalLayer
42from waeup.futminna.applicants.export import CustomApplicantsExporter
43from waeup.futminna.applicants.batching import CustomApplicantProcessor
44
45
46class ApplicantUITest(FunctionalTestCase):
47    """Perform some browser tests.
48    """
49    layer = FunctionalLayer
50
51    def setUp(self):
52        super(ApplicantUITest, self).setUp()
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
68        # Add an two different applicants containers
69        self.pgcontainer = ApplicantsContainer()
70        self.pgcontainer.code = u'pgft2011'
71        self.pgcontainer.prefix = u'pgft'
72        self.pgcontainer.application_category = u'pg_ft'
73        self.pgcontainer.year = 2011
74        self.pgcontainer.application_fee = 300.0
75        self.pgcontainer.title = u'This is the pgft2011 container'
76        self.app['applicants']['pgft2011'] = self.pgcontainer
77        self.ugcontainer = ApplicantsContainer()
78        self.ugcontainer.code = u'putme2011'
79        self.ugcontainer.prefix = u'putme'
80        self.ugcontainer.application_category = u'basic'
81        self.ugcontainer.year = 2011
82        self.ugcontainer.application_fee = 200.0
83        self.ugcontainer.title = u'This is the app2011 container'
84        self.app['applicants']['app2011'] = self.ugcontainer
85
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
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
97        self.certificate.study_mode = u'ug_ft'
98        self.app['faculties']['fac1'] = Faculty()
99        self.app['faculties']['fac1']['dep1'] = Department()
100        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
101            self.certificate)
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
107        self.certificate.study_mode = u'pg_ft'
108        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
109            self.certificate2)
110
111        # Add (customized) applicants
112        pgapplicant = createObject(u'waeup.Applicant')
113        pgapplicant.firstname = u'Anna'
114        pgapplicant.lastname = u'Post'
115        self.app['applicants']['pgft2011'].addApplicant(pgapplicant)
116        self.pgapplication_number = pgapplicant.application_number
117        self.pgapplicant = self.app['applicants']['pgft2011'][
118            self.pgapplication_number]
119
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]
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)
131
132        self.browser = Browser()
133        self.browser.handleErrors = False
134
135    def tearDown(self):
136        super(ApplicantUITest, self).tearDown()
137        shutil.rmtree(self.dc_root)
138        clearSite()
139        return
140
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']
147        self.browser.getControl(name="form.nationality").value = ['NG']
148        self.browser.getControl(name="form.sex").value = ['m']
149        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
150
151    def test_manage_and_view_applicant(self):
152        # Managers can manage pg applicants.
153        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
154        # The IPGApplicant interface is really used in all pages.
155        self.browser.open(self.pgapplicant_path)
156        self.assertEqual(self.browser.headers['Status'], '200 Ok')
157        self.assertTrue('Employer' in self.browser.contents)
158        self.browser.open(self.pgapplicant_path + '/manage')
159        self.assertEqual(self.browser.headers['Status'], '200 Ok')
160        self.assertTrue('Employer' in self.browser.contents)
161        self.browser.open(self.pgapplicant_path + '/edit')
162        self.assertEqual(self.browser.headers['Status'], '200 Ok')
163        self.assertTrue('Employer' in self.browser.contents)
164        self.browser.open(self.pgapplicant_path + '/application_slip.pdf')
165        self.assertEqual(self.browser.headers['Status'], '200 Ok')
166        # If we view the applicant in the ug container,
167        # the employer field doesn't appear.
168        self.browser.open(self.ugapplicant_path)
169        self.assertEqual(self.browser.headers['Status'], '200 Ok')
170        self.assertFalse('Employer' in self.browser.contents)
171        self.browser.open(self.ugapplicant_path + '/manage')
172        self.assertEqual(self.browser.headers['Status'], '200 Ok')
173        # We can save the applicant.
174        self.fill_correct_values()
175        self.browser.getControl(name="form.course1").value = ['CERT1']
176        self.browser.getControl("Save").click()
177        self.assertMatches('...Form has been saved...', self.browser.contents)
178        self.assertFalse('Employer' in self.browser.contents)
179        self.browser.open(self.ugapplicant_path + '/edit')
180        self.assertEqual(self.browser.headers['Status'], '200 Ok')
181        self.assertFalse('Employer' in self.browser.contents)
182        self.browser.open(self.ugapplicant_path + '/application_slip.pdf')
183        self.assertEqual(self.browser.headers['Status'], '200 Ok')
184        return
185
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
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()
205        self.browser.getControl(name="form.course1").value = ['CERT1']
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()
226        self.browser.getControl(name="form.course1").value = ['CERT2']
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
244    def test_create_ugstudent(self):
245        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
246        manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
247            'app2011', self.ugapplicant.application_number, 'manage')
248        self.browser.open(manage_path)
249        self.fill_correct_values()
250        self.browser.getControl("Save").click()
251        IWorkflowState(self.ugapplicant).setState('admitted')
252        self.browser.getControl(name="form.course1").value = ['CERT1']
253        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
254        self.browser.getControl("Save").click()
255        self.browser.getLink("Create student").click()
256        student_id =  self.app['students'].keys()[0]
257        self.assertTrue(('Student %s created' % student_id)
258            in self.browser.contents)
259        student = self.app['students'][student_id]
260        self.assertEqual(student.email, 'xx@yy.zz')
261        self.assertEqual(student.firstname, 'John')
262        self.assertEqual(student.lastname, 'Tester')
263        # Also additional attributes have been copied.
264        self.assertEqual(student.lga, 'foreigner')
265        self.assertEqual(student.nationality, 'NG')
266        return
267
268class ApplicantsExporterTest(ApplicantImportExportSetup):
269
270    layer = FunctionalLayer
271
272    def setUp(self):
273        super(ApplicantsExporterTest, self).setUp()
274        self.outfile = os.path.join(self.workdir, 'myoutput.csv')
275        self.cat = getUtility(ICatalog, name='applicants_catalog')
276        self.intids = getUtility(IIntIds)
277        return
278
279    def setup_applicant(self, applicant):
280        # set predictable values for `applicant`
281        applicant.reg_number = u'123456'
282        applicant.applicant_id = u'dp2011_654321'
283        applicant.firstname = u'Anna'
284        applicant.lastname = u'Tester'
285        applicant.middlename = u'M.'
286        applicant.date_of_birth = datetime.date(1981, 2, 4)
287        applicant.sex = 'f'
288        applicant.email = 'anna@sample.com'
289        applicant.phone = u'+234-123-12345'
290        applicant.course1 = self.certificate
291        applicant.course2 = self.certificate
292        applicant.course_admitted = self.certificate
293        applicant.notice = u'Some notice\nin lines.'
294        applicant.screening_score = 98
295        applicant.screening_venue = u'Exam Room'
296        applicant.screening_date = u'Saturday, 16th June 2012 2:00:00 PM'
297        applicant.password = 'any password'
298        return applicant
299
300    def test_export_reimport_all(self):
301        # we can export all applicants in a portal
302        # set values we can expect in export file
303        self.applicant = self.setup_applicant(self.applicant)
304        exporter = CustomApplicantsExporter()
305        exporter.export_all(self.app, self.outfile)
306        result = open(self.outfile, 'rb').read()
307        # The exported records do contain a real date in their
308        # history dict. We skip the date and split the comparison
309        # into two parts.
310        self.assertTrue(
311            'applicant_id,application_date,application_number,course1,course2,'
312            'course_admitted,date_of_birth,display_fullname,email,emp2_end,'
313            'emp2_position,emp2_reason,emp2_start,emp_end,emp_position,'
314            'emp_reason,emp_start,employer,employer2,firstname,history,'
315            'hq_degree,hq_disc,hq_matric_no,hq_school,hq_session,hq_type,'
316            'jamb_score,jamb_subjects,lastname,lga,locked,middlename,'
317            'nationality,notice,nysc_lga,'
318            'nysc_year,password,perm_address,phone,pp_school,presently_inst,'
319            'reg_number,screening_date,screening_score,screening_venue,sex,'
320            'state,student_id,'
321            'container_code'
322            in result)
323        self.assertTrue(
324            'Application initialized by system\'],,,,,,,,,Tester,,0,M.,,'
325            '"Some notice\nin lines.",,,any password,,+234-123-12345,,,'
326            '123456,"Saturday, 16th June 2012 2:00:00 PM",98,Exam Room,f,'
327            'initialized,,dp2011' in result)
328        # We can import the same file with if we ignore some columns.
329        # Since the applicants_catalog hasn't been notified, the same
330        # record with same reg_number can be imported twice.
331        processor = CustomApplicantProcessor()
332        result = processor.doImport(
333            self.outfile,
334            ['ignore_applicant_id','application_date','ignore_application_number',
335            'course1','course2',
336            'course_admitted','date_of_birth','ignore3','email','emp2_end',
337            'emp2_position','emp2_reason','emp2_start','emp_end','emp_position',
338            'emp_reason','emp_start','employer','employer2','firstname','ignore4',
339            'hq_degree','hq_disc','hq_matric_no','hq_school','hq_session','hq_type',
340            'jamb_score','jamb_subjects','lastname','lga','locked','middlename',
341            'nationality','notice','nysc_lga',
342            'nysc_year','password','perm_address','phone','pp_school','presently_inst',
343            'reg_number','screening_date','screening_score','screening_venue','sex',
344            'state','student_id','container_code'],
345            mode='create')
346        num_succ, num_fail, finished_path, failed_path = result
347        self.assertEqual(num_succ,1)
348        self.assertEqual(num_fail,0)
349        # Now we ignore also the container_code and import the same file
350        # in update mode which means that ICustomApplicantUpdateByRegNo
351        # is used for field conversion. applicant_id must be ignored
352        # too since the previous import has notified the applicants_catalog
353        # so that the portal 'knows' that reg_number is in use.
354        processor = CustomApplicantProcessor()
355        result = processor.doImport(
356            self.outfile,
357            ['ignore_applicant_id','application_date','ignore_application_number',
358            'course1','course2',
359            'course_admitted','date_of_birth','ignore3','email','emp2_end',
360            'emp2_position','emp2_reason','emp2_start','emp_end','emp_position',
361            'emp_reason','emp_start','employer','employer2','firstname','ignore4',
362            'hq_degree','hq_disc','hq_matric_no','hq_school','hq_session','hq_type',
363            'jamb_score','jamb_subjects','lastname','lga','locked','middlename',
364            'nationality','notice','nysc_lga',
365            'nysc_year','password','perm_address','phone','pp_school','presently_inst',
366            'reg_number','screening_date','screening_score','screening_venue','sex',
367            'state','student_id','ignore_container_code'],
368            mode='update')
369        num_succ, num_fail, finished_path, failed_path = result
370        self.assertEqual(num_succ,1)
371        self.assertEqual(num_fail,0)
372        return
Note: See TracBrowser for help on using the repository browser.