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

Last change on this file since 6568 was 6541, checked in by uli, 14 years ago

pyflakes.

File size: 28.2 KB
Line 
1##
2## test_browser.py
3## Login : <uli@pu.smp.net>
4## Started on  Tue Mar 29 11:31:11 2011 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""
23Test the applicant-related UI components.
24"""
25import shutil
26import tempfile
27from StringIO import StringIO
28from datetime import datetime
29from zope.component import createObject
30from zope.component.hooks import setSite, clearSite
31from zope.testbrowser.testing import Browser
32from waeup.sirp.testing import FunctionalLayer, FunctionalTestCase
33from waeup.sirp.app import University
34from waeup.sirp.applicants.container import ApplicantsContainer
35from waeup.sirp.applicants.applicants import Applicant
36from waeup.sirp.university.faculty import Faculty
37from waeup.sirp.university.department import Department
38
39PH_LEN = 2059  # Length of placeholder file
40
41class ApplicantsFullSetup(FunctionalTestCase):
42    # A test case that only contains a setup and teardown
43    #
44    # Complete setup for applicants handlings is rather complex and
45    # requires lots of things created before we can start. This is a
46    # setup that does all this, creates a university, creates PINs,
47    # etc.  so that we do not have to bother with that in different
48    # test cases.
49
50    layer = FunctionalLayer
51
52    def setUp(self):
53        super(ApplicantsFullSetup, self).setUp()
54
55        # Setup a sample site for each test
56        app = University()
57        self.dc_root = tempfile.mkdtemp()
58        app['datacenter'].setStoragePath(self.dc_root)
59
60        # Prepopulate the ZODB...
61        self.getRootFolder()['app'] = app
62        # we add the site immediately after creation to the
63        # ZODB. Catalogs and other local utilities are not setup
64        # before that step.
65        self.app = self.getRootFolder()['app']
66        # Set site here. Some of the following setup code might need
67        # to access grok.getSite() and should get our new app then
68        setSite(app)
69
70        self.root_path = 'http://localhost/app/applicants/'
71        self.container_path = 'http://localhost/app/applicants/app2009/'
72
73        # Add an applicants container
74        applicantscontainer = ApplicantsContainer()
75        applicantscontainer.ac_prefix = 'APP'
76        applicantscontainer.prefix = 'app'
77        applicantscontainer.year = 2009
78        applicantscontainer.application_category = 'basic'
79        self.app['applicants']['app2009'] = applicantscontainer
80
81        # Populate university
82        certificate = createObject('waeup.Certificate')
83        certificate.code = 'CERT1'
84        certificate.application_category = 'basic'
85        self.app['faculties']['fac1'] = Faculty()
86        self.app['faculties']['fac1']['dep1'] = Department()
87        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
88            certificate)
89
90        # Put the prepopulated site into test ZODB and prepare test
91        # browser
92        self.browser = Browser()
93        self.browser.handleErrors = False
94
95        # Create 5 access codes with prefix'FOO' and cost 9.99 each
96        pin_container = self.app['accesscodes']
97        pin_container.createBatch(
98            datetime.now(), 'some_userid', 'APP', 9.99, 5)
99        pins = pin_container[pin_container.keys()[0]].values()
100        self.pins = [x.representation for x in pins]
101        self.existing_pin = self.pins[0]
102        parts = self.existing_pin.split('-')[1:]
103        self.existing_series, self.existing_number = parts
104
105        # Add an applicant
106        self.applicant = Applicant()
107        self.pin_applicant = unicode(self.pins[1])
108        self.applicant.access_code = self.pin_applicant
109        app['applicants']['app2009'][self.pin_applicant] = self.applicant
110        return
111
112    def tearDown(self):
113        super(ApplicantsFullSetup, self).tearDown()
114        clearSite()
115        shutil.rmtree(self.dc_root)
116        #import pdb; pdb.set_trace()
117
118class ApplicantsUITests(ApplicantsFullSetup):
119    # Tests for ApplicantsRoot class
120
121    layer = FunctionalLayer
122
123    def test_anonymous_access(self):
124        # Anonymous users can access applicants root and applicants containers
125        self.browser.open(self.root_path)
126        self.assertEqual(self.browser.headers['Status'], '200 Ok')
127        self.assertFalse(
128            'Manage' in self.browser.contents)
129        self.browser.open(self.container_path)
130        self.assertEqual(self.browser.headers['Status'], '200 Ok')
131        self.assertFalse(
132            'Manage' in self.browser.contents)
133        return
134
135    def test_manage_cert_access(self):
136        # Managers can access CERT1
137        cert_path = 'http://localhost/app/faculties/fac1/dep1/certificates/CERT1'
138        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
139        self.browser.open(cert_path)
140        self.assertEqual(self.browser.headers['Status'], '200 Ok')
141
142    def test_manage_access(self):
143        # Managers can access the manage pages of applicants root and
144        # applicants containers
145        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
146        self.browser.open(self.root_path)
147        self.assertTrue(
148            'Manage application section' in self.browser.contents)
149        self.manage_root_path = self.root_path + '/@@manage'
150        self.manage_container_path = self.container_path + '/@@manage'
151        self.browser.open(self.manage_root_path)
152        self.assertEqual(self.browser.headers['Status'], '200 Ok')
153        self.assertEqual(self.browser.url, self.manage_root_path)
154        self.browser.open(self.manage_container_path)
155        self.assertEqual(self.browser.headers['Status'], '200 Ok')
156        self.assertEqual(self.browser.url, self.manage_container_path)
157        return
158
159    def test_add_delete_container(self):
160        # Managers can add and delete applicants containers
161        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
162        self.browser.open(self.root_path)
163        self.add_container_path = self.root_path + '/@@add'
164        self.browser.open(self.add_container_path)
165        self.assertEqual(self.browser.headers['Status'], '200 Ok')
166        self.assertEqual(self.browser.url, self.add_container_path)
167        self.browser.getControl(name="form.prefix").value = ['app']
168        self.browser.getControl("Add applicants container").click()
169        self.assertTrue(
170            'There were errors' in self.browser.contents)
171        self.browser.getControl(name="form.prefix").value = ['app']
172        self.browser.getControl(name="form.year").value = ['2010']
173        self.browser.getControl(name="form.provider").value = [
174            'waeup.sirp.applicants.ApplicantsContainer']
175        self.browser.getControl(name="form.ac_prefix").value = ['APP']
176        self.browser.getControl(name="form.application_category").value = ['basic']
177        self.browser.getControl("Add applicants container").click()
178        self.assertTrue('Added:' in self.browser.contents)
179        ctrl = self.browser.getControl(name='val_id')
180        ctrl.getControl(value='app2010').selected = True
181        self.browser.getControl("Remove selected", index=0).click()
182        self.assertTrue('Successfully removed:' in self.browser.contents)
183        return
184
185    def test_add_delete_applicants(self):
186        # Managers can add and delete applicants
187        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
188        self.add_applicant_path = self.container_path + '/addapplicant'
189        self.container_manage_path = self.container_path + '/@@manage'
190        self.browser.open(self.add_applicant_path)
191        self.assertEqual(self.browser.headers['Status'], '200 Ok')
192        self.assertEqual(self.browser.url, self.add_applicant_path)
193        self.browser.getControl(name="form.ac_series").value = self.existing_series
194        self.browser.getControl(name="form.ac_number").value = self.existing_number
195        self.browser.getControl("Create application record").click()
196        self.assertTrue('Application initialized' in self.browser.contents)
197        self.browser.open(self.container_manage_path)
198        self.assertEqual(self.browser.headers['Status'], '200 Ok')
199        ctrl = self.browser.getControl(name='val_id')
200        ctrl.getControl(value=self.existing_pin).selected = True
201        self.browser.getControl("Remove selected", index=0).click()
202        self.assertTrue('Successfully removed:' in self.browser.contents)
203        return
204
205    def test_manage_applicant(self):
206        # Managers can manage applicants
207        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
208        self.applicant_path = 'http://localhost/app/applicants/app2009/%s' % self.pin_applicant
209        self.applicant_view_path = self.applicant_path + '/index'
210        self.applicant_manage_path = self.applicant_path + '/edit_full'
211        self.applicant_slip_path = self.applicant_path + '/application_slip.pdf'
212        self.browser.open(self.applicant_view_path)
213        self.assertEqual(self.browser.headers['Status'], '200 Ok')
214        self.browser.open(self.applicant_slip_path)
215        self.assertEqual(self.browser.headers['Status'], '200 Ok')
216        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
217        self.browser.open(self.applicant_manage_path)
218        self.assertEqual(self.browser.headers['Status'], '200 Ok')
219        self.browser.getControl(name="form.firstname").value = 'John'
220        self.browser.getControl(name="form.lastname").value = 'Tester'
221        self.browser.getControl(name="form.course1").value = ['CERT1']
222        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
223        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
224        self.browser.getControl(name="form.lga").value = ['foreigner']
225        self.browser.getControl(name="form.sex").value = ['m']
226        self.browser.getControl("Save").click()
227        self.assertMatches('...Form has been saved...', self.browser.contents)
228        return
229
230    def test_view_applicant(self):
231        # Applicants can login and view their application
232        self.login_path = 'http://localhost/app/applicants/app2009/login'
233        self.browser.open(self.login_path)
234        pin = self.pins[2]
235        parts = pin.split('-')[1:]
236        existing_series, existing_number = parts
237        ac_series = self.browser.getControl(name="form.ac_series")
238        ac_series.value = existing_series
239        ac_number = self.browser.getControl(name="form.ac_number")
240        ac_number.value = existing_number
241        self.browser.getControl(name="SUBMIT").click()
242        self.assertTrue(self.browser.url != self.login_path)
243        self.assertEqual(self.browser.headers['Status'], '200 Ok')
244        return
245
246    def test_passport_edit_view(self):
247        # We get a default image after login
248        login_path = 'http://localhost/app/applicants/app2009/login'
249        self.browser.open(login_path)
250        pin = self.pins[2]
251        parts = pin.split('-')[1:]
252        existing_series, existing_number = parts
253        ac_series = self.browser.getControl(name="form.ac_series")
254        ac_series.value = existing_series
255        ac_number = self.browser.getControl(name="form.ac_number")
256        ac_number.value = existing_number
257        self.browser.getControl(name="SUBMIT").click()
258
259        pin = self.pins[2]
260        appl = self.getRootFolder()['app']['applicants']['app2009']
261        appl = appl[pin]
262        passp = appl.passport
263        #import pdb; pdb.set_trace()
264        passp_len = len(passp.file.read())
265        self.assertEqual(passp_len, PH_LEN)
266
267
268        #image_url = "%s/%s" % (self.browser.url, 'placeholder.jpg')
269        image_url = "%s/%s" % (self.browser.url, 'passport.jpg')
270        #self.browser.open(image_url)
271        self.browser.open('passport.jpg')
272        self.assertEqual(self.browser.headers['status'], '200 Ok')
273        self.assertEqual(self.browser.headers['content-type'], 'image/jpeg')
274
275
276        self.assertTrue('JFIF' in self.browser.contents)
277        self.assertEqual(
278            self.browser.headers['content-length'], str(PH_LEN))
279
280
281    def test_edit_applicant(self):
282        # Applicants can edit their record
283        self.login_path = 'http://localhost/app/applicants/app2009/login'
284        self.browser.open(self.login_path)
285        pin = self.pins[2]
286        parts = pin.split('-')[1:]
287        existing_series, existing_number = parts
288        ac_series = self.browser.getControl(name="form.ac_series")
289        ac_series.value = existing_series
290        ac_number = self.browser.getControl(name="form.ac_number")
291        ac_number.value = existing_number
292        self.browser.getControl(name="SUBMIT").click()
293        self.assertTrue(self.browser.url != self.login_path)
294        self.assertEqual(self.browser.headers['Status'], '200 Ok')
295        self.browser.getControl(name="form.firstname").value = 'John'
296        self.browser.getControl(name="form.lastname").value = 'Tester'
297        self.browser.getControl(name="form.course1").value = ['CERT1']
298        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
299        self.browser.getControl(name="form.lga").value = ['foreigner']
300        self.browser.getControl(name="form.sex").value = ['m']
301        self.browser.getControl("Save").click()
302        self.assertMatches('...Form has been saved...', self.browser.contents)
303        return
304
305class LoginTest(FunctionalTestCase):
306    # Here we check login view of applicants containers.
307    #
308    # Tests in here do only cover login attempts without any PINs
309    # created before.
310
311    layer = FunctionalLayer
312
313    def setUp(self):
314        super(LoginTest, self).setUp()
315
316        # Setup a sample site for each test
317        app = University()
318        self.dc_root = tempfile.mkdtemp()
319        app['datacenter'].setStoragePath(self.dc_root)
320        self.login_path = 'http://localhost/app/applicants/testapplicants/login'
321
322        # Add an applicants container where we can login (or not)
323        applicantscontainer = ApplicantsContainer()
324        applicantscontainer.ac_prefix = 'APP'
325        app['applicants']['testapplicants'] = applicantscontainer
326
327        # Put the prepopulated site into test ZODB and prepare test
328        # browser
329        self.getRootFolder()['app'] = app
330        self.browser = Browser()
331        self.browser.handleErrors = False
332
333    def tearDown(self):
334        super(LoginTest, self).tearDown()
335        shutil.rmtree(self.dc_root)
336
337    def test_anonymous_access(self):
338        # Anonymous users can access a login page
339        self.browser.open(self.login_path)
340        self.assertEqual(self.browser.headers['Status'], '200 Ok')
341        return
342
343    def test_anonymous_invalid_creds(self):
344        # Anonymous users giving invalid credentials stay at the page
345        self.browser.open(self.login_path)
346        # We do not give credentials but send the form as-is
347        submit = self.browser.getControl(name='SUBMIT')
348        submit.click()
349        # We are still at the same page...
350        self.assertEqual(self.browser.url, self.login_path)
351        self.assertEqual(self.browser.headers['Status'], '200 Ok')
352        return
353
354    def test_anonymous_invalid_creds_warning(self):
355        # Entering wrong credentials will yield a warning
356        self.browser.open(self.login_path)
357        # We do not give credentials but send the form as-is
358        submit = self.browser.getControl(name='SUBMIT')
359        submit.click()
360        self.assertTrue(
361            'Entered credentials are invalid' in self.browser.contents)
362        return
363
364    def test_manager_no_warnings(self):
365        # Browsing the login screen as a manager, won't raise warnings
366        # Authenticate ourself as manager
367        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
368        self.browser.open(self.login_path)
369        # Submit the form w/o any credentials
370        self.browser.getControl(name="SUBMIT").click()
371        self.assertTrue(
372            'Entered credentials are invalid' not in self.browser.contents)
373        return
374
375    def test_manager_no_redirect(self):
376        # Browsing the login screen as a manager won't trigger a redirect
377        # Authenticate ourself as manager
378        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
379        self.browser.open(self.login_path)
380        # Submit the form w/o any credentials
381        self.browser.getControl(name="SUBMIT").click()
382        self.assertEqual(self.browser.url, self.login_path)
383        return
384
385    def test_display_entered_values(self):
386        # After submit the entered values are displayed in the form
387        self.browser.open(self.login_path)
388        # Enter some value we can look for after submit
389        ac_series = self.browser.getControl(name="form.ac_series")
390        ac_series.value = '666'
391        self.browser.getControl(name="SUBMIT").click()
392        self.assertTrue('666' in self.browser.contents)
393        return
394
395class LoginTestWithPINs(LoginTest):
396    # Here we check login view of applicants containers with PINs provided.
397
398    # As setting up pins is time-consuming we only set them up when
399    # really needed (i.e. in this separate TestCase).
400
401    layer = FunctionalLayer
402
403    def setUp(self):
404        super(LoginTestWithPINs, self).setUp()
405
406        # Create 5 access codes with prefix'FOO' and cost 9.99 each
407        pin_container = self.getRootFolder()['app']['accesscodes']
408        pin_container.createBatch(
409            datetime.now(), 'some_userid', 'APP', 9.99, 5)
410        pins = pin_container[pin_container.keys()[0]].values()
411        self.pins = [x.representation for x in pins]
412        self.existing_pin = self.pins[0]
413        parts = self.existing_pin.split('-')[1:]
414        self.existing_series, self.existing_number = parts
415        self.browser.handleErrors = False
416
417    def tearDown(self):
418        super(LoginTestWithPINs, self).tearDown()
419
420    def test_anonymous_valid_login(self):
421        # If we enter valid credentials, we get to the applicants form
422        self.browser.open(self.login_path)
423        # Enter some value we can look for after submit
424        ac_series = self.browser.getControl(name="form.ac_series")
425        ac_series.value = self.existing_series
426        ac_number = self.browser.getControl(name="form.ac_number")
427        ac_number.value = self.existing_number
428        self.browser.getControl(name="SUBMIT").click()
429        # We should be redirected to applicants form.
430        self.assertTrue(self.browser.url != self.login_path)
431        return
432
433    def test_anonymous_invalid_login(self):
434        # If we enter wrong credentials we won't get far
435        self.browser.open(self.login_path)
436        # Enter some value we can look for after submit
437        ac_series = self.browser.getControl(name="form.ac_series")
438        ac_series.value = 'illegal series'
439        ac_number = self.browser.getControl(name="form.ac_number")
440        ac_number.value = 'invalid number'
441        self.browser.getControl(name="SUBMIT").click()
442        # We get a warning message
443        self.assertTrue(
444            'Entered credentials are invalid' in self.browser.contents)
445        # We stay at the login page (no redirect)
446        self.assertTrue(self.browser.url == self.login_path)
447        return
448
449class ApplicantsPassportTests(ApplicantsFullSetup):
450    # Tests for uploading/browsing the passport image of appplicants
451
452    layer = FunctionalLayer
453
454    def setUp(self):
455        super(ApplicantsPassportTests, self).setUp()
456        self.login_path = 'http://localhost/app/applicants/app2009/login'
457        self.pin = self.pins[2]
458        self.existing_series, self.existing_number = self.pin.split('-')[1:]
459        self.edit_path = 'http://localhost/app/applicants/app2009/%s/edit' % (
460            self.pin)
461
462    def tearDown(self):
463        super(ApplicantsPassportTests, self).tearDown()
464
465    def login(self):
466        # Perform an applicant login. This creates an applicant record.
467        #
468        # This helper also sets `self.applicant`, which is the
469        # applicant object created.
470        self.browser.open(self.login_path)
471        ac_series = self.browser.getControl(name="form.ac_series")
472        ac_series.value = self.existing_series
473        ac_number = self.browser.getControl(name="form.ac_number")
474        ac_number.value = self.existing_number
475        self.browser.getControl(name="SUBMIT").click()
476        self.applicant = self.app['applicants']['app2009'][self.pin]
477
478    def fill_correct_values(self):
479        # Fill the edit form with suitable values
480        self.browser.getControl(name="form.firstname").value = 'John'
481        self.browser.getControl(name="form.lastname").value = 'Tester'
482        self.browser.getControl(name="form.course1").value = ['CERT1']
483        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
484        self.browser.getControl(name="form.lga").value = ['foreigner']
485        self.browser.getControl(name="form.sex").value = ['m']
486
487    def image_url(self, filename):
488        return self.edit_path.replace('edit', filename)
489
490    def test_after_login_default_browsable(self):
491        # After login we see the placeholder image in the edit view
492        self.login()
493        self.assertEqual(self.browser.url, self.edit_path)
494        # There is a correct <img> link included
495        self.assertTrue(
496            '<img src="placeholder_m.jpg" />' in self.browser.contents)
497        # Browsing the link shows a real image
498        self.browser.open(self.image_url('placeholder_m.jpg'))
499        self.assertEqual(
500            self.browser.headers['content-type'], 'image/jpeg')
501        self.assertEqual(len(self.browser.contents), PH_LEN)
502
503    def test_after_login_default_stored_in_imagestorage(self):
504        # After login the applicants placeholder image is stored in
505        # an imagestorage
506        storage = self.app['images']
507        # In the beginning, the storage is empty
508        self.assertEqual([x for x in storage.keys()], [])
509        self.login()
510        # After login, it is filled
511        self.assertEqual(
512            [x for x in storage.keys()],
513            [u'b48a1d39bbcb32e955d9ff2dea4ed0e6'])
514        file_id = self.applicant.passport.data
515        self.assertEqual(
516            file_id, u'b48a1d39bbcb32e955d9ff2dea4ed0e6-1')
517        # The stored image can be fetched
518        fd = storage.retrieveFile(file_id)
519        file_len = len(fd.read())
520        self.assertEqual(file_len, PH_LEN)
521
522    def test_after_submit_default_browsable(self):
523        # After submitting an applicant form the default image is
524        # still visible
525        self.login()
526        self.browser.getControl("Save").click() # submit form
527        # There is a correct <img> link included
528        self.assertTrue(
529            '<img src="placeholder_m.jpg" />' in self.browser.contents)
530        # Browsing the link shows a real image
531        self.browser.open(self.image_url('placeholder_m.jpg'))
532        self.assertEqual(
533            self.browser.headers['content-type'], 'image/jpeg')
534        self.assertEqual(len(self.browser.contents), PH_LEN)
535
536    def test_after_submit_default_stored_in_imagestorage(self):
537        # After submitting an applicant form the default image is
538        # correctly stored in an imagestorage
539        self.login()
540        self.browser.getControl("Save").click() # submit form
541        storage = self.app['images']
542        self.assertEqual(
543            [x for x in storage.keys()],
544            [u'b48a1d39bbcb32e955d9ff2dea4ed0e6'])
545        file_id = self.applicant.passport.data
546        self.assertEqual(
547            file_id, u'b48a1d39bbcb32e955d9ff2dea4ed0e6-1')
548        # The stored image can be fetched
549        fd = storage.retrieveFile(file_id)
550        file_len = len(fd.read())
551        self.assertEqual(file_len, PH_LEN)
552
553    # XXX: Make this test work again
554    def DISABLEDtest_uploaded_image_browsable_w_errors(self):
555        # We can upload a different image and browse it after submit,
556        # even if there are still errors in the form
557        self.login()
558        # Create a pseudo image file and select it to be uploaded in form
559        pseudo_image = StringIO('I pretend to be a graphics file')
560        ctrl = self.browser.getControl(name='form.passport')
561        file_ctrl = ctrl.mech_control
562        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
563        self.browser.getControl("Save").click() # submit form
564        # There is a correct <img> link included
565        self.assertTrue(
566            '<img src="myphoto.jpg" />' in self.browser.contents)
567        # Browsing the link shows a real image
568        self.browser.open(self.image_url('myphoto.jpg'))
569        self.assertEqual(
570            self.browser.headers['content-type'], 'image/jpeg')
571        self.assertEqual(len(self.browser.contents), PH_LEN)
572
573    def test_uploaded_image_stored_in_imagestorage_w_errors(self):
574        # After uploading a new passport pic the file is correctly
575        # stored in an imagestorage
576        self.login()
577        # Create a pseudo image file and select it to be uploaded in form
578        pseudo_image = StringIO('I pretend to be a graphics file')
579        ctrl = self.browser.getControl(name='form.passport')
580        file_ctrl = ctrl.mech_control
581        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
582        self.browser.getControl("Save").click() # submit form
583        storage = self.app['images']
584        self.assertTrue(
585            u'18e57c7eac6ca7fb15b54b5b2bd4106d' in storage.keys())
586        # The stored image can be fetched
587        fd = storage.retrieveFile(u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
588        #fd = storage.retrieveFile(file_id)
589        file_len = len(fd.read())
590        self.assertEqual(file_len, 31)
591        # The image uploaded belongs to the applicant
592        # XXX: When there are errors in form, then the applicant is not
593        #      changed. This (failing) test is here to remember us that
594        #      we have to care for images when form submits fail.
595        file_id = self.applicant.passport.data
596        self.assertEqual(
597            file_id, u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
598
599    def test_uploaded_image_browsable_wo_errors(self):
600        # We can upload a different image and browse it after submit,
601        # if there are no errors in form
602        self.login()
603        self.fill_correct_values() # fill other fields with correct values
604        # Create a pseudo image file and select it to be uploaded in form
605        pseudo_image = StringIO('I pretend to be a graphics file')
606        ctrl = self.browser.getControl(name='form.passport')
607        file_ctrl = ctrl.mech_control
608        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
609        self.browser.getControl("Save").click() # submit form
610        # There is a correct <img> link included
611        self.assertTrue(
612            '<img src="myphoto.jpg" />' in self.browser.contents)
613        # Browsing the link shows a real image
614        self.browser.open(self.image_url('myphoto.jpg'))
615        self.assertEqual(
616            self.browser.headers['content-type'], 'image/jpeg')
617        self.assertEqual(len(self.browser.contents), 31)
618
619    def test_uploaded_image_stored_in_imagestorage_wo_errors(self):
620        # After uploading a new passport pic the file is correctly
621        # stored in an imagestorage if form contains no errors
622        self.login()
623        self.fill_correct_values() # fill other fields with correct values
624        # Create a pseudo image file and select it to be uploaded in form
625        pseudo_image = StringIO('I pretend to be a graphics file')
626        ctrl = self.browser.getControl(name='form.passport')
627        file_ctrl = ctrl.mech_control
628        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
629        self.browser.getControl("Save").click() # submit form
630        storage = self.app['images']
631        self.assertTrue(
632            u'18e57c7eac6ca7fb15b54b5b2bd4106d' in storage.keys())
633        # The stored image can be fetched
634        fd = storage.retrieveFile(u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
635        #fd = storage.retrieveFile(file_id)
636        file_len = len(fd.read())
637        self.assertEqual(file_len, 31)
638        # The image uploaded belongs to the applicant
639        file_id = self.applicant.passport.data
640        self.assertEqual(
641            file_id, u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
Note: See TracBrowser for help on using the repository browser.