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

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

Increase test coverage from 84% to 95%.

File size: 33.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
111        # Add an officer
112        myusers = self.app['users']
113        myusers.addUser('bob', 'bobssecret')
114        return
115
116    def tearDown(self):
117        super(ApplicantsFullSetup, self).tearDown()
118        clearSite()
119        shutil.rmtree(self.dc_root)
120        #import pdb; pdb.set_trace()
121
122class ApplicantsUITests(ApplicantsFullSetup):
123    # Tests for ApplicantsRoot class
124
125    layer = FunctionalLayer
126
127    def test_anonymous_access(self):
128        # Anonymous users can access applicants root and applicants containers
129        self.browser.open(self.root_path)
130        self.assertEqual(self.browser.headers['Status'], '200 Ok')
131        self.assertFalse(
132            'Manage' in self.browser.contents)
133        self.browser.open(self.container_path)
134        self.assertEqual(self.browser.headers['Status'], '200 Ok')
135        self.assertFalse(
136            'Manage' in self.browser.contents)
137        return
138
139    def test_manage_cert_access(self):
140        # Managers can access CERT1
141        cert_path = 'http://localhost/app/faculties/fac1/dep1/certificates/CERT1'
142        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
143        self.browser.open(cert_path)
144        self.assertEqual(self.browser.headers['Status'], '200 Ok')
145
146    def test_manage_access(self):
147        # Managers can access the manage pages of applicants root and
148        # applicants containers and can perform actions
149        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
150        self.browser.open(self.root_path)
151        self.assertTrue(
152            'Manage application section' in self.browser.contents)
153        self.manage_root_path = self.root_path + '/@@manage'
154        self.manage_container_path = self.container_path + '/@@manage'
155        self.browser.open(self.manage_root_path)
156        self.assertEqual(self.browser.headers['Status'], '200 Ok')
157        self.assertEqual(self.browser.url, self.manage_root_path)
158        self.browser.open(self.manage_container_path)
159        self.assertEqual(self.browser.headers['Status'], '200 Ok')
160        self.assertEqual(self.browser.url, self.manage_container_path)
161        self.browser.getControl("Save").click()
162        self.assertTrue(
163            'Data saved' in self.browser.contents)
164        self.browser.getControl("Remove selected", index=0).click()
165        self.assertTrue(
166            'No applicant selected' in self.browser.contents)
167        self.browser.getControl("Cancel", index=0).click()
168        self.assertEqual(self.browser.url, self.container_path)
169        return
170
171    def test_add_delete_container(self):
172        # Managers can add and delete applicants containers
173        self.manage_root_path = self.root_path + '/@@manage'
174        self.add_container_path = self.root_path + '/@@add'
175        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
176        self.browser.open(self.manage_root_path)
177        self.browser.getControl("Cancel").click()
178        self.assertEqual(self.browser.url, self.root_path)
179        self.browser.open(self.manage_root_path)
180        self.browser.getControl("Add applicants container").click()
181        self.assertEqual(self.browser.headers['Status'], '200 Ok')
182        self.assertEqual(self.browser.url, self.add_container_path)
183        self.browser.getControl(name="form.prefix").value = ['app']
184        self.browser.getControl("Add applicants container").click()
185        self.assertTrue(
186            'There were errors' in self.browser.contents)
187        self.browser.getControl(name="form.prefix").value = ['app']
188        self.browser.getControl(name="form.year").value = ['2010']
189        self.browser.getControl(name="form.provider").value = [
190            'waeup.sirp.applicants.ApplicantsContainer']
191        self.browser.getControl(name="form.ac_prefix").value = ['APP']
192        self.browser.getControl(name="form.application_category").value = ['basic']
193        self.browser.getControl("Add applicants container").click()
194        self.assertTrue('Added:' in self.browser.contents)
195        self.browser.open(self.add_container_path)
196        self.browser.getControl(name="form.prefix").value = ['app']
197        self.browser.getControl(name="form.year").value = ['2010']
198        self.browser.getControl(name="form.provider").value = [
199            'waeup.sirp.applicants.ApplicantsContainer']
200        self.browser.getControl(name="form.ac_prefix").value = ['APP']
201        self.browser.getControl(name="form.application_category").value = ['basic']
202        self.browser.getControl("Add applicants container").click()
203        self.assertTrue('exists already in the database' in self.browser.contents)
204        self.browser.open(self.manage_root_path)
205        ctrl = self.browser.getControl(name='val_id')
206        ctrl.getControl(value='app2010').selected = True
207        self.browser.getControl("Remove selected", index=0).click()
208        self.assertTrue('Successfully removed:' in self.browser.contents)
209        return
210
211    def test_add_delete_applicants(self):
212        # Managers can add and delete applicants
213        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
214        self.add_applicant_path = self.container_path + '/addapplicant'
215        self.container_manage_path = self.container_path + '/@@manage'
216        self.browser.open(self.add_applicant_path)
217        self.assertEqual(self.browser.headers['Status'], '200 Ok')
218        self.assertEqual(self.browser.url, self.add_applicant_path)
219        self.browser.getControl(name="form.ac_series").value = self.existing_series
220        self.browser.getControl(name="form.ac_number").value = self.existing_number
221        self.browser.getControl("Create application record").click()
222        self.assertTrue('Application initialized' in self.browser.contents)
223        self.browser.open(self.container_manage_path)
224        self.assertEqual(self.browser.headers['Status'], '200 Ok')
225        ctrl = self.browser.getControl(name='val_id')
226        ctrl.getControl(value=self.existing_pin).selected = True
227        self.browser.getControl("Remove selected", index=0).click()
228        self.assertTrue('Successfully removed:' in self.browser.contents)
229        return
230
231    def test_manage_and_view_applicant(self):
232        # Managers can manage applicants
233        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
234        self.applicant_path = 'http://localhost/app/applicants/app2009/%s' % self.pin_applicant
235        self.applicant_view_path = self.applicant_path + '/index'
236        self.applicant_manage_path = self.applicant_path + '/edit_full'
237        self.applicant_slip_path = self.applicant_path + '/application_slip.pdf'
238        self.browser.open(self.applicant_manage_path)
239        self.assertEqual(self.browser.headers['Status'], '200 Ok')
240        self.browser.getControl(name="form.firstname").value = 'John'
241        self.browser.getControl(name="form.lastname").value = 'Tester'
242        self.browser.getControl(name="form.course1").value = ['CERT1']
243        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
244        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
245        self.browser.getControl(name="form.lga").value = ['foreigner']
246        self.browser.getControl(name="form.sex").value = ['m']
247        self.browser.getControl("Save").click()
248        self.assertMatches('...Form has been saved...', self.browser.contents)
249        self.browser.open(self.applicant_view_path)
250        self.assertEqual(self.browser.headers['Status'], '200 Ok')
251        self.browser.open(self.applicant_slip_path)
252        self.assertEqual(self.browser.headers['Status'], '200 Ok')
253        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
254        return
255
256    def test_view_applicant(self):
257        # Applicants can login and view their application
258        self.login_path = 'http://localhost/app/applicants/app2009/login'
259        self.browser.open(self.login_path)
260        pin = self.pins[2]
261        parts = pin.split('-')[1:]
262        existing_series, existing_number = parts
263        ac_series = self.browser.getControl(name="form.ac_series")
264        ac_series.value = existing_series
265        ac_number = self.browser.getControl(name="form.ac_number")
266        ac_number.value = existing_number
267        self.browser.getControl(name="SUBMIT").click()
268        self.assertTrue(self.browser.url != self.login_path)
269        self.assertEqual(self.browser.headers['Status'], '200 Ok')
270        return
271
272    def test_passport_edit_view(self):
273        # We get a default image after login
274        login_path = 'http://localhost/app/applicants/app2009/login'
275        self.browser.open(login_path)
276        pin = self.pins[2]
277        parts = pin.split('-')[1:]
278        existing_series, existing_number = parts
279        ac_series = self.browser.getControl(name="form.ac_series")
280        ac_series.value = existing_series
281        ac_number = self.browser.getControl(name="form.ac_number")
282        ac_number.value = existing_number
283        self.browser.getControl(name="SUBMIT").click()
284
285        pin = self.pins[2]
286        appl = self.getRootFolder()['app']['applicants']['app2009']
287        appl = appl[pin]
288        passp = appl.passport
289        #import pdb; pdb.set_trace()
290        passp_len = len(passp.file.read())
291        self.assertEqual(passp_len, PH_LEN)
292
293
294        #image_url = "%s/%s" % (self.browser.url, 'placeholder.jpg')
295        image_url = "%s/%s" % (self.browser.url, 'passport.jpg')
296        #self.browser.open(image_url)
297        self.browser.open('passport.jpg')
298        self.assertEqual(self.browser.headers['status'], '200 Ok')
299        self.assertEqual(self.browser.headers['content-type'], 'image/jpeg')
300
301
302        self.assertTrue('JFIF' in self.browser.contents)
303        self.assertEqual(
304            self.browser.headers['content-length'], str(PH_LEN))
305
306
307    def test_edit_applicant(self):
308        # Applicants can edit their record
309        self.login_path = 'http://localhost/app/applicants/app2009/login'
310        self.browser.open(self.login_path)
311        pin = self.pins[2]
312        parts = pin.split('-')[1:]
313        existing_series, existing_number = parts
314        ac_series = self.browser.getControl(name="form.ac_series")
315        ac_series.value = existing_series
316        ac_number = self.browser.getControl(name="form.ac_number")
317        ac_number.value = existing_number
318        self.browser.getControl(name="SUBMIT").click()
319        self.assertTrue(self.browser.url != self.login_path)
320        self.assertEqual(self.browser.headers['Status'], '200 Ok')
321        self.browser.getControl(name="form.firstname").value = 'John'
322        self.browser.getControl(name="form.lastname").value = 'Tester'
323        self.browser.getControl(name="form.course1").value = ['CERT1']
324        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
325        self.browser.getControl(name="form.lga").value = ['foreigner']
326        self.browser.getControl(name="form.sex").value = ['m']
327        self.browser.getControl("Save").click()
328        self.assertMatches('...Form has been saved...', self.browser.contents)
329        return
330
331class LoginTest(FunctionalTestCase):
332    # Here we check login view of applicants containers.
333    #
334    # Tests in here do only cover login attempts without any PINs
335    # created before.
336
337    layer = FunctionalLayer
338
339    def setUp(self):
340        super(LoginTest, self).setUp()
341
342        # Setup a sample site for each test
343        app = University()
344        self.dc_root = tempfile.mkdtemp()
345        app['datacenter'].setStoragePath(self.dc_root)
346        self.login_path = 'http://localhost/app/applicants/testapplicants/login'
347
348        # Add an applicants container where we can login (or not)
349        applicantscontainer = ApplicantsContainer()
350        applicantscontainer.ac_prefix = 'APP'
351        app['applicants']['testapplicants'] = applicantscontainer
352
353        # Put the prepopulated site into test ZODB and prepare test
354        # browser
355        self.getRootFolder()['app'] = app
356        self.browser = Browser()
357        self.browser.handleErrors = False
358
359    def tearDown(self):
360        super(LoginTest, self).tearDown()
361        shutil.rmtree(self.dc_root)
362
363    def test_anonymous_access(self):
364        # Anonymous users can access a login page
365        self.browser.open(self.login_path)
366        self.assertEqual(self.browser.headers['Status'], '200 Ok')
367        return
368
369    def test_anonymous_invalid_creds(self):
370        # Anonymous users giving invalid credentials stay at the page
371        self.browser.open(self.login_path)
372        # We do not give credentials but send the form as-is
373        submit = self.browser.getControl(name='SUBMIT')
374        submit.click()
375        # We are still at the same page...
376        self.assertEqual(self.browser.url, self.login_path)
377        self.assertEqual(self.browser.headers['Status'], '200 Ok')
378        return
379
380    def test_anonymous_invalid_creds_warning(self):
381        # Entering wrong credentials will yield a warning
382        self.browser.open(self.login_path)
383        # We do not give credentials but send the form as-is
384        submit = self.browser.getControl(name='SUBMIT')
385        submit.click()
386        self.assertTrue(
387            'Entered credentials are invalid' in self.browser.contents)
388        return
389
390    def test_manager_no_warnings(self):
391        # Browsing the login screen as a manager, won't raise warnings
392        # Authenticate ourself as manager
393        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
394        self.browser.open(self.login_path)
395        # Submit the form w/o any credentials
396        self.browser.getControl(name="SUBMIT").click()
397        self.assertTrue(
398            'Entered credentials are invalid' not in self.browser.contents)
399        return
400
401    def test_manager_no_redirect(self):
402        # Browsing the login screen as a manager won't trigger a redirect
403        # Authenticate ourself as manager
404        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
405        self.browser.open(self.login_path)
406        # Submit the form w/o any credentials
407        self.browser.getControl(name="SUBMIT").click()
408        self.assertEqual(self.browser.url, self.login_path)
409        return
410
411    def test_display_entered_values(self):
412        # After submit the entered values are displayed in the form
413        self.browser.open(self.login_path)
414        # Enter some value we can look for after submit
415        ac_series = self.browser.getControl(name="form.ac_series")
416        ac_series.value = '666'
417        self.browser.getControl(name="SUBMIT").click()
418        self.assertTrue('666' in self.browser.contents)
419        return
420
421class LoginTestWithPINs(LoginTest):
422    # Here we check login view of applicants containers with PINs provided.
423
424    # As setting up pins is time-consuming we only set them up when
425    # really needed (i.e. in this separate TestCase).
426
427    layer = FunctionalLayer
428
429    def setUp(self):
430        super(LoginTestWithPINs, self).setUp()
431
432        # Create 5 access codes with prefix'FOO' and cost 9.99 each
433        pin_container = self.getRootFolder()['app']['accesscodes']
434        pin_container.createBatch(
435            datetime.now(), 'some_userid', 'APP', 9.99, 5)
436        pins = pin_container[pin_container.keys()[0]].values()
437        self.pins = [x.representation for x in pins]
438        self.existing_pin = self.pins[0]
439        parts = self.existing_pin.split('-')[1:]
440        self.existing_series, self.existing_number = parts
441        self.browser.handleErrors = False
442
443    def tearDown(self):
444        super(LoginTestWithPINs, self).tearDown()
445
446    def test_anonymous_valid_login(self):
447        # If we enter valid credentials, we get to the applicants form
448        self.browser.open(self.login_path)
449        # Enter some value we can look for after submit
450        ac_series = self.browser.getControl(name="form.ac_series")
451        ac_series.value = self.existing_series
452        ac_number = self.browser.getControl(name="form.ac_number")
453        ac_number.value = self.existing_number
454        self.browser.getControl(name="SUBMIT").click()
455        # We should be redirected to applicants form.
456        self.assertTrue(self.browser.url != self.login_path)
457        return
458
459    def test_anonymous_invalid_login(self):
460        # If we enter wrong credentials we won't get far
461        self.browser.open(self.login_path)
462        # Enter some value we can look for after submit
463        ac_series = self.browser.getControl(name="form.ac_series")
464        ac_series.value = 'illegal series'
465        ac_number = self.browser.getControl(name="form.ac_number")
466        ac_number.value = 'invalid number'
467        self.browser.getControl(name="SUBMIT").click()
468        # We get a warning message
469        self.assertTrue(
470            'Entered credentials are invalid' in self.browser.contents)
471        # We stay at the login page (no redirect)
472        self.assertTrue(self.browser.url == self.login_path)
473        return
474
475class ApplicantsPassportTests(ApplicantsFullSetup):
476    # Tests for uploading/browsing the passport image of appplicants
477
478    layer = FunctionalLayer
479
480    def setUp(self):
481        super(ApplicantsPassportTests, self).setUp()
482        self.login_path = 'http://localhost/app/applicants/app2009/login'
483        self.pin = self.pins[2]
484        self.existing_series, self.existing_number = self.pin.split('-')[1:]
485        self.edit_path = 'http://localhost/app/applicants/app2009/%s/edit' % (
486            self.pin)
487        self.edit_full_path = 'http://localhost/app/applicants/%s/%s/%s' % (
488            'app2009', self.pin, 'edit_full')
489
490    def tearDown(self):
491        super(ApplicantsPassportTests, self).tearDown()
492
493    def login(self):
494        # Perform an applicant login. This creates an applicant record.
495        #
496        # This helper also sets `self.applicant`, which is the
497        # applicant object created.
498        self.browser.open(self.login_path)
499        ac_series = self.browser.getControl(name="form.ac_series")
500        ac_series.value = self.existing_series
501        ac_number = self.browser.getControl(name="form.ac_number")
502        ac_number.value = self.existing_number
503        self.browser.getControl(name="SUBMIT").click()
504        self.applicant = self.app['applicants']['app2009'][self.pin]
505
506    def fill_correct_values(self):
507        # Fill the edit form with suitable values
508        self.browser.getControl(name="form.firstname").value = 'John'
509        self.browser.getControl(name="form.lastname").value = 'Tester'
510        self.browser.getControl(name="form.course1").value = ['CERT1']
511        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
512        self.browser.getControl(name="form.lga").value = ['foreigner']
513        self.browser.getControl(name="form.sex").value = ['m']
514
515    def image_url(self, filename):
516        return self.edit_path.replace('edit', filename)
517
518    def test_after_login_default_browsable(self):
519        # After login we see the placeholder image in the edit view
520        self.login()
521        self.assertEqual(self.browser.url, self.edit_path)
522        # There is a correct <img> link included
523        self.assertTrue(
524            '<img src="placeholder_m.jpg" />' in self.browser.contents)
525        # Browsing the link shows a real image
526        self.browser.open(self.image_url('placeholder_m.jpg'))
527        self.assertEqual(
528            self.browser.headers['content-type'], 'image/jpeg')
529        self.assertEqual(len(self.browser.contents), PH_LEN)
530
531    def test_after_login_default_stored_in_imagestorage(self):
532        # After login the applicants placeholder image is stored in
533        # an imagestorage
534        storage = self.app['images']
535        # In the beginning, the storage is empty
536        self.assertEqual([x for x in storage.keys()], [])
537        self.login()
538        # After login, it is filled
539        self.assertEqual(
540            [x for x in storage.keys()],
541            [u'b48a1d39bbcb32e955d9ff2dea4ed0e6'])
542        file_id = self.applicant.passport.data
543        self.assertEqual(
544            file_id, u'b48a1d39bbcb32e955d9ff2dea4ed0e6-1')
545        # The stored image can be fetched
546        fd = storage.retrieveFile(file_id)
547        file_len = len(fd.read())
548        self.assertEqual(file_len, PH_LEN)
549
550    def test_after_submit_default_browsable(self):
551        # After submitting an applicant form the default image is
552        # still visible
553        self.login()
554        self.browser.getControl("Save").click() # submit form
555        # There is a correct <img> link included
556        self.assertTrue(
557            '<img src="placeholder_m.jpg" />' in self.browser.contents)
558        # Browsing the link shows a real image
559        self.browser.open(self.image_url('placeholder_m.jpg'))
560        self.assertEqual(
561            self.browser.headers['content-type'], 'image/jpeg')
562        self.assertEqual(len(self.browser.contents), PH_LEN)
563
564    def test_after_submit_default_stored_in_imagestorage(self):
565        # After submitting an applicant form the default image is
566        # correctly stored in an imagestorage
567        self.login()
568        self.browser.getControl("Save").click() # submit form
569        storage = self.app['images']
570        self.assertEqual(
571            [x for x in storage.keys()],
572            [u'b48a1d39bbcb32e955d9ff2dea4ed0e6'])
573        file_id = self.applicant.passport.data
574        self.assertEqual(
575            file_id, u'b48a1d39bbcb32e955d9ff2dea4ed0e6-1')
576        # The stored image can be fetched
577        fd = storage.retrieveFile(file_id)
578        file_len = len(fd.read())
579        self.assertEqual(file_len, PH_LEN)
580
581    # XXX: Make this test work again
582    def DISABLEDtest_uploaded_image_browsable_w_errors(self):
583        # We can upload a different image and browse it after submit,
584        # even if there are still errors in the form
585        self.login()
586        # Create a pseudo image file and select it to be uploaded in form
587        pseudo_image = StringIO('I pretend to be a graphics file')
588        ctrl = self.browser.getControl(name='form.passport')
589        file_ctrl = ctrl.mech_control
590        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
591        self.browser.getControl("Save").click() # submit form
592        # There is a correct <img> link included
593        self.assertTrue(
594            '<img src="myphoto.jpg" />' in self.browser.contents)
595        # Browsing the link shows a real image
596        self.browser.open(self.image_url('myphoto.jpg'))
597        self.assertEqual(
598            self.browser.headers['content-type'], 'image/jpeg')
599        self.assertEqual(len(self.browser.contents), PH_LEN)
600
601    def test_uploaded_image_stored_in_imagestorage_w_errors(self):
602        # After uploading a new passport pic the file is correctly
603        # stored in an imagestorage
604        self.login()
605        # Create a pseudo image file and select it to be uploaded in form
606        pseudo_image = StringIO('I pretend to be a graphics file')
607        ctrl = self.browser.getControl(name='form.passport')
608        file_ctrl = ctrl.mech_control
609        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
610        self.browser.getControl("Save").click() # submit form
611        storage = self.app['images']
612        self.assertTrue(
613            u'18e57c7eac6ca7fb15b54b5b2bd4106d' in storage.keys())
614        # The stored image can be fetched
615        fd = storage.retrieveFile(u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
616        #fd = storage.retrieveFile(file_id)
617        file_len = len(fd.read())
618        self.assertEqual(file_len, 31)
619        # The image uploaded belongs to the applicant
620        # XXX: When there are errors in form, then the applicant is not
621        #      changed. This (failing) test is here to remember us that
622        #      we have to care for images when form submits fail.
623        file_id = self.applicant.passport.data
624        self.assertEqual(
625            file_id, u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
626
627    def test_uploaded_image_browsable_wo_errors(self):
628        # We can upload a different image and browse it after submit,
629        # if there are no errors in form
630        self.login()
631        self.fill_correct_values() # fill other fields with correct values
632        # Create a pseudo image file and select it to be uploaded in form
633        pseudo_image = StringIO('I pretend to be a graphics file')
634        ctrl = self.browser.getControl(name='form.passport')
635        file_ctrl = ctrl.mech_control
636        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
637        self.browser.getControl("Save").click() # submit form
638        # There is a correct <img> link included
639        self.assertTrue(
640            '<img src="myphoto.jpg" />' in self.browser.contents)
641        # Browsing the link shows a real image
642        self.browser.open(self.image_url('myphoto.jpg'))
643        self.assertEqual(
644            self.browser.headers['content-type'], 'image/jpeg')
645        self.assertEqual(len(self.browser.contents), 31)
646
647    def test_uploaded_image_stored_in_imagestorage_wo_errors(self):
648        # After uploading a new passport pic the file is correctly
649        # stored in an imagestorage if form contains no errors
650        self.login()
651        self.fill_correct_values() # fill other fields with correct values
652        # Create a pseudo image file and select it to be uploaded in form
653        pseudo_image = StringIO('I pretend to be a graphics file')
654        ctrl = self.browser.getControl(name='form.passport')
655        file_ctrl = ctrl.mech_control
656        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
657        self.browser.getControl("Save").click() # submit form
658        storage = self.app['images']
659        self.assertTrue(
660            u'18e57c7eac6ca7fb15b54b5b2bd4106d' in storage.keys())
661        # The stored image can be fetched
662        fd = storage.retrieveFile(u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
663        #fd = storage.retrieveFile(file_id)
664        file_len = len(fd.read())
665        self.assertEqual(file_len, 31)
666        # The image uploaded belongs to the applicant
667        file_id = self.applicant.passport.data
668        self.assertEqual(
669            file_id, u'18e57c7eac6ca7fb15b54b5b2bd4106d-1')
670
671    def test_uploaded_images_equal(self):
672        # Make sure uploaded images do really differ if we eject a
673        # change notfication (and do not if we don't)
674        self.login() # Create applicant form
675        self.fill_correct_values() # fill other fields with correct values
676        self.browser.getControl("Save").click() # submit form
677        # Now go on as an officer
678        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
679        self.browser.open(self.edit_full_path)
680
681        # Create a pseudo image file and select it to be uploaded in form
682        pseudo_image = StringIO('I pretend to be a graphics file')
683        ctrl = self.browser.getControl(name='form.passport')
684        file_ctrl = ctrl.mech_control
685        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
686        passport0 = self.applicant.passport
687        self.browser.getControl("Save").click() # submit form with changed pic
688        passport1 = self.applicant.passport
689        self.browser.getControl("Save").click() # submit form w/o changes
690        passport2 = self.applicant.passport
691        self.assertTrue(passport0 != passport1)
692        self.assertTrue(passport1 == passport2)
693        self.assertTrue(passport1 is passport2)
694        return
695
696    def test_final_submit(self):
697        # Make sure that a correctly filled form with passport picture
698        # can be submitted
699        self.login() # Create applicant form
700        self.fill_correct_values() # fill other fields with correct values
701        # Create a pseudo image file and select it to be uploaded in form
702        pseudo_image = StringIO('I pretend to be a graphics file')
703        ctrl = self.browser.getControl(name='form.passport')
704        file_ctrl = ctrl.mech_control
705        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
706        self.browser.getControl("Final Submit").click() # (finally) submit form
707        self.assertEqual(self.browser.headers['Status'], '200 Ok')
708        self.assertTrue(
709            'Passport confirmation box not ticked' in self.browser.contents)
710        self.browser.getControl(name="confirm_passport").value = True
711        self.browser.getControl("Final Submit").click() # submit form again
712        self.assertTrue(
713            '... submitted ...' in self.browser.contents)
714        return
715
716    def test_locking(self):
717        # Make sure that locked forms can't be submitted
718        self.login() # Create applicant form
719        self.fill_correct_values() # fill other fields with correct values
720        # Create a pseudo image file and select it to be uploaded in form
721        pseudo_image = StringIO('I pretend to be a graphics file')
722        ctrl = self.browser.getControl(name='form.passport')
723        file_ctrl = ctrl.mech_control
724        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
725        self.browser.getControl("Save").click()
726        self.browser.getLink("Logout").click()
727
728        # Login as manager and lock the form
729        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
730        self.browser.open(self.edit_full_path)
731        self.browser.getControl(name="form.locked").value = True
732        self.browser.getControl("Save").click()
733        self.browser.getLink("Logout").click()
734
735        # Login as applicant again and try to open the edit form
736        self.login()
737        self.browser.open(self.edit_path)
738        self.assertEqual(self.browser.headers['Status'], '200 Ok')
739        #print self.browser.contents
740        self.assertTrue(
741            'The requested form is locked' in self.browser.contents)
742        return
Note: See TracBrowser for help on using the repository browser.