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

Last change on this file since 15570 was 15530, checked in by Henrik Bettermann, 5 years ago

Implement Verification of Result/Transcript? and Certificate application form.

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