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

Last change on this file since 16250 was 16240, checked in by Henrik Bettermann, 4 years ago

Don't allow the total outcome of course grade exceed 100 (ie if CA + Score > 100, return "total score is greater than 100").

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