source: main/waeup.ikoba/trunk/src/waeup/ikoba/customers/tests/test_browser.py @ 12092

Last change on this file since 12092 was 12091, checked in by Henrik Bettermann, 10 years ago

Add browser tests and fix.

  • Property svn:keywords set to Id
File size: 57.7 KB
Line 
1## $Id: test_browser.py 12091 2014-11-29 12:39:00Z henrik $
2##
3## Copyright (C) 2014 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 customer-related UI components.
20"""
21import shutil
22import tempfile
23import pytz
24import base64
25from datetime import datetime, timedelta, date
26from StringIO import StringIO
27import os
28import grok
29from zc.async.testing import wait_for_result
30from zope.event import notify
31from zope.component import createObject, queryUtility, getUtility
32from zope.component.hooks import setSite, clearSite
33from zope.catalog.interfaces import ICatalog
34from zope.security.interfaces import Unauthorized
35from zope.securitypolicy.interfaces import IPrincipalRoleManager
36from zope.testbrowser.testing import Browser
37from hurry.workflow.interfaces import IWorkflowInfo, IWorkflowState
38from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
39from waeup.ikoba.app import Company
40from waeup.ikoba.customers.interfaces import ICustomersUtils
41from waeup.ikoba.customers.customer import Customer
42from waeup.ikoba.interfaces import IUserAccount, IJobManager, APPROVED
43from waeup.ikoba.authentication import LocalRoleSetEvent
44from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
45from waeup.ikoba.documents.workflow import VERIFIED
46from waeup.ikoba.browser.tests.test_pdf import samples_dir
47
48PH_LEN = 15911  # Length of placeholder file
49
50SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
51SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
52SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
53
54def lookup_submit_value(name, value, browser):
55    """Find a button with a certain value."""
56    for num in range(0, 100):
57        try:
58            button = browser.getControl(name=name, index=num)
59            if button.value.endswith(value):
60                return button
61        except IndexError:
62            break
63    return None
64
65class CustomersFullSetup(FunctionalTestCase):
66    # A test case that only contains a setup and teardown
67    #
68    # Complete setup for customers handlings is rather complex and
69    # requires lots of things created before we can start. This is a
70    # setup that does all this, creates a company etc.
71    # so that we do not have to bother with that in different
72    # test cases.
73
74    layer = FunctionalLayer
75
76    def setUp(self):
77        super(CustomersFullSetup, self).setUp()
78
79        # Setup a sample site for each test
80        app = Company()
81        self.dc_root = tempfile.mkdtemp()
82        app['datacenter'].setStoragePath(self.dc_root)
83
84        # Prepopulate the ZODB...
85        self.getRootFolder()['app'] = app
86        # we add the site immediately after creation to the
87        # ZODB. Catalogs and other local utilities are not setup
88        # before that step.
89        self.app = self.getRootFolder()['app']
90        # Set site here. Some of the following setup code might need
91        # to access grok.getSite() and should get our new app then
92        setSite(app)
93
94        # Add customer with subobjects
95        customer = createObject('waeup.Customer')
96        customer.firstname = u'Anna'
97        customer.lastname = u'Tester'
98        customer.reg_number = u'123'
99        customer.sex = u'm'
100        customer.email = 'aa@aa.ng'
101        customer.phone = u'1234'
102        customer.date_of_birth = date(1981, 2, 4)
103        self.app['customers'].addCustomer(customer)
104        self.customer_id = customer.customer_id
105        self.customer = self.app['customers'][self.customer_id]
106        document = createObject('waeup.CustomerSampleDocument')
107        document.title = u'My first document'
108        self.customer['documents'].addDocument(document)
109        application = createObject('waeup.SampleApplication')
110        application.title = u'My first application'
111        self.customer['applications'].addApplication(application)
112
113        # Set password
114        IUserAccount(
115            self.app['customers'][self.customer_id]).setPassword('cpwd')
116
117        self.login_path = 'http://localhost/app/login'
118        self.container_path = 'http://localhost/app/customers'
119        self.manage_container_path = self.container_path + '/@@manage'
120        self.add_customer_path = self.container_path + '/addcustomer'
121        self.customer_path = self.container_path + '/' + self.customer_id
122        self.manage_customer_path = self.customer_path + '/manage_base'
123        self.trigtrans_path = self.customer_path + '/trigtrans'
124        self.history_path = self.customer_path + '/history'
125        self.documents_path = self.customer_path + '/documents'
126        self.applications_path = self.customer_path + '/applications'
127
128        self.app['configuration'].carry_over = True
129        configuration = createObject('waeup.SessionConfiguration')
130        self.app['configuration'].addSessionConfiguration(configuration)
131
132        # Update the catalog
133        notify(grok.ObjectModifiedEvent(self.customer))
134
135        # Put the prepopulated site into test ZODB and prepare test
136        # browser
137        self.browser = Browser()
138        self.browser.handleErrors = False
139
140    def tearDown(self):
141        super(CustomersFullSetup, self).tearDown()
142        clearSite()
143        shutil.rmtree(self.dc_root)
144
145
146
147class CustomersContainerUITests(CustomersFullSetup):
148    # Tests for CustomersContainer class views and pages
149
150    layer = FunctionalLayer
151
152    def test_anonymous_access(self):
153        # Anonymous users can't access customers containers
154        self.assertRaises(
155            Unauthorized, self.browser.open, self.container_path)
156        self.assertRaises(
157            Unauthorized, self.browser.open, self.manage_container_path)
158        return
159
160    def test_manage_access(self):
161        # Managers can access the view page of customers
162        # containers and can perform actions
163        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
164        self.browser.open(self.container_path)
165        self.assertEqual(self.browser.headers['Status'], '200 Ok')
166        self.assertEqual(self.browser.url, self.container_path)
167        self.browser.getLink("Manage customer section").click()
168        self.assertEqual(self.browser.headers['Status'], '200 Ok')
169        self.assertEqual(self.browser.url, self.manage_container_path)
170        return
171
172    def test_add_search_delete_customers(self):
173        # Managers can add search and remove customers
174        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
175        self.browser.open(self.manage_container_path)
176        self.browser.getLink("Add customer").click()
177        self.assertEqual(self.browser.headers['Status'], '200 Ok')
178        self.assertEqual(self.browser.url, self.add_customer_path)
179        self.browser.getControl(name="form.firstname").value = 'Bob'
180        self.browser.getControl(name="form.lastname").value = 'Tester'
181        self.browser.getControl(name="form.reg_number").value = '123'
182        self.browser.getControl("Create customer record").click()
183        self.assertTrue('Registration number exists already'
184            in self.browser.contents)
185        self.browser.getControl(name="form.reg_number").value = '1234'
186        self.browser.getControl("Create customer record").click()
187        self.assertTrue('Customer record created' in self.browser.contents)
188
189        # Registration must be unique
190        self.browser.getLink("Manage").click()
191        self.browser.getControl(name="form.reg_number").value = '123'
192        self.browser.getControl("Save").click()
193        self.assertMatches('...Registration number exists...',
194                           self.browser.contents)
195
196        # We can find a customer with a certain customer_id
197        self.browser.open(self.container_path)
198        self.browser.getControl("Find customer(s)").click()
199        self.assertTrue('Empty search string' in self.browser.contents)
200        self.browser.getControl(name="searchtype").value = ['customer_id']
201        self.browser.getControl(name="searchterm").value = self.customer_id
202        self.browser.getControl("Find customer(s)").click()
203        self.assertTrue('Anna Tester' in self.browser.contents)
204
205        # We can find a customer by searching for all kind of name parts
206        self.browser.open(self.manage_container_path)
207        self.browser.getControl("Find customer(s)").click()
208        self.assertTrue('Empty search string' in self.browser.contents)
209        self.browser.getControl(name="searchtype").value = ['fullname']
210        self.browser.getControl(name="searchterm").value = 'Anna Tester'
211        self.browser.getControl("Find customer(s)").click()
212        self.assertTrue('Anna Tester' in self.browser.contents)
213        self.browser.open(self.manage_container_path)
214        self.browser.getControl(name="searchtype").value = ['fullname']
215        self.browser.getControl(name="searchterm").value = 'Anna'
216        self.browser.getControl("Find customer(s)").click()
217        self.assertTrue('Anna Tester' in self.browser.contents)
218        self.browser.open(self.manage_container_path)
219        self.browser.getControl(name="searchtype").value = ['fullname']
220        self.browser.getControl(name="searchterm").value = 'Tester'
221        self.browser.getControl("Find customer(s)").click()
222        self.assertTrue('Anna Tester' in self.browser.contents)
223        self.browser.open(self.manage_container_path)
224        self.browser.getControl(name="searchtype").value = ['fullname']
225        self.browser.getControl(name="searchterm").value = 'An'
226        self.browser.getControl("Find customer(s)").click()
227        self.assertFalse('Anna Tester' in self.browser.contents)
228        self.browser.open(self.manage_container_path)
229        self.browser.getControl(name="searchtype").value = ['fullname']
230        self.browser.getControl(name="searchterm").value = 'An*'
231        self.browser.getControl("Find customer(s)").click()
232        self.assertTrue('Anna Tester' in self.browser.contents)
233        self.browser.open(self.manage_container_path)
234        self.browser.getControl(name="searchtype").value = ['fullname']
235        self.browser.getControl(name="searchterm").value = 'tester'
236        self.browser.getControl("Find customer(s)").click()
237        self.assertTrue('Anna Tester' in self.browser.contents)
238        self.browser.open(self.manage_container_path)
239        self.browser.getControl(name="searchtype").value = ['fullname']
240        self.browser.getControl(name="searchterm").value = 'Tester Ana'
241        self.browser.getControl("Find customer(s)").click()
242        self.assertFalse('Anna Tester' in self.browser.contents)
243        self.browser.open(self.manage_container_path)
244        self.browser.getControl(name="searchtype").value = ['fullname']
245        self.browser.getControl(name="searchterm").value = 'Tester Anna'
246        self.browser.getControl("Find customer(s)").click()
247        self.assertTrue('Anna Tester' in self.browser.contents)
248        # The old searchterm will be used again
249        self.browser.getControl("Find customer(s)").click()
250        self.assertTrue('Anna Tester' in self.browser.contents)
251
252        # We can find suspended customers
253        self.customer.suspended = True
254        notify(grok.ObjectModifiedEvent(self.customer))
255        self.browser.open(self.manage_container_path)
256        self.browser.getControl(name="searchtype").value = ['suspended']
257        self.browser.getControl("Find customer(s)").click()
258        self.assertTrue('Anna Tester' in self.browser.contents)
259
260        # Removed customers won't be found
261        ctrl = self.browser.getControl(name='entries')
262        ctrl.getControl(value=self.customer_id).selected = True
263        self.browser.getControl("Remove selected", index=0).click()
264        self.assertTrue('Successfully removed' in self.browser.contents)
265        self.browser.getControl(name="searchtype").value = ['customer_id']
266        self.browser.getControl(name="searchterm").value = self.customer_id
267        self.browser.getControl("Find customer(s)").click()
268        self.assertTrue('No customer found' in self.browser.contents)
269        return
270
271class OfficerUITests(CustomersFullSetup):
272    # Tests for Customer class views and pages
273
274    def test_basic_auth(self):
275        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
276        self.browser.open('http://localhost/app')
277        self.browser.getLink("Logout").click()
278        self.assertTrue('You have been logged out' in self.browser.contents)
279        # But we are still logged in since we've used basic authentication here.
280        # Wikipedia says: Existing browsers retain authentication information
281        # until the tab or browser is closed or the user clears the history.
282        # HTTP does not provide a method for a server to direct clients to
283        # discard these cached credentials. This means that there is no
284        # effective way for a server to "log out" the user without closing
285        # the browser. This is a significant defect that requires browser
286        # manufacturers to support a "logout" user interface element ...
287        self.assertTrue('Manager' in self.browser.contents)
288
289    def test_basic_auth_base64(self):
290        auth_token = base64.b64encode('mgr:mgrpw')
291        self.browser.addHeader('Authorization', 'Basic %s' % auth_token)
292        self.browser.open(self.manage_container_path)
293        self.assertEqual(self.browser.headers['Status'], '200 Ok')
294
295    def test_manage_access(self):
296        # Managers can access the pages of customers
297        # and can perform actions
298        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
299        self.browser.open(self.customer_path)
300        self.assertEqual(self.browser.headers['Status'], '200 Ok')
301        self.assertEqual(self.browser.url, self.customer_path)
302        self.browser.getLink("Transition").click()
303        self.assertEqual(self.browser.headers['Status'], '200 Ok')
304        # Managers can trigger transitions
305        self.browser.getControl(name="transition").value = ['start']
306        self.browser.getControl("Save").click()
307        # Managers can edit base
308        self.browser.open(self.customer_path)
309        self.browser.getLink("Manage").click()
310        self.assertEqual(self.browser.url, self.manage_customer_path)
311        self.assertEqual(self.browser.headers['Status'], '200 Ok')
312        self.browser.getControl(name="form.firstname").value = 'John'
313        self.browser.getControl(name="form.lastname").value = 'Tester'
314        self.browser.getControl(name="form.reg_number").value = '345'
315        self.browser.getControl(name="password").value = 'secret'
316        self.browser.getControl(name="control_password").value = 'secret'
317        self.browser.getControl("Save").click()
318        self.assertMatches('...Form has been saved...',
319                           self.browser.contents)
320
321    def test_manage_contact_customer(self):
322        # Managers can contact customer
323        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
324        self.customer.email = None
325        self.browser.open(self.customer_path)
326        self.browser.getLink("Send email").click()
327        self.browser.getControl(name="form.subject").value = 'Important subject'
328        self.browser.getControl(name="form.body").value = 'Hello!'
329        self.browser.getControl("Send message now").click()
330        self.assertTrue('An smtp server error occurred' in self.browser.contents)
331        self.customer.email = 'xx@yy.zz'
332        self.browser.getControl("Send message now").click()
333        self.assertTrue('Your message has been sent' in self.browser.contents)
334        return
335
336    def test_manage_upload_passport(self):
337        # Managers can upload a file via the CustomerBaseManageFormPage
338        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
339        self.browser.open(self.manage_customer_path)
340        image = open(SAMPLE_IMAGE_BMP, 'rb')
341        ctrl = self.browser.getControl(name='passportmanageupload')
342        file_ctrl = ctrl.mech_control
343        file_ctrl.add_file(image, filename='my_photo.bmp')
344        self.browser.getControl(
345            name='upload_passportmanageupload').click()
346        self.assertTrue('jpg file extension expected'
347            in self.browser.contents)
348        ctrl = self.browser.getControl(name='passportmanageupload')
349        file_ctrl = ctrl.mech_control
350        image = open(SAMPLE_IMAGE, 'rb')
351        file_ctrl.add_file(image, filename='my_photo.jpg')
352        self.browser.getControl(
353            name='upload_passportmanageupload').click()
354        self.assertTrue(
355            'src="http://localhost/app/customers/K1000000/passport.jpg"'
356            in self.browser.contents)
357        # We remove the passport file again
358        self.browser.open(self.manage_customer_path)
359        self.browser.getControl('Delete').click()
360        self.assertTrue('passport.jpg deleted' in self.browser.contents)
361
362
363    def test_manage_workflow(self):
364        # Managers can pass through the whole workflow
365        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
366        customer = self.app['customers'][self.customer_id]
367        self.browser.open(self.trigtrans_path)
368        self.browser.getControl(name="transition").value = ['start']
369        self.browser.getControl("Save").click()
370        self.browser.getControl(name="transition").value = ['request']
371        self.browser.getControl("Save").click()
372        self.browser.getControl(name="transition").value = ['reject']
373        self.browser.getControl("Save").click()
374        self.browser.getControl(name="transition").value = ['request']
375        self.browser.getControl("Save").click()
376        self.browser.getControl(name="transition").value = ['approve']
377        self.browser.getControl("Save").click()
378        self.browser.getControl(name="transition").value = ['reset1']
379        self.browser.getControl("Save").click()
380        return
381
382    def test_manage_import(self):
383        # Managers can import customer data files
384        datacenter_path = 'http://localhost/app/datacenter'
385        # Prepare a csv file for customers
386        open('customers.csv', 'wb').write(
387"""firstname,lastname,reg_number,date_of_birth,email,phone,sex,password
388Aaren,Pieri,1,1990-01-02,aa@aa.ng,1234,m,mypwd1
389Claus,Finau,2,1990-01-03,aa@aa.ng,1234,m,mypwd1
390Brit,Berson,2,1990-01-04,aa@aa.ng,1234,m,mypwd1
391""")
392        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
393        self.browser.open(datacenter_path)
394        self.browser.getLink('Upload data').click()
395        filecontents = StringIO(open('customers.csv', 'rb').read())
396        filewidget = self.browser.getControl(name='uploadfile:file')
397        filewidget.add_file(filecontents, 'text/plain', 'customers.csv')
398        self.browser.getControl(name='SUBMIT').click()
399        self.browser.getLink('Process data').click()
400        button = lookup_submit_value(
401            'select', 'customers_zope.mgr.csv', self.browser)
402        button.click()
403        importerselect = self.browser.getControl(name='importer')
404        modeselect = self.browser.getControl(name='mode')
405        importerselect.getControl('Customer Processor').selected = True
406        modeselect.getControl(value='create').selected = True
407        self.browser.getControl('Proceed to step 3').click()
408        self.assertTrue('Header fields OK' in self.browser.contents)
409        self.browser.getControl('Perform import').click()
410        self.assertTrue('Processing of 1 rows failed' in self.browser.contents)
411        self.assertTrue('Successfully processed 2 rows' in self.browser.contents)
412        self.assertTrue('Batch processing finished' in self.browser.contents)
413
414        # The customers are properly indexed and we can
415        # thus find a customer in  the department
416        self.browser.open(self.manage_container_path)
417        # We can search for a new customer by name ...
418        self.browser.getControl(name="searchtype").value = ['fullname']
419        self.browser.getControl(name="searchterm").value = 'Claus'
420        self.browser.getControl("Find customer(s)").click()
421        self.assertTrue('Claus Finau' in self.browser.contents)
422        # ... and check if the imported password has been properly set
423        ctrl = self.browser.getControl(name='entries')
424        value = ctrl.options[0]
425        claus = self.app['customers'][value]
426        self.assertTrue(IUserAccount(claus).checkPassword('mypwd1'))
427        return
428
429    def test_activate_deactivate_buttons(self):
430        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
431        self.browser.open(self.customer_path)
432        self.browser.getLink("Deactivate").click()
433        self.assertTrue(
434            'Customer account has been deactivated.' in self.browser.contents)
435        self.assertTrue(
436            'Base Data (account deactivated)' in self.browser.contents)
437        self.assertTrue(self.customer.suspended)
438        self.browser.getLink("Activate").click()
439        self.assertTrue(
440            'Customer account has been activated.' in self.browser.contents)
441        self.assertFalse(
442            'Base Data (account deactivated)' in self.browser.contents)
443        self.assertFalse(self.customer.suspended)
444        # History messages have been added ...
445        self.browser.getLink("History").click()
446        self.assertTrue(
447            'Customer account deactivated by Manager<br />' in self.browser.contents)
448        self.assertTrue(
449            'Customer account activated by Manager<br />' in self.browser.contents)
450        # ... and actions have been logged.
451        logfile = os.path.join(
452            self.app['datacenter'].storage, 'logs', 'customers.log')
453        logcontent = open(logfile).read()
454        self.assertTrue('zope.mgr - customers.browser.CustomerDeactivatePage - '
455                        'K1000000 - account deactivated' in logcontent)
456        self.assertTrue('zope.mgr - customers.browser.CustomerActivatePage - '
457                        'K1000000 - account activated' in logcontent)
458
459
460    def test_login_as_customer(self):
461        # CustomerImpersonators can login as customer
462        # Create clearance officer
463        self.app['users'].addUser('mrofficer', 'mrofficersecret')
464        self.app['users']['mrofficer'].email = 'mrofficer@foo.ng'
465        self.app['users']['mrofficer'].title = 'Harry Actor'
466        prmglobal = IPrincipalRoleManager(self.app)
467        prmglobal.assignRoleToPrincipal('waeup.CustomerImpersonator', 'mrofficer')
468        prmglobal.assignRoleToPrincipal('waeup.CustomersManager', 'mrofficer')
469        # Login as customer impersonator
470        self.browser.open(self.login_path)
471        self.browser.getControl(name="form.login").value = 'mrofficer'
472        self.browser.getControl(name="form.password").value = 'mrofficersecret'
473        self.browser.getControl("Login").click()
474        self.assertMatches('...You logged in...', self.browser.contents)
475        self.browser.open(self.customer_path)
476        self.browser.getLink("Login as").click()
477        self.browser.getControl("Set password now").click()
478        temp_password = self.browser.getControl(name='form.password').value
479        self.browser.getControl("Login now").click()
480        self.assertMatches(
481            '...You successfully logged in as...', self.browser.contents)
482        # We are logged in as customer and can see the 'My Data' tab
483        self.assertMatches(
484            '...<a href="#" class="dropdown-toggle" data-toggle="dropdown">...',
485            self.browser.contents)
486        self.assertMatches(
487            '...My Data...',
488            self.browser.contents)
489        self.browser.getLink("Logout").click()
490        # The customer can't login with the original password ...
491        self.browser.open(self.login_path)
492        self.browser.getControl(name="form.login").value = self.customer_id
493        self.browser.getControl(name="form.password").value = 'cpwd'
494        self.browser.getControl("Login").click()
495        self.assertMatches(
496            '...Your account has been temporarily deactivated...',
497            self.browser.contents)
498        # ... but with the temporary password
499        self.browser.open(self.login_path)
500        self.browser.getControl(name="form.login").value = self.customer_id
501        self.browser.getControl(name="form.password").value = temp_password
502        self.browser.getControl("Login").click()
503        self.assertMatches('...You logged in...', self.browser.contents)
504        # Creation of temp_password is properly logged
505        logfile = os.path.join(
506            self.app['datacenter'].storage, 'logs', 'customers.log')
507        logcontent = open(logfile).read()
508        self.assertTrue(
509            'mrofficer - customers.browser.LoginAsCustomerStep1 - K1000000 - '
510            'temp_password generated: %s' % temp_password in logcontent)
511
512
513class CustomerUITests(CustomersFullSetup):
514    # Tests for Customer class views and pages
515
516    def test_customer_change_password(self):
517        # Customers can change the password
518        self.customer.personal_updated = datetime.utcnow()
519        self.browser.open(self.login_path)
520        self.browser.getControl(name="form.login").value = self.customer_id
521        self.browser.getControl(name="form.password").value = 'cpwd'
522        self.browser.getControl("Login").click()
523        self.assertEqual(self.browser.url, self.customer_path)
524        self.assertTrue('You logged in' in self.browser.contents)
525        # Change password
526        self.browser.getLink("Change password").click()
527        self.browser.getControl(name="change_password").value = 'pw'
528        self.browser.getControl(
529            name="change_password_repeat").value = 'pw'
530        self.browser.getControl("Save").click()
531        self.assertTrue('Password must have at least' in self.browser.contents)
532        self.browser.getControl(name="change_password").value = 'new_password'
533        self.browser.getControl(
534            name="change_password_repeat").value = 'new_passssword'
535        self.browser.getControl("Save").click()
536        self.assertTrue('Passwords do not match' in self.browser.contents)
537        self.browser.getControl(name="change_password").value = 'new_password'
538        self.browser.getControl(
539            name="change_password_repeat").value = 'new_password'
540        self.browser.getControl("Save").click()
541        self.assertTrue('Password changed' in self.browser.contents)
542        # We are still logged in. Changing the password hasn't thrown us out.
543        self.browser.getLink("Base Data").click()
544        self.assertEqual(self.browser.url, self.customer_path)
545        # We can logout
546        self.browser.getLink("Logout").click()
547        self.assertTrue('You have been logged out' in self.browser.contents)
548        self.assertEqual(self.browser.url, 'http://localhost/app/index')
549        # We can login again with the new password
550        self.browser.getLink("Login").click()
551        self.browser.open(self.login_path)
552        self.browser.getControl(name="form.login").value = self.customer_id
553        self.browser.getControl(name="form.password").value = 'new_password'
554        self.browser.getControl("Login").click()
555        self.assertEqual(self.browser.url, self.customer_path)
556        self.assertTrue('You logged in' in self.browser.contents)
557        return
558
559    def test_customer_upload_passport(self):
560        # Customer cant login if their password is not set
561        IWorkflowInfo(self.customer).fireTransition('start')
562        self.browser.open(self.login_path)
563        self.browser.getControl(name="form.login").value = self.customer_id
564        self.browser.getControl(name="form.password").value = 'cpwd'
565        self.browser.getControl("Login").click()
566        self.assertMatches(
567            '...You logged in...', self.browser.contents)
568        # Admitted customer can upload a passport picture
569        self.browser.getLink("Change portrait").click()
570        ctrl = self.browser.getControl(name='passporteditupload')
571        file_obj = open(SAMPLE_IMAGE, 'rb')
572        file_ctrl = ctrl.mech_control
573        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
574        self.browser.getControl(
575            name='upload_passporteditupload').click()
576        self.assertTrue(
577            'src="http://localhost/app/customers/K1000000/passport.jpg"'
578            in self.browser.contents)
579
580    def test_customer_baseedit(self):
581        # Customers can change the password
582        self.customer.personal_updated = datetime.utcnow()
583        self.browser.open(self.login_path)
584        self.browser.getControl(name="form.login").value = self.customer_id
585        self.browser.getControl(name="form.password").value = 'cpwd'
586        self.browser.getControl("Login").click()
587        self.assertEqual(self.browser.url, self.customer_path)
588        self.assertTrue('You logged in' in self.browser.contents)
589        self.browser.getLink("Edit").click()
590        self.browser.getControl(name="form.email").value = 'new_email@aa.ng'
591        self.browser.getControl("Save").click()
592        self.assertMatches('...Form has been saved...',
593                           self.browser.contents)
594        # Customer can view history
595        self.browser.getLink("History").click()
596        self.assertMatches('...Customer record created by system...',
597            self.browser.contents)
598
599    def test_customer_login(self):
600        # Customer cant login if their password is not set
601        self.customer.password = None
602        self.browser.open(self.login_path)
603        self.browser.getControl(name="form.login").value = self.customer_id
604        self.browser.getControl(name="form.password").value = 'cpwd'
605        self.browser.getControl("Login").click()
606        self.assertTrue(
607            'You entered invalid credentials.' in self.browser.contents)
608        # We set the password again
609        IUserAccount(
610            self.app['customers'][self.customer_id]).setPassword('cpwd')
611        # Customers can't login if their account is suspended/deactivated
612        self.customer.suspended = True
613        self.browser.open(self.login_path)
614        self.browser.getControl(name="form.login").value = self.customer_id
615        self.browser.getControl(name="form.password").value = 'cpwd'
616        self.browser.getControl("Login").click()
617        self.assertMatches(
618            '...<div class="alert alert-warning">'
619            'Your account has been deactivated.</div>...', self.browser.contents)
620        # If suspended_comment is set this message will be flashed instead
621        self.customer.suspended_comment = u'Aetsch baetsch!'
622        self.browser.getControl(name="form.login").value = self.customer_id
623        self.browser.getControl(name="form.password").value = 'cpwd'
624        self.browser.getControl("Login").click()
625        self.assertMatches(
626            '...<div class="alert alert-warning">Aetsch baetsch!</div>...',
627            self.browser.contents)
628        self.customer.suspended = False
629        # Customers can't login if a temporary password has been set and
630        # is not expired
631        self.app['customers'][self.customer_id].setTempPassword(
632            'anybody', 'temp_cpwd')
633        self.browser.open(self.login_path)
634        self.browser.getControl(name="form.login").value = self.customer_id
635        self.browser.getControl(name="form.password").value = 'cpwd'
636        self.browser.getControl("Login").click()
637        self.assertMatches(
638            '...Your account has been temporarily deactivated...',
639            self.browser.contents)
640        # The customer can login with the temporary password
641        self.browser.open(self.login_path)
642        self.browser.getControl(name="form.login").value = self.customer_id
643        self.browser.getControl(name="form.password").value = 'temp_cpwd'
644        self.browser.getControl("Login").click()
645        self.assertMatches(
646            '...You logged in...', self.browser.contents)
647        # Customer can view the base data
648        self.browser.open(self.customer_path)
649        self.assertEqual(self.browser.headers['Status'], '200 Ok')
650        self.assertEqual(self.browser.url, self.customer_path)
651        # When the password expires ...
652        delta = timedelta(minutes=11)
653        self.app['customers'][self.customer_id].temp_password[
654            'timestamp'] = datetime.utcnow() - delta
655        self.app['customers'][self.customer_id]._p_changed = True
656        # ... the customer will be automatically logged out
657        self.assertRaises(
658            Unauthorized, self.browser.open, self.customer_path)
659        # Then the customer can login with the original password
660        self.browser.open(self.login_path)
661        self.browser.getControl(name="form.login").value = self.customer_id
662        self.browser.getControl(name="form.password").value = 'cpwd'
663        self.browser.getControl("Login").click()
664        self.assertMatches(
665            '...You logged in...', self.browser.contents)
666
667    def test_change_password_request(self):
668        self.browser.open('http://localhost/app/changepw')
669        self.browser.getControl(name="form.identifier").value = '123'
670        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
671        self.browser.getControl("Send login credentials").click()
672        self.assertTrue('An email with' in self.browser.contents)
673
674class CustomerRegistrationTests(CustomersFullSetup):
675    # Tests for customer registration
676
677    layer = FunctionalLayer
678
679    def test_request_pw(self):
680        # Customer with wrong number can't be found.
681        self.browser.open('http://localhost/app/requestpw')
682        self.browser.getControl(name="form.firstname").value = 'Anna'
683        self.browser.getControl(name="form.number").value = 'anynumber'
684        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
685        self.browser.getControl("Send login credentials").click()
686        self.assertTrue('No customer record found.'
687            in self.browser.contents)
688        # Anonymous is not informed that firstname verification failed.
689        # It seems that the record doesn't exist.
690        self.browser.open('http://localhost/app/requestpw')
691        self.browser.getControl(name="form.firstname").value = 'Johnny'
692        self.browser.getControl(name="form.number").value = '123'
693        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
694        self.browser.getControl("Send login credentials").click()
695        self.assertTrue('No customer record found.'
696            in self.browser.contents)
697        # Even with the correct firstname we can't register if a
698        # password has been set and used.
699        self.browser.getControl(name="form.firstname").value = 'Anna'
700        self.browser.getControl(name="form.number").value = '123'
701        self.browser.getControl("Send login credentials").click()
702        self.assertTrue('Your password has already been set and used.'
703            in self.browser.contents)
704        self.browser.open('http://localhost/app/requestpw')
705        self.app['customers'][self.customer_id].password = None
706        # The firstname field, used for verification, is not case-sensitive.
707        self.browser.getControl(name="form.firstname").value = 'aNNa'
708        self.browser.getControl(name="form.number").value = '123'
709        self.browser.getControl(name="form.email").value = 'new@yy.zz'
710        self.browser.getControl("Send login credentials").click()
711        # Yeah, we succeded ...
712        self.assertTrue('Your request was successful.'
713            in self.browser.contents)
714        # ... and  customer can be found in the catalog via the email address
715        cat = queryUtility(ICatalog, name='customers_catalog')
716        results = list(
717            cat.searchResults(
718            email=('new@yy.zz', 'new@yy.zz')))
719        self.assertEqual(self.customer,results[0])
720        logfile = os.path.join(
721            self.app['datacenter'].storage, 'logs', 'main.log')
722        logcontent = open(logfile).read()
723        self.assertTrue('zope.anybody - customers.browser.CustomerRequestPasswordPage - '
724                        '123 (K1000000) - new@yy.zz' in logcontent)
725        return
726
727    def test_create_account(self):
728        # Customer with wrong number can't be found.
729        self.browser.open('http://localhost/app/createaccount')
730        self.browser.getControl(name="form.firstname").value = 'Ruben'
731        self.browser.getControl(name="form.lastname").value = 'Gonzales'
732        self.browser.getControl(name="form.email").value = 'newcustomer@xx.zz'
733        self.browser.getControl("Send login credentials").click()
734        self.assertTrue('Your request was successful.'
735            in self.browser.contents)
736        # ... and  customer can be found in the catalog via the email address
737        cat = queryUtility(ICatalog, name='customers_catalog')
738        results = list(
739            cat.searchResults(
740            email=('newcustomer@xx.zz', 'newcustomer@xx.zz')))
741        self.assertEqual(self.app['customers']['K1000001'], results[0])
742        self.assertEqual(self.app['customers']['K1000001'].firstname, 'Ruben')
743        self.assertEqual(self.app['customers']['K1000001'].lastname, 'Gonzales')
744        logfile = os.path.join(
745            self.app['datacenter'].storage, 'logs', 'main.log')
746        logcontent = open(logfile).read()
747        self.assertTrue('zope.anybody - customers.browser.CustomerCreateAccountPage - '
748                        'K1000001 - newcustomer@xx.zz' in logcontent)
749        return
750
751class CustomerDataExportTests(CustomersFullSetup, FunctionalAsyncTestCase):
752    # Tests for CustomersContainer class views and pages
753
754    layer = FunctionalLayer
755
756    def wait_for_export_job_completed(self):
757        # helper function waiting until the current export job is completed
758        manager = getUtility(IJobManager)
759        job_id = self.app['datacenter'].running_exports[0][0]
760        job = manager.get(job_id)
761        wait_for_result(job)
762        return job_id
763
764    def test_datacenter_export(self):
765        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
766        self.browser.open('http://localhost/app/datacenter/@@export')
767        self.browser.getControl(name="exporter").value = ['customers']
768        self.browser.getControl("Create CSV file").click()
769
770        # When the job is finished and we reload the page...
771        job_id = self.wait_for_export_job_completed()
772        # ... the csv file can be downloaded ...
773        self.browser.open('http://localhost/app/datacenter/@@export')
774        self.browser.getLink("Download").click()
775        self.assertEqual(self.browser.headers['content-type'],
776            'text/csv; charset=UTF-8')
777        self.assertTrue(
778            'filename="WAeUP.Ikoba_customers_%s.csv' % job_id in
779            self.browser.headers['content-disposition'])
780        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
781        job_id = self.app['datacenter'].running_exports[0][0]
782        # ... and discarded
783        self.browser.open('http://localhost/app/datacenter/@@export')
784        self.browser.getControl("Discard").click()
785        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
786        # Creation, downloading and discarding is logged
787        logfile = os.path.join(
788            self.app['datacenter'].storage, 'logs', 'datacenter.log')
789        logcontent = open(logfile).read()
790        self.assertTrue(
791            'zope.mgr - browser.pages.ExportCSVPage - exported: '
792            'customers, job_id=%s'
793            % job_id in logcontent
794            )
795        self.assertTrue(
796            'zope.mgr - browser.pages.ExportCSVView - downloaded: '
797            'WAeUP.Ikoba_customers_%s.csv, job_id=%s'
798            % (job_id, job_id) in logcontent
799            )
800        self.assertTrue(
801            'zope.mgr - browser.pages.ExportCSVPage - discarded: '
802            'job_id=%s' % job_id in logcontent
803            )
804
805
806class DocumentUITests(CustomersFullSetup):
807    # Tests for CustomerSampleDocument relates views and pages
808
809    def test_manage_document(self):
810        # Managers can access the pages of customer documentsconter
811        # and can perform actions
812        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
813        self.browser.open(self.customer_path)
814        self.assertEqual(self.browser.headers['Status'], '200 Ok')
815        self.assertEqual(self.browser.url, self.customer_path)
816        self.browser.open(self.customer_path)
817        self.browser.getLink("Documents").click()
818        self.browser.getLink("Add document").click()
819        self.browser.getControl(name="doctype").value = ['CustomerPDFDocument']
820        self.browser.getControl("Create document").click()
821        self.assertTrue('PDF Document created.' in self.browser.contents)
822        document = self.customer['documents']['d102']
823
824        # Document can be edited
825        self.browser.getLink("d102").click()
826        self.browser.getLink("Manage").click()
827        self.browser.getControl(name="form.title").value = 'My second doc'
828        self.browser.getControl("Save").click()
829        self.assertTrue('Form has been saved.' in self.browser.contents)
830        self.browser.getLink("View").click()
831        self.assertEqual(self.browser.url, self.documents_path + '/d102/index')
832
833        # Transitions can be performed
834        self.browser.getLink("Transition").click()
835        self.browser.getControl(name="transition").value = ['submit']
836        self.browser.getControl("Save").click()
837        self.browser.getControl(name="transition").value = ['verify']
838        self.browser.getControl("Save").click()
839        self.assertEqual(document.state, 'verified')
840
841        # Documents can be removed
842        self.browser.getLink("Documents").click()
843        ctrl = self.browser.getControl(name='val_id')
844        ctrl.getControl(value=document.document_id).selected = True
845        self.browser.getControl("Remove selected", index=0).click()
846        self.assertTrue('Successfully removed' in self.browser.contents)
847
848        # All actions are being logged
849        logfile = os.path.join(
850            self.app['datacenter'].storage, 'logs', 'customers.log')
851        logcontent = open(logfile).read()
852
853        self.assertTrue(
854            'INFO - zope.mgr - customers.browser.DocumentManageFormPage '
855            '- K1000000 - saved d102: title'
856            in logcontent)
857        self.assertTrue(
858            'INFO - zope.mgr - customers.browser.DocumentAddFormPage '
859            '- K1000000 - added: PDF Document %s'
860            % document.document_id in logcontent)
861        self.assertTrue(
862            'INFO - zope.mgr - customers.browser.DocumentsManageFormPage '
863            '- K1000000 - removed: %s'
864            % document.document_id in logcontent)
865
866    def test_edit_sample_document(self):
867        # Customers can manage documents under certain conditions
868        self.browser.open(self.login_path)
869        self.browser.getControl(name="form.login").value = self.customer_id
870        self.browser.getControl(name="form.password").value = 'cpwd'
871        self.browser.getControl("Login").click()
872        self.assertMatches(
873            '...You logged in...', self.browser.contents)
874        self.browser.getLink("Documents").click()
875        self.browser.getLink("Add document").click()
876        self.browser.getControl(name="doctype").value = ['CustomerSampleDocument']
877        self.browser.getControl("Create document").click()
878        self.assertTrue('Sample Document created.' in self.browser.contents)
879        document = self.customer['documents']['d102']
880
881        # Document can be edited ...
882        self.browser.getLink("d102").click()
883        self.browser.open(self.documents_path + '/d102/edit')
884        #self.browser.getLink("Edit").click()
885        self.assertTrue('The requested form is locked' in self.browser.contents)
886        # Customer is in wrong state
887        IWorkflowState(self.customer).setState(APPROVED)
888        self.browser.open(self.documents_path + '/d102/edit')
889        self.browser.getControl(name="form.title").value = 'My second doc'
890        self.browser.getControl("Save").click()
891        self.assertEqual(document.title, 'My second doc')
892        self.assertTrue('Form has been saved.' in self.browser.contents)
893        self.browser.getLink("View").click()
894        self.assertEqual(self.browser.url, self.documents_path + '/d102/index')
895        # Costumer can upload a document.
896        self.browser.getLink("Edit").click()
897        ctrl = self.browser.getControl(name='samplescaneditupload')
898        file_obj = open(SAMPLE_IMAGE, 'rb')
899        file_ctrl = ctrl.mech_control
900        file_ctrl.add_file(file_obj, filename='my_document.jpg')
901        self.browser.getControl(
902            name='upload_samplescaneditupload').click()
903        self.assertTrue(
904            'href="http://localhost/app/customers/K1000000/documents/d102/sample"'
905            in self.browser.contents)
906        # Costumer can submit the form. The form is also saved.
907        self.browser.getControl(name="form.title").value = 'My third doc'
908        self.browser.getControl("Final Submit").click()
909        self.assertEqual(document.title, 'My third doc')
910        self.assertEqual(document.state, 'submitted')
911        self.assertTrue('Document State: submitted for verification' in self.browser.contents)
912        # Customer can't edit the document once it has been submitted
913        self.browser.open(self.documents_path + '/d102/edit')
914        self.assertTrue('The requested form is locked' in self.browser.contents)
915
916    def test_manage_upload_sample_file(self):
917        # Managers can upload a file via the DocumentManageFormPage
918        # The image is stored even if form has errors
919        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
920        self.browser.open(self.customer_path + '/documents/d101/manage')
921        # Create a pseudo image file and select it to be uploaded
922        image = open(SAMPLE_IMAGE, 'rb')
923        ctrl = self.browser.getControl(name='samplescanmanageupload')
924        file_ctrl = ctrl.mech_control
925        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
926        # The Save action does not upload files
927        self.browser.getControl("Save").click() # submit form
928        self.assertFalse(
929            'href="http://localhost/app/customers/K1000000/documents/d101/sample"'
930            in self.browser.contents)
931        # ... but the correct upload submit button does
932        image = open(SAMPLE_IMAGE)
933        ctrl = self.browser.getControl(name='samplescanmanageupload')
934        file_ctrl = ctrl.mech_control
935        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
936        self.browser.getControl(
937            name='upload_samplescanmanageupload').click()
938        self.assertTrue(
939            'href="http://localhost/app/customers/K1000000/documents/d101/sample"'
940            in self.browser.contents)
941        # Browsing the link shows a real image
942        self.browser.open('sample')
943        self.assertEqual(
944            self.browser.headers['content-type'], 'image/jpeg')
945        self.assertEqual(len(self.browser.contents), 2787)
946        # We can't reupload a file. The existing file must be deleted first.
947        self.browser.open(self.customer_path + '/documents/d101/manage')
948        self.assertFalse(
949            'upload_samplescanmanageupload' in self.browser.contents)
950        # File must be deleted first
951        self.browser.getControl(name='delete_samplescanmanageupload').click()
952        self.assertTrue(
953            'sample deleted' in self.browser.contents)
954        # Uploading a file which is bigger than 150k will raise an error
955        big_image = StringIO(open(SAMPLE_IMAGE, 'rb').read() * 75)
956        ctrl = self.browser.getControl(name='samplescanmanageupload')
957        file_ctrl = ctrl.mech_control
958        file_ctrl.add_file(big_image, filename='my_sample_scan.jpg')
959        self.browser.getControl(
960            name='upload_samplescanmanageupload').click()
961        self.assertTrue(
962            'Uploaded file is too big' in self.browser.contents)
963        # we do not rely on filename extensions given by uploaders
964        image = open(SAMPLE_IMAGE, 'rb') # a jpg-file
965        ctrl = self.browser.getControl(name='samplescanmanageupload')
966        file_ctrl = ctrl.mech_control
967        # tell uploaded file is bmp
968        file_ctrl.add_file(image, filename='my_sample_scan.bmp')
969        self.browser.getControl(
970            name='upload_samplescanmanageupload').click()
971        self.assertTrue(
972            # jpg file was recognized
973            'File sample.jpg uploaded.' in self.browser.contents)
974        # Delete file again
975        self.browser.getControl(name='delete_samplescanmanageupload').click()
976        self.assertTrue(
977            'sample deleted' in self.browser.contents)
978        # File names must meet several conditions
979        bmp_image = open(SAMPLE_IMAGE_BMP, 'rb')
980        ctrl = self.browser.getControl(name='samplescanmanageupload')
981        file_ctrl = ctrl.mech_control
982        file_ctrl.add_file(bmp_image, filename='my_sample_scan.bmp')
983        self.browser.getControl(
984            name='upload_samplescanmanageupload').click()
985        self.assertTrue('Only the following extensions are allowed'
986            in self.browser.contents)
987
988    def test_manage_upload_pdf_file(self):
989        # Managers can upload a file via the DocumentManageFormPage
990        # The image is stored even if form has errors
991        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
992        self.browser.open(self.customer_path + '/documents')
993        self.browser.getLink("Add document").click()
994        self.browser.getControl(name="doctype").value = ['CustomerPDFDocument']
995        self.browser.getControl("Create document").click()
996        self.browser.open(self.documents_path + '/d102/manage')
997        # Create a pseudo image file and select it to be uploaded
998        image = open(SAMPLE_IMAGE, 'rb')
999        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1000        file_ctrl = ctrl.mech_control
1001        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
1002        self.browser.getControl(
1003            name='upload_pdfscanmanageupload').click()
1004        self.assertTrue(
1005            'pdf file extension expected' in self.browser.contents)
1006        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1007        file_ctrl = ctrl.mech_control
1008        file_ctrl.add_file(image, filename='my_sample_scan.pdf')
1009        self.browser.getControl(
1010            name='upload_pdfscanmanageupload').click()
1011        self.assertTrue(
1012            'Could not determine file type' in self.browser.contents)
1013        pdf = open(SAMPLE_PDF, 'rb')
1014        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1015        file_ctrl = ctrl.mech_control
1016        file_ctrl.add_file(pdf, filename='my_sample_scan.pdf')
1017        self.browser.getControl(
1018            name='upload_pdfscanmanageupload').click()
1019        self.assertTrue(
1020            'href="http://localhost/app/customers/K1000000/documents/d102/sample.pdf">PDF File</a>'
1021            in self.browser.contents)
1022        # Browsing the link shows a real pdf
1023        self.browser.open('sample.pdf')
1024        self.assertEqual(
1025            self.browser.headers['content-type'], 'application/pdf')
1026
1027    def test_view_slips(self):
1028        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1029        # Officers can open the document overview
1030        self.browser.open(self.customer_path + '/documents')
1031        self.browser.getLink("Download documents overview").click()
1032        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1033        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
1034        path = os.path.join(samples_dir(), 'documents_overview_slip.pdf')
1035        open(path, 'wb').write(self.browser.contents)
1036        print "Sample PDF overview_slip.pdf written to %s" % path
1037        # Officers can open document slips
1038        self.browser.open(self.customer_path + '/documents/d101')
1039        self.browser.getLink("Download document slip").click()
1040        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1041        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
1042        path = os.path.join(samples_dir(), 'document_slip.pdf')
1043        open(path, 'wb').write(self.browser.contents)
1044        print "Sample document_slip.pdf written to %s" % path
1045
1046
1047class ApplicationUITests(CustomersFullSetup):
1048    # Tests for CustomerSampleApplication relates views and pages
1049
1050    def test_manage_application(self):
1051        # Managers can access the pages of customer applicationsconter
1052        # and can perform actions
1053        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1054        self.browser.open(self.customer_path)
1055        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1056        self.assertEqual(self.browser.url, self.customer_path)
1057        self.browser.open(self.customer_path)
1058        self.browser.getLink("Applications").click()
1059        self.browser.getLink("Add application").click()
1060        self.browser.getControl(name="apptype").value = ['SampleApplication']
1061        self.browser.getControl("Create application").click()
1062        self.assertTrue('Sample Application created.' in self.browser.contents)
1063        application = self.customer['applications']['a102']
1064
1065        # Application can be edited
1066        self.browser.getLink("a102").click()
1067        self.browser.getLink("Manage").click()
1068        self.browser.getControl(name="form.title").value = 'My second app'
1069        self.browser.getControl("Save").click()
1070        self.assertTrue('Form has been saved.' in self.browser.contents)
1071        self.browser.getLink("View").click()
1072        self.assertEqual(self.browser.url, self.applications_path + '/a102/index')
1073
1074        # Transitions can be performed
1075        self.browser.getLink("Transition").click()
1076        self.browser.getControl(name="transition").value = ['submit']
1077        self.browser.getControl("Save").click()
1078        self.browser.getControl(name="transition").value = ['approve']
1079        self.browser.getControl("Save").click()
1080        self.assertEqual(application.state, 'approved')
1081
1082        # Applications can be removed
1083        self.browser.getLink("Applications").click()
1084        ctrl = self.browser.getControl(name='val_id')
1085        ctrl.getControl(value=application.application_id).selected = True
1086        self.browser.getControl("Remove selected", index=0).click()
1087        self.assertTrue('Successfully removed' in self.browser.contents)
1088
1089        # All actions are being logged
1090        logfile = os.path.join(
1091            self.app['datacenter'].storage, 'logs', 'customers.log')
1092        logcontent = open(logfile).read()
1093        self.assertTrue(
1094            'INFO - zope.mgr - customers.browser.ApplicationManageFormPage '
1095            '- K1000000 - saved a102: title'
1096            in logcontent)
1097        self.assertTrue(
1098            'INFO - zope.mgr - customers.browser.ApplicationAddFormPage '
1099            '- K1000000 - added: Sample Application %s'
1100            % application.application_id in logcontent)
1101        self.assertTrue(
1102            'INFO - zope.mgr - customers.browser.ApplicationsManageFormPage '
1103            '- K1000000 - removed: %s'
1104            % application.application_id in logcontent)
1105
1106    def test_edit_sample_application(self):
1107        # Customers can manage applications under certain conditions
1108        self.browser.open(self.login_path)
1109        self.browser.getControl(name="form.login").value = self.customer_id
1110        self.browser.getControl(name="form.password").value = 'cpwd'
1111        self.browser.getControl("Login").click()
1112        self.assertMatches(
1113            '...You logged in...', self.browser.contents)
1114        self.browser.getLink("Applications").click()
1115        self.browser.getLink("Add application").click()
1116        self.browser.getControl(name="apptype").value = ['SampleApplication']
1117        self.browser.getControl("Create application").click()
1118        self.assertTrue('Sample Application created.' in self.browser.contents)
1119        application = self.customer['applications']['a102']
1120
1121        # Application can be edited ...
1122        self.browser.getLink("a102").click()
1123        self.browser.open(self.applications_path + '/a102/edit')
1124        #self.browser.getLink("Edit").click()
1125        self.assertTrue('The requested form is locked' in self.browser.contents)
1126        # Customer is in wrong state
1127        IWorkflowState(self.customer).setState(APPROVED)
1128        self.browser.open(self.applications_path + '/a102/edit')
1129        self.browser.getControl(name="form.title").value = 'My second app'
1130        self.browser.getControl("Save").click()
1131        self.assertEqual(application.title, 'My second app')
1132        self.assertTrue('Form has been saved.' in self.browser.contents)
1133        self.browser.getLink("View").click()
1134        self.assertEqual(self.browser.url, self.applications_path + '/a102/index')
1135        # Customer can submit the form. The form is also saved.
1136        self.browser.getLink("Edit").click()
1137        self.browser.getControl(name="form.title").value = 'My third app'
1138        self.browser.getControl("Final Submit").click()
1139        self.assertEqual(application.title, 'My third app')
1140        self.assertEqual(application.state, 'submitted')
1141        self.assertTrue('Application State: submitted for approval' in self.browser.contents)
1142        # Customer can't edit the application once it has been submitted
1143        self.browser.open(self.applications_path + '/a102/edit')
1144        self.assertTrue('The requested form is locked' in self.browser.contents)
1145
1146    def test_view_slips(self):
1147        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1148        # Officers can open the application overview
1149        self.browser.open(self.customer_path + '/applications')
1150        self.browser.getLink("Download applications overview").click()
1151        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1152        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
1153        path = os.path.join(samples_dir(), 'applications_overview_slip.pdf')
1154        open(path, 'wb').write(self.browser.contents)
1155        print "Sample PDF overview_slip.pdf written to %s" % path
1156        # Officers can open application slips
1157        self.browser.open(self.customer_path + '/applications/a101')
1158        self.browser.getLink("Download application slip").click()
1159        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1160        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
1161        path = os.path.join(samples_dir(), 'application_slip.pdf')
1162        open(path, 'wb').write(self.browser.contents)
1163        print "Sample application_slip.pdf written to %s" % path
1164
Note: See TracBrowser for help on using the repository browser.