source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/tests/test_browser.py @ 10244

Last change on this file since 10244 was 10226, checked in by Henrik Bettermann, 12 years ago

Add local and global ApplicationsManager? role. Assign role dynamically.

  • Property svn:keywords set to Id
File size: 54.2 KB
Line 
1## $Id: test_browser.py 10226 2013-05-24 17:54:10Z 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 os
22import pytz
23import shutil
24import tempfile
25import grok
26from datetime import datetime
27from StringIO import StringIO
28from datetime import datetime, date, timedelta
29from mechanize import LinkNotFoundError
30from zope.event import notify
31from zope.catalog.interfaces import ICatalog
32from zope.component import createObject, getUtility
33from zope.component.hooks import setSite, clearSite
34from zope.security.interfaces import Unauthorized
35from zope.testbrowser.testing import Browser
36from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
37from waeup.kofa.testing import FunctionalLayer, FunctionalTestCase
38from waeup.kofa.app import University
39from waeup.kofa.payments.interfaces import IPayer
40from waeup.kofa.configuration import SessionConfiguration
41from waeup.kofa.applicants.container import ApplicantsContainer
42from waeup.kofa.applicants.applicant import Applicant
43from waeup.kofa.interfaces import (
44    IExtFileStore, IFileStoreNameChooser, IUserAccount)
45from waeup.kofa.university.faculty import Faculty
46from waeup.kofa.university.department import Department
47
48PH_LEN = 15911  # Length of placeholder file
49
50session_1 = datetime.now().year - 2
51container_name_1 = u'app%s' % session_1
52session_2 = datetime.now().year - 1
53container_name_2 = u'app%s' % session_2
54
55class ApplicantsFullSetup(FunctionalTestCase):
56    # A test case that only contains a setup and teardown
57    #
58    # Complete setup for applicants handlings is rather complex and
59    # requires lots of things created before we can start. This is a
60    # setup that does all this, creates a university, creates PINs,
61    # etc.  so that we do not have to bother with that in different
62    # test cases.
63
64    layer = FunctionalLayer
65
66    def setUp(self):
67        super(ApplicantsFullSetup, self).setUp()
68
69        # Setup a sample site for each test
70        app = University()
71        self.dc_root = tempfile.mkdtemp()
72        app['datacenter'].setStoragePath(self.dc_root)
73
74        # Prepopulate the ZODB...
75        self.getRootFolder()['app'] = app
76        # we add the site immediately after creation to the
77        # ZODB. Catalogs and other local utilities are not setup
78        # before that step.
79        self.app = self.getRootFolder()['app']
80        # Set site here. Some of the following setup code might need
81        # to access grok.getSite() and should get our new app then
82        setSite(app)
83
84        self.login_path = 'http://localhost/app/login'
85        self.root_path = 'http://localhost/app/applicants'
86        self.search_path = 'http://localhost/app/applicants/search'
87        self.manage_root_path = self.root_path + '/@@manage'
88        self.add_container_path = self.root_path + '/@@add'
89        self.container_path = 'http://localhost/app/applicants/%s' % container_name_1
90        self.manage_container_path = self.container_path + '/@@manage'
91
92        # Add an applicants container
93        applicantscontainer = ApplicantsContainer()
94        applicantscontainer.code = container_name_1
95        applicantscontainer.prefix = 'app'
96        applicantscontainer.year = session_1
97        applicantscontainer.title = u'This is the %s container' % container_name_1
98        applicantscontainer.application_category = 'basic'
99        applicantscontainer.mode = 'create'
100        applicantscontainer.strict_deadline = True
101        delta = timedelta(days=10)
102        applicantscontainer.startdate = datetime.now(pytz.utc) - delta
103        applicantscontainer.enddate = datetime.now(pytz.utc) + delta
104        self.app['applicants'][container_name_1] = applicantscontainer
105        self.applicantscontainer = self.app['applicants'][container_name_1]
106
107        # Populate university
108        certificate = createObject('waeup.Certificate')
109        certificate.code = 'CERT1'
110        certificate.application_category = 'basic'
111        certificate.start_level = 100
112        certificate.end_level = 500
113        certificate.study_mode = u'ug_ft'
114        self.certificate = certificate
115        self.app['faculties']['fac1'] = Faculty()
116        # The code has explicitely to be set, otherwise we don't
117        # find created students in their department
118        self.app['faculties']['fac1']['dep1'] = Department(code='dep1')
119        self.department = self.app['faculties']['fac1']['dep1']
120        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
121            certificate)
122
123        # Put the prepopulated site into test ZODB and prepare test
124        # browser
125        self.browser = Browser()
126        self.browser.handleErrors = False
127
128        # Create 5 access codes with prefix'FOO' and cost 9.99 each
129        pin_container = self.app['accesscodes']
130        pin_container.createBatch(
131            datetime.now(), 'some_userid', 'APP', 9.99, 5)
132        pins = pin_container[pin_container.keys()[0]].values()
133        self.pins = [x.representation for x in pins]
134        self.existing_pin = self.pins[0]
135        parts = self.existing_pin.split('-')[1:]
136        self.existing_series, self.existing_number = parts
137
138        # Add an applicant
139        self.applicant = createObject('waeup.Applicant')
140        # reg_number is the only field which has to be preset here
141        # because managers are allowed to edit this required field
142        self.applicant.reg_number = u'1234'
143        self.applicant.course1 = certificate
144        app['applicants'][container_name_1].addApplicant(self.applicant)
145        IUserAccount(
146            self.app['applicants'][container_name_1][
147            self.applicant.application_number]).setPassword('apwd')
148        self.manage_path = 'http://localhost/app/applicants/%s/%s/%s' % (
149            container_name_1, self.applicant.application_number, 'manage')
150        self.edit_path = 'http://localhost/app/applicants/%s/%s/%s' % (
151            container_name_1, self.applicant.application_number, 'edit')
152        self.view_path = 'http://localhost/app/applicants/%s/%s' % (
153            container_name_1, self.applicant.application_number)
154
155    def login(self):
156        # Perform an applicant login. This creates an applicant record.
157        #
158        # This helper also sets `self.applicant`, which is the
159        # applicant object created.
160        self.browser.open(self.login_path)
161        self.browser.getControl(
162            name="form.login").value = self.applicant.applicant_id
163        self.browser.getControl(name="form.password").value = 'apwd'
164        self.browser.getControl("Login").click()
165
166    def fill_correct_values(self):
167        # Fill the edit form with suitable values
168        self.browser.getControl(name="form.firstname").value = 'John'
169        self.browser.getControl(name="form.middlename").value = 'Anthony'
170        self.browser.getControl(name="form.lastname").value = 'Tester'
171        self.browser.getControl(name="form.course1").value = ['CERT1']
172        self.browser.getControl(name="form.date_of_birth").value = '09/09/1988'
173        self.browser.getControl(name="form.sex").value = ['m']
174        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
175
176    def tearDown(self):
177        super(ApplicantsFullSetup, self).tearDown()
178        clearSite()
179        shutil.rmtree(self.dc_root)
180
181class ApplicantsRootUITests(ApplicantsFullSetup):
182    # Tests for ApplicantsRoot class
183
184    layer = FunctionalLayer
185
186    def test_anonymous_access(self):
187        # Anonymous users can access applicants root
188        self.browser.open(self.root_path)
189        self.assertEqual(self.browser.headers['Status'], '200 Ok')
190        self.assertFalse(
191            'Manage ' in self.browser.contents)
192        return
193
194    def test_anonymous_no_actions(self):
195        # Make sure anonymous users cannot access actions
196        self.browser.open(self.root_path)
197        self.assertRaises(
198            LookupError, self.browser.getControl, "Add local role")
199        # Manage screen neither linked nor accessible for anonymous
200        self.assertRaises(
201            LinkNotFoundError,
202            self.browser.getLink, 'Manage application section')
203        self.assertRaises(
204            Unauthorized, self.browser.open, self.manage_root_path)
205        # Add container screen not accessible for anonymous
206        self.assertRaises(
207            Unauthorized, self.browser.open, self.add_container_path)
208        return
209
210    def test_manage_access(self):
211        # Managers can access the manage pages of applicants root
212        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
213        self.browser.open(self.root_path)
214        self.assertTrue('Manage application section' in self.browser.contents)
215        # There is a manage link
216        link = self.browser.getLink('Manage application section')
217        link.click()
218        self.assertEqual(self.browser.headers['Status'], '200 Ok')
219        self.assertEqual(self.browser.url, self.manage_root_path)
220        return
221
222    def test_hide_container(self):
223        self.browser.open(self.root_path)
224        self.assertTrue(
225            '<a href="http://localhost/app/applicants/app2011">'
226            'This is the app2011 container</a>' in self.browser.contents)
227        self.app['applicants']['app2011'].hidden = True
228        self.browser.open(self.root_path)
229        # Anonymous users can't see hidden containers
230        self.assertFalse(
231            '<a href="http://localhost/app/applicants/app2011">'
232            'This is the app2011 container</a>' in self.browser.contents)
233        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
234        self.browser.open(self.root_path)
235        self.assertTrue(
236            '<a href="http://localhost/app/applicants/app2011">'
237            'This is the app2011 container</a>' in self.browser.contents)
238        return
239
240    def test_search(self):
241        # Managers can access the manage pages of applicants root
242        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
243        self.browser.open(self.manage_path)
244        self.fill_correct_values()
245        self.browser.getControl("Save").click()
246        self.browser.open(self.root_path)
247        self.assertTrue('Manage application section' in self.browser.contents)
248        # There is a search link
249        link = self.browser.getLink('Search applicants')
250        link.click()
251        self.assertEqual(self.browser.headers['Status'], '200 Ok')
252        # We can find an applicant ...
253        # ... via his name
254        self.browser.getControl(name="searchtype").value = ['fullname']
255        self.browser.getControl(name="searchterm").value = 'John'
256        self.browser.getControl("Search").click()
257        self.assertTrue('John Anthony Tester' in self.browser.contents)
258        self.browser.getControl(name="searchtype").value = ['fullname']
259        self.browser.getControl(name="searchterm").value = 'Tester'
260        self.browser.getControl("Search").click()
261        self.assertTrue('John Anthony Tester' in self.browser.contents)
262        self.browser.open(self.search_path)
263        # ... and via his reg_number ...
264        self.browser.getControl(name="searchtype").value = ['reg_number']
265        self.browser.getControl(name="searchterm").value = '2345'
266        self.browser.getControl("Search").click()
267        self.assertFalse('John Anthony Tester' in self.browser.contents)
268        self.browser.getControl(name="searchtype").value = ['reg_number']
269        self.browser.getControl(name="searchterm").value = '1234'
270        self.browser.getControl("Search").click()
271        self.assertTrue('John Anthony Tester' in self.browser.contents)
272        # ... and not via his application_number ...
273        self.browser.getControl(name="searchtype").value = ['applicant_id']
274        self.browser.getControl(
275            name="searchterm").value = self.applicant.application_number
276        self.browser.getControl("Search").click()
277        self.assertFalse('John Anthony Tester' in self.browser.contents)
278        # ... but ia his applicant_id ...
279        self.browser.getControl(name="searchtype").value = ['applicant_id']
280        self.browser.getControl(
281            name="searchterm").value = self.applicant.applicant_id
282        self.browser.getControl("Search").click()
283        self.assertTrue('John Anthony Tester' in self.browser.contents)
284        # ... and via his email
285        self.browser.getControl(name="searchtype").value = ['email']
286        self.browser.getControl(name="searchterm").value = 'xx@yy.zz'
287        self.browser.getControl("Search").click()
288        self.assertTrue('John Anthony Tester' in self.browser.contents)
289        return
290
291    def test_manage_actions_access(self):
292        # Managers can access the action on manage screen
293        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
294        self.browser.open(self.manage_root_path)
295        self.browser.getControl("Add local role").click()
296        self.assertTrue('No user selected' in self.browser.contents)
297        return
298
299    def test_local_roles_add_delete(self):
300        # Managers can assign and delete local roles of applicants root
301        myusers = self.app['users']
302        myusers.addUser('bob', 'bobssecret')
303        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
304        self.browser.open('http://localhost/app/faculties/fac1/dep1/manage')
305        self.browser.getControl(name="user").value = ['bob']
306        self.browser.getControl(name="local_role").value = [
307            'waeup.local.ApplicationsManager']
308        self.browser.getControl("Add local role").click()
309        self.assertTrue('<td>bob</td>' in self.browser.contents)
310        # Remove the role assigned
311        ctrl = self.browser.getControl(name='role_id')
312        ctrl.getControl(
313            value='bob|waeup.local.ApplicationsManager').selected = True
314        self.browser.getControl("Remove selected local roles").click()
315        self.assertTrue(
316            'Local role successfully removed: bob|waeup.local.ApplicationsManager'
317            in self.browser.contents)
318        self.assertFalse('<td>bob</td>' in self.browser.contents)
319        return
320
321    def test_add_delete_container(self):
322        # Managers can add and delete applicants containers
323        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
324        self.browser.open(self.manage_root_path)
325        self.browser.getControl("Add applicants container").click()
326        self.assertEqual(self.browser.headers['Status'], '200 Ok')
327        self.assertEqual(self.browser.url, self.add_container_path)
328        self.browser.getControl(name="form.prefix").value = ['app']
329        self.browser.getControl("Add applicants container").click()
330        self.assertTrue(
331            'There were errors' in self.browser.contents)
332        self.browser.getControl(name="form.prefix").value = ['app']
333        self.browser.getControl(name="form.year").value = [str(session_2)]
334        self.browser.getControl(name="form.mode").value = ['create']
335        self.browser.getControl(
336            name="form.application_category").value = ['basic']
337        self.browser.getControl("Add applicants container").click()
338        self.assertTrue('Added:' in self.browser.contents)
339        self.browser.getLink("app2011").click()
340        self.assertTrue('Manage applicants container'
341            in self.browser.contents)
342        self.browser.open(self.add_container_path)
343        self.browser.getControl("Cancel").click()
344        self.assertEqual(self.browser.url, self.manage_root_path)
345        self.browser.open(self.add_container_path)
346        self.browser.getControl(name="form.prefix").value = ['app']
347        self.browser.getControl(name="form.year").value = [str(session_2)]
348        self.browser.getControl(name="form.mode").value = ['create']
349        self.browser.getControl(
350            name="form.application_category").value = ['basic']
351        self.browser.getControl("Add applicants container").click()
352        self.assertTrue('exists already in the database'
353                        in self.browser.contents)
354        self.browser.open(self.manage_root_path)
355        ctrl = self.browser.getControl(name='val_id')
356        ctrl.getControl(value=container_name_2).selected = True
357        self.browser.getControl("Remove selected", index=0).click()
358        self.assertTrue('Successfully removed:' in self.browser.contents)
359        self.browser.open(self.add_container_path)
360        self.browser.getControl(name="form.prefix").value = ['app']
361        self.browser.getControl(name="form.year").value = [str(session_2)]
362        self.browser.getControl(name="form.mode").value = ['create']
363        #self.browser.getControl(name="form.ac_prefix").value = ['APP']
364        self.browser.getControl(
365            name="form.application_category").value = ['basic']
366        self.browser.getControl("Add applicants container").click()
367        del self.app['applicants'][container_name_2]
368        ctrl = self.browser.getControl(name='val_id')
369        ctrl.getControl(value=container_name_2).selected = True
370        self.browser.getControl("Remove selected", index=0).click()
371        self.assertMatches('...Could not delete...', self.browser.contents)
372        return
373
374class ApplicantsContainerUITests(ApplicantsFullSetup):
375    # Tests for ApplicantsContainer class views and pages
376
377    layer = FunctionalLayer
378
379    def test_anonymous_access(self):
380        # Anonymous users can access applicants containers
381        self.browser.open(self.container_path)
382        self.assertEqual(self.browser.headers['Status'], '200 Ok')
383        self.assertFalse(
384            'Manage ' in self.browser.contents)
385        return
386
387    def test_manage_access(self):
388        # Managers can access the manage pages of applicants
389        # containers and can perform actions
390        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
391        self.browser.open(self.manage_container_path)
392        self.assertEqual(self.browser.headers['Status'], '200 Ok')
393        self.assertEqual(self.browser.url, self.manage_container_path)
394        self.browser.getControl(name="form.application_fee").value = '200'
395        self.browser.getControl("Save").click()
396        self.assertTrue('Form has been saved' in self.browser.contents)
397        logfile = os.path.join(
398            self.app['datacenter'].storage, 'logs', 'applicants.log')
399        logcontent = open(logfile).read()
400        self.assertTrue(
401            'zope.mgr - applicants.browser.ApplicantsContainerManageFormPage - '
402            'app2011 - saved: application_fee\n' in logcontent)
403        self.browser.getControl("Remove selected", index=0).click()
404        self.assertTrue('No applicant selected' in self.browser.contents)
405        self.browser.getControl("Add local role").click()
406        self.assertTrue('No user selected' in self.browser.contents)
407        self.browser.getControl("Cancel", index=0).click()
408        self.assertEqual(self.browser.url, self.container_path)
409        return
410
411    def test_statistics(self):
412        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
413        self.browser.open(self.container_path)
414        self.browser.getLink("Container statistics").click()
415        self.assertTrue('<td>initialized</td>' in self.browser.contents)
416        self.assertTrue('<td>1</td>' in self.browser.contents)
417        self.assertEqual(self.applicantscontainer.statistics[0],
418            {'not admitted': 0, 'started': 0, 'created': 0,
419            'admitted': 0, 'submitted': 0, 'initialized': 1, 'paid': 0})
420        #self.assertEqual(self.applicantscontainer.statistics[1],
421        #    {u'fac1': 0})
422        IWorkflowState(self.applicant).setState('submitted')
423        notify(grok.ObjectModifiedEvent(self.applicant))
424        self.assertEqual(self.applicantscontainer.statistics[0],
425            {'not admitted': 0, 'started': 0, 'created': 0,
426            'admitted': 0, 'submitted': 1, 'initialized': 0, 'paid': 0})
427        #self.assertEqual(self.applicantscontainer.statistics[1],
428        #    {u'fac1': 1})
429        return
430
431    def test_add_delete_applicants(self):
432        # Managers can add and delete applicants
433        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
434        self.add_applicant_path = self.container_path + '/addapplicant'
435        self.container_manage_path = self.container_path + '/@@manage'
436        self.browser.open(self.container_manage_path)
437        self.browser.getLink("Add applicant").click()
438        self.assertEqual(self.browser.headers['Status'], '200 Ok')
439        self.assertEqual(self.browser.url, self.add_applicant_path)
440        self.browser.getControl(name="form.firstname").value = 'Alois'
441        self.browser.getControl(name="form.middlename").value = 'Kofi'
442        self.browser.getControl(name="form.lastname").value = 'Bettermann'
443        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
444        self.browser.getControl("Create application record").click()
445        self.assertTrue('Application initialized' in self.browser.contents)
446        self.browser.open(self.container_manage_path)
447        self.assertEqual(self.browser.headers['Status'], '200 Ok')
448        ctrl = self.browser.getControl(name='val_id')
449        value = ctrl.options[0]
450        ctrl.getControl(value=value).selected = True
451        self.browser.getControl("Remove selected", index=0).click()
452        self.assertTrue('Successfully removed:' in self.browser.contents)
453        self.browser.open(self.add_applicant_path)
454        self.browser.getControl(name="form.firstname").value = 'Albert'
455        self.browser.getControl(name="form.lastname").value = 'Einstein'
456        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
457        self.browser.getControl("Create application record").click()
458        self.assertTrue('Application initialized' in self.browser.contents)
459        return
460
461class ApplicantUITests(ApplicantsFullSetup):
462    # Tests for uploading/browsing the passport image of appplicants
463
464    layer = FunctionalLayer
465
466    def test_manage_and_view_applicant(self):
467        # Managers can manage applicants
468        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
469        self.slip_path = self.view_path + '/application_slip.pdf'
470        self.browser.open(self.manage_path)
471        self.assertEqual(self.browser.headers['Status'], '200 Ok')
472        self.fill_correct_values()
473        # Fire transition
474        self.browser.getControl(name="transition").value = ['start']
475        self.browser.getControl("Save").click()
476        # Be sure that the empty phone field does not show wrong error message
477        self.assertFalse('Required input is missing' in self.browser.contents)
478        self.assertMatches('...Form has been saved...', self.browser.contents)
479        self.assertMatches('...Application started by Manager...',
480                           self.browser.contents)
481        self.browser.open(self.view_path)
482        self.assertEqual(self.browser.headers['Status'], '200 Ok')
483        # Change course_admitted
484        self.browser.open(self.manage_path)
485        self.browser.getControl(name="form.course_admitted").value = ['CERT1']
486        self.browser.getControl("Save").click()
487        self.assertMatches('...Form has been saved...', self.browser.contents)
488        # Change password
489        self.browser.getControl(name="password").value = 'secret'
490        self.browser.getControl(name="control_password").value = 'secre'
491        self.browser.getControl("Save").click()
492        self.assertMatches('...Passwords do not match...',
493                           self.browser.contents)
494        self.browser.getControl(name="password").value = 'secret'
495        self.browser.getControl(name="control_password").value = 'secret'
496        self.browser.getControl("Save").click()
497        self.assertMatches('...Form has been saved...', self.browser.contents)
498        # Pdf slip can't be opened and download button is not available
499        self.assertFalse('Download application slip' in self.browser.contents)
500        self.browser.open(self.slip_path)
501        self.assertTrue(
502            'Please pay and submit before trying to download the application slip.'
503            in self.browser.contents)
504        # If applicant is in correct state the pdf slip can be opened.
505        IWorkflowState(self.applicant).setState('submitted')
506        self.browser.open(self.manage_path)
507        self.browser.getLink("Download application slip").click()
508        self.assertEqual(self.browser.headers['Status'], '200 Ok')
509        self.assertEqual(self.browser.headers['Content-Type'],
510                         'application/pdf')
511        # Managers can view applicants even if certificate has been removed
512        del self.app['faculties']['fac1']['dep1'].certificates['CERT1']
513        self.browser.open(self.view_path)
514        self.assertEqual(self.browser.headers['Status'], '200 Ok')
515        self.browser.open(self.slip_path)
516        self.assertEqual(self.browser.headers['Status'], '200 Ok')
517        return
518
519    def test_passport_edit_view(self):
520        # We get a default image after login
521        self.browser.open(self.login_path)
522        self.login()
523        self.browser.open(self.browser.url + '/passport.jpg')
524        self.assertEqual(self.browser.headers['status'], '200 Ok')
525        self.assertEqual(self.browser.headers['content-type'], 'image/jpeg')
526        self.assertTrue('JFIF' in self.browser.contents)
527        self.assertEqual(
528            self.browser.headers['content-length'], str(PH_LEN))
529
530    def test_applicant_login(self):
531        self.applicant.suspended = True
532        self.login()
533        self.assertTrue(
534            'You entered invalid credentials.' in self.browser.contents)
535        self.applicant.suspended = False
536        self.browser.getControl("Login").click()
537        self.assertTrue(
538            'You logged in.' in self.browser.contents)
539
540    def test_applicant_access(self):
541        # Applicants can edit their record
542        self.browser.open(self.login_path)
543        self.login()
544        self.assertTrue(
545            'You logged in.' in self.browser.contents)
546        self.browser.open(self.edit_path)
547        self.assertTrue(self.browser.url != self.login_path)
548        self.assertEqual(self.browser.headers['Status'], '200 Ok')
549        self.fill_correct_values()
550        self.assertTrue(IUserAccount(self.applicant).checkPassword('apwd'))
551        self.browser.getControl("Save").click()
552        self.assertMatches('...Form has been saved...', self.browser.contents)
553        # Applicants don't see manage and search links ...
554        self.browser.open(self.root_path)
555        self.assertEqual(self.browser.headers['Status'], '200 Ok')
556        self.assertFalse('Search' in self.browser.contents)
557        self.assertFalse('Manage application section' in self.browser.contents)
558        # ... and can't access the manage page
559        self.assertRaises(
560            Unauthorized, self.browser.open, self.manage_path)
561        return
562
563    def image_url(self, filename):
564        return self.edit_path.replace('edit', filename)
565
566    def test_after_login_default_browsable(self):
567        # After login we see the placeholder image in the edit view
568        self.login()
569        self.assertEqual(self.browser.url, self.view_path)
570        self.browser.open(self.edit_path)
571        # There is a correct <img> link included
572        self.assertTrue(
573              '<img src="passport.jpg" height="180px" />' in self.browser.contents)
574        # Browsing the link shows a real image
575        self.browser.open(self.image_url('passport.jpg'))
576        self.assertEqual(
577            self.browser.headers['content-type'], 'image/jpeg')
578        self.assertEqual(len(self.browser.contents), PH_LEN)
579
580    def test_after_submit_default_browsable(self):
581        # After submitting an applicant form the default image is
582        # still visible
583        self.login()
584        self.browser.open(self.edit_path)
585        self.browser.getControl("Save").click() # submit form
586        # There is a correct <img> link included
587        self.assertTrue(
588            '<img src="passport.jpg" height="180px" />' in self.browser.contents)
589        # Browsing the link shows a real image
590        self.browser.open(self.image_url('passport.jpg'))
591        self.assertEqual(
592            self.browser.headers['content-type'], 'image/jpeg')
593        self.assertEqual(len(self.browser.contents), PH_LEN)
594
595    def test_uploaded_image_respects_file_size_restriction(self):
596        # When we upload an image that is too big ( > 10 KB) we will
597        # get an error message
598        self.login()
599        self.browser.open(self.edit_path)
600        # Create a pseudo image file and select it to be uploaded in form
601        photo_content = 'A' * 1024 * 21  # A string of 21 KB size
602        pseudo_image = StringIO(photo_content)
603        ctrl = self.browser.getControl(name='form.passport')
604        file_ctrl = ctrl.mech_control
605        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
606        self.browser.getControl("Save").click() # submit form
607        # There is a correct <img> link included
608        self.assertTrue(
609            '<img src="passport.jpg" height="180px" />' in self.browser.contents)
610        # We get a warning message
611        self.assertTrue(
612            'Uploaded image is too big' in self.browser.contents)
613        # Browsing the image gives us the default image, not the
614        # uploaded one.
615        self.browser.open(self.image_url('passport.jpg'))
616        self.assertEqual(
617            self.browser.headers['content-type'], 'image/jpeg')
618        self.assertEqual(len(self.browser.contents), PH_LEN)
619        # There is really no file stored for the applicant
620        img = getUtility(IExtFileStore).getFile(
621            IFileStoreNameChooser(self.applicant).chooseName())
622        self.assertTrue(img is None)
623
624    def test_uploaded_image_browsable_w_errors(self):
625        # We can upload a different image and browse it after submit,
626        # even if there are still errors in the form
627        self.login()
628        self.browser.open(self.edit_path)
629        # Create a pseudo image file and select it to be uploaded in form
630        photo_content = 'I pretend to be a graphics file'
631        pseudo_image = StringIO(photo_content)
632        ctrl = self.browser.getControl(name='form.passport')
633        file_ctrl = ctrl.mech_control
634        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
635        self.browser.getControl("Save").click() # submit form
636        # There is a correct <img> link included
637        self.assertTrue(
638            '<img src="passport.jpg" height="180px" />' in self.browser.contents)
639        # Browsing the link shows a real image
640        self.browser.open(self.image_url('passport.jpg'))
641        self.assertEqual(
642            self.browser.headers['content-type'], 'image/jpeg')
643        self.assertEqual(self.browser.contents, photo_content)
644
645    def test_uploaded_image_stored_in_imagestorage_w_errors(self):
646        # After uploading a new passport pic the file is correctly
647        # stored in an imagestorage
648        self.login()
649        self.browser.open(self.edit_path)
650        # Create a pseudo image file and select it to be uploaded in form
651        pseudo_image = StringIO('I pretend to be a graphics file')
652        ctrl = self.browser.getControl(name='form.passport')
653        file_ctrl = ctrl.mech_control
654        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
655        self.browser.getControl("Save").click() # submit form
656        storage = getUtility(IExtFileStore)
657        file_id = IFileStoreNameChooser(self.applicant).chooseName()
658        pseudo_image.seek(0) # reset our file data source
659        self.assertEqual(
660            storage.getFile(file_id).read(), pseudo_image.read())
661        return
662
663    def test_uploaded_image_browsable_wo_errors(self):
664        # We can upload a different image and browse it after submit,
665        # if there are no errors in form
666        self.login()
667        self.browser.open(self.edit_path)
668        self.fill_correct_values() # fill other fields with correct values
669        # Create a pseudo image file and select it to be uploaded in form
670        pseudo_image = StringIO('I pretend to be a graphics file')
671        ctrl = self.browser.getControl(name='form.passport')
672        file_ctrl = ctrl.mech_control
673        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
674        self.browser.getControl("Save").click() # submit form
675        # There is a correct <img> link included
676        self.assertTrue(
677            '<img src="passport.jpg" height="180px" />' in self.browser.contents)
678        # Browsing the link shows a real image
679        self.browser.open(self.image_url('passport.jpg'))
680        self.assertEqual(
681            self.browser.headers['content-type'], 'image/jpeg')
682        self.assertEqual(len(self.browser.contents), 31)
683
684    def test_uploaded_image_stored_in_imagestorage_wo_errors(self):
685        # After uploading a new passport pic the file is correctly
686        # stored in an imagestorage if form contains no errors
687        self.login()
688        self.browser.open(self.edit_path)
689        self.fill_correct_values() # fill other fields with correct values
690        # Create a pseudo image file and select it to be uploaded in form
691        pseudo_image = StringIO('I pretend to be a graphics file')
692        ctrl = self.browser.getControl(name='form.passport')
693        file_ctrl = ctrl.mech_control
694        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
695        self.browser.getControl("Save").click() # submit form
696        storage = getUtility(IExtFileStore)
697        file_id = IFileStoreNameChooser(self.applicant).chooseName()
698        # The stored image can be fetched
699        fd = storage.getFile(file_id)
700        file_len = len(fd.read())
701        self.assertEqual(file_len, 31)
702        # When an applicant is removed, also the image is gone.
703        del self.app['applicants']['app2011'][self.applicant.application_number]
704        fd = storage.getFile(file_id)
705        self.assertTrue(fd is None)
706
707    def test_uploaded_images_equal(self):
708        # Make sure uploaded images do really differ if we eject a
709        # change notfication (and do not if we don't)
710        self.login()
711        self.browser.open(self.edit_path)
712        self.fill_correct_values() # fill other fields with correct values
713        self.browser.getControl("Save").click() # submit form
714        # Now go on as an officer
715        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
716        self.browser.open(self.manage_path)
717
718        # Create a pseudo image file and select it to be uploaded in form
719        pseudo_image = StringIO('I pretend to be a graphics file')
720        ctrl = self.browser.getControl(name='form.passport')
721        file_ctrl = ctrl.mech_control
722        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
723        file_id = IFileStoreNameChooser(self.applicant).chooseName()
724        setSite(self.app)
725        passport0 = getUtility(IExtFileStore).getFile(file_id)
726        self.browser.getControl("Save").click() # submit form with changed pic
727        passport1 = getUtility(IExtFileStore).getFile(file_id).read()
728        self.browser.getControl("Save").click() # submit form w/o changes
729        passport2 = getUtility(IExtFileStore).getFile(file_id).read()
730        self.assertTrue(passport0 is None)
731        self.assertTrue(passport0 != passport1)
732        self.assertTrue(passport1 == passport2)
733        return
734
735    def test_upload_image_by_manager_with_logging(self):
736        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
737        self.browser.open(self.manage_path)
738        # Create a pseudo image file and select it to be uploaded in form
739        photo_content = 'A' * 1024 * 5  # A string of 5 KB size
740        pseudo_image = StringIO(photo_content)
741        ctrl = self.browser.getControl(name='form.passport')
742        file_ctrl = ctrl.mech_control
743        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
744        self.browser.getControl("Save").click() # submit form
745        # Even though the form could not be saved ...
746        self.assertTrue(
747            'Required input is missing' in self.browser.contents)
748        # ... the file has been successfully uploaded
749        logfile = os.path.join(
750            self.app['datacenter'].storage, 'logs', 'applicants.log')
751        logcontent = open(logfile).read()
752        self.assertTrue(
753            'zope.mgr - applicants.browser.ApplicantManageFormPage - '
754            '%s - saved: passport'
755            % (self.applicant.applicant_id)
756            in logcontent)
757
758    def test_pay_application_fee(self):
759        self.login()
760        self.browser.open(self.edit_path)
761        # Payment tickets can't be created before the form has been validated
762        self.browser.getControl("Add online payment ticket").click()
763        self.assertTrue('Required input is missing' in self.browser.contents)
764        self.fill_correct_values()
765        # We have to save the form otherwise the filled fields will be cleared
766        # after adding an online payment, because adding an online payment
767        # requires a filled form but does not save it
768        self.browser.getControl("Save").click()
769        self.browser.getControl("Add online payment ticket").click()
770        # Session object missing
771        self.assertTrue(
772            'Session configuration object is not available'
773            in self.browser.contents)
774        configuration = SessionConfiguration()
775        configuration.academic_session = session_1
776        configuration.application_fee = 200.0
777        self.app['configuration'].addSessionConfiguration(configuration)
778        self.browser.open(self.edit_path)
779        self.browser.getControl("Add online payment ticket").click()
780        self.assertMatches('...Payment ticket created...',
781                           self.browser.contents)
782        self.assertMatches('...Activation Code...',
783                           self.browser.contents)
784        # Payment ticket can be removed if they haven't received a
785        # valid callback
786        self.browser.open(self.edit_path)
787        ctrl = self.browser.getControl(name='val_id')
788        value = ctrl.options[0]
789        ctrl.getControl(value=value).selected = True
790        self.browser.getControl("Remove selected", index=0).click()
791        self.assertMatches('...Successfully removed...', self.browser.contents)
792        # We will try the callback request view
793        self.browser.getControl("Add online payment ticket").click()
794        self.browser.open(self.edit_path)
795        ctrl = self.browser.getControl(name='val_id')
796        value = ctrl.options[0]
797        self.browser.getLink(value).click()
798        self.assertMatches('...Amount Authorized...',
799                           self.browser.contents)
800        payment_url = self.browser.url
801        payment_id = self.applicant.keys()[0]
802        payment = self.applicant[payment_id]
803        self.assertEqual(payment.p_item,'This is the %s container' % container_name_1)
804        self.assertEqual(payment.p_session, session_1)
805        self.assertEqual(payment.p_category,'application')
806        self.assertEqual(payment.amount_auth,200.0)
807        # Applicant is payer of the payment ticket.
808        self.assertEqual(
809            IPayer(payment).display_fullname, 'John Anthony Tester')
810        self.assertEqual(
811            IPayer(payment).id, self.applicant.applicant_id)
812        self.assertEqual(IPayer(payment).faculty, '')
813        self.assertEqual(IPayer(payment).department, '')
814        # The pdf payment slip can't yet be opened
815        #self.browser.open(payment_url + '/payment_receipt.pdf')
816        #self.assertMatches('...Ticket not yet paid...',
817        #                   self.browser.contents)
818        # Approve payment
819        # Applicants can't approve payments
820        self.assertRaises(
821            Unauthorized, self.browser.open, payment_url + '/approve')
822        # We approve the payment by bypassing the view
823        payment.approve()
824        # The payment slip can be downloaded now
825        self.browser.open(payment_url)
826        self.browser.getLink("Download payment slip").click()
827        self.assertEqual(self.browser.headers['Status'], '200 Ok')
828        self.assertEqual(self.browser.headers['Content-Type'],
829                         'application/pdf')
830        # Applicant is is not yet in state 'paid' because it was only
831        # the payment which we set to paid
832        self.browser.open(self.view_path)
833        self.assertMatches('...started...',
834                           self.browser.contents)
835        self.assertTrue(self.applicant.state == 'started')
836        # Let's logout and approve the payment as manager
837        self.browser.getLink("Logout").click()
838        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
839        # First we reset the payment
840        payment.r_amount_approved = 0.0
841        payment.r_code = u''
842        payment.p_state = 'unpaid'
843        payment.r_desc = u''
844        payment.payment_date = None
845        self.browser.open(payment_url)
846        self.browser.getLink("Approve payment").click()
847        self.assertEqual(payment.p_state, 'paid')
848        self.assertEqual(payment.r_amount_approved, 200.0)
849        self.assertEqual(payment.r_code, 'AP')
850        self.assertTrue(self.applicant.state == 'paid')
851        # Approval is logged in students.log ...
852        logfile = os.path.join(
853            self.app['datacenter'].storage, 'logs', 'applicants.log')
854        logcontent = open(logfile).read()
855        self.assertTrue(
856            'zope.mgr - applicants.browser.OnlinePaymentApprovePage - '
857            '%s - payment approved' % self.applicant.applicant_id
858            in logcontent)
859        # ... and in payments.log
860        logfile = os.path.join(
861            self.app['datacenter'].storage, 'logs', 'payments.log')
862        logcontent = open(logfile).read()
863        self.assertTrue(
864            '"zope.mgr",%s,%s,application,200.0,AP,,,,,,\n'
865            % (self.applicant.applicant_id, payment.p_id)
866            in logcontent)
867        return
868
869    def test_duplicate_choice(self):
870        # Make sure that that 1st and 2nd choice are different
871        self.login()
872        self.browser.open(self.edit_path)
873        self.fill_correct_values() # fill other fields with correct values
874        self.browser.getControl(name="form.course2").value = ['CERT1']
875        self.browser.getControl("Save").click()
876        self.assertTrue(
877            '1st and 2nd choice must be different' in self.browser.contents)
878        self.browser.getControl(name="form.course2").value = []
879        self.browser.getControl("Save").click()
880        self.assertTrue('Form has been saved' in self.browser.contents)
881        return
882
883    def test_final_submit(self):
884        # Make sure that a correctly filled form with passport picture
885        # can be submitted (only) after payment
886        self.login()
887        self.browser.getLink("Edit application record").click()
888        self.assertFalse('Final Submit' in self.browser.contents)
889        IWorkflowInfo(self.applicant).fireTransition('pay')
890        self.browser.open(self.edit_path)
891        self.assertTrue('Final Submit' in self.browser.contents)
892        self.fill_correct_values() # fill other fields with correct values
893        self.browser.getControl("Save").click()
894        self.browser.getControl("Final Submit").click()
895        # We forgot to upload a passport picture
896        self.assertTrue(
897            'No passport picture uploaded' in self.browser.contents)
898        # Create a pseudo image file and select it to be uploaded in form
899        pseudo_image = StringIO('I pretend to be a graphics file')
900        ctrl = self.browser.getControl(name='form.passport')
901        file_ctrl = ctrl.mech_control
902        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
903        self.browser.getControl("Final Submit").click() # (finally) submit form
904        # The picture has been uploaded but the form cannot be submitted
905        # since the passport confirmation box was not ticked
906        self.assertTrue(
907            'Passport picture confirmation box not ticked'
908            in self.browser.contents)
909        self.browser.getControl(name="confirm_passport").value = True
910        # If application period has expired and strict-deadline is set
911        # applicants do notsee edit button and can't open
912        # the edit form.
913        self.applicantscontainer.enddate = datetime.now(pytz.utc)
914        self.browser.open(self.view_path)
915        self.assertFalse(
916            'Edit application record' in self.browser.contents)
917        self.browser.open(self.edit_path)
918        self.assertTrue(
919            'form is locked' in self.browser.contents)
920        # We can either postpone the enddate ...
921        self.applicantscontainer.enddate = datetime.now(
922            pytz.utc) + timedelta(days=10)
923        self.browser.open(self.edit_path)
924        self.browser.getControl(name="confirm_passport").value = True
925        self.browser.getControl("Final Submit").click()
926        self.assertTrue(
927            'Application submitted' in self.browser.contents)
928        # ... or allow submission after deadline.
929        IWorkflowState(self.applicant).setState('paid')
930        self.applicant.locked = False
931        self.applicantscontainer.strict_deadline = False
932        self.browser.open(self.edit_path)
933        self.browser.getControl(name="confirm_passport").value = True
934        self.browser.getControl("Final Submit").click()
935        self.assertTrue(
936            'Application submitted' in self.browser.contents)
937        self.browser.goBack(count=1)
938        self.browser.getControl("Save").click()
939        # The form is locked.
940        self.assertTrue(self.applicant.locked)
941        self.assertTrue(
942            'The requested form is locked' in self.browser.contents)
943        self.browser.goBack(count=1)
944        self.browser.getControl("Final Submit").click()
945        self.assertTrue(
946            'The requested form is locked' in self.browser.contents)
947        return
948
949    def test_locking(self):
950        # Make sure that locked forms can't be submitted
951        self.login()
952        self.browser.open(self.edit_path)
953        self.fill_correct_values() # fill other fields with correct values
954        # Create a pseudo image file and select it to be uploaded in form
955        pseudo_image = StringIO('I pretend to be a graphics file')
956        ctrl = self.browser.getControl(name='form.passport')
957        file_ctrl = ctrl.mech_control
958        file_ctrl.add_file(pseudo_image, filename='myphoto.jpg')
959        self.browser.getControl("Save").click()
960        # Now we lock the form
961        self.applicant.locked = True
962        self.browser.open(self.edit_path)
963        self.assertEqual(self.browser.headers['Status'], '200 Ok')
964        self.assertTrue(
965            'The requested form is locked' in self.browser.contents)
966        return
967
968    def test_certificate_removed(self):
969        self.login()
970        self.browser.open(self.edit_path)
971        self.fill_correct_values()
972        self.browser.getControl("Save").click()
973        self.browser.open(self.view_path)
974        self.assertTrue(
975            'Unnamed Certificate' in self.browser.contents)
976        self.browser.open(self.edit_path)
977        self.assertTrue(
978            '<option selected="selected" value="CERT1">' in self.browser.contents)
979        # Now we remove the certificate
980        del self.app['faculties']['fac1']['dep1'].certificates['CERT1']
981        # The certificate is still shown in display mode
982        self.browser.open(self.view_path)
983        self.assertTrue(
984            'Unnamed Certificate' in self.browser.contents)
985        # The certificate is still selectable in edit mode so that it won't
986        # be automatically replaced by another (arbitrary) certificate
987        self.browser.open(self.edit_path)
988        self.assertTrue(
989            '<option selected="selected" value="CERT1">' in self.browser.contents)
990        # Consequently, the certificate is still shown after saving the form
991        self.browser.getControl("Save").click()
992        self.browser.open(self.view_path)
993        self.assertTrue(
994            'Unnamed Certificate' in self.browser.contents)
995        # Even if we add a new certificate the previous (removed)
996        # certificate is shown
997        certificate = createObject('waeup.Certificate')
998        certificate.code = 'CERT2'
999        certificate.title = 'New Certificate'
1000        certificate.application_category = 'basic'
1001        self.app['faculties']['fac1']['dep1'].certificates.addCertificate(
1002            certificate)
1003        self.browser.open(self.edit_path)
1004        self.assertTrue(
1005            '<option selected="selected" value="CERT1">'
1006            in self.browser.contents)
1007
1008class ApplicantRegisterTests(ApplicantsFullSetup):
1009    # Tests for applicant registration
1010
1011    layer = FunctionalLayer
1012
1013    def test_register_applicant_create(self):
1014        # An applicant can register himself.
1015        self.browser.open(self.container_path)
1016        self.browser.getLink("Register for application").click()
1017        # Fill the edit form with suitable values
1018        self.browser.getControl(name="form.firstname").value = 'Anna'
1019        self.browser.getControl(name="form.lastname").value = 'Kurios'
1020        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
1021        self.browser.getControl(name="form.phone.country").value = ['+234']
1022        self.browser.getControl(name="form.phone.area").value = '555'
1023        self.browser.getControl(name="form.phone.ext").value = '6666666'
1024        self.browser.getControl("Send login credentials").click()
1025        self.assertEqual(self.browser.url,
1026            self.container_path + '/registration_complete?email=xx%40yy.zz')
1027        # The new applicant can be found in the catalog via the email address
1028        cat = getUtility(ICatalog, name='applicants_catalog')
1029        results = list(
1030            cat.searchResults(email=('xx@yy.zz', 'xx@yy.zz')))
1031        applicant = results[0]
1032        self.assertEqual(applicant.lastname,'Kurios')
1033        # The application_id has been copied to the reg_number
1034        self.assertEqual(applicant.applicant_id, applicant.reg_number)
1035        # The applicant can be found in the catalog via the reg_number
1036        results = list(
1037            cat.searchResults(
1038            reg_number=(applicant.reg_number, applicant.reg_number)))
1039        self.assertEqual(applicant,results[0])
1040        return
1041
1042    def test_register_applicant_update(self):
1043        # We change the application mode and check if applicants
1044        # can find and update imported records instead of creating new records.
1045        # First we check what happens if record does not exist.
1046        self.applicantscontainer.mode = 'update'
1047        self.browser.open(self.container_path + '/register')
1048        self.browser.getControl(name="form.firstname").value = 'John'
1049        self.browser.getControl(name="form.reg_number").value = 'anynumber'
1050        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
1051        self.browser.getControl("Send login credentials").click()
1052        self.assertTrue('No application record found.'
1053            in self.browser.contents)
1054        # Even with the correct reg_number we can't register
1055        # because firstname attribute is not set.
1056        self.applicantscontainer.mode = 'update'
1057        self.browser.open(self.container_path + '/register')
1058        self.browser.getControl(name="form.firstname").value = 'John'
1059        self.browser.getControl(name="form.reg_number").value = '1234'
1060        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
1061        self.browser.getControl("Send login credentials").click()
1062        self.assertTrue('An error occurred.' in self.browser.contents)
1063        # Let's set this attribute manually
1064        # and try to register with a wrong name.
1065        self.applicant.firstname = u'John'
1066        self.browser.open(self.container_path + '/register')
1067        self.browser.getControl(name="form.firstname").value = 'Johnny'
1068        self.browser.getControl(name="form.reg_number").value = '1234'
1069        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
1070        self.browser.getControl("Send login credentials").click()
1071        # Anonymous is not informed that firstname verification failed.
1072        # It seems that the record doesn't exist.
1073        self.assertTrue('No application record found.'
1074            in self.browser.contents)
1075        # Even with the correct firstname we can't register if a
1076        # password has been set and used.
1077        IWorkflowState(self.applicant).setState('started')
1078        self.browser.getControl(name="form.firstname").value = 'John'
1079        self.browser.getControl(name="form.reg_number").value = '1234'
1080        self.browser.getControl("Send login credentials").click()
1081        self.assertTrue('Your password has already been set and used.'
1082            in self.browser.contents)
1083        #IUserAccount(
1084        #    self.app['applicants'][container_name_1][
1085        #    self.applicant.application_number]).context.password = None
1086        # Even without unsetting the password we can re-register if state
1087        # is 'initialized'
1088        IWorkflowState(self.applicant).setState('initialized')
1089        self.browser.open(self.container_path + '/register')
1090        # The firstname field, used for verification, is not case-sensitive.
1091        self.browser.getControl(name="form.firstname").value = 'jOhn'
1092        self.browser.getControl(name="form.reg_number").value = '1234'
1093        self.browser.getControl(name="form.email").value = 'new@yy.zz'
1094        self.browser.getControl("Send login credentials").click()
1095        # Yeah, we succeded ...
1096        self.assertTrue('Your registration was successful.'
1097            in self.browser.contents)
1098        # ... and  applicant can be found in the catalog via the email address
1099        cat = getUtility(ICatalog, name='applicants_catalog')
1100        results = list(
1101            cat.searchResults(
1102            email=('new@yy.zz', 'new@yy.zz')))
1103        self.assertEqual(self.applicant,results[0])
1104        return
1105
1106    def test_change_password_request(self):
1107        self.browser.open('http://localhost/app/changepw')
1108        self.browser.getControl(name="form.identifier").value = '1234'
1109        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
1110        self.browser.getControl("Send login credentials").click()
1111        self.assertTrue('No record found' in self.browser.contents)
1112        self.applicant.email = 'aa@aa.ng'
1113        # Update the catalog
1114        notify(grok.ObjectModifiedEvent(self.applicant))
1115        self.browser.open('http://localhost/app/changepw')
1116        self.browser.getControl(name="form.identifier").value = '1234'
1117        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
1118        self.browser.getControl("Send login credentials").click()
1119        self.assertTrue(
1120            'An email with your user name and password has been sent'
1121            in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.