source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/tests/test_browser.py @ 7259

Last change on this file since 7259 was 7259, checked in by Henrik Bettermann, 13 years ago

Use reduced display form page as header in payment receipts.
Add more tests.

  • Property svn:keywords set to Id
File size: 33.0 KB
Line 
1## $Id: test_browser.py 7259 2011-12-03 08:35:33Z 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##
18"""
19Test the applicant-related UI components.
20"""
21import shutil
22import tempfile
23from StringIO import StringIO
24from datetime import datetime, date, timedelta
25from mechanize import LinkNotFoundError
26from zope.component import createObject, getUtility
27from zope.component.hooks import setSite, clearSite
28from zope.security.interfaces import Unauthorized
29from zope.testbrowser.testing import Browser
30from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
31from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
32from waeup.sirp.app import University
33from waeup.sirp.configuration import SessionConfiguration
34from waeup.sirp.applicants.container import ApplicantsContainer
35from waeup.sirp.applicants.applicant import Applicant
36from waeup.sirp.interfaces import (
37    IExtFileStore, IFileStoreNameChooser, IUserAccount)
38from waeup.sirp.university.faculty import Faculty
39from waeup.sirp.university.department import Department
40
41PH_LEN = 2059  # Length of placeholder file
42
43class ApplicantsFullSetup(FunctionalTestCase):
44    # A test case that only contains a setup and teardown
45    #
46    # Complete setup for applicants handlings is rather complex and
47    # requires lots of things created before we can start. This is a
48    # setup that does all this, creates a university, creates PINs,
49    # etc.  so that we do not have to bother with that in different
50    # test cases.
51
52    layer = FunctionalLayer
53
54    def setUp(self):
55        super(ApplicantsFullSetup, self).setUp()
56
57        # Setup a sample site for each test
58        app = University()
59        self.dc_root = tempfile.mkdtemp()
60        app['datacenter'].setStoragePath(self.dc_root)
61
62        # Prepopulate the ZODB...
63        self.getRootFolder()['app'] = app
64        # we add the site immediately after creation to the
65        # ZODB. Catalogs and other local utilities are not setup
66        # before that step.
67        self.app = self.getRootFolder()['app']
68        # Set site here. Some of the following setup code might need
69        # to access grok.getSite() and should get our new app then
70        setSite(app)
71
72        self.login_path = 'http://localhost/app/login'
73        self.root_path = 'http://localhost/app/applicants'
74        self.manage_root_path = self.root_path + '/@@manage'
75        self.add_container_path = self.root_path + '/@@add'
76        self.container_path = 'http://localhost/app/applicants/app2009'
77        self.manage_container_path = self.container_path + '/@@manage'
78
79        # Add an applicants container
80        applicantscontainer = ApplicantsContainer()
81        applicantscontainer.ac_prefix = 'APP'
82        applicantscontainer.code = u'app2009'
83        applicantscontainer.prefix = 'app'
84        applicantscontainer.year = 2009
85        applicantscontainer.application_category = 'basic'
86        delta = timedelta(days=10)
87        applicantscontainer.startdate = date.today() - delta
88        applicantscontainer.enddate = date.today() + delta
89        self.app['applicants']['app2009'] = applicantscontainer
90        self.applicantscontainer = self.app['applicants']['app2009']
91
92        # Populate university
93        certificate = createObject('waeup.Certificate')
94        certificate.code = 'CERT1'
95        certificate.application_category = 'basic'
96        self.certificate = certificate
97        self.app['faculties']['fac1'] = Faculty()
98        self.app['faculties']['fac1']['dep1'] = Department()
99        self.department = self.app['faculties']['fac1']['dep1']
100        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
101            certificate)
102
103        # Put the prepopulated site into test ZODB and prepare test
104        # browser
105        self.browser = Browser()
106        self.browser.handleErrors = False
107
108        # Create 5 access codes with prefix'FOO' and cost 9.99 each
109        pin_container = self.app['accesscodes']
110        pin_container.createBatch(
111            datetime.now(), 'some_userid', 'APP', 9.99, 5)
112        pins = pin_container[pin_container.keys()[0]].values()
113        self.pins = [x.representation for x in pins]
114        self.existing_pin = self.pins[0]
115        parts = self.existing_pin.split('-')[1:]
116        self.existing_series, self.existing_number = parts
117
118        # Add an applicant
119        self.applicant = Applicant(container=applicantscontainer)
120        app['applicants']['app2009'][
121            self.applicant.application_number] = self.applicant
122        IUserAccount(
123            self.app['applicants']['app2009'][
124            self.applicant.application_number]).setPassword('apwd')
125        self.manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
126            'app2009', self.applicant.application_number, 'manage')
127        self.edit_path = 'http://localhost/app/applicants/%s/%s/%s' % (
128            'app2009', self.applicant.application_number, 'edit')
129        self.view_path = 'http://localhost/app/applicants/%s/%s' % (
130            'app2009', self.applicant.application_number)
131
132    def login(self):
133        # Perform an applicant login. This creates an applicant record.
134        #
135        # This helper also sets `self.applicant`, which is the
136        # applicant object created.
137        self.browser.open(self.login_path)
138        self.browser.getControl(name="form.login").value = self.applicant.applicant_id
139        self.browser.getControl(name="form.password").value = 'apwd'
140        self.browser.getControl("Login").click()
141
142    def fill_correct_values(self):
143        # Fill the edit form with suitable values
144        self.browser.getControl(name="form.firstname").value = 'John'
145        self.browser.getControl(name="form.lastname").value = 'Tester'
146        self.browser.getControl(name="form.course1").value = ['CERT1']
147        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
148        self.browser.getControl(name="form.lga").value = ['foreigner']
149        self.browser.getControl(name="form.sex").value = ['m']
150        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
151
152    def tearDown(self):
153        super(ApplicantsFullSetup, self).tearDown()
154        clearSite()
155        shutil.rmtree(self.dc_root)
156
157class ApplicantsRootUITests(ApplicantsFullSetup):
158    # Tests for ApplicantsRoot class
159
160    layer = FunctionalLayer
161
162    def test_anonymous_access(self):
163        # Anonymous users can access applicants root
164        self.browser.open(self.root_path)
165        self.assertEqual(self.browser.headers['Status'], '200 Ok')
166        self.assertFalse(
167            'Manage' in self.browser.contents)
168
169   
170    def test_anonymous_no_actions(self):
171        # Make sure anonymous users cannot access actions
172        self.browser.open(self.root_path)
173        self.assertRaises(
174            LookupError, self.browser.getControl, "Add local role")
175        # Manage screen neither linked nor accessible for anonymous
176        self.assertRaises(
177            LinkNotFoundError,
178            self.browser.getLink, 'Manage application section')
179        self.assertRaises(
180            Unauthorized, self.browser.open, self.manage_root_path)
181        # Add container screen not accessible for anonymous
182        self.assertRaises(
183            Unauthorized, self.browser.open, self.add_container_path)
184        return
185
186    def test_manage_access(self):
187        # Managers can access the manage pages of applicants root
188        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
189        self.browser.open(self.root_path)
190        self.assertTrue('Manage application section' in self.browser.contents)
191        # There is a manage link
192        link = self.browser.getLink('Manage application section')
193        link.click()
194        self.assertEqual(self.browser.headers['Status'], '200 Ok')
195        self.assertEqual(self.browser.url, self.manage_root_path)
196
197    def test_manage_actions_access(self):
198        # Managers can access the action on manage screen
199        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
200        self.browser.open(self.manage_root_path)
201        self.browser.getControl("Add local role").click()
202        self.assertTrue('No user selected' in self.browser.contents)
203        return
204
205    # We have no local roles yet
206    #def test_local_roles_add_delete(self):
207    #    # Managers can assign and delete local roles of applicants root
208    #    myusers = self.app['users']
209    #    myusers.addUser('bob', 'bobssecret')
210    #    self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
211    #    self.browser.open(self.manage_root_path)
212    #    self.browser.getControl(name="user").value = ['bob']
213    #    self.browser.getControl(name="local_role").value = [
214    #        'waeup.local.ApplicationsOfficer']
215    #    self.browser.getControl("Add local role").click()
216    #    self.assertTrue('<td>bob</td>' in self.browser.contents)
217    #    # Remove the role assigned
218    #    ctrl = self.browser.getControl(name='role_id')
219    #    ctrl.getControl(value='bob|waeup.ApplicationsOfficer').selected = True
220    #    self.browser.getControl("Remove selected local roles").click()
221    #    self.assertTrue('Successfully removed:' in self.browser.contents)
222    #    self.assertFalse('<td>bob</td>' in self.browser.contents)
223    #    return
224
225    def test_add_delete_container(self):
226        # Managers can add and delete applicants containers
227        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
228        self.browser.open(self.manage_root_path)
229        self.browser.getControl("Cancel").click()
230        self.assertEqual(self.browser.url, self.root_path)
231        self.browser.open(self.manage_root_path)
232        self.browser.getControl("Add applicants container").click()
233        self.assertEqual(self.browser.headers['Status'], '200 Ok')
234        self.assertEqual(self.browser.url, self.add_container_path)
235        self.browser.getControl(name="form.prefix").value = ['app']
236        self.browser.getControl("Add applicants container").click()
237        self.assertTrue(
238            'There were errors' in self.browser.contents)
239        self.browser.getControl(name="form.prefix").value = ['app']
240        self.browser.getControl(name="form.year").value = ['2010']
241        self.browser.getControl(name="form.provider").value = [
242            'waeup.sirp.applicants.ApplicantsContainer']
243        self.browser.getControl(name="form.ac_prefix").value = ['APP']
244        self.browser.getControl(name="form.application_category").value = ['basic']
245        self.browser.getControl("Add applicants container").click()
246        self.assertTrue('Added:' in self.browser.contents)
247        self.browser.open(self.add_container_path)
248        self.browser.getControl("Cancel").click()
249        self.assertEqual(self.browser.url, self.manage_root_path + '#tab-1')
250        self.browser.open(self.add_container_path)
251        self.browser.getControl(name="form.prefix").value = ['app']
252        self.browser.getControl(name="form.year").value = ['2010']
253        self.browser.getControl(name="form.provider").value = [
254            'waeup.sirp.applicants.ApplicantsContainer']
255        self.browser.getControl(name="form.ac_prefix").value = ['APP']
256        self.browser.getControl(name="form.application_category").value = ['basic']
257        self.browser.getControl("Add applicants container").click()
258        self.assertTrue('exists already in the database' in self.browser.contents)
259        self.browser.open(self.manage_root_path)
260        ctrl = self.browser.getControl(name='val_id')
261        ctrl.getControl(value='app2010').selected = True
262        self.browser.getControl("Remove selected", index=0).click()
263        self.assertTrue('Successfully removed:' in self.browser.contents)
264        self.browser.open(self.add_container_path)
265        self.browser.getControl(name="form.prefix").value = ['app']
266        self.browser.getControl(name="form.year").value = ['2010']
267        self.browser.getControl(name="form.provider").value = [
268            'waeup.sirp.applicants.ApplicantsContainer']
269        self.browser.getControl(name="form.ac_prefix").value = ['APP']
270        self.browser.getControl(name="form.application_category").value = ['basic']
271        self.browser.getControl("Add applicants container").click()
272        del self.app['applicants']['app2010']
273        ctrl = self.browser.getControl(name='val_id')
274        ctrl.getControl(value='app2010').selected = True
275        self.browser.getControl("Remove selected", index=0).click()
276        self.assertMatches('...Could not delete...', self.browser.contents)
277        return
278
279    def test_add_delete_applicants(self):
280        # Managers can add and delete applicants
281        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
282        self.add_applicant_path = self.container_path + '/addapplicant'
283        self.container_manage_path = self.container_path + '/@@manage'
284        self.browser.open(self.container_manage_path)
285        self.browser.getControl("Add applicant").click()
286        self.assertEqual(self.browser.headers['Status'], '200 Ok')
287        self.assertEqual(self.browser.url, self.add_applicant_path)
288        self.browser.getControl(name="form.firstname").value = 'Alois'
289        self.browser.getControl(name="form.middlenames").value = 'Kofi'
290        self.browser.getControl(name="form.lastname").value = 'Bettermann'
291        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
292        self.browser.getControl("Create application record").click()
293        self.assertTrue('Application initialized' in self.browser.contents)
294        self.browser.open(self.container_manage_path)
295        self.assertEqual(self.browser.headers['Status'], '200 Ok')
296        ctrl = self.browser.getControl(name='val_id')
297        value = ctrl.options[0]
298        ctrl.getControl(value=value).selected = True
299        self.browser.getControl("Remove selected", index=0).click()
300        self.assertTrue('Successfully removed:' in self.browser.contents)
301        self.browser.open(self.add_applicant_path)
302        self.browser.getControl(name="form.firstname").value = 'Albert'
303        self.browser.getControl(name="form.lastname").value = 'Einstein'
304        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
305        self.browser.getControl("Create application record").click()
306        self.assertTrue('Application initialized' in self.browser.contents)
307        return
308
309    def test_manage_and_view_applicant(self):
310        # Managers can manage applicants
311        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
312        self.slip_path = self.view_path + '/application_slip.pdf'
313        self.browser.open(self.manage_path)
314        self.assertEqual(self.browser.headers['Status'], '200 Ok')
315        self.fill_correct_values()
316        # Fire transition
317        self.browser.getControl(name="transition").value = ['start']
318        self.browser.getControl("Save").click()
319        self.assertMatches('...Form has been saved...', self.browser.contents)
320        self.assertMatches('...Application started by zope.mgr...', self.browser.contents)
321        self.browser.open(self.view_path)
322        self.assertEqual(self.browser.headers['Status'], '200 Ok')
323        # Change course_admitted
324        self.browser.open(self.manage_path)
325        self.browser.getControl(name="form.course_admitted").value = []
326        self.browser.getControl("Save").click()
327        self.assertMatches('...Form has been saved...', self.browser.contents)
328        # Change password
329        self.browser.getControl(name="password").value = 'secret'
330        self.browser.getControl(name="control_password").value = 'secre'
331        self.browser.getControl("Save").click()
332        self.assertMatches('...Passwords do not match...', self.browser.contents)
333        self.browser.getControl(name="password").value = 'secret'
334        self.browser.getControl(name="control_password").value = 'secret'
335        self.browser.getControl("Save").click()
336        self.assertMatches('...Form has been saved...', self.browser.contents)
337        # Open pdf slip
338        self.browser.open(self.slip_path)
339        self.assertEqual(self.browser.headers['Status'], '200 Ok')
340        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
341        return
342
343    def test_passport_edit_view(self):
344        # We get a default image after login
345        self.browser.open(self.login_path)
346        self.login()
347        self.browser.open(self.browser.url + '/passport.jpg')
348        self.assertEqual(self.browser.headers['status'], '200 Ok')
349        self.assertEqual(self.browser.headers['content-type'], 'image/jpeg')
350        self.assertTrue('JFIF' in self.browser.contents)
351        self.assertEqual(
352            self.browser.headers['content-length'], str(PH_LEN))
353
354    def test_edit_applicant(self):
355        # Applicants can edit their record
356        self.browser.open(self.login_path)
357        self.login()
358        self.browser.open(self.edit_path)
359        self.assertTrue(self.browser.url != self.login_path)
360        self.assertEqual(self.browser.headers['Status'], '200 Ok')
361        self.fill_correct_values()
362        self.browser.getControl("Save").click()
363        self.assertMatches('...Form has been saved...', self.browser.contents)
364        return
365
366class ApplicantsContainerUITests(ApplicantsFullSetup):
367    # Tests for ApplicantsContainer class views and pages
368
369    layer = FunctionalLayer
370
371    def test_anonymous_access(self):
372        # Anonymous users can access applicants containers
373        self.browser.open(self.container_path)
374        self.assertEqual(self.browser.headers['Status'], '200 Ok')
375        self.assertFalse(
376            'Manage' in self.browser.contents)
377        return
378
379    def test_manage_access(self):
380        # Managers can access the manage pages of applicants
381        # containers and can perform actions
382        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
383        self.browser.open(self.manage_container_path)
384        self.assertEqual(self.browser.headers['Status'], '200 Ok')
385        self.assertEqual(self.browser.url, self.manage_container_path)
386        self.browser.getControl("Save").click()
387        self.assertTrue('Data saved' in self.browser.contents)
388        self.browser.getControl("Remove selected", index=0).click()
389        self.assertTrue('No applicant selected' in self.browser.contents)
390        self.browser.getControl("Add local role").click()
391        self.assertTrue('No user selected' in self.browser.contents)
392        self.browser.getControl("Cancel", index=0).click()
393        self.assertEqual(self.browser.url, self.container_path)
394        return
395
396class ApplicantsPassportTests(ApplicantsFullSetup):
397    # Tests for uploading/browsing the passport image of appplicants
398
399    layer = FunctionalLayer
400
401    def image_url(self, filename):
402        return self.edit_path.replace('edit', filename)
403
404    def test_after_login_default_browsable(self):
405        # After login we see the placeholder image in the edit view
406        #import pdb; pdb.set_trace()
407        self.login()
408        self.assertEqual(self.browser.url, self.view_path)
409        self.browser.open(self.edit_path)
410        # There is a correct <img> link included
411        self.assertTrue(
412              '<img src="passport.jpg" />' in self.browser.contents)
413        # Browsing the link shows a real image
414        self.browser.open(self.image_url('passport.jpg'))
415        self.assertEqual(
416            self.browser.headers['content-type'], 'image/jpeg')
417        self.assertEqual(len(self.browser.contents), PH_LEN)
418
419    def test_after_submit_default_browsable(self):
420        # After submitting an applicant form the default image is
421        # still visible
422        self.login()
423        self.browser.open(self.edit_path)
424        self.browser.getControl("Save").click() # submit form
425        # There is a correct <img> link included
426        self.assertTrue(
427            '<img src="passport.jpg" />' in self.browser.contents)
428        # Browsing the link shows a real image
429        self.browser.open(self.image_url('passport.jpg'))
430        self.assertEqual(
431            self.browser.headers['content-type'], 'image/jpeg')
432        self.assertEqual(len(self.browser.contents), PH_LEN)
433
434    def test_uploaded_image_respects_file_size_restriction(self):
435        # When we upload an image that is too big ( > 10 KB) we will
436        # get an error message
437        self.login()
438        self.browser.open(self.edit_path)
439        # Create a pseudo image file and select it to be uploaded in form
440        photo_content = 'A' * 1024 * 21  # A string of 21 KB size
441        pseudo_image = StringIO(photo_content)
442        ctrl = self.browser.getControl(name='form.passport')
443        file_ctrl = ctrl.mech_control
444        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
445        self.browser.getControl("Save").click() # submit form
446        # There is a correct <img> link included
447        self.assertTrue(
448            '<img src="passport.jpg" />' in self.browser.contents)
449        # We get a warning message
450        self.assertTrue(
451            'Uploaded image is too big' in self.browser.contents)
452        # Browsing the image gives us the default image, not the
453        # uploaded one.
454        self.browser.open(self.image_url('passport.jpg'))
455        self.assertEqual(
456            self.browser.headers['content-type'], 'image/jpeg')
457        self.assertEqual(len(self.browser.contents), PH_LEN)
458        # There is really no file stored for the applicant
459        img = getUtility(IExtFileStore).getFile(
460            IFileStoreNameChooser(self.applicant).chooseName())
461        self.assertTrue(img is None)
462
463    def test_uploaded_image_browsable_w_errors(self):
464        # We can upload a different image and browse it after submit,
465        # even if there are still errors in the form
466        self.login()
467        self.browser.open(self.edit_path)
468        # Create a pseudo image file and select it to be uploaded in form
469        photo_content = 'I pretend to be a graphics file'
470        pseudo_image = StringIO(photo_content)
471        ctrl = self.browser.getControl(name='form.passport')
472        file_ctrl = ctrl.mech_control
473        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
474        self.browser.getControl("Save").click() # submit form
475        # There is a correct <img> link included
476        self.assertTrue(
477            '<img src="passport.jpg" />' in self.browser.contents)
478        # Browsing the link shows a real image
479        self.browser.open(self.image_url('passport.jpg'))
480        self.assertEqual(
481            self.browser.headers['content-type'], 'image/jpeg')
482        self.assertEqual(self.browser.contents, photo_content)
483
484    def test_uploaded_image_stored_in_imagestorage_w_errors(self):
485        # After uploading a new passport pic the file is correctly
486        # stored in an imagestorage
487        self.login()
488        self.browser.open(self.edit_path)
489        # Create a pseudo image file and select it to be uploaded in form
490        pseudo_image = StringIO('I pretend to be a graphics file')
491        ctrl = self.browser.getControl(name='form.passport')
492        file_ctrl = ctrl.mech_control
493        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
494        self.browser.getControl("Save").click() # submit form
495        storage = getUtility(IExtFileStore)
496        file_id = IFileStoreNameChooser(self.applicant).chooseName()
497        pseudo_image.seek(0) # reset our file data source
498        self.assertEqual(
499            storage.getFile(file_id).read(), pseudo_image.read())
500        return
501
502    def test_uploaded_image_browsable_wo_errors(self):
503        # We can upload a different image and browse it after submit,
504        # if there are no errors in form
505        self.login()
506        self.browser.open(self.edit_path)
507        self.fill_correct_values() # fill other fields with correct values
508        # Create a pseudo image file and select it to be uploaded in form
509        pseudo_image = StringIO('I pretend to be a graphics file')
510        ctrl = self.browser.getControl(name='form.passport')
511        file_ctrl = ctrl.mech_control
512        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
513        self.browser.getControl("Save").click() # submit form
514        # There is a correct <img> link included
515        self.assertTrue(
516            '<img src="passport.jpg" />' in self.browser.contents)
517        # Browsing the link shows a real image
518        self.browser.open(self.image_url('passport.jpg'))
519        self.assertEqual(
520            self.browser.headers['content-type'], 'image/jpeg')
521        self.assertEqual(len(self.browser.contents), 31)
522
523    def test_uploaded_image_stored_in_imagestorage_wo_errors(self):
524        # After uploading a new passport pic the file is correctly
525        # stored in an imagestorage if form contains no errors
526        self.login()
527        self.browser.open(self.edit_path)
528        self.fill_correct_values() # fill other fields with correct values
529        # Create a pseudo image file and select it to be uploaded in form
530        pseudo_image = StringIO('I pretend to be a graphics file')
531        ctrl = self.browser.getControl(name='form.passport')
532        file_ctrl = ctrl.mech_control
533        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
534        self.browser.getControl("Save").click() # submit form
535        storage = getUtility(IExtFileStore)
536        file_id = IFileStoreNameChooser(self.applicant).chooseName()
537        # The stored image can be fetched
538        fd = storage.getFile(file_id)
539        file_len = len(fd.read())
540        self.assertEqual(file_len, 31)
541
542    def test_uploaded_images_equal(self):
543        # Make sure uploaded images do really differ if we eject a
544        # change notfication (and do not if we don't)
545        self.login()
546        self.browser.open(self.edit_path)
547        self.fill_correct_values() # fill other fields with correct values
548        self.browser.getControl("Save").click() # submit form
549        # Now go on as an officer
550        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
551        self.browser.open(self.manage_path)
552
553        # Create a pseudo image file and select it to be uploaded in form
554        pseudo_image = StringIO('I pretend to be a graphics file')
555        ctrl = self.browser.getControl(name='form.passport')
556        file_ctrl = ctrl.mech_control
557        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
558        file_id = IFileStoreNameChooser(self.applicant).chooseName()
559        setSite(self.app)
560        passport0 = getUtility(IExtFileStore).getFile(file_id)
561        self.browser.getControl("Save").click() # submit form with changed pic
562        passport1 = getUtility(IExtFileStore).getFile(file_id).read()
563        self.browser.getControl("Save").click() # submit form w/o changes
564        passport2 = getUtility(IExtFileStore).getFile(file_id).read()
565        self.assertTrue(passport0 is None)
566        self.assertTrue(passport0 != passport1)
567        self.assertTrue(passport1 == passport2)
568        return
569
570    def test_pay_acceptance_fee(self):
571        self.login()
572        self.browser.open(self.edit_path)
573        # Payment tickets can't be created before the form has been validated
574        self.browser.getControl("Add online payment ticket").click()
575        self.assertTrue('Required input is missing' in self.browser.contents)
576        self.fill_correct_values()
577        # We have to savethe form otherwise the filled fields will be cleared
578        # after adding an online payment, because adding an online payment
579        # requires a filled form but does not save it
580        self.browser.getControl("Save").click()
581        self.browser.getControl("Add online payment ticket").click()
582        # Session object missing
583        self.assertTrue(
584            'Session configuration object is not available'
585            in self.browser.contents)
586        configuration = SessionConfiguration()
587        configuration.academic_session = 2009
588        configuration.acceptance_fee = 200
589        self.app['configuration'].addSessionConfiguration(configuration)
590        self.browser.open(self.edit_path)
591        self.fill_correct_values()
592        self.browser.getControl("Add online payment ticket").click()
593        self.assertMatches('...Payment ticket created...', self.browser.contents)
594        # Payment ticket can be removed if they haven't received a valid callback
595        ctrl = self.browser.getControl(name='val_id')
596        value = ctrl.options[0]
597        ctrl.getControl(value=value).selected = True
598        self.browser.getControl("Remove selected", index=0).click()
599        self.assertMatches('...Successfully removed...', self.browser.contents)
600        # We will try the callback request view
601        self.browser.getControl("Add online payment ticket").click()
602        ctrl = self.browser.getControl(name='val_id')
603        value = ctrl.options[0]
604        self.browser.getLink(value).click()
605        self.assertMatches('...Amount Authorized...',
606                           self.browser.contents)
607        payment_url = self.browser.url
608        # The pdf payment receipt can't yet be opened
609        self.browser.open(payment_url + '/payment_receipt.pdf')
610        self.assertMatches('...Ticket not yet paid...',
611                           self.browser.contents)
612        # Request callback
613        self.browser.open(payment_url)
614        self.browser.getLink("Request callback").click()
615        self.assertMatches('...Valid callback received...',
616                          self.browser.contents)
617        # Callback can't be applied twice
618        self.browser.open(payment_url + '/callback')
619        self.assertMatches('...This ticket has already been paid...',
620                          self.browser.contents)
621        # The payment receipt can be downloaded now
622        self.browser.open(payment_url)
623        self.browser.getLink("Download payment receipt").click()
624        self.assertEqual(self.browser.headers['Status'], '200 Ok')
625        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
626        # Applicant is is in state 'paid'
627        self.browser.open(self.view_path)
628        self.assertMatches('...paid...',
629                           self.browser.contents)
630        state = IWorkflowState(self.applicant).getState()
631        self.assertTrue(state == 'paid')
632
633    def test_final_submit(self):
634        # Make sure that a correctly filled form with passport picture
635        # can be submitted (only) after payment
636        self.login()
637        self.browser.getLink("Edit application record").click()
638        self.assertFalse('Final Submit' in self.browser.contents)
639        IWorkflowInfo(self.applicant).fireTransition('pay')
640        self.browser.open(self.edit_path)
641        self.assertTrue('Final Submit' in self.browser.contents)
642        self.fill_correct_values() # fill other fields with correct values
643        self.browser.getControl("Final Submit").click()
644        # We forgot to upload a passport picture
645        self.assertTrue(
646            'No passport picture uploaded' in self.browser.contents)
647        # Create a pseudo image file and select it to be uploaded in form
648        pseudo_image = StringIO('I pretend to be a graphics file')
649        ctrl = self.browser.getControl(name='form.passport')
650        file_ctrl = ctrl.mech_control
651        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
652        self.browser.getControl("Final Submit").click() # (finally) submit form
653        # The picture has been uploaded but the form cannot be submitted
654        # since the passport confirmation box was not ticked
655        self.assertTrue(
656            'Passport picture confirmation box not ticked' in self.browser.contents)
657        self.browser.getControl(name="confirm_passport").value = True
658        self.browser.getControl("Final Submit").click()
659        self.assertTrue(
660            '... submitted ...' in self.browser.contents)
661        self.browser.goBack(count=1)
662        self.browser.getControl("Save").click()
663        self.assertTrue(
664            'The requested form is locked' in self.browser.contents)
665        self.browser.goBack(count=1)
666        #import pdb; pdb.set_trace()
667        self.browser.getControl("Final Submit").click()
668        self.assertTrue(
669            'The requested form is locked' in self.browser.contents)
670        return
671
672    def test_locking(self):
673        # Make sure that locked forms can't be submitted
674        self.login()
675        self.browser.open(self.edit_path)
676        self.fill_correct_values() # fill other fields with correct values
677        # Create a pseudo image file and select it to be uploaded in form
678        pseudo_image = StringIO('I pretend to be a graphics file')
679        ctrl = self.browser.getControl(name='form.passport')
680        file_ctrl = ctrl.mech_control
681        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
682        self.browser.getControl("Save").click()
683        # Now we lock the form
684        self.applicant.locked = True
685        self.browser.open(self.edit_path)
686        self.assertEqual(self.browser.headers['Status'], '200 Ok')
687        #print self.browser.contents
688        self.assertTrue(
689            'The requested form is locked' in self.browser.contents)
690        return
Note: See TracBrowser for help on using the repository browser.