source: main/waeup.ikoba/branches/uli-payments/src/waeup/ikoba/customers/tests/test_browser.py @ 12693

Last change on this file since 12693 was 12693, checked in by uli, 10 years ago

pyflakes.

  • Property svn:keywords set to Id
File size: 77.7 KB
Line 
1## $Id: test_browser.py 12693 2015-03-08 19:44:13Z uli $
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 logging
24import base64
25from decimal import Decimal
26from datetime import datetime, timedelta, date
27from StringIO import StringIO
28import os
29import grok
30from zc.async.testing import wait_for_result
31from zope.event import notify
32from zope.component import createObject, queryUtility, getUtility
33from zope.component.hooks import setSite, clearSite
34from zope.schema.interfaces import ConstraintNotSatisfied
35from zope.catalog.interfaces import ICatalog
36from zope.security.interfaces import Unauthorized
37from zope.securitypolicy.interfaces import IPrincipalRoleManager
38from zope.testbrowser.testing import Browser
39from hurry.workflow.interfaces import (
40    IWorkflowInfo, IWorkflowState, InvalidTransitionError)
41from waeup.ikoba.testing import FunctionalLayer, FunctionalTestCase
42from waeup.ikoba.app import Company
43from waeup.ikoba.interfaces import (
44    IUserAccount, IJobManager, APPROVED, SUBMITTED,
45    IFileStoreNameChooser, NotIdValue)
46from waeup.ikoba.imagestorage import ExtFileStore
47from waeup.ikoba.tests.test_async import FunctionalAsyncTestCase
48from waeup.ikoba.interfaces import VERIFIED
49from waeup.ikoba.browser.tests.test_pdf import samples_dir
50from waeup.ikoba.products.productoptions import ProductOption
51
52PH_LEN = 15911  # Length of placeholder file
53
54SAMPLE_IMAGE = os.path.join(os.path.dirname(__file__), 'test_image.jpg')
55SAMPLE_IMAGE_BMP = os.path.join(os.path.dirname(__file__), 'test_image.bmp')
56SAMPLE_PDF = os.path.join(os.path.dirname(__file__), 'test_pdf.pdf')
57
58
59def lookup_submit_value(name, value, browser):
60    """Find a button with a certain value."""
61    for num in range(0, 100):
62        try:
63            button = browser.getControl(name=name, index=num)
64            if button.value.endswith(value):
65                return button
66        except IndexError:
67            break
68    return None
69
70
71class CustomersFullSetup(FunctionalTestCase):
72    # A test case that only contains a setup and teardown
73    #
74    # Complete setup for customers handlings is rather complex and
75    # requires lots of things created before we can start. This is a
76    # setup that does all this, creates a company etc.
77    # so that we do not have to bother with that in different
78    # test cases.
79
80    layer = FunctionalLayer
81
82    def setup_customizable_params(self):
83        self._contract_category = u'sample'
84        self._document_factory = 'waeup.CustomerSampleDocument'
85        self._contract_factory = 'waeup.SampleContract'
86        return
87
88    def setUp(self):
89        super(CustomersFullSetup, self).setUp()
90        self.setup_customizable_params()
91        # Setup a sample site for each test
92        app = Company()
93        self.dc_root = tempfile.mkdtemp()
94        app['datacenter'].setStoragePath(self.dc_root)
95
96        # Prepopulate the ZODB...
97        self.getRootFolder()['app'] = app
98        # we add the site immediately after creation to the
99        # ZODB. Catalogs and other local utilities are not setup
100        # before that step.
101        self.app = self.getRootFolder()['app']
102        # Set site here. Some of the following setup code might need
103        # to access grok.getSite() and should get our new app then
104        setSite(app)
105
106        # Add some products
107        self.product = createObject('waeup.Product')
108        self.product.product_id = u'SAM'
109        self.product.title = u'Our Sample Product'
110        self.product.contract_category = self._contract_category
111        self.product.valid_from = date(2014, 12, 4)
112        self.product.tc_dict = {'en': u'Hello world'}
113        prodoption = ProductOption()
114        prodoption.title = u'First option'
115        prodoption.fee = Decimal('99.9')
116        prodoption.currency = 'USD'
117        self.product.options = [prodoption, ]
118        self.app['products'].addProduct(self.product)
119
120        # Add customer with subobjects
121        customer = createObject('waeup.Customer')
122        customer.firstname = u'Anna'
123        customer.lastname = u'Tester'
124        customer.reg_number = u'123'
125        customer.sex = u'm'
126        customer.email = u'aa@aa.ng'
127        customer.phone = u'1234'
128        customer.date_of_birth = date(1981, 2, 4)
129        self.app['customers'].addCustomer(customer)
130        self.customer_id = customer.customer_id
131        self.customer = self.app['customers'][self.customer_id]
132        self.document = createObject(self._document_factory)
133        self.document.title = u'My first document'
134        self.document.document_id = u'DOC1'
135        self.assertRaises(
136            NotIdValue, setattr, self.document, 'document_id',
137            u'id with spaces')
138        self.customer['documents'].addDocument(self.document)
139        self.contract = createObject(self._contract_factory)
140        self.contract.contract_id = u'CON1'
141        self.assertRaises(
142            NotIdValue, setattr, self.contract, 'contract_id',
143            u'id with spaces')
144        self.customer['contracts'].addContract(self.contract)
145
146        # Set password
147        IUserAccount(
148            self.app['customers'][self.customer_id]).setPassword('cpwd')
149
150        self.login_path = 'http://localhost/app/login'
151        self.container_path = 'http://localhost/app/customers'
152        self.manage_container_path = self.container_path + '/@@manage'
153        self.add_customer_path = self.container_path + '/addcustomer'
154        self.customer_path = self.container_path + '/' + self.customer_id
155        self.manage_customer_path = self.customer_path + '/manage_base'
156        self.trigtrans_path = self.customer_path + '/trigtrans'
157        self.history_path = self.customer_path + '/history'
158        self.documents_path = self.customer_path + '/documents'
159        self.contracts_path = self.customer_path + '/contracts'
160
161        # Update the catalog
162        notify(grok.ObjectModifiedEvent(self.customer))
163
164        # Put the prepopulated site into test ZODB and prepare test
165        # browser
166        self.browser = Browser()
167        self.browser.handleErrors = False
168
169    def tearDown(self):
170        super(CustomersFullSetup, self).tearDown()
171        clearSite()
172        shutil.rmtree(self.dc_root)
173
174
175class CustomersContainerUITests(CustomersFullSetup):
176    # Tests for CustomersContainer class views and pages
177
178    layer = FunctionalLayer
179
180    def test_anonymous_access(self):
181        # Anonymous users can't access customers containers
182        self.assertRaises(
183            Unauthorized, self.browser.open, self.container_path)
184        self.assertRaises(
185            Unauthorized, self.browser.open, self.manage_container_path)
186        return
187
188    def test_manage_access(self):
189        # Managers can access the view page of customers
190        # containers and can perform actions
191        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
192        self.browser.open(self.container_path)
193        self.assertEqual(self.browser.headers['Status'], '200 Ok')
194        self.assertEqual(self.browser.url, self.container_path)
195        self.browser.getLink("Manage customer section").click()
196        self.assertEqual(self.browser.headers['Status'], '200 Ok')
197        self.assertEqual(self.browser.url, self.manage_container_path)
198        return
199
200    def test_add_search_delete_customers(self):
201        # Managers can add search and remove customers
202        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
203        self.browser.open(self.manage_container_path)
204        self.browser.getLink("Add customer").click()
205        self.assertEqual(self.browser.headers['Status'], '200 Ok')
206        self.assertEqual(self.browser.url, self.add_customer_path)
207        self.browser.getControl(name="form.firstname").value = 'Bob'
208        self.browser.getControl(name="form.lastname").value = 'Tester'
209        self.browser.getControl(name="form.reg_number").value = '123'
210        self.browser.getControl("Create customer record").click()
211        self.assertTrue('Registration number in use.'
212            in self.browser.contents)
213        self.browser.getControl(name="form.reg_number").value = '1234'
214        self.browser.getControl("Create customer").click()
215        self.assertTrue('Customer created' in self.browser.contents)
216
217        # Registration must be unique
218        self.browser.getLink("Manage").click()
219        self.browser.getControl(name="form.reg_number").value = '123'
220        self.browser.getControl("Save").click()
221        self.assertMatches('...Registration number in use...',
222                           self.browser.contents)
223
224        # We can find a customer with a certain customer_id
225        self.browser.open(self.container_path)
226        self.browser.getControl("Find customer(s)").click()
227        self.assertTrue('Empty search string' in self.browser.contents)
228        self.browser.getControl(name="searchtype").value = ['customer_id']
229        self.browser.getControl(name="searchterm").value = self.customer_id
230        self.browser.getControl("Find customer(s)").click()
231        self.assertTrue('Anna Tester' in self.browser.contents)
232
233        # We can find a customer by searching for all kind of name parts
234        self.browser.open(self.manage_container_path)
235        self.browser.getControl("Find customer(s)").click()
236        self.assertTrue('Empty search string' in self.browser.contents)
237        self.browser.getControl(name="searchtype").value = ['fullname']
238        self.browser.getControl(name="searchterm").value = 'Anna Tester'
239        self.browser.getControl("Find customer(s)").click()
240        self.assertTrue('Anna Tester' in self.browser.contents)
241        self.browser.open(self.manage_container_path)
242        self.browser.getControl(name="searchtype").value = ['fullname']
243        self.browser.getControl(name="searchterm").value = 'Anna'
244        self.browser.getControl("Find customer(s)").click()
245        self.assertTrue('Anna Tester' in self.browser.contents)
246        self.browser.open(self.manage_container_path)
247        self.browser.getControl(name="searchtype").value = ['fullname']
248        self.browser.getControl(name="searchterm").value = 'Tester'
249        self.browser.getControl("Find customer(s)").click()
250        self.assertTrue('Anna Tester' in self.browser.contents)
251        self.browser.open(self.manage_container_path)
252        self.browser.getControl(name="searchtype").value = ['fullname']
253        self.browser.getControl(name="searchterm").value = 'An'
254        self.browser.getControl("Find customer(s)").click()
255        self.assertFalse('Anna Tester' in self.browser.contents)
256        self.browser.open(self.manage_container_path)
257        self.browser.getControl(name="searchtype").value = ['fullname']
258        self.browser.getControl(name="searchterm").value = 'An*'
259        self.browser.getControl("Find customer(s)").click()
260        self.assertTrue('Anna Tester' in self.browser.contents)
261        self.browser.open(self.manage_container_path)
262        self.browser.getControl(name="searchtype").value = ['fullname']
263        self.browser.getControl(name="searchterm").value = 'tester'
264        self.browser.getControl("Find customer(s)").click()
265        self.assertTrue('Anna Tester' in self.browser.contents)
266        self.browser.open(self.manage_container_path)
267        self.browser.getControl(name="searchtype").value = ['fullname']
268        self.browser.getControl(name="searchterm").value = 'Tester Ana'
269        self.browser.getControl("Find customer(s)").click()
270        self.assertFalse('Anna Tester' in self.browser.contents)
271        self.browser.open(self.manage_container_path)
272        self.browser.getControl(name="searchtype").value = ['fullname']
273        self.browser.getControl(name="searchterm").value = 'Tester Anna'
274        self.browser.getControl("Find customer(s)").click()
275        self.assertTrue('Anna Tester' in self.browser.contents)
276        # The old searchterm will be used again
277        self.browser.getControl("Find customer(s)").click()
278        self.assertTrue('Anna Tester' in self.browser.contents)
279
280        # We can find suspended customers
281        self.customer.suspended = True
282        notify(grok.ObjectModifiedEvent(self.customer))
283        self.browser.open(self.manage_container_path)
284        self.browser.getControl(name="searchtype").value = ['suspended']
285        self.browser.getControl("Find customer(s)").click()
286        self.assertTrue('Anna Tester' in self.browser.contents)
287
288        # Removed customers won't be found
289        ctrl = self.browser.getControl(name='entries')
290        ctrl.getControl(value=self.customer_id).selected = True
291        self.browser.getControl("Remove selected", index=0).click()
292        self.assertTrue('Successfully removed' in self.browser.contents)
293        self.browser.getControl(name="searchtype").value = ['customer_id']
294        self.browser.getControl(name="searchterm").value = self.customer_id
295        self.browser.getControl("Find customer(s)").click()
296        self.assertTrue('No customer found' in self.browser.contents)
297        return
298
299
300class OfficerUITests(CustomersFullSetup):
301    # Tests for Customer class views and pages
302
303    def setup_logging(self):
304        # setup a log-handler that catches all fake mailer output
305        self.stream = StringIO()
306        handler = logging.StreamHandler(self.stream)
307        logger = logging.getLogger('test.smtp')
308        logger.addHandler(handler)
309        logger.setLevel(logging.INFO)
310        return
311
312    def get_fake_smtp_output(self):
313        # get output generated by fake mailer
314        self.stream.flush()
315        self.stream.seek(0)
316        return self.stream.read()
317
318    def teardown_logging(self):
319        # remove the log handler for fake mailer output
320        logger = logging.getLogger('test.smtp')
321        handlers = [x for x in logger.handlers]
322        for handler in handlers:
323            logger.removeHandler(handler)
324        return
325
326    def test_basic_auth(self):
327        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
328        self.browser.open('http://localhost/app')
329        self.browser.getLink("Logout").click()
330        self.assertTrue('You have been logged out' in self.browser.contents)
331        # But we are still logged in since we've used basic
332        # authentication here.  Wikipedia says: Existing browsers
333        # retain authentication information until the tab or browser
334        # is closed or the user clears the history.  HTTP does not
335        # provide a method for a server to direct clients to discard
336        # these cached credentials. This means that there is no
337        # effective way for a server to "log out" the user without
338        # closing the browser. This is a significant defect that
339        # requires browser manufacturers to support a "logout" user
340        # interface element ...
341        self.assertTrue('Manager' in self.browser.contents)
342
343    def test_basic_auth_base64(self):
344        auth_token = base64.b64encode('mgr:mgrpw')
345        self.browser.addHeader('Authorization', 'Basic %s' % auth_token)
346        self.browser.open(self.manage_container_path)
347        self.assertEqual(self.browser.headers['Status'], '200 Ok')
348
349    def test_manage_access(self):
350        # Managers can access the pages of customers
351        # and can perform actions
352        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
353        self.browser.open(self.customer_path)
354        self.assertEqual(self.browser.headers['Status'], '200 Ok')
355        self.assertEqual(self.browser.url, self.customer_path)
356        self.browser.getLink("Transition").click()
357        self.assertEqual(self.browser.headers['Status'], '200 Ok')
358        # Managers can trigger transitions
359        self.browser.getControl(name="transition").value = ['start']
360        self.browser.getControl("Apply").click()
361        # Managers can edit base
362        self.browser.open(self.customer_path)
363        self.browser.getLink("Manage").click()
364        self.assertEqual(self.browser.url, self.manage_customer_path)
365        self.assertEqual(self.browser.headers['Status'], '200 Ok')
366        self.browser.getControl(name="form.firstname").value = 'John'
367        self.browser.getControl(name="form.lastname").value = 'Tester'
368        self.browser.getControl(name="form.reg_number").value = '345'
369        self.browser.getControl(name="password").value = 'secret'
370        self.browser.getControl(name="control_password").value = 'secret'
371        self.browser.getControl("Save").click()
372        self.assertMatches('...Form has been saved...',
373                           self.browser.contents)
374
375    def test_manage_contact_customer(self):
376        # Managers can contact customer
377        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
378        self.browser.open(self.customer_path)
379        self.browser.getLink("Send email").click()
380        self.browser.getControl(
381            name="form.subject").value = 'Important subject'
382        self.browser.getControl(name="form.body").value = 'Hello!'
383        self.browser.getControl("Send message now").click()
384        self.assertTrue('Your message has been sent' in self.browser.contents)
385        return
386
387    def test_manage_upload_passport(self):
388        # Managers can upload a file via the CustomerBaseManageFormPage
389        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
390        self.browser.open(self.manage_customer_path)
391        image = open(SAMPLE_IMAGE_BMP, 'rb')
392        ctrl = self.browser.getControl(name='passportmanageupload')
393        file_ctrl = ctrl.mech_control
394        file_ctrl.add_file(image, filename='my_photo.bmp')
395        self.browser.getControl(
396            name='upload_passportmanageupload').click()
397        self.assertTrue('jpg file format expected'
398            in self.browser.contents)
399        ctrl = self.browser.getControl(name='passportmanageupload')
400        file_ctrl = ctrl.mech_control
401        image = open(SAMPLE_IMAGE, 'rb')
402        file_ctrl.add_file(image, filename='my_photo.jpg')
403        self.browser.getControl(
404            name='upload_passportmanageupload').click()
405        self.assertTrue(
406            'src="http://localhost/app/customers/K1000000/passport.jpg"'
407            in self.browser.contents)
408        # We remove the passport file again
409        self.browser.open(self.manage_customer_path)
410        self.browser.getControl('Delete').click()
411        self.assertTrue('passport.jpg deleted' in self.browser.contents)
412
413    def test_manage_workflow_send_transition_information(self):
414        # Managers can pass through the whole workflow
415        config = grok.getSite()['configuration']
416        config.email_notification = True
417        self.setup_logging()
418        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
419        self.customer = self.app['customers'][self.customer_id]
420        self.browser.open(self.trigtrans_path)
421        self.browser.getControl(name="transition").value = ['start']
422        self.browser.getControl("Apply").click()
423        self.browser.open(self.trigtrans_path)
424        self.browser.getControl(name="transition").value = ['request']
425        self.browser.getControl("Apply").click()
426        self.browser.open(self.trigtrans_path)
427        self.browser.getControl(name="transition").value = ['reject']
428        self.browser.getControl("Apply").click()
429        # The customer is being notified by email after rejection
430        expected = [
431            u'Sending email from no-reply@waeup.org to aa@aa.ng:',
432            u'Message:', u'msg: MIME-Version: 1.0',
433            u'msg: Content-Type: text/plain; charset="us-ascii"',
434            u'msg: Content-Transfer-Encoding: 7bit',
435            u'msg: From: Administrator <no-reply@waeup.org>',
436            u'msg: To: Anna Tester <aa@aa.ng>',
437            u'msg: Reply-To: Administrator <contact@waeup.org>',
438            u'msg: Subject: Ikoba status change information',
439            u'msg: ',
440            u'msg: Dear Anna Tester,',
441            u'msg: ',
442            u'msg: The status of the following object has been changed:',
443            u'msg: ', u'msg: Object Id: K1000000',
444            u'msg: Title: Anna Tester',
445            u'msg: Transition: customer registration rejected',
446            u'msg: New state: started',
447            u'msg: ',
448            u'msg: Regards,',
449            u'msg: ',
450            u'msg: Manager',
451            u'msg: ',
452            u'msg: --',
453            u'msg: Sample Company',
454            u'msg: ',
455            u'']
456        self.assertEqual(expected, self.get_fake_smtp_output().split('\n'))
457        self.browser.open(self.trigtrans_path)
458        self.browser.getControl(name="transition").value = ['request']
459        self.browser.getControl("Apply").click()
460        self.browser.open(self.trigtrans_path)
461        self.browser.getControl(name="transition").value = [
462            'approve_provisionally']
463        self.browser.getControl("Apply").click()
464        self.browser.open(self.trigtrans_path)
465        self.browser.getControl(name="transition").value = ['approve_finally']
466        self.browser.getControl("Apply").click()
467        self.browser.open(self.trigtrans_path)
468        self.browser.getControl(name="transition").value = ['reset1']
469        self.browser.getControl("Apply").click()
470        self.teardown_logging()
471        return
472
473    def test_manage_import(self):
474        # Managers can import customer data files
475        datacenter_path = 'http://localhost/app/datacenter'
476        # Prepare a csv file for customers
477        open('customers.csv', 'wb').write(
478"""firstname,lastname,reg_number,date_of_birth,email,phone,sex,password
479Aaren,Pieri,1,1990-01-02,bb@aa.ng,1234,m,mypwd1
480Claus,Finau,2,1990-01-03,cc@aa.ng,1234,m,mypwd1
481Brit,Berson,2,1990-01-04,dd@aa.ng,1234,m,mypwd1
482""")
483        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
484        self.browser.open(datacenter_path)
485        self.browser.getLink('Upload data').click()
486        filecontents = StringIO(open('customers.csv', 'rb').read())
487        filewidget = self.browser.getControl(name='uploadfile:file')
488        filewidget.add_file(filecontents, 'text/plain', 'customers.csv')
489        self.browser.getControl(name='SUBMIT').click()
490        self.browser.getLink('Process data').click()
491        button = lookup_submit_value(
492            'select', 'customers_zope.mgr.csv', self.browser)
493        button.click()
494        importerselect = self.browser.getControl(name='importer')
495        modeselect = self.browser.getControl(name='mode')
496        importerselect.getControl('Customer Processor').selected = True
497        modeselect.getControl(value='create').selected = True
498        self.browser.getControl('Proceed to step 3').click()
499        self.assertTrue('Header fields OK' in self.browser.contents)
500        self.browser.getControl('Perform import').click()
501        self.assertTrue('Processing of 1 rows failed' in self.browser.contents)
502        self.assertTrue(
503            'Successfully processed 2 rows' in self.browser.contents)
504        self.assertTrue('Batch processing finished' in self.browser.contents)
505
506        # The customers are properly indexed and we can
507        # thus find a customer in  the department
508        self.browser.open(self.manage_container_path)
509        # We can search for a new customer by name ...
510        self.browser.getControl(name="searchtype").value = ['fullname']
511        self.browser.getControl(name="searchterm").value = 'Claus'
512        self.browser.getControl("Find customer(s)").click()
513        self.assertTrue('Claus Finau' in self.browser.contents)
514        # ... and check if the imported password has been properly set
515        ctrl = self.browser.getControl(name='entries')
516        value = ctrl.options[0]
517        claus = self.app['customers'][value]
518        self.assertTrue(IUserAccount(claus).checkPassword('mypwd1'))
519        return
520
521    def test_activate_deactivate_buttons(self):
522        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
523        self.browser.open(self.customer_path)
524        self.browser.getLink("Deactivate").click()
525        self.assertTrue(
526            'Customer account has been deactivated.' in self.browser.contents)
527        self.assertTrue(
528            'Base Data (account deactivated)' in self.browser.contents)
529        self.assertTrue(self.customer.suspended)
530        self.browser.getLink("Activate").click()
531        self.assertTrue(
532            'Customer account has been activated.' in self.browser.contents)
533        self.assertFalse(
534            'Base Data (account deactivated)' in self.browser.contents)
535        self.assertFalse(self.customer.suspended)
536        # History messages have been added ...
537        self.browser.getLink("History").click()
538        self.assertTrue(
539            'Customer account deactivated by Manager<br />'
540            in self.browser.contents)
541        self.assertTrue(
542            'Customer account activated by Manager<br />'
543            in self.browser.contents)
544        # ... and actions have been logged.
545        logfile = os.path.join(
546            self.app['datacenter'].storage, 'logs', 'customers.log')
547        logcontent = open(logfile).read()
548        self.assertTrue(
549            'zope.mgr - customers.browser.CustomerDeactivatePage - '
550            'K1000000 - account deactivated' in logcontent)
551        self.assertTrue(
552            'zope.mgr - customers.browser.CustomerActivatePage - '
553            'K1000000 - account activated' in logcontent)
554
555    def test_login_as_customer(self):
556        # CustomerImpersonators can login as customer
557        self.app['users'].addUser('mrofficer', 'mrofficersecret')
558        self.app['users']['mrofficer'].email = 'mrofficer@foo.ng'
559        self.app['users']['mrofficer'].title = 'Harry Actor'
560        prmglobal = IPrincipalRoleManager(self.app)
561        prmglobal.assignRoleToPrincipal(
562            'waeup.CustomerImpersonator', 'mrofficer')
563        prmglobal.assignRoleToPrincipal('waeup.CustomersManager', 'mrofficer')
564        self.assertEqual(self.customer.state, 'created')
565        # Login as customer impersonator
566        self.browser.open(self.login_path)
567        self.browser.getControl(name="form.login").value = 'mrofficer'
568        self.browser.getControl(name="form.password").value = 'mrofficersecret'
569        self.browser.getControl("Login").click()
570        self.assertMatches('...You logged in...', self.browser.contents)
571        self.browser.open(self.customer_path)
572        self.browser.getLink("Login as").click()
573        self.browser.getControl("Set password now").click()
574        temp_password = self.browser.getControl(name='form.password').value
575        self.browser.getControl("Login now").click()
576        self.assertMatches(
577            '...You successfully logged in as...', self.browser.contents)
578        # Status has changed
579        self.assertEqual(self.customer.state, 'started')
580        # We are logged in as customer and can see the 'My Data' tab
581        self.assertMatches(
582            '...<a href="#" class="dropdown-toggle"'
583            ' data-toggle="dropdown">...',
584            self.browser.contents)
585        self.assertMatches(
586            '...My Data...',
587            self.browser.contents)
588        self.browser.getLink("Logout").click()
589        # The customer can't login with the original password ...
590        self.browser.open(self.login_path)
591        self.browser.getControl(name="form.login").value = self.customer_id
592        self.browser.getControl(name="form.password").value = 'cpwd'
593        self.browser.getControl("Login").click()
594        self.assertMatches(
595            '...Your account has been temporarily deactivated...',
596            self.browser.contents)
597        # ... but with the temporary password
598        self.browser.open(self.login_path)
599        self.browser.getControl(name="form.login").value = self.customer_id
600        self.browser.getControl(name="form.password").value = temp_password
601        self.browser.getControl("Login").click()
602        self.assertMatches('...You logged in...', self.browser.contents)
603        # Creation of temp_password is properly logged
604        logfile = os.path.join(
605            self.app['datacenter'].storage, 'logs', 'customers.log')
606        logcontent = open(logfile).read()
607        self.assertTrue(
608            'mrofficer - customers.browser.LoginAsCustomerStep1 - K1000000 - '
609            'temp_password generated: %s' % temp_password in logcontent)
610
611
612class CustomerUITests(CustomersFullSetup):
613    # Tests for Customer class views and pages
614
615    def test_customer_login_with_email(self):
616        self.assertEqual(self.customer.state, 'created')
617        self.browser.open(self.login_path)
618        self.browser.getControl(name="form.login").value = self.customer.email
619        self.browser.getControl(name="form.password").value = 'cpwd'
620        self.browser.getControl("Login").click()
621        self.assertEqual(self.browser.url, self.customer_path)
622        self.assertTrue('You logged in' in self.browser.contents)
623        # Status has changed
624        self.assertEqual(self.customer.state, 'started')
625        return
626
627    def test_customer_change_password(self):
628        # Customers can change the password
629        self.assertEqual(self.customer.state, 'created')
630        self.customer.personal_updated = datetime.utcnow()
631        self.browser.open(self.login_path)
632        self.browser.getControl(name="form.login").value = self.customer_id
633        self.browser.getControl(name="form.password").value = 'cpwd'
634        self.browser.getControl("Login").click()
635        self.assertEqual(self.browser.url, self.customer_path)
636        self.assertTrue('You logged in' in self.browser.contents)
637        # Status has changed
638        self.assertEqual(self.customer.state, 'started')
639        # Change password
640        self.browser.getLink("Change password").click()
641        self.browser.getControl(name="change_password").value = 'pw'
642        self.browser.getControl(
643            name="change_password_repeat").value = 'pw'
644        self.browser.getControl("Save").click()
645        self.assertTrue('Password must have at least' in self.browser.contents)
646        self.browser.getControl(name="change_password").value = 'new_password'
647        self.browser.getControl(
648            name="change_password_repeat").value = 'new_passssword'
649        self.browser.getControl("Save").click()
650        self.assertTrue('Passwords do not match' in self.browser.contents)
651        self.browser.getControl(name="change_password").value = 'new_password'
652        self.browser.getControl(
653            name="change_password_repeat").value = 'new_password'
654        self.browser.getControl("Save").click()
655        self.assertTrue('Password changed' in self.browser.contents)
656        # We are still logged in. Changing the password hasn't thrown us out.
657        self.browser.getLink("Base Data").click()
658        self.assertEqual(self.browser.url, self.customer_path)
659        # We can logout
660        self.browser.getLink("Logout").click()
661        self.assertTrue('You have been logged out' in self.browser.contents)
662        self.assertEqual(self.browser.url, 'http://localhost/app/index')
663        # We can login again with the new password
664        self.browser.getLink("Login").click()
665        self.browser.open(self.login_path)
666        self.browser.getControl(name="form.login").value = self.customer_id
667        self.browser.getControl(name="form.password").value = 'new_password'
668        self.browser.getControl("Login").click()
669        self.assertEqual(self.browser.url, self.customer_path)
670        self.assertTrue('You logged in' in self.browser.contents)
671        return
672
673    def test_customer_edit_upload_upload_and_request(self):
674        # Customer cant login if their password is not set
675        self.browser.open(self.login_path)
676        self.browser.getControl(name="form.login").value = self.customer_id
677        self.browser.getControl(name="form.password").value = 'cpwd'
678        self.browser.getControl("Login").click()
679        self.assertMatches(
680            '...You logged in...', self.browser.contents)
681        self.browser.getLink("Edit").click()
682        self.browser.getControl(name="form.email").value = 'new_email@aa.ng'
683        self.browser.getControl("Save", index=0).click()
684        self.assertMatches('...Form has been saved...',
685                           self.browser.contents)
686        self.browser.getControl("Save and request registration").click()
687        self.assertMatches('...Passport picture is missing...',
688                           self.browser.contents)
689        self.assertEqual(self.customer.state, 'started')
690        # Customer must upload a passport picture. We are already on
691        # the upload page.
692        ctrl = self.browser.getControl(name='passporteditupload')
693        file_obj = open(SAMPLE_IMAGE, 'rb')
694        file_ctrl = ctrl.mech_control
695        file_ctrl.add_file(file_obj, filename='my_photo.jpg')
696        self.browser.getControl(
697            name='upload_passporteditupload').click()
698        self.assertTrue(
699            'src="http://localhost/app/customers/K1000000/passport.jpg"'
700            in self.browser.contents)
701        self.browser.getControl(name="CANCEL").click()
702        self.assertEqual(self.browser.url, self.customer_path)
703        self.browser.getLink("Edit").click()
704        self.browser.getControl("Save and request registration").click()
705        self.assertMatches('...Registration form has been submitted...',
706                           self.browser.contents)
707        self.assertEqual(self.customer.state, 'requested')
708        # Customer can view history
709        self.browser.getLink("History").click()
710        self.assertMatches('...Customer created by system...',
711            self.browser.contents)
712
713    def test_customer_login(self):
714        # Customer cant login if their password is not set
715        self.customer.password = None
716        self.browser.open(self.login_path)
717        self.browser.getControl(name="form.login").value = self.customer_id
718        self.browser.getControl(name="form.password").value = 'cpwd'
719        self.browser.getControl("Login").click()
720        self.assertTrue(
721            'You entered invalid credentials.' in self.browser.contents)
722        # We set the password again
723        IUserAccount(
724            self.app['customers'][self.customer_id]).setPassword('cpwd')
725        # Customers can't login if their account is suspended/deactivated
726        self.customer.suspended = True
727        self.browser.open(self.login_path)
728        self.browser.getControl(name="form.login").value = self.customer_id
729        self.browser.getControl(name="form.password").value = 'cpwd'
730        self.browser.getControl("Login").click()
731        self.assertMatches(
732            '...<div class="alert alert-warning">'
733            'Your account has been deactivated.</div>...',
734            self.browser.contents)
735        # If suspended_comment is set this message will be flashed instead
736        self.customer.suspended_comment = u'Aetsch baetsch!'
737        self.browser.getControl(name="form.login").value = self.customer_id
738        self.browser.getControl(name="form.password").value = 'cpwd'
739        self.browser.getControl("Login").click()
740        self.assertMatches(
741            '...<div class="alert alert-warning">Aetsch baetsch!</div>...',
742            self.browser.contents)
743        self.customer.suspended = False
744        # Customers can't login if a temporary password has been set and
745        # is not expired
746        self.app['customers'][self.customer_id].setTempPassword(
747            'anybody', 'temp_cpwd')
748        self.browser.open(self.login_path)
749        self.browser.getControl(name="form.login").value = self.customer_id
750        self.browser.getControl(name="form.password").value = 'cpwd'
751        self.browser.getControl("Login").click()
752        self.assertMatches(
753            '...Your account has been temporarily deactivated...',
754            self.browser.contents)
755        # The customer can login with the temporary password
756        self.browser.open(self.login_path)
757        self.browser.getControl(name="form.login").value = self.customer_id
758        self.browser.getControl(name="form.password").value = 'temp_cpwd'
759        self.browser.getControl("Login").click()
760        self.assertMatches(
761            '...You logged in...', self.browser.contents)
762        # Customer can view the base data
763        self.browser.open(self.customer_path)
764        self.assertEqual(self.browser.headers['Status'], '200 Ok')
765        self.assertEqual(self.browser.url, self.customer_path)
766        # When the password expires ...
767        delta = timedelta(minutes=11)
768        self.app['customers'][self.customer_id].temp_password[
769            'timestamp'] = datetime.utcnow() - delta
770        self.app['customers'][self.customer_id]._p_changed = True
771        # ... the customer will be automatically logged out
772        self.assertRaises(
773            Unauthorized, self.browser.open, self.customer_path)
774        # Then the customer can login with the original password
775        self.browser.open(self.login_path)
776        self.browser.getControl(name="form.login").value = self.customer_id
777        self.browser.getControl(name="form.password").value = 'cpwd'
778        self.browser.getControl("Login").click()
779        self.assertMatches(
780            '...You logged in...', self.browser.contents)
781
782    def test_change_password_request(self):
783        self.browser.open('http://localhost/app/changepw')
784        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
785        self.browser.getControl("Send login credentials").click()
786        self.assertTrue('An email with' in self.browser.contents)
787
788
789class CustomerRegistrationTests(CustomersFullSetup):
790    # Tests for customer registration
791
792    layer = FunctionalLayer
793
794    def test_request_pw(self):
795        # Customer with wrong number can't be found.
796        self.browser.open('http://localhost/app/requestpw')
797        self.browser.getControl(name="form.firstname").value = 'Anna'
798        self.browser.getControl(name="form.number").value = 'anynumber'
799        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
800        self.browser.getControl("Send login credentials").click()
801        self.assertTrue('No customer found.'
802            in self.browser.contents)
803        # Anonymous is not informed that firstname verification failed.
804        # It seems that the record doesn't exist.
805        self.browser.open('http://localhost/app/requestpw')
806        self.browser.getControl(name="form.firstname").value = 'Johnny'
807        self.browser.getControl(name="form.number").value = '123'
808        self.browser.getControl(name="form.email").value = 'xx@yy.zz'
809        self.browser.getControl("Send login credentials").click()
810        self.assertTrue('No customer found.'
811            in self.browser.contents)
812        # Even with the correct firstname we can't register if a
813        # password has been set and used.
814        self.browser.getControl(name="form.firstname").value = 'Anna'
815        self.browser.getControl(name="form.number").value = '123'
816        self.browser.getControl("Send login credentials").click()
817        self.assertTrue('Your password has already been set and used.'
818            in self.browser.contents)
819        self.browser.open('http://localhost/app/requestpw')
820        self.app['customers'][self.customer_id].password = None
821        # The firstname field, used for verification, is not case-sensitive.
822        self.browser.getControl(name="form.firstname").value = 'aNNa'
823        self.browser.getControl(name="form.number").value = '123'
824        self.browser.getControl(name="form.email").value = 'new@yy.zz'
825        self.browser.getControl("Send login credentials").click()
826        # Yeah, we succeded ...
827        self.assertTrue('Your request was successful.'
828            in self.browser.contents)
829        # ... and  customer can be found in the catalog via the email address
830        cat = queryUtility(ICatalog, name='customers_catalog')
831        results = list(
832            cat.searchResults(
833            email=('new@yy.zz', 'new@yy.zz')))
834        self.assertEqual(self.customer, results[0])
835        logfile = os.path.join(
836            self.app['datacenter'].storage, 'logs', 'main.log')
837        logcontent = open(logfile).read()
838        self.assertTrue(
839            'zope.anybody - customers.browser.CustomerRequestPasswordPage - '
840            '123 (K1000000) - new@yy.zz' in logcontent)
841        return
842
843    def test_create_account(self):
844        self.browser.open('http://localhost/app/createaccount')
845        self.browser.getControl(name="form.firstname").value = 'Ruben'
846        self.browser.getControl(name="form.lastname").value = 'Gonzales'
847        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
848        self.browser.getControl("Send login credentials").click()
849        # Email address exists.
850        self.assertTrue('Email address in use.' in self.browser.contents)
851        self.browser.getControl(name="form.email").value = 'newcustomer@xx.zz'
852        self.browser.getControl("Send login credentials").click()
853        self.assertTrue(
854            'Your request was successful.' in self.browser.contents)
855        # Customer can be found in the catalog via the email address
856        cat = queryUtility(ICatalog, name='customers_catalog')
857        results = list(
858            cat.searchResults(
859            email=('newcustomer@xx.zz', 'newcustomer@xx.zz')))
860        self.assertEqual(self.app['customers']['K1000001'], results[0])
861        self.assertEqual(self.app['customers']['K1000001'].firstname, 'Ruben')
862        self.assertEqual(
863            self.app['customers']['K1000001'].lastname, 'Gonzales')
864        logfile = os.path.join(
865            self.app['datacenter'].storage, 'logs', 'main.log')
866        logcontent = open(logfile).read()
867        self.assertTrue(
868            'zope.anybody - customers.browser.CustomerCreateAccountPage - '
869            'K1000001 - newcustomer@xx.zz' in logcontent)
870        return
871
872
873class CustomerDataExportTests(CustomersFullSetup, FunctionalAsyncTestCase):
874    # Tests for CustomersContainer class views and pages
875
876    layer = FunctionalLayer
877
878    def wait_for_export_job_completed(self):
879        # helper function waiting until the current export job is completed
880        manager = getUtility(IJobManager)
881        job_id = self.app['datacenter'].running_exports[0][0]
882        job = manager.get(job_id)
883        wait_for_result(job)
884        return job_id
885
886    def test_datacenter_export(self):
887        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
888        self.browser.open('http://localhost/app/datacenter/@@export')
889        self.browser.getControl(name="exporter").value = ['customers']
890        self.browser.getControl("Create CSV file").click()
891
892        # When the job is finished and we reload the page...
893        job_id = self.wait_for_export_job_completed()
894        # ... the csv file can be downloaded ...
895        self.browser.open('http://localhost/app/datacenter/@@export')
896        self.browser.getLink("Download").click()
897        self.assertEqual(self.browser.headers['content-type'],
898            'text/csv; charset=UTF-8')
899        self.assertTrue(
900            'filename="WAeUP.Ikoba_customers_%s.csv' % job_id in
901            self.browser.headers['content-disposition'])
902        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
903        job_id = self.app['datacenter'].running_exports[0][0]
904        # ... and discarded
905        self.browser.open('http://localhost/app/datacenter/@@export')
906        self.browser.getControl("Discard").click()
907        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
908        # Creation, downloading and discarding is logged
909        logfile = os.path.join(
910            self.app['datacenter'].storage, 'logs', 'datacenter.log')
911        logcontent = open(logfile).read()
912        self.assertTrue(
913            'zope.mgr - browser.pages.ExportCSVPage - exported: '
914            'customers, job_id=%s'
915            % job_id in logcontent
916            )
917        self.assertTrue(
918            'zope.mgr - browser.pages.ExportCSVView - downloaded: '
919            'WAeUP.Ikoba_customers_%s.csv, job_id=%s'
920            % (job_id, job_id) in logcontent
921            )
922        self.assertTrue(
923            'zope.mgr - browser.pages.ExportCSVPage - discarded: '
924            'job_id=%s' % job_id in logcontent
925            )
926
927
928class DocumentUITests(CustomersFullSetup):
929    # Tests for customer document related views and pages
930
931    def test_manage_document(self):
932        # Managers can access the pages of customer documentsconter
933        # and can perform actions
934        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
935        self.browser.open(self.customer_path)
936        self.assertEqual(self.browser.headers['Status'], '200 Ok')
937        self.assertEqual(self.browser.url, self.customer_path)
938        self.browser.open(self.customer_path)
939        self.browser.getLink("Documents", index=1).click()
940        self.browser.getControl("Add document").click()
941        self.browser.getControl(name="doctype").value = ['CustomerPDFDocument']
942        self.browser.getControl(name="form.title").value = 'My PDF Document'
943        self.browser.getControl("Add document").click()
944        self.assertTrue('PDF Document added.' in self.browser.contents)
945        docid = [i for i in self.customer['documents'].keys()
946                 if len(i) > 10][0]
947        document = self.customer['documents'][docid]
948
949        # Document can be edited
950        self.browser.getLink(docid[:9]).click()
951        self.browser.getLink("Manage").click()
952        self.browser.getControl(name="form.title").value = 'My second doc'
953        self.browser.getControl("Save").click()
954        self.assertTrue('Form has been saved.' in self.browser.contents)
955        self.browser.getLink("View").click()
956        self.assertEqual(self.browser.url,
957            self.documents_path + '/' + docid + '/index')
958
959        # Transitions can be performed
960        self.browser.getLink("Transition").click()
961        self.browser.getControl(name="transition").value = ['submit']
962        self.browser.getControl("Apply").click()
963        self.browser.getLink("Transition").click()
964        # Document can only be verified if customer is approved
965        self.browser.getControl(name="transition").value = ['verify']
966        self.browser.getControl("Apply").click()
967        self.assertTrue(
968            'Customer has not yet been approved' in self.browser.contents)
969        IWorkflowState(self.customer).setState(APPROVED)
970        # Document can only be verified if files have been uploaded before
971        self.browser.getLink("Transition").click()
972        self.browser.getControl(name="transition").value = ['verify']
973        self.browser.getControl("Apply").click()
974        self.assertTrue('No file uploaded' in self.browser.contents)
975        self.assertEqual(document.state, 'submitted')
976        # We set state here manually (verification is tested in
977        # test_verify_document)
978        IWorkflowState(document).setState(VERIFIED)
979
980        # Manage button and form is no longer available
981        self.browser.open(self.documents_path + '/' + docid + '/index')
982        self.assertFalse(
983            'href="http://localhost/app/customers/K1000000/'
984            'documents/%s/manage"'
985            % docid in self.browser.contents)
986        self.browser.open(self.documents_path + '/' + docid + '/manage')
987        self.assertTrue(
988            'The requested form is locked (read-only)'
989            in self.browser.contents)
990
991        # Documents can be removed
992        self.browser.getLink("Documents", index=1).click()
993        ctrl = self.browser.getControl(name='val_id')
994        ctrl.getControl(value=document.document_id).selected = True
995        self.browser.getControl("Remove selected", index=0).click()
996        self.assertTrue('Successfully removed' in self.browser.contents)
997
998        # All actions are being logged
999        logfile = os.path.join(
1000            self.app['datacenter'].storage, 'logs', 'customers.log')
1001        logcontent = open(logfile).read()
1002
1003        self.assertTrue(
1004            'INFO - system - K1000000 - DOC1 - Document created'
1005            in logcontent)
1006        self.assertTrue(
1007            'INFO - zope.mgr - customers.browser.DocumentAddFormPage '
1008            '- K1000000 - added: PDF Document %s'
1009            % document.document_id in logcontent)
1010        self.assertTrue(
1011            'INFO - zope.mgr - customers.browser.DocumentManageFormPage '
1012            '- K1000000 - %s - saved: title' % docid
1013            in logcontent)
1014        self.assertTrue(
1015            'INFO - zope.mgr - K1000000 - %s - Submitted for verification'
1016            % docid in logcontent)
1017        self.assertTrue(
1018            'INFO - zope.mgr - customers.browser.DocumentsManageFormPage '
1019            '- K1000000 - removed: %s' % docid
1020            in logcontent)
1021
1022    def test_edit_sample_document(self):
1023        # Customers can manage documents under certain conditions
1024        self.browser.open(self.login_path)
1025        self.browser.getControl(name="form.login").value = self.customer_id
1026        self.browser.getControl(name="form.password").value = 'cpwd'
1027        self.browser.getControl("Login").click()
1028        self.assertMatches(
1029            '...You logged in...', self.browser.contents)
1030        self.browser.getLink("Documents").click()
1031        self.browser.getControl("Add document").click()
1032        self.assertTrue(
1033            'The requested form is locked' in self.browser.contents)
1034        # Customer is in wrong state
1035        IWorkflowState(self.customer).setState(APPROVED)
1036        self.browser.getControl("Add document").click()
1037        self.browser.getControl(name="doctype").value = [
1038            'CustomerSampleDocument']
1039        self.browser.getControl(name="form.title").value = 'My Sample Document'
1040        self.browser.getControl("Add document").click()
1041        self.assertTrue('Sample Document added.' in self.browser.contents)
1042        docid = [i for i in self.customer['documents'].keys()
1043                 if len(i) > 10][0]
1044        document = self.customer['documents'][docid]
1045        self.browser.getControl(name="form.title").value = 'My second doc'
1046        self.browser.getControl("Save").click()
1047        self.assertEqual(document.title, 'My second doc')
1048        self.assertTrue('Form has been saved.' in self.browser.contents)
1049        self.browser.getLink("View").click()
1050        self.assertEqual(
1051            self.browser.url, self.documents_path + '/%s/index' % docid)
1052        # Customer can upload a document.
1053        self.browser.getLink("Edit").click()
1054        ctrl = self.browser.getControl(name='samplescaneditupload')
1055        file_obj = open(SAMPLE_IMAGE, 'rb')
1056        file_ctrl = ctrl.mech_control
1057        file_ctrl.add_file(file_obj, filename='my_document.jpg')
1058        self.browser.getControl(
1059            name='upload_samplescaneditupload').click()
1060        self.assertTrue(
1061            'href="http://localhost/app/customers/K1000000/'
1062            'documents/%s/sample"'
1063            % docid in self.browser.contents)
1064        # Customer can submit the form. The form is also saved.
1065        self.browser.getControl(name="form.title").value = 'My third doc'
1066        self.browser.getControl("Final Submit").click()
1067        self.assertEqual(document.title, 'My third doc')
1068        self.assertEqual(document.state, 'submitted')
1069        self.assertTrue(
1070            'Document State: submitted for verification'
1071            in self.browser.contents)
1072        # Customer can't edit the document once it has been submitted
1073        self.browser.open(self.documents_path + '/%s/edit' % docid)
1074        self.assertTrue(
1075            'The requested form is locked' in self.browser.contents)
1076
1077    def test_manage_upload_sample_file(self):
1078        # Managers can upload a file via the DocumentManageFormPage
1079        # The image is stored even if form has errors
1080        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1081        self.browser.open(self.customer_path + '/documents/DOC1/manage')
1082        # Create a pseudo image file and select it to be uploaded
1083        image = open(SAMPLE_IMAGE, 'rb')
1084        ctrl = self.browser.getControl(name='samplescanmanageupload')
1085        file_ctrl = ctrl.mech_control
1086        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
1087        # The Save action does not upload files
1088        self.browser.getControl("Save").click()  # submit form
1089        self.assertFalse(
1090            'href="http://localhost/app/customers/K1000000/'
1091            'documents/DOC1/sample"'
1092            in self.browser.contents)
1093        # ... but the correct upload submit button does
1094        image = open(SAMPLE_IMAGE)
1095        ctrl = self.browser.getControl(name='samplescanmanageupload')
1096        file_ctrl = ctrl.mech_control
1097        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
1098        self.browser.getControl(
1099            name='upload_samplescanmanageupload').click()
1100        self.assertTrue(
1101            'href="http://localhost/app/customers/K1000000/'
1102            'documents/DOC1/sample"'
1103            in self.browser.contents)
1104        # Browsing the link shows a real image
1105        self.browser.open('sample')
1106        self.assertEqual(
1107            self.browser.headers['content-type'], 'image/jpeg')
1108        self.assertEqual(len(self.browser.contents), 2787)
1109        # We can't reupload a file. The existing file must be deleted first.
1110        self.browser.open(self.customer_path + '/documents/DOC1/manage')
1111        self.assertFalse(
1112            'upload_samplescanmanageupload' in self.browser.contents)
1113        # File must be deleted first
1114        self.browser.getControl(name='delete_samplescanmanageupload').click()
1115        self.assertTrue(
1116            'sample deleted' in self.browser.contents)
1117        # Uploading a file which is bigger than 150k will raise an error
1118        big_image = StringIO(open(SAMPLE_IMAGE, 'rb').read() * 75)
1119        ctrl = self.browser.getControl(name='samplescanmanageupload')
1120        file_ctrl = ctrl.mech_control
1121        file_ctrl.add_file(big_image, filename='my_sample_scan.jpg')
1122        self.browser.getControl(
1123            name='upload_samplescanmanageupload').click()
1124        self.assertTrue(
1125            'Uploaded file is too big' in self.browser.contents)
1126        # We do not rely on filename extensions given by uploaders
1127        image = open(SAMPLE_IMAGE, 'rb')  # a jpg-file
1128        ctrl = self.browser.getControl(name='samplescanmanageupload')
1129        file_ctrl = ctrl.mech_control
1130        # Tell uploaded file is bmp
1131        file_ctrl.add_file(image, filename='my_sample_scan.bmp')
1132        self.browser.getControl(
1133            name='upload_samplescanmanageupload').click()
1134        self.assertTrue(
1135            # jpg file was recognized
1136            'File sample.jpg uploaded.' in self.browser.contents)
1137        # Delete file again
1138        self.browser.getControl(name='delete_samplescanmanageupload').click()
1139        self.assertTrue(
1140            'sample deleted' in self.browser.contents)
1141        # File names must meet several conditions
1142        bmp_image = open(SAMPLE_IMAGE_BMP, 'rb')
1143        ctrl = self.browser.getControl(name='samplescanmanageupload')
1144        file_ctrl = ctrl.mech_control
1145        file_ctrl.add_file(bmp_image, filename='my_sample_scan.bmp')
1146        self.browser.getControl(
1147            name='upload_samplescanmanageupload').click()
1148        self.assertTrue('Only the following extensions are allowed'
1149            in self.browser.contents)
1150
1151    def test_verify_document(self):
1152        IWorkflowState(self.customer).setState('approved')
1153        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1154        self.browser.open(self.customer_path + '/documents/DOC1/manage')
1155        image = open(SAMPLE_IMAGE, 'rb')
1156        ctrl = self.browser.getControl(name='samplescanmanageupload')
1157        file_ctrl = ctrl.mech_control
1158        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
1159        self.browser.getControl(
1160            name='upload_samplescanmanageupload').click()
1161        IWorkflowState(self.document).setState(SUBMITTED)
1162        # Only after verifying the document, sample_md5 is set
1163        self.assertEqual(
1164            getattr(self.document, 'sample_md5', None), None)
1165        self.browser.open(self.documents_path + '/DOC1/trigtrans')
1166        self.browser.getControl(name="transition").value = ['verify']
1167        self.browser.getControl("Apply").click()
1168        self.assertEqual(
1169            getattr(self.document, 'sample_md5', None),
1170                    '1d1ab893e87c240afb2104d61ddfe180')
1171
1172    def test_manage_upload_pdf_file(self):
1173        # Managers can upload a file via the DocumentManageFormPage
1174        # The image is stored even if form has errors
1175        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1176        self.browser.open(self.customer_path + '/documents')
1177        self.browser.getControl("Add document").click()
1178        self.browser.getControl(name="doctype").value = ['CustomerPDFDocument']
1179        self.browser.getControl(name="form.title").value = 'My PDF Document'
1180        self.browser.getControl("Add document").click()
1181        docid = [
1182            i for i in self.customer['documents'].keys() if len(i) > 10][0]
1183        self.browser.open(self.documents_path + '/%s/manage' % docid)
1184        # Create a pseudo image file and select it to be uploaded
1185        image = open(SAMPLE_IMAGE, 'rb')
1186        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1187        file_ctrl = ctrl.mech_control
1188        file_ctrl.add_file(image, filename='my_sample_scan.jpg')
1189        self.browser.getControl(
1190            name='upload_pdfscanmanageupload').click()
1191        self.assertTrue(
1192            'pdf file format expected' in self.browser.contents)
1193        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1194        file_ctrl = ctrl.mech_control
1195        file_ctrl.add_file(image, filename='my_sample_scan.pdf')
1196        self.browser.getControl(
1197            name='upload_pdfscanmanageupload').click()
1198        self.assertTrue(
1199            'Could not determine file type' in self.browser.contents)
1200        pdf = open(SAMPLE_PDF, 'rb')
1201        ctrl = self.browser.getControl(name='pdfscanmanageupload')
1202        file_ctrl = ctrl.mech_control
1203        file_ctrl.add_file(pdf, filename='my_sample_scan.pdf')
1204        self.browser.getControl(
1205            name='upload_pdfscanmanageupload').click()
1206        self.assertTrue(
1207            'href="http://localhost/app/customers/K1000000/'
1208            'documents/%s/sample.pdf">%s.pdf</a>'
1209            % (docid, docid[:9]) in self.browser.contents)
1210        # Browsing the link shows a real pdf
1211        self.browser.open('sample.pdf')
1212        self.assertEqual(
1213            self.browser.headers['content-type'], 'application/pdf')
1214        # The name of the downloaded file will be different
1215        self.assertEqual(
1216            self.browser.headers['Content-Disposition'],
1217            'attachment; filename="%s.pdf' % docid[:9])
1218
1219    def test_view_slips(self):
1220        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1221        # Officers can open the document overview
1222        self.browser.open(self.customer_path + '/documents')
1223        self.browser.getLink("Download documents overview").click()
1224        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1225        self.assertEqual(
1226            self.browser.headers['Content-Type'], 'application/pdf')
1227        path = os.path.join(samples_dir(), 'documents_overview_slip.pdf')
1228        open(path, 'wb').write(self.browser.contents)
1229        print "Sample PDF overview_slip.pdf written to %s" % path
1230        # Officers can open document slips which shows a thumbnail of
1231        # the jpeg file attached.
1232        file_id = IFileStoreNameChooser(self.document).chooseName(
1233            attr='sample.jpg')
1234        fs = ExtFileStore(root=self.dc_root)
1235        jpegfile = open(SAMPLE_IMAGE, 'rb')
1236        fs.createFile(file_id, jpegfile)
1237        self.browser.open(self.customer_path + '/documents/DOC1')
1238        self.browser.getLink("Download document slip").click()
1239        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1240        self.assertEqual(
1241            self.browser.headers['Content-Type'], 'application/pdf')
1242        path = os.path.join(samples_dir(), 'document_slip.pdf')
1243        open(path, 'wb').write(self.browser.contents)
1244        print "Sample document_slip.pdf written to %s" % path
1245        # Officers can open merged pdf document slips
1246        pdfdocument = createObject('waeup.CustomerPDFDocument')
1247        pdfdocument.title = u'My first document'
1248        self.customer['documents'].addDocument(pdfdocument)
1249        # Add pdf file
1250        file_id = IFileStoreNameChooser(pdfdocument).chooseName(
1251            attr='sample.pdf')
1252        fs = ExtFileStore(root=self.dc_root)
1253        pdffile = open(SAMPLE_PDF, 'rb')
1254        fs.createFile(file_id, pdffile)
1255        docid = [i for i in self.customer['documents'].keys()
1256                 if len(i) > 10][0]
1257        self.browser.open(self.customer_path + '/documents/' + docid)
1258        self.browser.getLink("Download document slip").click()
1259        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1260        self.assertEqual(
1261            self.browser.headers['Content-Type'], 'application/pdf')
1262        path = os.path.join(samples_dir(), 'pdfdocument_slip.pdf')
1263        open(path, 'wb').write(self.browser.contents)
1264        print "Sample pdfdocument_slip.pdf written to %s" % path
1265
1266    def test_get_setmd5_file(self):
1267        # A proper file name chooser is registered for customer documents.
1268        # This is not a UI test. It's just a functional test.
1269        file_id = IFileStoreNameChooser(self.document).chooseName(
1270            attr='sample')
1271        fs = ExtFileStore(root=self.dc_root)
1272        fs.createFile(file_id, StringIO('my sample 1'))
1273        result = fs.getFileByContext(self.document, attr='sample')
1274        self.assertEqual(
1275            file_id, '__file-customerdocument__01000/'
1276            'K1000000/sample_DOC1_K1000000')
1277        self.assertEqual(result.read(), 'my sample 1')
1278        self.assertEqual(
1279            self.document.connected_files[0][1].read(), 'my sample 1')
1280        self.document.setMD5()
1281        self.assertEqual(
1282            self.document.sample_md5, 'a406995ee8eb6772bacf51aa4b0caa24')
1283        return
1284
1285
1286class ContractUITests(CustomersFullSetup):
1287    # Tests for contract related views and pages
1288
1289    def test_manage_contract(self):
1290        # Managers can access the pages of customer contractsconter
1291        # and can perform actions
1292        IWorkflowState(self.customer).setState(APPROVED)
1293        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1294        self.browser.open(self.customer_path)
1295        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1296        self.assertEqual(self.browser.url, self.customer_path)
1297        self.browser.open(self.customer_path)
1298        self.browser.getLink("Contracts").click()
1299        self.browser.getControl("Add contract").click()
1300        self.browser.getControl(name="contype").value = ['SampleContract']
1301        self.browser.getControl("Add contract").click()
1302        self.assertTrue('Sample Contract added.' in self.browser.contents)
1303        conid = [i for i in self.customer['contracts'].keys()
1304                 if len(i) > 10][0]
1305        contract = self.customer['contracts'][conid]
1306        self.assertEqual(
1307            self.browser.url,
1308            self.contracts_path + '/%s/selectproduct' % conid)
1309        # SAM is in the correct contract_category
1310        self.assertTrue('<option value="SAM">' in self.browser.contents)
1311        # So far last_product_id is None.
1312        self.assertTrue(
1313            self.customer['contracts'][conid].last_product_id is None)
1314        self.browser.getControl(name="form.product_object").value = ['SAM']
1315        self.browser.getControl("Save and proceed").click()
1316        self.assertEqual(
1317            self.browser.url, self.contracts_path + '/%s/manage' % conid)
1318        self.browser.getLink("View").click()
1319        self.assertEqual(
1320            self.browser.url, self.contracts_path + '/%s/index' % conid)
1321        self.assertEqual(contract.tc_dict, {'en': u'Hello world'})
1322
1323        # Transitions can be performed
1324        self.browser.getLink("Transition").click()
1325        self.browser.getControl(name="transition").value = ['submit']
1326        self.browser.getControl("Apply").click()
1327        self.browser.getLink("Transition").click()
1328        self.browser.getControl(name="transition").value = ['approve']
1329        self.browser.getControl("Apply").click()
1330        self.assertEqual(contract.state, 'approved')
1331
1332        # Even in state approved the official use data can be edited
1333        self.browser.open(self.contracts_path + '/%s/index' % conid)
1334        self.browser.getLink("Manage official data").click()
1335        self.browser.getControl(name="form.comment").value = u'Nice place'
1336        self.browser.getControl("Save").click()
1337        self.assertEqual(contract.comment, 'Nice place')
1338        self.assertTrue('Form has been saved.' in self.browser.contents)
1339
1340        # Contracts can be removed
1341        self.browser.getLink("Contracts").click()
1342        ctrl = self.browser.getControl(name='val_id')
1343        ctrl.getControl(value=contract.contract_id).selected = True
1344        self.browser.getControl("Remove selected", index=0).click()
1345        self.assertTrue('Successfully removed' in self.browser.contents)
1346
1347        # All actions are being logged
1348        logfile = os.path.join(
1349            self.app['datacenter'].storage, 'logs', 'customers.log')
1350        logcontent = open(logfile).read()
1351        self.assertTrue(
1352            'INFO - zope.mgr - K1000000 - %s - Contract created' % conid
1353            in logcontent)
1354        self.assertTrue(
1355            'INFO - zope.mgr - customers.browser.ContractAddFormPage '
1356            '- K1000000 - added: Sample Contract %s'
1357            % contract.contract_id in logcontent)
1358        self.assertTrue(
1359            'INFO - zope.mgr - K1000000 - %s - Submitted for approval' % conid
1360            in logcontent)
1361        self.assertTrue(
1362            'INFO - zope.mgr - K1000000 - %s - Approved' % conid
1363            in logcontent)
1364        self.assertTrue(
1365            'INFO - zope.mgr - customers.browser.ContractsFormPage '
1366            '- K1000000 - removed: %s' % conid
1367            in logcontent)
1368
1369    def test_edit_sample_contract(self):
1370        # We add a second product.
1371        product = createObject('waeup.Product')
1372        product.product_id = u'LIC'
1373        product.title = u'Our License Product'
1374        product.contract_category = u'license'
1375        product.valid_from = date(2014, 12, 4)
1376        self.app['products'].addProduct(product)
1377        # Customers can manage contracts under certain conditions
1378        self.browser.open(self.login_path)
1379        self.browser.getControl(name="form.login").value = self.customer_id
1380        self.browser.getControl(name="form.password").value = 'cpwd'
1381        self.browser.getControl("Login").click()
1382        self.assertMatches(
1383            '...You logged in...', self.browser.contents)
1384        self.browser.getLink("Contracts").click()
1385        # Customer is in wrong state
1386        self.assertFalse('Add contract' in self.browser.contents)
1387        self.browser.open(self.contracts_path + '/addcontract')
1388        self.assertTrue(
1389            'The requested form is locked' in self.browser.contents)
1390        IWorkflowState(self.customer).setState(APPROVED)
1391        self.browser.open(self.contracts_path)
1392        # Now customer can add a contract
1393        self.browser.getControl("Add contract").click()
1394        self.browser.getControl(name="contype").value = ['SampleContract']
1395        self.browser.getControl("Add contract").click()
1396        self.assertTrue('Sample Contract added.' in self.browser.contents)
1397        conid = [i for i in self.customer['contracts'].keys()
1398                 if len(i) > 10][0]
1399        contract = self.customer['contracts'][conid]
1400        self.assertEqual(
1401            self.browser.url,
1402            self.contracts_path + '/%s/selectproduct' % conid)
1403        # SAM is in the correct contract_category ...
1404        self.assertTrue('<option value="SAM">' in self.browser.contents)
1405        # ... but LIC not.
1406        self.assertFalse('<option value="LIC">' in self.browser.contents)
1407        # So far last_product_id is None.
1408        self.assertTrue(
1409            self.customer['contracts'][conid].last_product_id is None)
1410        self.browser.getControl(name="form.product_object").value = ['SAM']
1411        self.browser.getControl("Save and proceed").click()
1412        self.assertEqual(
1413            self.browser.url, self.contracts_path + '/%s/edit' % conid)
1414        # Document is a required field on edit form page.
1415        self.browser.getControl("Save").click()
1416        self.assertTrue(
1417            'Document: <span class="error">Required input is missing.</span>'
1418            in self.browser.contents)
1419        # But our document can't be selected because it's not submitted
1420        self.assertFalse('My first document' in self.browser.contents)
1421        IWorkflowState(self.document).setState(SUBMITTED)
1422        self.browser.open(self.contracts_path + '/%s/edit' % conid)
1423        self.browser.getControl(name="form.document_object").value = ['DOC1']
1424        self.browser.getControl("Save").click()
1425        # After saving the form, last_product_id and other attributes are set
1426        self.assertTrue('Form has been saved.' in self.browser.contents)
1427        self.assertEqual(
1428            self.customer['contracts'][conid].last_product_id, 'SAM')
1429        self.assertEqual(contract.title, 'Our Sample Product')
1430        self.assertEqual(contract.product_object, self.product)
1431        self.assertEqual(contract.document_object, self.document)
1432        # Saving the form again does not unset last_product_id
1433        self.browser.getControl("Save").click()
1434        self.assertEqual(
1435            self.customer['contracts'][conid].last_product_id, 'SAM')
1436        self.assertTrue('Form has been saved.' in self.browser.contents)
1437        # So far we have not yet set product options.
1438        # Unfortunately, we can't set them in test browser
1439        prodoption = ProductOption()
1440        prodoption.title = u'Any product option'
1441        prodoption.fee = Decimal('88.8')
1442        prodoption.currency = 'EUR'
1443        contract.product_options = [prodoption, ]
1444        self.browser.open(self.contracts_path + '/%s/edit' % conid)
1445        # We can see both the stored and the recent product options
1446        # from the chosen product.
1447        self.assertTrue(
1448            '<option selected="selected" value="Any product option">'
1449            'Any product option @ 88.8 Euro</option>'
1450            in self.browser.contents)
1451        self.assertTrue('<option value="First option">First option '
1452                        '@ 99.9 US Dollar</option>' in self.browser.contents)
1453        # In test browser we can at least replace the option
1454        self.browser.getControl(
1455            name="form.product_options.0.").value = ['First option']
1456        self.assertEqual(
1457            contract.product_options[0].title, 'Any product option')
1458        self.browser.getControl("Save").click()
1459        self.assertEqual(contract.product_options[0].title, 'First option')
1460        self.browser.getLink("View").click()
1461        self.assertTrue(
1462            '<span>First option @ 99.9 US Dollar</span>'
1463            in self.browser.contents)
1464        self.assertEqual(
1465            self.browser.url, self.contracts_path + '/%s/index' % conid)
1466        # An href attribute is referring to the document and product objects
1467        self.assertTrue('<a href="http://localhost/app/products/SAM">SAM -'
1468            in self.browser.contents)
1469        self.assertTrue(
1470            '<a href="http://localhost/app/customers/K1000000/'
1471            'documents/DOC1">DOC1 -'
1472            in self.browser.contents)
1473        # Customer can submit the form if confirmation box is ticket.
1474        # The form is also saved.
1475        self.browser.getLink("Edit").click()
1476        self.browser.getControl("Proceed to checkout").click()
1477        self.assertTrue(
1478            'confirm your acceptance of these by ticking'
1479            in self.browser.contents)
1480        self.assertEqual(contract.state, 'created')
1481        self.browser.getControl(name="confirm_tc").value = True
1482        self.browser.getControl("Proceed to checkout").click()
1483        self.assertEqual(contract.state, 'created')
1484        radio_ctrl = self.browser.getControl(name='gw')
1485        radio_ctrl.value = [radio_ctrl.options[0]]  # pick first payment opt
1486        self.browser.getControl("Select payment method").click()
1487        self.assertEqual(contract.state, 'awaiting')
1488        # Customer can't edit the contract once it has been submitted
1489        self.browser.open(self.contracts_path + '/%s/edit' % conid)
1490        self.assertTrue(
1491            'The requested form is locked' in self.browser.contents)
1492
1493    def test_view_slips(self):
1494        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1495        # Officers can open the contract overview
1496        self.browser.open(self.customer_path + '/contracts')
1497        self.browser.getLink("Download contracts overview").click()
1498        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1499        self.assertEqual(
1500            self.browser.headers['Content-Type'], 'application/pdf')
1501        path = os.path.join(samples_dir(), 'contracts_overview_slip.pdf')
1502        open(path, 'wb').write(self.browser.contents)
1503        print "Sample PDF overview_slip.pdf written to %s" % path
1504        # Officers can open contract slips.
1505        # First we add a submitted document and a product.
1506        IWorkflowState(self.document).setState(SUBMITTED)
1507        self.contract.document_object = self.document
1508        self.contract.product_object = self.product
1509        self.contract.tc_dict = {'en': u'<strong>Hello world</strong>'}
1510        self.contract.valid_from = date(2015, 12, 4)
1511        self.contract.valid_to = 'anything'
1512        self.contract.title = u'Contract Title'
1513        self.browser.open(self.customer_path + '/contracts/CON1')
1514        self.browser.getLink("Download contract slip").click()
1515        self.assertEqual(self.browser.headers['Status'], '200 Ok')
1516        self.assertEqual(
1517            self.browser.headers['Content-Type'], 'application/pdf')
1518        path = os.path.join(samples_dir(), 'contract_slip.pdf')
1519        open(path, 'wb').write(self.browser.contents)
1520        print "Sample contract_slip.pdf written to %s" % path
1521
1522    def test_contract_approval(self):
1523        # This is not a UI test. It's just a functional test.
1524        self.assertRaises(ConstraintNotSatisfied,
1525            self.contract.document_object, self.document)
1526        # Document must be at least submitted
1527        IWorkflowState(self.document).setState('submitted')
1528        self.contract.document_object = self.document
1529        IWorkflowState(self.contract).setState('submitted')
1530        self.assertRaises(InvalidTransitionError,
1531            IWorkflowInfo(self.contract).fireTransition, 'approve')
1532        # Customer must be approved and
1533        # document must be verified for the approval of contracts
1534        IWorkflowState(self.document).setState('verified')
1535        IWorkflowState(self.customer).setState('approved')
1536        IWorkflowInfo(self.contract).fireTransition('approve')
1537        self.assertEqual(IWorkflowState(self.contract).getState(), 'approved')
1538
1539    def test_contract_approval_in_UI(self):
1540        # Now let's see what the UI says when trying to approve a contract
1541        # with unverified documents.
1542        IWorkflowState(self.customer).setState('approved')
1543        IWorkflowState(self.document).setState('submitted')
1544        self.contract.document_object = self.document
1545        IWorkflowState(self.contract).setState('submitted')
1546        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
1547        self.browser.open(self.contracts_path + '/CON1/trigtrans')
1548        self.browser.getControl(name="transition").value = ['approve']
1549        self.browser.getControl("Apply").click()
1550        # InvalidTransitionError is catched
1551        self.assertTrue(
1552            '<div class="alert alert-warning">Attached documents '
1553            'must be verified first.</div>'
1554            in self.browser.contents)
1555        self.browser.open(self.contracts_path + '/CON1/trigtrans')
1556        IWorkflowState(self.document).setState('verified')
1557        self.browser.getControl(name="transition").value = ['approve']
1558        self.browser.getControl("Apply").click()
1559        self.assertEqual(IWorkflowState(self.contract).getState(), 'approved')
1560
1561    def add_product_option(self, contract):
1562        prodoption = ProductOption()
1563        prodoption.title = u'Any product option'
1564        prodoption.fee = Decimal('88.8')
1565        prodoption.currency = 'EUR'
1566        contract.product_options = [prodoption, ]
1567
1568    def prepare_payment_select(self):
1569        IWorkflowState(self.customer).setState('approved')
1570        IWorkflowState(self.document).setState('verified')
1571        self.contract.document_object = self.document
1572        self.add_product_option(self.contract)
1573        IWorkflowState(self.contract).setState('created')
1574        # login as customer
1575        self.browser.open(self.login_path)
1576        self.browser.getControl(name="form.login").value = self.customer_id
1577        self.browser.getControl(name="form.password").value = 'cpwd'
1578        self.browser.getControl("Login").click()
1579
1580    def test_select_payment(self):
1581        # select payment
1582        self.prepare_payment_select()
1583        self.browser.open('%s/CON1/edit' % self.contracts_path)
1584        self.browser.getControl("Proceed to checkout").click()
1585        self.assertTrue(
1586            "Select payment method" in self.browser.contents)
1587        self.assertTrue(
1588            'Credit Card (Demo Payments)' in self.browser.contents)
1589
1590    def test_select_payment_no_choice(self):
1591        # we get warned if no payment was selected
1592        self.prepare_payment_select()
1593        never_ending_button_text = (
1594            'Select payment method and proceed to payment gateway'
1595            ' (final submission)')
1596        self.browser.open(
1597            '%s/CON1/select_payment_method' % self.contracts_path)
1598        self.browser.getControl(never_ending_button_text).click()
1599        self.assertTrue(
1600            'Please pick a payment method' in self.browser.contents)
1601
1602    def test_select_payment_demo_provider(self):
1603        # we can proceed with payments if we select a payment method
1604        self.prepare_payment_select()
1605        never_ending_button_text = (
1606            'Select payment method and proceed to payment gateway'
1607            ' (final submission)')
1608        self.browser.open(
1609            '%s/CON1/select_payment_method' % self.contracts_path)
1610        radio_ctrl = self.browser.getControl(name='gw')
1611        radio_ctrl.displayValue = ['Credit Card (Demo Payments)']
1612        self.browser.getControl(never_ending_button_text).click()
1613        self.assertTrue(
1614            'Payment has been initiated.' in self.browser.contents)
Note: See TracBrowser for help on using the repository browser.