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

Last change on this file since 17668 was 17632, checked in by Henrik Bettermann, 13 months ago

See ticket #773.

  • Property svn:keywords set to Id
File size: 24.0 KB
Line 
1## $Id: test_browser.py 17632 2023-11-01 17:59:53Z 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 grok
19import datetime
20import pytz
21import os
22from StringIO import StringIO
23from zope.event import notify
24from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
25from zope.component import createObject, getUtility
26from waeup.kofa.configuration import SessionConfiguration
27from waeup.kofa.interfaces import (
28    IUserAccount, IExtFileStore, IFileStoreNameChooser)
29from waeup.kofa.applicants.container import ApplicantsContainer
30from waeup.kofa.browser.tests.test_pdf import samples_dir
31from waeup.aaue.testing import FunctionalLayer
32from waeup.kofa.applicants.tests.test_browser import (
33    ApplicantsFullSetup, container_name_1, session_1)
34
35SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
36
37class CustomApplicantUITest(ApplicantsFullSetup):
38    """Perform some browser tests.
39    """
40
41    layer = FunctionalLayer
42
43    def test_show_credentials_on_landing_page(self):
44        # An applicant can register himself.
45        self.applicant.reg_number = u'1234'
46        notify(grok.ObjectModifiedEvent(self.applicant))
47        self.browser.open('http://localhost/app/applicants/%s/' % container_name_1)
48        self.browser.getLink("Register for application").click()
49        # Fill the edit form with suitable values
50        self.browser.getControl(name="form.firstname").value = 'Klaus'
51        self.browser.getControl(name="form.lastname").value = 'Lutz'
52        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
53        self.browser.getControl("Send login credentials").click()
54        self.assertMatches('...Your registration was successful...',
55            self.browser.contents)
56        self.assertTrue('<td>Password:</td>' in self.browser.contents)
57        return
58
59    def test_payment(self):
60        certificate = createObject('waeup.Certificate')
61        certificate.code = 'CERT2'
62        certificate.title = 'New Certificate'
63        certificate.application_category = 'basic'
64        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
65            certificate)
66        certificate = createObject('waeup.Certificate')
67        certificate.code = 'CERT3'
68        certificate.title = 'New Certificate 2'
69        certificate.application_category = 'basic'
70        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
71            certificate)
72        configuration = SessionConfiguration()
73        configuration.academic_session = session_1
74        self.app['configuration'].addSessionConfiguration(configuration)
75        self.applicantscontainer.application_fee = 200.0
76        self.applicant.jamb_score = 1000000
77        self.login()
78        self.browser.open(self.edit_path)
79        self.browser.getControl(name="form.course2").value = ['CERT2']
80        self.browser.getControl(name="form.course3").value = ['CERT3']
81        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
82        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
83        #self.browser.getControl(name="form.programme_type").value = ['regular']
84        self.browser.getControl(name="form.nationality").value = ['NG']
85        self.browser.getControl(name="form.sex").value = ['m']
86        self.browser.getControl(name="form.lastname").value = 'Merkel'
87        self.browser.getControl(name="form.fst_sit_fname").value = 'name'
88        self.browser.getControl(name="form.fst_sit_no").value = 'no'
89        self.browser.getControl(name="form.fst_sit_sc_pin").value = 'pin'
90        self.browser.getControl(name="form.fst_sit_sc_serial_number").value = 'serial'
91        self.browser.getControl(name="form.fst_sit_date").value = '09/09/2000'
92        self.browser.getControl(name="form.fst_sit_type").value = ['ssce']
93        self.browser.getControl("Save").click()
94        self.browser.getControl("Add online payment ticket").click()
95        self.assertMatches('...Payment ticket created...',
96                           self.browser.contents)
97        # Ticket can't be downloaded because payment gatewy is not specified
98        self.assertFalse("Download payment slip" in self.browser.contents)
99        self.applicant.payments[0].r_company = u'interswitch'
100        self.browser.open(self.edit_path)
101        self.browser.getLink(self.applicant.payments[0].p_id).click()
102        # Payment tickets can now be downloaded without submitting the form.
103        self.browser.getLink("Download payment slip").click()
104        self.assertEqual(self.browser.headers['Content-Type'],
105                 'application/pdf')
106        # AAUE applicants never see the 'Remove Selected Tickets' button.
107        self.browser.open(self.edit_path)
108        self.assertFalse('Remove' in self.browser.contents)
109        return
110
111    def test_screening_invitation_download(self):
112        self.login()
113        self.applicant.screening_date = u'29th August 2016 @ 8:30 am'
114        self.applicant.screening_venue = u'Main Auditorium'
115        self.applicant.lastname = u'Cox'
116        self.applicant.firstname = u'Jo'
117        self.applicant.email = 'xx@yy.zz'
118        self.browser.open(self.view_path)
119        self.assertFalse("Download application slip" in self.browser.contents)
120        IWorkflowState(self.applicant).setState('submitted')
121        self.browser.open(self.view_path)
122        self.browser.getLink("screening invitation").click()
123        self.assertEqual(self.browser.headers['Status'], '200 Ok')
124        self.assertEqual(
125            self.browser.headers['Content-Type'], 'application/pdf')
126        path = os.path.join(samples_dir(), 'screening_invitation.pdf')
127        open(path, 'wb').write(self.browser.contents)
128        print "Sample PDF screening_invitation.pdf written to %s" % path
129        return
130
131    def test_application_slips(self):
132        delattr(ApplicantsContainer, 'prefix')
133        self.applicantscontainer.prefix = 'ude'
134        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
135        self.slip_path = self.view_path + '/application_slip.pdf'
136        self.browser.open(self.manage_path)
137        self.assertEqual(self.browser.headers['Status'], '200 Ok')
138        self.fill_correct_values()
139        self.browser.getControl("Save").click()
140        IWorkflowState(self.applicant).setState('admitted')
141        self.applicant.course_admitted = self.certificate
142        self.browser.open(self.view_path)
143        self.browser.getLink("Download application slip").click()
144        self.assertEqual(self.browser.headers['Status'], '200 Ok')
145        self.assertEqual(self.browser.headers['Content-Type'],
146                         'application/pdf')
147        path = os.path.join(samples_dir(), 'application_slip.pdf')
148        open(path, 'wb').write(self.browser.contents)
149        print "Sample application_slip.pdf written to %s" % path
150
151    def test_transcript_application_manage(self):
152        # Add trans applicants container
153        self.transcontainer = ApplicantsContainer()
154        self.transcontainer.mode = 'create'
155        self.transcontainer.code = u'trans%s' % session_1
156        self.transcontainer.prefix = u'trans'
157        self.transcontainer.application_category = u'no'
158        self.transcontainer.year = session_1
159        self.transcontainer.application_fee = 300.0
160        self.transcontainer.title = u'This is the trans%s container' % session_1
161        self.app['applicants'][self.transcontainer.code] = self.transcontainer
162        delta = datetime.timedelta(days=10)
163        self.transcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
164        self.transcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
165        # Add applicant
166        transapplicant = createObject(u'waeup.Applicant')
167        transapplicant.firstname = u'Anna'
168        transapplicant.lastname = u'Post'
169        self.app['applicants'][self.transcontainer.code].addApplicant(transapplicant)
170        self.transapplication_number = transapplicant.application_number
171        self.transapplicant = self.app['applicants'][self.transcontainer.code][
172            self.transapplication_number]
173        self.transapplicant_path = ('http://localhost/app/applicants/trans%s/%s'
174            % (session_1, self.transapplication_number))
175        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
176        self.browser.open(self.transapplicant_path)
177        self.assertEqual(self.browser.headers['Status'], '200 Ok')
178        self.assertTrue("Dispatch Address" in self.browser.contents)
179
180    def _prepare_cert_container(self):
181        # Add cert applicants container
182        self.certcontainer = ApplicantsContainer()
183        self.certcontainer.mode = 'update'
184        self.certcontainer.code = u'cert%s' % session_1
185        self.certcontainer.prefix = u'cert'
186        self.certcontainer.application_category = u'no'
187        self.certcontainer.year = session_1
188        self.certcontainer.application_fee = 300.0
189        self.certcontainer.title = u'This is the cert%s container' % session_1
190        self.app['applicants'][self.certcontainer.code] = self.certcontainer
191        delta = datetime.timedelta(days=10)
192        self.certcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
193        self.certcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
194        # Add applicant
195        certapplicant = createObject(u'waeup.Applicant')
196        certapplicant.firstname = u'Anna'
197        certapplicant.lastname = u'Post'
198        certapplicant.reg_number = u'1234%s' % self.certcontainer.code
199        self.app['applicants'][self.certcontainer.code].addApplicant(certapplicant)
200        self.certapplication_number = certapplicant.application_number
201        self.certapplicant = self.app['applicants'][self.certcontainer.code][
202            self.certapplication_number]
203        self.certcontainer_path = ('http://localhost/app/applicants/cert%s'
204            % session_1)
205        self.certapplicant_path = ('http://localhost/app/applicants/cert%s/%s'
206            % (session_1, self.certapplication_number))
207
208    def test_certificate_request_manage(self):
209        self._prepare_cert_container()
210        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
211        self.browser.open(self.certapplicant_path)
212        self.assertEqual(self.browser.headers['Status'], '200 Ok')
213        #self.assertTrue("Dispatch Address" in self.browser.contents)
214
215    def test_certificate_request_update(self):
216        self._prepare_cert_container()
217        #IWorkflowState(self.applicant).setState('initialized')
218        self.browser.open(self.certcontainer_path + '/register')
219        self.browser.getControl(name="form.lastname").value = 'post'
220        self.browser.getControl(name="form.reg_number").value = '1234'
221        self.browser.getControl(name="form.email").value = 'new@yy.zz'
222        self.browser.getControl("Send login credentials").click()
223        # Yeah, we succeded ...
224        self.assertTrue('Your registration was successful.'
225            in self.browser.contents)
226
227    def test_pg_application_manage(self):
228        # Add pg applicants container
229        self.pgcontainer = ApplicantsContainer()
230        self.pgcontainer.mode = 'create'
231        self.pgcontainer.code = u'pgft%s' % session_1
232        self.pgcontainer.prefix = u'pgft'
233        self.pgcontainer.application_category = u'no'
234        self.pgcontainer.year = session_1
235        self.pgcontainer.application_fee = 300.0
236        self.pgcontainer.title = u'This is the pgft%s container' % session_1
237        self.app['applicants'][self.pgcontainer.code] = self.pgcontainer
238        delta = datetime.timedelta(days=10)
239        self.pgcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
240        self.pgcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
241        # Add applicant
242        pgapplicant = createObject(u'waeup.Applicant')
243        pgapplicant.firstname = u'Anna'
244        pgapplicant.lastname = u'Post'
245        self.app['applicants'][self.pgcontainer.code].addApplicant(pgapplicant)
246        self.pgapplication_number = pgapplicant.application_number
247        self.pgapplicant = self.app['applicants'][self.pgcontainer.code][
248            self.pgapplication_number]
249        self.pgapplicant_path = ('http://localhost/app/applicants/pgft%s/%s'
250            % (session_1, self.pgapplication_number))
251        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
252        self.browser.open(self.pgapplicant_path)
253        self.assertEqual(self.browser.headers['Status'], '200 Ok')
254        self.assertTrue("3rd Higher Education Record" in self.browser.contents)
255
256    def test_transcript_payment(self):
257        configuration = SessionConfiguration()
258        configuration.academic_session = session_1
259        self.app['configuration'].addSessionConfiguration(configuration)
260        # Add special application container
261        applicantscontainer = ApplicantsContainer()
262        applicantscontainer.year = session_1
263        applicantscontainer.application_fee = 200.0
264        applicantscontainer.code = u'trans1234'
265        applicantscontainer.prefix = 'trans'
266        applicantscontainer.title = u'This is a trans container'
267        applicantscontainer.application_category = 'no'
268        applicantscontainer.mode = 'create'
269        applicantscontainer.strict_deadline = True
270        delta = datetime.timedelta(days=10)
271        applicantscontainer.startdate = datetime.datetime.now(pytz.utc) - delta
272        applicantscontainer.enddate = datetime.datetime.now(pytz.utc) + delta
273        self.app['applicants']['trans1234'] = applicantscontainer
274        # Add an applicant
275        applicant = createObject('waeup.Applicant')
276        # reg_number is the only field which has to be preset here
277        # because managers are allowed to edit this required field
278        applicant.reg_number = u'12345'
279        self.app['applicants']['trans1234'].addApplicant(applicant)
280        IUserAccount(
281            self.app['applicants']['trans1234'][
282            applicant.application_number]).setPassword('apwd')
283        # Login
284        self.browser.open(self.login_path)
285        self.browser.getControl(
286            name="form.login").value = applicant.applicant_id
287        self.browser.getControl(name="form.password").value = 'apwd'
288        self.browser.getControl("Login").click()
289        self.browser.getLink("Edit").click()
290        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
291        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
292        self.browser.getControl(name="form.nationality").value = ['NG']
293        self.browser.getControl(name="form.firstname").value = 'Angela'
294        self.browser.getControl(name="form.lastname").value = 'Merkel'
295        self.browser.getControl(name="form.sex").value = ['f']
296        self.browser.getControl(name="form.no_copies").value = ['3']
297        self.browser.getControl(name="form.course_studied").value = ['CERT1']
298        self.browser.getControl(name="form.matric_number").value = '234'
299        self.browser.getControl(name="form.place_of_birth").value = 'Bochum'
300        self.browser.getControl(name="form.dispatch_address").value = 'Kuensche'
301        self.browser.getControl(name="form.perm_address").value = 'Kuensche'
302        self.browser.getControl(name="form.entry_mode").value = ['ug_ft']
303        self.browser.getControl(name="form.entry_session").value = ['2014']
304        self.browser.getControl(name="form.end_session").value = ['2015']
305        self.browser.getControl(name="form.phone.country").value = ['+234']
306        self.browser.getControl(name="form.phone.ext").value = '5678'
307        self.browser.getControl("Save").click()
308        self.browser.getControl("Add online payment ticket").click()
309        self.assertTrue('Payment ticket created' in self.browser.contents)
310        self.assertTrue('<span>200.0</span>' in self.browser.contents)
311        self.assertEqual(applicant.values()[0].amount_auth, 200.0)
312        return
313
314    def test_view_course_admitted(self):
315        self.applicant.course_admitted = self.certificate
316        self.login()
317        self.assertFalse('Admitted Course of Study' in self.browser.contents)
318        return
319
320    def test_upload_stateresult_by_manager(self):
321        # Add trans applicants container
322        self.transcontainer = ApplicantsContainer()
323        self.transcontainer.mode = 'create'
324        self.transcontainer.code = u'trans%s' % session_1
325        self.transcontainer.prefix = u'trans'
326        self.transcontainer.application_category = u'no'
327        self.transcontainer.year = session_1
328        self.transcontainer.application_fee = 300.0
329        self.transcontainer.title = u'This is the trans%s container' % session_1
330        self.app['applicants'][self.transcontainer.code] = self.transcontainer
331        delta = datetime.timedelta(days=10)
332        self.transcontainer.startdate = datetime.datetime.now(pytz.utc) - delta
333        self.transcontainer.enddate = datetime.datetime.now(pytz.utc) + delta
334        # Add applicant
335        transapplicant = createObject(u'waeup.Applicant')
336        transapplicant.firstname = u'Anna'
337        transapplicant.lastname = u'Post'
338        self.app['applicants'][self.transcontainer.code].addApplicant(transapplicant)
339        self.transapplicant = self.app['applicants'][self.transcontainer.code][
340            transapplicant.application_number]
341        self.transapplicant_view_path = ('http://localhost/app/applicants/trans%s/%s'
342            % (session_1, transapplicant.application_number))
343        self.transapplicant_manage_path = ('http://localhost/app/applicants/trans%s/%s/manage'
344            % (session_1, transapplicant.application_number))
345        # Login
346        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
347        self.browser.open(self.transapplicant_manage_path)
348        # Create a pseudo file with acceptable size
349        #pdf_content = 'A' * 1024 * 300  # A string of 300 KB size
350        #pseudo_pdf = StringIO(pdf_content)
351        image = open(SAMPLE_IMAGE, 'rb')
352        ctrl = self.browser.getControl(name='stateresult')
353        file_ctrl = ctrl.mech_control
354        file_ctrl.add_file(image, filename='my_scan.jpg')
355        self.browser.getControl("Save").click() # submit form
356        # Even though the form could not be saved ...
357        self.assertTrue('Required input is missing' in self.browser.contents)
358        # ... the file has been successfully uploaded
359        image_url = self.transapplicant_manage_path.replace('manage', 'stateresult')
360        self.browser.open(image_url)
361        self.assertEqual(
362            self.browser.headers['content-type'], 'image/jpeg')
363        self.assertEqual(len(self.browser.contents), 2787)
364        # There is really a file stored for the applicant
365        storage = getUtility(IExtFileStore)
366        file_id = IFileStoreNameChooser(self.transapplicant).chooseName(
367            attr='stateresult.pdf')
368        # The stored file can be fetched
369        fd = storage.getFile(file_id)
370        file_len = len(fd.read())
371        self.assertEqual(file_len, 2787)
372        # A file link is displayed on the edit view ...
373        self.browser.open(self.transapplicant_manage_path)
374        self.assertTrue('<a href="stateresult">' in self.browser.contents)
375        # ... and on the dislay view
376        self.browser.open(self.transapplicant_view_path)
377        self.assertTrue('stateresult">Statement of Result</a>'
378            in self.browser.contents)
379        # Adding file is properly logged
380        logfile = os.path.join(
381            self.app['datacenter'].storage, 'logs', 'applicants.log')
382        logcontent = open(logfile).read()
383        self.assertTrue(
384            'zope.mgr - waeup.aaue.applicants.browser.CustomApplicantManageFormPage'
385            ' - %s - saved: stateresult'
386            % (self.transapplicant.applicant_id)
387            in logcontent)
388        # When an applicant is removed, also the pdf files are gone.
389        del self.app['applicants'][self.transcontainer.code][self.transapplicant.application_number]
390        fd = storage.getFile(file_id)
391        self.assertTrue(fd is None)
392
393    def test_upload_verificationdoc_by_manager(self):
394        # Add ver applicants container
395        self.vercontainer = ApplicantsContainer()
396        self.vercontainer.mode = 'create'
397        self.vercontainer.code = u'ver%s' % session_1
398        self.vercontainer.prefix = u'ver'
399        self.vercontainer.application_category = u'no'
400        self.vercontainer.year = session_1
401        self.vercontainer.application_fee = 300.0
402        self.vercontainer.title = u'This is the ver%s container' % session_1
403        self.app['applicants'][self.vercontainer.code] = self.vercontainer
404        delta = datetime.timedelta(days=10)
405        self.vercontainer.startdate = datetime.datetime.now(pytz.utc) - delta
406        self.vercontainer.enddate = datetime.datetime.now(pytz.utc) + delta
407        # Add applicant
408        verapplicant = createObject(u'waeup.Applicant')
409        verapplicant.firstname = u'Anna'
410        verapplicant.lastname = u'Post'
411        self.app['applicants'][self.vercontainer.code].addApplicant(verapplicant)
412        self.verapplicant = self.app['applicants'][self.vercontainer.code][
413            verapplicant.application_number]
414        self.verapplicant_view_path = ('http://localhost/app/applicants/ver%s/%s'
415            % (session_1, verapplicant.application_number))
416        self.verapplicant_manage_path = ('http://localhost/app/applicants/ver%s/%s/manage'
417            % (session_1, verapplicant.application_number))
418        # Login
419        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
420        self.browser.open(self.verapplicant_manage_path)
421        # Create a pseudo file with acceptable size
422        #pdf_content = 'A' * 1024 * 300  # A string of 300 KB size
423        #pseudo_pdf = StringIO(pdf_content)
424        image = open(SAMPLE_IMAGE, 'rb')
425        ctrl = self.browser.getControl(name='verificationdoc')
426        file_ctrl = ctrl.mech_control
427        file_ctrl.add_file(image, filename='my_scan.jpg')
428        self.browser.getControl("Save").click() # submit form
429        # Even though the form could not be saved ...
430        self.assertTrue('Required input is missing' in self.browser.contents)
431        # ... the file has been successfully uploaded
432        image_url = self.verapplicant_manage_path.replace('manage', 'verificationdoc')
433        self.browser.open(image_url)
434        self.assertEqual(
435            self.browser.headers['content-type'], 'image/jpeg')
436        self.assertEqual(len(self.browser.contents), 2787)
437        # There is really a file stored for the applicant
438        storage = getUtility(IExtFileStore)
439        file_id = IFileStoreNameChooser(self.verapplicant).chooseName(
440            attr='verificationdoc.pdf')
441        # The stored file can be fetched
442        fd = storage.getFile(file_id)
443        file_len = len(fd.read())
444        self.assertEqual(file_len, 2787)
445        # A file link is displayed on the edit view ...
446        self.browser.open(self.verapplicant_manage_path)
447        self.assertTrue('<a href="verificationdoc">' in self.browser.contents)
448        # ... and on the dislay view
449        self.browser.open(self.verapplicant_view_path)
450        self.assertTrue('verificationdoc">Result/Certificate Document</a>'
451            in self.browser.contents)
452        # Adding file is properly logged
453        logfile = os.path.join(
454            self.app['datacenter'].storage, 'logs', 'applicants.log')
455        logcontent = open(logfile).read()
456        self.assertTrue(
457            'zope.mgr - waeup.aaue.applicants.browser.CustomApplicantManageFormPage'
458            ' - %s - saved: verificationdoc'
459            % (self.verapplicant.applicant_id)
460            in logcontent)
461        # When an applicant is removed, also the files are gone.
462        del self.app['applicants'][self.vercontainer.code][self.verapplicant.application_number]
463        fd = storage.getFile(file_id)
464        self.assertTrue(fd is None)
Note: See TracBrowser for help on using the repository browser.