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

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

Add tests for acceptance fee payment.

  • Property svn:keywords set to Id
File size: 32.4 KB
Line 
1## $Id: test_browser.py 7252 2011-12-02 21:11:44Z 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 = 'Albert'
289        self.browser.getControl(name="form.lastname").value = 'Einstein'
290        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
291        self.browser.getControl("Create application record").click()
292        self.assertTrue('Application initialized' in self.browser.contents)
293        self.browser.open(self.container_manage_path)
294        self.assertEqual(self.browser.headers['Status'], '200 Ok')
295        ctrl = self.browser.getControl(name='val_id')
296        value = ctrl.options[0]
297        ctrl.getControl(value=value).selected = True
298        self.browser.getControl("Remove selected", index=0).click()
299        self.assertTrue('Successfully removed:' in self.browser.contents)
300        self.browser.open(self.add_applicant_path)
301        self.browser.getControl(name="form.firstname").value = 'Albert'
302        self.browser.getControl(name="form.lastname").value = 'Einstein'
303        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
304        self.browser.getControl("Create application record").click()
305        self.assertTrue('Application initialized' in self.browser.contents)
306        return
307
308    def test_manage_and_view_applicant(self):
309        # Managers can manage applicants
310        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
311        self.slip_path = self.view_path + '/application_slip.pdf'
312        self.browser.open(self.manage_path)
313        self.assertEqual(self.browser.headers['Status'], '200 Ok')
314        self.fill_correct_values()
315        self.browser.getControl(name="transition").value = ['start']
316        self.browser.getControl("Save").click()
317        self.assertMatches('...Form has been saved...', self.browser.contents)
318        self.assertMatches('...Application started by zope.mgr...', self.browser.contents)
319        self.browser.open(self.view_path)
320        self.assertEqual(self.browser.headers['Status'], '200 Ok')
321        self.browser.open(self.slip_path)
322        self.assertEqual(self.browser.headers['Status'], '200 Ok')
323        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
324        self.browser.open(self.manage_path)
325        self.browser.getControl(name="form.course_admitted").value = []
326        self.browser.getControl("Save").click()
327        self.browser.open(self.slip_path)
328        self.assertEqual(self.browser.headers['Status'], '200 Ok')
329        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
330        return
331
332    def test_passport_edit_view(self):
333        # We get a default image after login
334        self.browser.open(self.login_path)
335        self.login()
336        self.browser.open(self.browser.url + '/passport.jpg')
337        self.assertEqual(self.browser.headers['status'], '200 Ok')
338        self.assertEqual(self.browser.headers['content-type'], 'image/jpeg')
339        self.assertTrue('JFIF' in self.browser.contents)
340        self.assertEqual(
341            self.browser.headers['content-length'], str(PH_LEN))
342
343    def test_edit_applicant(self):
344        # Applicants can edit their record
345        self.browser.open(self.login_path)
346        self.login()
347        self.browser.open(self.edit_path)
348        self.assertTrue(self.browser.url != self.login_path)
349        self.assertEqual(self.browser.headers['Status'], '200 Ok')
350        self.fill_correct_values()
351        self.browser.getControl("Save").click()
352        self.assertMatches('...Form has been saved...', self.browser.contents)
353        return
354
355class ApplicantsContainerUITests(ApplicantsFullSetup):
356    # Tests for ApplicantsContainer class views and pages
357
358    layer = FunctionalLayer
359
360    def test_anonymous_access(self):
361        # Anonymous users can access applicants containers
362        self.browser.open(self.container_path)
363        self.assertEqual(self.browser.headers['Status'], '200 Ok')
364        self.assertFalse(
365            'Manage' in self.browser.contents)
366        return
367
368    def test_manage_access(self):
369        # Managers can access the manage pages of applicants
370        # containers and can perform actions
371        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
372        self.browser.open(self.manage_container_path)
373        self.assertEqual(self.browser.headers['Status'], '200 Ok')
374        self.assertEqual(self.browser.url, self.manage_container_path)
375        self.browser.getControl("Save").click()
376        self.assertTrue('Data saved' in self.browser.contents)
377        self.browser.getControl("Remove selected", index=0).click()
378        self.assertTrue('No applicant selected' in self.browser.contents)
379        self.browser.getControl("Add local role").click()
380        self.assertTrue('No user selected' in self.browser.contents)
381        self.browser.getControl("Cancel", index=0).click()
382        self.assertEqual(self.browser.url, self.container_path)
383        return
384
385class ApplicantsPassportTests(ApplicantsFullSetup):
386    # Tests for uploading/browsing the passport image of appplicants
387
388    layer = FunctionalLayer
389
390    def image_url(self, filename):
391        return self.edit_path.replace('edit', filename)
392
393    def test_after_login_default_browsable(self):
394        # After login we see the placeholder image in the edit view
395        #import pdb; pdb.set_trace()
396        self.login()
397        self.assertEqual(self.browser.url, self.view_path)
398        self.browser.open(self.edit_path)
399        # There is a correct <img> link included
400        self.assertTrue(
401              '<img src="passport.jpg" />' in self.browser.contents)
402        # Browsing the link shows a real image
403        self.browser.open(self.image_url('passport.jpg'))
404        self.assertEqual(
405            self.browser.headers['content-type'], 'image/jpeg')
406        self.assertEqual(len(self.browser.contents), PH_LEN)
407
408    def test_after_submit_default_browsable(self):
409        # After submitting an applicant form the default image is
410        # still visible
411        self.login()
412        self.browser.open(self.edit_path)
413        self.browser.getControl("Save").click() # submit form
414        # There is a correct <img> link included
415        self.assertTrue(
416            '<img src="passport.jpg" />' in self.browser.contents)
417        # Browsing the link shows a real image
418        self.browser.open(self.image_url('passport.jpg'))
419        self.assertEqual(
420            self.browser.headers['content-type'], 'image/jpeg')
421        self.assertEqual(len(self.browser.contents), PH_LEN)
422
423    def test_uploaded_image_respects_file_size_restriction(self):
424        # When we upload an image that is too big ( > 10 KB) we will
425        # get an error message
426        self.login()
427        self.browser.open(self.edit_path)
428        # Create a pseudo image file and select it to be uploaded in form
429        photo_content = 'A' * 1024 * 21  # A string of 21 KB size
430        pseudo_image = StringIO(photo_content)
431        ctrl = self.browser.getControl(name='form.passport')
432        file_ctrl = ctrl.mech_control
433        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
434        self.browser.getControl("Save").click() # submit form
435        # There is a correct <img> link included
436        self.assertTrue(
437            '<img src="passport.jpg" />' in self.browser.contents)
438        # We get a warning message
439        self.assertTrue(
440            'Uploaded image is too big' in self.browser.contents)
441        # Browsing the image gives us the default image, not the
442        # uploaded one.
443        self.browser.open(self.image_url('passport.jpg'))
444        self.assertEqual(
445            self.browser.headers['content-type'], 'image/jpeg')
446        self.assertEqual(len(self.browser.contents), PH_LEN)
447        # There is really no file stored for the applicant
448        img = getUtility(IExtFileStore).getFile(
449            IFileStoreNameChooser(self.applicant).chooseName())
450        self.assertTrue(img is None)
451
452    def test_uploaded_image_browsable_w_errors(self):
453        # We can upload a different image and browse it after submit,
454        # even if there are still errors in the form
455        self.login()
456        self.browser.open(self.edit_path)
457        # Create a pseudo image file and select it to be uploaded in form
458        photo_content = 'I pretend to be a graphics file'
459        pseudo_image = StringIO(photo_content)
460        ctrl = self.browser.getControl(name='form.passport')
461        file_ctrl = ctrl.mech_control
462        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
463        self.browser.getControl("Save").click() # submit form
464        # There is a correct <img> link included
465        self.assertTrue(
466            '<img src="passport.jpg" />' in self.browser.contents)
467        # Browsing the link shows a real image
468        self.browser.open(self.image_url('passport.jpg'))
469        self.assertEqual(
470            self.browser.headers['content-type'], 'image/jpeg')
471        self.assertEqual(self.browser.contents, photo_content)
472
473    def test_uploaded_image_stored_in_imagestorage_w_errors(self):
474        # After uploading a new passport pic the file is correctly
475        # stored in an imagestorage
476        self.login()
477        self.browser.open(self.edit_path)
478        # Create a pseudo image file and select it to be uploaded in form
479        pseudo_image = StringIO('I pretend to be a graphics file')
480        ctrl = self.browser.getControl(name='form.passport')
481        file_ctrl = ctrl.mech_control
482        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
483        self.browser.getControl("Save").click() # submit form
484        storage = getUtility(IExtFileStore)
485        file_id = IFileStoreNameChooser(self.applicant).chooseName()
486        pseudo_image.seek(0) # reset our file data source
487        self.assertEqual(
488            storage.getFile(file_id).read(), pseudo_image.read())
489        return
490
491    def test_uploaded_image_browsable_wo_errors(self):
492        # We can upload a different image and browse it after submit,
493        # if there are no errors in form
494        self.login()
495        self.browser.open(self.edit_path)
496        self.fill_correct_values() # fill other fields with correct values
497        # Create a pseudo image file and select it to be uploaded in form
498        pseudo_image = StringIO('I pretend to be a graphics file')
499        ctrl = self.browser.getControl(name='form.passport')
500        file_ctrl = ctrl.mech_control
501        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
502        self.browser.getControl("Save").click() # submit form
503        # There is a correct <img> link included
504        self.assertTrue(
505            '<img src="passport.jpg" />' in self.browser.contents)
506        # Browsing the link shows a real image
507        self.browser.open(self.image_url('passport.jpg'))
508        self.assertEqual(
509            self.browser.headers['content-type'], 'image/jpeg')
510        self.assertEqual(len(self.browser.contents), 31)
511
512    def test_uploaded_image_stored_in_imagestorage_wo_errors(self):
513        # After uploading a new passport pic the file is correctly
514        # stored in an imagestorage if form contains no errors
515        self.login()
516        self.browser.open(self.edit_path)
517        self.fill_correct_values() # fill other fields with correct values
518        # Create a pseudo image file and select it to be uploaded in form
519        pseudo_image = StringIO('I pretend to be a graphics file')
520        ctrl = self.browser.getControl(name='form.passport')
521        file_ctrl = ctrl.mech_control
522        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
523        self.browser.getControl("Save").click() # submit form
524        storage = getUtility(IExtFileStore)
525        file_id = IFileStoreNameChooser(self.applicant).chooseName()
526        # The stored image can be fetched
527        fd = storage.getFile(file_id)
528        file_len = len(fd.read())
529        self.assertEqual(file_len, 31)
530
531    def test_uploaded_images_equal(self):
532        # Make sure uploaded images do really differ if we eject a
533        # change notfication (and do not if we don't)
534        self.login()
535        self.browser.open(self.edit_path)
536        self.fill_correct_values() # fill other fields with correct values
537        self.browser.getControl("Save").click() # submit form
538        # Now go on as an officer
539        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
540        self.browser.open(self.manage_path)
541
542        # Create a pseudo image file and select it to be uploaded in form
543        pseudo_image = StringIO('I pretend to be a graphics file')
544        ctrl = self.browser.getControl(name='form.passport')
545        file_ctrl = ctrl.mech_control
546        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
547        file_id = IFileStoreNameChooser(self.applicant).chooseName()
548        setSite(self.app)
549        passport0 = getUtility(IExtFileStore).getFile(file_id)
550        self.browser.getControl("Save").click() # submit form with changed pic
551        passport1 = getUtility(IExtFileStore).getFile(file_id).read()
552        self.browser.getControl("Save").click() # submit form w/o changes
553        passport2 = getUtility(IExtFileStore).getFile(file_id).read()
554        self.assertTrue(passport0 is None)
555        self.assertTrue(passport0 != passport1)
556        self.assertTrue(passport1 == passport2)
557        return
558
559    def test_pay_acceptance_fee(self):
560        self.login()
561        self.browser.open(self.edit_path)
562        # Payment tickets can't be created before the form has been validated
563        self.browser.getControl("Add online payment ticket").click()
564        self.assertTrue('Required input is missing' in self.browser.contents)
565        self.fill_correct_values()
566        # We have to savethe form otherwise the filled fields will be cleared
567        # after adding an online payment, because adding an online payment
568        # requires a filled form but does not save it
569        self.browser.getControl("Save").click()
570        self.browser.getControl("Add online payment ticket").click()
571        # Session object missing
572        self.assertTrue(
573            'Session configuration object is not available'
574            in self.browser.contents)
575        configuration = SessionConfiguration()
576        configuration.academic_session = 2009
577        configuration.acceptance_fee = 200
578        self.app['configuration'].addSessionConfiguration(configuration)
579        self.browser.open(self.edit_path)
580        self.fill_correct_values()
581        self.browser.getControl("Add online payment ticket").click()
582        self.assertMatches('...Payment ticket created...', self.browser.contents)
583        # Payment ticket can be removed if they haven't received a valid callback
584        ctrl = self.browser.getControl(name='val_id')
585        value = ctrl.options[0]
586        ctrl.getControl(value=value).selected = True
587        self.browser.getControl("Remove selected", index=0).click()
588        self.assertMatches('...Successfully removed...', self.browser.contents)
589        # We will try the callback request view
590        self.browser.getControl("Add online payment ticket").click()
591        ctrl = self.browser.getControl(name='val_id')
592        value = ctrl.options[0]
593        self.browser.getLink(value).click()
594        self.assertMatches('...Amount Authorized...',
595                           self.browser.contents)
596        payment_url = self.browser.url
597        # The pdf payment receipt can't yet be opened
598        self.browser.open(payment_url + '/payment_receipt.pdf')
599        self.assertMatches('...Ticket not yet paid...',
600                           self.browser.contents)
601        # Request callback
602        self.browser.open(payment_url)
603        self.browser.getLink("Request callback").click()
604        self.assertMatches('...Valid callback received...',
605                          self.browser.contents)
606        # Callback can't be applied twice
607        self.browser.open(payment_url + '/callback')
608        self.assertMatches('...This ticket has already been paid...',
609                          self.browser.contents)
610        # The payment receipt can be downloaded now
611        self.browser.open(payment_url)
612        self.browser.getLink("Download payment receipt").click()
613        self.assertEqual(self.browser.headers['Status'], '200 Ok')
614        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
615        # Applicant is is in state 'paid'
616        self.browser.open(self.view_path)
617        self.assertMatches('...paid...',
618                           self.browser.contents)
619        state = IWorkflowState(self.applicant).getState()
620        self.assertTrue(state == 'paid')
621
622    def test_final_submit(self):
623        # Make sure that a correctly filled form with passport picture
624        # can be submitted (only) after payment
625        self.login()
626        self.browser.getLink("Edit application record").click()
627        self.assertFalse('Final Submit' in self.browser.contents)
628        IWorkflowInfo(self.applicant).fireTransition('pay')
629        self.browser.open(self.edit_path)
630        self.assertTrue('Final Submit' in self.browser.contents)
631        self.fill_correct_values() # fill other fields with correct values
632        self.browser.getControl("Final Submit").click()
633        # We forgot to upload a passport picture
634        self.assertTrue(
635            'No passport picture uploaded' in self.browser.contents)
636        # Create a pseudo image file and select it to be uploaded in form
637        pseudo_image = StringIO('I pretend to be a graphics file')
638        ctrl = self.browser.getControl(name='form.passport')
639        file_ctrl = ctrl.mech_control
640        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
641        self.browser.getControl("Final Submit").click() # (finally) submit form
642        # The picture has been uploaded but the form cannot be submitted
643        # since the passport confirmation box was not ticked
644        self.assertTrue(
645            'Passport picture confirmation box not ticked' in self.browser.contents)
646        self.browser.getControl(name="confirm_passport").value = True
647        self.browser.getControl("Final Submit").click()
648        self.assertTrue(
649            '... submitted ...' in self.browser.contents)
650        self.browser.goBack(count=1)
651        self.browser.getControl("Save").click()
652        self.assertTrue(
653            'The requested form is locked' in self.browser.contents)
654        self.browser.goBack(count=1)
655        #import pdb; pdb.set_trace()
656        self.browser.getControl("Final Submit").click()
657        self.assertTrue(
658            'The requested form is locked' in self.browser.contents)
659        return
660
661    def test_locking(self):
662        # Make sure that locked forms can't be submitted
663        self.login()
664        self.browser.open(self.edit_path)
665        self.fill_correct_values() # fill other fields with correct values
666        # Create a pseudo image file and select it to be uploaded in form
667        pseudo_image = StringIO('I pretend to be a graphics file')
668        ctrl = self.browser.getControl(name='form.passport')
669        file_ctrl = ctrl.mech_control
670        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
671        self.browser.getControl("Save").click()
672        # Now we lock the form
673        self.applicant.locked = True
674        self.browser.open(self.edit_path)
675        self.assertEqual(self.browser.headers['Status'], '200 Ok')
676        #print self.browser.contents
677        self.assertTrue(
678            'The requested form is locked' in self.browser.contents)
679        return
Note: See TracBrowser for help on using the repository browser.