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

Last change on this file since 16827 was 16548, checked in by Henrik Bettermann, 3 years ago

Adjust to changes in base package.

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